Salome HOME
673bab04eec7f8409a38fb6294c87b5098e6f92f
[modules/shaper.git] / src / SHAPERGUI / SHAPERGUI_ToolbarsMgr.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include "SHAPERGUI_ToolbarsMgr.h"
22 #include "SHAPERGUI.h"
23
24 #include <CAM_Application.h>
25 #include <SUIT_Desktop.h>
26 #include <QtxActionToolMgr.h>
27
28 #include <QLayout>
29 #include <QDialogButtonBox>
30 #include <QLabel>
31 #include <QListWidget>
32 #include <QPushButton>
33 #include <QInputDialog>
34 #include <QMessageBox>
35 #include <QMouseEvent>
36
37
38 #define SEPARATOR "------"
39 #define LIST_WIDTH 180
40
41 class SHAPERGUI_CommandIdItem : public QListWidgetItem
42 {
43 public:
44   SHAPERGUI_CommandIdItem(QListWidget* theParent, int theId, SHAPERGUI* theModule)
45     : QListWidgetItem(theParent), myId(theId), myModule(theModule) {}
46
47
48   virtual QVariant data(int theRole) const {
49     QAction* aAction = 0;
50     if (myId != -1)
51       aAction = myModule->action(myId);
52
53     switch (theRole) {
54     case Qt::DisplayRole:
55       if (aAction)
56         return aAction->text();
57       else
58         return SEPARATOR;
59     case Qt::DecorationRole:
60       if (aAction)
61         return aAction->icon();
62       else
63         return QIcon();
64     }
65     return QListWidgetItem::data(theRole);
66   }
67
68
69   int id() const { return myId; }
70
71 private:
72   SHAPERGUI* myModule;
73   int myId;
74 };
75
76
77 //************************************************************************************
78 //************************************************************************************
79 //************************************************************************************
80 SHAPERGUI_ToolbarsDlg::SHAPERGUI_ToolbarsDlg(SHAPERGUI* theModule)
81   : QDialog(theModule->application()->desktop()),
82   myModule(theModule),
83   myResult(theModule->shaperToolbars())
84 {
85   myFreeCommands = getModuleFreeCommands();
86
87   setWindowTitle(tr("Toolbars"));
88   QVBoxLayout* aMailLayout = new QVBoxLayout(this);
89
90   // Controls part of the dialog
91   QWidget* aControlsWgt = new QWidget(this);
92   QHBoxLayout* aContolsLay = new QHBoxLayout(aControlsWgt);
93   aContolsLay->setContentsMargins(0, 0, 0, 0);
94   aMailLayout->addWidget(aControlsWgt);
95
96   // Right controls
97   QWidget* aListWgt = new QWidget(aControlsWgt);
98   QVBoxLayout* aListLayout = new QVBoxLayout(aListWgt);
99   aListLayout->setContentsMargins(0, 0, 0, 0);
100   aContolsLay->addWidget(aListWgt);
101
102   aListLayout->addWidget(new QLabel(tr("Toolbars:"), aListWgt));
103
104   myToolbarsList = new QListWidget(aListWgt);
105   connect(myToolbarsList, SIGNAL(doubleClicked(const QModelIndex&)),
106     SLOT(onDoubleClick(const QModelIndex&)));
107   aListLayout->addWidget(myToolbarsList);
108
109   QWidget* aFreeItemsWgt = new QWidget(aListWgt);
110   QHBoxLayout* aFreeLayout = new QHBoxLayout(aFreeItemsWgt);
111   aFreeLayout->setContentsMargins(0, 0, 0, 0);
112   aListLayout->addWidget(aFreeItemsWgt);
113
114   aFreeLayout->addWidget(new QLabel(tr("Number of commands out of toolbars:"), aFreeItemsWgt));
115   myFreeNbLbl = new QLabel(aFreeItemsWgt);
116   aFreeLayout->addWidget(myFreeNbLbl);
117
118   // Left controls
119   QWidget* aButtonsWgt = new QWidget(aControlsWgt);
120   QVBoxLayout* aBtnLayout = new QVBoxLayout(aButtonsWgt);
121   aBtnLayout->setContentsMargins(0, 0, 0, 0);
122   aContolsLay->addWidget(aButtonsWgt);
123
124   QPushButton* aAddBtn = new QPushButton(tr("Add..."), aButtonsWgt);
125   connect(aAddBtn, SIGNAL(clicked(bool)), SLOT(onAdd()));
126   aBtnLayout->addWidget(aAddBtn);
127
128   QPushButton* aEditBtn = new QPushButton(tr("Edit..."), aButtonsWgt);
129   connect(aEditBtn, SIGNAL(clicked(bool)), SLOT(onEdit()));
130   aBtnLayout->addWidget(aEditBtn);
131
132   QPushButton* aDeleteBtn = new QPushButton(tr("Delete"), aButtonsWgt);
133   connect(aDeleteBtn, SIGNAL(clicked(bool)), SLOT(onDelete()));
134   aBtnLayout->addWidget(aDeleteBtn);
135   aBtnLayout->addStretch(1);
136
137   // Buttons part of the dialog
138   QDialogButtonBox* aButtons =
139     new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
140   aMailLayout->addWidget(aButtons);
141   connect(aButtons, SIGNAL(accepted()), SLOT(accept()));
142   connect(aButtons, SIGNAL(rejected()), SLOT(reject()));
143
144   updateToolbarsList();
145   updateNumber();
146 }
147
148 void SHAPERGUI_ToolbarsDlg::onAdd()
149 {
150   QString aNewToolbar =
151     QInputDialog::getText(this, tr("Create toolbar"), tr("Name of a new toolbar"));
152   if (!(aNewToolbar.isNull() || aNewToolbar.isEmpty())) {
153     if (!myResult.contains(aNewToolbar)) {
154       myResult[aNewToolbar] = QIntList();
155       updateToolbarsList();
156     }
157     else {
158       QString aMsg = tr("A tool bar with name %1 already exists").arg(aNewToolbar);
159       QMessageBox::warning(this, tr("Create toolbar"), aMsg);
160     }
161   }
162 }
163
164 void SHAPERGUI_ToolbarsDlg::onEdit()
165 {
166   QList<QListWidgetItem*> aSelected = myToolbarsList->selectedItems();
167   if (aSelected.size() == 1) {
168     QString aToolbarName = aSelected.first()->text();
169     int aPos = aToolbarName.lastIndexOf(" (");
170     aToolbarName = aToolbarName.left(aPos);
171
172     SHAPERGUI_ToolbarItemsDlg aDlg(this, myModule,
173       aToolbarName, myFreeCommands, myResult[aToolbarName]);
174     if (aDlg.exec() == QDialog::Accepted) {
175       myFreeCommands = aDlg.freeItems();
176       myResult[aToolbarName] = aDlg.toolbarItems();
177       updateNumber();
178       updateToolbarsList();
179     }
180   }
181 }
182
183 void SHAPERGUI_ToolbarsDlg::onDelete()
184 {
185   QList<QListWidgetItem*> aSelected = myToolbarsList->selectedItems();
186   if (aSelected.size() == 1) {
187     QString aToolbarName = aSelected.first()->text();
188     int aPos = aToolbarName.lastIndexOf(" (");
189     aToolbarName = aToolbarName.left(aPos);
190
191     QString aMsg = tr("Toolbar %1 will be deleted. Continue?").arg(aToolbarName);
192     if (QMessageBox::question(this, tr("Delete toolbar"), aMsg) == QMessageBox::Yes) {
193       myFreeCommands.append(myResult[aToolbarName]);
194       // remove separators from free items
195       myFreeCommands.removeAll(-1);
196       myResult.remove(aToolbarName);
197       updateToolbarsList();
198       updateNumber();
199     }
200   }
201 }
202
203 void SHAPERGUI_ToolbarsDlg::updateToolbarsList()
204 {
205   myToolbarsList->clear();
206   QStringList aItems;
207   QMap<QString, QIntList>::const_iterator aIt;
208   for (aIt = myResult.cbegin(); aIt != myResult.cend(); aIt++) {
209     aItems.append(aIt.key() + tr(" (%1 items)").arg(aIt.value().size() - aIt.value().count(-1)));
210   }
211   myToolbarsList->addItems(aItems);
212 }
213
214 QIntList SHAPERGUI_ToolbarsDlg::getModuleFreeCommands() const
215 {
216   QIntList aFreeCommands;
217   QtxActionToolMgr* aMgr = myModule->toolMgr();
218   QAction* anAction;
219   int aId;
220   QMap<QString, QIntList>::const_iterator aIt;
221   QIntList aShaperActions = myModule->shaperActions();
222   foreach(int aCmd, aShaperActions) {
223     anAction = myModule->action(aCmd);
224     aId = aMgr->actionId(anAction);
225     if (!aMgr->containsAction(aId))
226       aFreeCommands.append(aCmd);
227   }
228   return aFreeCommands;
229 }
230
231
232 void SHAPERGUI_ToolbarsDlg::onDoubleClick(const QModelIndex& theIdx)
233 {
234   if (theIdx.isValid())
235     onEdit();
236 }
237
238 void SHAPERGUI_ToolbarsDlg::updateNumber()
239 {
240   myFreeNbLbl->setText(QString::number(myFreeCommands.size()));
241 }
242
243 //************************************************************************************
244 //************************************************************************************
245 //************************************************************************************
246 SHAPERGUI_ToolbarItemsDlg::SHAPERGUI_ToolbarItemsDlg(QWidget* theParent,
247   SHAPERGUI* theModule,
248   const QString& theToolbar,
249   const QIntList& theFreeItems,
250   const QIntList& theItemsList)
251   : QDialog(theParent),
252   myModule(theModule)
253 {
254   setWindowTitle(tr("Edit toolbar items"));
255
256   QVBoxLayout* aMailLayout = new QVBoxLayout(this);
257
258   // Name of toolbar
259   QWidget* aNameWgt = new QWidget(this);
260   QHBoxLayout* aNameLay = new QHBoxLayout(aNameWgt);
261   aNameLay->setContentsMargins(0, 0, 0, 0);
262   aMailLayout->addWidget(aNameWgt);
263
264   aNameLay->addWidget(new QLabel(tr("Toolbar name:"), aNameWgt));
265   QLabel* aNameLbl = new QLabel(theToolbar, aNameWgt);
266   QFont aFont = aNameLbl->font();
267   aFont.setBold(true);
268   aNameLbl->setFont(aFont);
269   aNameLay->addWidget(aNameLbl);
270   aNameLay->addStretch(1);
271
272   // Lists widget
273   QWidget* aControlsWgt = new QWidget(this);
274   QHBoxLayout* aCtrlLayout = new QHBoxLayout(aControlsWgt);
275   aCtrlLayout->setContentsMargins(0, 0, 0, 0);
276   aMailLayout->addWidget(aControlsWgt);
277
278   // Left list
279   QWidget* aCommandsWgt = new QWidget(aControlsWgt);
280   QVBoxLayout* aCommandsLay = new QVBoxLayout(aCommandsWgt);
281   aCommandsLay->setContentsMargins(0, 0, 0, 0);
282   aCtrlLayout->addWidget(aCommandsWgt);
283
284   aCommandsLay->addWidget(new QLabel(tr("Out of toolbars:"), aCommandsWgt));
285   myCommandsList = new QListWidget(aCommandsWgt);
286   myCommandsList->setSortingEnabled(false);
287
288   myCommandsList->addItem(new SHAPERGUI_CommandIdItem(myCommandsList, -1, myModule));
289   foreach(int aId, theFreeItems) {
290     myCommandsList->addItem(new SHAPERGUI_CommandIdItem(myCommandsList, aId, myModule));
291   }
292   myCommandsList->setMaximumWidth(LIST_WIDTH);
293   aCommandsLay->addWidget(myCommandsList);
294
295   // Middle buttons
296   QWidget* aButtonsWgt = new QWidget(aControlsWgt);
297   QVBoxLayout* aBtnLayout = new QVBoxLayout(aButtonsWgt);
298   aBtnLayout->setContentsMargins(0, 0, 0, 0);
299   aCtrlLayout->addWidget(aButtonsWgt);
300
301   aBtnLayout->addStretch(1);
302   QPushButton* aAddButton = new QPushButton(QIcon(":pictures/arrow-right.png"), "", aButtonsWgt);
303   connect(aAddButton, SIGNAL(clicked(bool)), SLOT(onAddItem()));
304   aBtnLayout->addWidget(aAddButton);
305
306   aBtnLayout->addSpacing(20);
307
308   QPushButton* aDelButton = new QPushButton(QIcon(":pictures/arrow-left.png"), "", aButtonsWgt);
309   connect(aDelButton, SIGNAL(clicked(bool)), SLOT(onDelItem()));
310   aBtnLayout->addWidget(aDelButton);
311   aBtnLayout->addStretch(1);
312
313   // Right list
314   QWidget* aItemsWgt = new QWidget(aControlsWgt);
315   QVBoxLayout* aItemsLay = new QVBoxLayout(aItemsWgt);
316   aItemsLay->setContentsMargins(0, 0, 0, 0);
317   aCtrlLayout->addWidget(aItemsWgt);
318
319   aItemsLay->addWidget(new QLabel(tr("In the toolbar:"), aItemsWgt));
320   myItemsList = new QListWidget(aItemsWgt);
321   myItemsList->setSortingEnabled(false);
322   foreach(int aId, theItemsList) {
323     myItemsList->addItem(new SHAPERGUI_CommandIdItem(myItemsList, aId, myModule));
324   }
325   myItemsList->setMaximumWidth(LIST_WIDTH);
326   myItemsList->viewport()->installEventFilter(this);
327   aItemsLay->addWidget(myItemsList);
328
329   // Buttons of right list
330   QWidget* aBtnWgt = new QWidget(aControlsWgt);
331   QVBoxLayout* aBtnLay = new QVBoxLayout(aBtnWgt);
332   aBtnLay->setContentsMargins(0, 0, 0, 0);
333   aCtrlLayout->addWidget(aBtnWgt);
334
335   aBtnLay->addStretch(1);
336   QPushButton* aUpButton = new QPushButton(QIcon(":pictures/arrow-up.png"), "", aBtnWgt);
337   connect(aUpButton, SIGNAL(clicked(bool)), SLOT(onUp()));
338   aBtnLay->addWidget(aUpButton);
339
340   aBtnLay->addSpacing(20);
341
342   QPushButton* aDownButton = new QPushButton(QIcon(":pictures/arrow-down.png"), "", aBtnWgt);
343   connect(aDownButton, SIGNAL(clicked(bool)), SLOT(onDown()));
344   aBtnLay->addWidget(aDownButton);
345   aBtnLay->addStretch(1);
346
347   // Buttons part of the dialog
348   QDialogButtonBox* aButtons =
349     new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, this);
350   aMailLayout->addWidget(aButtons);
351   connect(aButtons, SIGNAL(accepted()), SLOT(accept()));
352   connect(aButtons, SIGNAL(rejected()), SLOT(reject()));
353 }
354
355 void SHAPERGUI_ToolbarItemsDlg::onAddItem()
356 {
357   QList<QListWidgetItem*> aCurrentList = myCommandsList->selectedItems();
358   if (aCurrentList.size() > 0) {
359     SHAPERGUI_CommandIdItem* aItem = dynamic_cast<SHAPERGUI_CommandIdItem*>(aCurrentList.first());
360     int aId = aItem->id();
361     if (aId != -1) {
362       myCommandsList->removeItemWidget(aItem);
363       delete aItem;
364     }
365     QModelIndex aIdx = myItemsList->currentIndex();
366     aItem = new SHAPERGUI_CommandIdItem(0, aId, myModule);
367     if (aIdx.isValid()) {
368       int aRow = aIdx.row();
369       myItemsList->insertItem(aRow, aItem);
370     }
371     else {
372       myItemsList->addItem(aItem);
373     }
374   }
375 }
376
377 void SHAPERGUI_ToolbarItemsDlg::onDelItem()
378 {
379   QList<QListWidgetItem*> aCurrentList = myItemsList->selectedItems();
380   if (aCurrentList.size() > 0) {
381     SHAPERGUI_CommandIdItem* aItem = dynamic_cast<SHAPERGUI_CommandIdItem*>(aCurrentList.first());
382     int aId = aItem->id();
383     myItemsList->removeItemWidget(aItem);
384     delete aItem;
385     if (aId != -1) {
386       aItem = new SHAPERGUI_CommandIdItem(myCommandsList, aId, myModule);
387       myCommandsList->addItem(aItem);
388     }
389   }
390 }
391
392
393 bool SHAPERGUI_ToolbarItemsDlg::eventFilter(QObject* theObj, QEvent* theEvent)
394 {
395   if (theEvent->type() == QEvent::MouseButtonRelease) {
396     QMouseEvent* aMouseEvent = (QMouseEvent*)theEvent;
397     QModelIndex aIdx = myItemsList->indexAt(aMouseEvent->pos());
398     if (!aIdx.isValid() || aMouseEvent->button() == Qt::RightButton) {
399       myItemsList->setCurrentIndex(QModelIndex());
400     }
401   }
402   return QDialog::eventFilter(theObj, theEvent);
403 }
404
405 void SHAPERGUI_ToolbarItemsDlg::onUp()
406 {
407   QModelIndex aCurrentIdx = myItemsList->currentIndex();
408   if (aCurrentIdx.isValid()) {
409     int aRow = aCurrentIdx.row();
410     if (aRow > 0) {
411       QListWidgetItem* aItem = myItemsList->takeItem(aRow);
412       aRow--;
413       myItemsList->insertItem(aRow, aItem);
414       myItemsList->setCurrentRow(aRow);
415     }
416   }
417 }
418
419 void SHAPERGUI_ToolbarItemsDlg::onDown()
420 {
421   QModelIndex aCurrentIdx = myItemsList->currentIndex();
422   if (aCurrentIdx.isValid()) {
423     int aNb = myItemsList->count();
424     int aRow = aCurrentIdx.row();
425     if (aRow < (aNb - 1)) {
426       QListWidgetItem* aItem = myItemsList->takeItem(aRow);
427       aRow++;
428       myItemsList->insertItem(aRow, aItem);
429       myItemsList->setCurrentRow(aRow);
430     }
431   }
432 }
433
434 QIntList SHAPERGUI_ToolbarItemsDlg::freeItems() const
435 {
436   return getItems(myCommandsList, 1);
437 }
438
439 QIntList SHAPERGUI_ToolbarItemsDlg::toolbarItems() const
440 {
441   return getItems(myItemsList, 0);
442 }
443
444 QIntList SHAPERGUI_ToolbarItemsDlg::getItems(QListWidget* theWidget, int theStart) const
445 {
446   QIntList aList;
447   SHAPERGUI_CommandIdItem* aItem = 0;
448   int aNb = theWidget->count();
449   for (int i = theStart; i < aNb; i++) {
450     aItem = (SHAPERGUI_CommandIdItem*)theWidget->item(i);
451     aList.append(aItem->id());
452   }
453   return aList;
454 }