def _create_theme_menu(self):
        theme_menu = QMenu(self)
        theme_menu.setTitle('Buttons Theme')
        theme_menu.setTearOffEnabled(True)
        theme_menu.setWindowTitle(TAG)
        theme_actions = QActionGroup(self)
        theme_actions.setExclusive(True)
        # create ordered theme list
        custom_order_theme = sorted(THEMES.iterkeys())
        custom_order_theme.remove('Maya Theme')
        custom_order_theme.insert(0, 'Maya Theme')
        default_item = True
        for theme in custom_order_theme:
            current_theme_action = QAction(theme, theme_actions)
            current_theme_action.setCheckable(True)
            current_theme_action.setChecked(
                MTTSettings.value('theme', 'Maya Theme') == theme)
            current_theme_action.triggered.connect(self.on_change_theme)
            theme_menu.addAction(current_theme_action)

            if default_item:
                theme_menu.addSeparator()
                default_item = False

        return theme_menu
    def on_show_debug_menu(self):
        self.debug_menu.clear()

        if self.is_master_cmd or self.power_user:
            power_user_mode = QAction('Power User Mode', self)
            power_user_mode.setCheckable(True)
            power_user_mode.setChecked(MTTSettings.value('powerUser'))
            power_user_mode.triggered.connect(self.__on_toggle_power_user)
            self.debug_menu.addAction(power_user_mode)
            self.is_master_cmd = False

            self.debug_menu.addSeparator()

        open_pref_folder_action = QAction('Open Preferences Folder', self)
        open_pref_folder_action.setStatusTip('Open MTT preference folder')
        open_pref_folder_action.triggered.connect(self.on_open_preference_folder)
        self.debug_menu.addAction(open_pref_folder_action)

        self.debug_menu.addSeparator()

        database_dump_csv = QAction('Dump Database as CSV', self)
        database_dump_csv.triggered.connect(self.view.model.database_dump_csv)
        self.debug_menu.addAction(database_dump_csv)

        database_dump_sql = QAction('Dump Database as SQL', self)
        database_dump_sql.triggered.connect(self.view.model.database_dump_sql)
        self.debug_menu.addAction(database_dump_sql)

        self.debug_menu.addSeparator()

        support_info = QMenu(self)
        support_info.setTitle('Supported Node Type')
        support_info.aboutToShow.connect(self.on_show_supported_type)
        self.debug_menu.addMenu(support_info)
Example #3
0
class menuBar(QMenuBar):
    def __init__(self,prozor):
        
        QMenuBar.__init__(self)
        self.prozor=prozor
        menuBarActions.menuBarActions.mBarActions(self)
        #File
        self.fileMenu = QMenu()
        self.fileMenu.setTitle("File")
        self.fileMenu.addAction(self.newFileAction)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.openFileAction)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.saveAction)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.saveAsAction)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.exitProgramAction)
        self.addMenu(self.fileMenu)
        #Edit
        self.editMenu=QMenu()
        self.editMenu.setTitle("Edit")
        self.editMenu.addAction(self.undoAction)
        self.fileMenu.addSeparator()
        self.editMenu.addAction(self.redoAction)
        self.fileMenu.addSeparator()
        self.editMenu.addAction(self.cutAction)
        self.fileMenu.addSeparator()
        self.editMenu.addAction(self.copyAction)
        self.fileMenu.addSeparator()
        self.editMenu.addAction(self.pasteAction)
        self.fileMenu.addSeparator()
        self.addMenu(self.editMenu)

        self.addAction(self.optionsAction)
    def on_show_debug_menu(self):
        self.debug_menu.clear()

        if self.is_master_cmd or self.power_user:
            power_user_mode = QAction('Power User Mode', self)
            power_user_mode.setCheckable(True)
            power_user_mode.setChecked(MTTSettings.value('powerUser'))
            power_user_mode.triggered.connect(self.__on_toggle_power_user)
            self.debug_menu.addAction(power_user_mode)
            self.is_master_cmd = False

            self.debug_menu.addSeparator()

        open_pref_folder_action = QAction('Open Preferences Folder', self)
        open_pref_folder_action.setStatusTip('Open MTT preference folder')
        open_pref_folder_action.triggered.connect(
            self.on_open_preference_folder)
        self.debug_menu.addAction(open_pref_folder_action)

        self.debug_menu.addSeparator()

        database_dump_csv = QAction('Dump Database as CSV', self)
        database_dump_csv.triggered.connect(self.view.model.database_dump_csv)
        self.debug_menu.addAction(database_dump_csv)

        database_dump_sql = QAction('Dump Database as SQL', self)
        database_dump_sql.triggered.connect(self.view.model.database_dump_sql)
        self.debug_menu.addAction(database_dump_sql)

        self.debug_menu.addSeparator()

        support_info = QMenu(self)
        support_info.setTitle('Supported Node Type')
        support_info.aboutToShow.connect(self.on_show_supported_type)
        self.debug_menu.addMenu(support_info)
    def _create_theme_menu(self):
        theme_menu = QMenu(self)
        theme_menu.setTitle('Buttons Theme')
        theme_menu.setTearOffEnabled(True)
        theme_menu.setWindowTitle(TAG)
        theme_actions = QActionGroup(self)
        theme_actions.setExclusive(True)
        # create ordered theme list
        custom_order_theme = sorted(THEMES.iterkeys())
        custom_order_theme.remove('Maya Theme')
        custom_order_theme.insert(0, 'Maya Theme')
        default_item = True
        for theme in custom_order_theme:
            current_theme_action = QAction(theme, theme_actions)
            current_theme_action.setCheckable(True)
            current_theme_action.setChecked(
                MTTSettings.value('theme', 'Maya Theme') == theme)
            current_theme_action.triggered.connect(self.on_change_theme)
            theme_menu.addAction(current_theme_action)

            if default_item:
                theme_menu.addSeparator()
                default_item = False

        return theme_menu
Example #6
0
    def __init__(self, parent=None):
        super(Status, self).__init__(parent)
        self.setupUi(self)
        self.base = parent

        self.wait_anim = QMovie(":/stuff/wait.gif")
        self.anim_lbl.setMovie(self.wait_anim)
        self.anim_lbl.hide()

        self.show_menu = QMenu(self)
        for i in [
                self.act_page, self.act_date, self.act_text, self.act_comment
        ]:
            self.show_menu.addAction(i)
            # noinspection PyUnresolvedReferences
            i.triggered.connect(self.on_show_items)
            i.setChecked(True)

        sort_menu = QMenu(self)
        ico_sort = QIcon(":/stuff/sort.png")
        group = QActionGroup(self)

        action = QAction(_("Date"), sort_menu)
        action.setCheckable(True)
        action.setChecked(not self.base.high_by_page)
        action.triggered.connect(self.base.set_highlight_sort)
        action.setData(False)
        group.addAction(action)
        sort_menu.addAction(action)

        action = QAction(_("Page"), sort_menu)
        action.setCheckable(True)
        action.setChecked(self.base.high_by_page)
        action.triggered.connect(self.base.set_highlight_sort)
        action.setData(True)
        group.addAction(action)
        sort_menu.addAction(action)

        sort_menu.setIcon(ico_sort)
        sort_menu.setTitle(_("Sort by"))
        self.show_menu.addMenu(sort_menu)

        self.show_items_btn.setMenu(self.show_menu)
Example #7
0
 def __init__(self, parent=None):
     super(Truss, self).__init__(parent)
     self.resize(800, 600)
     self.filename = None
     self.filetuple = None
     self.dirty = False  # Refers to Data Page only.
     centralwidget = QWidget(self)
     gridLayout = QGridLayout(centralwidget)
     self.tabWidget = QTabWidget(centralwidget)
     self.tab = QWidget()
     font = QFont()
     font.setFamily("Courier 10 Pitch")
     font.setPointSize(12)
     self.tab.setFont(font)
     gridLayout_3 = QGridLayout(self.tab)
     self.plainTextEdit = QPlainTextEdit(self.tab)
     gridLayout_3.addWidget(self.plainTextEdit, 0, 0, 1, 1)
     self.tabWidget.addTab(self.tab, "")
     self.tab_2 = QWidget()
     self.tab_2.setFont(font)
     gridLayout_2 = QGridLayout(self.tab_2)
     self.plainTextEdit_2 = QPlainTextEdit(self.tab_2)
     gridLayout_2.addWidget(self.plainTextEdit_2, 0, 0, 1, 1)
     self.tabWidget.addTab(self.tab_2, "")
     gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
     self.setCentralWidget(centralwidget)
     menubar = QMenuBar(self)
     menubar.setGeometry(QRect(0, 0, 800, 29))
     menu_File = QMenu(menubar)
     self.menu_Solve = QMenu(menubar)
     self.menu_Help = QMenu(menubar)
     self.setMenuBar(menubar)
     self.statusbar = QStatusBar(self)
     self.setStatusBar(self.statusbar)
     self.action_New = QAction(self)
     self.actionSave_As = QAction(self)
     self.action_Save = QAction(self)
     self.action_Open = QAction(self)
     self.action_Quit = QAction(self)
     self.action_About = QAction(self)
     self.actionShow_CCPL = QAction(self)
     self.action_Solve = QAction(self)
     self.action_CCPL = QAction(self)
     self.action_Help = QAction(self)
     menu_File.addAction(self.action_New)
     menu_File.addAction(self.action_Open)
     menu_File.addAction(self.actionSave_As)
     menu_File.addAction(self.action_Save)
     menu_File.addSeparator()
     menu_File.addAction(self.action_Quit)
     self.menu_Solve.addAction(self.action_Solve)
     self.menu_Help.addAction(self.action_About)
     self.menu_Help.addAction(self.action_CCPL)
     self.menu_Help.addAction(self.action_Help)
     menubar.addAction(menu_File.menuAction())
     menubar.addAction(self.menu_Solve.menuAction())
     menubar.addAction(self.menu_Help.menuAction())
     self.setWindowTitle("Main Window")
     self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),\
                                "Data Page")
     self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),\
                                "Solution Page")
     menu_File.setTitle("&File")
     self.menu_Solve.setTitle("&Solve")
     self.menu_Help.setTitle("&Help")
     self.tabWidget.setCurrentIndex(0)
     self.action_New.setText("&New")
     self.action_Open.setText("&Open")
     self.actionSave_As.setText("Save &As")
     self.action_Save.setText("&Save")
     self.action_Quit.setText("&Quit")
     self.action_Solve.setText("&Solve")
     self.action_About.setText("&About")
     self.action_CCPL.setText("&CCPL")
     self.action_Help.setText("&Help")
     self.action_Quit.triggered.connect(self.close)
     allToolBar = self.addToolBar("AllToolBar")
     allToolBar.setObjectName("AllToolBar")
     self.addActions(allToolBar, (self.action_Open, self.actionSave_As,\
                     self.action_Save, self.action_Solve,\
                     self.action_Quit ))
     self.action_New.triggered.connect(self.fileNew)
     self.action_Open.triggered.connect(self.fileOpen)
     self.actionSave_As.triggered.connect(self.fileSaveAs)
     self.action_Save.triggered.connect(self.fileSave)
     self.action_Solve.triggered.connect(self.trussSolve)
     self.action_About.triggered.connect(self.aboutBox)
     self.action_CCPL.triggered.connect(self.displayCCPL)
     self.action_Help.triggered.connect(self.help)
     self.plainTextEdit.textChanged.connect(self.setDirty)
     self.action_New = self.editAction(self.action_New, None,\
                         'ctrl+N', 'filenew', 'New File.')
     self.action_Open = self.editAction(self.action_Open, None, 'ctrl+O',
                                        'fileopen', 'Open File.')
     self.actionSave_As = self.editAction(self.actionSave_As,\
                         None, 'ctrl+A', 'filesaveas',\
                         'Save and Name File.')
     self.action_Save = self.editAction(self.action_Save, None, 'ctrl+S',
                                        'filesave', 'Save File.')
     self.action_Solve = self.editAction(self.action_Solve, None, 'ctrl+L',
                                         'solve', 'Solve Structure.')
     self.action_About = self.editAction(self.action_About, None, 'ctrl+B',
                                         'about', 'Pop About Box.')
     self.action_CCPL = self.editAction(self.action_CCPL, None, 'ctrl+G',
                                        'licence', 'Show Licence')
     self.action_Help = self.editAction(self.action_Help, None, 'ctrl+H',
                                        'help', 'Show Help Page.')
     self.action_Quit = self.editAction(self.action_Quit, None, 'ctrl+Q',
                                        'quit', 'Quit the program.')
     self.plainTextEdit_2.setReadOnly(True)
Example #8
0
class Truss(QMainWindow):
    def __init__(self, parent=None):
        super(Truss, self).__init__(parent)
        self.resize(800, 600)
        self.filename = None
        self.filetuple = None
        self.dirty = False  # Refers to Data Page only.
        centralwidget = QWidget(self)
        gridLayout = QGridLayout(centralwidget)
        self.tabWidget = QTabWidget(centralwidget)
        self.tab = QWidget()
        font = QFont()
        font.setFamily("Courier 10 Pitch")
        font.setPointSize(12)
        self.tab.setFont(font)
        gridLayout_3 = QGridLayout(self.tab)
        self.plainTextEdit = QPlainTextEdit(self.tab)
        gridLayout_3.addWidget(self.plainTextEdit, 0, 0, 1, 1)
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QWidget()
        self.tab_2.setFont(font)
        gridLayout_2 = QGridLayout(self.tab_2)
        self.plainTextEdit_2 = QPlainTextEdit(self.tab_2)
        gridLayout_2.addWidget(self.plainTextEdit_2, 0, 0, 1, 1)
        self.tabWidget.addTab(self.tab_2, "")
        gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
        self.setCentralWidget(centralwidget)
        menubar = QMenuBar(self)
        menubar.setGeometry(QRect(0, 0, 800, 29))
        menu_File = QMenu(menubar)
        self.menu_Solve = QMenu(menubar)
        self.menu_Help = QMenu(menubar)
        self.setMenuBar(menubar)
        self.statusbar = QStatusBar(self)
        self.setStatusBar(self.statusbar)
        self.action_New = QAction(self)
        self.actionSave_As = QAction(self)
        self.action_Save = QAction(self)
        self.action_Open = QAction(self)
        self.action_Quit = QAction(self)
        self.action_About = QAction(self)
        self.actionShow_CCPL = QAction(self)
        self.action_Solve = QAction(self)
        self.action_CCPL = QAction(self)
        self.action_Help = QAction(self)
        menu_File.addAction(self.action_New)
        menu_File.addAction(self.action_Open)
        menu_File.addAction(self.actionSave_As)
        menu_File.addAction(self.action_Save)
        menu_File.addSeparator()
        menu_File.addAction(self.action_Quit)
        self.menu_Solve.addAction(self.action_Solve)
        self.menu_Help.addAction(self.action_About)
        self.menu_Help.addAction(self.action_CCPL)
        self.menu_Help.addAction(self.action_Help)
        menubar.addAction(menu_File.menuAction())
        menubar.addAction(self.menu_Solve.menuAction())
        menubar.addAction(self.menu_Help.menuAction())
        self.setWindowTitle("Main Window")
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),\
                                   "Data Page")
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),\
                                   "Solution Page")
        menu_File.setTitle("&File")
        self.menu_Solve.setTitle("&Solve")
        self.menu_Help.setTitle("&Help")
        self.tabWidget.setCurrentIndex(0)
        self.action_New.setText("&New")
        self.action_Open.setText("&Open")
        self.actionSave_As.setText("Save &As")
        self.action_Save.setText("&Save")
        self.action_Quit.setText("&Quit")
        self.action_Solve.setText("&Solve")
        self.action_About.setText("&About")
        self.action_CCPL.setText("&CCPL")
        self.action_Help.setText("&Help")
        self.action_Quit.triggered.connect(self.close)
        allToolBar = self.addToolBar("AllToolBar")
        allToolBar.setObjectName("AllToolBar")
        self.addActions(allToolBar, (self.action_Open, self.actionSave_As,\
                        self.action_Save, self.action_Solve,\
                        self.action_Quit ))
        self.action_New.triggered.connect(self.fileNew)
        self.action_Open.triggered.connect(self.fileOpen)
        self.actionSave_As.triggered.connect(self.fileSaveAs)
        self.action_Save.triggered.connect(self.fileSave)
        self.action_Solve.triggered.connect(self.trussSolve)
        self.action_About.triggered.connect(self.aboutBox)
        self.action_CCPL.triggered.connect(self.displayCCPL)
        self.action_Help.triggered.connect(self.help)
        self.plainTextEdit.textChanged.connect(self.setDirty)
        self.action_New = self.editAction(self.action_New, None,\
                            'ctrl+N', 'filenew', 'New File.')
        self.action_Open = self.editAction(self.action_Open, None, 'ctrl+O',
                                           'fileopen', 'Open File.')
        self.actionSave_As = self.editAction(self.actionSave_As,\
                            None, 'ctrl+A', 'filesaveas',\
                            'Save and Name File.')
        self.action_Save = self.editAction(self.action_Save, None, 'ctrl+S',
                                           'filesave', 'Save File.')
        self.action_Solve = self.editAction(self.action_Solve, None, 'ctrl+L',
                                            'solve', 'Solve Structure.')
        self.action_About = self.editAction(self.action_About, None, 'ctrl+B',
                                            'about', 'Pop About Box.')
        self.action_CCPL = self.editAction(self.action_CCPL, None, 'ctrl+G',
                                           'licence', 'Show Licence')
        self.action_Help = self.editAction(self.action_Help, None, 'ctrl+H',
                                           'help', 'Show Help Page.')
        self.action_Quit = self.editAction(self.action_Quit, None, 'ctrl+Q',
                                           'quit', 'Quit the program.')
        self.plainTextEdit_2.setReadOnly(True)

    def setDirty(self):
        '''On change of text in textEdit window, set the flag
        "dirty" to True'''
        index = self.tabWidget.currentIndex()
        if index is not 0:
            return
        if self.dirty:
            return True
        self.dirty = True
        self.updateStatus('self.dirty set to True')

    def clearDirty(self):
        'Clear dirty flag'
        self.dirty = False

    def fileNew(self):
        '''Clear both Data Page and Solution Page.'''
        self.plainTextEdit.setPlainText(' ')
        self.plainTextEdit_2.setPlainText(' ')
        self.clearDirty(self)

    def okToContinue(self):
        if self.dirty:
            reply = QMessageBox.question(
                self, "Data Loader - Unsaved Changes", "Save unsaved changes?",
                QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
            if reply == QMessageBox.Cancel:
                return False
            elif reply == QMessageBox.Yes:
                self.clearDirty()
                return self.fileSave()
        return True

    def okRead(self):
        'Pop-up a warning message.'
        reply = QMessageBox.warning(
            self, "Warning",
            '''\nFile Open and Save is possible only in Data Page!
\n\(Use SaveAs for Solution Page)''', QMessageBox.Ok)
        return True

    def fileOpen(self):
        '''Open a file in Data Page (with index == 0)'''
        if self.tabWidget.currentIndex():
            self.okRead()
            return
        if not self.okToContinue():
            return
        dir = (os.path.dirname(self.filename)
               if self.filename is not None else ".")
        self.filetuple = QFileDialog.getOpenFileName(self,\
                        "Open File", dir, \
                        "Data (*.dat *.txt)\nAll Files (*.*)")
        self.filename = self.filetuple[0]
        fname = self.filename
        #  QFileDialog returns a tuple x with x[0] = file name and
        #  x[1] = type of filter.
        if fname:
            self.loadFile(fname)
            self.filename = fname
            self.updateStatus('New file opened.')

    def loadFile(self, fname=None):
        fl = open(fname)
        text = fl.read()
        self.plainTextEdit.setPlainText(text)
        self.dirty = False

    def fileSave(self):
        '''Save file with current file name.'''
        if self.tabWidget.currentIndex():
            self.okRead()
            return
        if self.filename is None:
            return self.fileSaveAs()
        else:
            flname = self.filename
            if flname:
                try:
                    with open(flname, 'w') as fl:
                        fl.write(tempText)
                    self.dirty = False
                    self.updateStatus('File saved.')
                except IOError:
                    self.dirty = True
                    self.updateStatus('File not saved.')
                    return False
                return True
            else:
                self.updateStatus('Failed to save... ')
                return False
        self.filename = None
        self.dirty = False

    def fileSaveAs(self):
        '''Save file with a new name.'''
        qpr = self.qprintline
        fname = self.filename if self.filename is not None else\
        "NoName"
        self.filetuple = QFileDialog.getSaveFileName(
            self, "Truss program - Save File", fname, "Data File (*.*)")
        flname = self.filetuple[0]
        index = self.tabWidget.currentIndex()
        if index == 0:
            self.filename = flname
            if flname:
                fl = open(flname, 'w')
                tempText = self.plainTextEdit.toPlainText()
                fl.write(tempText)
                fl.close()
                self.dirty = False
                self.updateStatus('File saved.')
        elif index == 1:
            if flname:
                fl = open(flname, 'w')
                tempText = self.plainTextEdit_2.toPlainText()
                fl.write(tempText)
                fl.close()

    def trussSolve(self):
        '''Solve a statically determinate truss, specified in
        Data Page and display the results in the Solution Page.
        To start, make a copy of the Data Page with a header all
        shown on the Data Page.'''
        printline = self.qprintline
        dataBall = self.plainTextEdit.toPlainText()
        self.plainTextEdit_2.clear()
        printline('================================')
        flbase = os.path.basename(self.filename)
        printline('SOLUTION FOR ' + flbase)
        printline('================================')
        dataBall = self.plainTextEdit.toPlainText()
        ncrunch.main(printline, self.filename, dataBall)

    def aboutBox(self):
        '''Popup a box with about message.'''
        QMessageBox.about(self, "About PySide, Platform and the like",
                """<b>Part of Structural Analysis.</b> v %s
                <p>Copyright &copy; 2011 Algis Kabaila. 
                All rights reserved in accordance with
                Creative Commons Attribution Licence (CCPL) v3
                or later - NO WARRANTIES!
                <p>This progam finds bar forces in 
                statically determinate trusses.                
                <p>Python %s -  PySide version %s - Qt version %s on\
                %s""" % (__version__, platform.python_version(),\
                PySide.__version__,  PySide.QtCore.__version__,
                platform.system()))

    def displayCCPL(self):
        '''Read and display CCPL licence.'''
        self.plainTextEdit.setPlainText(open('CCPL.txt').read())
        self.dirty = False
        self.filename = 'COPYING.txt'
        self.updateStatus('CCPL displayed.')

    def help(self):
        '''Read and display a help file- currently the README.txt.'''
        self.plainTextEdit.setPlainText(open('README.md').read())
        self.dirty = False
        self.filename = 'README.txt'
        self.updateStatus('README displayed.')

    def addActions(self, target, actions):
        '''Actions are added to Tool Bar.'''
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)

    def editAction(self,
                   action,
                   slot=None,
                   shortcut=None,
                   icon=None,
                   tip=None):
        '''This method adds to action: icon, shortcut, ToolTip,\
        StatusTip and can connect triggered action to slot '''
        if icon is not None:
            action.setIcon(QIcon(":/%s.png" % (icon)))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            action.triggered.connect(slot)
        return action

    def qreadline(self, lineNo):
        '''Read one line from Data Page (lineNo starts with 0)'''
        return str(self.plainTextEdit.document().\
            findBlockByLineNumber(lineNo).text()).rstrip()

    def qprintline(self, line):
        '''Append one line to Solution Page.'''
        self.plainTextEdit_2.appendPlainText(line.rstrip())

    def updateStatus(self, message):
        '''Keep status current.'''
        if self.filename is not None:
            flbase = os.path.basename(self.filename)
            self.setWindowTitle(str("Truss Analysis - " +\
                                         flbase + "[*]") )
            self.statusBar().showMessage(message, 5000)
            self.setWindowModified(self.dirty)
class MTTSettingsMenu(QMenu):

    def __init__(self, parent=None):
        super(MTTSettingsMenu, self).__init__(parent)

        self.view = parent
        self.is_master_cmd = False
        # power user state
        self.power_user = MTTSettings.value('powerUser')

        self.__create_actions()
        self.__populate_menu()

    def keyPressEvent(self, event):
        if event.modifiers() == Qt.ControlModifier:
            self.is_master_cmd = True

        super(MTTSettingsMenu, self).keyPressEvent(event)

    def keyReleaseEvent(self, event):
        self.is_master_cmd = False
        super(MTTSettingsMenu, self).keyReleaseEvent(event)

    def __create_actions(self):
        def add_action(lbl, tip, cmd, checkable=False, checked=False):
            a = QAction(lbl, self)
            a.setStatusTip(tip)
            a.triggered.connect(cmd)
            if checkable:
                a.setCheckable(True)
                a.setChecked(checked)

            return a

        self.help_a = add_action(
            'Help',
            'Opens the online Help page',
            self.on_settings_help)

        self.switch_edit_a = add_action(
            'Switch Edit/Source',
            'Replace "Edit" button by "Source" button',
            self.on_switch_source_edit_menu,
            True,
            MTTSettings.value('switchEdit'))

        self.heads_up_a = add_action(
            'HeadsUp Message',
            'Show HeadsUp Message in viewport',
            self.on_toggle_headsup,
            True,
            MTTSettings.value('showHeadsUp'))

        self.focus_filter_a = add_action(
            'Focus Filter Field at Startup',
            'Focus filter field at startup',
            self.on_toggle_focus,
            True,
            MTTSettings.value('filterFocus'))

        self.force_relative_path_a = add_action(
            'Force Relative Path',
            'Set a relative path when selecting a new file',
            self.on_force_relative_path,
            True,
            MTTSettings.value('forceRelativePath'))

        self.show_real_attr_value_a = add_action(
            'Show Real Attribute Value',
            'Show fullpath instead of filtering path as Attribute Editor',
            self.on_show_real_attribute_value,
            True,
            MTTSettings.value('showRealAttributeValue'))

        self.manage_quick_filter_a = add_action(
            'Manage Quick Filters',
            'Manage filters that popup with right clic in filter field',
            self.on_filter_manage_quick_filter)

        self.clear_completion_cache_a = add_action(
            'Clear Completion Cache',
            'Erase auto completion cache of filter field',
            self.on_filter_clear_completion_cache)

        self.override_panels_a = add_action(
            'Add CreateNode Button to Editors',
            ('Add "Create Node" to HyperShade and '
                'Node Editor for the current session'),
            self.on_override_panels)

        self.export_to_csv = add_action(
            'Export Texture List as CSV',
            'Export current textures into a csv file',
            self.view.model.export_as_csv)

        self.about = add_action(
            'About',
            'About',
            self.on_settings_about)

    def __populate_menu(self):
        self.addAction(self.help_a)

        self.addSeparator()

        self.addAction(self._get_menu_header('SETTINGS'))
        self.addAction(self.switch_edit_a)
        self.addAction(self.heads_up_a)
        self.addAction(self.focus_filter_a)
        self.addAction(self.force_relative_path_a)
        self.addAction(self.show_real_attr_value_a)
        self.addMenu(self._create_instance_menu())
        self.addMenu(self._create_theme_menu())

        self.addSeparator()

        self.addAction(self._get_menu_header('FILTER OPTIONS'))
        self.addAction(self.manage_quick_filter_a)
        self.addAction(self.clear_completion_cache_a)

        self.addSeparator()

        self.addAction(self._get_menu_header('MISC'))
        self.addAction(self.override_panels_a)
        self.addAction(self.export_to_csv)

        self.addSeparator()

        self.addAction(self._get_menu_header('DEBUG'))
        self.addMenu(self._create_debug_menu())

        self.addSeparator()

        self.addAction(self.about)

    def _get_menu_header(self, title):
        header = QAction(title, self)
        header.setEnabled(False)
        return header

    def _create_instance_menu(self):
        self.instance_menu = QMenu(self)
        self.instance_menu.setTitle('Prompt Instance Delay')
        self.instance_menu.aboutToShow.connect(
            self.on_show_prompt_instance_delay_menu)

        return self.instance_menu

    def _create_theme_menu(self):
        theme_menu = QMenu(self)
        theme_menu.setTitle('Buttons Theme')
        theme_menu.setTearOffEnabled(True)
        theme_menu.setWindowTitle(TAG)
        theme_actions = QActionGroup(self)
        theme_actions.setExclusive(True)
        # create ordered theme list
        custom_order_theme = sorted(THEMES.iterkeys())
        custom_order_theme.remove('Maya Theme')
        custom_order_theme.insert(0, 'Maya Theme')
        default_item = True
        for theme in custom_order_theme:
            current_theme_action = QAction(theme, theme_actions)
            current_theme_action.setCheckable(True)
            current_theme_action.setChecked(
                MTTSettings.value('theme', 'Maya Theme') == theme)
            current_theme_action.triggered.connect(self.on_change_theme)
            theme_menu.addAction(current_theme_action)

            if default_item:
                theme_menu.addSeparator()
                default_item = False

        return theme_menu

    def _create_debug_menu(self):
        self.debug_menu = QMenu(self)
        self.debug_menu.setTitle('Debug Menu')
        self.debug_menu.aboutToShow.connect(self.on_show_debug_menu)

        return self.debug_menu

    def on_change_theme(self):
        self.view.on_choose_theme(self.sender().text())

    def on_show_debug_menu(self):
        self.debug_menu.clear()

        if self.is_master_cmd or self.power_user:
            power_user_mode = QAction('Power User Mode', self)
            power_user_mode.setCheckable(True)
            power_user_mode.setChecked(MTTSettings.value('powerUser'))
            power_user_mode.triggered.connect(self.__on_toggle_power_user)
            self.debug_menu.addAction(power_user_mode)
            self.is_master_cmd = False

            self.debug_menu.addSeparator()

        open_pref_folder_action = QAction('Open Preferences Folder', self)
        open_pref_folder_action.setStatusTip('Open MTT preference folder')
        open_pref_folder_action.triggered.connect(self.on_open_preference_folder)
        self.debug_menu.addAction(open_pref_folder_action)

        self.debug_menu.addSeparator()

        database_dump_csv = QAction('Dump Database as CSV', self)
        database_dump_csv.triggered.connect(self.view.model.database_dump_csv)
        self.debug_menu.addAction(database_dump_csv)

        database_dump_sql = QAction('Dump Database as SQL', self)
        database_dump_sql.triggered.connect(self.view.model.database_dump_sql)
        self.debug_menu.addAction(database_dump_sql)

        self.debug_menu.addSeparator()

        support_info = QMenu(self)
        support_info.setTitle('Supported Node Type')
        support_info.aboutToShow.connect(self.on_show_supported_type)
        self.debug_menu.addMenu(support_info)

    def on_filter_clear_completion_cache(self):
        """ Clear filter auto completion cache """
        self.view.on_filter_set_text('')
        MTTSettings.remove('filterCompletionWildcard')
        MTTSettings.remove('filterCompletionRegExp')
        self.view.completion_model.setStringList([])

    def on_switch_source_edit_menu(self):
        state = MTTSettings.value('switchEdit')
        MTTSettings.set_value('switchEdit', not state)
        self.view.on_set_source_edit_menu(not state)

    def on_show_real_attribute_value(self):
        self.view.model.layoutAboutToBeChanged.emit()
        show_real_attribute_state = MTTSettings.value('showRealAttributeValue')
        MTTSettings.set_value(
            'showRealAttributeValue', not show_real_attribute_state)
        self.view._layout_changed()

    def on_filter_manage_quick_filter(self):
        """ Open Quick Filter words manager and save its content """
        manager = MTTQuickFilterManager(self)
        if manager.exec_():
            lists = manager.get_lists()
            # save list in settings
            MTTSettings.set_value('filterQuickWordsWildcard', ';;'.join(lists[0]))
            MTTSettings.set_value('filterQuickWordsRegExp', ';;'.join(lists[1]))
            # set current list
            self.view.quick_filter_words = lists[MTTSettings.value('filterRE')]
        manager.deleteLater()

    @staticmethod
    def on_toggle_headsup():
        state = MTTSettings.value('showHeadsUp')
        MTTSettings.set_value('showHeadsUp', not state)

    @staticmethod
    def on_toggle_focus():
        state = MTTSettings.value('filterFocus')
        MTTSettings.set_value('filterFocus', not state)

    @staticmethod
    def on_force_relative_path():
        state = MTTSettings.value('forceRelativePath')
        MTTSettings.set_value('forceRelativePath', not state)

    def on_show_supported_type(self):
        node_types = sorted(
            [n_type for (n_type, nice, attr) in
             MTTSettings.SUPPORTED_TYPE] + MTTSettings.UNSUPPORTED_TYPE)
        support_info = self.sender()
        support_info.clear()

        for node_type in node_types:
            current = QAction(node_type, self)
            current.setEnabled(False)
            current.setCheckable(True)
            current.setChecked(node_type not in MTTSettings.UNSUPPORTED_TYPE)
            support_info.addAction(current)

    def __on_toggle_power_user(self):
        state = MTTSettings.value('powerUser')
        MTTSettings.set_value('powerUser', not state)
        self.power_user = not state

    @staticmethod
    def on_open_preference_folder():
        """ Open preference folder """
        folder_path = os.path.dirname(MTTSettings.filename())
        cmds.launchImageEditor(viewImageFile=folder_path)

    @staticmethod
    def on_override_panels():
        """ Override HyperShade and NodeEditor creation callback"""
        override_info_box = QMessageBox()
        override_info_box.setWindowTitle(WINDOW_TITLE)
        override_info_box.setIcon(QMessageBox.Information)
        override_info_box.setText(
            'Buttons will be added to HyperShade toolbar and Node Editor toolbar.<br/>'
            'Changes will exists during this session.'
        )
        override_info_box.setInformativeText('<i>Read Help to set this settings permanent</i>')
        override_info_box.setStandardButtons(QMessageBox.Ok)
        override_info_box.setDefaultButton(QMessageBox.Ok)
        override_info_box.exec_()

        mttOverridePanels.override_panels()

    def on_settings_about(self):

        special_list = map(lambda x: x.replace(' ', '&nbsp;'), sorted([
            u'Beno\xeet Stordeur', u'Fran\xe7ois Jumel',
            'Jonathan Lorber', 'Norbert Cretinon',
            'Gilles Hoff'
        ]))
        QMessageBox.about(
            self.parent(),
            WINDOW_TITLE,
            '<b>Maya Texture Toolkit v{:.02f}</b>'
            u'<p>{} - \xa9 2014 - 2016'
            '</p>'
            '<p>Special thanks to :<br/>'
            '<i>{}</i>'
            '</p>'.format(__version__, __author__, ', '.join(special_list))
        )

    @staticmethod
    def on_settings_help():
        help_wiki = 'https://github.com/Bioeden/dbMayaTextureToolkit/wiki'
        webbrowser.open(help_wiki)

    def on_show_prompt_instance_delay_menu(self):
        prompt_instance_state = cmds.optionVar(query='MTT_prompt_instance_state')

        if prompt_instance_state == PROMPT_INSTANCE_WAIT:
            elapsed_time = time() - cmds.optionVar(query='MTT_prompt_instance_suspend')
            if elapsed_time > PROMPT_INSTANCE_WAIT_DURATION:
                prompt_instance_state = PROMPT_INSTANCE_ASK
                cmds.optionVar(iv=['MTT_prompt_instance_state', prompt_instance_state])
            else:
                mtt_log('Remaining %.2fs' % (PROMPT_INSTANCE_WAIT_DURATION - elapsed_time))
        elif prompt_instance_state == PROMPT_INSTANCE_SESSION:
            if 'mtt_prompt_session' not in __main__.__dict__:
                prompt_instance_state = PROMPT_INSTANCE_ASK
                cmds.optionVar(iv=['MTT_prompt_instance_state', prompt_instance_state])

        self.instance_menu.clear()

        prompt_delay = QActionGroup(self)
        prompt_delay.setExclusive(True)
        for i in range(len(PROMPT_INSTANCE_STATE.keys())):
            current_delay_action = QAction(PROMPT_INSTANCE_STATE[i], prompt_delay)
            current_delay_action.setCheckable(True)
            current_delay_action.setChecked(prompt_instance_state == i)
            current_delay_action.triggered.connect(
                partial(self.view.on_choose_instance_delay, i, prompt=i != 0))
            self.instance_menu.addAction(current_delay_action)
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):

        lbMinWidth = 65
        # leMinWidth = 200

        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(400, 310)

        # self.centralwidget = QWidget(MainWindow)
        self.mainSplitter = QSplitter(Qt.Horizontal, MainWindow)
        self.mainSplitter.setObjectName("centralwidget")
        self.mainSplitter.setProperty("childrenCollapsible", False)
        MainWindow.setCentralWidget(self.mainSplitter)

        self.leftSplitter = QSplitter(Qt.Vertical, self.mainSplitter)
        self.leftSplitter.setProperty("childrenCollapsible", False)
        ##### login_gbox
        self.login_gbox = QGroupBox(self.leftSplitter)
        self.login_gbox.setFlat(True)
        self.login_gbox.setObjectName("login_gbox")

        login_gbox_layout = QVBoxLayout(self.login_gbox)
        login_gbox_csf_layout = QHBoxLayout()
        login_gbox_account_layout = QHBoxLayout()
        login_gbox_connect_layout = QHBoxLayout()
        login_gbox_layout.addLayout(login_gbox_csf_layout)
        login_gbox_layout.addLayout(login_gbox_account_layout)
        login_gbox_layout.addLayout(login_gbox_connect_layout)

        self.lb_client_secrets_file_path = QLabel(self.login_gbox)
        self.lb_client_secrets_file_path.setObjectName("lb_client_secrets_file_path")
        self.lb_client_secrets_file_path.setMinimumWidth(lbMinWidth)

        self.client_secrets_file_path_le = QLineEdit(self.login_gbox)
        self.client_secrets_file_path_le.setObjectName("client_secrets_file_path_le")

        self.client_secret_file_path_tBtn = QToolButton(self.login_gbox)
        self.client_secret_file_path_tBtn.setObjectName("client_secret_file_path_tBtn")

        login_gbox_csf_layout.addWidget(self.lb_client_secrets_file_path)
        login_gbox_csf_layout.addWidget(self.client_secrets_file_path_le)
        login_gbox_csf_layout.addWidget(self.client_secret_file_path_tBtn)

        self.lb_account = QLabel(self.login_gbox)
        self.lb_account.setMaximumWidth(lbMinWidth)
        self.lb_account.setObjectName("lb_account")

        self.remove_account_btn = QToolButton(self.login_gbox)
        self.remove_account_btn.setObjectName("remove_account_btn")
        self.remove_account_btn.setMinimumWidth(20)
        self.remove_account_btn.setEnabled(False)

        self.add_account_btn = QToolButton(self.login_gbox)
        self.add_account_btn.setObjectName("add_account_btn")
        self.add_account_btn.setMinimumWidth(20)

        self.accounts_cb = QComboBox(self.login_gbox)
        self.accounts_cb.setObjectName("accounts_cb")

        login_gbox_account_layout.addWidget(self.lb_account)
        login_gbox_account_layout.addWidget(self.remove_account_btn)
        login_gbox_account_layout.addWidget(self.add_account_btn)
        login_gbox_account_layout.addWidget(self.accounts_cb)

        self.lb_decryption_key = QLabel(self.login_gbox)
        self.lb_decryption_key.setObjectName("lb_decryption_key")
        self.lb_decryption_key.setMinimumWidth(lbMinWidth)
        self.lb_decryption_key.hide()

        self.decryption_key_le = QLineEdit(self.login_gbox)
        self.decryption_key_le.setEchoMode(QLineEdit.Password)
        self.decryption_key_le.setObjectName("decryption_key_le")
        self.decryption_key_le.hide()

        self.connect_btn = QPushButton(self.login_gbox)
        self.connect_btn.setEnabled(False)
        self.connect_btn.setObjectName("connect_btn")

        login_gbox_connect_layout.addWidget(self.lb_decryption_key)
        login_gbox_connect_layout.addWidget(self.decryption_key_le)
        login_gbox_connect_layout.addWidget(self.connect_btn)

        #### search_gbox
        self.search_gbox = QGroupBox(self.leftSplitter)
        self.search_gbox.setFlat(True)
        self.search_gbox.setObjectName("search_gbox")
        self.search_gbox.hide()

        search_gbox_layout = QVBoxLayout(self.search_gbox)
        search_gbox_mailbox_layout = QVBoxLayout()
        search_gbox_date_layout = QHBoxLayout()
        search_gbox_from_layout = QHBoxLayout()
        search_gbox_to_layout = QHBoxLayout()
        search_gbox_subject_layout = QHBoxLayout()
        search_gbox_threads_layout = QHBoxLayout()
        search_gbox_paramaters_layout = QHBoxLayout()

        search_gbox_layout.addLayout(search_gbox_mailbox_layout)
        search_gbox_layout.addLayout(search_gbox_date_layout)
        search_gbox_layout.addLayout(search_gbox_from_layout)
        search_gbox_layout.addLayout(search_gbox_to_layout)
        search_gbox_layout.addLayout(search_gbox_subject_layout)
        search_gbox_layout.addLayout(search_gbox_threads_layout)
        search_gbox_layout.addLayout(search_gbox_paramaters_layout)

        self.lb_select_mailbox = QLabel(self.search_gbox)
        self.lb_select_mailbox.setObjectName("lb_select_mailbox")
        self.mailboxes_lw = QListWidget(self.search_gbox)
        self.mailboxes_lw.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.mailboxes_lw.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.mailboxes_lw.setObjectName("mailboxes_lw")
        search_gbox_mailbox_layout.addWidget(self.lb_select_mailbox)
        search_gbox_mailbox_layout.addWidget(self.mailboxes_lw)

        self.after_date_cb = QCheckBox(self.search_gbox)
        self.after_date_cb.setObjectName("after_date_cb")
        self.after_date_cb.setMinimumWidth(lbMinWidth)
        self.after_date_cb.setMaximumWidth(lbMinWidth)
        self.after_date_edit = QDateEdit(self.search_gbox)
        self.after_date_edit.setCalendarPopup(True)
        self.after_date_edit.setObjectName("after_date_edit")
        self.after_date_edit.setDate(QDate.currentDate().addDays(-365))
        self.after_date_edit.setMaximumDate(QDate.currentDate())
        self.after_date_edit.setEnabled(False)
        self.before_date_cb = QCheckBox(self.search_gbox)
        self.before_date_cb.setObjectName("before_date_cb")
        self.before_date_cb.setMinimumWidth(70)
        self.before_date_cb.setMaximumWidth(70)
        self.before_date_edit = QDateEdit(self.search_gbox)
        self.before_date_edit.setCalendarPopup(True)
        self.before_date_edit.setObjectName("before_date_edit")
        self.before_date_edit.setDate(QDate.currentDate())
        self.before_date_edit.setMaximumDate(QDate.currentDate())
        self.before_date_edit.setEnabled(False)
        search_gbox_date_layout.addWidget(self.after_date_cb)
        search_gbox_date_layout.addWidget(self.after_date_edit)
        search_gbox_date_layout.addWidget(self.before_date_cb)
        search_gbox_date_layout.addWidget(self.before_date_edit)

        self.lb_from = QLabel(self.search_gbox)
        self.lb_from.setObjectName("lb_from")
        self.lb_from.setMinimumWidth(lbMinWidth)
        self.from_le = QLineEdit(self.search_gbox)
        self.from_le.setObjectName("from_le")
        search_gbox_from_layout.addWidget(self.lb_from)
        search_gbox_from_layout.addWidget(self.from_le)

        self.lb_to = QLabel(self.search_gbox)
        self.lb_to.setObjectName("lb_to")
        self.lb_to.setMinimumWidth(lbMinWidth)
        self.to_le = QLineEdit(self.search_gbox)
        self.to_le.setObjectName("to_le")
        search_gbox_to_layout.addWidget(self.lb_to)
        search_gbox_to_layout.addWidget(self.to_le)

        self.lb_subject = QLabel(self.search_gbox)
        self.lb_subject.setObjectName("lb_subject")
        self.lb_subject.setMinimumWidth(lbMinWidth)
        self.subject_le = QLineEdit(self.search_gbox)
        self.subject_le.setObjectName("subject_le")
        search_gbox_subject_layout.addWidget(self.lb_subject)
        search_gbox_subject_layout.addWidget(self.subject_le)

        self.lb_threads = QLabel(self.search_gbox)
        self.lb_threads.setObjectName("lb_threads")
        self.lb_threads.setMaximumWidth(lbMinWidth)
        self.thread_count_sb = QSpinBox(self.search_gbox)
        self.thread_count_sb.setMinimum(1)
        self.thread_count_sb.setMaximum(10)
        self.thread_count_sb.setObjectName("thread_count_sb")
        self.html_radio = QRadioButton(self.search_gbox)
        self.html_radio.setObjectName("html_radio")
        self.text_radio = QRadioButton(self.search_gbox)
        self.text_radio.setObjectName("text_radio")
        self.extactTypeButtonGroup = QButtonGroup(self)
        self.extactTypeButtonGroup.addButton(self.html_radio)
        self.extactTypeButtonGroup.addButton(self.text_radio)
        self.html_radio.setChecked(True)
        self.search_btn = QPushButton(self.search_gbox)
        self.search_btn.setObjectName("search_btn")
        search_gbox_threads_layout.addWidget(self.lb_threads)
        search_gbox_threads_layout.addWidget(self.thread_count_sb)
        search_gbox_threads_layout.addWidget(self.html_radio)
        search_gbox_threads_layout.addWidget(self.text_radio)
        search_gbox_threads_layout.addWidget(self.search_btn)

        self.parameters_cb = QCheckBox(self.search_gbox)
        self.parameters_cb.setText("")
        self.parameters_cb.setObjectName("parameters_cb")
        self.parameters_le = QLineEdit(self.search_gbox)
        self.parameters_le.setEnabled(False)
        self.parameters_le.setObjectName("parameters_le")
        search_gbox_paramaters_layout.addWidget(self.parameters_cb)
        search_gbox_paramaters_layout.addWidget(self.parameters_le)

        #### log_gbox
        self.log_gbox = QGroupBox(self.leftSplitter)
        self.log_gbox.setFlat(True)
        self.log_gbox.setObjectName("log_gbox")
        log_layout = QVBoxLayout(self.log_gbox)
        self.log_te = QTextEdit(self.log_gbox)
        self.log_te.setLineWrapMode(QTextEdit.NoWrap)
        self.log_te.setReadOnly(True)
        self.log_te.setTextInteractionFlags(Qt.TextSelectableByKeyboard | Qt.TextSelectableByMouse)
        self.log_te.setObjectName("log_te")

        self.disconnect_btn = QPushButton(self.log_gbox)
        self.disconnect_btn.setObjectName("disconnect_btn")
        self.disconnect_btn.hide()
        log_layout.addWidget(self.log_te)
        log_layout_btn = QHBoxLayout()
        log_layout.addLayout(log_layout_btn)
        log_layout_btn.addWidget(self.disconnect_btn)
        log_layout_btn.addStretch()

        #### links_gbox
        self.links_gbox = QGroupBox(self.mainSplitter)
        self.links_gbox.setFlat(True)
        self.links_gbox.setObjectName("links_gbox")
        self.links_gbox.hide()
        links_gbox_layout = QVBoxLayout(self.links_gbox)
        links_gbox_links_layout = QVBoxLayout()
        links_gbox_buttons_layout = QHBoxLayout()
        links_gbox_layout.addLayout(links_gbox_links_layout)
        links_gbox_layout.addLayout(links_gbox_buttons_layout)

        self.links_text_edit = QTextEdit(self.links_gbox)
        self.links_text_edit.setObjectName("links_text_edit")
        links_gbox_links_layout.addWidget(self.links_text_edit)

        self.export_txt_btn = QPushButton(self.links_gbox)
        self.export_txt_btn.setObjectName("export_txt_btn")
        self.export_txt_btn.setEnabled(False)
        self.export_html_btn = QPushButton(self.links_gbox)
        self.export_html_btn.setObjectName("export_html_btn")
        self.export_html_btn.setEnabled(False)

        links_gbox_buttons_layout.addWidget(self.export_txt_btn)
        links_gbox_buttons_layout.addWidget(self.export_html_btn)
        
        ### menubar
        self.menubar = QMenuBar(MainWindow)
        # self.menubar.setGeometry(QRect(0, 0, 860, 21))
        self.menubar.setObjectName("menubar")
        self.menu_file = QMenu(self.menubar)
        self.menu_file.setObjectName("menu_file")
        self.menu_help = QMenu(self.menubar)
        self.menu_help.setObjectName("menu_help")
        MainWindow.setMenuBar(self.menubar)
        self.action_about = QAction(MainWindow)
        self.action_about.setObjectName("action_about")
        self.action_About_Qt = QAction(MainWindow)
        self.action_About_Qt.setObjectName("action_About_Qt")
        self.action_exit = QAction(MainWindow)
        self.action_exit.setObjectName("action_exit")
        self.actionSave = QAction(MainWindow)
        self.actionSave.setObjectName("actionSave")
        self.action_Gmail_Advanced_Search_Syntax = QAction(MainWindow)
        self.action_Gmail_Advanced_Search_Syntax.setObjectName("action_Gmail_Advanced_Search_Syntax")
        self.menu_file.addAction(self.action_exit)
        self.menu_help.addAction(self.action_Gmail_Advanced_Search_Syntax)
        self.menu_help.addSeparator()
        self.menu_help.addAction(self.action_about)
        self.menu_help.addAction(self.action_About_Qt)
        self.menubar.addAction(self.menu_file.menuAction())
        self.menubar.addAction(self.menu_help.menuAction())
        
        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)
        MainWindow.setTabOrder(self.client_secrets_file_path_le, self.client_secret_file_path_tBtn)
        MainWindow.setTabOrder(self.client_secret_file_path_tBtn, self.remove_account_btn)
        MainWindow.setTabOrder(self.remove_account_btn, self.add_account_btn)
        MainWindow.setTabOrder(self.add_account_btn, self.accounts_cb)
        MainWindow.setTabOrder(self.decryption_key_le, self.connect_btn)
        MainWindow.setTabOrder(self.connect_btn, self.log_te)
        MainWindow.setTabOrder(self.log_te, self.mailboxes_lw)
        MainWindow.setTabOrder(self.mailboxes_lw, self.after_date_cb)
        MainWindow.setTabOrder(self.after_date_cb, self.after_date_edit)
        MainWindow.setTabOrder(self.after_date_edit, self.before_date_cb)
        MainWindow.setTabOrder(self.before_date_cb, self.before_date_edit)
        MainWindow.setTabOrder(self.before_date_edit, self.from_le)
        MainWindow.setTabOrder(self.from_le, self.to_le)
        MainWindow.setTabOrder(self.to_le, self.subject_le)
        MainWindow.setTabOrder(self.subject_le, self.thread_count_sb)
        MainWindow.setTabOrder(self.thread_count_sb, self.html_radio)
        MainWindow.setTabOrder(self.html_radio, self.text_radio)
        MainWindow.setTabOrder(self.text_radio, self.search_btn)
        MainWindow.setTabOrder(self.search_btn, self.parameters_cb)
        MainWindow.setTabOrder(self.parameters_cb, self.parameters_le)
        MainWindow.setTabOrder(self.parameters_le, self.disconnect_btn)
        MainWindow.setTabOrder(self.disconnect_btn, self.links_text_edit)
        MainWindow.setTabOrder(self.links_text_edit, self.export_txt_btn)
        MainWindow.setTabOrder(self.export_txt_btn, self.export_html_btn)
        MainWindow.setTabOrder(self.export_html_btn, self.mailboxes_lw)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QApplication.translate("MainWindow", "Gmail URL Parser", None, QApplication.UnicodeUTF8))
        self.login_gbox.setTitle(QApplication.translate("MainWindow", "  Client secrets file path  ", None, QApplication.UnicodeUTF8))
        self.client_secrets_file_path_le.setPlaceholderText(QApplication.translate("MainWindow", "Please select your client secrets file", None, QApplication.UnicodeUTF8))
        self.lb_client_secrets_file_path.setText(QApplication.translate("MainWindow", "Path", None, QApplication.UnicodeUTF8))
        self.connect_btn.setText(QApplication.translate("MainWindow", "Connect", None, QApplication.UnicodeUTF8))
        self.client_secret_file_path_tBtn.setText(QApplication.translate("MainWindow", "...", None, QApplication.UnicodeUTF8))
        self.lb_account.setText(QApplication.translate("MainWindow", "Account", None, QApplication.UnicodeUTF8))
        self.add_account_btn.setText(QApplication.translate("MainWindow", "+", None, QApplication.UnicodeUTF8))
        self.remove_account_btn.setText(QApplication.translate("MainWindow", "-", None, QApplication.UnicodeUTF8))
        self.decryption_key_le.setPlaceholderText(QApplication.translate("MainWindow", "Decryption key", None, QApplication.UnicodeUTF8))
        self.lb_decryption_key.setText(QApplication.translate("MainWindow", "Key", None, QApplication.UnicodeUTF8))
        self.log_gbox.setTitle(QApplication.translate("MainWindow", "  Log  ", None, QApplication.UnicodeUTF8))
        self.search_gbox.setTitle(QApplication.translate("MainWindow", "  Search Parameters  ", None, QApplication.UnicodeUTF8))
        self.lb_to.setText(QApplication.translate("MainWindow", "To", None, QApplication.UnicodeUTF8))
        self.lb_from.setText(QApplication.translate("MainWindow", "From", None, QApplication.UnicodeUTF8))
        self.lb_subject.setText(QApplication.translate("MainWindow", "Subject", None, QApplication.UnicodeUTF8))
        self.search_btn.setText(QApplication.translate("MainWindow", "Search", None, QApplication.UnicodeUTF8))
        self.after_date_edit.setDisplayFormat(QApplication.translate("MainWindow", "yyyy-MM-dd", None, QApplication.UnicodeUTF8))
        self.before_date_edit.setDisplayFormat(QApplication.translate("MainWindow", "yyyy-MM-dd", None, QApplication.UnicodeUTF8))
        self.lb_select_mailbox.setToolTip(QApplication.translate("MainWindow", "<html><head/><body><p>Select multiple items to select labels</p></body></html>", None, QApplication.UnicodeUTF8))
        self.lb_select_mailbox.setText(QApplication.translate("MainWindow", "Select Mailbox or Labels", None, QApplication.UnicodeUTF8))
        self.after_date_cb.setText(QApplication.translate("MainWindow", "After", None, QApplication.UnicodeUTF8))
        self.before_date_cb.setText(QApplication.translate("MainWindow", "Before", None, QApplication.UnicodeUTF8))
        self.html_radio.setText(QApplication.translate("MainWindow", "html", None, QApplication.UnicodeUTF8))
        self.text_radio.setText(QApplication.translate("MainWindow", "text", None, QApplication.UnicodeUTF8))
        self.lb_threads.setText(QApplication.translate("MainWindow", "Threads", None, QApplication.UnicodeUTF8))
        self.links_gbox.setTitle(QApplication.translate("MainWindow", "  Links  ", None, QApplication.UnicodeUTF8))
        self.disconnect_btn.setText(QApplication.translate("MainWindow", "Disconnect", None, QApplication.UnicodeUTF8))
        self.export_txt_btn.setText(QApplication.translate("MainWindow", "Export as txt", None, QApplication.UnicodeUTF8))
        self.export_html_btn.setText(QApplication.translate("MainWindow", "Export as HTML", None, QApplication.UnicodeUTF8))
        self.menu_file.setTitle(QApplication.translate("MainWindow", "File", None, QApplication.UnicodeUTF8))
        self.menu_help.setTitle(QApplication.translate("MainWindow", "Help", None, QApplication.UnicodeUTF8))
        self.action_about.setText(QApplication.translate("MainWindow", "About", None, QApplication.UnicodeUTF8))
        self.action_About_Qt.setText(QApplication.translate("MainWindow", "About Qt", None, QApplication.UnicodeUTF8))
        self.action_exit.setText(QApplication.translate("MainWindow", "Exit", None, QApplication.UnicodeUTF8))
        self.action_exit.setShortcut(QApplication.translate("MainWindow", "Ctrl+Q", None, QApplication.UnicodeUTF8))
        self.actionSave.setText(QApplication.translate("MainWindow", "Save", None, QApplication.UnicodeUTF8))
        self.action_Gmail_Advanced_Search_Syntax.setText(QApplication.translate("MainWindow", "Gmail Advanced Search Syntax", None, QApplication.UnicodeUTF8))
class MTTSettingsMenu(QMenu):
    def __init__(self, parent=None):
        super(MTTSettingsMenu, self).__init__(parent)

        self.view = parent
        self.is_master_cmd = False
        # power user state
        self.power_user = MTTSettings.value('powerUser')

        self.__create_actions()
        self.__populate_menu()

    def keyPressEvent(self, event):
        if event.modifiers() == Qt.ControlModifier:
            self.is_master_cmd = True

        super(MTTSettingsMenu, self).keyPressEvent(event)

    def keyReleaseEvent(self, event):
        self.is_master_cmd = False
        super(MTTSettingsMenu, self).keyReleaseEvent(event)

    def __create_actions(self):
        def add_action(lbl, tip, cmd, checkable=False, checked=False):
            a = QAction(lbl, self)
            a.setStatusTip(tip)
            a.triggered.connect(cmd)
            if checkable:
                a.setCheckable(True)
                a.setChecked(checked)

            return a

        self.help_a = add_action('Help', 'Opens the online Help page',
                                 self.on_settings_help)

        self.switch_edit_a = add_action(
            'Switch Edit/Source', 'Replace "Edit" button by "Source" button',
            self.on_switch_source_edit_menu, True,
            MTTSettings.value('switchEdit'))

        self.heads_up_a = add_action('HeadsUp Message',
                                     'Show HeadsUp Message in viewport',
                                     self.on_toggle_headsup, True,
                                     MTTSettings.value('showHeadsUp'))

        self.focus_filter_a = add_action('Focus Filter Field at Startup',
                                         'Focus filter field at startup',
                                         self.on_toggle_focus, True,
                                         MTTSettings.value('filterFocus'))

        self.force_relative_path_a = add_action(
            'Force Relative Path',
            'Set a relative path when selecting a new file',
            self.on_force_relative_path, True,
            MTTSettings.value('forceRelativePath'))

        self.show_real_attr_value_a = add_action(
            'Show Real Attribute Value',
            'Show fullpath instead of filtering path as Attribute Editor',
            self.on_show_real_attribute_value, True,
            MTTSettings.value('showRealAttributeValue'))

        self.manage_quick_filter_a = add_action(
            'Manage Quick Filters',
            'Manage filters that popup with right clic in filter field',
            self.on_filter_manage_quick_filter)

        self.clear_completion_cache_a = add_action(
            'Clear Completion Cache',
            'Erase auto completion cache of filter field',
            self.on_filter_clear_completion_cache)

        self.override_panels_a = add_action(
            'Add CreateNode Button to Editors',
            ('Add "Create Node" to HyperShade and '
             'Node Editor for the current session'), self.on_override_panels)

        self.export_to_csv = add_action(
            'Export Texture List as CSV',
            'Export current textures into a csv file',
            self.view.model.export_as_csv)

        self.about = add_action('About', 'About', self.on_settings_about)

    def __populate_menu(self):
        self.addAction(self.help_a)

        self.addSeparator()

        self.addAction(self._get_menu_header('SETTINGS'))
        self.addAction(self.switch_edit_a)
        self.addAction(self.heads_up_a)
        self.addAction(self.focus_filter_a)
        self.addAction(self.force_relative_path_a)
        self.addAction(self.show_real_attr_value_a)
        self.addMenu(self._create_instance_menu())
        self.addMenu(self._create_theme_menu())

        self.addSeparator()

        self.addAction(self._get_menu_header('FILTER OPTIONS'))
        self.addAction(self.manage_quick_filter_a)
        self.addAction(self.clear_completion_cache_a)

        self.addSeparator()

        self.addAction(self._get_menu_header('MISC'))
        self.addAction(self.override_panels_a)
        self.addAction(self.export_to_csv)

        self.addSeparator()

        self.addAction(self._get_menu_header('DEBUG'))
        self.addMenu(self._create_debug_menu())

        self.addSeparator()

        self.addAction(self.about)

    def _get_menu_header(self, title):
        header = QAction(title, self)
        header.setEnabled(False)
        return header

    def _create_instance_menu(self):
        self.instance_menu = QMenu(self)
        self.instance_menu.setTitle('Prompt Instance Delay')
        self.instance_menu.aboutToShow.connect(
            self.on_show_prompt_instance_delay_menu)

        return self.instance_menu

    def _create_theme_menu(self):
        theme_menu = QMenu(self)
        theme_menu.setTitle('Buttons Theme')
        theme_menu.setTearOffEnabled(True)
        theme_menu.setWindowTitle(TAG)
        theme_actions = QActionGroup(self)
        theme_actions.setExclusive(True)
        # create ordered theme list
        custom_order_theme = sorted(THEMES.iterkeys())
        custom_order_theme.remove('Maya Theme')
        custom_order_theme.insert(0, 'Maya Theme')
        default_item = True
        for theme in custom_order_theme:
            current_theme_action = QAction(theme, theme_actions)
            current_theme_action.setCheckable(True)
            current_theme_action.setChecked(
                MTTSettings.value('theme', 'Maya Theme') == theme)
            current_theme_action.triggered.connect(self.on_change_theme)
            theme_menu.addAction(current_theme_action)

            if default_item:
                theme_menu.addSeparator()
                default_item = False

        return theme_menu

    def _create_debug_menu(self):
        self.debug_menu = QMenu(self)
        self.debug_menu.setTitle('Debug Menu')
        self.debug_menu.aboutToShow.connect(self.on_show_debug_menu)

        return self.debug_menu

    def on_change_theme(self):
        self.view.on_choose_theme(self.sender().text())

    def on_show_debug_menu(self):
        self.debug_menu.clear()

        if self.is_master_cmd or self.power_user:
            power_user_mode = QAction('Power User Mode', self)
            power_user_mode.setCheckable(True)
            power_user_mode.setChecked(MTTSettings.value('powerUser'))
            power_user_mode.triggered.connect(self.__on_toggle_power_user)
            self.debug_menu.addAction(power_user_mode)
            self.is_master_cmd = False

            self.debug_menu.addSeparator()

        open_pref_folder_action = QAction('Open Preferences Folder', self)
        open_pref_folder_action.setStatusTip('Open MTT preference folder')
        open_pref_folder_action.triggered.connect(
            self.on_open_preference_folder)
        self.debug_menu.addAction(open_pref_folder_action)

        self.debug_menu.addSeparator()

        database_dump_csv = QAction('Dump Database as CSV', self)
        database_dump_csv.triggered.connect(self.view.model.database_dump_csv)
        self.debug_menu.addAction(database_dump_csv)

        database_dump_sql = QAction('Dump Database as SQL', self)
        database_dump_sql.triggered.connect(self.view.model.database_dump_sql)
        self.debug_menu.addAction(database_dump_sql)

        self.debug_menu.addSeparator()

        support_info = QMenu(self)
        support_info.setTitle('Supported Node Type')
        support_info.aboutToShow.connect(self.on_show_supported_type)
        self.debug_menu.addMenu(support_info)

    def on_filter_clear_completion_cache(self):
        """ Clear filter auto completion cache """
        self.view.on_filter_set_text('')
        MTTSettings.remove('filterCompletionWildcard')
        MTTSettings.remove('filterCompletionRegExp')
        self.view.completion_model.setStringList([])

    def on_switch_source_edit_menu(self):
        state = MTTSettings.value('switchEdit')
        MTTSettings.set_value('switchEdit', not state)
        self.view.on_set_source_edit_menu(not state)

    def on_show_real_attribute_value(self):
        self.view.model.layoutAboutToBeChanged.emit()
        show_real_attribute_state = MTTSettings.value('showRealAttributeValue')
        MTTSettings.set_value('showRealAttributeValue',
                              not show_real_attribute_state)
        self.view._layout_changed()

    def on_filter_manage_quick_filter(self):
        """ Open Quick Filter words manager and save its content """
        manager = MTTQuickFilterManager(self)
        if manager.exec_():
            lists = manager.get_lists()
            # save list in settings
            MTTSettings.set_value('filterQuickWordsWildcard',
                                  ';;'.join(lists[0]))
            MTTSettings.set_value('filterQuickWordsRegExp',
                                  ';;'.join(lists[1]))
            # set current list
            self.view.quick_filter_words = lists[MTTSettings.value('filterRE')]
        manager.deleteLater()

    @staticmethod
    def on_toggle_headsup():
        state = MTTSettings.value('showHeadsUp')
        MTTSettings.set_value('showHeadsUp', not state)

    @staticmethod
    def on_toggle_focus():
        state = MTTSettings.value('filterFocus')
        MTTSettings.set_value('filterFocus', not state)

    @staticmethod
    def on_force_relative_path():
        state = MTTSettings.value('forceRelativePath')
        MTTSettings.set_value('forceRelativePath', not state)

    def on_show_supported_type(self):
        node_types = sorted(
            [n_type for (n_type, nice, attr) in MTTSettings.SUPPORTED_TYPE] +
            MTTSettings.UNSUPPORTED_TYPE)
        support_info = self.sender()
        support_info.clear()

        for node_type in node_types:
            current = QAction(node_type, self)
            current.setEnabled(False)
            current.setCheckable(True)
            current.setChecked(node_type not in MTTSettings.UNSUPPORTED_TYPE)
            support_info.addAction(current)

    def __on_toggle_power_user(self):
        state = MTTSettings.value('powerUser')
        MTTSettings.set_value('powerUser', not state)
        self.power_user = not state

    @staticmethod
    def on_open_preference_folder():
        """ Open preference folder """
        folder_path = os.path.dirname(MTTSettings.filename())
        cmds.launchImageEditor(viewImageFile=folder_path)

    @staticmethod
    def on_override_panels():
        """ Override HyperShade and NodeEditor creation callback"""
        override_info_box = QMessageBox()
        override_info_box.setWindowTitle(WINDOW_TITLE)
        override_info_box.setIcon(QMessageBox.Information)
        override_info_box.setText(
            'Buttons will be added to HyperShade toolbar and Node Editor toolbar.<br/>'
            'Changes will exists during this session.')
        override_info_box.setInformativeText(
            '<i>Read Help to set this settings permanent</i>')
        override_info_box.setStandardButtons(QMessageBox.Ok)
        override_info_box.setDefaultButton(QMessageBox.Ok)
        override_info_box.exec_()

        mttOverridePanels.override_panels()

    def on_settings_about(self):

        special_list = map(
            lambda x: x.replace(' ', '&nbsp;'),
            sorted([
                u'Beno\xeet Stordeur', u'Fran\xe7ois Jumel', 'Jonathan Lorber',
                'Norbert Cretinon', 'Gilles Hoff'
            ]))
        QMessageBox.about(
            self.parent(), WINDOW_TITLE, '<b>Maya Texture Toolkit v{:.02f}</b>'
            u'<p>{} - \xa9 2014 - 2016'
            '</p>'
            '<p>Special thanks to :<br/>'
            '<i>{}</i>'
            '</p>'.format(__version__, __author__, ', '.join(special_list)))

    @staticmethod
    def on_settings_help():
        help_wiki = 'https://github.com/Bioeden/dbMayaTextureToolkit/wiki'
        webbrowser.open(help_wiki)

    def on_show_prompt_instance_delay_menu(self):
        prompt_instance_state = cmds.optionVar(
            query='MTT_prompt_instance_state')

        if prompt_instance_state == PROMPT_INSTANCE_WAIT:
            elapsed_time = time() - cmds.optionVar(
                query='MTT_prompt_instance_suspend')
            if elapsed_time > PROMPT_INSTANCE_WAIT_DURATION:
                prompt_instance_state = PROMPT_INSTANCE_ASK
                cmds.optionVar(
                    iv=['MTT_prompt_instance_state', prompt_instance_state])
            else:
                mtt_log('Remaining %.2fs' %
                        (PROMPT_INSTANCE_WAIT_DURATION - elapsed_time))
        elif prompt_instance_state == PROMPT_INSTANCE_SESSION:
            if 'mtt_prompt_session' not in __main__.__dict__:
                prompt_instance_state = PROMPT_INSTANCE_ASK
                cmds.optionVar(
                    iv=['MTT_prompt_instance_state', prompt_instance_state])

        self.instance_menu.clear()

        prompt_delay = QActionGroup(self)
        prompt_delay.setExclusive(True)
        for i in range(len(PROMPT_INSTANCE_STATE.keys())):
            current_delay_action = QAction(PROMPT_INSTANCE_STATE[i],
                                           prompt_delay)
            current_delay_action.setCheckable(True)
            current_delay_action.setChecked(prompt_instance_state == i)
            current_delay_action.triggered.connect(
                partial(self.view.on_choose_instance_delay, i, prompt=i != 0))
            self.instance_menu.addAction(current_delay_action)
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):

        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(810, 492)

        lbMinWidth = 65
        lbMinWidthLogin = 110
        # leMinWidth = 200

        # self.centralwidget = QWidget(MainWindow)
        self.mainSplitter = QSplitter(Qt.Horizontal, MainWindow)
        self.mainSplitter.setObjectName("centralwidget")
        self.mainSplitter.setProperty("childrenCollapsible", False)
        MainWindow.setCentralWidget(self.mainSplitter)

        self.leftSplitter = QSplitter(Qt.Vertical, self.mainSplitter)
        self.leftSplitter.setProperty("childrenCollapsible", False)

        # login_gbox
        self.login_gbox = QGroupBox(self.leftSplitter)
        self.login_gbox.setFlat(True)
        self.login_gbox.setObjectName("login_gbox")

        login_gbox_layout = QVBoxLayout(self.login_gbox)
        login_gbox_presets_layout = QHBoxLayout()
        login_gbox_server_layout = QHBoxLayout()
        login_gbox_ssl_layout = QHBoxLayout()
        login_gbox_address_layout = QHBoxLayout()
        login_gbox_pass_layout = QHBoxLayout()
        login_gbox_connect_layout = QHBoxLayout()
        login_gbox_layout.addLayout(login_gbox_presets_layout)
        login_gbox_layout.addLayout(login_gbox_server_layout)
        login_gbox_layout.addLayout(login_gbox_ssl_layout)
        login_gbox_layout.addLayout(login_gbox_address_layout)
        login_gbox_layout.addLayout(login_gbox_pass_layout)
        login_gbox_layout.addLayout(login_gbox_connect_layout)

        self.lb_presets = QLabel(self.login_gbox)
        self.lb_presets.setObjectName("lb_presets")
        self.lb_presets.setMinimumWidth(lbMinWidthLogin)
        self.lb_presets.setMaximumWidth(lbMinWidthLogin)
        self.presets_cbox = QComboBox(self.login_gbox)
        self.presets_cbox.setObjectName("presets_cbox")
        self.add_preset_btn = QPushButton(self.login_gbox)
        self.add_preset_btn.setObjectName("add_preset_btn")
        self.add_preset_btn.setMaximumWidth(30)
        self.remove_preset_btn = QPushButton(self.login_gbox)
        self.remove_preset_btn.setObjectName("remove_preset_btn")
        self.remove_preset_btn.setMaximumWidth(20)
        login_gbox_presets_layout.addWidget(self.lb_presets)
        login_gbox_presets_layout.addWidget(self.presets_cbox)
        login_gbox_presets_layout.addWidget(self.add_preset_btn)
        login_gbox_presets_layout.addWidget(self.remove_preset_btn)

        self.lb_imap_server = QLabel(self.login_gbox)
        self.lb_imap_server.setObjectName("lb_imap_server")
        self.lb_imap_server.setMinimumWidth(lbMinWidthLogin)
        self.imap_server_le = QLineEdit(self.login_gbox)
        self.imap_server_le.setObjectName("imap_server_le")
        login_gbox_server_layout.addWidget(self.lb_imap_server)
        login_gbox_server_layout.addWidget(self.imap_server_le)

        self.lb_ssl = QLabel(self.login_gbox)
        self.lb_ssl.setObjectName("lb_ssl")
        self.lb_ssl.setMinimumWidth(lbMinWidthLogin)
        self.lb_ssl.setMaximumWidth(lbMinWidthLogin)
        self.ssl_cb = QCheckBox(self.login_gbox)
        self.ssl_cb.setEnabled(False)
        self.ssl_cb.setCheckable(True)
        self.ssl_cb.setChecked(True)
        self.ssl_cb.setObjectName("ssl_cb")
        login_gbox_ssl_layout.addWidget(self.lb_ssl)
        login_gbox_ssl_layout.addWidget(self.ssl_cb)

        self.lb_adress = QLabel(self.login_gbox)
        self.lb_adress.setObjectName("lb_adress")
        self.lb_adress.setMinimumWidth(lbMinWidthLogin)
        self.adress_le = QLineEdit(self.login_gbox)
        self.adress_le.setInputMethodHints(Qt.ImhNone)
        self.adress_le.setObjectName("adress_le")
        login_gbox_address_layout.addWidget(self.lb_adress)
        login_gbox_address_layout.addWidget(self.adress_le)

        self.lb_pass = QLabel(self.login_gbox)
        self.lb_pass.setObjectName("lb_pass")
        self.lb_pass.setMinimumWidth(lbMinWidthLogin)
        self.pass_le = QLineEdit(self.login_gbox)
        self.pass_le.setText("")
        self.pass_le.setEchoMode(QLineEdit.Password)
        self.pass_le.setObjectName("pass_le")
        login_gbox_pass_layout.addWidget(self.lb_pass)
        login_gbox_pass_layout.addWidget(self.pass_le)

        self.connect_btn = QPushButton(self.login_gbox)
        self.connect_btn.setObjectName("connect_btn")
        login_gbox_connect_layout.addStretch()
        login_gbox_connect_layout.addWidget(self.connect_btn)

        # search_gbox
        self.search_gbox = QGroupBox(self.leftSplitter)
        self.search_gbox.hide()
        self.search_gbox.setObjectName("search_gbox")

        search_gbox_layout = QVBoxLayout(self.search_gbox)
        search_gbox_mailbox_layout = QVBoxLayout()
        search_gbox_date_layout = QHBoxLayout()
        search_gbox_from_layout = QHBoxLayout()
        search_gbox_to_layout = QHBoxLayout()
        search_gbox_subject_layout = QHBoxLayout()
        search_gbox_threads_layout = QHBoxLayout()
        search_gbox_paramaters_layout = QHBoxLayout()

        search_gbox_layout.addLayout(search_gbox_mailbox_layout)
        search_gbox_layout.addLayout(search_gbox_date_layout)
        search_gbox_layout.addLayout(search_gbox_from_layout)
        search_gbox_layout.addLayout(search_gbox_to_layout)
        search_gbox_layout.addLayout(search_gbox_subject_layout)
        search_gbox_layout.addLayout(search_gbox_threads_layout)
        search_gbox_layout.addLayout(search_gbox_paramaters_layout)

        self.lb_select_mailbox = QLabel(self.search_gbox)
        self.lb_select_mailbox.setObjectName("lb_select_mailbox")
        self.mailboxes_lw = QListWidget(self.search_gbox)
        self.mailboxes_lw.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.mailboxes_lw.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.mailboxes_lw.setObjectName("mailboxes_lw")
        search_gbox_mailbox_layout.addWidget(self.lb_select_mailbox)
        search_gbox_mailbox_layout.addWidget(self.mailboxes_lw)

        self.since_date_cb = QCheckBox(self.search_gbox)
        self.since_date_cb.setObjectName("since_date_cb")
        self.since_date_cb.setMinimumWidth(lbMinWidth)
        self.since_date_cb.setMaximumWidth(lbMinWidth)
        self.since_date_edit = QDateEdit(self.search_gbox)
        self.since_date_edit.setCalendarPopup(True)
        self.since_date_edit.setObjectName("since_date_edit")
        self.since_date_edit.setDate(QDate.currentDate().addDays(-365))
        self.since_date_edit.setMaximumDate(QDate.currentDate())
        self.since_date_edit.setEnabled(False)
        self.before_date_cb = QCheckBox(self.search_gbox)
        self.before_date_cb.setObjectName("before_date_cb")
        self.before_date_cb.setMinimumWidth(70)
        self.before_date_cb.setMaximumWidth(70)
        self.before_date_edit = QDateEdit(self.search_gbox)
        self.before_date_edit.setCalendarPopup(True)
        self.before_date_edit.setObjectName("before_date_edit")
        self.before_date_edit.setDate(QDate.currentDate())
        self.before_date_edit.setMaximumDate(QDate.currentDate())
        self.before_date_edit.setEnabled(False)
        search_gbox_date_layout.addWidget(self.since_date_cb)
        search_gbox_date_layout.addWidget(self.since_date_edit)
        search_gbox_date_layout.addWidget(self.before_date_cb)
        search_gbox_date_layout.addWidget(self.before_date_edit)

        self.lb_from = QLabel(self.search_gbox)
        self.lb_from.setObjectName("lb_from")
        self.lb_from.setMinimumWidth(lbMinWidth)
        self.from_le = QLineEdit(self.search_gbox)
        self.from_le.setObjectName("from_le")
        search_gbox_from_layout.addWidget(self.lb_from)
        search_gbox_from_layout.addWidget(self.from_le)

        self.lb_to = QLabel(self.search_gbox)
        self.lb_to.setObjectName("lb_to")
        self.lb_to.setMinimumWidth(lbMinWidth)
        self.to_le = QLineEdit(self.search_gbox)
        self.to_le.setObjectName("to_le")
        search_gbox_to_layout.addWidget(self.lb_to)
        search_gbox_to_layout.addWidget(self.to_le)

        self.lb_subject = QLabel(self.search_gbox)
        self.lb_subject.setObjectName("lb_subject")
        self.lb_subject.setMinimumWidth(lbMinWidth)
        self.subject_le = QLineEdit(self.search_gbox)
        self.subject_le.setObjectName("subject_le")
        search_gbox_subject_layout.addWidget(self.lb_subject)
        search_gbox_subject_layout.addWidget(self.subject_le)

        # self.lb_threads = QLabel(self.search_gbox)
        # self.lb_threads.setObjectName("lb_threads")
        # self.lb_threads.setMaximumWidth(lbMinWidth)
        # self.thread_count_sb = QSpinBox(self.search_gbox)
        # self.thread_count_sb.setMinimum(1)
        # self.thread_count_sb.setMaximum(10)
        # self.thread_count_sb.setObjectName("thread_count_sb")
        self.html_radio = QRadioButton(self.search_gbox)
        self.html_radio.setObjectName("html_radio")
        self.text_radio = QRadioButton(self.search_gbox)
        self.text_radio.setObjectName("text_radio")
        self.extactTypeButtonGroup = QButtonGroup(self)
        self.extactTypeButtonGroup.addButton(self.html_radio)
        self.extactTypeButtonGroup.addButton(self.text_radio)
        self.html_radio.setChecked(True)
        self.search_btn = QPushButton(self.search_gbox)
        self.search_btn.setObjectName("search_btn")
        # search_gbox_threads_layout.addWidget(self.lb_threads)
        # search_gbox_threads_layout.addWidget(self.thread_count_sb)
        search_gbox_threads_layout.addStretch()
        search_gbox_threads_layout.addWidget(self.html_radio)
        search_gbox_threads_layout.addWidget(self.text_radio)
        # search_gbox_threads_layout.addStretch()
        search_gbox_threads_layout.addWidget(self.search_btn)

        self.parameters_cb = QCheckBox(self.search_gbox)
        self.parameters_cb.setText("")
        self.parameters_cb.setObjectName("parameters_cb")
        self.parameters_le = QLineEdit(self.search_gbox)
        self.parameters_le.setEnabled(False)
        self.parameters_le.setObjectName("parameters_le")
        search_gbox_paramaters_layout.addWidget(self.parameters_cb)
        search_gbox_paramaters_layout.addWidget(self.parameters_le)

        # log_gbox
        self.log_gbox = QGroupBox(self.leftSplitter)
        self.log_gbox.setFlat(True)
        self.log_gbox.setObjectName("log_gbox")
        log_layout = QVBoxLayout(self.log_gbox)
        self.log_te = QTextEdit(self.log_gbox)
        self.log_te.setLineWrapMode(QTextEdit.NoWrap)
        self.log_te.setReadOnly(True)
        self.log_te.setTextInteractionFlags(Qt.TextSelectableByKeyboard | Qt.TextSelectableByMouse)
        self.log_te.setObjectName("log_te")

        self.disconnect_btn = QPushButton(self.log_gbox)
        self.disconnect_btn.setObjectName("disconnect_btn")
        self.disconnect_btn.hide()
        log_layout.addWidget(self.log_te)
        log_layout_btn = QHBoxLayout()
        log_layout.addLayout(log_layout_btn)
        log_layout_btn.addWidget(self.disconnect_btn)
        log_layout_btn.addStretch()

        # links_gbox
        self.links_gbox = QGroupBox(self.mainSplitter)
        self.links_gbox.setFlat(True)
        self.links_gbox.setObjectName("links_gbox")
        links_gbox_layout = QVBoxLayout(self.links_gbox)
        links_gbox_links_layout = QVBoxLayout()
        links_gbox_buttons_layout = QHBoxLayout()
        links_gbox_layout.addLayout(links_gbox_links_layout)
        links_gbox_layout.addLayout(links_gbox_buttons_layout)

        self.links_text_edit = QTextEdit(self.links_gbox)
        self.links_text_edit.setObjectName("links_text_edit")
        links_gbox_links_layout.addWidget(self.links_text_edit)

        self.export_txt_btn = QPushButton(self.links_gbox)
        self.export_txt_btn.setObjectName("export_txt_btn")
        self.export_txt_btn.setEnabled(False)
        self.export_html_btn = QPushButton(self.links_gbox)
        self.export_html_btn.setObjectName("export_html_btn")
        self.export_html_btn.setEnabled(False)

        links_gbox_buttons_layout.addWidget(self.export_txt_btn)
        links_gbox_buttons_layout.addWidget(self.export_html_btn)

        # menubar
        self.menubar = QMenuBar(MainWindow)
        self.menubar.setObjectName("menubar")
        self.menu_file = QMenu(self.menubar)
        self.menu_file.setObjectName("menu_file")
        self.menu_about = QMenu(self.menubar)
        self.menu_about.setObjectName("menu_about")
        MainWindow.setMenuBar(self.menubar)
        self.action_about = QAction(MainWindow)
        self.action_about.setObjectName("action_about")
        self.action_About_Qt = QAction(MainWindow)
        self.action_About_Qt.setObjectName("action_About_Qt")
        self.action_exit = QAction(MainWindow)
        self.action_exit.setObjectName("action_exit")
        self.actionSave = QAction(MainWindow)
        self.actionSave.setObjectName("actionSave")
        self.menu_file.addAction(self.action_exit)
        self.menu_about.addAction(self.action_about)
        self.menu_about.addAction(self.action_About_Qt)
        self.menubar.addAction(self.menu_file.menuAction())
        self.menubar.addAction(self.menu_about.menuAction())

        self.retranslateUi(MainWindow)
        QMetaObject.connectSlotsByName(MainWindow)
        MainWindow.setTabOrder(self.presets_cbox, self.imap_server_le)
        MainWindow.setTabOrder(self.imap_server_le, self.adress_le)
        MainWindow.setTabOrder(self.adress_le, self.pass_le)
        MainWindow.setTabOrder(self.pass_le, self.connect_btn)
        MainWindow.setTabOrder(self.connect_btn, self.log_te)
        MainWindow.setTabOrder(self.log_te, self.since_date_cb)
        MainWindow.setTabOrder(self.since_date_cb, self.since_date_edit)
        MainWindow.setTabOrder(self.since_date_edit, self.before_date_cb)
        MainWindow.setTabOrder(self.before_date_cb, self.before_date_edit)
        MainWindow.setTabOrder(self.before_date_edit, self.mailboxes_lw)
        MainWindow.setTabOrder(self.mailboxes_lw, self.from_le)
        MainWindow.setTabOrder(self.from_le, self.to_le)
        MainWindow.setTabOrder(self.to_le, self.subject_le)
        MainWindow.setTabOrder(self.subject_le, self.search_btn)
        MainWindow.setTabOrder(self.search_btn, self.links_text_edit)
        MainWindow.setTabOrder(self.links_text_edit, self.export_txt_btn)
        MainWindow.setTabOrder(self.export_txt_btn, self.export_html_btn)
        MainWindow.setTabOrder(self.export_html_btn, self.disconnect_btn)
        MainWindow.setTabOrder(self.disconnect_btn, self.add_preset_btn)
        MainWindow.setTabOrder(self.add_preset_btn, self.remove_preset_btn)
        MainWindow.setTabOrder(self.remove_preset_btn, self.ssl_cb)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QApplication.translate("MainWindow", "Email Link Extractor", None, QApplication.UnicodeUTF8))
        self.login_gbox.setTitle(QApplication.translate("MainWindow", "  Login", None, QApplication.UnicodeUTF8))
        self.lb_presets.setText(QApplication.translate("MainWindow", "Server Presets", None, QApplication.UnicodeUTF8))
        self.add_preset_btn.setText(QApplication.translate("MainWindow", "+", None, QApplication.UnicodeUTF8))
        self.remove_preset_btn.setText(QApplication.translate("MainWindow", "-", None, QApplication.UnicodeUTF8))
        self.lb_imap_server.setText(QApplication.translate("MainWindow", "IMAP Server", None, QApplication.UnicodeUTF8))
        self.lb_ssl.setText(QApplication.translate("MainWindow", "SSL", None, QApplication.UnicodeUTF8))
        self.ssl_cb.setText(QApplication.translate("MainWindow", "Port : 993", None, QApplication.UnicodeUTF8))
        self.lb_adress.setText(QApplication.translate("MainWindow", "Adress", None, QApplication.UnicodeUTF8))
        self.lb_pass.setText(QApplication.translate("MainWindow", "Password", None, QApplication.UnicodeUTF8))
        self.connect_btn.setText(QApplication.translate("MainWindow", "Connect", None, QApplication.UnicodeUTF8))
        self.lb_select_mailbox.setText(QApplication.translate("MainWindow", "Select Mailbox", None, QApplication.UnicodeUTF8))

        self.search_gbox.setTitle(QApplication.translate("MainWindow", "  Search Parameters", None, QApplication.UnicodeUTF8))
        self.since_date_cb.setText(QApplication.translate("MainWindow", "Since", None, QApplication.UnicodeUTF8))
        self.since_date_edit.setDisplayFormat(QApplication.translate("MainWindow", "dd-MMM-yyyy", None, QApplication.UnicodeUTF8))
        self.before_date_cb.setText(QApplication.translate("MainWindow", "Before", None, QApplication.UnicodeUTF8))
        self.before_date_edit.setDisplayFormat(QApplication.translate("MainWindow", "dd-MMM-yyyy", None, QApplication.UnicodeUTF8))

        self.html_radio.setText(QApplication.translate("MainWindow", "html", None, QApplication.UnicodeUTF8))
        self.text_radio.setText(QApplication.translate("MainWindow", "text", None, QApplication.UnicodeUTF8))
        # self.lb_threads.setText(QApplication.translate("MainWindow", "Threads", None, QApplication.UnicodeUTF8))

        self.lb_from.setText(QApplication.translate("MainWindow", "From", None, QApplication.UnicodeUTF8))
        self.lb_to.setText(QApplication.translate("MainWindow", "To", None, QApplication.UnicodeUTF8))
        self.lb_subject.setText(QApplication.translate("MainWindow", "Subject", None, QApplication.UnicodeUTF8))
        self.search_btn.setText(QApplication.translate("MainWindow", "Search", None, QApplication.UnicodeUTF8))

        self.links_gbox.setTitle(QApplication.translate("MainWindow", "  Links", None, QApplication.UnicodeUTF8))
        self.export_html_btn.setText(QApplication.translate("MainWindow", "Export as HTML", None, QApplication.UnicodeUTF8))
        self.export_txt_btn.setText(QApplication.translate("MainWindow", "Export as txt", None, QApplication.UnicodeUTF8))
        self.log_gbox.setTitle(QApplication.translate("MainWindow", "  Log", None, QApplication.UnicodeUTF8))
        self.disconnect_btn.setText(QApplication.translate("MainWindow", "Disconnect", None, QApplication.UnicodeUTF8))
        self.menu_file.setTitle(QApplication.translate("MainWindow", "File", None, QApplication.UnicodeUTF8))
        self.menu_about.setTitle(QApplication.translate("MainWindow", "About", None, QApplication.UnicodeUTF8))
        self.action_about.setText(QApplication.translate("MainWindow", "About", None, QApplication.UnicodeUTF8))
        self.action_About_Qt.setText(QApplication.translate("MainWindow", "About Qt", None, QApplication.UnicodeUTF8))
        self.action_exit.setText(QApplication.translate("MainWindow", "Exit", None, QApplication.UnicodeUTF8))
        self.action_exit.setShortcut(QApplication.translate("MainWindow", "Ctrl+Q", None, QApplication.UnicodeUTF8))
        self.actionSave.setText(QApplication.translate("MainWindow", "Save", None, QApplication.UnicodeUTF8))
Example #13
0
    def notifyOntologyAdded(self, ontology):
        """
        Notify that an ontology was added to the index.
        
        Parameter :
        
        - ontology : The added ontology.
        """
        if ontology is None:
            return
        self.addRecentOntology(ontology)
        i = len(self.menuOntology.actions()) - 3
        ontologyMenu = None
        for x in range(i, len(self.menuOntology.actions())):
            a = self.menuOntology.actions()[x]
            if a.text() == ontology.name:
                # Don't need to add menu.
                ontologyMenu = a.menu()
                break

        if ontologyMenu is None:
            ontologyMenu = QMenu(self)
            ontologyMenu.setTitle(ontology.name)
        ontologyMenu.clear()
        # Update action
        icon = QIcon()
        icon.addPixmap(QPixmap(":/actions/gfx/actions/update-product.png"),
                       QIcon.Normal, QIcon.Off)
        actionUpdate = ontologyMenu.addAction("Update")
        actionUpdate.setData(ontology)
        actionUpdate.setIcon(icon)
        actionUpdate.setIconVisibleInMenu(True)
        actionUpdate.triggered.connect(partial(self._updateOntology_,
                                               ontology))
        icon = QIcon()
        icon.addPixmap(QPixmap(":/actions/gfx/actions/document-revert.png"),
                       QIcon.Normal, QIcon.Off)
        actionRevert = ontologyMenu.addAction("Revert")
        actionRevert.setData(ontology)
        actionRevert.setIcon(icon)
        actionRevert.setIconVisibleInMenu(True)
        actionRevert.triggered.connect(
            partial(self._revertOntology_, ontology, ontologyMenu))
        icon = QIcon()
        icon.addPixmap(
            QPixmap(":/actions/gfx/actions/document-properties.png"),
            QIcon.Normal, QIcon.Off)
        actionProperties = ontologyMenu.addAction("Properties")
        actionProperties.setData(ontology)
        actionProperties.setIconVisibleInMenu(True)
        actionProperties.setIcon(icon)
        actionProperties.triggered.connect(
            partial(self._showOntologyProperties_, ontology))
        ontologyMenu.addSeparator()
        # Close action
        icon = QIcon()
        icon.addPixmap(QPixmap(":/actions/gfx/actions/document-close.png"),
                       QIcon.Normal, QIcon.Off)
        actionClose = ontologyMenu.addAction("Close")
        actionClose.setIcon(icon)
        actionClose.setIconVisibleInMenu(True)
        actionClose.setData(ontology)
        actionClose.triggered.connect(
            partial(self._closeOntology_, ontology, ontologyMenu))
        ontologyMenu.addSeparator()
        # Add ontology menu to menu bar
        self.menuOntology.addMenu(ontologyMenu)
Example #14
0
 def __init__(self, parent=None):
     super(Truss, self).__init__(parent)        
     self.resize(800, 600)
     self.filename  = None
     self.filetuple = None
     self.dirty = False  # Refers to Data Page only.
     centralwidget = QWidget(self)
     gridLayout = QGridLayout(centralwidget)
     self.tabWidget = QTabWidget(centralwidget)
     self.tab = QWidget()
     font = QFont()
     font.setFamily("Courier 10 Pitch")
     font.setPointSize(12)
     self.tab.setFont(font)
     gridLayout_3 = QGridLayout(self.tab)
     self.plainTextEdit = QPlainTextEdit(self.tab)
     gridLayout_3.addWidget(self.plainTextEdit, 0, 0, 1, 1)
     self.tabWidget.addTab(self.tab, "")
     self.tab_2 = QWidget()
     self.tab_2.setFont(font)
     gridLayout_2 = QGridLayout(self.tab_2)
     self.plainTextEdit_2 = QPlainTextEdit(self.tab_2)
     gridLayout_2.addWidget(self.plainTextEdit_2, 0, 0, 1, 1)
     self.tabWidget.addTab(self.tab_2, "")
     gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
     self.setCentralWidget(centralwidget)
     menubar = QMenuBar(self)
     menubar.setGeometry(QRect(0, 0, 800, 29))
     menu_File = QMenu(menubar)
     self.menu_Solve = QMenu(menubar)
     self.menu_Help = QMenu(menubar)
     self.setMenuBar(menubar)
     self.statusbar = QStatusBar(self)
     self.setStatusBar(self.statusbar)
     self.action_New = QAction(self)
     self.actionSave_As = QAction(self)
     self.action_Save = QAction(self)
     self.action_Open = QAction(self)
     self.action_Quit = QAction(self)
     self.action_About = QAction(self)
     self.actionShow_CCPL = QAction(self)
     self.action_Solve = QAction(self)
     self.action_CCPL = QAction(self)
     self.action_Help = QAction(self)
     menu_File.addAction(self.action_New)
     menu_File.addAction(self.action_Open)
     menu_File.addAction(self.actionSave_As)
     menu_File.addAction(self.action_Save)
     menu_File.addSeparator()
     menu_File.addAction(self.action_Quit)
     self.menu_Solve.addAction(self.action_Solve)
     self.menu_Help.addAction(self.action_About)
     self.menu_Help.addAction(self.action_CCPL)
     self.menu_Help.addAction(self.action_Help)
     menubar.addAction(menu_File.menuAction())
     menubar.addAction(self.menu_Solve.menuAction())
     menubar.addAction(self.menu_Help.menuAction())        
     self.setWindowTitle("Main Window")
     self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),\
                                "Data Page")
     self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),\
                                "Solution Page")        
     menu_File.setTitle("&File")        
     self.menu_Solve.setTitle("&Solve")
     self.menu_Help.setTitle("&Help")
     self.tabWidget.setCurrentIndex(0)
     self.action_New.setText("&New") 
     self.action_Open.setText("&Open")       
     self.actionSave_As.setText("Save &As")
     self.action_Save.setText("&Save")
     self.action_Quit.setText("&Quit")        
     self.action_Solve.setText("&Solve")
     self.action_About.setText("&About")
     self.action_CCPL.setText("&CCPL")
     self.action_Help.setText("&Help")
     self.action_Quit.triggered.connect(self.close)
     allToolBar = self.addToolBar("AllToolBar") 
     allToolBar.setObjectName("AllToolBar") 
     self.addActions(allToolBar, (self.action_Open, self.actionSave_As,\
                     self.action_Save, self.action_Solve,\
                     self.action_Quit ))
     self.action_New.triggered.connect(self.fileNew)
     self.action_Open.triggered.connect(self.fileOpen)
     self.actionSave_As.triggered.connect(self.fileSaveAs)
     self.action_Save.triggered.connect(self.fileSave)
     self.action_Solve.triggered.connect(self.trussSolve)
     self.action_About.triggered.connect(self.aboutBox)
     self.action_CCPL.triggered.connect(self.displayCCPL)
     self.action_Help.triggered.connect(self.help)
     self.plainTextEdit.textChanged.connect(self.setDirty)
     self.action_New = self.editAction(self.action_New, None,\
                         'ctrl+N', 'filenew', 'New File.')   
     self.action_Open = self.editAction(self.action_Open, None, 
                         'ctrl+O', 'fileopen', 'Open File.')
     self.actionSave_As = self.editAction(self.actionSave_As,\
                         None, 'ctrl+A', 'filesaveas',\
                         'Save and Name File.')
     self.action_Save = self.editAction(self.action_Save, None, 
                         'ctrl+S', 'filesave', 'Save File.')
     self.action_Solve = self.editAction(self.action_Solve, None, 
                         'ctrl+L', 'solve', 'Solve Structure.')                                   
     self.action_About = self.editAction(self.action_About, None, 
                         'ctrl+B', 'about','Pop About Box.')                                  
     self.action_CCPL = self.editAction(self.action_CCPL, None, 
                         'ctrl+G', 'licence', 'Show Licence') 
     self.action_Help = self.editAction(self.action_Help, None, 
                         'ctrl+H', 'help', 'Show Help Page.')
     self.action_Quit =  self.editAction(self.action_Quit, None, 
                         'ctrl+Q', 'quit', 'Quit the program.')                                           
     self.plainTextEdit_2.setReadOnly(True)
Example #15
0
class Truss(QMainWindow):
    def __init__(self, parent=None):
        super(Truss, self).__init__(parent)        
        self.resize(800, 600)
        self.filename  = None
        self.filetuple = None
        self.dirty = False  # Refers to Data Page only.
        centralwidget = QWidget(self)
        gridLayout = QGridLayout(centralwidget)
        self.tabWidget = QTabWidget(centralwidget)
        self.tab = QWidget()
        font = QFont()
        font.setFamily("Courier 10 Pitch")
        font.setPointSize(12)
        self.tab.setFont(font)
        gridLayout_3 = QGridLayout(self.tab)
        self.plainTextEdit = QPlainTextEdit(self.tab)
        gridLayout_3.addWidget(self.plainTextEdit, 0, 0, 1, 1)
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QWidget()
        self.tab_2.setFont(font)
        gridLayout_2 = QGridLayout(self.tab_2)
        self.plainTextEdit_2 = QPlainTextEdit(self.tab_2)
        gridLayout_2.addWidget(self.plainTextEdit_2, 0, 0, 1, 1)
        self.tabWidget.addTab(self.tab_2, "")
        gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
        self.setCentralWidget(centralwidget)
        menubar = QMenuBar(self)
        menubar.setGeometry(QRect(0, 0, 800, 29))
        menu_File = QMenu(menubar)
        self.menu_Solve = QMenu(menubar)
        self.menu_Help = QMenu(menubar)
        self.setMenuBar(menubar)
        self.statusbar = QStatusBar(self)
        self.setStatusBar(self.statusbar)
        self.action_New = QAction(self)
        self.actionSave_As = QAction(self)
        self.action_Save = QAction(self)
        self.action_Open = QAction(self)
        self.action_Quit = QAction(self)
        self.action_About = QAction(self)
        self.actionShow_CCPL = QAction(self)
        self.action_Solve = QAction(self)
        self.action_CCPL = QAction(self)
        self.action_Help = QAction(self)
        menu_File.addAction(self.action_New)
        menu_File.addAction(self.action_Open)
        menu_File.addAction(self.actionSave_As)
        menu_File.addAction(self.action_Save)
        menu_File.addSeparator()
        menu_File.addAction(self.action_Quit)
        self.menu_Solve.addAction(self.action_Solve)
        self.menu_Help.addAction(self.action_About)
        self.menu_Help.addAction(self.action_CCPL)
        self.menu_Help.addAction(self.action_Help)
        menubar.addAction(menu_File.menuAction())
        menubar.addAction(self.menu_Solve.menuAction())
        menubar.addAction(self.menu_Help.menuAction())        
        self.setWindowTitle("Main Window")
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab),\
                                   "Data Page")
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2),\
                                   "Solution Page")        
        menu_File.setTitle("&File")        
        self.menu_Solve.setTitle("&Solve")
        self.menu_Help.setTitle("&Help")
        self.tabWidget.setCurrentIndex(0)
        self.action_New.setText("&New") 
        self.action_Open.setText("&Open")       
        self.actionSave_As.setText("Save &As")
        self.action_Save.setText("&Save")
        self.action_Quit.setText("&Quit")        
        self.action_Solve.setText("&Solve")
        self.action_About.setText("&About")
        self.action_CCPL.setText("&CCPL")
        self.action_Help.setText("&Help")
        self.action_Quit.triggered.connect(self.close)
        allToolBar = self.addToolBar("AllToolBar") 
        allToolBar.setObjectName("AllToolBar") 
        self.addActions(allToolBar, (self.action_Open, self.actionSave_As,\
                        self.action_Save, self.action_Solve,\
                        self.action_Quit ))
        self.action_New.triggered.connect(self.fileNew)
        self.action_Open.triggered.connect(self.fileOpen)
        self.actionSave_As.triggered.connect(self.fileSaveAs)
        self.action_Save.triggered.connect(self.fileSave)
        self.action_Solve.triggered.connect(self.trussSolve)
        self.action_About.triggered.connect(self.aboutBox)
        self.action_CCPL.triggered.connect(self.displayCCPL)
        self.action_Help.triggered.connect(self.help)
        self.plainTextEdit.textChanged.connect(self.setDirty)
        self.action_New = self.editAction(self.action_New, None,\
                            'ctrl+N', 'filenew', 'New File.')   
        self.action_Open = self.editAction(self.action_Open, None, 
                            'ctrl+O', 'fileopen', 'Open File.')
        self.actionSave_As = self.editAction(self.actionSave_As,\
                            None, 'ctrl+A', 'filesaveas',\
                            'Save and Name File.')
        self.action_Save = self.editAction(self.action_Save, None, 
                            'ctrl+S', 'filesave', 'Save File.')
        self.action_Solve = self.editAction(self.action_Solve, None, 
                            'ctrl+L', 'solve', 'Solve Structure.')                                   
        self.action_About = self.editAction(self.action_About, None, 
                            'ctrl+B', 'about','Pop About Box.')                                  
        self.action_CCPL = self.editAction(self.action_CCPL, None, 
                            'ctrl+G', 'licence', 'Show Licence') 
        self.action_Help = self.editAction(self.action_Help, None, 
                            'ctrl+H', 'help', 'Show Help Page.')
        self.action_Quit =  self.editAction(self.action_Quit, None, 
                            'ctrl+Q', 'quit', 'Quit the program.')                                           
        self.plainTextEdit_2.setReadOnly(True)
    
    def setDirty(self):
        '''On change of text in textEdit window, set the flag
        "dirty" to True'''
        index = self.tabWidget.currentIndex()
        if index is not 0:
            return
        if self.dirty:
            return True
        self.dirty = True
        self.updateStatus('self.dirty set to True')    
    
    def clearDirty(self):
        'Clear dirty flag'
        self.dirty = False
    
    def fileNew(self):
        '''Clear both Data Page and Solution Page.'''
        self.plainTextEdit.setPlainText(' ')
        self.plainTextEdit_2.setPlainText(' ')
        self.clearDirty(self)

    def okToContinue(self):
        if self.dirty:
            reply = QMessageBox.question(self,
                    "Data Loader - Unsaved Changes",
                    "Save unsaved changes?",
                    QMessageBox.Yes|QMessageBox.No|QMessageBox.Cancel)
            if reply == QMessageBox.Cancel:
                return False
            elif reply == QMessageBox.Yes:
                self.clearDirty()
                return self.fileSave()
        return True
    
    def okRead(self):
        'Pop-up a warning message.'
        reply = QMessageBox.warning(self,
                "Warning",
                '''\nFile Open and Save is possible only in Data Page!
\n\(Use SaveAs for Solution Page)''', QMessageBox.Ok)
        return True

    def fileOpen(self):
        '''Open a file in Data Page (with index == 0)'''
        if self.tabWidget.currentIndex():
            self.okRead()
            return
        if not self.okToContinue():
            return
        dir = (os.path.dirname(self.filename)
               if self.filename is not None else ".")
        self.filetuple = QFileDialog.getOpenFileName(self,\
                        "Open File", dir, \
                        "Data (*.dat *.txt)\nAll Files (*.*)")
        self.filename = self.filetuple[0] 
        fname = self.filename        
#  QFileDialog returns a tuple x with x[0] = file name and 
#  x[1] = type of filter.
        if fname:
            self.loadFile(fname)
            self.filename = fname
            self.updateStatus('New file opened.')
                
    def loadFile(self, fname=None):
        fl = open(fname)
        text = fl.read()
        self.plainTextEdit.setPlainText(text)
        self.dirty = False
    
    def fileSave(self):
        '''Save file with current file name.'''
        if self.tabWidget.currentIndex():
            self.okRead()
            return        
        if self.filename is None:
            return self.fileSaveAs()
        else:
            flname = self.filename
            if flname:
                with open(flname, 'w') as fl:
                    fl.write(tempText)
                self.dirty = False
                self.updateStatus('File saved.')
                return True
            else:
                self.updateStatus('Failed to save... ')
                return False
        self.filename = None
        self.dirty = False

    def fileSaveAs(self):        
        '''Save file with a new name.'''
        qpr = self.qprintline
        fname = self.filename if self.filename is not None else\
        "NoName"
        self.filetuple = QFileDialog.getSaveFileName(self,
                "Truss program - Save File", fname, "Data File (*.*)")
        flname = self.filetuple[0]        
        index = self.tabWidget.currentIndex()
        if index == 0:
            self.filename = flname 
            if flname:
                fl = open(flname, 'w')
                tempText = self.plainTextEdit.toPlainText()
                fl.write(tempText)
                fl.close()
                self.dirty = False
                self.updateStatus('File saved.')   
        elif index == 1:
            if flname:
                fl = open(flname, 'w')
                tempText = self.plainTextEdit_2.toPlainText()
                fl.write(tempText)
                fl.close()

    def trussSolve(self):
        '''Solve a statically determinate truss, specified in
        Data Page and display the results in the Solution Page.
        To start, make a copy of the Data Page with a header all
        shown on the Data Page.'''
        printline = self.qprintline
        dataBall = self.plainTextEdit.toPlainText() 
        self.plainTextEdit_2.clear()
        printline('================================') 
        flbase = os.path.basename(self.filename)
        printline('SOLUTION FOR ' + flbase)
        printline('================================') 
        dataBall = self.plainTextEdit.toPlainText()
        ncrunch.main(printline, self.filename, dataBall)

    def aboutBox(self):
        '''Popup a box with about message.'''
        QMessageBox.about(self, "About PySide, Platform and the like",
                """<b>Part of Structural Analysis.</b> v %s
                <p>Copyright &copy; 2011 Algis Kabaila. 
                All rights reserved in accordance with
                Creative Commons Attribution Licence (CCPL) v3
                or later - NO WARRANTIES!
                <p>This progam finds bar forces in 
                statically determinate trusses.                
                <p>Python %s -  PySide version %s - Qt version %s on\
                %s""" % (__version__, platform.python_version(),\
                PySide.__version__,  PySide.QtCore.__version__,
                platform.system()))
              
    def displayCCPL(self):
        '''Read and display CCPL licence.'''
        self.plainTextEdit.setPlainText(open('CCPL.txt').read())
        self.dirty = False
        self.filename = 'COPYING.txt'
        self.updateStatus('CCPL displayed.')

    def help(self):
        '''Read and display a help file- currently the README.txt.'''
        self.plainTextEdit.setPlainText(open('README.md').read())
        self.dirty = False
        self.filename = 'README.txt'
        self.updateStatus('README displayed.')
        
    def addActions(self, target, actions):
        '''Actions are added to Tool Bar.'''
        for action in actions:
            if action is None:
                target.addSeparator()
            else:
                target.addAction(action)
    
    def editAction(self, action, slot=None, shortcut=None, icon=None,
                     tip=None):
        '''This method adds to action: icon, shortcut, ToolTip,\
        StatusTip and can connect triggered action to slot '''
        if icon is not None:
            action.setIcon(QIcon(":/%s.png" % (icon)))
        if shortcut is not None:
            action.setShortcut(shortcut)
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            action.triggered.connect(slot)                        
        return action

    def qreadline(self, lineNo):
        '''Read one line from Data Page (lineNo starts with 0)'''
        return unicode(self.plainTextEdit.document().\
            findBlockByLineNumber(lineNo).text()).rstrip()

    def qprintline(self, line):        
        '''Append one line to Solution Page.'''
        self.plainTextEdit_2.appendPlainText(line.rstrip())

    def updateStatus(self, message):
        '''Keep status current.'''
        if self.filename is not None:
            flbase = os.path.basename(self.filename)
            self.setWindowTitle(unicode("Truss Analysis - " +\
                                         flbase + "[*]") )
            self.statusBar().showMessage(message, 5000)
            self.setWindowModified(self.dirty)