1
2
3 #include "toonzqt/dvdialog.h"
4
5 // TnzQt includes
6 #include "toonzqt/checkbox.h"
7 #include "toonzqt/lineedit.h"
8 #include "toonzqt/fxsettings.h"
9
10 // TnzLib includes
11 #include "toonz/txsheethandle.h"
12 #include "toonz/txshsimplelevel.h"
13 #include "toonz/palettecmd.h"
14 #include "toonz/preferences.h"
15 #include "toonz/toonzfolders.h"
16
17 // TnzCore includes
18 #include "tversion.h"
19
20 // Qt includes
21 #include <QFrame>
22 #include <QLayout>
23 #include <QLabel>
24 #include <QPushButton>
25 #include <QApplication>
26 #include <QStyle>
27 #include <QButtonGroup>
28 #include <QPainter>
29 #include <QRadioButton>
30 #include <QThread>
31 #include <QDesktopWidget>
32 #include <QCheckBox>
33
34 #include <algorithm>
35
36 using namespace DVGui;
37
38 //=============================================================================
39 namespace {
getMsgBoxPixmap(MsgType type)40 QPixmap getMsgBoxPixmap(MsgType type) {
41 int iconSize =
42 QApplication::style()->pixelMetric(QStyle::PM_MessageBoxIconSize);
43 QIcon msgBoxIcon;
44
45 switch (type) {
46 case DVGui::INFORMATION:
47 msgBoxIcon =
48 QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
49 break;
50 case DVGui::WARNING:
51 msgBoxIcon =
52 QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning);
53 break;
54 case DVGui::CRITICAL:
55 msgBoxIcon =
56 QApplication::style()->standardIcon(QStyle::SP_MessageBoxCritical);
57 break;
58 case DVGui::QUESTION:
59 msgBoxIcon =
60 QApplication::style()->standardIcon(QStyle::SP_MessageBoxQuestion);
61 break;
62 default:
63 break;
64 }
65
66 if (!msgBoxIcon.isNull()) return msgBoxIcon.pixmap(iconSize, iconSize);
67 return QPixmap();
68 }
69
70 //-----------------------------------------------------------------------------
71
getMsgBoxTitle(MsgType type)72 QString getMsgBoxTitle(MsgType type) {
73 TVER::ToonzVersion tver;
74 QString title = QString::fromStdString(tver.getAppName() + " " +
75 tver.getAppVersionString() + " - ");
76
77 switch (type) {
78 case DVGui::INFORMATION:
79 title.append(QObject::tr("Information"));
80 break;
81 case DVGui::WARNING:
82 title.append(QObject::tr("Warning"));
83 break;
84 case DVGui::CRITICAL:
85 title.append(QObject::tr("Critical"));
86 break;
87 case DVGui::QUESTION:
88 title.append(QObject::tr("Question"));
89 break;
90 default:
91 break;
92 }
93 return title;
94 }
95
96 //-----------------------------------------------------------------------------
97 } // namespace
98 //-----------------------------------------------------------------------------
99
100 //=============================================================================
101 // Separator
102 //-----------------------------------------------------------------------------
103
Separator(QString name,QWidget * parent,bool isHorizontal)104 Separator::Separator(QString name, QWidget *parent, bool isHorizontal)
105 : QFrame(parent), m_name(name), m_isHorizontal(isHorizontal) {
106 // if(m_name.isEmpty())
107 // setMinimumSize(1,1);
108 // else
109 setMinimumSize(1, 15);
110 }
111
112 //-----------------------------------------------------------------------------
113
~Separator()114 Separator::~Separator() {}
115
116 //-----------------------------------------------------------------------------
117
paintEvent(QPaintEvent *)118 void Separator::paintEvent(QPaintEvent *) {
119 QPainter p(this);
120 ParamsPage *page = dynamic_cast<ParamsPage *>(parentWidget());
121 if (!page)
122 p.setPen(palette().alternateBase().color());
123 else
124 p.setPen(page->getTextColor());
125
126 QRect contents(contentsRect());
127
128 int textWidth = p.fontMetrics().width(m_name);
129
130 p.drawText(contents.left(), 10, m_name);
131
132 // make the line semi-transparent
133 QColor lineColor = Qt::black;
134 lineColor.setAlpha(128);
135
136 p.setPen(lineColor);
137 int h = contents.height();
138 if (m_isHorizontal) {
139 int y = contents.center().y();
140 int space = (textWidth == 0) ? 0 : 8;
141 p.drawLine(textWidth + space, y, contents.width(), y);
142 } else {
143 double w = width();
144 int space = (textWidth == 0) ? 0 : 2;
145 int x0 = (w > textWidth) ? w * 0.5 : (double)textWidth * 0.5;
146 int textHeghit = (space == 0) ? 0 : p.fontMetrics().height();
147 p.drawLine(x0, textHeghit + space, x0, contents.bottom());
148 }
149 }
150
151 //=============================================================================
152 /*! \class DVGui::Dialog
153 \brief The Dialog class is the base class of dialog windows.
154
155 Inherits \b QDialog.
156
157 A dialog window is a top-level window, defined in \b QDialog,
158 this class provides
159 a collection of functions to manage \b QDialog widget
160 visualization.
161 Dialog window can be modal or modeless, from this it depends
162 dialog visualization.
163 You set your dialog to modal or modeless directly in
164 constructor, with \b bool
165 hasButton, in fact if the dialog has button then is modal too.
166
167 If dialog is \b modal it's composed of two part, two \b QFrame;
168 the first, \b main
169 \b part at top of dialog, contains a vertical box layout \b
170 QVBoxLayout, the second,
171 \b button \b part at bottom, contains an horizontal box layout
172 \b QHBoxLayout.
173 Else if dialog is modeless it is composed only of first part, to
174 be more precise,
175 it is composed of a \b QFrame containing a vertical box layout
176 \b QVBoxLayout.
177
178 The first part of dialog can be implemented using different
179 objects. You can manage
180 directly vertical box layout, insert widget addWidget(), or
181 layout addLayout(), set
182 border and spacing, using setTopMargin() and setTopSpacing(), or
183 insert a spece,
184 addSpacing().
185 \n If you need an horizontal layout you can use an implemented horizontal
186 box layout;
187 the function beginHLayout() initialize the horizontal box
188 layout, a collection of
189 function permit to insert object in this layout; at the end you
190 must recall
191 endVLayout(), this add horizontal layout to first part of
192 dialog.
193 This struct permit you to allign the object you insert.
194 \n If you need vertical layout you can use an implemented vertical box
195 layout composed
196 of two column, the function beginVLayout() initialize the
197 vertical box layout,
198 a collection of function permit to insert object in this layout.
199 All this functions insert a pair of object in two vertical
200 layout and permit
201 to allign the objects, all pairs you insert are tabulated.
202 At the end you must recall endVLayout(), this add vertical
203 layout to first part of
204 dialog.
205
206 The second part of dialog may be implemented if dialog is modal.
207 It's possible insert one, two or three widget in its horizontal
208 box layout using
209 addButtonBarWidget(), or clear all widget using
210 clearButtonBar(). You can also
211 set margin and spacing with setButtonBarMargin() and
212 setButtonBarSpacing() functions.
213 */
214 //-----------------------------------------------------------------------------
215
216 namespace {
217 QString settingsPath;
218 };
219
Dialog(QWidget * parent,bool hasButton,bool hasFixedSize,const QString & name)220 Dialog::Dialog(QWidget *parent, bool hasButton, bool hasFixedSize,
221 const QString &name)
222 : QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowTitleHint |
223 Qt::WindowCloseButtonHint)
224 , m_hasButton(hasButton)
225 , m_mainHLayout(0)
226 , m_leftVLayout(0)
227 , m_rightVLayout(0)
228 , m_isMainVLayout(false)
229 , m_isMainHLayout(false)
230 , m_layoutSpacing(5)
231 , m_layoutMargin(0)
232 , m_labelWidth(100)
233 , m_name() {
234 QVBoxLayout *mainLayout = new QVBoxLayout;
235 mainLayout->setMargin(0);
236 mainLayout->setSpacing(0);
237 m_mainFrame = new QFrame(this);
238 m_mainFrame->setObjectName("dialogMainFrame");
239 m_mainFrame->setMinimumHeight(41);
240 m_mainFrame->setFrameStyle(QFrame::StyledPanel);
241 m_topLayout = new QVBoxLayout;
242 m_topLayout->setMargin(12);
243 m_topLayout->setSpacing(m_layoutSpacing);
244 m_topLayout->setAlignment(Qt::AlignCenter);
245 m_mainFrame->setLayout(m_topLayout);
246
247 mainLayout->addWidget(m_mainFrame);
248
249 if (m_hasButton) {
250 // The dialog is modal
251 setModal(true);
252
253 m_buttonFrame = new QFrame(this);
254 m_buttonFrame->setObjectName("dialogButtonFrame");
255 m_buttonFrame->setFrameStyle(QFrame::StyledPanel);
256 m_buttonFrame->setFixedHeight(45);
257
258 m_buttonLayout = new QHBoxLayout;
259 m_buttonLayout->setMargin(0);
260 m_buttonLayout->setSpacing(20);
261 m_buttonLayout->setAlignment(Qt::AlignHCenter);
262
263 QVBoxLayout *buttonFrameLayout = new QVBoxLayout;
264 buttonFrameLayout->setAlignment(Qt::AlignVCenter);
265 buttonFrameLayout->addLayout(m_buttonLayout);
266 m_buttonFrame->setLayout(buttonFrameLayout);
267
268 mainLayout->addWidget(m_buttonFrame);
269 }
270
271 if (hasFixedSize)
272 mainLayout->setSizeConstraint(QLayout::SetFixedSize);
273 else
274 mainLayout->setSizeConstraint(QLayout::SetMinimumSize);
275
276 setLayout(mainLayout);
277 // this->setGeometry(30, 30, 300, 300);
278 #ifdef MACOSX
279 setWindowFlags(Qt::Tool);
280 #endif
281
282 if (settingsPath.isEmpty()) {
283 TFilePath savePath =
284 ToonzFolder::getMyModuleDir() + TFilePath("popups.ini");
285 settingsPath = QString::fromStdWString(savePath.getWideString());
286 }
287
288 QSettings settings(settingsPath, QSettings::IniFormat);
289
290 if (name == QString()) return;
291 m_name = name + "DialogGeometry";
292 QString geo = settings.value(m_name).toString();
293 if (geo != QString()) {
294 QStringList values = geo.split(" ");
295 assert(values.size() == 4);
296 // Ensure that the dialog is visible in the screen.
297 // The dialog opens with some offset to bottom-right direction
298 // if a flag Qt::WindowMaximizeButtonHint is set. (e.g. PencilTestPopup)
299 // Therefore, if the dialog is moved to the bottom-end of the screen,
300 // it will be got out of the screen on the next launch.
301 // The following position adjustment will also prevent such behavior.
302
303 // try and get active screen
304 if (parent != NULL) {
305 m_currentScreen = QApplication::desktop()->screenNumber(parent);
306 }
307 QRect screen = QApplication::desktop()->availableGeometry(m_currentScreen);
308 int x = values.at(0).toInt();
309 int y = values.at(1).toInt();
310
311 // make sure that the window is visible on the screen
312 // all popups will popup on the active window the first time
313 // so popups moved to other monitors will be moved back
314 // when restarting OpenToonz.
315
316 // This may be somewhat annoying if a user REALLY wants the popup
317 // on another monitor by default, but this is better than
318 // a user thinking the program is broken because they didn't notice
319 // the popup on another monitor
320 if (x > screen.right() - 50) x = screen.right() - 50;
321 if (x < screen.left()) x = screen.left();
322 if (y > screen.bottom() - 90) y = screen.bottom() - 90;
323 if (y < screen.top()) y = screen.top();
324 setGeometry(x, y, values.at(2).toInt(), values.at(3).toInt());
325 settings.setValue(m_name, QString::number(x) + " " + QString::number(y) +
326 " " + QString::number(values.at(2).toInt()) +
327 " " + QString::number(values.at(3).toInt()));
328 }
329 }
330
331 //-----------------------------------------------------------------------------
332
~Dialog()333 Dialog::~Dialog() {
334 if (m_name == QString()) return;
335
336 QRect r = geometry();
337 QSettings settings(settingsPath, QSettings::IniFormat);
338 settings.setValue(m_name, QString::number(r.left()) + " " +
339 QString::number(r.top()) + " " +
340 QString::number(r.width()) + " " +
341 QString::number(r.height()));
342 }
343
344 //---------------------------------------------------------------------------------
345
resizeEvent(QResizeEvent * e)346 void Dialog::resizeEvent(QResizeEvent *e) {
347 if (Preferences::instance()->getCurrentLanguage() != "English") {
348 QSize t = this->size();
349 for (QLabel *s : m_labelList) s->setFixedWidth(t.width() * .35);
350 }
351 }
352
353 //-----------------------------------------------------------------------------
354
355 //! By default, QDialogs always reset position/size upon hide events. However,
356 //! we want to prevent such behaviour on Toonz Dialogs - this method is
357 //! reimplemented
358 //! for this purpose.
hideEvent(QHideEvent * event)359 void Dialog::hideEvent(QHideEvent *event) {
360 int x = pos().rx();
361 int y = pos().ry();
362 // make sure the dialog is actually visible on a screen
363 int screenCount = QApplication::desktop()->screenCount();
364 int currentScreen;
365 for (int i = 0; i < screenCount; i++) {
366 if (QApplication::desktop()->screenGeometry(i).contains(pos())) {
367 currentScreen = i;
368 break;
369 } else {
370 // if not - put it back on the main window
371 currentScreen = m_currentScreen;
372 }
373 }
374 QRect screen = QApplication::desktop()->availableGeometry(currentScreen);
375
376 if (x > screen.right() - 50) x = screen.right() - 50;
377 if (x < screen.left()) x = screen.left();
378 if (y > screen.bottom() - 90) y = screen.bottom() - 90;
379 if (y < screen.top()) y = screen.top();
380 move(QPoint(x, y));
381 resize(size());
382 QRect r = geometry();
383 QSettings settings(settingsPath, QSettings::IniFormat);
384 settings.setValue(m_name, QString::number(r.left()) + " " +
385 QString::number(r.top()) + " " +
386 QString::number(r.width()) + " " +
387 QString::number(r.height()));
388 emit dialogClosed();
389 }
390
391 //-----------------------------------------------------------------------------
392 /*! Create the new layouts (2 Vertical) for main part of dialog.
393 */
beginVLayout()394 void Dialog::beginVLayout() {
395 m_isMainVLayout = true;
396
397 m_leftVLayout = new QVBoxLayout;
398 m_leftVLayout->setMargin(m_layoutMargin);
399 m_leftVLayout->setSpacing(m_layoutSpacing);
400
401 m_rightVLayout = new QVBoxLayout;
402 m_rightVLayout->setMargin(m_layoutMargin);
403 m_rightVLayout->setSpacing(m_layoutSpacing);
404 }
405
406 //-----------------------------------------------------------------------------
407 /*! Add to main part of dialog the Vertical Layouts ,insert them in a orizontal
408 layout to form two column, set Vertical Layouts to 0 .
409 */
endVLayout()410 void Dialog::endVLayout() {
411 if (!m_leftVLayout || !m_rightVLayout) return;
412 m_isMainVLayout = false;
413
414 QHBoxLayout *layout = new QHBoxLayout;
415 layout->setMargin(m_layoutMargin);
416 layout->setSpacing(m_layoutSpacing);
417 layout->setSizeConstraint(QLayout::SetFixedSize);
418
419 layout->addLayout(m_leftVLayout);
420 layout->setAlignment(m_leftVLayout, Qt::AlignLeft);
421 layout->addLayout(m_rightVLayout);
422 layout->setAlignment(m_rightVLayout, Qt::AlignLeft);
423
424 addLayout(layout);
425
426 m_leftVLayout = 0;
427 m_rightVLayout = 0;
428 }
429
430 //-----------------------------------------------------------------------------
431 /*! Create a new Horizontal Layout for main part of dialog.
432 */
beginHLayout()433 void Dialog::beginHLayout() {
434 m_isMainHLayout = true;
435 m_mainHLayout = new QHBoxLayout;
436 m_mainHLayout->setMargin(m_layoutMargin);
437 m_mainHLayout->setSpacing(m_layoutSpacing);
438 }
439
440 //-----------------------------------------------------------------------------
441 /*! Add to main part of dialog the Horizontal Layout and set it to 0.
442 */
endHLayout()443 void Dialog::endHLayout() {
444 m_isMainHLayout = false;
445 if (!m_mainHLayout) return;
446 addLayout(m_mainHLayout);
447 m_mainHLayout = 0;
448 }
449
450 //-----------------------------------------------------------------------------
451 /*! Add a widget \b widget to main part of dialog. If vertical layout is
452 initialized add widget in right column if \b isRight is true,
453 otherwise in
454 left column. \b isRight by default is true.
455 */
addWidget(QWidget * widget,bool isRight)456 void Dialog::addWidget(QWidget *widget, bool isRight) {
457 if (m_isMainVLayout) {
458 assert(m_leftVLayout && m_rightVLayout);
459 QWidget *w = new QWidget();
460 int h = widget->height() + m_layoutSpacing;
461 if (isRight) {
462 m_leftVLayout->addSpacing(h);
463 m_rightVLayout->addWidget(widget);
464 } else {
465 m_leftVLayout->addWidget(widget, 1, Qt::AlignRight);
466 m_rightVLayout->addSpacing(h);
467 }
468 return;
469 } else if (m_isMainHLayout) {
470 assert(m_mainHLayout);
471 m_mainHLayout->addWidget(widget);
472 return;
473 }
474 m_topLayout->addWidget(widget);
475 }
476
477 //-----------------------------------------------------------------------------
478 /*! Add a pair [widget,widget] to main part of dialog.
479 \n If vertical and horizontal layout are not initialized create an
480 horizontal
481 box layout containing the two widgets and recall \b addLayout().
482 If vertical layout is current add the pair to vertical layout of
483 main part,
484 \b firstW on first column and \b secondW on second column.
485 Else if horizontal layout is current create an horizontal box
486 layout containing
487 \b firstW and \b secondW and add it to horizontal layout.
488 */
addWidgets(QWidget * firstW,QWidget * secondW)489 void Dialog::addWidgets(QWidget *firstW, QWidget *secondW) {
490 if (m_isMainVLayout) {
491 assert(m_leftVLayout && m_rightVLayout);
492 m_leftVLayout->addWidget(firstW);
493 m_rightVLayout->addWidget(secondW);
494 return;
495 }
496 QHBoxLayout *pairLayout = new QHBoxLayout;
497 pairLayout->setMargin(m_layoutMargin);
498 pairLayout->setSpacing(m_layoutSpacing);
499 pairLayout->addWidget(firstW);
500 pairLayout->addWidget(secondW);
501
502 if (m_isMainHLayout) {
503 assert(m_mainHLayout);
504 m_mainHLayout->addLayout(pairLayout);
505 return;
506 }
507 addLayout(pairLayout);
508 }
509
510 //-----------------------------------------------------------------------------
511 /*! Add a pair [label,widget] to main part of dialog, label is created from
512 \b QString \b nameLabel.
513 \n Recall \b addWidgets(QWdiget* firstW, QWdiget* secondW).
514 */
addWidget(QString labelName,QWidget * widget)515 void Dialog::addWidget(QString labelName, QWidget *widget) {
516 QLabel *label = new QLabel(labelName);
517 m_labelList.push_back(label);
518 label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
519 label->setFixedSize(m_labelWidth, widget->height());
520 addWidgets(label, widget);
521 }
522
523 //-----------------------------------------------------------------------------
524 /*! Add a layout \b layout to main part of dialog. If vertical layout is
525 initialized add widget in right column if \b isRight is true,
526 otherwise in
527 left column. \b isRight by default is true.
528 */
addLayout(QLayout * layout,bool isRight)529 void Dialog::addLayout(QLayout *layout, bool isRight) {
530 if (m_isMainVLayout) {
531 assert(m_leftVLayout && m_rightVLayout);
532 int h = layout->itemAt(0)->widget()->height() + m_layoutSpacing;
533 if (isRight) {
534 m_leftVLayout->addSpacing(h);
535 m_rightVLayout->addLayout(layout);
536 } else {
537 m_leftVLayout->addLayout(layout);
538 m_rightVLayout->addSpacing(h);
539 }
540 return;
541 } else if (m_isMainHLayout) {
542 assert(m_mainHLayout);
543 m_mainHLayout->addLayout(layout);
544 return;
545 }
546 m_topLayout->addLayout(layout);
547 }
548
549 //-----------------------------------------------------------------------------
550 /*! Add a pair [widget,layout] to main part of dialog.
551 \n If vertical and horizontal layout are not initialized create an
552 horizontal
553 box layout containing \b widget and \b layout and recall \b
554 addLayout().
555 If vertical layout is current add the pair [label,layout] to
556 vertical layout
557 of main part, label on first column and layout on second column.
558 Else if horizontal layout is current create an horizontal box
559 layout containing
560 \b widget and \b layout and add it to horizontal layout.
561 */
addWidgetLayout(QWidget * widget,QLayout * layout)562 void Dialog::addWidgetLayout(QWidget *widget, QLayout *layout) {
563 layout->setMargin(m_layoutMargin);
564 layout->setSpacing(m_layoutSpacing);
565
566 if (m_isMainVLayout) {
567 assert(m_leftVLayout && m_rightVLayout);
568 m_leftVLayout->addWidget(widget);
569 m_rightVLayout->addLayout(layout);
570 return;
571 }
572
573 QHBoxLayout *pairLayout = new QHBoxLayout;
574 pairLayout->setMargin(m_layoutMargin);
575 pairLayout->setSpacing(m_layoutSpacing);
576 pairLayout->addWidget(widget);
577 pairLayout->addLayout(layout);
578
579 if (m_isMainHLayout) {
580 assert(m_mainHLayout);
581 m_mainHLayout->addLayout(pairLayout);
582 return;
583 }
584
585 addLayout(pairLayout);
586 }
587
588 //-----------------------------------------------------------------------------
589 /*! Add a pair [label,layout] to main part of dialog, label is created from
590 \b QString \b nameLabel.
591 \n Recall \b addWidgetLayout(QWdiget* widget, QWdiget* layout).
592 */
addLayout(QString labelName,QLayout * layout)593 void Dialog::addLayout(QString labelName, QLayout *layout) {
594 QLabel *label = new QLabel(labelName);
595 m_labelList.push_back(label);
596 label->setFixedWidth(m_labelWidth);
597 label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
598 addWidgetLayout(label, layout);
599 }
600
601 //-----------------------------------------------------------------------------
602 /*! Add a pair [layout,layout] to main part of dialog.
603 \n If vertical and horizontal layout are not initialized create an
604 horizontal
605 box layout containing the two layouts and recall \b addLayout().
606 If vertical layout is current add the pair [layout,layout] to
607 vertical layout
608 of main part, \b firstL on first column and \b secondL on second
609 column.
610 Else if horizontal layout is current create an horizontal box
611 layout containing
612 \b firstL and \b secondL and add it to horizontal layout.
613 */
addLayouts(QLayout * firstL,QLayout * secondL)614 void Dialog::addLayouts(QLayout *firstL, QLayout *secondL) {
615 firstL->setMargin(m_layoutMargin);
616 firstL->setSpacing(m_layoutSpacing);
617 secondL->setMargin(m_layoutMargin);
618 secondL->setSpacing(m_layoutSpacing);
619
620 if (m_isMainVLayout) {
621 assert(m_leftVLayout && m_rightVLayout);
622 m_leftVLayout->addLayout(firstL);
623 m_rightVLayout->addLayout(secondL);
624 return;
625 }
626
627 QHBoxLayout *pairLayout = new QHBoxLayout;
628 pairLayout->setMargin(m_layoutMargin);
629 pairLayout->setSpacing(m_layoutSpacing);
630 pairLayout->addLayout(firstL);
631 pairLayout->addLayout(secondL);
632
633 if (m_isMainHLayout) {
634 assert(m_mainHLayout);
635 m_mainHLayout->addLayout(pairLayout);
636 return;
637 }
638
639 addLayout(pairLayout);
640 }
641
642 //-----------------------------------------------------------------------------
643 /*! Add spacing \b spacing to main part of dialog.
644 */
addSpacing(int spacing)645 void Dialog::addSpacing(int spacing) {
646 if (m_isMainVLayout) {
647 assert(m_leftVLayout && m_rightVLayout);
648 m_leftVLayout->addSpacing(spacing);
649 m_rightVLayout->addSpacing(spacing);
650 return;
651 } else if (m_isMainHLayout) {
652 assert(m_mainHLayout);
653 m_mainHLayout->addSpacing(spacing);
654 return;
655 }
656 m_topLayout->addSpacing(spacing);
657 }
658
659 //-----------------------------------------------------------------------------
660 /*! Add a separator \b Separator to main part of dialog.
661 If vertical layout is initialized add an horizontal separator.
662 If horizontal layout is initialized add a vertical separator.
663 */
addSeparator(QString name)664 void Dialog::addSeparator(QString name) {
665 Separator *separator = new Separator(name);
666 if (m_isMainVLayout) {
667 assert(m_leftVLayout && m_rightVLayout);
668 endVLayout();
669 addWidget(separator);
670 beginVLayout();
671 return;
672 } else if (m_isMainHLayout) {
673 assert(m_mainHLayout);
674 separator->setOrientation(false);
675 m_mainHLayout->addWidget(separator);
676 return;
677 }
678 addWidget(separator);
679 }
680
681 //-----------------------------------------------------------------------------
682 /*! Set the alignement of the main layout
683 */
setAlignment(Qt::Alignment alignment)684 void Dialog::setAlignment(Qt::Alignment alignment) {
685 m_mainFrame->layout()->setAlignment(alignment);
686 }
687
688 //-----------------------------------------------------------------------------
689 /*! Set to \b spacing spacing of main part of dialog.
690 */
setTopSpacing(int spacing)691 void Dialog::setTopSpacing(int spacing) {
692 m_layoutSpacing = spacing;
693 m_topLayout->setSpacing(spacing);
694 }
695 //-----------------------------------------------------------------------------
696
setLabelWidth(int labelWidth)697 void Dialog::setLabelWidth(int labelWidth) { m_labelWidth = labelWidth; }
698
699 //-----------------------------------------------------------------------------
700 /*! Set to \b spacing spacing of all layout inserted in main part of dialog,
701 horizontal layout and vertical layout.
702 */
setLayoutInsertedSpacing(int spacing)703 void Dialog::setLayoutInsertedSpacing(int spacing) {
704 m_layoutSpacing = spacing;
705 }
706
707 //-----------------------------------------------------------------------------
708 /*! Return the spacing of all layout inserted in main part of dialog,
709 horizontal layout and vertical layout.
710 */
getLayoutInsertedSpacing()711 int Dialog::getLayoutInsertedSpacing() { return m_layoutSpacing; }
712
713 //-----------------------------------------------------------------------------
714 /*! Set to \b margin margin of main part of dialog.
715 */
setTopMargin(int margin)716 void Dialog::setTopMargin(int margin) { m_topLayout->setMargin(margin); }
717
718 //-----------------------------------------------------------------------------
719 /*! Set to \b margin margin of button part of dialog.
720 */
setButtonBarMargin(int margin)721 void Dialog::setButtonBarMargin(int margin) {
722 m_buttonLayout->setMargin(margin);
723 }
724
725 //-----------------------------------------------------------------------------
726 /*! Set to \b spacing spacing of button part of dialog.
727 */
setButtonBarSpacing(int spacing)728 void Dialog::setButtonBarSpacing(int spacing) {
729 m_buttonLayout->setSpacing(spacing);
730 }
731
732 //-----------------------------------------------------------------------------
733 /*! Add a widget to the button part of dialog.
734 */
addButtonBarWidget(QWidget * widget)735 void Dialog::addButtonBarWidget(QWidget *widget) {
736 widget->setMinimumSize(65, 25);
737 assert(m_hasButton);
738 if (m_hasButton) {
739 m_buttonLayout->addWidget(widget);
740 m_buttonBarWidgets.push_back(widget);
741 }
742 }
743
744 //-----------------------------------------------------------------------------
745 /*! Remove all widget from the button part of dialog.
746 */
clearButtonBar()747 void Dialog::clearButtonBar() {
748 for (int i = 0; i < (int)m_buttonBarWidgets.size(); i++) {
749 m_buttonLayout->removeWidget(m_buttonBarWidgets[i]);
750 }
751 m_buttonBarWidgets.clear();
752 }
753
754 //-----------------------------------------------------------------------------
755 /*! Add two widget to the button part of dialog.
756 */
addButtonBarWidget(QWidget * first,QWidget * second)757 void Dialog::addButtonBarWidget(QWidget *first, QWidget *second) {
758 first->setMinimumSize(65, 25);
759 second->setMinimumSize(65, 25);
760 assert(m_hasButton);
761 if (m_hasButton) {
762 m_buttonLayout->addWidget(first);
763 m_buttonLayout->addWidget(second);
764 }
765 }
766
767 //-----------------------------------------------------------------------------
768 /*! Add three widget to the button part of dialog.
769 */
addButtonBarWidget(QWidget * first,QWidget * second,QWidget * third)770 void Dialog::addButtonBarWidget(QWidget *first, QWidget *second,
771 QWidget *third) {
772 first->setMinimumSize(65, 25);
773 second->setMinimumSize(65, 25);
774 third->setMinimumSize(65, 25);
775 assert(m_hasButton);
776 if (m_hasButton) {
777 m_buttonLayout->addWidget(first);
778 m_buttonLayout->addWidget(second);
779 m_buttonLayout->addWidget(third);
780 }
781 }
782
783 //-----------------------------------------------------------------------------
784 /*! Add four widget to the button part of dialog.
785 */
addButtonBarWidget(QWidget * first,QWidget * second,QWidget * third,QWidget * fourth)786 void Dialog::addButtonBarWidget(QWidget *first, QWidget *second, QWidget *third,
787 QWidget *fourth) {
788 first->setMinimumSize(65, 25);
789 second->setMinimumSize(65, 25);
790 third->setMinimumSize(65, 25);
791 assert(m_hasButton);
792 if (m_hasButton) {
793 m_buttonLayout->addWidget(first);
794 m_buttonLayout->addWidget(second);
795 m_buttonLayout->addWidget(third);
796 m_buttonLayout->addWidget(fourth);
797 }
798 }
799
800 //=============================================================================
801
MessageAndCheckboxDialog(QWidget * parent,bool hasButton,bool hasFixedSize,const QString & name,Qt::CheckState checkButtonState)802 MessageAndCheckboxDialog::MessageAndCheckboxDialog(
803 QWidget *parent, bool hasButton, bool hasFixedSize, const QString &name,
804 Qt::CheckState checkButtonState)
805 : Dialog(parent, hasButton, hasFixedSize, name)
806 , m_checked(checkButtonState) {}
807
808 //=============================================================================
809
onButtonPressed(int id)810 void MessageAndCheckboxDialog::onButtonPressed(int id) { done(id); }
811
812 //=============================================================================
813
onCheckboxChanged(int checked)814 void MessageAndCheckboxDialog::onCheckboxChanged(int checked) {
815 m_checked = checked;
816 }
817
818 //=============================================================================
819
RadioButtonDialog(const QString & labelText,const QList<QString> & radioButtonList,QWidget * parent,Qt::WindowFlags f)820 RadioButtonDialog::RadioButtonDialog(const QString &labelText,
821 const QList<QString> &radioButtonList,
822 QWidget *parent, Qt::WindowFlags f)
823 : Dialog(parent, true, true), m_result(1) {
824 setWindowTitle(tr("OpenToonz"));
825
826 setMinimumSize(20, 20);
827
828 beginVLayout();
829
830 QLabel *label = new QLabel(labelText);
831 label->setAlignment(Qt::AlignLeft);
832 label->setFixedHeight(2 * WidgetHeight);
833 addWidget(label);
834
835 QButtonGroup *buttonGroup = new QButtonGroup(this);
836 int i;
837 for (i = 0; i < radioButtonList.count(); i++) {
838 QRadioButton *radioButton = new QRadioButton(radioButtonList.at(i));
839 if (i == m_result - 1) radioButton->setChecked(true);
840 radioButton->setFixedHeight(WidgetHeight);
841 buttonGroup->addButton(radioButton);
842 buttonGroup->setId(radioButton, i);
843 addWidget(radioButton);
844 }
845
846 bool ret = connect(buttonGroup, SIGNAL(buttonClicked(int)),
847 SLOT(onButtonClicked(int)));
848
849 endVLayout();
850
851 QPushButton *applyButton = new QPushButton(QObject::tr("Apply"));
852 ret = ret && connect(applyButton, SIGNAL(pressed()), this, SLOT(onApply()));
853 QPushButton *cancelButton = new QPushButton(QObject::tr("Cancel"));
854 ret = ret && connect(cancelButton, SIGNAL(pressed()), this, SLOT(onCancel()));
855
856 addButtonBarWidget(applyButton, cancelButton);
857
858 assert(ret);
859 }
860
861 //-----------------------------------------------------------------------------
862
onButtonClicked(int id)863 void RadioButtonDialog::onButtonClicked(int id) {
864 // Add "1" because "0" is cancel button.
865 m_result = id + 1;
866 }
867
868 //-----------------------------------------------------------------------------
869
onCancel()870 void RadioButtonDialog::onCancel() { done(0); }
871
872 //-----------------------------------------------------------------------------
873
onApply()874 void RadioButtonDialog::onApply() { done(m_result); }
875
876 //=============================================================================
877
RadioButtonMsgBox(MsgType type,const QString & labelText,const QList<QString> & radioButtonList,QWidget * parent)878 int DVGui::RadioButtonMsgBox(MsgType type, const QString &labelText,
879 const QList<QString> &radioButtonList,
880 QWidget *parent) {
881 RadioButtonDialog *dialog =
882 new RadioButtonDialog(labelText, radioButtonList, parent);
883 QString msgBoxTitle = getMsgBoxTitle(DVGui::WARNING);
884 dialog->setWindowTitle(msgBoxTitle);
885 return dialog->exec();
886 }
887
888 //=============================================================================
889
ProgressDialog(const QString & labelText,const QString & cancelButtonText,int minimum,int maximum,QWidget * parent,Qt::WindowFlags f)890 ProgressDialog::ProgressDialog(const QString &labelText,
891 const QString &cancelButtonText, int minimum,
892 int maximum, QWidget *parent, Qt::WindowFlags f)
893 : Dialog(parent, true, true), m_isCanceled(false) {
894 setWindowTitle(tr("OpenToonz"));
895
896 setMinimumSize(20, 20);
897
898 beginVLayout();
899
900 m_label = new QLabel(this);
901 m_label->setText(labelText);
902 addWidget(m_label);
903
904 m_progressBar = new QProgressBar(this);
905 m_progressBar->setRange(minimum, maximum);
906 m_progressBar->setMinimumWidth(250);
907 addWidget(m_progressBar);
908
909 endVLayout();
910
911 if (!cancelButtonText.isEmpty())
912 setCancelButton(new QPushButton(cancelButtonText));
913 }
914
915 //-----------------------------------------------------------------------------
916
setLabelText(const QString & text)917 void ProgressDialog::setLabelText(const QString &text) {
918 m_label->setText(text);
919 }
920
921 //-----------------------------------------------------------------------------
922
setCancelButton(QPushButton * cancelButton)923 void ProgressDialog::setCancelButton(QPushButton *cancelButton) {
924 m_cancelButton = cancelButton;
925 bool ret = connect(cancelButton, SIGNAL(pressed()), this, SLOT(onCancel()));
926 ret =
927 ret && connect(cancelButton, SIGNAL(pressed()), this, SIGNAL(canceled()));
928 assert(ret);
929 addButtonBarWidget(m_cancelButton);
930 }
931
932 //-----------------------------------------------------------------------------
933
maximum()934 int ProgressDialog::maximum() { return m_progressBar->maximum(); }
935 //-----------------------------------------------------------------------------
936
setMaximum(int maximum)937 void ProgressDialog::setMaximum(int maximum) {
938 m_progressBar->setMaximum(maximum);
939 }
940
941 //-----------------------------------------------------------------------------
942
minimum()943 int ProgressDialog::minimum() { return m_progressBar->minimum(); }
944 //-----------------------------------------------------------------------------
945
setMinimum(int minimum)946 void ProgressDialog::setMinimum(int minimum) {
947 m_progressBar->setMinimum(minimum);
948 }
949
950 //-----------------------------------------------------------------------------
951
value()952 int ProgressDialog::value() { return m_progressBar->value(); }
953
954 //-----------------------------------------------------------------------------
955
setValue(int progress)956 void ProgressDialog::setValue(int progress) {
957 m_progressBar->setValue(progress);
958 if (isModal()) qApp->processEvents();
959 }
960
961 //-----------------------------------------------------------------------------
962
reset()963 void ProgressDialog::reset() { m_progressBar->reset(); }
964
965 //-----------------------------------------------------------------------------
966
wasCanceled() const967 bool ProgressDialog::wasCanceled() const { return m_isCanceled; }
968
969 //-----------------------------------------------------------------------------
970
onCancel()971 void ProgressDialog::onCancel() {
972 m_isCanceled = true;
973 reset();
974 hide();
975 }
976
977 //=============================================================================
978
MsgBox(MsgType type,const QString & text,const std::vector<QString> & buttons,int defaultButtonIndex,QWidget * parent)979 int DVGui::MsgBox(MsgType type, const QString &text,
980 const std::vector<QString> &buttons, int defaultButtonIndex,
981 QWidget *parent) {
982 Dialog dialog(parent, true);
983 dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint);
984 dialog.setAlignment(Qt::AlignLeft);
985 QString msgBoxTitle = getMsgBoxTitle(type);
986
987 dialog.setWindowTitle(msgBoxTitle);
988
989 QLabel *mainTextLabel = new QLabel(text, &dialog);
990 QPixmap iconPixmap = getMsgBoxPixmap(type);
991 if (!iconPixmap.isNull()) {
992 QLabel *iconLabel = new QLabel(&dialog);
993 iconLabel->setPixmap(iconPixmap);
994
995 QHBoxLayout *mainLayout = new QHBoxLayout;
996 mainLayout->addWidget(iconLabel);
997 mainLayout->addSpacing(16);
998 mainLayout->addWidget(mainTextLabel);
999 dialog.addLayout(mainLayout);
1000 } else
1001 dialog.addWidget(mainTextLabel);
1002
1003 // ButtonGroup: is used only to retrieve the clicked button
1004 QButtonGroup *buttonGroup = new QButtonGroup(&dialog);
1005
1006 for (int i = 0; i < (int)buttons.size(); i++) {
1007 QPushButton *button = new QPushButton(buttons[i], &dialog);
1008 if (defaultButtonIndex == i)
1009 button->setDefault(true);
1010 else
1011 button->setDefault(false);
1012 dialog.addButtonBarWidget(button);
1013
1014 buttonGroup->addButton(button, i + 1);
1015 }
1016
1017 QObject::connect(buttonGroup, SIGNAL(buttonPressed(int)), &dialog,
1018 SLOT(done(int)));
1019
1020 dialog.raise();
1021
1022 return dialog.exec();
1023 }
1024
1025 //-----------------------------------------------------------------------------
1026
MsgBoxInPopup(MsgType type,const QString & text)1027 void DVGui::MsgBoxInPopup(MsgType type, const QString &text) {
1028 // this function must be called by the main thread only
1029 // (only the main thread should access directly the GUI)
1030 // (note: working thread can and should call MsgBox(type,text) instead; see
1031 // tmsgcore.h)
1032
1033 Q_ASSERT(QApplication::instance()->thread() == QThread::currentThread());
1034
1035 // a working thread can trigger a call to this function (by the main thread)
1036 // also when a popup is already open
1037 // therefore we need a messageQueue
1038 // note: no mutex are needed because only the main thread call this function
1039 static QList<QPair<MsgType, QString>> messageQueue;
1040 static bool popupIsOpen = false;
1041
1042 messageQueue.append(qMakePair(type, text));
1043 if (popupIsOpen) return;
1044 popupIsOpen = true;
1045
1046 Dialog dialog(0, true);
1047
1048 dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint);
1049 dialog.setAlignment(Qt::AlignLeft);
1050 QLabel *mainTextLabel = new QLabel("", &dialog);
1051 mainTextLabel->setMinimumWidth(400);
1052 QLabel *iconLabel = new QLabel(&dialog);
1053
1054 QHBoxLayout *mainLayout = new QHBoxLayout;
1055 mainLayout->addWidget(iconLabel);
1056 mainLayout->addStretch();
1057 mainLayout->addWidget(mainTextLabel);
1058 mainLayout->addStretch();
1059 dialog.addLayout(mainLayout);
1060
1061 // ButtonGroup: is used only to retrieve the clicked button
1062 QButtonGroup *buttonGroup = new QButtonGroup(&dialog);
1063 QPushButton *button = new QPushButton(QPushButton::tr("OK"), &dialog);
1064 button->setDefault(true);
1065 dialog.addButtonBarWidget(button);
1066 buttonGroup->addButton(button, 1);
1067 QObject::connect(buttonGroup, SIGNAL(buttonPressed(int)), &dialog,
1068 SLOT(done(int)));
1069
1070 while (!messageQueue.empty()) {
1071 MsgType type1 = messageQueue.first().first;
1072 QString text1 = messageQueue.first().second;
1073 messageQueue.pop_front();
1074
1075 mainTextLabel->setText(text1);
1076
1077 QString msgBoxTitle = getMsgBoxTitle(type1);
1078 dialog.setWindowTitle(msgBoxTitle);
1079
1080 QPixmap iconPixmap = getMsgBoxPixmap(type1);
1081 if (!iconPixmap.isNull()) {
1082 iconLabel->setPixmap(iconPixmap);
1083 iconLabel->setVisible(true);
1084 } else {
1085 iconLabel->setVisible(false);
1086 }
1087
1088 dialog.raise();
1089 dialog.exec();
1090
1091 } // loop: open the next dialog in the queue
1092 popupIsOpen = false;
1093 }
1094
1095 //-----------------------------------------------------------------------------
1096
MsgBox(const QString & text,const QString & button1Text,const QString & button2Text,const QString & button3Text,int defaultButtonIndex,QWidget * parent)1097 int DVGui::MsgBox(const QString &text, const QString &button1Text,
1098 const QString &button2Text, const QString &button3Text,
1099 int defaultButtonIndex, QWidget *parent) {
1100 Dialog dialog(parent, true);
1101 dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint);
1102 dialog.setAlignment(Qt::AlignLeft);
1103 QString msgBoxTitle = getMsgBoxTitle(QUESTION);
1104 dialog.setWindowTitle(msgBoxTitle);
1105
1106 QLabel *mainTextLabel = new QLabel(text, &dialog);
1107 QPixmap iconPixmap = getMsgBoxPixmap(QUESTION);
1108 if (!iconPixmap.isNull()) {
1109 QLabel *iconLabel = new QLabel(&dialog);
1110 iconLabel->setPixmap(iconPixmap);
1111
1112 QHBoxLayout *mainLayout = new QHBoxLayout;
1113 mainLayout->addWidget(iconLabel);
1114 mainLayout->addSpacing(16);
1115 mainLayout->addWidget(mainTextLabel);
1116 dialog.addLayout(mainLayout);
1117 } else
1118 dialog.addWidget(mainTextLabel);
1119
1120 // ButtonGroup: is used only to retrieve the clicked button
1121 QButtonGroup *buttonGroup = new QButtonGroup(&dialog);
1122
1123 QPushButton *button1 = new QPushButton(button1Text, &dialog);
1124 button1->setDefault(false);
1125 if (defaultButtonIndex == 0) button1->setDefault(true);
1126 dialog.addButtonBarWidget(button1);
1127 buttonGroup->addButton(button1, 1);
1128
1129 QPushButton *button2 = new QPushButton(button2Text, &dialog);
1130 button2->setDefault(false);
1131 if (defaultButtonIndex == 1) button2->setDefault(true);
1132 dialog.addButtonBarWidget(button2);
1133 buttonGroup->addButton(button2, 2);
1134
1135 QPushButton *button3 = new QPushButton(button3Text, &dialog);
1136 button3->setDefault(false);
1137 if (defaultButtonIndex == 2) button3->setDefault(true);
1138 dialog.addButtonBarWidget(button3);
1139 buttonGroup->addButton(button3, 3);
1140
1141 QObject::connect(buttonGroup, SIGNAL(buttonPressed(int)), &dialog,
1142 SLOT(done(int)));
1143 dialog.raise();
1144 return dialog.exec();
1145 }
1146
1147 //-----------------------------------------------------------------------------
1148
MsgBox(const QString & text,const QString & button1Text,const QString & button2Text,const QString & button3Text,const QString & button4Text,int defaultButtonIndex,QWidget * parent)1149 int DVGui::MsgBox(const QString &text, const QString &button1Text,
1150 const QString &button2Text, const QString &button3Text,
1151 const QString &button4Text, int defaultButtonIndex,
1152 QWidget *parent) {
1153 Dialog dialog(parent, true);
1154 dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint);
1155 dialog.setAlignment(Qt::AlignLeft);
1156 QString msgBoxTitle = getMsgBoxTitle(QUESTION);
1157 dialog.setWindowTitle(msgBoxTitle);
1158
1159 QLabel *mainTextLabel = new QLabel(text, &dialog);
1160 QPixmap iconPixmap = getMsgBoxPixmap(QUESTION);
1161 if (!iconPixmap.isNull()) {
1162 QLabel *iconLabel = new QLabel(&dialog);
1163 iconLabel->setPixmap(iconPixmap);
1164
1165 QHBoxLayout *mainLayout = new QHBoxLayout;
1166 mainLayout->addWidget(iconLabel);
1167 mainLayout->addSpacing(16);
1168 mainLayout->addWidget(mainTextLabel);
1169 dialog.addLayout(mainLayout);
1170 } else
1171 dialog.addWidget(mainTextLabel);
1172
1173 // ButtonGroup: is used only to retrieve the clicked button
1174 QButtonGroup *buttonGroup = new QButtonGroup(&dialog);
1175
1176 QPushButton *button1 = new QPushButton(button1Text, &dialog);
1177 button1->setDefault(false);
1178 if (defaultButtonIndex == 0) button1->setDefault(true);
1179 dialog.addButtonBarWidget(button1);
1180 buttonGroup->addButton(button1, 1);
1181
1182 QPushButton *button2 = new QPushButton(button2Text, &dialog);
1183 button2->setDefault(false);
1184 if (defaultButtonIndex == 1) button2->setDefault(true);
1185 dialog.addButtonBarWidget(button2);
1186 buttonGroup->addButton(button2, 2);
1187
1188 QPushButton *button3 = new QPushButton(button3Text, &dialog);
1189 button3->setDefault(false);
1190 if (defaultButtonIndex == 2) button3->setDefault(true);
1191 dialog.addButtonBarWidget(button3);
1192 buttonGroup->addButton(button3, 3);
1193
1194 QPushButton *button4 = new QPushButton(button4Text, &dialog);
1195 button4->setDefault(false);
1196 if (defaultButtonIndex == 3) button4->setDefault(true);
1197 dialog.addButtonBarWidget(button4);
1198 buttonGroup->addButton(button4, 4);
1199
1200 QObject::connect(buttonGroup, SIGNAL(buttonPressed(int)), &dialog,
1201 SLOT(done(int)));
1202 dialog.raise();
1203 return dialog.exec();
1204 }
1205
1206 //-----------------------------------------------------------------------------
1207
MsgBox(const QString & text,const QString & button1,const QString & button2,int defaultButtonIndex,QWidget * parent)1208 int DVGui::MsgBox(const QString &text, const QString &button1,
1209 const QString &button2, int defaultButtonIndex,
1210 QWidget *parent) {
1211 Dialog dialog(parent, true);
1212 dialog.setWindowFlags(dialog.windowFlags() | Qt::WindowStaysOnTopHint);
1213 std::vector<QString> buttons;
1214 buttons.push_back(button1);
1215 buttons.push_back(button2);
1216 return DVGui::MsgBox(DVGui::QUESTION, text, buttons, defaultButtonIndex,
1217 parent);
1218 }
1219
1220 //-----------------------------------------------------------------------------
1221
createMsgBox(MsgType type,const QString & text,const QStringList & buttons,int defaultButtonIndex,QWidget * parent)1222 Dialog *DVGui::createMsgBox(MsgType type, const QString &text,
1223 const QStringList &buttons, int defaultButtonIndex,
1224 QWidget *parent) {
1225 Dialog *dialog = new Dialog(parent, true);
1226 dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnTopHint);
1227 dialog->setAlignment(Qt::AlignLeft);
1228 QString msgBoxTitle = getMsgBoxTitle(type);
1229
1230 dialog->setWindowTitle(msgBoxTitle);
1231
1232 QLabel *mainTextLabel = new QLabel(text, dialog);
1233 mainTextLabel->setObjectName("Label");
1234 QPixmap iconPixmap = getMsgBoxPixmap(type);
1235 if (!iconPixmap.isNull()) {
1236 QLabel *iconLabel = new QLabel(dialog);
1237 iconLabel->setPixmap(iconPixmap);
1238
1239 QHBoxLayout *mainLayout = new QHBoxLayout;
1240 mainLayout->addWidget(iconLabel);
1241 mainLayout->addSpacing(16);
1242 mainLayout->addWidget(mainTextLabel);
1243 dialog->addLayout(mainLayout);
1244 } else
1245 dialog->addWidget(mainTextLabel);
1246
1247 // ButtonGroup: is used only to retrieve the clicked button
1248 QButtonGroup *buttonGroup = new QButtonGroup(dialog);
1249
1250 for (int i = 0; i < (int)buttons.size(); i++) {
1251 QPushButton *button = new QPushButton(buttons[i], dialog);
1252 if (defaultButtonIndex == i)
1253 button->setDefault(true);
1254 else
1255 button->setDefault(false);
1256 dialog->addButtonBarWidget(button);
1257
1258 buttonGroup->addButton(button, i + 1);
1259 }
1260
1261 QObject::connect(buttonGroup, SIGNAL(buttonPressed(int)), dialog,
1262 SLOT(done(int)));
1263
1264 return dialog;
1265 }
1266
1267 //-----------------------------------------------------------------------------
1268
createMsgandCheckbox(MsgType type,const QString & text,const QString & checkBoxText,const QStringList & buttons,int defaultButtonIndex,Qt::CheckState defaultCheckBoxState,QWidget * parent)1269 MessageAndCheckboxDialog *DVGui::createMsgandCheckbox(
1270 MsgType type, const QString &text, const QString &checkBoxText,
1271 const QStringList &buttons, int defaultButtonIndex,
1272 Qt::CheckState defaultCheckBoxState, QWidget *parent) {
1273 MessageAndCheckboxDialog *dialog = new MessageAndCheckboxDialog(
1274 parent, true, true, "", defaultCheckBoxState);
1275 dialog->setWindowFlags(dialog->windowFlags() | Qt::WindowStaysOnTopHint);
1276 dialog->setAlignment(Qt::AlignLeft);
1277 QString msgBoxTitle = getMsgBoxTitle(type);
1278
1279 dialog->setWindowTitle(msgBoxTitle);
1280
1281 QLabel *mainTextLabel = new QLabel(text, dialog);
1282 mainTextLabel->setObjectName("Label");
1283 QPixmap iconPixmap = getMsgBoxPixmap(type);
1284 if (!iconPixmap.isNull()) {
1285 QLabel *iconLabel = new QLabel(dialog);
1286 iconLabel->setPixmap(iconPixmap);
1287
1288 QHBoxLayout *mainLayout = new QHBoxLayout;
1289 mainLayout->addWidget(iconLabel);
1290 mainLayout->addSpacing(16);
1291 mainLayout->addWidget(mainTextLabel);
1292 dialog->addLayout(mainLayout);
1293 } else
1294 dialog->addWidget(mainTextLabel);
1295
1296 // ButtonGroup: is used only to retrieve the clicked button
1297 QButtonGroup *buttonGroup = new QButtonGroup(dialog);
1298
1299 for (int i = 0; i < (int)buttons.size(); i++) {
1300 QPushButton *button = new QPushButton(buttons[i], dialog);
1301 if (defaultButtonIndex == i)
1302 button->setDefault(true);
1303 else
1304 button->setDefault(false);
1305 dialog->addButtonBarWidget(button);
1306
1307 buttonGroup->addButton(button, i + 1);
1308 }
1309
1310 QCheckBox *dialogCheckBox = new QCheckBox(checkBoxText, dialog);
1311 QHBoxLayout *checkBoxLayout = new QHBoxLayout;
1312 checkBoxLayout->addWidget(dialogCheckBox);
1313 checkBoxLayout->addStretch(0);
1314 dialog->addLayout(checkBoxLayout);
1315
1316 dialogCheckBox->setCheckState(defaultCheckBoxState);
1317
1318 QObject::connect(dialogCheckBox, SIGNAL(stateChanged(int)), dialog,
1319 SLOT(onCheckboxChanged(int)));
1320 QObject::connect(buttonGroup, SIGNAL(buttonPressed(int)), dialog,
1321 SLOT(onButtonPressed(int)));
1322
1323 return dialog;
1324 }
1325
1326 //-----------------------------------------------------------------------------
1327
getText(const QString & title,const QString & labelText,const QString & text,bool * ok)1328 QString DVGui::getText(const QString &title, const QString &labelText,
1329 const QString &text, bool *ok) {
1330 Dialog dialog(0, true);
1331
1332 dialog.setWindowTitle(title);
1333 dialog.setWindowFlags(Qt::WindowStaysOnTopHint | Qt::WindowTitleHint |
1334 Qt::CustomizeWindowHint);
1335
1336 QVBoxLayout *layout = new QVBoxLayout(&dialog);
1337 dialog.addLayout(layout);
1338
1339 QLabel *label = new QLabel(labelText, &dialog);
1340 layout->addWidget(label);
1341
1342 LineEdit *nameFld = new LineEdit(text, &dialog);
1343 layout->addWidget(nameFld);
1344
1345 QPushButton *okBtn = new QPushButton(QObject::tr("OK"), &dialog);
1346 okBtn->setDefault(true);
1347 QPushButton *cancelBtn = new QPushButton(QObject::tr("Cancel"), &dialog);
1348 QObject::connect(okBtn, SIGNAL(clicked()), &dialog, SLOT(accept()));
1349 QObject::connect(cancelBtn, SIGNAL(clicked()), &dialog, SLOT(reject()));
1350
1351 dialog.addButtonBarWidget(okBtn, cancelBtn);
1352
1353 int ret = dialog.exec();
1354 if (ok) *ok = (ret == QDialog::Accepted);
1355
1356 return nameFld->text();
1357 }
1358
1359 //-----------------------------------------------------------------------------
1360
1361 namespace {
isStyleIdInPalette(int styleId,const TPalette * palette)1362 bool isStyleIdInPalette(int styleId, const TPalette *palette) {
1363 if (palette->getStyleCount() == 0) return false;
1364 int i;
1365 for (i = 0; i < palette->getPageCount(); i++) {
1366 const TPalette::Page *page = palette->getPage(i);
1367 if (!page) return false; // La pagina dovrebbe esserci sempre
1368 int j;
1369 for (j = 0; j < page->getStyleCount(); j++)
1370 if (page->getStyleId(j) == styleId) return true;
1371 }
1372 return false;
1373 }
1374 } // namespace
1375
1376 //-----------------------------------------------------------------------------
1377
eraseStylesInDemand(TPalette * palette,const TXsheetHandle * xsheetHandle,TPalette * newPalette)1378 int DVGui::eraseStylesInDemand(TPalette *palette,
1379 const TXsheetHandle *xsheetHandle,
1380 TPalette *newPalette) {
1381 // Verifico se gli stili della paletta sono usati : eraseStylesInDemand()
1382 std::vector<int> styleIds;
1383 int h;
1384 for (h = 0; h < palette->getPageCount(); h++) {
1385 TPalette::Page *page = palette->getPage(h);
1386 if (!page) continue; // La pagina dovrebbe esserci sempre
1387 int k;
1388 for (k = 0; k < page->getStyleCount(); k++) {
1389 int styleId = page->getStyleId(k);
1390 bool isStyleIdInNewPalette =
1391 (!newPalette) ? false : isStyleIdInPalette(styleId, newPalette);
1392 if (styleId > 0 && !isStyleIdInNewPalette) styleIds.push_back(styleId);
1393 }
1394 }
1395
1396 return eraseStylesInDemand(palette, styleIds, xsheetHandle);
1397 }
1398
1399 //-----------------------------------------------------------------------------
1400
eraseStylesInDemand(TPalette * palette,std::vector<int> styleIds,const TXsheetHandle * xsheetHandle)1401 int DVGui::eraseStylesInDemand(TPalette *palette, std::vector<int> styleIds,
1402 const TXsheetHandle *xsheetHandle) {
1403 struct locals {
1404 static bool isRasterLevel(const TXshSimpleLevel *level) {
1405 return level->getType() == TZP_XSHLEVEL ||
1406 level->getType() == OVL_XSHLEVEL;
1407 }
1408 }; // locals
1409
1410 // Search xsheet levels attached to the palette
1411 std::set<TXshSimpleLevel *> levels;
1412 int row, column;
1413 findPaletteLevels(levels, row, column, palette, xsheetHandle->getXsheet());
1414
1415 bool someStyleIsUsed =
1416 !levels.empty() ||
1417 styleIds.empty(); // I guess this is wrong... but I'm not touching it
1418 if (someStyleIsUsed) someStyleIsUsed = areStylesUsed(levels, styleIds);
1419
1420 if (!someStyleIsUsed) return 1;
1421
1422 // At least a style is selected and present in some level - ask user if and
1423 // how styles
1424 // should be deleted
1425
1426 QString question = QObject::tr(
1427 "Styles you are going to delete are used to paint "
1428 "lines and areas in the animation level.\n") +
1429 QObject::tr("How do you want to proceed?");
1430
1431 int ret = DVGui::MsgBox(question, QObject::tr("Delete Styles Only"),
1432 QObject::tr("Delete Styles, Lines and Areas"),
1433 QObject::tr("Cancel"), 0);
1434 if (ret != 2) return (ret == 0 || ret == 3) ? 0 : 1;
1435
1436 // Inform the user that case 2 will not produce an undo if a raster-based
1437 // level is detected
1438 if (std::any_of(levels.begin(), levels.end(), locals::isRasterLevel)) {
1439 std::vector<QString> buttons(2);
1440 buttons[0] = QObject::tr("Ok"), buttons[1] = QObject::tr("Cancel");
1441
1442 if (DVGui::MsgBox(DVGui::WARNING,
1443 QObject::tr("Deletion of Lines and Areas from "
1444 "raster-based levels is not undoable.\n"
1445 "Are you sure?"),
1446 buttons) != 1)
1447 return 0;
1448 }
1449
1450 QApplication::setOverrideCursor(Qt::WaitCursor);
1451 PaletteCmd::eraseStyles(levels, styleIds);
1452 QApplication::restoreOverrideCursor();
1453
1454 return (assert(ret == 2), ret); // return 2 ? :D
1455 }
1456
1457 //-----------------------------------------------------------------------------