1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4#
5
6"""
7Module implementing the eric message box wizard dialog.
8"""
9
10import os
11
12from PyQt5.QtCore import pyqtSlot
13from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton
14
15from E5Gui import E5MessageBox
16
17from .Ui_E5MessageBoxWizardDialog import Ui_E5MessageBoxWizardDialog
18
19
20class E5MessageBoxWizardDialog(QDialog, Ui_E5MessageBoxWizardDialog):
21    """
22    Class implementing the eric message box wizard dialog.
23
24    It displays a dialog for entering the parameters
25    for the E5MessageBox code generator.
26    """
27    def __init__(self, parent=None):
28        """
29        Constructor
30
31        @param parent reference to the parent widget (QWidget)
32        """
33        super().__init__(parent)
34        self.setupUi(self)
35
36        # keep the following three lists in sync
37        self.buttonsList = [
38            self.tr("No button"),
39            self.tr("Abort"),
40            self.tr("Apply"),
41            self.tr("Cancel"),
42            self.tr("Close"),
43            self.tr("Discard"),
44            self.tr("Help"),
45            self.tr("Ignore"),
46            self.tr("No"),
47            self.tr("No to all"),
48            self.tr("Ok"),
49            self.tr("Open"),
50            self.tr("Reset"),
51            self.tr("Restore defaults"),
52            self.tr("Retry"),
53            self.tr("Save"),
54            self.tr("Save all"),
55            self.tr("Yes"),
56            self.tr("Yes to all"),
57        ]
58        self.buttonsCodeListBinary = [
59            E5MessageBox.NoButton,
60            E5MessageBox.Abort,
61            E5MessageBox.Apply,
62            E5MessageBox.Cancel,
63            E5MessageBox.Close,
64            E5MessageBox.Discard,
65            E5MessageBox.Help,
66            E5MessageBox.Ignore,
67            E5MessageBox.No,
68            E5MessageBox.NoToAll,
69            E5MessageBox.Ok,
70            E5MessageBox.Open,
71            E5MessageBox.Reset,
72            E5MessageBox.RestoreDefaults,
73            E5MessageBox.Retry,
74            E5MessageBox.Save,
75            E5MessageBox.SaveAll,
76            E5MessageBox.Yes,
77            E5MessageBox.YesToAll,
78        ]
79        self.buttonsCodeListText = [
80            "E5MessageBox.NoButton",
81            "E5MessageBox.Abort",
82            "E5MessageBox.Apply",
83            "E5MessageBox.Cancel",
84            "E5MessageBox.Close",
85            "E5MessageBox.Discard",
86            "E5MessageBox.Help",
87            "E5MessageBox.Ignore",
88            "E5MessageBox.No",
89            "E5MessageBox.NoToAll",
90            "E5MessageBox.Ok",
91            "E5MessageBox.Open",
92            "E5MessageBox.Reset",
93            "E5MessageBox.RestoreDefaults",
94            "E5MessageBox.Retry",
95            "E5MessageBox.Save",
96            "E5MessageBox.SaveAll",
97            "E5MessageBox.Yes",
98            "E5MessageBox.YesToAll",
99        ]
100
101        self.defaultCombo.addItems(self.buttonsList)
102
103        self.bTest = self.buttonBox.addButton(
104            self.tr("Test"), QDialogButtonBox.ButtonRole.ActionRole)
105
106        self.__enabledGroups()
107
108    def __enabledGroups(self):
109        """
110        Private method to enable/disable some group boxes.
111        """
112        self.standardButtons.setEnabled(
113            self.rInformation.isChecked() or
114            self.rQuestion.isChecked() or
115            self.rWarning.isChecked() or
116            self.rCritical.isChecked() or
117            self.rStandard.isChecked()
118        )
119
120        self.defaultButton.setEnabled(
121            self.rInformation.isChecked() or
122            self.rQuestion.isChecked() or
123            self.rWarning.isChecked() or
124            self.rCritical.isChecked()
125        )
126
127        self.iconBox.setEnabled(
128            self.rYesNo.isChecked() or
129            self.rRetryAbort.isChecked() or
130            self.rStandard.isChecked()
131        )
132
133        self.bTest.setEnabled(not self.rStandard.isChecked())
134
135        self.eMessage.setEnabled(not self.rAboutQt.isChecked())
136
137    @pyqtSlot(bool)
138    def on_rInformation_toggled(self, on):
139        """
140        Private slot to handle the toggled signal of the rInformation
141        radio button.
142
143        @param on toggle state (boolean) (ignored)
144        """
145        self.__enabledGroups()
146
147    @pyqtSlot(bool)
148    def on_rQuestion_toggled(self, on):
149        """
150        Private slot to handle the toggled signal of the rQuestion
151        radio button.
152
153        @param on toggle state (boolean) (ignored)
154        """
155        self.__enabledGroups()
156
157    @pyqtSlot(bool)
158    def on_rWarning_toggled(self, on):
159        """
160        Private slot to handle the toggled signal of the rWarning
161        radio button.
162
163        @param on toggle state (boolean) (ignored)
164        """
165        self.__enabledGroups()
166
167    @pyqtSlot(bool)
168    def on_rCritical_toggled(self, on):
169        """
170        Private slot to handle the toggled signal of the rCritical
171        radio button.
172
173        @param on toggle state (boolean) (ignored)
174        """
175        self.__enabledGroups()
176
177    @pyqtSlot(bool)
178    def on_rYesNo_toggled(self, on):
179        """
180        Private slot to handle the toggled signal of the rYesNo
181        radio button.
182
183        @param on toggle state (boolean) (ignored)
184        """
185        self.__enabledGroups()
186
187    @pyqtSlot(bool)
188    def on_rRetryAbort_toggled(self, on):
189        """
190        Private slot to handle the toggled signal of the rRetryAbort
191        radio button.
192
193        @param on toggle state (boolean) (ignored)
194        """
195        self.__enabledGroups()
196
197    @pyqtSlot(bool)
198    def on_rOkToClearData_toggled(self, on):
199        """
200        Private slot to handle the toggled signal of the rOkToClearData
201        radio button.
202
203        @param on toggle state (boolean) (ignored)
204        """
205        self.__enabledGroups()
206
207    @pyqtSlot(bool)
208    def on_rAbout_toggled(self, on):
209        """
210        Private slot to handle the toggled signal of the rAbout
211        radio button.
212
213        @param on toggle state (boolean) (ignored)
214        """
215        self.__enabledGroups()
216
217    @pyqtSlot(bool)
218    def on_rAboutQt_toggled(self, on):
219        """
220        Private slot to handle the toggled signal of the rAboutQt
221        radio button.
222
223        @param on toggle state (boolean) (ignored)
224        """
225        self.__enabledGroups()
226
227    @pyqtSlot(bool)
228    def on_rStandard_toggled(self, on):
229        """
230        Private slot to handle the toggled signal of the rStandard
231        radio button.
232
233        @param on toggle state (boolean) (ignored)
234        """
235        self.__enabledGroups()
236
237    @pyqtSlot(QAbstractButton)
238    def on_buttonBox_clicked(self, button):
239        """
240        Private slot called by a button of the button box clicked.
241
242        @param button button that was clicked (QAbstractButton)
243        """
244        if button == self.bTest:
245            self.on_bTest_clicked()
246
247    @pyqtSlot()
248    def on_bTest_clicked(self):
249        """
250        Private method to test the selected options.
251        """
252        if self.rAbout.isChecked():
253            E5MessageBox.about(
254                None,
255                self.eCaption.text(),
256                self.eMessage.toPlainText()
257            )
258        elif self.rAboutQt.isChecked():
259            E5MessageBox.aboutQt(
260                None, self.eCaption.text()
261            )
262        elif (
263            self.rInformation.isChecked() or
264            self.rQuestion.isChecked() or
265            self.rWarning.isChecked() or
266            self.rCritical.isChecked()
267        ):
268            buttons = E5MessageBox.NoButton
269            if self.abortCheck.isChecked():
270                buttons |= E5MessageBox.Abort
271            if self.applyCheck.isChecked():
272                buttons |= E5MessageBox.Apply
273            if self.cancelCheck.isChecked():
274                buttons |= E5MessageBox.Cancel
275            if self.closeCheck.isChecked():
276                buttons |= E5MessageBox.Close
277            if self.discardCheck.isChecked():
278                buttons |= E5MessageBox.Discard
279            if self.helpCheck.isChecked():
280                buttons |= E5MessageBox.Help
281            if self.ignoreCheck.isChecked():
282                buttons |= E5MessageBox.Ignore
283            if self.noCheck.isChecked():
284                buttons |= E5MessageBox.No
285            if self.notoallCheck.isChecked():
286                buttons |= E5MessageBox.NoToAll
287            if self.okCheck.isChecked():
288                buttons |= E5MessageBox.Ok
289            if self.openCheck.isChecked():
290                buttons |= E5MessageBox.Open
291            if self.resetCheck.isChecked():
292                buttons |= E5MessageBox.Reset
293            if self.restoreCheck.isChecked():
294                buttons |= E5MessageBox.RestoreDefaults
295            if self.retryCheck.isChecked():
296                buttons |= E5MessageBox.Retry
297            if self.saveCheck.isChecked():
298                buttons |= E5MessageBox.Save
299            if self.saveallCheck.isChecked():
300                buttons |= E5MessageBox.SaveAll
301            if self.yesCheck.isChecked():
302                buttons |= E5MessageBox.Yes
303            if self.yestoallCheck.isChecked():
304                buttons |= E5MessageBox.YesToAll
305            if buttons == E5MessageBox.NoButton:
306                buttons = E5MessageBox.Ok
307
308            defaultButton = self.buttonsCodeListBinary[
309                self.defaultCombo.currentIndex()]
310
311            if self.rInformation.isChecked():
312                E5MessageBox.information(
313                    self,
314                    self.eCaption.text(),
315                    self.eMessage.toPlainText(),
316                    E5MessageBox.StandardButtons(buttons),
317                    defaultButton
318                )
319            elif self.rQuestion.isChecked():
320                E5MessageBox.question(
321                    self,
322                    self.eCaption.text(),
323                    self.eMessage.toPlainText(),
324                    E5MessageBox.StandardButtons(buttons),
325                    defaultButton
326                )
327            elif self.rWarning.isChecked():
328                E5MessageBox.warning(
329                    self,
330                    self.eCaption.text(),
331                    self.eMessage.toPlainText(),
332                    E5MessageBox.StandardButtons(buttons),
333                    defaultButton
334                )
335            elif self.rCritical.isChecked():
336                E5MessageBox.critical(
337                    self,
338                    self.eCaption.text(),
339                    self.eMessage.toPlainText(),
340                    E5MessageBox.StandardButtons(buttons),
341                    defaultButton
342                )
343        elif (
344            self.rYesNo.isChecked() or
345            self.rRetryAbort.isChecked()
346        ):
347            if self.iconInformation.isChecked():
348                icon = E5MessageBox.Information
349            elif self.iconQuestion.isChecked():
350                icon = E5MessageBox.Question
351            elif self.iconWarning.isChecked():
352                icon = E5MessageBox.Warning
353            elif self.iconCritical.isChecked():
354                icon = E5MessageBox.Critical
355
356            if self.rYesNo.isChecked():
357                E5MessageBox.yesNo(
358                    self,
359                    self.eCaption.text(),
360                    self.eMessage.toPlainText(),
361                    icon=icon,
362                    yesDefault=self.yesDefaultCheck.isChecked()
363                )
364            elif self.rRetryAbort.isChecked():
365                E5MessageBox.retryAbort(
366                    self,
367                    self.eCaption.text(),
368                    self.eMessage.toPlainText(),
369                    icon=icon
370                )
371        elif self.rOkToClearData.isChecked():
372            E5MessageBox.okToClearData(
373                self,
374                self.eCaption.text(),
375                self.eMessage.toPlainText(),
376                lambda: True
377            )
378
379    def __getStandardButtonCode(self, istring, indString, withIntro=True):
380        """
381        Private method to generate the button code for the standard buttons.
382
383        @param istring indentation string (string)
384        @param indString string used for indentation (space or tab) (string)
385        @param withIntro flag indicating to generate a first line
386            with introductory text (boolean)
387        @return the button code (string)
388        """
389        buttons = []
390        if self.abortCheck.isChecked():
391            buttons.append("E5MessageBox.Abort")
392        if self.applyCheck.isChecked():
393            buttons.append("E5MessageBox.Apply")
394        if self.cancelCheck.isChecked():
395            buttons.append("E5MessageBox.Cancel")
396        if self.closeCheck.isChecked():
397            buttons.append("E5MessageBox.Close")
398        if self.discardCheck.isChecked():
399            buttons.append("E5MessageBox.Discard")
400        if self.helpCheck.isChecked():
401            buttons.append("E5MessageBox.Help")
402        if self.ignoreCheck.isChecked():
403            buttons.append("E5MessageBox.Ignore")
404        if self.noCheck.isChecked():
405            buttons.append("E5MessageBox.No")
406        if self.notoallCheck.isChecked():
407            buttons.append("E5MessageBox.NoToAll")
408        if self.okCheck.isChecked():
409            buttons.append("E5MessageBox.Ok")
410        if self.openCheck.isChecked():
411            buttons.append("E5MessageBox.Open")
412        if self.resetCheck.isChecked():
413            buttons.append("E5MessageBox.Reset")
414        if self.restoreCheck.isChecked():
415            buttons.append("E5MessageBox.RestoreDefaults")
416        if self.retryCheck.isChecked():
417            buttons.append("E5MessageBox.Retry")
418        if self.saveCheck.isChecked():
419            buttons.append("E5MessageBox.Save")
420        if self.saveallCheck.isChecked():
421            buttons.append("E5MessageBox.SaveAll")
422        if self.yesCheck.isChecked():
423            buttons.append("E5MessageBox.Yes")
424        if self.yestoallCheck.isChecked():
425            buttons.append("E5MessageBox.YesToAll")
426        if len(buttons) == 0:
427            return ""
428
429        istring2 = istring + indString
430        joinstring = ' |{0}{1}'.format(os.linesep, istring2)
431        btnCode = (
432            ',{0}{1}E5MessageBox.StandardButtons('.format(os.linesep, istring)
433            if withIntro else
434            'E5MessageBox.StandardButtons('
435        )
436        btnCode += '{0}{1}{2})'.format(
437            os.linesep, istring2, joinstring.join(buttons))
438
439        return btnCode
440
441    def __getDefaultButtonCode(self, istring):
442        """
443        Private method to generate the button code for the default button.
444
445        @param istring indentation string (string)
446        @return the button code (string)
447        """
448        btnCode = ""
449        defaultIndex = self.defaultCombo.currentIndex()
450        if defaultIndex:
451            btnCode = ',{0}{1}{2}'.format(
452                os.linesep, istring,
453                self.buttonsCodeListText[defaultIndex])
454        return btnCode
455
456    def getCode(self, indLevel, indString):
457        """
458        Public method to get the source code.
459
460        @param indLevel indentation level (int)
461        @param indString string used for indentation (space or tab) (string)
462        @return generated code (string)
463        """
464        # calculate our indentation level and the indentation string
465        il = indLevel + 1
466        istring = il * indString
467        estring = os.linesep + indLevel * indString
468
469        # now generate the code
470        if self.parentSelf.isChecked():
471            parent = "self"
472        elif self.parentNone.isChecked():
473            parent = "None"
474        elif self.parentOther.isChecked():
475            parent = self.parentEdit.text()
476            if parent == "":
477                parent = "None"
478
479        if self.iconInformation.isChecked():
480            icon = "E5MessageBox.Information"
481        elif self.iconQuestion.isChecked():
482            icon = "E5MessageBox.Question"
483        elif self.iconWarning.isChecked():
484            icon = "E5MessageBox.Warning"
485        elif self.iconCritical.isChecked():
486            icon = "E5MessageBox.Critical"
487
488        if not self.rStandard.isChecked():
489            resvar = self.eResultVar.text()
490            if not resvar:
491                resvar = "res"
492
493            if self.rAbout.isChecked():
494                msgdlg = "E5MessageBox.about({0}".format(os.linesep)
495            elif self.rAboutQt.isChecked():
496                msgdlg = "E5MessageBox.aboutQt({0}".format(os.linesep)
497            elif self.rInformation.isChecked():
498                msgdlg = "{0} = E5MessageBox.information({1}".format(
499                    resvar, os.linesep)
500            elif self.rQuestion.isChecked():
501                msgdlg = "{0} = E5MessageBox.question({1}".format(
502                    resvar, os.linesep)
503            elif self.rWarning.isChecked():
504                msgdlg = "{0} = E5MessageBox.warning({1}".format(
505                    resvar, os.linesep)
506            elif self.rCritical.isChecked():
507                msgdlg = "{0} = E5MessageBox.critical({1}".format(
508                    resvar, os.linesep)
509            elif self.rYesNo.isChecked():
510                msgdlg = "{0} = E5MessageBox.yesNo({1}".format(
511                    resvar, os.linesep)
512            elif self.rRetryAbort.isChecked():
513                msgdlg = "{0} = E5MessageBox.retryAbort({1}".format(
514                    resvar, os.linesep)
515            elif self.rOkToClearData.isChecked():
516                msgdlg = "{0} = E5MessageBox.okToClearData({1}".format(
517                    resvar, os.linesep)
518
519            msgdlg += '{0}{1},{2}'.format(istring, parent, os.linesep)
520            msgdlg += '{0}self.tr("{1}")'.format(
521                istring, self.eCaption.text())
522
523            if not self.rAboutQt.isChecked():
524                msgdlg += ',{0}{1}self.tr("""{2}""")'.format(
525                    os.linesep, istring, self.eMessage.toPlainText())
526
527            if (
528                self.rInformation.isChecked() or
529                self.rQuestion.isChecked() or
530                self.rWarning.isChecked() or
531                self.rCritical.isChecked()
532            ):
533                msgdlg += self.__getStandardButtonCode(istring, indString)
534                msgdlg += self.__getDefaultButtonCode(istring)
535            elif self.rYesNo.isChecked():
536                if not self.iconQuestion.isChecked():
537                    msgdlg += ',{0}{1}icon={2}'.format(
538                        os.linesep, istring, icon)
539                if self.yesDefaultCheck.isChecked():
540                    msgdlg += ',{0}{1}yesDefault=True'.format(
541                        os.linesep, istring)
542            elif self.rRetryAbort.isChecked():
543                if not self.iconQuestion.isChecked():
544                    msgdlg += ',{0}{1}icon={2}'.format(
545                        os.linesep, istring, icon)
546            elif self.rOkToClearData.isChecked():
547                saveFunc = self.saveFuncEdit.text()
548                if saveFunc == "":
549                    saveFunc = "lambda: True"
550                msgdlg += ',{0}{1}{2}'.format(os.linesep, istring, saveFunc)
551        else:
552            resvar = self.eResultVar.text()
553            if not resvar:
554                resvar = "dlg"
555
556            msgdlg = "{0} = E5MessageBox.E5MessageBox({1}".format(
557                resvar, os.linesep)
558            msgdlg += '{0}{1},{2}'.format(istring, icon, os.linesep)
559            msgdlg += '{0}self.tr("{1}")'.format(
560                istring, self.eCaption.text())
561            msgdlg += ',{0}{1}self.tr("""{2}""")'.format(
562                os.linesep, istring, self.eMessage.toPlainText())
563            if self.modalCheck.isChecked():
564                msgdlg += ',{0}{1}modal=True'.format(os.linesep, istring)
565            btnCode = self.__getStandardButtonCode(
566                istring, indString, withIntro=False)
567            if btnCode:
568                msgdlg += ',{0}{1}buttons={2}'.format(
569                    os.linesep, istring, btnCode)
570            if not self.parentNone.isChecked():
571                msgdlg += ',{0}{1}parent={2}'.format(
572                    os.linesep, istring, parent)
573
574        msgdlg += '){0}'.format(estring)
575        return msgdlg
576