From 5174778cc01c99697e1cb85a62239de89362151c Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 3 Jun 2012 12:11:38 +0200 Subject: [PATCH] 0000719: Implement a KActionSelector-like widget --- src/Gui/Widgets.cpp | 225 +++++++++++++++---- src/Gui/Widgets.h | 43 +++- src/Tools/plugins/widget/FreeCAD_widgets.sln | 20 -- src/Tools/plugins/widget/customwidgets.cpp | 88 ++++++++ src/Tools/plugins/widget/customwidgets.h | 27 +++ src/Tools/plugins/widget/plugin.cpp | 74 ++++++ 6 files changed, 407 insertions(+), 70 deletions(-) delete mode 100644 src/Tools/plugins/widget/FreeCAD_widgets.sln diff --git a/src/Gui/Widgets.cpp b/src/Gui/Widgets.cpp index 714774d06..98a87442c 100644 --- a/src/Gui/Widgets.cpp +++ b/src/Gui/Widgets.cpp @@ -104,82 +104,229 @@ void CommandIconView::onSelectionChanged(QListWidgetItem * item, QListWidgetItem // ------------------------------------------------------------------------------ +/* TRANSLATOR Gui::ActionSelector */ + ActionSelector::ActionSelector(QWidget* parent) : QWidget(parent) { - moveActionRightButton = new QPushButton(this); - moveActionRightButton->setMinimumSize(QSize(30, 30)); + addButton = new QPushButton(this); + addButton->setMinimumSize(QSize(30, 30)); QIcon icon; icon.addFile(QString::fromUtf8(":/icons/button_right.xpm"), QSize(), QIcon::Normal, QIcon::Off); - moveActionRightButton->setIcon(icon); - gridLayout->addWidget(moveActionRightButton, 1, 1, 1, 1); + addButton->setIcon(icon); + gridLayout = new QGridLayout(this); + gridLayout->addWidget(addButton, 1, 1, 1, 1); spacerItem = new QSpacerItem(33, 57, QSizePolicy::Minimum, QSizePolicy::Expanding); gridLayout->addItem(spacerItem, 5, 1, 1, 1); spacerItem1 = new QSpacerItem(33, 58, QSizePolicy::Minimum, QSizePolicy::Expanding); gridLayout->addItem(spacerItem1, 0, 1, 1, 1); - moveActionLeftButton = new QPushButton(this); - moveActionLeftButton->setMinimumSize(QSize(30, 30)); + removeButton = new QPushButton(this); + removeButton->setMinimumSize(QSize(30, 30)); QIcon icon1; icon1.addFile(QString::fromUtf8(":/icons/button_left.xpm"), QSize(), QIcon::Normal, QIcon::Off); - moveActionLeftButton->setIcon(icon1); - moveActionLeftButton->setAutoDefault(true); - moveActionLeftButton->setDefault(false); + removeButton->setIcon(icon1); + removeButton->setAutoDefault(true); + removeButton->setDefault(false); - gridLayout->addWidget(moveActionLeftButton, 2, 1, 1, 1); + gridLayout->addWidget(removeButton, 2, 1, 1, 1); - moveActionDownButton = new QPushButton(this); - moveActionDownButton->setMinimumSize(QSize(30, 30)); - QIcon icon2; - icon2.addFile(QString::fromUtf8(":/icons/button_down.xpm"), QSize(), QIcon::Normal, QIcon::Off); - moveActionDownButton->setIcon(icon2); - moveActionDownButton->setAutoDefault(true); - - gridLayout->addWidget(moveActionDownButton, 4, 1, 1, 1); - - moveActionUpButton = new QPushButton(this); - moveActionUpButton->setMinimumSize(QSize(30, 30)); + upButton = new QPushButton(this); + upButton->setMinimumSize(QSize(30, 30)); QIcon icon3; icon3.addFile(QString::fromUtf8(":/icons/button_up.xpm"), QSize(), QIcon::Normal, QIcon::Off); - moveActionUpButton->setIcon(icon3); + upButton->setIcon(icon3); - gridLayout->addWidget(moveActionUpButton, 3, 1, 1, 1); + gridLayout->addWidget(upButton, 3, 1, 1, 1); + + downButton = new QPushButton(this); + downButton->setMinimumSize(QSize(30, 30)); + QIcon icon2; + icon2.addFile(QString::fromUtf8(":/icons/button_down.xpm"), QSize(), QIcon::Normal, QIcon::Off); + downButton->setIcon(icon2); + downButton->setAutoDefault(true); + + gridLayout->addWidget(downButton, 4, 1, 1, 1); vboxLayout = new QVBoxLayout(); vboxLayout->setContentsMargins(0, 0, 0, 0); - label_2 = new QLabel(this); - vboxLayout->addWidget(label_2); + labelAvailable = new QLabel(this); + vboxLayout->addWidget(labelAvailable); - avalableTreeWidget = new QTreeWidget(this); - avalableTreeWidget->setRootIsDecorated(false); - avalableTreeWidget->setColumnCount(0); - vboxLayout->addWidget(avalableTreeWidget); + availableWidget = new QTreeWidget(this); + availableWidget->setRootIsDecorated(false); + availableWidget->setHeaderLabels(QStringList() << QString()); + availableWidget->header()->hide(); + vboxLayout->addWidget(availableWidget); gridLayout->addLayout(vboxLayout, 0, 0, 6, 1); vboxLayout1 = new QVBoxLayout(); vboxLayout1->setContentsMargins(0, 0, 0, 0); - label = new QLabel(this); - vboxLayout1->addWidget(label); + labelSelected = new QLabel(this); + vboxLayout1->addWidget(labelSelected); - selectedTreeWidget = new QTreeWidget(this); - vboxLayout1->addWidget(selectedTreeWidget); + selectedWidget = new QTreeWidget(this); + selectedWidget->setRootIsDecorated(false); + selectedWidget->setHeaderLabels(QStringList() << QString()); + selectedWidget->header()->hide(); + vboxLayout1->addWidget(selectedWidget); gridLayout->addLayout(vboxLayout1, 0, 2, 6, 1); - moveActionRightButton->setText(QString()); - moveActionLeftButton->setText(QString()); - moveActionDownButton->setText(QString()); - moveActionUpButton->setText(QString()); - label_2->setText(QApplication::translate("Gui::ActionSelector", "Available:", 0, QApplication::UnicodeUTF8)); - label->setText(QApplication::translate("Gui::ActionSelector", "Selected:", 0, QApplication::UnicodeUTF8)); + addButton->setText(QString()); + removeButton->setText(QString()); + upButton->setText(QString()); + downButton->setText(QString()); + + connect(addButton, SIGNAL(clicked()), + this, SLOT(on_addButton_clicked()) ); + connect(removeButton, SIGNAL(clicked()), + this, SLOT(on_removeButton_clicked()) ); + connect(upButton, SIGNAL(clicked()), + this, SLOT(on_upButton_clicked()) ); + connect(downButton, SIGNAL(clicked()), + this, SLOT(on_downButton_clicked()) ); + connect(availableWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), + 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)) ); + retranslateUi(); } ActionSelector::~ActionSelector() { } +void ActionSelector::retranslateUi() +{ + labelAvailable->setText(QApplication::translate("Gui::ActionSelector", "Available:", 0, QApplication::UnicodeUTF8)); + labelSelected->setText(QApplication::translate("Gui::ActionSelector", "Selected:", 0, QApplication::UnicodeUTF8)); + addButton->setToolTip(QApplication::translate("Gui::ActionSelector", "Add", 0, QApplication::UnicodeUTF8)); + removeButton->setToolTip(QApplication::translate("Gui::ActionSelector", "Remove", 0, QApplication::UnicodeUTF8)); + upButton->setToolTip(QApplication::translate("Gui::ActionSelector", "Move up", 0, QApplication::UnicodeUTF8)); + downButton->setToolTip(QApplication::translate("Gui::ActionSelector", "Move down", 0, QApplication::UnicodeUTF8)); +} + +void ActionSelector::changeEvent(QEvent* event) +{ + if (event->type() == QEvent::LanguageChange) { + retranslateUi(); + } + QWidget::changeEvent(event); +} + +void ActionSelector::keyPressEvent(QKeyEvent* event) +{ + if ((event->modifiers() & Qt::ControlModifier)) { + switch (event->key()) + { + case Qt::Key_Right: + on_addButton_clicked(); + break; + case Qt::Key_Left: + on_removeButton_clicked(); + break; + case Qt::Key_Up: + on_upButton_clicked(); + break; + case Qt::Key_Down: + on_downButton_clicked(); + break; + default: + event->ignore(); + return; + } + } +} + +void ActionSelector::setButtonsEnabled() +{ + addButton->setEnabled(availableWidget->indexOfTopLevelItem(availableWidget->currentItem()) > -1); + removeButton->setEnabled(selectedWidget->indexOfTopLevelItem(selectedWidget->currentItem()) > -1); + upButton->setEnabled(selectedWidget->indexOfTopLevelItem(selectedWidget->currentItem()) > 0); + downButton->setEnabled(selectedWidget->indexOfTopLevelItem(selectedWidget->currentItem()) > -1 && + selectedWidget->indexOfTopLevelItem(selectedWidget->currentItem()) < selectedWidget->topLevelItemCount() - 1); +} + +void ActionSelector::onItemChanged(QTreeWidgetItem * /*item*/, int /*column*/) +{ + setButtonsEnabled(); +} + +void ActionSelector::onItemDoubleClicked(QTreeWidgetItem * item, int column) +{ + QTreeWidget* treeWidget = item->treeWidget(); + if (treeWidget == availableWidget) { + int index = availableWidget->indexOfTopLevelItem(item); + item = availableWidget->takeTopLevelItem(index); + availableWidget->setCurrentItem(0); + selectedWidget->addTopLevelItem(item); + selectedWidget->setCurrentItem(item); + } + else if (treeWidget == selectedWidget) { + int index = selectedWidget->indexOfTopLevelItem(item); + item = selectedWidget->takeTopLevelItem(index); + selectedWidget->setCurrentItem(0); + availableWidget->addTopLevelItem(item); + availableWidget->setCurrentItem(item); + } +} + +void ActionSelector::on_addButton_clicked() +{ + QTreeWidgetItem* item = availableWidget->currentItem(); + if (item) { + int index = availableWidget->indexOfTopLevelItem(item); + item = availableWidget->takeTopLevelItem(index); + availableWidget->setCurrentItem(0); + selectedWidget->addTopLevelItem(item); + selectedWidget->setCurrentItem(item); + } +} + +void ActionSelector::on_removeButton_clicked() +{ + QTreeWidgetItem* item = selectedWidget->currentItem(); + if (item) { + int index = selectedWidget->indexOfTopLevelItem(item); + item = selectedWidget->takeTopLevelItem(index); + selectedWidget->setCurrentItem(0); + availableWidget->addTopLevelItem(item); + availableWidget->setCurrentItem(item); + } +} + +void ActionSelector::on_upButton_clicked() +{ + QTreeWidgetItem* item = selectedWidget->currentItem(); + if (item && selectedWidget->isItemSelected(item)) { + int index = selectedWidget->indexOfTopLevelItem(item); + if (index > 0) { + selectedWidget->takeTopLevelItem(index); + selectedWidget->insertTopLevelItem(index-1, item); + selectedWidget->setCurrentItem(item); + } + } +} + +void ActionSelector::on_downButton_clicked() +{ + QTreeWidgetItem* item = selectedWidget->currentItem(); + if (item && selectedWidget->isItemSelected(item)) { + int index = selectedWidget->indexOfTopLevelItem(item); + if (index < selectedWidget->topLevelItemCount()-1) { + selectedWidget->takeTopLevelItem(index); + selectedWidget->insertTopLevelItem(index+1, item); + selectedWidget->setCurrentItem(item); + } + } +} // ------------------------------------------------------------------------------ diff --git a/src/Gui/Widgets.h b/src/Gui/Widgets.h index a13e407c6..afdddba89 100644 --- a/src/Gui/Widgets.h +++ b/src/Gui/Widgets.h @@ -63,26 +63,47 @@ Q_SIGNALS: // ------------------------------------------------------------------------------ -class ActionSelector : public QWidget +class GuiExport ActionSelector : public QWidget { + Q_OBJECT + public: ActionSelector(QWidget* parent=0); ~ActionSelector(); + QTreeWidget* availableTreeWidget() const + { return availableWidget; } + QTreeWidget* selectedTreeWidget() const + { return selectedWidget; } + +private: + void keyPressEvent(QKeyEvent *); + void changeEvent(QEvent*); + void retranslateUi(); + void setButtonsEnabled(); + +private Q_SLOTS: + void on_addButton_clicked(); + void on_removeButton_clicked(); + void on_upButton_clicked(); + void on_downButton_clicked(); + void onItemChanged(QTreeWidgetItem * item, int column); + void onItemDoubleClicked(QTreeWidgetItem * item, int column); + private: QGridLayout *gridLayout; - QPushButton *moveActionRightButton; + QVBoxLayout *vboxLayout; + QVBoxLayout *vboxLayout1; + QPushButton *addButton; + QPushButton *removeButton; + QPushButton *upButton; + QPushButton *downButton; + QLabel *labelAvailable; + QLabel *labelSelected; + QTreeWidget *availableWidget; + QTreeWidget *selectedWidget; QSpacerItem *spacerItem; QSpacerItem *spacerItem1; - QPushButton *moveActionLeftButton; - QPushButton *moveActionDownButton; - QPushButton *moveActionUpButton; - QVBoxLayout *vboxLayout; - QLabel *label_2; - QTreeWidget *avalableTreeWidget; - QVBoxLayout *vboxLayout1; - QLabel *label; - QTreeWidget *selectedTreeWidget; }; // ------------------------------------------------------------------------------ diff --git a/src/Tools/plugins/widget/FreeCAD_widgets.sln b/src/Tools/plugins/widget/FreeCAD_widgets.sln deleted file mode 100644 index 98489c937..000000000 --- a/src/Tools/plugins/widget/FreeCAD_widgets.sln +++ /dev/null @@ -1,20 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual C++ Express 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeCAD_widgets", "FreeCAD_widgets.vcproj", "{50CDC58F-0FF6-3CFA-BF66-E79DA98E7DF0}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {50CDC58F-0FF6-3CFA-BF66-E79DA98E7DF0}.Debug|Win32.ActiveCfg = Debug|Win32 - {50CDC58F-0FF6-3CFA-BF66-E79DA98E7DF0}.Debug|Win32.Build.0 = Debug|Win32 - {50CDC58F-0FF6-3CFA-BF66-E79DA98E7DF0}.Release|Win32.ActiveCfg = Release|Win32 - {50CDC58F-0FF6-3CFA-BF66-E79DA98E7DF0}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/src/Tools/plugins/widget/customwidgets.cpp b/src/Tools/plugins/widget/customwidgets.cpp index 6a2280377..9de8c0f82 100644 --- a/src/Tools/plugins/widget/customwidgets.cpp +++ b/src/Tools/plugins/widget/customwidgets.cpp @@ -330,6 +330,94 @@ void AccelLineEdit::keyPressEvent ( QKeyEvent * e) // ------------------------------------------------------------------------------ +ActionSelector::ActionSelector(QWidget* parent) + : QWidget(parent) +{ + addButton = new QPushButton(this); + addButton->setMinimumSize(QSize(30, 30)); + QIcon icon; + icon.addFile(QString::fromUtf8(":/icons/button_right.xpm"), QSize(), QIcon::Normal, QIcon::Off); + addButton->setIcon(icon); + gridLayout = new QGridLayout(this); + gridLayout->addWidget(addButton, 1, 1, 1, 1); + + spacerItem = new QSpacerItem(33, 57, QSizePolicy::Minimum, QSizePolicy::Expanding); + gridLayout->addItem(spacerItem, 5, 1, 1, 1); + spacerItem1 = new QSpacerItem(33, 58, QSizePolicy::Minimum, QSizePolicy::Expanding); + gridLayout->addItem(spacerItem1, 0, 1, 1, 1); + + removeButton = new QPushButton(this); + removeButton->setMinimumSize(QSize(30, 30)); + QIcon icon1; + icon1.addFile(QString::fromUtf8(":/icons/button_left.xpm"), QSize(), QIcon::Normal, QIcon::Off); + removeButton->setIcon(icon1); + removeButton->setAutoDefault(true); + removeButton->setDefault(false); + + gridLayout->addWidget(removeButton, 2, 1, 1, 1); + + upButton = new QPushButton(this); + upButton->setMinimumSize(QSize(30, 30)); + QIcon icon3; + icon3.addFile(QString::fromUtf8(":/icons/button_up.xpm"), QSize(), QIcon::Normal, QIcon::Off); + upButton->setIcon(icon3); + + gridLayout->addWidget(upButton, 3, 1, 1, 1); + + downButton = new QPushButton(this); + downButton->setMinimumSize(QSize(30, 30)); + QIcon icon2; + icon2.addFile(QString::fromUtf8(":/icons/button_down.xpm"), QSize(), QIcon::Normal, QIcon::Off); + downButton->setIcon(icon2); + downButton->setAutoDefault(true); + + gridLayout->addWidget(downButton, 4, 1, 1, 1); + + vboxLayout = new QVBoxLayout(); + vboxLayout->setContentsMargins(0, 0, 0, 0); + labelAvailable = new QLabel(this); + vboxLayout->addWidget(labelAvailable); + + availableWidget = new QTreeWidget(this); + availableWidget->setRootIsDecorated(false); + availableWidget->setHeaderLabels(QStringList() << QString()); + availableWidget->header()->hide(); + vboxLayout->addWidget(availableWidget); + + gridLayout->addLayout(vboxLayout, 0, 0, 6, 1); + + vboxLayout1 = new QVBoxLayout(); + vboxLayout1->setContentsMargins(0, 0, 0, 0); + labelSelected = new QLabel(this); + vboxLayout1->addWidget(labelSelected); + + selectedWidget = new QTreeWidget(this); + selectedWidget->setRootIsDecorated(false); + selectedWidget->setHeaderLabels(QStringList() << QString()); + selectedWidget->header()->hide(); + vboxLayout1->addWidget(selectedWidget); + + gridLayout->addLayout(vboxLayout1, 0, 2, 6, 1); + + addButton->setText(QString()); + removeButton->setText(QString()); + upButton->setText(QString()); + downButton->setText(QString()); + + labelAvailable->setText(QApplication::translate("Gui::ActionSelector", "Available:", 0, QApplication::UnicodeUTF8)); + labelSelected->setText(QApplication::translate("Gui::ActionSelector", "Selected:", 0, QApplication::UnicodeUTF8)); + addButton->setToolTip(QApplication::translate("Gui::ActionSelector", "Add", 0, QApplication::UnicodeUTF8)); + removeButton->setToolTip(QApplication::translate("Gui::ActionSelector", "Remove", 0, QApplication::UnicodeUTF8)); + upButton->setToolTip(QApplication::translate("Gui::ActionSelector", "Move up", 0, QApplication::UnicodeUTF8)); + downButton->setToolTip(QApplication::translate("Gui::ActionSelector", "Move down", 0, QApplication::UnicodeUTF8)); +} + +ActionSelector::~ActionSelector() +{ +} + +// -------------------------------------------------------------------- + CommandIconView::CommandIconView ( QWidget * parent ) : QListWidget(parent) { diff --git a/src/Tools/plugins/widget/customwidgets.h b/src/Tools/plugins/widget/customwidgets.h index 2543a119e..013f6ba4a 100644 --- a/src/Tools/plugins/widget/customwidgets.h +++ b/src/Tools/plugins/widget/customwidgets.h @@ -37,6 +37,7 @@ #include #include #include +#include namespace Gui { @@ -176,6 +177,32 @@ protected: // ------------------------------------------------------------------------------ +class ActionSelector : public QWidget +{ + Q_OBJECT + +public: + ActionSelector(QWidget* parent=0); + ~ActionSelector(); + +private: + QGridLayout *gridLayout; + QVBoxLayout *vboxLayout; + QVBoxLayout *vboxLayout1; + QPushButton *addButton; + QPushButton *removeButton; + QPushButton *upButton; + QPushButton *downButton; + QLabel *labelAvailable; + QLabel *labelSelected; + QTreeWidget *availableWidget; + QTreeWidget *selectedWidget; + QSpacerItem *spacerItem; + QSpacerItem *spacerItem1; +}; + +// ------------------------------------------------------------------------------ + class CommandIconView : public QListWidget { Q_OBJECT diff --git a/src/Tools/plugins/widget/plugin.cpp b/src/Tools/plugins/widget/plugin.cpp index d0a2aca92..3769f37d4 100644 --- a/src/Tools/plugins/widget/plugin.cpp +++ b/src/Tools/plugins/widget/plugin.cpp @@ -340,6 +340,79 @@ public: } }; +/* XPM */ +static const char *actionselector_pixmap[]={ +"22 22 6 1", +"a c #000000", +"# c #000080", +"b c #008080", +"c c #808080", +"d c #c0c0c0", +". c #ffffff", +"......................", +"......................", +"......................", +"...#aaaaaaaaaaaaaa#...", +".baccccccccccccccccab.", +".acccddddddddddddddca.", +"#ccd................d#", +"acc.................da", +"acd.......d....ca.ac.a", +"acd......db......a...a", +"acd.dbbb.dbbbd...a...a", +"acd.ccdbddb.db...a...a", +"acd.dbbbddb..b...a...a", +"acd.bd.bddb..b...a...a", +"acd.bbbbddbbbc...a...a", +"acd..d.....dd..ca.acda", +"#cd.................d#", +".ac................da.", +".badd............dda#.", +"...#aaaaaaaaaaaaaa#...", +"......................", +"......................"}; + +class ActionSelectorPlugin : public QDesignerCustomWidgetInterface +{ + Q_INTERFACES(QDesignerCustomWidgetInterface) +public: + ActionSelectorPlugin() + { + } + QWidget *createWidget(QWidget *parent) + { + return new Gui::ActionSelector(parent); + } + QString group() const + { + return QLatin1String("Input Widgets"); + } + QIcon icon() const + { + return QIcon( QPixmap( actionselector_pixmap ) ); + } + QString includeFile() const + { + return QLatin1String("Gui/Widgets.h"); + } + QString toolTip() const + { + return QLatin1String("Action Selector"); + } + QString whatsThis() const + { + return QLatin1String("A widget to select actions."); + } + bool isContainer() const + { + return false; + } + QString name() const + { + return QLatin1String("Gui::ActionSelector"); + } +}; + /* XPM */ static const char *iconview_pixmap[]={ "22 22 10 1", @@ -1061,6 +1134,7 @@ QList CustomWidgetPlugin::customWidgets () con cw.append(new LocationWidgetPlugin); cw.append(new FileChooserPlugin); cw.append(new AccelLineEditPlugin); + cw.append(new ActionSelectorPlugin); cw.append(new CommandIconViewPlugin); cw.append(new UIntSpinBoxPlugin); cw.append(new ColorButtonPlugin);