eric6/Preferences/ToolConfigurationDialog.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
child 7229
53054eb5b15a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric6/Preferences/ToolConfigurationDialog.py	Sun Apr 14 15:09:21 2019 +0200
@@ -0,0 +1,395 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2002 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a configuration dialog for the tools menu.
+"""
+
+from __future__ import unicode_literals
+
+import copy
+
+from PyQt5.QtCore import Qt, pyqtSlot
+from PyQt5.QtWidgets import QDialog
+
+from E5Gui import E5MessageBox
+from E5Gui.E5PathPicker import E5PathPickerModes
+
+from .Ui_ToolConfigurationDialog import Ui_ToolConfigurationDialog
+
+import Utilities
+
+
+class ToolConfigurationDialog(QDialog, Ui_ToolConfigurationDialog):
+    """
+    Class implementing a configuration dialog for the tools menu.
+    """
+    def __init__(self, toollist, parent=None):
+        """
+        Constructor
+        
+        @param toollist list of configured tools
+        @param parent parent widget (QWidget)
+        """
+        super(ToolConfigurationDialog, self).__init__(parent)
+        self.setupUi(self)
+        
+        self.iconPicker.setMode(E5PathPickerModes.OpenFileMode)
+        self.iconPicker.setFilters(self.tr("Icon files (*.png)"))
+        self.executablePicker.setMode(E5PathPickerModes.OpenFileMode)
+        
+        self.redirectionModes = [
+            ("no", self.tr("no redirection")),
+            ("show", self.tr("show output")),
+            ("insert", self.tr("insert into current editor")),
+            ("replaceSelection",
+             self.tr("replace selection of current editor")),
+        ]
+        
+        self.toollist = copy.deepcopy(toollist)
+        for tool in toollist:
+            self.toolsList.addItem(tool['menutext'])
+        
+        for mode in self.redirectionModes:
+            self.redirectCombo.addItem(mode[1])
+        
+        if len(toollist):
+            self.toolsList.setCurrentRow(0)
+            self.on_toolsList_currentRowChanged(0)
+        
+        t = self.argumentsEdit.whatsThis()
+        if t:
+            t += Utilities.getPercentReplacementHelp()
+            self.argumentsEdit.setWhatsThis(t)
+        
+    def __findModeIndex(self, shortName):
+        """
+        Private method to find the mode index by its short name.
+        
+        @param shortName short name of the mode (string)
+        @return index of the mode (integer)
+        """
+        ind = 0
+        for mode in self.redirectionModes:
+            if mode[0] == shortName:
+                return ind
+            ind += 1
+        return 1    # default is "show output"
+        
+    @pyqtSlot()
+    def on_newButton_clicked(self):
+        """
+        Private slot to clear all entry fields.
+        """
+        self.executablePicker.clear()
+        self.menuEdit.clear()
+        self.iconPicker.clear()
+        self.argumentsEdit.clear()
+        self.redirectCombo.setCurrentIndex(1)
+        
+    @pyqtSlot()
+    def on_addButton_clicked(self):
+        """
+        Private slot to add a new entry.
+        """
+        menutext = self.menuEdit.text()
+        icon = self.iconPicker.text()
+        executable = self.executablePicker.text()
+        arguments = self.argumentsEdit.text()
+        redirect = self.redirectionModes[self.redirectCombo.currentIndex()][0]
+        
+        if not executable:
+            E5MessageBox.critical(
+                self,
+                self.tr("Add tool entry"),
+                self.tr(
+                    "You have to set an executable to add to the"
+                    " Tools-Menu first."))
+            return
+        
+        if not menutext:
+            E5MessageBox.critical(
+                self,
+                self.tr("Add tool entry"),
+                self.tr(
+                    "You have to insert a menuentry text to add the"
+                    " selected program to the Tools-Menu first."))
+            return
+        
+        if not Utilities.isinpath(executable):
+            E5MessageBox.critical(
+                self,
+                self.tr("Add tool entry"),
+                self.tr(
+                    "The selected file could not be found or"
+                    " is not an executable."
+                    " Please choose an executable filename."))
+            return
+        
+        if len(self.toolsList.findItems(
+                menutext, Qt.MatchFlags(Qt.MatchExactly))):
+            E5MessageBox.critical(
+                self,
+                self.tr("Add tool entry"),
+                self.tr("An entry for the menu text {0} already exists.")
+                .format(menutext))
+            return
+        
+        self.toolsList.addItem(menutext)
+        tool = {
+            'menutext': menutext,
+            'icon': icon,
+            'executable': executable,
+            'arguments': arguments,
+            'redirect': redirect,
+        }
+        self.toollist.append(tool)
+        
+    @pyqtSlot()
+    def on_changeButton_clicked(self):
+        """
+        Private slot to change an entry.
+        """
+        row = self.toolsList.currentRow()
+        if row < 0:
+            return
+        
+        menutext = self.menuEdit.text()
+        icon = self.iconPicker.text()
+        executable = self.executablePicker.text()
+        arguments = self.argumentsEdit.text()
+        redirect = self.redirectionModes[self.redirectCombo.currentIndex()][0]
+        
+        if not executable:
+            E5MessageBox.critical(
+                self,
+                self.tr("Change tool entry"),
+                self.tr(
+                    "You have to set an executable to change the"
+                    " Tools-Menu entry."))
+            return
+            
+        if not menutext:
+            E5MessageBox.critical(
+                self,
+                self.tr("Change tool entry"),
+                self.tr(
+                    "You have to insert a menuentry text to change the"
+                    " selected Tools-Menu entry."))
+            return
+            
+        if not Utilities.isinpath(executable):
+            E5MessageBox.critical(
+                self,
+                self.tr("Change tool entry"),
+                self.tr(
+                    "The selected file could not be found or"
+                    " is not an executable."
+                    " Please choose an existing executable filename."))
+            return
+            
+        self.toollist[row] = {
+            'menutext': menutext,
+            'icon': icon,
+            'executable': executable,
+            'arguments': arguments,
+            'redirect': redirect,
+        }
+        self.toolsList.currentItem().setText(menutext)
+        self.changeButton.setEnabled(False)
+        
+    @pyqtSlot()
+    def on_deleteButton_clicked(self):
+        """
+        Private slot to delete the selected entry.
+        """
+        row = self.toolsList.currentRow()
+        if row < 0:
+            return
+        
+        del self.toollist[row]
+        itm = self.toolsList.takeItem(row)
+        del itm
+        if row >= len(self.toollist):
+            row -= 1
+        self.toolsList.setCurrentRow(row)
+        self.on_toolsList_currentRowChanged(row)
+        
+    @pyqtSlot()
+    def on_downButton_clicked(self):
+        """
+        Private slot to move an entry down in the list.
+        """
+        curr = self.toolsList.currentRow()
+        self.__swap(curr, curr + 1)
+        self.toolsList.clear()
+        for tool in self.toollist:
+            self.toolsList.addItem(tool['menutext'])
+        self.toolsList.setCurrentRow(curr + 1)
+        if curr + 1 == len(self.toollist):
+            self.downButton.setEnabled(False)
+        self.upButton.setEnabled(True)
+        
+    @pyqtSlot()
+    def on_upButton_clicked(self):
+        """
+        Private slot to move an entry up in the list.
+        """
+        curr = self.toolsList.currentRow()
+        self.__swap(curr - 1, curr)
+        self.toolsList.clear()
+        for tool in self.toollist:
+            self.toolsList.addItem(tool['menutext'])
+        self.toolsList.setCurrentRow(curr - 1)
+        if curr - 1 == 0:
+            self.upButton.setEnabled(False)
+        self.downButton.setEnabled(True)
+        
+    @pyqtSlot()
+    def on_separatorButton_clicked(self):
+        """
+        Private slot to add a menu separator.
+        """
+        self.toolsList.addItem('--')
+        tool = {
+            'menutext': '--',
+            'icon': '',
+            'executable': '',
+            'arguments': '',
+            'redirect': 'no',
+        }
+        self.toollist.append(tool)
+    
+    @pyqtSlot(str)
+    def on_executablePicker_pathSelected(self, path):
+        """
+        Private slot to check the executable after it has been selected.
+        
+        @param path path of the executable
+        @type str
+        """
+        if path:
+            if not Utilities.isinpath(path):
+                E5MessageBox.critical(
+                    self,
+                    self.tr("Select executable"),
+                    self.tr(
+                        "The selected file is not an executable."
+                        " Please choose an executable filename."))
+    
+    def on_toolsList_currentRowChanged(self, row):
+        """
+        Private slot to set the lineedits depending on the selected entry.
+        
+        @param row the row of the selected entry (integer)
+        """
+        if row >= 0 and row < len(self.toollist):
+            if self.toollist[row]['menutext'] == '--':
+                self.executablePicker.clear()
+                self.menuEdit.clear()
+                self.iconPicker.clear()
+                self.argumentsEdit.clear()
+                self.redirectCombo.setCurrentIndex(0)
+            else:
+                tool = self.toollist[row]
+                self.menuEdit.setText(tool['menutext'])
+                self.iconPicker.setText(tool['icon'])
+                self.executablePicker.setText(tool['executable'])
+                self.argumentsEdit.setText(tool['arguments'])
+                self.redirectCombo.setCurrentIndex(
+                    self.__findModeIndex(tool['redirect']))
+            
+            self.changeButton.setEnabled(False)
+            self.deleteButton.setEnabled(True)
+            
+            if row != 0:
+                self.upButton.setEnabled(True)
+            else:
+                self.upButton.setEnabled(False)
+            
+            if row + 1 != len(self.toollist):
+                self.downButton.setEnabled(True)
+            else:
+                self.downButton.setEnabled(False)
+        else:
+            self.executablePicker.clear()
+            self.menuEdit.clear()
+            self.iconPicker.clear()
+            self.argumentsEdit.clear()
+            self.downButton.setEnabled(False)
+            self.upButton.setEnabled(False)
+            self.deleteButton.setEnabled(False)
+            self.changeButton.setEnabled(False)
+        
+    def __toolEntryChanged(self):
+        """
+        Private slot to perform actions when a tool entry was changed.
+        """
+        row = self.toolsList.currentRow()
+        if row >= 0 and \
+           row < len(self.toollist) and \
+           self.toollist[row]['menutext'] != '--':
+            self.changeButton.setEnabled(True)
+        
+    def on_menuEdit_textChanged(self, text):
+        """
+        Private slot called, when the menu text was changed.
+        
+        @param text the new text (string) (ignored)
+        """
+        self.__toolEntryChanged()
+        
+    def on_iconPicker_textChanged(self, text):
+        """
+        Private slot called, when the icon path was changed.
+        
+        @param text the new text (string) (ignored)
+        """
+        self.__toolEntryChanged()
+        
+    def on_executablePicker_textChanged(self, text):
+        """
+        Private slot called, when the executable was changed.
+        
+        @param text the new text (string) (ignored)
+        """
+        self.__toolEntryChanged()
+        
+    def on_argumentsEdit_textChanged(self, text):
+        """
+        Private slot called, when the arguments string was changed.
+        
+        @param text the new text (string) (ignored)
+        """
+        self.__toolEntryChanged()
+        
+    @pyqtSlot(int)
+    def on_redirectCombo_currentIndexChanged(self, index):
+        """
+        Private slot called, when the redirection mode was changed.
+        
+        @param index the selected mode index (integer) (ignored)
+        """
+        self.__toolEntryChanged()
+        
+    def getToollist(self):
+        """
+        Public method to retrieve the tools list.
+        
+        @return a list of tuples containing the menu text, the executable,
+            the executables arguments and a redirection flag
+        """
+        return self.toollist[:]
+        
+    def __swap(self, itm1, itm2):
+        """
+        Private method used two swap two list entries given by their index.
+        
+        @param itm1 index of first entry (int)
+        @param itm2 index of second entry (int)
+        """
+        tmp = self.toollist[itm1]
+        self.toollist[itm1] = self.toollist[itm2]
+        self.toollist[itm2] = tmp

eric ide

mercurial