Salome HOME
e390a4c366bfff536b443b8810513720ccf1c7f2
[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   myIsReset(false)
85 {
86   myFreeCommands = theModule->getFreeCommands();
87
88   setWindowTitle(tr("Toolbars"));
89   QVBoxLayout* aMailLayout = new QVBoxLayout(this);
90
91   // Controls part of the dialog
92   QWidget* aControlsWgt = new QWidget(this);
93   QHBoxLayout* aContolsLay = new QHBoxLayout(aControlsWgt);
94   aContolsLay->setContentsMargins(0, 0, 0, 0);
95   aMailLayout->addWidget(aControlsWgt);
96
97   // Right controls
98   QWidget* aListWgt = new QWidget(aControlsWgt);
99   QVBoxLayout* aListLayout = new QVBoxLayout(aListWgt);
100   aListLayout->setContentsMargins(0, 0, 0, 0);
101   aContolsLay->addWidget(aListWgt);
102
103   aListLayout->addWidget(new QLabel(tr("Toolbars:"), aListWgt));
104
105   myToolbarsList = new QListWidget(aListWgt);
106   connect(myToolbarsList, SIGNAL(doubleClicked(const QModelIndex&)),
107     SLOT(onDoubleClick(const QModelIndex&)));
108   aListLayout->addWidget(myToolbarsList);
109
110   QWidget* aFreeItemsWgt = new QWidget(aListWgt);
111   QHBoxLayout* aFreeLayout = new QHBoxLayout(aFreeItemsWgt);
112   aFreeLayout->setContentsMargins(0, 0, 0, 0);
113   aListLayout->addWidget(aFreeItemsWgt);
114
115   aFreeLayout->addWidget(new QLabel(tr("Number of commands out of toolbars:"), aFreeItemsWgt));
116   myFreeNbLbl = new QLabel(aFreeItemsWgt);
117   aFreeLayout->addWidget(myFreeNbLbl);
118
119   // Left controls
120   QWidget* aButtonsWgt = new QWidget(aControlsWgt);
121   QVBoxLayout* aBtnLayout = new QVBoxLayout(aButtonsWgt);
122   aBtnLayout->setContentsMargins(0, 0, 0, 0);
123   aContolsLay->addWidget(aButtonsWgt);
124
125   QPushButton* aAddBtn = new QPushButton(tr("Add..."), aButtonsWgt);
126   aAddBtn->setToolTip(tr("Add a new empty toolbar to the toolbars list"));
127   connect(aAddBtn, SIGNAL(clicked(bool)), SLOT(onAdd()));
128   aBtnLayout->addWidget(aAddBtn);
129
130   QPushButton* aEditBtn = new QPushButton(tr("Edit..."), aButtonsWgt);
131   aEditBtn->setToolTip(tr("Edit currently selected toolbar"));
132   connect(aEditBtn, SIGNAL(clicked(bool)), SLOT(onEdit()));
133   aBtnLayout->addWidget(aEditBtn);
134
135   QPushButton* aDeleteBtn = new QPushButton(tr("Delete"), aButtonsWgt);
136   aDeleteBtn->setToolTip(tr("Delete currently selected toolbar"));
137   connect(aDeleteBtn, SIGNAL(clicked(bool)), SLOT(onDelete()));
138   aBtnLayout->addWidget(aDeleteBtn);
139   aBtnLayout->addStretch(1);
140
141   QPushButton* aResetBtn = new QPushButton(tr("Reset"), aButtonsWgt);
142   aResetBtn->setToolTip(tr("Restore default toolbars structure"));
143   connect(aResetBtn, SIGNAL(clicked(bool)), SLOT(onReset()));
144   aBtnLayout->addWidget(aResetBtn);
145   aBtnLayout->addSpacing(19);
146
147   // Buttons part of the dialog
148   QDialogButtonBox* aButtons =
149     new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
150       Qt::Horizontal, this);
151   aMailLayout->addWidget(aButtons);
152   connect(aButtons, SIGNAL(accepted()), SLOT(accept()));
153   connect(aButtons, SIGNAL(rejected()), SLOT(reject()));
154   connect(aButtons, SIGNAL(helpRequested()), SLOT(onHelp()));
155
156   updateToolbarsList();
157   updateNumber();
158 }
159
160 void SHAPERGUI_ToolbarsDlg::onAdd()
161 {
162   QString aNewToolbar =
163     QInputDialog::getText(this, tr("Create toolbar"), tr("Name of a new toolbar"));
164   if (!(aNewToolbar.isNull() || aNewToolbar.isEmpty())) {
165     if (!myResult.contains(aNewToolbar)) {
166       myResult[aNewToolbar] = QIntList();
167       updateToolbarsList();
168       myIsReset = false;
169     }
170     else {
171       QString aMsg = tr("A tool bar with name %1 already exists").arg(aNewToolbar);
172       QMessageBox::warning(this, tr("Create toolbar"), aMsg);
173     }
174   }
175 }
176
177 void SHAPERGUI_ToolbarsDlg::onEdit()
178 {
179   QList<QListWidgetItem*> aSelected = myToolbarsList->selectedItems();
180   if (aSelected.size() == 1) {
181     QString aToolbarName = aSelected.first()->text();
182     int aPos = aToolbarName.lastIndexOf(" (");
183     aToolbarName = aToolbarName.left(aPos);
184
185     SHAPERGUI_ToolbarItemsDlg aDlg(this, myModule,
186       aToolbarName, myFreeCommands, myResult[aToolbarName]);
187     if (aDlg.exec() == QDialog::Accepted) {
188       myFreeCommands = aDlg.freeItems();
189       myResult[aToolbarName] = aDlg.toolbarItems();
190       updateNumber();
191       updateToolbarsList();
192       myIsReset = false;
193     }
194   }
195 }
196
197 void SHAPERGUI_ToolbarsDlg::onDelete()
198 {
199   QList<QListWidgetItem*> aSelected = myToolbarsList->selectedItems();
200   if (aSelected.size() == 1) {
201     QString aToolbarName = aSelected.first()->text();
202     int aPos = aToolbarName.lastIndexOf(" (");
203     aToolbarName = aToolbarName.left(aPos);
204
205     QString aMsg = tr("Toolbar %1 will be deleted. Continue?").arg(aToolbarName);
206     if (QMessageBox::question(this, tr("Delete toolbar"), aMsg) == QMessageBox::Yes) {
207       myFreeCommands.append(myResult[aToolbarName]);
208       // remove separators from free items
209       myFreeCommands.removeAll(-1);
210       myResult.remove(aToolbarName);
211       updateToolbarsList();
212       updateNumber();
213       myIsReset = false;
214     }
215   }
216 }
217
218 void SHAPERGUI_ToolbarsDlg::updateToolbarsList()
219 {
220   myToolbarsList->clear();
221   QStringList aItems;
222   QMap<QString, QIntList>::const_iterator aIt;
223   for (aIt = myResult.cbegin(); aIt != myResult.cend(); aIt++) {
224     aItems.append(aIt.key() + tr(" (%1 commands)").arg(aIt.value().size() - aIt.value().count(-1)));
225   }
226   myToolbarsList->addItems(aItems);
227 }
228
229
230 void SHAPERGUI_ToolbarsDlg::onDoubleClick(const QModelIndex& theIdx)
231 {
232   if (theIdx.isValid())
233     onEdit();
234 }
235
236 void SHAPERGUI_ToolbarsDlg::updateNumber()
237 {
238   myFreeNbLbl->setText(QString::number(myFreeCommands.size()));
239 }
240
241 void SHAPERGUI_ToolbarsDlg::onReset()
242 {
243   myResult = myModule->defaultToolbars();
244   updateNumber();
245   updateToolbarsList();
246   myIsReset = true;
247 }
248
249 void SHAPERGUI_ToolbarsDlg::onHelp()
250 {
251
252 }
253
254
255 //************************************************************************************
256 //************************************************************************************
257 //************************************************************************************
258 SHAPERGUI_ToolbarItemsDlg::SHAPERGUI_ToolbarItemsDlg(QWidget* theParent,
259   SHAPERGUI* theModule,
260   const QString& theToolbar,
261   const QIntList& theFreeItems,
262   const QIntList& theItemsList)
263   : QDialog(theParent),
264   myModule(theModule)
265 {
266   setWindowTitle(tr("Edit toolbar"));
267
268   QVBoxLayout* aMailLayout = new QVBoxLayout(this);
269
270   // Name of toolbar
271   QWidget* aNameWgt = new QWidget(this);
272   QHBoxLayout* aNameLay = new QHBoxLayout(aNameWgt);
273   aNameLay->setContentsMargins(0, 0, 0, 0);
274   aMailLayout->addWidget(aNameWgt);
275
276   aNameLay->addWidget(new QLabel(tr("Toolbar name:"), aNameWgt));
277   QLabel* aNameLbl = new QLabel(theToolbar, aNameWgt);
278   QFont aFont = aNameLbl->font();
279   aFont.setBold(true);
280   aNameLbl->setFont(aFont);
281   aNameLay->addWidget(aNameLbl);
282   aNameLay->addStretch(1);
283
284   // Lists widget
285   QWidget* aControlsWgt = new QWidget(this);
286   QHBoxLayout* aCtrlLayout = new QHBoxLayout(aControlsWgt);
287   aCtrlLayout->setContentsMargins(0, 0, 0, 0);
288   aMailLayout->addWidget(aControlsWgt);
289
290   // Left list
291   QWidget* aCommandsWgt = new QWidget(aControlsWgt);
292   QVBoxLayout* aCommandsLay = new QVBoxLayout(aCommandsWgt);
293   aCommandsLay->setContentsMargins(0, 0, 0, 0);
294   aCtrlLayout->addWidget(aCommandsWgt);
295
296   aCommandsLay->addWidget(new QLabel(tr("Out of toolbars:"), aCommandsWgt));
297   myCommandsList = new QListWidget(aCommandsWgt);
298   myCommandsList->setSortingEnabled(false);
299
300   myCommandsList->addItem(new SHAPERGUI_CommandIdItem(myCommandsList, -1, myModule));
301   foreach(int aId, theFreeItems) {
302     myCommandsList->addItem(new SHAPERGUI_CommandIdItem(myCommandsList, aId, myModule));
303   }
304   myCommandsList->setMaximumWidth(LIST_WIDTH);
305   aCommandsLay->addWidget(myCommandsList);
306
307   // Middle buttons
308   QWidget* aButtonsWgt = new QWidget(aControlsWgt);
309   QVBoxLayout* aBtnLayout = new QVBoxLayout(aButtonsWgt);
310   aBtnLayout->setContentsMargins(0, 0, 0, 0);
311   aCtrlLayout->addWidget(aButtonsWgt);
312
313   aBtnLayout->addStretch(1);
314   QPushButton* aAddButton = new QPushButton(QIcon(":pictures/arrow-right.png"), "", aButtonsWgt);
315   connect(aAddButton, SIGNAL(clicked(bool)), SLOT(onAddItem()));
316   aBtnLayout->addWidget(aAddButton);
317
318   aBtnLayout->addSpacing(20);
319
320   QPushButton* aDelButton = new QPushButton(QIcon(":pictures/arrow-left.png"), "", aButtonsWgt);
321   connect(aDelButton, SIGNAL(clicked(bool)), SLOT(onDelItem()));
322   aBtnLayout->addWidget(aDelButton);
323   aBtnLayout->addStretch(1);
324
325   // Right list
326   QWidget* aItemsWgt = new QWidget(aControlsWgt);
327   QVBoxLayout* aItemsLay = new QVBoxLayout(aItemsWgt);
328   aItemsLay->setContentsMargins(0, 0, 0, 0);
329   aCtrlLayout->addWidget(aItemsWgt);
330
331   aItemsLay->addWidget(new QLabel(tr("In the toolbar:"), aItemsWgt));
332   myItemsList = new QListWidget(aItemsWgt);
333   myItemsList->setSortingEnabled(false);
334   foreach(int aId, theItemsList) {
335     myItemsList->addItem(new SHAPERGUI_CommandIdItem(myItemsList, aId, myModule));
336   }
337   myItemsList->setMaximumWidth(LIST_WIDTH);
338   myItemsList->viewport()->installEventFilter(this);
339   aItemsLay->addWidget(myItemsList);
340
341   // Buttons of right list
342   QWidget* aBtnWgt = new QWidget(aControlsWgt);
343   QVBoxLayout* aBtnLay = new QVBoxLayout(aBtnWgt);
344   aBtnLay->setContentsMargins(0, 0, 0, 0);
345   aCtrlLayout->addWidget(aBtnWgt);
346
347   aBtnLay->addStretch(1);
348   QPushButton* aUpButton = new QPushButton(QIcon(":pictures/arrow-up.png"), "", aBtnWgt);
349   connect(aUpButton, SIGNAL(clicked(bool)), SLOT(onUp()));
350   aBtnLay->addWidget(aUpButton);
351
352   aBtnLay->addSpacing(20);
353
354   QPushButton* aDownButton = new QPushButton(QIcon(":pictures/arrow-down.png"), "", aBtnWgt);
355   connect(aDownButton, SIGNAL(clicked(bool)), SLOT(onDown()));
356   aBtnLay->addWidget(aDownButton);
357   aBtnLay->addStretch(1);
358
359   // Buttons part of the dialog
360   QDialogButtonBox* aButtons =
361     new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
362       Qt::Horizontal, this);
363   aMailLayout->addWidget(aButtons);
364   connect(aButtons, SIGNAL(accepted()), SLOT(accept()));
365   connect(aButtons, SIGNAL(rejected()), SLOT(reject()));
366   connect(aButtons, SIGNAL(helpRequested()), SLOT(onHelp()));
367 }
368
369 void SHAPERGUI_ToolbarItemsDlg::onAddItem()
370 {
371   QList<QListWidgetItem*> aCurrentList = myCommandsList->selectedItems();
372   if (aCurrentList.size() > 0) {
373     SHAPERGUI_CommandIdItem* aItem = dynamic_cast<SHAPERGUI_CommandIdItem*>(aCurrentList.first());
374     int aId = aItem->id();
375     if (aId != -1) {
376       myCommandsList->removeItemWidget(aItem);
377       delete aItem;
378     }
379     QModelIndex aIdx = myItemsList->currentIndex();
380     aItem = new SHAPERGUI_CommandIdItem(0, aId, myModule);
381     if (aIdx.isValid()) {
382       int aRow = aIdx.row();
383       myItemsList->insertItem(aRow, aItem);
384     }
385     else {
386       myItemsList->addItem(aItem);
387     }
388   }
389 }
390
391 void SHAPERGUI_ToolbarItemsDlg::onDelItem()
392 {
393   QList<QListWidgetItem*> aCurrentList = myItemsList->selectedItems();
394   if (aCurrentList.size() > 0) {
395     SHAPERGUI_CommandIdItem* aItem = dynamic_cast<SHAPERGUI_CommandIdItem*>(aCurrentList.first());
396     int aId = aItem->id();
397     myItemsList->removeItemWidget(aItem);
398     delete aItem;
399     if (aId != -1) {
400       aItem = new SHAPERGUI_CommandIdItem(myCommandsList, aId, myModule);
401       myCommandsList->addItem(aItem);
402     }
403   }
404 }
405
406
407 bool SHAPERGUI_ToolbarItemsDlg::eventFilter(QObject* theObj, QEvent* theEvent)
408 {
409   if (theEvent->type() == QEvent::MouseButtonRelease) {
410     QMouseEvent* aMouseEvent = (QMouseEvent*)theEvent;
411     QModelIndex aIdx = myItemsList->indexAt(aMouseEvent->pos());
412     if (!aIdx.isValid() || aMouseEvent->button() == Qt::RightButton) {
413       myItemsList->setCurrentIndex(QModelIndex());
414     }
415   }
416   return QDialog::eventFilter(theObj, theEvent);
417 }
418
419 void SHAPERGUI_ToolbarItemsDlg::onUp()
420 {
421   QModelIndex aCurrentIdx = myItemsList->currentIndex();
422   if (aCurrentIdx.isValid()) {
423     int aRow = aCurrentIdx.row();
424     if (aRow > 0) {
425       QListWidgetItem* aItem = myItemsList->takeItem(aRow);
426       aRow--;
427       myItemsList->insertItem(aRow, aItem);
428       myItemsList->setCurrentRow(aRow);
429     }
430   }
431 }
432
433 void SHAPERGUI_ToolbarItemsDlg::onDown()
434 {
435   QModelIndex aCurrentIdx = myItemsList->currentIndex();
436   if (aCurrentIdx.isValid()) {
437     int aNb = myItemsList->count();
438     int aRow = aCurrentIdx.row();
439     if (aRow < (aNb - 1)) {
440       QListWidgetItem* aItem = myItemsList->takeItem(aRow);
441       aRow++;
442       myItemsList->insertItem(aRow, aItem);
443       myItemsList->setCurrentRow(aRow);
444     }
445   }
446 }
447
448 QIntList SHAPERGUI_ToolbarItemsDlg::freeItems() const
449 {
450   return getItems(myCommandsList, 1);
451 }
452
453 QIntList SHAPERGUI_ToolbarItemsDlg::toolbarItems() const
454 {
455   return getItems(myItemsList, 0);
456 }
457
458 QIntList SHAPERGUI_ToolbarItemsDlg::getItems(QListWidget* theWidget, int theStart) const
459 {
460   QIntList aList;
461   SHAPERGUI_CommandIdItem* aItem = 0;
462   int aNb = theWidget->count();
463   for (int i = theStart; i < aNb; i++) {
464     aItem = (SHAPERGUI_CommandIdItem*)theWidget->item(i);
465     aList.append(aItem->id());
466   }
467   return aList;
468 }
469
470 void SHAPERGUI_ToolbarItemsDlg::onHelp()
471 {
472
473 }