In my main I try to set the stylesheet for my mainwidget (Subclass of QWidget). But unfortunately it does not apply. With qApp it works. Whats the difference? In the docs I cant find any.
You need to implement paintEvent in order for QSS styles to work in QWidget derived classes:
void mainwidget::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
I don't think it works if you set the stylesheet on qApp, I did a test and it doesn't:
main.cpp:
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qApp->setStyleSheet("QWidget{ background-color: red; } MyCustomWidget { background-color: blue; } ");
Widget w;
w.show();
return a.exec();
}
mycustomwidget.h:
#ifndef MYCUSTOMWIDGET_H
#define MYCUSTOMWIDGET_H
#include <QWidget>
#include <QPaintEvent>
#include <QPainter>
class MyCustomWidget : public QWidget
{
Q_OBJECT
public:
explicit MyCustomWidget(QWidget *parent = 0);
signals:
public slots:
protected:
// void paintEvent(QPaintEvent *e);
};
#endif // MYCUSTOMWIDGET_H
mycustomwidget.cpp:
#include "mycustomwidget.h"
#include <QStyleOption>
MyCustomWidget::MyCustomWidget(QWidget *parent) :
QWidget(parent)
{
}
//void MyCustomWidget::paintEvent(QPaintEvent *)
//{
// QStyleOption opt;
// opt.init(this);
// QPainter p(this);
// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
//}
widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
widget.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>465</width>
<height>392</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QWidget" name="widget_2" native="true">
<property name="styleSheet">
<string notr="true"/>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="MyCustomWidget" name="widget" native="true">
<property name="styleSheet">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>MyCustomWidget</class>
<extends>QWidget</extends>
<header>mycustomwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
Result:
Uncommenting the commented code generates the following result:
So I don't see how it works for you...maybe the problem is somewhere else, so show us the code.
Related
I have a class:
#ifndef _BUTTON_LISTENER_H_
#define _BUTTON_LISTENER_H_
#include <iostream>
#include <vector>
#include "mbed.h"
#include "Buttons/MenuButton.h"
#include "MenuNavigator.h"
class MenuNavigator;
class ButtonListener
{
public:
ButtonListener(MenuNavigator* navigator, unsigned int samplePeriod_us,
MenuButton* select, MenuButton* down,
MenuButton* up, MenuButton* cancel);
vector<MenuButton*> getButtons();
MenuNavigator* getNavigator();
protected:
void init();
void isr();
vector<MenuButton*> buttons;
MenuNavigator* navigator;
unsigned int samplePeriod_us;
Ticker ticker;
};
#endif
And its implementation:
#include "ButtonListener.h"
#include "Buttons/MenuButton.h"
ButtonListener::ButtonListener(MenuNavigator* navigator,
unsigned int samplePeriod, MenuButton* s, MenuButton* d,
MenuButton* u, MenuButton* c) :
navigator(navigator),
samplePeriod_us(samplePeriod_us)
{
buttons.push_back(s);
buttons.push_back(d);
buttons.push_back(u);
buttons.push_back(c);
init();
}
void ButtonListener::init()
{
ticker.attach_us(callback(this, &ButtonListener::isr), 500000);
}
void ButtonListener::isr()
{
printf("in isr\n");
}
I'm attaching isr() method to create an interrupt so that it sends the text to the terminal window. But for some reason, it doesn't work.
If I put printf() statement before or after the init() method in the constructor, the text of printf() gets printed, but the text in the isr() doesn't.
Any help?
Accidentally found the solution. I have MyClass that instantiates ButtonListener. In this class, I declared ButtonListener as a pointer:
ButtonListener* blistener;.
In the constructor of the MyClass, I had ButtonListener buttonListener = new ButtonListener(args...). After I changed it to just buttonListener = new ButtonListener(args...) things worked out.
Hope it's going to be helpful to someone else.
I'm trying to call some functions from GenDList.h inside GenQueue.h after including, but I'm getting a couple errors.
This is my header, GenDList.h:
#ifndef GENDLIST_H
#define GENDLIST_H
#include <iostream>
#include "GenListNode.h"
using namespace std;
template <class T>
class GenDList
{
public:
GenListNode<T> *front;
GenListNode<T> *back;
unsigned int size;
GenDList();
~GenDList();
void insertFront(T data);
void insertBack(T data);
bool insertAfter(int key, T data);
T removeFront();
T removeBack(); //for doubly
T removeAt(int position);
int isEmpty();
unsigned int getSize();
void printList();
T find(T d);
};
#endif
This is my other header that I included the previous header file into, GenQueue.h:
#ifndef GENQUEUE_H
#define GENQUEUE_H
#include <iostream>
#include "GenDList.h"
using namespace std;
template <class T>
class GenQueue
{
public:
GenQueue();
~GenQueue();
void insert(T data);
T remove();
T peek();
int isEmpty();
int isFull();
};
#endif
//***********implementation***************
template <class T>
GenQueue<T>::GenQueue()
{
GenDList<T> list;
}
template <class T>
GenQueue<T>::~GenQueue()
{
}
template <class T>
void GenQueue<T>::insert(T data)
{
GenDList<T>::insertBack(data);
}//error: call to non-static member function without an object argument
template <class T>
T GenQueue<T>::remove()
{
GenDList<T>::removeFront();
}
template <class T>
T GenQueue<T>::peek()
{
return front; //error: use of undeclared identifier here
}
I try to create a DLL in Embarcadero C++ Builder XE3, and use it in a test-project in the same environment.
I take example on a tutorial which code does not give a good result for me (!) : http://docwiki.embarcadero.com/RADStudio/XE3/en/Tutorial:_Using_Dynamic_Linked_Libraries_in_C%2B%2BBuilder_Applications
Here is the content of my DLL :
BaseAuth.h file :
#ifndef BaseAuthH
#define BaseAuthH
#include <System.hpp>
class TBaseAuth
{
public:
virtual void TestMessage() = 0;
};
#endif // BaseAuthH
Auth.h file :
//---------------------------------------------------------------------------
#ifndef AuthH
#define AuthH
//---------------------------------------------------------------------------
#include "BaseAuth.h"
class TAuth : public TBaseAuth
{
public:
TAuth();
~TAuth();
void TestMessage();
};
#endif
Auth.cpp file :
//---------------------------------------------------------------------------
#pragma hdrstop
#include "Auth.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
TAuth::TAuth()
{
}
TAuth::~TAuth()
{
}
void TAuth::TestMessage()
{
MessageBox(0, "Test message", "Test", MB_OK);
}
and File1.cpp :
#pragma hdrstop
#pragma argsused
#include "Auth.h"
extern "C" __declspec(dllexport) void* __stdcall GetClassInstance()
{
return static_cast<void*>(new TAuth());
}
extern "C" int _libmain(unsigned long reason)
{
return 1;
}
Now in the test application I have :
the same BaseAuth.h file
a form with a Button :
Test_DLLAuthOrga.h :
#ifndef Test_DLLAuthOrgaH
#define Test_DLLAuthOrgaH
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
//---------------------------------------------------------------------------
#include "BaseAuth.h"
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published: // Composants gérés par l'EDI
TButton *Button2;
void __fastcall Button2Click(TObject *Sender);
private: // Déclarations utilisateur
TBaseAuth *mpAuth;
public: // Déclarations utilisateur
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Test_DLLAuthOrga.cpp :
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Test_DLLAuthOrga.h"
#include "BaseAuth.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
const wchar_t* library = L"DLLAuthOrga.dll";
extern "C" __declspec(dllimport) void* __stdcall GetClassInstance();
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
HINSTANCE load;
try
{ load = LoadLibrary(library); }
catch(Exception &e)
{ ShowMessage(e.Message); }
if (load)
{
ShowMessage("Library Loaded!");
void *myFunc;
myFunc = (void *)GetProcAddress(load, "GetClassInstance");
mpAuth = (AuthParent*)myFunc;
}
else { ShowMessage("Library not loaded!"); }
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (mpAuth == NULL) return;
try { pRes = mpAuth->TestMessage(); }
catch(Exception &e) { ShowMessage(e.Message); return; }
}
The result is :
the pointer mpAuth has an adress.
But its methods have no adress, and when I call a simple method such as "void TestMessage()", it raises an access violation.
=> It first seemed to be a question of string compatibility (but between "C++ Builder XE3" and "C++ Builder XE3" I would expect the same string format to be used ?!) : Error calling DLL with Unicode Delphi
=> I found a similar issue but with C++ DLL into Delphi, not C++ DLL into C++ ... : Call C++ DLL in Delphi app
=> I tried using "HMODULE" instead of "HINSTANCE load;" : same result.
=> I tried without success using
mpAuth = static_cast<AuthParent*>(myFunc);
instead of :
mpAuth = (AuthParent*)myFunc;
=> I also tried replacing "__stdcall" by "__cdecl" or "" (removing) : the libray loads but GetProcAdress returns NULL.
=> What am I doing wrong in attempting to call the DLL's method "TestMessage()" ?
To correctly bind function from dll you should give it full definition, including calling convention, arguments, return type and __dllexport/__dllimport modifier. The easiest way to do it - using typedef so instead of typing (in Test_DLLAuthOrga.cpp)
void *myFunc;
myFunc = (void *)GetProcAddress(load, "GetClassInstance");
use
typedef __declspec(dllimport) void (__stdcall *MyFuncPointerType)(void);
MyFuncPointerType myFunc;
myFunc = (MyFuncPointerType)GetProcAddress(load, "GetClassInstance");
If you are using __cdecl convention you should also add underscore to the target function name
typedef __declspec(dllimport) void (__cdecl *MyFuncPointerType)(void);
MyFuncPointerType myFunc;
myFunc = (MyFuncPointerType)GetProcAddress(load, "_GetClassInstance");
you can also explicitly define AuthParent* as a return type for your factory function to get rid of uneccessary casts to void* and back to AuthParent* (in File1.cpp and Test_DLLAuthOrga.cpp) so, the final code snippet would look like this:
typedef __declspec(dllimport) AuthParent* (__cdecl *MyFuncPointerType)(void);
MyFuncPointerType myFunc;
myFunc = (MyFuncPointerType)GetProcAddress(load, "_GetClassInstance");
mpAuth = myFunc();
I have two classes: first generate position data (latitude and longitude), how I can access this data (variables latitude and longitute) in second class? becouse in second class I get crazy number(
Here are headers and classes:
first header:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGeoPositionInfoSource>
#include <QGeoPositionInfo>
#include <QtCore/QPointer>
#include <QGeoSatelliteInfo>
#include <QGeoSatelliteInfoSource>
#include "gpsform.h"
QTM_USE_NAMESPACE
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
double latitude;
double longitude;
double altitude;
double speed;
public slots:
void positionUpdated(QGeoPositionInfo geoPositionInfo);
private:
Ui::MainWindow *ui;
QPointer<QGeoPositionInfoSource> locationDataSource;
private slots:
void on_pushButton_2_clicked();
void on_pushButton_4_clicked();
void startGPS();
void on_pushButton_clicked();
signals:
void updated();
};
#endif // MAINWINDOW_H
first class
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "quitdiallog.h"
#include <QGeoCoordinate>
#include <QDebug>
#include <QtGui/QMessageBox>
#include <QList>
#include "gpsform.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
setWindowTitle("Мой кОмпаС");
ui->setupUi(this);
startGPS();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::startGPS()
{
// Obtain the location data source if it is not obtained already
if (!locationDataSource)
{
locationDataSource =
QGeoPositionInfoSource::createDefaultSource(this);
if (locationDataSource)
{
// Whenever the location data source signals that the current
// position is updated, the positionUpdated function is called.
QObject::connect(locationDataSource,
SIGNAL(positionUpdated(QGeoPositionInfo)),
this,
SLOT(positionUpdated(QGeoPositionInfo)));
// Start listening for position updates
locationDataSource->setUpdateInterval(100);
locationDataSource->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods);
locationDataSource->startUpdates();
} else {
// Not able to obtain the location data source
// TODO: Error handling
}
} else {
// Start listening for position updates
locationDataSource->setUpdateInterval(5000);
locationDataSource->startUpdates();
}
}
void MainWindow::positionUpdated(QGeoPositionInfo geoPositionInfo)
{
//gpsform *gpf=new gpsform;
if (geoPositionInfo.isValid())
{
//locationDataSource->stopUpdates();
QGeoCoordinate geoCoordinate = geoPositionInfo.coordinate();
latitude = geoCoordinate.latitude();
longitude = geoCoordinate.longitude();
altitude=geoCoordinate.altitude();
ui->label->setNum(latitude);
ui->label_2->setNum(longitude);
/*if(QGeoPositionInfo::GroundSpeed)
{
speed=QGeoPositionInfo::GroundSpeed;
ui->label_4->setNum(speed);
}*/
emit updated();
//gpf->latitude=this->latitude;
//gpsform *gpf=new gpsform;
//gpf->show();
//gpf->latitude=latitude;
}
}
void MainWindow::on_pushButton_clicked()
{
/*ui->label_3->setNum(latitude);
qDebug()<<latitude<<" "<<longitude<<" "<<altitude;*/
gpsform *gps=new gpsform;
this->hide();
gps->show();
}
void MainWindow::on_pushButton_4_clicked()
{
QuitDiallog *qi=new QuitDiallog;
this->hide();
qi->show();
}
void MainWindow::on_pushButton_2_clicked()
{
ui->label_3->setNum(latitude);
}
second header
#ifndef GPSFORM_H
#define GPSFORM_H
#include <QWidget>
#include "mainwindow.h"
QTM_USE_NAMESPACE
namespace Ui {
class gpsform;
}
class gpsform : public QWidget
{
Q_OBJECT
public:
explicit gpsform(QWidget *parent = 0);
~gpsform();
double latitude;
private:
Ui::gpsform *ui;
private slots:
void on_pushButton_clicked();
void updatedata();
};
#endif // GPSFORM_H
second class:
#include "gpsform.h"
#include "ui_gpsform.h"
#include "mainwindow.h"
#include <QTimer>
#include <QDebug>
gpsform::gpsform(QWidget *parent) :
QWidget(parent),
ui(new Ui::gpsform)
{
ui->setupUi(this);
/*ui->label->setNum(mw->latitude);*/
/* QTimer * timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(update()));
timer->start(50);*/
/* MainWindow *mw = new MainWindow;
QObject::connect(mw,SIGNAL(updated()),this,SLOT(updatedata()));*/
}
gpsform::~gpsform()
{
delete ui;
}
void gpsform::updatedata()
{
/* MainWindow *mw = new MainWindow;
this->latitude=mw->latitude;
ui->label->setNum(mw->latitude);*/
}
void gpsform::on_pushButton_clicked()
{
MainWindow *mw = new MainWindow;
//latitude=mw->latitude;
qDebug()<<mw->latitude;
ui->label->setNum(latitude);
}
For example I want to see latitude in second class, by pressing button. In future I'll do this by Signal/slot to generate label text every time, the position is updated. But now I'll get crazy number. Help me please
MainWindow *mw = new MainWindow;
//latitude=mw->latitude;
qDebug()<<mw->latitude;
You create a new instance of MainWindow and directly access its latitude member. But was it initialized? I see the only place writing into this member in MainWindow is positionUpdated. Are you sure this method gets invoked before you access mw->latitude? You could easily verify that with another qDebug printout from positionUpdated, or by using the debugger.
To comment on the code style in general - it's not good practice to directly access members of other classes like this. One of the problems (as you've just encountered!) with this approach is that the class has no way to actually control the validity of its member. Even the most basic solution - having an accessor method instead of raw member access could do wonders for you here, because the accessor method could potentially check if the value has been computed (or even compute it lazily).
I tried to create a dynamic list constraint. The data in the drop down is not getting refreshed when an item is added to the database.
ListOfValuesQueryConstraint.java
package org.alfresco.ryden;
import java.util.ArrayList;
import java.util.List;
import java.io.Serializable;
import java.sql.*;
import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
import org.alfresco.web.bean.generator.BaseComponentGenerator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.faces.model.SelectItem;
public class ListOfValuesQueryConstraint extends ListOfValuesConstraint implements Serializable {
private static Log logger = LogFactory.getLog(BaseComponentGenerator.class);
private static final long serialVersionUID=1;
private List allowedLabels;
public void setAllowedValues(List allowedValues) {}
public void setCaseSensitive(boolean caseSensitive) {}
public void initialize() {
super.setCaseSensitive(false);
this.loadDB();
}
public List getAllowedValues() {
this.loadDB();
return super.getAllowedValues(); // In earlier post there is no return statement..
//return this.getAllowedValues();
}
public List getAllowedLabels() {
return this.allowedLabels;
}
public void setAllowedLabels(List allowedLabels) {
this.allowedLabels=allowedLabels;
}
public List getSelectItemList() {
List result = new ArrayList(this.getAllowedValues().size());
for(int i=0;i<this.getAllowedValues().size();i++) {
result.add(new SelectItem((Object)this.getAllowedValues().get(i),this.allowedLabels.get(i)));
}
return result;
}
protected void loadDB() {
String driverName = "com.mysql.jdbc.Driver";
String serverName = "localhost:3307";
String mydatabase = "propertyrecord";
String username = "propertyrecord";
String password = "rydenproperty";
List av = new ArrayList();
List al=new ArrayList();
try {
Connection connection = null;
Class.forName(driverName);
String url = “jdbc:mysql://” + serverName + “/” + mydatabase;
connection = DriverManager.getConnection(url, username, password);
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(“select propertyRef from propertyrecord”);
while (rs.next()) {
av.add(rs.getString(“propertyRef”));
al.add(rs.getString(“propertyRef”));
System.out.println(“value of prop pavani “+rs.getString(“propertyRef”));
logger.debug(“value of prop pavani “+rs.getString(“propertyRef”));
}
rs=null;
}
catch (Exception e) {}
super.setAllowedValues(av);
this.setAllowedLabels(al);
}
}
CustomListComponentGenerator.java
package org.alfresco.ryden;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.component.UISelectOne;
import javax.faces.context.FacesContext;
import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
import org.alfresco.service.cmr.dictionary.Constraint;
import org.alfresco.service.cmr.dictionary.ConstraintDefinition;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.web.bean.generator.TextFieldGenerator;
import org.alfresco.web.ui.repo.component.property.PropertySheetItem;
import org.alfresco.web.ui.repo.component.property.UIPropertySheet;
import org.apache.log4j.Logger;
import org.alfresco.ryden.ListOfValuesQueryConstraint;
public class CustomListComponentGenerator extends TextFieldGenerator {
private static Logger log = Logger.getLogger(CustomListComponentGenerator.class);
// private String tutorialQuery =
// “( TYPE:\”{http://www.alfresco.org/model/content/1.0}content\” AND
// (#\\{http\\://www.alfresco.org/model/content/1.0\\}name:\”tutorial\”
// TEXT:\”tutorial\”))”
// ;
private boolean autoRefresh = false;
public boolean isAutoRefresh() {
return autoRefresh;
}
/**
* This gets set from faces-config-beans.xml, and allows some drop downs to
* be automaticlaly refreshable (i.e. country), and others not (i.e. city).
*/
public void setAutoRefresh(boolean autoRefresh) {
this.autoRefresh = autoRefresh;
}
#Override
#SuppressWarnings(“unchecked”)
protected UIComponent createComponent(FacesContext context, UIPropertySheet propertySheet, PropertySheetItem item) {
UIComponent component = super.createComponent(context, propertySheet, item);
log.info(“********************** ” + item + ” >” + component + ” >” + (component instanceof UISelectOne) + ” ” + isAutoRefresh());
if (component instanceof UISelectOne && isAutoRefresh()) {
component.getAttributes().put(“onchange”, “submit()”);
}
return component;
}
/**
* Retrieves the list of values constraint for the item, if it has one
*
* #param context
* FacesContext
* #param propertySheet
* The property sheet being generated
* #param item
* The item being generated
* #return The constraint if the item has one, null otherwise
*/
protected ListOfValuesConstraint getListOfValuesConstraint(FacesContext context, UIPropertySheet propertySheet, PropertySheetItem item) {
ListOfValuesConstraint lovConstraint = null;
log.info(“propertySheet: ” + propertySheet.getNode() + ” item: ” + item.getName());
// get the property definition for the item
PropertyDefinition propertyDef = getPropertyDefinition(context, propertySheet.getNode(), item.getName());
if (propertyDef != null) {
// go through the constaints and see if it has the
// list of values constraint
List constraints = propertyDef.getConstraints();
for (ConstraintDefinition constraintDef : constraints) {
Constraint constraint = constraintDef.getConstraint();
//log.info(“constraint: ” + constraint);
if (constraint instanceof ListOfValuesQueryConstraint) {
//Node currentNode = (Node) propertySheet.getNode();
// This is a workaround for the fact that constraints do not
// have a reference to Node.
//((ListOfValuesQueryConstraint) constraint).setNode(currentNode);
lovConstraint = (ListOfValuesQueryConstraint) constraint;
break;
}
if (constraint instanceof ListOfValuesConstraint) {
lovConstraint = (ListOfValuesConstraint) constraint;
break;
}
}
}
return lovConstraint;
}
}
custom-model.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Definition of Property Base Model -->
<model name="cdl:customdatalist" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<!-- Optional meta-data about the model -->
<description>Custom Data Model</description>
<author>Lalitha Akella</author>
<version>1.0</version>
<!-- Imports are required to allow references to definitions in other models -->
<imports>
<!-- Import Alfresco Dictionary Definitions -->
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
<!-- Import Alfresco Content Domain Model Definitions -->
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
<import uri="http://www.alfresco.org/model/datalist/1.0" prefix="dl"/>
</imports>
<!-- Introduction of new namespaces defined by this model -->
<namespaces>
<namespace uri="cdl.model" prefix="cdl"/>
</namespaces>
<constraints>
<constraint name="cdl:PropertyRef" type="org.alfresco.ryden.ListOfValuesQueryConstraint" >
<parameter name="allowedValues">
<list>
</list>
</parameter>
<parameter name="caseSensitive"><value>true</value></parameter>
</constraint>
</constraints>
<types>
<type name="cdl:applicationform">
<title>Custom Application Form</title>
<parent>dl:dataListItem</parent>
<properties>
<property name="cdl:applicationpropertyRef">
<title>Property Reference</title>
<type>d:text</type>
<mandatory>true</mandatory>
<constraints>
<constraint ref="cdl:PropertyRef" />
</constraints>
</property>
<property name="cdl:applicationpropAddress">
<title>Property Address</title>
<type>d:text</type>
<mandatory>false</mandatory>
</property>
<property name="cdl:apcreateddate">
<title>Created Date</title>
<type>d:date</type>
<mandatory>false</mandatory>
</property>
<property name="cdl:apcreatedby">
<title>Created By</title>
<type>d:text</type>
<mandatory>false</mandatory>
</property>
<property name="cdl:applicationstatus">
<title>Application Status</title>
<type>d:text</type>
<mandatory>false</mandatory>
</property>
<property name="cdl:applicationlink">
<title>Application Workflow Link</title>
<type>d:text</type>
<mandatory>false</mandatory>
</property>
</properties>
<associations>
<association name="cdl:applicationassignee">
<title>Assignee</title>
<source>
<mandatory>true</mandatory>
<many>true</many>
</source>
<target>
<class>cm:person</class>
<mandatory>true</mandatory>
<many>false</many>
</target>
</association>
<association name="cdl:applicationattachments">
<title>Attachments</title>
<source>
<mandatory>true</mandatory>
<many>true</many>
</source>
<target>
<class>cm:cmobject</class>
<mandatory>true</mandatory>
<many>true</many>
</target>
</association>
</associations>
</type>
<type name="cdl:terminationform">
<title>Custom Termination Form</title>
<parent>dl:dataListItem</parent>
<properties>
<property name="cdl:terminationpropertyRef">
<title>Property Reference</title>
<type>d:text</type>
<mandatory>true</mandatory>
<constraints>
<constraint ref="cdl:PropertyRef" />
</constraints>
</property>
<property name="cdl:trcreateddate">
<title>Created Date</title>
<type>d:date</type>
<mandatory>false</mandatory>
</property>
<property name="cdl:trcreatedby">
<title>Created By</title>
<type>d:text</type>
<mandatory>false</mandatory>
</property>
<property name="cdl:terminationstatus">
<title>Termination Status</title>
<type>d:text</type>
<mandatory>false</mandatory>
</property>
<property name="cdl:terminationlink">
<title>Termination Workflow Link</title>
<type>d:text</type>
<mandatory>false</mandatory>
</property>
</properties>
<associations>
<association name="cdl:terminationassignee">
<title>Assignee</title>
<source>
<mandatory>true</mandatory>
<many>true</many>
</source>
<target>
<class>cm:person</class>
<mandatory>true</mandatory>
<many>false</many>
</target>
</association>
<association name="cdl:terminationattachments">
<title>Attachments</title>
<source>
<mandatory>true</mandatory>
<many>true</many>
</source>
<target>
<class>cm:cmobject</class>
<mandatory>true</mandatory>
<many>true</many>
</target>
</association>
</associations>
</type>
</types>
</model>
web-client-config-custom.xml
<config evaluator="node-type" condition="cdl:assignationform">
<property-sheet>
<show-property name="cdl:assignationpropertyRef" component-generator="CustomListComponentGenerator" />
</property-sheet>
</config>
faces-config-beans.xml
<managed-bean>
<description>
Bean that generates a custom generator component
</description>
<managed-bean-name>
CustomListComponentGenerator
</managed-bean-name>
<managed-bean-class>
org.alfresco.ryden.CustomListComponentGenerator
</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>autoRefresh</property-name>
<value>true</value>
</managed-property>
</managed-bean>
I don't know whether I should be changing any other files or some thing is wrong in the code above.
I am new To alfresco. Any help is deeply appreciated.
Thanks,
Pavani
Try the following and change to as needed, as it works
ListOfCountriesQueryConstraint.java
package org.spectrum.customConstraints;
import java.util.ArrayList;
import java.util.List;
import java.sql.*;
import org.alfresco.repo.dictionary.constraint.ListOfValuesConstraint;
import org.alfresco.web.bean.generator.BaseComponentGenerator;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.Serializable;
import javax.faces.model.SelectItem;
public class ListOfCountriesQueryConstraint extends ListOfValuesConstraint implements Serializable {
private static Log logger = LogFactory.getLog(BaseComponentGenerator.class);
private static final long serialVersionUID = 1;
private List<String> allowedLabels;
#Override
public void setAllowedValues(List allowedValues) {
}
#Override
public void setCaseSensitive(boolean caseSensitive) {
}
#Override
public void initialize() {
super.setCaseSensitive(false);
this.loadDB();
}
#Override
public List getAllowedValues() {
this.loadDB();
return super.getAllowedValues();
}
public List<String> getAllowedLabels() {
return this.allowedLabels;
}
public void setAllowedLabels(List<String> allowedLabels) {
this.allowedLabels = allowedLabels;
}
public List<SelectItem> getSelectItemList() {
List<SelectItem> result = new ArrayList<SelectItem>(this.getAllowedValues().size());
for (int i = 0; i < this.getAllowedValues().size(); i++) {
result.add(new SelectItem((Object) this.getAllowedValues().get(i), this.allowedLabels.get(i)));
}
return result;
}
protected void loadDB() {
String driverName = "org.gjt.mm.mysql.Driver";
String serverName = "alfrescotest";
String mydatabase = "alfresco_custom";
String username = "root";
String password = "support";
List<String> av = new ArrayList<String>();
List<String> al = new ArrayList<String>();
try {
Connection connection = null;
Class.forName(driverName);
String url = "jdbc:mysql://" + serverName + "/" + mydatabase;
connection = DriverManager.getConnection(url, username, password);
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("select country from countries");
while (rs.next()) {
av.add(rs.getString("country"));
al.add(rs.getString("country"));
}
} catch (Exception e) {
}
super.setAllowedValues(av);
this.setAllowedLabels(al);
}
}
custom-model.xml
<constraint name="sp:country" type="org.spectrum.customConstraints.ListOfCountriesQueryConstraint">
<parameter name="allowedValues">
<list>
</list>
</parameter>
<parameter name="caseSensitive"><value>true</value></parameter>
</constraint>
Make sure to copy the compile java to tomcat/webapps/alfresco/WEB-INF/classes/org/xxx/