diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index d62c36b4e..a4c3542b3 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -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"); diff --git a/src/Gui/WidgetFactory.cpp b/src/Gui/WidgetFactory.cpp index c074fcd7e..fd734154f 100644 --- a/src/Gui/WidgetFactory.cpp +++ b/src/Gui/WidgetFactory.cpp @@ -23,6 +23,7 @@ #include "PreCompiled.h" +#include #include #include #include @@ -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(ptr); + if (object) + parent = qobject_cast(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() diff --git a/src/Gui/WidgetFactory.h b/src/Gui/WidgetFactory.h index 8f20c8864..705e4c36b 100644 --- a/src/Gui/WidgetFactory.h +++ b/src/Gui/WidgetFactory.h @@ -32,6 +32,7 @@ #include "DlgPreferencesImp.h" #include "DlgCustomizeImp.h" #include "PropertyPage.h" +#include 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 +{ +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. diff --git a/src/Gui/Widgets.cpp b/src/Gui/Widgets.cpp index 98a87442c..d4e66e3be 100644 --- a/src/Gui/Widgets.cpp +++ b/src/Gui/Widgets.cpp @@ -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(); } diff --git a/src/Gui/Widgets.h b/src/Gui/Widgets.h index afdddba89..70366a67f 100644 --- a/src/Gui/Widgets.h +++ b/src/Gui/Widgets.h @@ -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: diff --git a/src/Gui/resource.cpp b/src/Gui/resource.cpp index 3143f1502..b7f3ce8fb 100644 --- a/src/Gui/resource.cpp +++ b/src/Gui/resource.cpp @@ -91,6 +91,7 @@ WidgetFactorySupplier::WidgetFactorySupplier() new WidgetProducer; new WidgetProducer; new WidgetProducer; + new WidgetProducer; new WidgetProducer; new WidgetProducer; new WidgetProducer; diff --git a/src/Mod/Part/Gui/TaskLoft.cpp b/src/Mod/Part/Gui/TaskLoft.cpp index b6d58885d..96c3417a2 100644 --- a/src/Mod/Part/Gui/TaskLoft.cpp +++ b/src/Mod/Part/Gui/TaskLoft.cpp @@ -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; iui.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")); } } diff --git a/src/Mod/Part/Gui/TaskLoft.h b/src/Mod/Part/Gui/TaskLoft.h index 82ac877a5..50d30771d 100644 --- a/src/Mod/Part/Gui/TaskLoft.h +++ b/src/Mod/Part/Gui/TaskLoft.h @@ -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: diff --git a/src/Mod/Part/Gui/TaskLoft.ui b/src/Mod/Part/Gui/TaskLoft.ui index 1dd0c6159..dd461047d 100644 --- a/src/Mod/Part/Gui/TaskLoft.ui +++ b/src/Mod/Part/Gui/TaskLoft.ui @@ -6,7 +6,7 @@ 0 0 - 324 + 336 326 @@ -14,172 +14,8 @@ Loft - - - - - Vertex/Wire - - - - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 33 - 58 - - - - - - - - true - - - - 30 - 30 - - - - Move right - - - <b>Move the selected item one level down.</b><p>This will also change the level of the parent item.</p> - - - - - - - :/icons/button_right.xpm:/icons/button_right.xpm - - - - - - - true - - - - 30 - 30 - - - - Move left - - - <b>Move the selected item one level up.</b><p>This will also change the level of the parent item.</p> - - - - - - - :/icons/button_left.xpm:/icons/button_left.xpm - - - true - - - false - - - - - - - true - - - - 30 - 30 - - - - Move up - - - <b>Move the selected item up.</b><p>The item will be moved within the hierarchy level.</p> - - - - - - - :/icons/button_up.xpm:/icons/button_up.xpm - - - - - - - true - - - - 30 - 30 - - - - Move down - - - <b>Move the selected item down.</b><p>The item will be moved within the hierarchy level.</p> - - - - - - - :/icons/button_down.xpm:/icons/button_down.xpm - - - true - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 33 - 57 - - - - - - - - - - - Loft - - - + + @@ -188,15 +24,35 @@ - + Ruled surface + + + + Qt::Horizontal + + + + 130 + 20 + + + + + + + Gui::ActionSelector + QWidget +
Gui/Widgets.h
+
+