Ejemplo n.º 1
0
class ValidatedDialog(QDialog):
    """
    A dialog for creating a validated new value. Performs validation of name against a provided.
    Can be used to select from the list or for creating a new value that is not on the list.

    """

    INVALID_COLOR = QColor(255, 235, 235)

    def __init__(self, title = "Title", description = "Description", unique_names = None, choose_from_list=False):
        QDialog.__init__(self)
        self.setModal(True)
        self.setWindowTitle(title)
        # self.setMinimumWidth(250)
        # self.setMinimumHeight(150)

        if unique_names is None:
            unique_names = []

        self.unique_names = unique_names
        self.choose_from_list = choose_from_list

        self.layout = QFormLayout()
        self.layout.setSizeConstraint(QLayout.SetFixedSize)

        label = QLabel(description)
        label.setAlignment(Qt.AlignHCenter)
        
        self.layout.addRow(self.createSpace(5))
        self.layout.addRow(label)
        self.layout.addRow(self.createSpace(10))


        buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
        self.ok_button = buttons.button(QDialogButtonBox.Ok)
        self.ok_button.setEnabled(False)


        if choose_from_list:
            self.param_name_combo = QComboBox()
            self.connect(self.param_name_combo, SIGNAL('currentIndexChanged(QString)'), self.validateChoice)
            for item in unique_names:
                self.param_name_combo.addItem(item)
            self.layout.addRow("Job:", self.param_name_combo)
        else:
            self.param_name = QLineEdit(self)
            self.param_name.setFocus()
            self.connect(self.param_name, SIGNAL('textChanged(QString)'), self.validateName)
            self.validColor = self.param_name.palette().color(self.param_name.backgroundRole())

            self.layout.addRow("Name:", self.param_name)

        self.layout.addRow(self.createSpace(10))


        self.layout.addRow(buttons)

        self.connect(buttons, SIGNAL('accepted()'), self.accept)
        self.connect(buttons, SIGNAL('rejected()'), self.reject)



        self.setLayout(self.layout)

    def notValid(self, msg):
        """Called when the name is not valid."""
        self.ok_button.setEnabled(False)
        palette = self.param_name.palette()
        palette.setColor(self.param_name.backgroundRole(), self.INVALID_COLOR)
        self.param_name.setToolTip(msg)
        self.param_name.setPalette(palette)

    def valid(self):
        """Called when the name is valid."""
        self.ok_button.setEnabled(True)
        palette = self.param_name.palette()
        palette.setColor(self.param_name.backgroundRole(), self.validColor)
        self.param_name.setToolTip("")
        self.param_name.setPalette(palette)

    def validateName(self, value):
        """Called to perform validation of a name. For specific needs override this function and call valid() and notValid(msg)."""
        value = str(value)

        if value == "":
            self.notValid("Can not be empty!")
        elif not value.find(" ") == -1:
            self.notValid("No spaces allowed!")
        elif value in self.unique_names:
            self.notValid("Name must be unique!")
        else:
            self.valid()

    def validateChoice(self, choice):
        """Only called when using selection mode."""
        self.ok_button.setEnabled(not choice == "")
            

    def getName(self):
        """Return the new name chosen by the user"""
        if self.choose_from_list:
            return str(self.param_name_combo.currentText())
        else:
            return str(self.param_name.text())

    def showAndTell(self):
        """Shows the dialog and returns the result"""
        if self.exec_():
            return str(self.getName()).strip()

        return ""

    def createSpace(self, size = 5):
        """Creates a widget that can be used as spacing on  a panel."""
        qw = QWidget()
        qw.setMinimumSize(QSize(size, size))

        return qw
Ejemplo n.º 2
0
class ValidatedDialog(QDialog):
    """
    A dialog for creating a validated new value. Performs validation of name against a provided.
    Can be used to select from the list or for creating a new value that is not on the list.

    """

    INVALID_COLOR = QColor(255, 235, 235)

    def __init__(self,
                 title="Title",
                 description="Description",
                 unique_names=None,
                 choose_from_list=False):
        QDialog.__init__(self)
        self.setModal(True)
        self.setWindowTitle(title)
        # self.setMinimumWidth(250)
        # self.setMinimumHeight(150)

        if unique_names is None:
            unique_names = []

        self.unique_names = unique_names
        self.choose_from_list = choose_from_list

        self.layout = QFormLayout()
        self.layout.setSizeConstraint(QLayout.SetFixedSize)

        label = QLabel(description)
        label.setAlignment(Qt.AlignHCenter)

        self.layout.addRow(self.createSpace(5))
        self.layout.addRow(label)
        self.layout.addRow(self.createSpace(10))

        buttons = QDialogButtonBox(
            QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
        self.ok_button = buttons.button(QDialogButtonBox.Ok)
        self.ok_button.setEnabled(False)

        if choose_from_list:
            self.param_name_combo = QComboBox()
            self.connect(self.param_name_combo,
                         SIGNAL('currentIndexChanged(QString)'),
                         self.validateChoice)
            for item in unique_names:
                self.param_name_combo.addItem(item)
            self.layout.addRow("Job:", self.param_name_combo)
        else:
            self.param_name = QLineEdit(self)
            self.param_name.setFocus()
            self.connect(self.param_name, SIGNAL('textChanged(QString)'),
                         self.validateName)
            self.validColor = self.param_name.palette().color(
                self.param_name.backgroundRole())

            self.layout.addRow("Name:", self.param_name)

        self.layout.addRow(self.createSpace(10))

        self.layout.addRow(buttons)

        self.connect(buttons, SIGNAL('accepted()'), self.accept)
        self.connect(buttons, SIGNAL('rejected()'), self.reject)

        self.setLayout(self.layout)

    def notValid(self, msg):
        """Called when the name is not valid."""
        self.ok_button.setEnabled(False)
        palette = self.param_name.palette()
        palette.setColor(self.param_name.backgroundRole(), self.INVALID_COLOR)
        self.param_name.setToolTip(msg)
        self.param_name.setPalette(palette)

    def valid(self):
        """Called when the name is valid."""
        self.ok_button.setEnabled(True)
        palette = self.param_name.palette()
        palette.setColor(self.param_name.backgroundRole(), self.validColor)
        self.param_name.setToolTip("")
        self.param_name.setPalette(palette)

    def validateName(self, value):
        """Called to perform validation of a name. For specific needs override this function and call valid() and notValid(msg)."""
        value = str(value)

        if value == "":
            self.notValid("Can not be empty!")
        elif not value.find(" ") == -1:
            self.notValid("No spaces allowed!")
        elif value in self.unique_names:
            self.notValid("Name must be unique!")
        else:
            self.valid()

    def validateChoice(self, choice):
        """Only called when using selection mode."""
        self.ok_button.setEnabled(not choice == "")

    def getName(self):
        """Return the new name chosen by the user"""
        if self.choose_from_list:
            return str(self.param_name_combo.currentText())
        else:
            return str(self.param_name.text())

    def showAndTell(self):
        """Shows the dialog and returns the result"""
        if self.exec_():
            return str(self.getName()).strip()

        return ""

    def createSpace(self, size=5):
        """Creates a widget that can be used as spacing on  a panel."""
        qw = QWidget()
        qw.setMinimumSize(QSize(size, size))

        return qw
Ejemplo n.º 3
0
class PathChooser(HelpedWidget):
    """
    PathChooser: shows, enables choosing of and validates paths.
    The data structure expected and sent to the models getValue and setValue is a string.
    """

    PATH_DOES_NOT_EXIST_MSG = "The specified path does not exist."
    FILE_IS_NOT_EXECUTABLE_MSG = "The specified file is not an executable."
    PATH_IS_NOT_A_FILE_MSG = "The specified path must be a file."
    PATH_IS_NOT_ABSOLUTE_MSG = "The specified path must be an absolute path."
    PATH_IS_NOT_A_DIRECTORY_MSG = "The specified path must be a directory."
    REQUIRED_FIELD_MSG = "A path is required."

    #    UNDEFINED = 0
    #    REQUIRED = 1
    #    FILE = 2
    #    DIRECTORY = 4
    #    MUST_EXIST = 8
    #    EXECUTABLE = 16

    def __init__(self, model, path_label="Path", help_link=""):
        HelpedWidget.__init__(self, path_label, help_link)

        self.__editing = True
        self.__valid = True

        self.path_line = QLineEdit()
        self.path_line.setMinimumWidth(250)

        self.addWidget(self.path_line)

        dialog_button = QToolButton(self)
        dialog_button.setIcon(resourceIcon("ide/small/folder"))
        dialog_button.setIconSize(QSize(16, 16))
        self.connect(dialog_button, SIGNAL('clicked()'), self.selectPath)
        self.addWidget(dialog_button)

        self.valid_color = self.path_line.palette().color(
            self.path_line.backgroundRole())

        self.path_line.setText(os.getcwd())
        self.__editing = False

        assert isinstance(model, PathModelMixin)
        self.model = model
        model.observable().attach(PathModelMixin.PATH_CHANGED_EVENT,
                                  self.getPathFromModel)

        self.connect(self.path_line, SIGNAL('editingFinished()'),
                     self.validatePath)
        self.connect(self.path_line, SIGNAL('editingFinished()'),
                     self.contentsChanged)
        self.connect(self.path_line, SIGNAL('textChanged(QString)'),
                     self.validatePath)

        self.getPathFromModel()

    def isPathValid(self, path):
        """ @rtype: tuple of (bool, str) """
        path = path.strip()
        path_exists = os.path.exists(path)
        is_file = os.path.isfile(path)
        is_directory = os.path.isdir(path)
        is_executable = os.access(path, os.X_OK)
        is_absolute = os.path.isabs(path)

        valid = True
        message = ""

        if path == "":
            if self.model.pathIsRequired():
                valid = False
                message = PathChooser.REQUIRED_FIELD_MSG
        elif not path_exists:
            if self.model.pathMustExist():
                valid = False
                message = PathChooser.PATH_DOES_NOT_EXIST_MSG
            #todo: check if new (non-existing) file has directory or file format?
        elif path_exists:
            if self.model.pathMustBeExecutable(
            ) and is_file and not is_executable:
                valid = False
                message = PathChooser.FILE_IS_NOT_EXECUTABLE_MSG
            elif self.model.pathMustBeADirectory() and not is_directory:
                valid = False
                message = PathChooser.PATH_IS_NOT_A_DIRECTORY_MSG
            elif self.model.pathMustBeAbsolute() and not is_absolute:
                valid = False
                message = PathChooser.PATH_IS_NOT_ABSOLUTE_MSG
            elif self.model.pathMustBeAFile() and not is_file:
                valid = False
                message = PathChooser.PATH_IS_NOT_A_FILE_MSG

        return valid, message

    def validatePath(self):
        """Called whenever the path is modified"""
        palette = self.path_line.palette()

        valid, message = self.isPathValid(self.getPath())

        validity_type = self.WARNING

        if not valid:
            color = self.ERROR_COLOR
        else:
            color = self.valid_color

        self.__valid = valid

        self.setValidationMessage(message, validity_type)
        self.path_line.setToolTip(message)
        palette.setColor(self.path_line.backgroundRole(), color)

        self.path_line.setPalette(palette)

    def getPath(self):
        """Returns the path"""
        return os.path.expanduser(str(self.path_line.text()).strip())

    def pathExists(self):
        """Returns True if the entered path exists"""
        return os.path.exists(self.getPath())

    def isValid(self):
        """Returns the validation value"""
        return self.__valid

    def selectPath(self):
        """Pops up the 'select a file/directory' dialog"""
        # todo: This probably needs some reworking to work properly with different scenarios... (file + dir)
        self.__editing = True
        current_directory = self.getPath()

        #if not os.path.exists(currentDirectory):
        #    currentDirectory = "~"

        if self.model.pathMustBeAFile():
            current_directory = QFileDialog.getOpenFileName(
                self, "Select a file path", current_directory)
        else:
            current_directory = QFileDialog.getExistingDirectory(
                self, "Select a directory", current_directory)

        if not current_directory == "":
            if not self.model.pathMustBeAbsolute():
                cwd = os.getcwd()
                match = re.match(cwd + "/(.*)", current_directory)
                if match:
                    current_directory = match.group(1)

            self.path_line.setText(current_directory)
            self.model.setPath(self.getPath())

        self.__editing = False

    def contentsChanged(self):
        """Called whenever the path is changed."""
        path_is_valid, message = self.isPathValid(self.getPath())

        if not self.__editing and path_is_valid:
            self.model.setPath(self.getPath())

    def getPathFromModel(self):
        """Retrieves data from the model and inserts it into the edit line"""
        self.__editing = True

        path = self.model.getPath()
        if path is None:
            path = ""

        self.path_line.setText("%s" % path)
        self.__editing = False

    def cleanup(self):
        self.model.observable().detach(PathModelMixin.PATH_CHANGED_EVENT,
                                       self.getPathFromModel)
Ejemplo n.º 4
0
class PathFormatChooser(HelpedWidget):
    """
    PathChooser shows, enables choosing of and validates paths.
    The data structure expected and sent to the models getValue and setValue is a string.
    """
    path_format_msg = "Must be a path format."

    #    UNDEFINED = 0
    #    REQUIRED = 1
    #    FILE = 2
    #    DIRECTORY = 4
    #    MUST_EXIST = 8
    #    EXECUTABLE = 16

    def __init__(self, model, path_label="Path", help_link=""):
        HelpedWidget.__init__(self, path_label, help_link)
        self.path_line = QLineEdit()
        #self.pathLine.setMinimumWidth(250)
        self.addWidget(self.path_line)

        self.validColor = self.path_line.palette().color(self.path_line.backgroundRole())

        self.path_line.setText("Not initialized!")
        self.editing = False

        self.connect(self.path_line, SIGNAL('editingFinished()'), self.validatePathFormat)
        self.connect(self.path_line, SIGNAL('editingFinished()'), self.contentsChanged)
        self.connect(self.path_line, SIGNAL('textChanged(QString)'), self.validatePathFormat)

        assert isinstance(model, BasicModelMixin)
        self.model = model
        self.getPathFromModel()
        model.observable().attach(BasicModelMixin.VALUE_CHANGED_EVENT, self.getPathFromModel)


    def getValidationTypeAndColor(self):
        """Returns the type of validation message and the color that should be applied"""
        if self.must_be_set:
            color = self.ERROR_COLOR
            validity_type = self.WARNING
        else:
            color = self.INVALID_COLOR
            validity_type = self.EXCLAMATION
        return validity_type, color

    def validatePathFormat(self):
        """Called whenever the path is modified"""
        palette = self.path_line.palette()

        path = self.getPathFormat().strip()

        color = self.validColor
        message = ""
        validity_type = self.WARNING

        self.valid = True

        if not re.search("%[0-9]*d", path):
            message = self.path_format_msg
            color = self.ERROR_COLOR
            self.valid = False

        self.setValidationMessage(message, validity_type)
        self.path_line.setToolTip(message)
        palette.setColor(self.path_line.backgroundRole(), color)

        self.path_line.setPalette(palette)


    def getPathFormat(self):
        """Returns the path"""
        return str(self.path_line.text())


    def isValid(self):
        """Returns the validation value"""
        return self.valid


    def contentsChanged(self):
        """Called whenever the path is changed."""
        if not self.editing:
            self.model.setValue(self.getPathFormat())

    def getPathFromModel(self):
        """Retrieves data from the model and inserts it into the edit line"""
        self.editing = True

        path = self.model.getValue()
        if path is None:
            path = ""

        self.path_line.setText("%s" % path)
        self.editing = False
Ejemplo n.º 5
0
class PathChooser(HelpedWidget):
    """
    PathChooser shows, enables choosing of and validates paths. 
    The data structure expected and sent to the models getValue and setValue is a string.
    """

    file_does_not_exist_msg = "The specified path does not exist."
    file_is_not_executable_msg = "The specified file is not an executable."
    path_is_not_a_file_msg = "The specified path must be a file."
    required_field_msg = "A value is required."

#    UNDEFINED = 0
#    REQUIRED = 1
#    FILE = 2
#    DIRECTORY = 4
#    MUST_EXIST = 8
#    EXECUTABLE = 16

    def __init__(self, model, path_label="Path", help_link=""):
        HelpedWidget.__init__(self, path_label, help_link)

        self.__editing = True

        self.path_line = QLineEdit()

        self.addWidget(self.path_line)

        dialog_button = QToolButton(self)
        dialog_button.setIcon(resourceIcon("folder"))
        dialog_button.setIconSize(QSize(16, 16))
        self.connect(dialog_button, SIGNAL('clicked()'), self.selectDirectory)
        self.addWidget(dialog_button)

        self.valid_color = self.path_line.palette().color(self.path_line.backgroundRole())

        self.path_line.setText(os.getcwd())
        self.__editing = False

        assert isinstance(model, PathModelMixin)
        self.model = model
        model.observable().attach(PathModelMixin.PATH_CHANGED_EVENT, self.getPathFromModel)
        self.getPathFromModel()

        self.connect(self.path_line, SIGNAL('editingFinished()'), self.validatePath)
        self.connect(self.path_line, SIGNAL('editingFinished()'), self.contentsChanged)
        self.connect(self.path_line, SIGNAL('textChanged(QString)'), self.validatePath)


    def getValidationTypeAndColor(self):
        """Returns the type of validation message and the color that should be applied"""
        if self.model.pathIsRequired():
            color = self.ERROR_COLOR
            validity_type = self.WARNING
        else:
            color = self.INVALID_COLOR
            validity_type = self.EXCLAMATION
        return validity_type, color

    def validatePath(self):
        """Called whenever the path is modified"""
        palette = self.path_line.palette()

        path = self.getPath().strip()
        exists = os.path.exists(path)

        color = self.valid_color
        message = ""
        validity_type = self.WARNING

        self.valid = True

        if path == "" and self.model.pathIsRequired():
            message = self.required_field_msg
            color = self.ERROR_COLOR
            self.valid = False
        elif not exists:
            if self.model.pathMustExist():
                message = self.file_does_not_exist_msg
                self.valid = False
                validity_type, color = self.getValidationTypeAndColor()
        elif exists:
            if self.model.pathMustBeExecutable() and os.path.isfile(path) and not os.access(path, os.X_OK):
                validity_type, color = self.getValidationTypeAndColor()
                message = self.file_is_not_executable_msg
                self.valid = False
            elif self.model.pathMustBeExecutable() and not os.path.isfile(path):
                validity_type, color = self.getValidationTypeAndColor()
                message = self.path_is_not_a_file_msg
                self.valid = False
            

        self.setValidationMessage(message, validity_type)
        self.path_line.setToolTip(message)
        palette.setColor(self.path_line.backgroundRole(), color)

        self.path_line.setPalette(palette)


    def getPath(self):
        """Returns the path"""
        return str(self.path_line.text())

    def pathExists(self):
        """Returns True if the entered path exists"""
        return os.path.exists(self.getPath())
        
    def isValid(self):
        """Returns the validation value"""
        return self.valid


    def selectDirectory(self):
        """Pops up the 'select a directory' dialog"""
        self.__editing = True
        currentDirectory = self.getPath()

        #if not os.path.exists(currentDirectory):
        #    currentDirectory = "~"

        if self.model.pathMustBeAFile():
            currentDirectory = QFileDialog.getOpenFileName(self, "Select a path", currentDirectory)
        else:
            currentDirectory = QFileDialog.getExistingDirectory(self, "Select a directory", currentDirectory)

        if not currentDirectory == "":
            if not self.model.pathMustBeAbsolute():
                cwd = os.getcwd()
                match = re.match(cwd + "/(.*)", currentDirectory)
                if match:
                    currentDirectory = match.group(1)

            self.path_line.setText(currentDirectory)
            self.model.setPath(self.getPath())

        self.__editing = False


    def contentsChanged(self):
        """Called whenever the path is changed."""
        if not self.__editing:
            if self.model.pathIsRequired() and (self.model.pathMustExist() and self.pathExists()):
                # print("Pathchooser value set!")
                self.model.setPath(self.getPath())

                #todo: FIX!!!!

            # else:
            #     print("Pathchooser value not set!")


    def getPathFromModel(self):
        """Retrieves data from the model and inserts it into the edit line"""
        self.__editing = True

        path = self.model.getPath()
        if path is None:
            path = ""

        self.path_line.setText("%s" % path)
        self.__editing = False
Ejemplo n.º 6
0
class PathChooser(QWidget):
    """
    PathChooser: shows, enables choosing of and validates paths.
    The data structure expected and sent to the models getValue and setValue is a string.
    """

    PATH_DOES_NOT_EXIST_MSG = "The specified path does not exist."
    FILE_IS_NOT_EXECUTABLE_MSG = "The specified file is not an executable."
    PATH_IS_NOT_A_FILE_MSG = "The specified path must be a file."
    PATH_IS_NOT_ABSOLUTE_MSG = "The specified path must be an absolute path."
    PATH_IS_NOT_A_DIRECTORY_MSG = "The specified path must be a directory."
    REQUIRED_FIELD_MSG = "A path is required."

#    UNDEFINED = 0
#    REQUIRED = 1
#    FILE = 2
#    DIRECTORY = 4
#    MUST_EXIST = 8
#    EXECUTABLE = 16

    def __init__(self, model, help_link=""):
        """
        :type model: ert_gui.ertwidgets.models.path_model.PathModel
        :param help_link: str
        """
        QWidget.__init__(self)
        addHelpToWidget(self, help_link)
        self._validation_support = ValidationSupport(self)

        self._editing = True

        layout = QHBoxLayout()
        layout.setMargin(0)

        self._path_line = QLineEdit()
        self._path_line.setMinimumWidth(250)

        layout.addWidget(self._path_line)

        dialog_button = QToolButton(self)
        dialog_button.setIcon(resourceIcon("ide/small/folder"))
        dialog_button.setIconSize(QSize(16, 16))
        dialog_button.clicked.connect(self.selectPath)
        layout.addWidget(dialog_button)

        self.valid_color = self._path_line.palette().color(self._path_line.backgroundRole())

        self._path_line.setText(os.getcwd())
        self._editing = False

        self._model = model
        self._model.valueChanged.connect(self.getPathFromModel)

        self._path_line.editingFinished.connect(self.validatePath)
        self._path_line.editingFinished.connect(self.contentsChanged)
        self._path_line.textChanged.connect(self.validatePath)

        self.setLayout(layout)
        self.getPathFromModel()


    def isPathValid(self, path):
        """ @rtype: tuple of (bool, str) """
        path = path.strip()
        path_exists = os.path.exists(path)
        is_file = os.path.isfile(path)
        is_directory = os.path.isdir(path)
        is_executable = os.access(path, os.X_OK)
        is_absolute = os.path.isabs(path)

        valid = True
        message = ""

        if path == "":
            if self._model.pathIsRequired():
                valid = False
                message = PathChooser.REQUIRED_FIELD_MSG
        elif not path_exists:
            if self._model.pathMustExist():
                valid = False
                message = PathChooser.PATH_DOES_NOT_EXIST_MSG
            #todo: check if new (non-existing) file has directory or file format?
        elif path_exists:
            if self._model.pathMustBeExecutable() and is_file and not is_executable:
                valid = False
                message = PathChooser.FILE_IS_NOT_EXECUTABLE_MSG
            elif self._model.pathMustBeADirectory() and not is_directory:
                valid = False
                message = PathChooser.PATH_IS_NOT_A_DIRECTORY_MSG
            elif self._model.pathMustBeAbsolute() and not is_absolute:
                valid = False
                message = PathChooser.PATH_IS_NOT_ABSOLUTE_MSG
            elif self._model.pathMustBeAFile() and not is_file:
                valid = False
                message = PathChooser.PATH_IS_NOT_A_FILE_MSG

        return valid, message


    def validatePath(self):
        """Called whenever the path is modified"""
        palette = self._path_line.palette()

        valid, message = self.isPathValid(self.getPath())

        validity_type = ValidationSupport.WARNING

        if not valid:
            color = ValidationSupport.ERROR_COLOR
        else:
            color = self.valid_color

        self._validation_support.setValidationMessage(message, validity_type)
        self._path_line.setToolTip(message)
        palette.setColor(self._path_line.backgroundRole(), color)

        self._path_line.setPalette(palette)


    def getPath(self):
        """Returns the path"""
        return os.path.expanduser(str(self._path_line.text()).strip())

    def pathExists(self):
        """Returns True if the entered path exists"""
        return os.path.exists(self.getPath())

    def selectPath(self):
        """Pops up the 'select a file/directory' dialog"""
        # todo: This probably needs some reworking to work properly with different scenarios... (file + dir)
        self._editing = True
        current_directory = self.getPath()

        #if not os.path.exists(currentDirectory):
        #    currentDirectory = "~"

        if self._model.pathMustBeAFile():
            current_directory = QFileDialog.getOpenFileName(self, "Select a file path", current_directory)
        else:
            current_directory = QFileDialog.getExistingDirectory(self, "Select a directory", current_directory)

        if not current_directory == "":
            if not self._model.pathMustBeAbsolute():
                cwd = os.getcwd()
                match = re.match(cwd + "/(.*)", current_directory)
                if match:
                    current_directory = match.group(1)

            self._path_line.setText(current_directory)
            self._model.setPath(self.getPath())

        self._editing = False


    def contentsChanged(self):
        """Called whenever the path is changed."""
        path_is_valid, message = self.isPathValid(self.getPath())

        if not self._editing and path_is_valid:
            self._model.setPath(self.getPath())


    def getPathFromModel(self):
        """Retrieves data from the model and inserts it into the edit line"""
        self._editing = True

        path = self._model.getPath()
        if path is None:
            path = ""

        self._path_line.setText("%s" % path)
        self._editing = False


    def getValidationSupport(self):
        return self._validation_support

    def isValid(self):
        return self._validation_support.isValid()
Ejemplo n.º 7
0
class PathChooser(HelpedWidget):
    """
    PathChooser shows, enables choosing of and validates paths. 
    The data structure expected and sent to the models getValue and setValue is a string.
    """

    file_does_not_exist_msg = "The specified path does not exist."
    file_is_not_executable_msg = "The specified file is not an executable."
    path_is_not_a_file_msg = "The specified path must be a file."
    required_field_msg = "A value is required."

    #    UNDEFINED = 0
    #    REQUIRED = 1
    #    FILE = 2
    #    DIRECTORY = 4
    #    MUST_EXIST = 8
    #    EXECUTABLE = 16

    def __init__(self, model, path_label="Path", help_link=""):
        HelpedWidget.__init__(self, path_label, help_link)

        self.__editing = True

        self.path_line = QLineEdit()

        self.addWidget(self.path_line)

        dialog_button = QToolButton(self)
        dialog_button.setIcon(resourceIcon("folder"))
        dialog_button.setIconSize(QSize(16, 16))
        self.connect(dialog_button, SIGNAL('clicked()'), self.selectDirectory)
        self.addWidget(dialog_button)

        self.valid_color = self.path_line.palette().color(
            self.path_line.backgroundRole())

        self.path_line.setText(os.getcwd())
        self.__editing = False

        assert isinstance(model, PathModelMixin)
        self.model = model
        model.observable().attach(PathModelMixin.PATH_CHANGED_EVENT,
                                  self.getPathFromModel)
        self.getPathFromModel()

        self.connect(self.path_line, SIGNAL('editingFinished()'),
                     self.validatePath)
        self.connect(self.path_line, SIGNAL('editingFinished()'),
                     self.contentsChanged)
        self.connect(self.path_line, SIGNAL('textChanged(QString)'),
                     self.validatePath)

    def getValidationTypeAndColor(self):
        """Returns the type of validation message and the color that should be applied"""
        if self.model.pathIsRequired():
            color = self.ERROR_COLOR
            validity_type = self.WARNING
        else:
            color = self.INVALID_COLOR
            validity_type = self.EXCLAMATION
        return validity_type, color

    def validatePath(self):
        """Called whenever the path is modified"""
        palette = self.path_line.palette()

        path = self.getPath().strip()
        exists = os.path.exists(path)

        color = self.valid_color
        message = ""
        validity_type = self.WARNING

        self.valid = True

        if path == "" and self.model.pathIsRequired():
            message = self.required_field_msg
            color = self.ERROR_COLOR
            self.valid = False
        elif not exists:
            if self.model.pathMustExist():
                message = self.file_does_not_exist_msg
                self.valid = False
                validity_type, color = self.getValidationTypeAndColor()
        elif exists:
            if self.model.pathMustBeExecutable() and os.path.isfile(
                    path) and not os.access(path, os.X_OK):
                validity_type, color = self.getValidationTypeAndColor()
                message = self.file_is_not_executable_msg
                self.valid = False
            elif self.model.pathMustBeExecutable(
            ) and not os.path.isfile(path):
                validity_type, color = self.getValidationTypeAndColor()
                message = self.path_is_not_a_file_msg
                self.valid = False

        self.setValidationMessage(message, validity_type)
        self.path_line.setToolTip(message)
        palette.setColor(self.path_line.backgroundRole(), color)

        self.path_line.setPalette(palette)

    def getPath(self):
        """Returns the path"""
        return str(self.path_line.text())

    def pathExists(self):
        """Returns True if the entered path exists"""
        return os.path.exists(self.getPath())

    def isValid(self):
        """Returns the validation value"""
        return self.valid

    def selectDirectory(self):
        """Pops up the 'select a directory' dialog"""
        self.__editing = True
        currentDirectory = self.getPath()

        #if not os.path.exists(currentDirectory):
        #    currentDirectory = "~"

        if self.model.pathMustBeAFile():
            currentDirectory = QFileDialog.getOpenFileName(
                self, "Select a path", currentDirectory)
        else:
            currentDirectory = QFileDialog.getExistingDirectory(
                self, "Select a directory", currentDirectory)

        if not currentDirectory == "":
            if not self.model.pathMustBeAbsolute():
                cwd = os.getcwd()
                match = re.match(cwd + "/(.*)", currentDirectory)
                if match:
                    currentDirectory = match.group(1)

            self.path_line.setText(currentDirectory)
            self.model.setPath(self.getPath())

        self.__editing = False

    def contentsChanged(self):
        """Called whenever the path is changed."""
        if not self.__editing:
            if self.model.pathIsRequired() and (self.model.pathMustExist()
                                                and self.pathExists()):
                # print("Pathchooser value set!")
                self.model.setPath(self.getPath())

                #todo: FIX!!!!

            # else:
            #     print("Pathchooser value not set!")

    def getPathFromModel(self):
        """Retrieves data from the model and inserts it into the edit line"""
        self.__editing = True

        path = self.model.getPath()
        if path is None:
            path = ""

        self.path_line.setText("%s" % path)
        self.__editing = False
Ejemplo n.º 8
0
class PathFormatChooser(HelpedWidget):
    """
    PathChooser shows, enables choosing of and validates paths.
    The data structure expected and sent to the models getValue and setValue is a string.
    """
    path_format_msg = "Must be a path format."

    #    UNDEFINED = 0
    #    REQUIRED = 1
    #    FILE = 2
    #    DIRECTORY = 4
    #    MUST_EXIST = 8
    #    EXECUTABLE = 16

    def __init__(self, model, path_label="Path", help_link=""):
        HelpedWidget.__init__(self, path_label, help_link)
        self.path_line = QLineEdit()
        #self.pathLine.setMinimumWidth(250)
        self.addWidget(self.path_line)

        self.validColor = self.path_line.palette().color(
            self.path_line.backgroundRole())

        self.path_line.setText("Not initialized!")
        self.editing = False

        self.connect(self.path_line, SIGNAL('editingFinished()'),
                     self.validatePathFormat)
        self.connect(self.path_line, SIGNAL('editingFinished()'),
                     self.contentsChanged)
        self.connect(self.path_line, SIGNAL('textChanged(QString)'),
                     self.validatePathFormat)

        assert isinstance(model, BasicModelMixin)
        self.model = model
        self.getPathFromModel()
        model.observable().attach(BasicModelMixin.VALUE_CHANGED_EVENT,
                                  self.getPathFromModel)

    def getValidationTypeAndColor(self):
        """Returns the type of validation message and the color that should be applied"""
        if self.must_be_set:
            color = self.ERROR_COLOR
            validity_type = self.WARNING
        else:
            color = self.INVALID_COLOR
            validity_type = self.EXCLAMATION
        return validity_type, color

    def validatePathFormat(self):
        """Called whenever the path is modified"""
        palette = self.path_line.palette()

        path = self.getPathFormat().strip()

        color = self.validColor
        message = ""
        validity_type = self.WARNING

        self.valid = True

        if not re.search("%[0-9]*d", path):
            message = self.path_format_msg
            color = self.ERROR_COLOR
            self.valid = False

        self.setValidationMessage(message, validity_type)
        self.path_line.setToolTip(message)
        palette.setColor(self.path_line.backgroundRole(), color)

        self.path_line.setPalette(palette)

    def getPathFormat(self):
        """Returns the path"""
        return str(self.path_line.text())

    def isValid(self):
        """Returns the validation value"""
        return self.valid

    def contentsChanged(self):
        """Called whenever the path is changed."""
        if not self.editing:
            self.model.setValue(self.getPathFormat())

    def getPathFromModel(self):
        """Retrieves data from the model and inserts it into the edit line"""
        self.editing = True

        path = self.model.getValue()
        if path is None:
            path = ""

        self.path_line.setText("%s" % path)
        self.editing = False