Use ActionSelector in Loft panel and expose to Python by UiLoader

This commit is contained in:
wmayer 2012-06-03 14:22:05 +02:00
parent 5174778cc0
commit 0623cd9b5e
9 changed files with 174 additions and 234 deletions

View File

@ -341,6 +341,10 @@ Application::Application(bool GUIenabled)
"workbenches.");
Py::Module(module).setAttr(std::string("ActiveDocument"),Py::None());
UiLoaderPy::init_type();
Base::Interpreter().addType(UiLoaderPy::type_object(),
module,"UiLoader");
//insert Selection module
PyObject* pSelectionModule = Py_InitModule3("Selection", SelectionSingleton::Methods,
"Selection module");

View File

@ -23,6 +23,7 @@
#include "PreCompiled.h"
#include <CXX/Objects.hxx>
#include <App/Application.h>
#include <Base/Console.h>
#include <Base/Exception.h>
@ -194,6 +195,79 @@ QWidget* UiLoader::createWidget(const QString & className, QWidget * parent,
// ----------------------------------------------------
PyObject *UiLoaderPy::PyMake(struct _typeobject *type, PyObject * args, PyObject * kwds)
{
if (!PyArg_ParseTuple(args, ""))
return 0;
return new UiLoaderPy();
}
void UiLoaderPy::init_type()
{
behaviors().name("UiLoader");
behaviors().doc("UiLoader to create widgets");
behaviors().type_object()->tp_new = &PyMake;
// you must have overwritten the virtual functions
behaviors().supportRepr();
behaviors().supportGetattr();
behaviors().supportSetattr();
add_varargs_method("createWidget",&UiLoaderPy::createWidget,"createWidget()");
}
UiLoaderPy::UiLoaderPy()
{
}
UiLoaderPy::~UiLoaderPy()
{
}
Py::Object UiLoaderPy::repr()
{
std::string s;
std::ostringstream s_out;
s_out << "Ui loader";
return Py::String(s_out.str());
}
Py::Object UiLoaderPy::createWidget(const Py::Tuple& args)
{
Py::Module sipmod(PyImport_AddModule((char*)"sip"));
Py::Module qtmod(PyImport_ImportModule((char*)"PyQt4.Qt"));
// 1st argument
std::string className = (std::string)Py::String(args[0]);
// 2nd argument
QWidget* parent = 0;
if (args.size() > 1) {
Py::Callable func = sipmod.getDict().getItem("unwrapinstance");
Py::Tuple arguments(1);
arguments[0] = args[1]; //PyQt pointer
Py::Object result = func.apply(arguments);
void* ptr = PyLong_AsVoidPtr(result.ptr());
QObject* object = reinterpret_cast<QObject*>(ptr);
if (object)
parent = qobject_cast<QWidget*>(object);
}
// 3rd argument
std::string objectName;
if (args.size() > 2) {
objectName = (std::string)Py::String(args[2]);
}
QWidget* widget = loader.createWidget(QString::fromAscii(className.c_str()), parent,
QString::fromAscii(objectName.c_str()));
Py::Callable func = sipmod.getDict().getItem("wrapinstance");
Py::Tuple arguments(2);
arguments[0] = Py::asObject(PyLong_FromVoidPtr(widget));
arguments[1] = qtmod.getDict().getItem("QWidget");
return func.apply(arguments);
}
// ----------------------------------------------------
WidgetFactorySupplier* WidgetFactorySupplier::_pcSingleton = 0L;
WidgetFactorySupplier & WidgetFactorySupplier::instance()

View File

@ -32,6 +32,7 @@
#include "DlgPreferencesImp.h"
#include "DlgCustomizeImp.h"
#include "PropertyPage.h"
#include <CXX/Extensions.hxx>
namespace Gui {
namespace Dialog{
@ -85,13 +86,33 @@ public:
* Fore more details see the documentation to QWidgetFactory.
*/
QWidget* createWidget(const QString & className, QWidget * parent=0,
const QString& name =QString());
const QString& name = QString());
private:
QStringList cw;
};
// --------------------------------------------------------------------
class UiLoaderPy : public Py::PythonExtension<UiLoaderPy>
{
public:
static void init_type(void); // announce properties and methods
UiLoaderPy();
~UiLoaderPy();
Py::Object repr();
Py::Object createWidget(const Py::Tuple&);
private:
static PyObject *PyMake(struct _typeobject *, PyObject *, PyObject *);
private:
UiLoader loader;
};
// --------------------------------------------------------------------
/**
* The WidgetProducer class is a value-based template class that provides
* the ability to create widgets dynamically.

View File

@ -110,6 +110,7 @@ ActionSelector::ActionSelector(QWidget* parent)
: QWidget(parent)
{
addButton = new QPushButton(this);
addButton->setObjectName(QLatin1String("addButton"));
addButton->setMinimumSize(QSize(30, 30));
QIcon icon;
icon.addFile(QString::fromUtf8(":/icons/button_right.xpm"), QSize(), QIcon::Normal, QIcon::Off);
@ -123,6 +124,7 @@ ActionSelector::ActionSelector(QWidget* parent)
gridLayout->addItem(spacerItem1, 0, 1, 1, 1);
removeButton = new QPushButton(this);
removeButton->setObjectName(QLatin1String("removeButton"));
removeButton->setMinimumSize(QSize(30, 30));
QIcon icon1;
icon1.addFile(QString::fromUtf8(":/icons/button_left.xpm"), QSize(), QIcon::Normal, QIcon::Off);
@ -133,6 +135,7 @@ ActionSelector::ActionSelector(QWidget* parent)
gridLayout->addWidget(removeButton, 2, 1, 1, 1);
upButton = new QPushButton(this);
upButton->setObjectName(QLatin1String("upButton"));
upButton->setMinimumSize(QSize(30, 30));
QIcon icon3;
icon3.addFile(QString::fromUtf8(":/icons/button_up.xpm"), QSize(), QIcon::Normal, QIcon::Off);
@ -141,6 +144,7 @@ ActionSelector::ActionSelector(QWidget* parent)
gridLayout->addWidget(upButton, 3, 1, 1, 1);
downButton = new QPushButton(this);
downButton->setObjectName(QLatin1String("downButton"));
downButton->setMinimumSize(QSize(30, 30));
QIcon icon2;
icon2.addFile(QString::fromUtf8(":/icons/button_down.xpm"), QSize(), QIcon::Normal, QIcon::Off);
@ -155,6 +159,7 @@ ActionSelector::ActionSelector(QWidget* parent)
vboxLayout->addWidget(labelAvailable);
availableWidget = new QTreeWidget(this);
availableWidget->setObjectName(QLatin1String("availableTreeWidget"));
availableWidget->setRootIsDecorated(false);
availableWidget->setHeaderLabels(QStringList() << QString());
availableWidget->header()->hide();
@ -168,6 +173,7 @@ ActionSelector::ActionSelector(QWidget* parent)
vboxLayout1->addWidget(labelSelected);
selectedWidget = new QTreeWidget(this);
selectedWidget->setObjectName(QLatin1String("selectedTreeWidget"));
selectedWidget->setRootIsDecorated(false);
selectedWidget->setHeaderLabels(QStringList() << QString());
selectedWidget->header()->hide();
@ -192,17 +198,39 @@ ActionSelector::ActionSelector(QWidget* parent)
this, SLOT(onItemDoubleClicked(QTreeWidgetItem*,int)) );
connect(selectedWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
this, SLOT(onItemDoubleClicked(QTreeWidgetItem*,int)) );
connect(availableWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
this, SLOT(onItemChanged(QTreeWidgetItem *,int)) );
connect(selectedWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
this, SLOT(onItemChanged(QTreeWidgetItem *,int)) );
connect(availableWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem *)),
this, SLOT(onCurrentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)) );
connect(selectedWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem *)),
this, SLOT(onCurrentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)) );
retranslateUi();
setButtonsEnabled();
}
ActionSelector::~ActionSelector()
{
}
void ActionSelector::setSelectedLabel(const QString& label)
{
labelSelected->setText(label);
}
QString ActionSelector::selectedLabel() const
{
return labelSelected->text();
}
void ActionSelector::setAvailableLabel(const QString& label)
{
labelAvailable->setText(label);
}
QString ActionSelector::availableLabel() const
{
return labelAvailable->text();
}
void ActionSelector::retranslateUi()
{
labelAvailable->setText(QApplication::translate("Gui::ActionSelector", "Available:", 0, QApplication::UnicodeUTF8));
@ -254,7 +282,7 @@ void ActionSelector::setButtonsEnabled()
selectedWidget->indexOfTopLevelItem(selectedWidget->currentItem()) < selectedWidget->topLevelItemCount() - 1);
}
void ActionSelector::onItemChanged(QTreeWidgetItem * /*item*/, int /*column*/)
void ActionSelector::onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)
{
setButtonsEnabled();
}

View File

@ -75,6 +75,10 @@ public:
{ return availableWidget; }
QTreeWidget* selectedTreeWidget() const
{ return selectedWidget; }
void setSelectedLabel(const QString&);
QString selectedLabel() const;
void setAvailableLabel(const QString&);
QString availableLabel() const;
private:
void keyPressEvent(QKeyEvent *);
@ -87,7 +91,7 @@ private Q_SLOTS:
void on_removeButton_clicked();
void on_upButton_clicked();
void on_downButton_clicked();
void onItemChanged(QTreeWidgetItem * item, int column);
void onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*);
void onItemDoubleClicked(QTreeWidgetItem * item, int column);
private:

View File

@ -91,6 +91,7 @@ WidgetFactorySupplier::WidgetFactorySupplier()
new WidgetProducer<Gui::PrefColorButton>;
new WidgetProducer<Gui::CommandIconView>;
new WidgetProducer<Gui::AccelLineEdit>;
new WidgetProducer<Gui::ActionSelector>;
new WidgetProducer<Gui::ColorButton>;
new WidgetProducer<Gui::UrlLabel>;
new WidgetProducer<Gui::FileChooser>;

View File

@ -68,10 +68,14 @@ LoftWidget::LoftWidget(QWidget* parent)
Gui::Application::Instance->runPythonCode("import Part");
d->ui.setupUi(this);
connect(d->ui.treeWidgetWire, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
d->ui.selector->setAvailableLabel(tr("Vertex/Wire"));
d->ui.selector->setSelectedLabel(tr("Loft"));
connect(d->ui.selector->availableTreeWidget(), SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
this, SLOT(onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
connect(d->ui.treeWidgetLoft, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
connect(d->ui.selector->selectedTreeWidget(), SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
this, SLOT(onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
findShapes();
}
@ -105,7 +109,7 @@ void LoftWidget::findShapes()
child->setData(0, Qt::UserRole, name);
Gui::ViewProvider* vp = activeGui->getViewProvider(*it);
if (vp) child->setIcon(0, vp->getIcon());
d->ui.treeWidgetWire->addTopLevelItem(child);
d->ui.selector->availableTreeWidget()->addTopLevelItem(child);
}
}
}
@ -125,13 +129,13 @@ bool LoftWidget::accept()
QTextStream str(&list);
int count = d->ui.treeWidgetLoft->topLevelItemCount();
int count = d->ui.selector->selectedTreeWidget()->topLevelItemCount();
if (count < 2) {
QMessageBox::critical(this, tr("Too few elements"), tr("At least two vertices, edges or wires are required."));
return false;
}
for (int i=0; i<count; i++) {
QTreeWidgetItem* child = d->ui.treeWidgetLoft->topLevelItem(i);
QTreeWidgetItem* child = d->ui.selector->selectedTreeWidget()->topLevelItem(i);
QString name = child->data(0, Qt::UserRole).toString();
str << "App.getDocument('" << d->document.c_str() << "')." << name << ", ";
}
@ -177,61 +181,13 @@ void LoftWidget::onCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem*
}
}
void LoftWidget::on_addButton_clicked()
{
QTreeWidgetItem* item = d->ui.treeWidgetWire->currentItem();
if (item) {
int index = d->ui.treeWidgetWire->indexOfTopLevelItem(item);
item = d->ui.treeWidgetWire->takeTopLevelItem(index);
d->ui.treeWidgetWire->setCurrentItem(0);
d->ui.treeWidgetLoft->addTopLevelItem(item);
d->ui.treeWidgetLoft->setCurrentItem(item);
}
}
void LoftWidget::on_removeButton_clicked()
{
QTreeWidgetItem* item = d->ui.treeWidgetLoft->currentItem();
if (item) {
int index = d->ui.treeWidgetLoft->indexOfTopLevelItem(item);
item = d->ui.treeWidgetLoft->takeTopLevelItem(index);
d->ui.treeWidgetLoft->setCurrentItem(0);
d->ui.treeWidgetWire->addTopLevelItem(item);
d->ui.treeWidgetWire->setCurrentItem(item);
}
}
void LoftWidget::on_upButton_clicked()
{
QTreeWidgetItem* item = d->ui.treeWidgetLoft->currentItem();
if (item && d->ui.treeWidgetLoft->isItemSelected(item)) {
int index = d->ui.treeWidgetLoft->indexOfTopLevelItem(item);
if (index > 0) {
d->ui.treeWidgetLoft->takeTopLevelItem(index);
d->ui.treeWidgetLoft->insertTopLevelItem(index-1, item);
d->ui.treeWidgetLoft->setCurrentItem(item);
}
}
}
void LoftWidget::on_downButton_clicked()
{
QTreeWidgetItem* item = d->ui.treeWidgetLoft->currentItem();
if (item && d->ui.treeWidgetLoft->isItemSelected(item)) {
int index = d->ui.treeWidgetLoft->indexOfTopLevelItem(item);
if (index < d->ui.treeWidgetLoft->topLevelItemCount()-1) {
d->ui.treeWidgetLoft->takeTopLevelItem(index);
d->ui.treeWidgetLoft->insertTopLevelItem(index+1, item);
d->ui.treeWidgetLoft->setCurrentItem(item);
}
}
}
void LoftWidget::changeEvent(QEvent *e)
{
QWidget::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
d->ui.retranslateUi(this);
d->ui.selector->setAvailableLabel(tr("Vertex/Wire"));
d->ui.selector->setSelectedLabel(tr("Loft"));
}
}

View File

@ -43,10 +43,6 @@ public:
bool reject();
private Q_SLOTS:
void on_addButton_clicked();
void on_removeButton_clicked();
void on_upButton_clicked();
void on_downButton_clicked();
void onCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*);
private:

View File

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>324</width>
<width>336</width>
<height>326</height>
</rect>
</property>
@ -14,172 +14,8 @@
<string>Loft</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0" colspan="2">
<widget class="QTreeWidget" name="treeWidgetWire">
<column>
<property name="text">
<string>Vertex/Wire</string>
</property>
</column>
</widget>
</item>
<item row="0" column="2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<spacer name="spacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>33</width>
<height>58</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="addButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>Move right</string>
</property>
<property name="whatsThis">
<string>&lt;b&gt;Move the selected item one level down.&lt;/b&gt;&lt;p&gt;This will also change the level of the parent item.&lt;/p&gt;</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../Gui/Icons/resource.qrc">
<normaloff>:/icons/button_right.xpm</normaloff>:/icons/button_right.xpm</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removeButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>Move left</string>
</property>
<property name="whatsThis">
<string>&lt;b&gt;Move the selected item one level up.&lt;/b&gt;&lt;p&gt;This will also change the level of the parent item.&lt;/p&gt;</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../Gui/Icons/resource.qrc">
<normaloff>:/icons/button_left.xpm</normaloff>:/icons/button_left.xpm</iconset>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
<property name="default">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="upButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>Move up</string>
</property>
<property name="whatsThis">
<string>&lt;b&gt;Move the selected item up.&lt;/b&gt;&lt;p&gt;The item will be moved within the hierarchy level.&lt;/p&gt;</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../Gui/Icons/resource.qrc">
<normaloff>:/icons/button_up.xpm</normaloff>:/icons/button_up.xpm</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="downButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="minimumSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
<property name="toolTip">
<string>Move down</string>
</property>
<property name="whatsThis">
<string>&lt;b&gt;Move the selected item down.&lt;/b&gt;&lt;p&gt;The item will be moved within the hierarchy level.&lt;/p&gt;</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../../Gui/Icons/resource.qrc">
<normaloff>:/icons/button_down.xpm</normaloff>:/icons/button_down.xpm</iconset>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="spacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>33</width>
<height>57</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="3">
<widget class="QTreeWidget" name="treeWidgetLoft">
<column>
<property name="text">
<string>Loft</string>
</property>
</column>
</widget>
<item row="0" column="0" colspan="3">
<widget class="Gui::ActionSelector" name="selector"/>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkSolid">
@ -188,15 +24,35 @@
</property>
</widget>
</item>
<item row="1" column="1" colspan="2">
<item row="1" column="1">
<widget class="QCheckBox" name="checkRuledSurface">
<property name="text">
<string>Ruled surface</string>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>130</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Gui::ActionSelector</class>
<extends>QWidget</extends>
<header>Gui/Widgets.h</header>
</customwidget>
</customwidgets>
<resources>
<include location="../../../Gui/Icons/resource.qrc"/>
</resources>