예제 #1
0
    def __createLayout(self):
        """Creates the dialog layout"""
        self.resize(450, 150)
        self.setSizeGripEnabled(True)

        verticalLayout = QVBoxLayout(self)
        gridLayout = QGridLayout()

        # Link
        gridLayout.addWidget(QLabel('Link', self), 0, 0, 1, 1)
        self.linkEdit = QLineEdit(self)
        self.linkEdit.setClearButtonEnabled(True)
        self.linkEdit.setToolTip(
            'A link to a file or to an external web resource')
        gridLayout.addWidget(self.linkEdit, 0, 1, 1, 1)
        self.linkEdit.textChanged.connect(self.__validate)
        self.fileButton = QPushButton(self)
        self.fileButton.setText('...')
        self.fileButton.setToolTip('Select an existing or non existing file')
        gridLayout.addWidget(self.fileButton, 0, 2, 1, 1)
        self.fileButton.clicked.connect(self.__onSelectPath)
        self.createCheckBox = QCheckBox(
            'Create a markdown file if does not exist', self)
        self.createCheckBox.setChecked(False)
        gridLayout.addWidget(self.createCheckBox, 1, 1, 1, 1)
        self.createCheckBox.stateChanged.connect(self.__validate)

        # Anchor
        gridLayout.addWidget(QLabel('Anchor', self), 2, 0, 1, 1)
        self.anchorEdit = QLineEdit(self)
        self.anchorEdit.setClearButtonEnabled(True)
        gridLayout.addWidget(self.anchorEdit, 2, 1, 1, 1)
        self.anchorEdit.textChanged.connect(self.__validate)

        # Title
        titleLabel = QLabel('Title', self)
        titleLabel.setAlignment(Qt.AlignTop)
        gridLayout.addWidget(titleLabel, 3, 0, 1, 1)
        self.titleEdit = QTextEdit()
        self.titleEdit.setTabChangesFocus(True)
        self.titleEdit.setAcceptRichText(False)
        self.titleEdit.setFont(getZoomedMonoFont())
        self.titleEdit.setToolTip(
            'If provided then will be displayed in the rectangle')
        gridLayout.addWidget(self.titleEdit, 3, 1, 1, 1)

        # Buttons at the bottom
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Ok)
        self.__OKButton = buttonBox.button(QDialogButtonBox.Ok)
        self.__OKButton.setDefault(True)
        buttonBox.accepted.connect(self.accept)
        buttonBox.rejected.connect(self.close)

        verticalLayout.addLayout(gridLayout)
        verticalLayout.addWidget(buttonBox)

        self.linkEdit.setFocus()
예제 #2
0
    def __createLayout(self):
        """Creates the dialog layout"""
        self.resize(400, 80)
        self.setSizeGripEnabled(True)

        vboxLayout = QVBoxLayout(self)

        hboxLayout = QHBoxLayout()
        hboxLayout.addWidget(QLabel("Status update interval, sec."))
        self.__intervalEdit = QLineEdit()
        self.__intervalEdit.setValidator(QIntValidator(1, 3600, self))
        self.__intervalEdit.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        hboxLayout.addWidget(self.__intervalEdit)

        # Buttons at the bottom
        self.__buttonBox = QDialogButtonBox(self)
        self.__buttonBox.setOrientation(Qt.Horizontal)
        self.__buttonBox.setStandardButtons(QDialogButtonBox.Ok
                                            | QDialogButtonBox.Cancel)
        self.__buttonBox.accepted.connect(self.userAccept)
        self.__buttonBox.rejected.connect(self.close)

        vboxLayout.addLayout(hboxLayout)
        vboxLayout.addWidget(self.__buttonBox)
예제 #3
0
class SVNPluginPropsDialog(QDialog):
    """SVN plugin properties dialog"""
    def __init__(self, plugin, client, path, parent=None):
        QDialog.__init__(self, parent)

        self.__plugin = plugin
        self.__client = client
        self.__path = path

        self.__createLayout()
        self.setWindowTitle("SVN Properties of " + path)
        self.__populate()
        self.__propsView.setFocus()

    def __populate(self):
        """Populate the properties list"""
        # Get the currently selected name
        selectedName = None
        selected = list(self.__propsView.selectedItems())
        if selected:
            selectedName = str(selected[0].text(0))

        self.__propsView.clear()
        properties = readProperties(self.__client, self.__path)
        if properties:
            for itemPath, itemProps in properties:
                if self.__path == itemPath or \
                   self.__path == itemPath + os.path.sep:
                    for name, value in itemProps.iteritems():
                        name = str(name).strip()
                        value = str(value).strip()
                        newItem = QTreeWidgetItem([name, value])
                        self.__propsView.addTopLevelItem(newItem)

        self.__resizePropsView()
        self.__sortPropsView()

        if selectedName:
            index = 0
            for index in range(0, self.__propsView.topLevelItemCount()):
                item = self.__propsView.topLevelItem(index)
                if selectedName == item.text(0):
                    item.setSelected(True)

    def __resizePropsView(self):
        """Resizes the properties table"""
        self.__propsView.header().setStretchLastSection(True)
        self.__propsView.header().resizeSections(QHeaderView.ResizeToContents)

    def __sortPropsView(self):
        """Sorts the properties table"""
        self.__propsView.sortItems(
            self.__propsView.sortColumn(),
            self.__propsView.header().sortIndicatorOrder())

    def __createLayout(self):
        """Creates the dialog layout"""
        self.resize(640, 480)
        self.setSizeGripEnabled(True)

        vboxLayout = QVBoxLayout(self)

        hLayout = QHBoxLayout()
        self.__propsView = QTreeWidget()
        self.__propsView.setAlternatingRowColors(True)
        self.__propsView.setRootIsDecorated(False)
        self.__propsView.setItemsExpandable(False)
        self.__propsView.setSortingEnabled(True)
        self.__propsView.setItemDelegate(NoOutlineHeightDelegate(4))
        self.__propsView.itemSelectionChanged.connect(
            self.__propsSelectionChanged)

        propsViewHeader = QTreeWidgetItem(["Property Name", "Property Value"])
        self.__propsView.setHeaderItem(propsViewHeader)
        self.__propsView.header().setSortIndicator(0, Qt.DescendingOrder)
        hLayout.addWidget(self.__propsView)

        self.__delButton = QToolButton()
        self.__delButton.setText("Delete")
        self.__delButton.setFocusPolicy(Qt.NoFocus)
        self.__delButton.setEnabled(False)
        self.__delButton.clicked.connect(self.__onDel)
        hLayout.addWidget(self.__delButton, 0, Qt.AlignBottom)
        vboxLayout.addLayout(hLayout)

        # Set property part
        setGroupbox = QGroupBox(self)
        setGroupbox.setTitle("Set Property")

        setLayout = QGridLayout(setGroupbox)
        setLayout.addWidget(QLabel("Name"), 0, 0, Qt.AlignTop | Qt.AlignRight)
        setLayout.addWidget(QLabel("Value"), 1, 0, Qt.AlignTop | Qt.AlignRight)

        self.__nameEdit = QLineEdit()
        self.__nameEdit.textChanged.connect(self.__nameChanged)
        setLayout.addWidget(self.__nameEdit, 0, 1)

        self.__valueEdit = QTextEdit()
        self.__valueEdit.setAcceptRichText(False)
        self.__valueEdit.textChanged.connect(self.__valueChanged)
        metrics = QFontMetrics(self.__valueEdit.font())
        rect = metrics.boundingRect("X")
        self.__valueEdit.setFixedHeight(rect.height() * 4 + 5)
        setLayout.addWidget(self.__valueEdit, 1, 1)

        self.__setButton = QToolButton()
        self.__setButton.setText("Set")
        self.__setButton.setFocusPolicy(Qt.NoFocus)
        self.__setButton.setEnabled(False)
        self.__setButton.clicked.connect(self.__onSet)
        setLayout.addWidget(self.__setButton, 1, 2,
                            Qt.AlignBottom | Qt.AlignHCenter)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            setGroupbox.sizePolicy().hasHeightForWidth())
        setGroupbox.setSizePolicy(sizePolicy)
        vboxLayout.addWidget(setGroupbox)

        # Buttons at the bottom
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Ok)
        buttonBox.button(QDialogButtonBox.Ok).setDefault(True)
        buttonBox.accepted.connect(self.close)
        vboxLayout.addWidget(buttonBox)

    def __onSet(self):
        """Triggered when propery set is clicked"""
        name = self.__nameEdit.text().strip()
        value = self.__valueEdit.toPlainText().strip()
        try:
            commitInfo = self.__client.propset(name, value, self.__path)
            if commitInfo:
                logging.info(str(commitInfo))
            self.__populate()
            self.__plugin.notifyPathChanged(self.__path)
            self.__nameEdit.clear()
            self.__valueEdit.clear()
            self.__propsView.setFocus()
        except pysvn.ClientError as exc:
            message = exc.args[0]
            logging.error(message)
        except Exception as exc:
            logging.error(str(exc))
        except:
            logging.error("Unknown property setting error")

    def __propsSelectionChanged(self):
        """Selection of a property has changed"""
        selected = list(self.__propsView.selectedItems())
        self.__delButton.setEnabled(len(selected) > 0)

    def __onDel(self):
        """Triggered when a property del is clicked"""
        selected = list(self.__propsView.selectedItems())
        if len(selected) == 0:
            self.__delButton.setEnabled(False)
            return

        name = str(selected[0].text(0))
        res = QMessageBox.warning(
            self, "Deleting Property", "You are about to delete <b>" + name +
            "</b> SVN property from " + self.__path + ".\nAre you sure?",
            QMessageBox.StandardButtons(QMessageBox.Cancel | QMessageBox.Yes),
            QMessageBox.Cancel)
        if res != QMessageBox.Yes:
            return

        try:
            self.__client.propdel(name, self.__path)
            self.__populate()
            self.__plugin.notifyPathChanged(self.__path)
            self.__propsView.setFocus()
        except pysvn.ClientError as exc:
            message = exc.args[0]
            logging.error(message)
        except Exception as exc:
            logging.error(str(exc))
        except:
            logging.error("Unknown property deleting error")

    def __nameChanged(self, text):
        """Triggered when a property name to set is changed"""
        self.__updateSetButton()

    def __valueChanged(self):
        """Triggered when a property value to set is changed"""
        self.__updateSetButton()

    def __updateSetButton(self):
        """Updates the 'Set' button state"""
        name = self.__nameEdit.text().strip()
        value = self.__valueEdit.toPlainText().strip()
        self.__setButton.setEnabled(name != "" and value != "")
예제 #4
0
    def __createLayout(self):
        """Creates the dialog layout"""
        self.resize(640, 480)
        self.setSizeGripEnabled(True)

        vboxLayout = QVBoxLayout(self)

        hLayout = QHBoxLayout()
        self.__propsView = QTreeWidget()
        self.__propsView.setAlternatingRowColors(True)
        self.__propsView.setRootIsDecorated(False)
        self.__propsView.setItemsExpandable(False)
        self.__propsView.setSortingEnabled(True)
        self.__propsView.setItemDelegate(NoOutlineHeightDelegate(4))
        self.__propsView.itemSelectionChanged.connect(
            self.__propsSelectionChanged)

        propsViewHeader = QTreeWidgetItem(["Property Name", "Property Value"])
        self.__propsView.setHeaderItem(propsViewHeader)
        self.__propsView.header().setSortIndicator(0, Qt.DescendingOrder)
        hLayout.addWidget(self.__propsView)

        self.__delButton = QToolButton()
        self.__delButton.setText("Delete")
        self.__delButton.setFocusPolicy(Qt.NoFocus)
        self.__delButton.setEnabled(False)
        self.__delButton.clicked.connect(self.__onDel)
        hLayout.addWidget(self.__delButton, 0, Qt.AlignBottom)
        vboxLayout.addLayout(hLayout)

        # Set property part
        setGroupbox = QGroupBox(self)
        setGroupbox.setTitle("Set Property")

        setLayout = QGridLayout(setGroupbox)
        setLayout.addWidget(QLabel("Name"), 0, 0, Qt.AlignTop | Qt.AlignRight)
        setLayout.addWidget(QLabel("Value"), 1, 0, Qt.AlignTop | Qt.AlignRight)

        self.__nameEdit = QLineEdit()
        self.__nameEdit.textChanged.connect(self.__nameChanged)
        setLayout.addWidget(self.__nameEdit, 0, 1)

        self.__valueEdit = QTextEdit()
        self.__valueEdit.setAcceptRichText(False)
        self.__valueEdit.textChanged.connect(self.__valueChanged)
        metrics = QFontMetrics(self.__valueEdit.font())
        rect = metrics.boundingRect("X")
        self.__valueEdit.setFixedHeight(rect.height() * 4 + 5)
        setLayout.addWidget(self.__valueEdit, 1, 1)

        self.__setButton = QToolButton()
        self.__setButton.setText("Set")
        self.__setButton.setFocusPolicy(Qt.NoFocus)
        self.__setButton.setEnabled(False)
        self.__setButton.clicked.connect(self.__onSet)
        setLayout.addWidget(self.__setButton, 1, 2,
                            Qt.AlignBottom | Qt.AlignHCenter)

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            setGroupbox.sizePolicy().hasHeightForWidth())
        setGroupbox.setSizePolicy(sizePolicy)
        vboxLayout.addWidget(setGroupbox)

        # Buttons at the bottom
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Ok)
        buttonBox.button(QDialogButtonBox.Ok).setDefault(True)
        buttonBox.accepted.connect(self.close)
        vboxLayout.addWidget(buttonBox)
예제 #5
0
class VCSUpdateIntervalConfigDialog(QDialog):
    """Dialog to configure update interval"""
    def __init__(self, value, parent=None):
        QDialog.__init__(self, parent)
        self.interval = value

        self.__createLayout()
        self.setWindowTitle("VCS file status update interval configuration")

        self.__intervalEdit.setText(str(self.interval))
        self.__updateOKStatus()

        self.__intervalEdit.textChanged.connect(self.__updateOKStatus)
        self.__intervalEdit.setFocus()

    def __createLayout(self):
        """Creates the dialog layout"""
        self.resize(400, 80)
        self.setSizeGripEnabled(True)

        vboxLayout = QVBoxLayout(self)

        hboxLayout = QHBoxLayout()
        hboxLayout.addWidget(QLabel("Status update interval, sec."))
        self.__intervalEdit = QLineEdit()
        self.__intervalEdit.setValidator(QIntValidator(1, 3600, self))
        self.__intervalEdit.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        hboxLayout.addWidget(self.__intervalEdit)

        # Buttons at the bottom
        self.__buttonBox = QDialogButtonBox(self)
        self.__buttonBox.setOrientation(Qt.Horizontal)
        self.__buttonBox.setStandardButtons(QDialogButtonBox.Ok
                                            | QDialogButtonBox.Cancel)
        self.__buttonBox.accepted.connect(self.userAccept)
        self.__buttonBox.rejected.connect(self.close)

        vboxLayout.addLayout(hboxLayout)
        vboxLayout.addWidget(self.__buttonBox)

    def __updateOKStatus(self):
        """Updates the OK button status"""
        okButton = self.__buttonBox.button(QDialogButtonBox.Ok)

        if self.__intervalEdit.text() == "":
            okButton.setEnabled(False)
            okButton.setToolTip("Interval must be defined")
            return

        value = int(self.__intervalEdit.text())
        if value < 1 or value > 3600:
            okButton.setEnabled(False)
            okButton.setToolTip("Interval must be within 1..3600 sec")
            return

        okButton.setEnabled(True)
        okButton.setToolTip("")

    def userAccept(self):
        """Triggered when the user clicks OK"""
        self.interval = int(self.__intervalEdit.text())
        self.accept()
예제 #6
0
    def __createLayout(self):
        """Creates the widget layout"""
        verticalLayout = QVBoxLayout(self)
        verticalLayout.setContentsMargins(0, 0, 0, 0)
        verticalLayout.setSpacing(0)

        self.__excptLabel = QLabel("Ignored exception types", self)

        self.headerFrame = QFrame()
        self.headerFrame.setObjectName('ignexcpt')
        self.headerFrame.setStyleSheet('QFrame#ignexcpt {' +
                                       getLabelStyle(self.__excptLabel) + '}')
        self.headerFrame.setFixedHeight(HEADER_HEIGHT)

        expandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding)

        self.__showHideButton = QToolButton()
        self.__showHideButton.setAutoRaise(True)
        self.__showHideButton.setIcon(getIcon('less.png'))
        self.__showHideButton.setFixedSize(HEADER_BUTTON, HEADER_BUTTON)
        self.__showHideButton.setToolTip("Hide ignored exceptions list")
        self.__showHideButton.setFocusPolicy(Qt.NoFocus)
        self.__showHideButton.clicked.connect(self.__onShowHide)

        headerLayout = QHBoxLayout()
        headerLayout.setContentsMargins(0, 0, 0, 0)
        headerLayout.addSpacing(3)
        headerLayout.addWidget(self.__excptLabel)
        headerLayout.addSpacerItem(expandingSpacer)
        headerLayout.addWidget(self.__showHideButton)
        self.headerFrame.setLayout(headerLayout)

        self.exceptionsList = QTreeWidget(self)
        self.exceptionsList.setSortingEnabled(False)
        self.exceptionsList.setAlternatingRowColors(True)
        self.exceptionsList.setRootIsDecorated(False)
        self.exceptionsList.setItemsExpandable(True)
        self.exceptionsList.setUniformRowHeights(True)
        self.exceptionsList.setSelectionMode(QAbstractItemView.SingleSelection)
        self.exceptionsList.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.exceptionsList.setItemDelegate(NoOutlineHeightDelegate(4))
        self.exceptionsList.setContextMenuPolicy(Qt.CustomContextMenu)

        self.exceptionsList.customContextMenuRequested.connect(
            self.__showContextMenu)
        self.exceptionsList.itemSelectionChanged.connect(
            self.__onSelectionChanged)
        self.exceptionsList.setHeaderLabels(["Exception type"])

        self.__excTypeEdit = QLineEdit()
        self.__excTypeEdit.setFixedHeight(26)
        self.__excTypeEdit.textChanged.connect(self.__onNewFilterChanged)
        self.__excTypeEdit.returnPressed.connect(self.__onAddExceptionFilter)
        self.__addButton = QPushButton("Add")
        # self.__addButton.setFocusPolicy(Qt.NoFocus)
        self.__addButton.setEnabled(False)
        self.__addButton.clicked.connect(self.__onAddExceptionFilter)

        expandingSpacer2 = QWidget()
        expandingSpacer2.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)

        self.__removeButton = QAction(getIcon('delitem.png'),
                                      "Remove selected exception type", self)
        self.__removeButton.triggered.connect(self.__onRemoveFromIgnore)
        self.__removeButton.setEnabled(False)

        fixedSpacer1 = QWidget()
        fixedSpacer1.setFixedWidth(5)

        self.__removeAllButton = QAction(getIcon('ignexcptdelall.png'),
                                         "Remove all the exception types",
                                         self)
        self.__removeAllButton.triggered.connect(self.__onRemoveAllFromIgnore)
        self.__removeAllButton.setEnabled(False)

        self.toolbar = QToolBar()
        self.toolbar.setOrientation(Qt.Horizontal)
        self.toolbar.setMovable(False)
        self.toolbar.setAllowedAreas(Qt.TopToolBarArea)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setFixedHeight(28)
        self.toolbar.setContentsMargins(0, 0, 0, 0)
        self.toolbar.addWidget(expandingSpacer2)
        self.toolbar.addAction(self.__removeButton)
        self.toolbar.addWidget(fixedSpacer1)
        self.toolbar.addAction(self.__removeAllButton)

        addLayout = QHBoxLayout()
        addLayout.setContentsMargins(1, 1, 1, 1)
        addLayout.setSpacing(1)
        addLayout.addWidget(self.__excTypeEdit)
        addLayout.addWidget(self.__addButton)

        verticalLayout.addWidget(self.headerFrame)
        verticalLayout.addWidget(self.toolbar)
        verticalLayout.addWidget(self.exceptionsList)
        verticalLayout.addLayout(addLayout)
예제 #7
0
class IgnoredExceptionsViewer(QWidget):
    """Implements the client exceptions viewer for a debugger"""
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.__createPopupMenu()
        self.__createLayout()
        self.__ignored = []
        self.__currentItem = None

        GlobalData().project.sigProjectChanged.connect(self.__onProjectChanged)

        if not Settings()['showIgnoredExcViewer']:
            self.__onShowHide(True)

    def __createPopupMenu(self):
        """Creates the popup menu"""
        self.__excptMenu = QMenu()
        self.__removeMenuItem = self.__excptMenu.addAction(
            getIcon('ignexcptdel.png'), "Remove from ignore list",
            self.__onRemoveFromIgnore)

    def __createLayout(self):
        """Creates the widget layout"""
        verticalLayout = QVBoxLayout(self)
        verticalLayout.setContentsMargins(0, 0, 0, 0)
        verticalLayout.setSpacing(0)

        self.__excptLabel = QLabel("Ignored exception types", self)

        self.headerFrame = QFrame()
        self.headerFrame.setObjectName('ignexcpt')
        self.headerFrame.setStyleSheet('QFrame#ignexcpt {' +
                                       getLabelStyle(self.__excptLabel) + '}')
        self.headerFrame.setFixedHeight(HEADER_HEIGHT)

        expandingSpacer = QSpacerItem(10, 10, QSizePolicy.Expanding)

        self.__showHideButton = QToolButton()
        self.__showHideButton.setAutoRaise(True)
        self.__showHideButton.setIcon(getIcon('less.png'))
        self.__showHideButton.setFixedSize(HEADER_BUTTON, HEADER_BUTTON)
        self.__showHideButton.setToolTip("Hide ignored exceptions list")
        self.__showHideButton.setFocusPolicy(Qt.NoFocus)
        self.__showHideButton.clicked.connect(self.__onShowHide)

        headerLayout = QHBoxLayout()
        headerLayout.setContentsMargins(0, 0, 0, 0)
        headerLayout.addSpacing(3)
        headerLayout.addWidget(self.__excptLabel)
        headerLayout.addSpacerItem(expandingSpacer)
        headerLayout.addWidget(self.__showHideButton)
        self.headerFrame.setLayout(headerLayout)

        self.exceptionsList = QTreeWidget(self)
        self.exceptionsList.setSortingEnabled(False)
        self.exceptionsList.setAlternatingRowColors(True)
        self.exceptionsList.setRootIsDecorated(False)
        self.exceptionsList.setItemsExpandable(True)
        self.exceptionsList.setUniformRowHeights(True)
        self.exceptionsList.setSelectionMode(QAbstractItemView.SingleSelection)
        self.exceptionsList.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.exceptionsList.setItemDelegate(NoOutlineHeightDelegate(4))
        self.exceptionsList.setContextMenuPolicy(Qt.CustomContextMenu)

        self.exceptionsList.customContextMenuRequested.connect(
            self.__showContextMenu)
        self.exceptionsList.itemSelectionChanged.connect(
            self.__onSelectionChanged)
        self.exceptionsList.setHeaderLabels(["Exception type"])

        self.__excTypeEdit = QLineEdit()
        self.__excTypeEdit.setFixedHeight(26)
        self.__excTypeEdit.textChanged.connect(self.__onNewFilterChanged)
        self.__excTypeEdit.returnPressed.connect(self.__onAddExceptionFilter)
        self.__addButton = QPushButton("Add")
        # self.__addButton.setFocusPolicy(Qt.NoFocus)
        self.__addButton.setEnabled(False)
        self.__addButton.clicked.connect(self.__onAddExceptionFilter)

        expandingSpacer2 = QWidget()
        expandingSpacer2.setSizePolicy(QSizePolicy.Expanding,
                                       QSizePolicy.Expanding)

        self.__removeButton = QAction(getIcon('delitem.png'),
                                      "Remove selected exception type", self)
        self.__removeButton.triggered.connect(self.__onRemoveFromIgnore)
        self.__removeButton.setEnabled(False)

        fixedSpacer1 = QWidget()
        fixedSpacer1.setFixedWidth(5)

        self.__removeAllButton = QAction(getIcon('ignexcptdelall.png'),
                                         "Remove all the exception types",
                                         self)
        self.__removeAllButton.triggered.connect(self.__onRemoveAllFromIgnore)
        self.__removeAllButton.setEnabled(False)

        self.toolbar = QToolBar()
        self.toolbar.setOrientation(Qt.Horizontal)
        self.toolbar.setMovable(False)
        self.toolbar.setAllowedAreas(Qt.TopToolBarArea)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setFixedHeight(28)
        self.toolbar.setContentsMargins(0, 0, 0, 0)
        self.toolbar.addWidget(expandingSpacer2)
        self.toolbar.addAction(self.__removeButton)
        self.toolbar.addWidget(fixedSpacer1)
        self.toolbar.addAction(self.__removeAllButton)

        addLayout = QHBoxLayout()
        addLayout.setContentsMargins(1, 1, 1, 1)
        addLayout.setSpacing(1)
        addLayout.addWidget(self.__excTypeEdit)
        addLayout.addWidget(self.__addButton)

        verticalLayout.addWidget(self.headerFrame)
        verticalLayout.addWidget(self.toolbar)
        verticalLayout.addWidget(self.exceptionsList)
        verticalLayout.addLayout(addLayout)

    def clear(self):
        """Clears the content"""
        self.exceptionsList.clear()
        self.__excTypeEdit.clear()
        self.__addButton.setEnabled(False)
        self.__ignored = []
        self.__currentItem = None
        self.__updateTitle()

    def __onShowHide(self, startup=False):
        """Triggered when show/hide button is clicked"""
        if startup or self.exceptionsList.isVisible():
            self.exceptionsList.setVisible(False)
            self.__excTypeEdit.setVisible(False)
            self.__addButton.setVisible(False)
            self.__removeButton.setVisible(False)
            self.__removeAllButton.setVisible(False)
            self.__showHideButton.setIcon(getIcon('more.png'))
            self.__showHideButton.setToolTip("Show ignored exceptions list")

            self.__minH = self.minimumHeight()
            self.__maxH = self.maximumHeight()

            self.setMinimumHeight(self.headerFrame.height())
            self.setMaximumHeight(self.headerFrame.height())

            Settings()['showIgnoredExcViewer'] = False
        else:
            self.exceptionsList.setVisible(True)
            self.__excTypeEdit.setVisible(True)
            self.__addButton.setVisible(True)
            self.__removeButton.setVisible(True)
            self.__removeAllButton.setVisible(True)
            self.__showHideButton.setIcon(getIcon('less.png'))
            self.__showHideButton.setToolTip("Hide ignored exceptions list")

            self.setMinimumHeight(self.__minH)
            self.setMaximumHeight(self.__maxH)

            Settings()['showIgnoredExcViewer'] = True

    def __onSelectionChanged(self):
        """Triggered when the current item is changed"""
        selected = list(self.exceptionsList.selectedItems())
        if selected:
            self.__currentItem = selected[0]
            self.__removeButton.setEnabled(True)
        else:
            self.__currentItem = None
            self.__removeButton.setEnabled(False)

    def __showContextMenu(self, coord):
        """Shows the frames list context menu"""
        contextItem = self.exceptionsList.itemAt(coord)
        if contextItem is not None:
            self.__currentItem = contextItem
            self.__excptMenu.popup(QCursor.pos())

    def __updateTitle(self):
        """Updates the section title"""
        count = self.exceptionsList.topLevelItemCount()
        if count == 0:
            self.__excptLabel.setText("Ignored exception types")
        else:
            self.__excptLabel.setText("Ignored exception types (total: " +
                                      str(count) + ")")
        self.__removeAllButton.setEnabled(count != 0)

    def __onProjectChanged(self, what):
        """Triggered when a project is changed"""
        if what != CodimensionProject.CompleteProject:
            return

        self.clear()
        project = GlobalData().project
        if project.isLoaded():
            self.__ignored = list(project.exceptionFilters)
        else:
            self.__ignored = Settings()['ignoredExceptions']

        for exceptionType in self.__ignored:
            item = QTreeWidgetItem(self.exceptionsList)
            item.setText(0, exceptionType)
        self.__updateTitle()

    def __onNewFilterChanged(self, text):
        """Triggered when the text is changed"""
        text = str(text).strip()
        if text == "":
            self.__addButton.setEnabled(False)
            return
        if " " in text:
            self.__addButton.setEnabled(False)
            return

        if text in self.__ignored:
            self.__addButton.setEnabled(False)
            return

        self.__addButton.setEnabled(True)

    def __onAddExceptionFilter(self):
        """Adds an item into the ignored exceptions list"""
        text = self.__excTypeEdit.text().strip()
        self.addExceptionFilter(text)

    def addExceptionFilter(self, excType):
        """Adds a new item into the ignored exceptions list"""
        if excType == "":
            return
        if " " in excType:
            return
        if excType in self.__ignored:
            return

        item = QTreeWidgetItem(self.exceptionsList)
        item.setText(0, excType)

        project = GlobalData().project
        if project.isLoaded():
            project.addExceptionFilter(excType)
        else:
            Settings().addExceptionFilter(excType)
        self.__ignored.append(excType)
        self.__updateTitle()

    def __onRemoveFromIgnore(self):
        """Removes an item from the ignored exception types list"""
        if self.__currentItem is None:
            return

        text = self.__currentItem.text(0)

        # Find the item index and remove it
        index = 0
        while True:
            if self.exceptionsList.topLevelItem(index).text(0) == text:
                self.exceptionsList.takeTopLevelItem(index)
                break
            index += 1

        project = GlobalData().project
        if project.isLoaded():
            project.deleteExceptionFilter(text)
        else:
            Settings().deleteExceptionFilter(text)
        self.__ignored.remove(text)
        self.__updateTitle()

    def __onRemoveAllFromIgnore(self):
        """Triggered when all the ignored exceptions should be deleted"""
        self.clear()

        project = GlobalData().project
        if project.isLoaded():
            project.setExceptionFilters([])
        else:
            Settings().setExceptionFilters([])

    def isIgnored(self, exceptionType):
        """Returns True if this exception type should be ignored"""
        return exceptionType in self.__ignored
예제 #8
0
class DocLinkAnchorDialog(QDialog):
    """Replace text input dialog"""
    def __init__(self, windowTitle, cmlDocComment, fileName, parent):
        QDialog.__init__(self, parent)

        # Name of a file from which the doc link is created/edited
        self.__fileName = fileName
        self.setWindowTitle(windowTitle + ' documentation link and/or anchor')

        self.__createLayout()
        self.__invalidInputColor = GlobalData().skin['invalidInputPaper']
        self.__validInputColor = self.linkEdit.palette().color(
            self.linkEdit.backgroundRole())

        if cmlDocComment is not None:
            self.__populate(cmlDocComment)

    def __createLayout(self):
        """Creates the dialog layout"""
        self.resize(450, 150)
        self.setSizeGripEnabled(True)

        verticalLayout = QVBoxLayout(self)
        gridLayout = QGridLayout()

        # Link
        gridLayout.addWidget(QLabel('Link', self), 0, 0, 1, 1)
        self.linkEdit = QLineEdit(self)
        self.linkEdit.setClearButtonEnabled(True)
        self.linkEdit.setToolTip(
            'A link to a file or to an external web resource')
        gridLayout.addWidget(self.linkEdit, 0, 1, 1, 1)
        self.linkEdit.textChanged.connect(self.__validate)
        self.fileButton = QPushButton(self)
        self.fileButton.setText('...')
        self.fileButton.setToolTip('Select an existing or non existing file')
        gridLayout.addWidget(self.fileButton, 0, 2, 1, 1)
        self.fileButton.clicked.connect(self.__onSelectPath)
        self.createCheckBox = QCheckBox(
            'Create a markdown file if does not exist', self)
        self.createCheckBox.setChecked(False)
        gridLayout.addWidget(self.createCheckBox, 1, 1, 1, 1)
        self.createCheckBox.stateChanged.connect(self.__validate)

        # Anchor
        gridLayout.addWidget(QLabel('Anchor', self), 2, 0, 1, 1)
        self.anchorEdit = QLineEdit(self)
        self.anchorEdit.setClearButtonEnabled(True)
        gridLayout.addWidget(self.anchorEdit, 2, 1, 1, 1)
        self.anchorEdit.textChanged.connect(self.__validate)

        # Title
        titleLabel = QLabel('Title', self)
        titleLabel.setAlignment(Qt.AlignTop)
        gridLayout.addWidget(titleLabel, 3, 0, 1, 1)
        self.titleEdit = QTextEdit()
        self.titleEdit.setTabChangesFocus(True)
        self.titleEdit.setAcceptRichText(False)
        self.titleEdit.setToolTip(
            'If provided then will be displayed in the rectangle')
        gridLayout.addWidget(self.titleEdit, 3, 1, 1, 1)

        # Buttons at the bottom
        buttonBox = QDialogButtonBox(self)
        buttonBox.setOrientation(Qt.Horizontal)
        buttonBox.setStandardButtons(QDialogButtonBox.Ok)
        self.__OKButton = buttonBox.button(QDialogButtonBox.Ok)
        self.__OKButton.setDefault(True)
        buttonBox.accepted.connect(self.accept)
        buttonBox.rejected.connect(self.close)

        verticalLayout.addLayout(gridLayout)
        verticalLayout.addWidget(buttonBox)

        self.linkEdit.setFocus()

    def setTitle(self, txt):
        """Sets the title text to be edited"""
        self.titleEdit.setPlainText(txt)

    def title(self):
        """Provides the new title text"""
        return self.titleEdit.toPlainText()

    def needToCreate(self):
        return self.createCheckBox.isEnabled(
        ) and self.createCheckBox.isChecked()

    def __populate(self, cmlDocComment):
        """Populates the fields from the comment"""
        if cmlDocComment.link:
            self.linkEdit.setText(cmlDocComment.link)
        if cmlDocComment.anchor:
            self.anchorEdit.setText(cmlDocComment.anchor)
        if cmlDocComment.title:
            self.setTitle(cmlDocComment.getTitle())

    def __onSelectPath(self):
        """Select file or directory"""
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        selectedPath = QFileDialog.getOpenFileName(self,
                                                   'Select documentation file',
                                                   self.linkEdit.text(),
                                                   options=options)
        if isinstance(selectedPath, tuple):
            selectedPath = selectedPath[0]
        if selectedPath:
            self.linkEdit.setText(os.path.normpath(selectedPath))

    def __setLinkValid(self):
        """Sets the link edit valid"""
        self.linkEdit.setToolTip(
            'A link to a file or to an external web resource')
        setLineEditBackground(self.linkEdit, self.__validInputColor,
                              self.__validInputColor)

    def __setLinkInvalid(self, msg):
        """Sets the link edit invalid"""
        self.linkEdit.setToolTip(msg)
        setLineEditBackground(self.linkEdit, self.__invalidInputColor,
                              self.__invalidInputColor)

    def __validateLink(self):
        """Validates the link field content"""
        txt = self.linkEdit.text().strip()
        if txt == '' or txt.startswith('http://') or txt.startswith(
                'https://'):
            self.__setLinkValid()
            self.createCheckBox.setEnabled(False)
            return True

        if txt.endswith(os.path.sep):
            self.__setLinkInvalid('A link must be a file, not a directory')
            return False

        # Not a link; it is supposed to be a file or a creatable file
        # However the invalid values will also be acceptable
        self.createCheckBox.setEnabled(True)
        fromFile = None
        if self.__fileName:
            if os.path.isabs(self.__fileName):
                fromFile = self.__fileName
        fName, anchor, errMsg = preResolveLinkPath(
            txt, fromFile, self.createCheckBox.isChecked())
        del anchor

        if fName:
            self.__setLinkValid()
            return True

        self.__setLinkInvalid(errMsg)
        return not self.createCheckBox.isChecked()

    def __setAnchorValid(self):
        """Sets the anchor edit valid"""
        self.anchorEdit.setToolTip(
            'Anchor may not contain neither spaces nor tabs')
        setLineEditBackground(self.anchorEdit, self.__invalidInputColor,
                              self.__validInputColor)

    def __setAnchorInvalid(self):
        """Sets the anchor edit invalid"""
        self.anchorEdit.setToolTip(
            'Anchor is used to refer to it from the other files')
        setLineEditBackground(self.anchorEdit, self.__validInputColor,
                              self.__validInputColor)

    def __validateAnchor(self):
        """Validates the anchor field"""
        txt = self.anchorEdit.text().strip()
        if ' ' in txt or '\t' in txt:
            self.__setAnchorValid()
            return False
        self.__setAnchorInvalid()
        return True

    def __validate(self, _=None):
        """Validates the input fields and sets the OK button enable"""
        self.__OKButton.setToolTip('')
        valid = self.__validateAnchor() and self.__validateLink()
        if valid:
            if not self.linkEdit.text().strip() and not self.anchorEdit.text(
            ).strip():
                valid = False
                self.__OKButton.setToolTip(
                    'At least one of the items: link or anchor must be provided'
                )

        self.__OKButton.setEnabled(valid)
        return valid
    def __createLayout(self):
        """Creates the widget layout"""
        verticalLayout = QVBoxLayout(self)
        verticalLayout.setContentsMargins(0, 0, 0, 0)
        verticalLayout.setSpacing(0)

        self.__excptLabel = HeaderFitLabel(self)
        self.__excptLabel.setText('Ignored exception types')
        self.__excptLabel.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Fixed)
        self.__excptLabel.setMinimumWidth(10)

        self.__showHideButton = QToolButton()
        self.__showHideButton.setAutoRaise(True)
        self.__showHideButton.setIcon(getIcon('less.png'))
        self.__showHideButton.setFixedSize(self.__excptLabel.height(),
                                           self.__excptLabel.height())
        self.__showHideButton.setToolTip('Hide ignored exceptions list')
        self.__showHideButton.setFocusPolicy(Qt.NoFocus)
        self.__showHideButton.clicked.connect(self.onShowHide)

        self.headerToolbar = QToolBar(self)
        self.headerToolbar.setIconSize(QSize(16, 16))
        self.headerToolbar.setContentsMargins(1, 1, 1, 1)
        self.headerToolbar.addWidget(self.__excptLabel)
        self.headerToolbar.addWidget(self.__showHideButton)

        self.exceptionsList = QTreeWidget(self)
        self.exceptionsList.setSortingEnabled(False)
        self.exceptionsList.setAlternatingRowColors(True)
        self.exceptionsList.setRootIsDecorated(False)
        self.exceptionsList.setItemsExpandable(True)
        self.exceptionsList.setUniformRowHeights(True)
        self.exceptionsList.setSelectionMode(QAbstractItemView.SingleSelection)
        self.exceptionsList.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.exceptionsList.setItemDelegate(NoOutlineHeightDelegate(4))
        self.exceptionsList.setContextMenuPolicy(Qt.CustomContextMenu)

        self.exceptionsList.customContextMenuRequested.connect(
            self.__showContextMenu)
        self.exceptionsList.itemSelectionChanged.connect(
            self.__onSelectionChanged)
        self.exceptionsList.setHeaderLabels(["Exception type"])

        self.__excTypeEdit = QLineEdit()
        self.__excTypeEdit.setFixedHeight(26)
        self.__excTypeEdit.textChanged.connect(self.__onNewFilterChanged)
        self.__excTypeEdit.returnPressed.connect(self.__onAddExceptionFilter)
        self.__addButton = QPushButton("Add")
        # self.__addButton.setFocusPolicy(Qt.NoFocus)
        self.__addButton.setEnabled(False)
        self.__addButton.clicked.connect(self.__onAddExceptionFilter)

        self.__removeButton = QAction(getIcon('delitem.png'),
                                      "Remove selected exception type", self)
        self.__removeButton.triggered.connect(self.__onRemoveFromIgnore)
        self.__removeButton.setEnabled(False)

        self.__removeAllButton = QAction(getIcon('ignexcptdelall.png'),
                                         "Remove all the exception types",
                                         self)
        self.__removeAllButton.triggered.connect(self.__onRemoveAllFromIgnore)
        self.__removeAllButton.setEnabled(False)

        self.toolbar = QToolBar()
        self.toolbar.setOrientation(Qt.Horizontal)
        self.toolbar.setMovable(False)
        self.toolbar.setAllowedAreas(Qt.TopToolBarArea)
        self.toolbar.setIconSize(QSize(16, 16))
        self.toolbar.setFixedHeight(28)
        self.toolbar.setContentsMargins(0, 0, 0, 0)
        self.toolbar.addWidget(ToolBarExpandingSpacer(self.toolbar))
        self.toolbar.addAction(self.__removeButton)
        self.toolbar.addWidget(ToolBarHSpacer(self.toolbar, 5))
        self.toolbar.addAction(self.__removeAllButton)

        addLayout = QHBoxLayout()
        addLayout.setContentsMargins(1, 1, 1, 1)
        addLayout.setSpacing(1)
        addLayout.addWidget(self.__excTypeEdit)
        addLayout.addWidget(self.__addButton)

        verticalLayout.addWidget(self.headerToolbar)
        verticalLayout.addWidget(self.toolbar)
        verticalLayout.addWidget(self.exceptionsList)
        verticalLayout.addLayout(addLayout)
예제 #10
0
    def __createProjectSpecific(self):
        """Creates the project specific part"""
        widget = QWidget()

        verticalLayout = QVBoxLayout(widget)
        infoLabel = QLabel("Note: the settings below are used "
                           "only for the specific project.")
        verticalLayout.addWidget(infoLabel)

        # Authorization group box
        authGroupbox = QGroupBox(self)
        authGroupbox.setTitle("Authorization")
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            authGroupbox.sizePolicy().hasHeightForWidth())
        authGroupbox.setSizePolicy(sizePolicy)

        layoutAuth = QVBoxLayout(authGroupbox)
        self.__projectAuthExtRButton = QRadioButton("External", authGroupbox)
        self.__projectAuthExtRButton.clicked.connect(self.__projectAuthChanged)
        layoutAuth.addWidget(self.__projectAuthExtRButton)
        self.__projectAuthPasswdRButton = QRadioButton(
            "Use user name / password", authGroupbox)
        self.__projectAuthPasswdRButton.clicked.connect(
            self.__projectAuthChanged)
        layoutAuth.addWidget(self.__projectAuthPasswdRButton)

        upLayout = QGridLayout()
        self.__projectUser = QLineEdit()
        self.__projectUser.setToolTip("Attention: user name is "
                                      "saved unencrypted")
        self.__projectPasswd = QLineEdit()
        self.__projectPasswd.setToolTip("Attention: password is "
                                        "saved unencrypted")
        spacer = QWidget()
        spacer.setFixedWidth(16)
        upLayout.addWidget(spacer, 0, 0)
        upLayout.addWidget(QLabel("User name"), 0, 1)
        upLayout.addWidget(self.__projectUser, 0, 2)
        upLayout.addWidget(QLabel("Password"), 1, 1)
        upLayout.addWidget(self.__projectPasswd, 1, 2)
        layoutAuth.addLayout(upLayout)

        # Update status group box
        updateGroupbox = QGroupBox(self)
        updateGroupbox.setTitle("Update status policy")
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            updateGroupbox.sizePolicy().hasHeightForWidth())
        updateGroupbox.setSizePolicy(sizePolicy)

        layoutUpdate = QVBoxLayout(updateGroupbox)
        self.__projectReposRButton = QRadioButton("Check repository",
                                                  updateGroupbox)
        layoutUpdate.addWidget(self.__projectReposRButton)
        self.__projectLocalRButton = QRadioButton("Local only", updateGroupbox)
        layoutUpdate.addWidget(self.__projectLocalRButton)

        verticalLayout.addWidget(authGroupbox)
        verticalLayout.addWidget(updateGroupbox)
        return widget
예제 #11
0
class SVNPluginConfigDialog(QDialog):
    """
    SVN Plugin config dialog
    """
    def __init__(self, ideWideSettings, projectSettings, parent=None):
        QDialog.__init__(self, parent)

        self.__projectLocalRButton = None
        self.__idewideUser = None
        self.__idewideLocalRButton = None
        self.__projectReposRButton = None
        self.__idewideAuthPasswdRButton = None
        self.__projectPasswd = None
        self.__projectUser = None
        self.__projectAuthExtRButton = None
        self.__idewidePasswd = None
        self.__idewideAuthExtRButton = None
        self.__projectAuthPasswdRButton = None
        self.__idewideReposRButton = None

        self.__createLayout()
        self.setWindowTitle("SVN plugin configuration")

        self.ideWideSettings = copy.deepcopy(ideWideSettings)
        if projectSettings is None:
            self.projectSettings = None
        else:
            self.projectSettings = copy.deepcopy(projectSettings)

        # Set the values
        self.__setIDEWideValues()
        if projectSettings is None:
            self.__tabWidget.setTabEnabled(1, False)
        else:
            self.__setProjectValues()
            self.__tabWidget.setCurrentIndex(1)
        self.__updateOKStatus()

        self.__idewideUser.textChanged.connect(self.__updateOKStatus)
        self.__projectUser.textChanged.connect(self.__updateOKStatus)

    def __setIDEWideValues(self):
        """Sets the values in the IDE wide tab"""
        if self.ideWideSettings.authKind == AUTH_EXTERNAL:
            self.__idewideAuthExtRButton.setChecked(True)
            self.__idewideUser.setEnabled(False)
            self.__idewidePasswd.setEnabled(False)
        else:
            self.__idewideAuthPasswdRButton.setChecked(True)
            if self.ideWideSettings.userName:
                self.__idewideUser.setText(self.ideWideSettings.userName)
            if self.ideWideSettings.password:
                self.__idewidePasswd.setText(self.ideWideSettings.password)

        if self.ideWideSettings.statusKind == STATUS_REPOSITORY:
            self.__idewideReposRButton.setChecked(True)
        else:
            self.__idewideLocalRButton.setChecked(True)

    def __setProjectValues(self):
        """Sets the values in the project tab"""
        if self.projectSettings.authKind == AUTH_EXTERNAL:
            self.__projectAuthExtRButton.setChecked(True)
            self.__projectUser.setEnabled(False)
            self.__projectPasswd.setEnabled(False)
        else:
            self.__projectAuthPasswdRButton.setChecked(True)
            if self.projectSettings.userName:
                self.__projectUser.setText(self.projectSettings.userName)
            if self.projectSettings.password:
                self.__projectPasswd.setText(self.projectSettings.password)

        if self.projectSettings.statusKind == STATUS_REPOSITORY:
            self.__projectReposRButton.setChecked(True)
        else:
            self.__projectLocalRButton.setChecked(True)

    def __createLayout(self):
        """Creates the dialog layout"""
        self.resize(640, 420)
        self.setSizeGripEnabled(True)

        vboxLayout = QVBoxLayout(self)
        hboxLayout = QHBoxLayout()
        iconLabel = QLabel()
        logoPath = os.path.dirname(os.path.abspath(__file__)) + \
                   os.path.sep + "svn-logo.png"
        iconLabel.setPixmap(QPixmap(logoPath))
        iconLabel.setScaledContents(True)
        iconLabel.setFixedSize(48, 48)
        hboxLayout.addWidget(iconLabel)
        titleLabel = QLabel("Codimension SVN plugin settings")
        titleLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        titleLabel.setFixedHeight(48)
        titleLabel.setAlignment(Qt.AlignCenter)
        hboxLayout.addWidget(titleLabel)
        vboxLayout.addLayout(hboxLayout)

        self.__tabWidget = QTabWidget(self)
        self.__tabWidget.setFocusPolicy(Qt.NoFocus)

        ideWide = self.__createIDEWide()
        self.__tabWidget.addTab(ideWide, "IDE Wide")
        projectSpecific = self.__createProjectSpecific()
        self.__tabWidget.addTab(projectSpecific, "Project Specific")
        version = self.__createVersionWidget()
        self.__tabWidget.addTab(version, "Versions")
        vboxLayout.addWidget(self.__tabWidget)

        # Buttons at the bottom
        self.__buttonBox = QDialogButtonBox(self)
        self.__buttonBox.setOrientation(Qt.Horizontal)
        self.__buttonBox.setStandardButtons(QDialogButtonBox.Ok
                                            | QDialogButtonBox.Cancel)
        self.__buttonBox.accepted.connect(self.userAccept)
        self.__buttonBox.rejected.connect(self.close)
        vboxLayout.addWidget(self.__buttonBox)

    def __createIDEWide(self):
        """Creates the IDE wide part"""
        widget = QWidget()

        verticalLayout = QVBoxLayout(widget)
        infoLabel = QLabel("Note: the settings below are used "
                           "when there is no project loaded.")
        verticalLayout.addWidget(infoLabel)

        # Authorization group box
        authGroupbox = QGroupBox(self)
        authGroupbox.setTitle("Authorization")
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            authGroupbox.sizePolicy().hasHeightForWidth())
        authGroupbox.setSizePolicy(sizePolicy)

        layoutAuth = QVBoxLayout(authGroupbox)
        self.__idewideAuthExtRButton = QRadioButton("External", authGroupbox)
        self.__idewideAuthExtRButton.clicked.connect(self.__idewideAuthChanged)
        layoutAuth.addWidget(self.__idewideAuthExtRButton)
        self.__idewideAuthPasswdRButton = QRadioButton(
            "Use user name / password", authGroupbox)
        self.__idewideAuthPasswdRButton.clicked.connect(
            self.__idewideAuthChanged)
        layoutAuth.addWidget(self.__idewideAuthPasswdRButton)

        upLayout = QGridLayout()
        self.__idewideUser = QLineEdit()
        self.__idewideUser.setToolTip("Attention: user name is "
                                      "saved unencrypted")
        self.__idewidePasswd = QLineEdit()
        self.__idewidePasswd.setToolTip("Attention: password is "
                                        "saved unencrypted")
        spacer = QWidget()
        spacer.setFixedWidth(16)
        upLayout.addWidget(spacer, 0, 0)
        upLayout.addWidget(QLabel("User name"), 0, 1)
        upLayout.addWidget(self.__idewideUser, 0, 2)
        upLayout.addWidget(QLabel("Password"), 1, 1)
        upLayout.addWidget(self.__idewidePasswd, 1, 2)
        layoutAuth.addLayout(upLayout)

        # Update status group box
        updateGroupbox = QGroupBox(self)
        updateGroupbox.setTitle("Update status policy")
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            updateGroupbox.sizePolicy().hasHeightForWidth())
        updateGroupbox.setSizePolicy(sizePolicy)

        layoutUpdate = QVBoxLayout(updateGroupbox)
        self.__idewideReposRButton = QRadioButton("Check repository",
                                                  updateGroupbox)
        layoutUpdate.addWidget(self.__idewideReposRButton)
        self.__idewideLocalRButton = QRadioButton("Local only", updateGroupbox)
        layoutUpdate.addWidget(self.__idewideLocalRButton)

        verticalLayout.addWidget(authGroupbox)
        verticalLayout.addWidget(updateGroupbox)
        return widget

    def __idewideAuthChanged(self):
        """Triggered when authorization has been changed"""
        if self.__idewideAuthExtRButton.isChecked():
            self.__idewideUser.setEnabled(False)
            self.__idewidePasswd.setEnabled(False)
        else:
            self.__idewideUser.setEnabled(True)
            self.__idewidePasswd.setEnabled(True)
            self.__idewideUser.setFocus()
        self.__updateOKStatus()

    def __createProjectSpecific(self):
        """Creates the project specific part"""
        widget = QWidget()

        verticalLayout = QVBoxLayout(widget)
        infoLabel = QLabel("Note: the settings below are used "
                           "only for the specific project.")
        verticalLayout.addWidget(infoLabel)

        # Authorization group box
        authGroupbox = QGroupBox(self)
        authGroupbox.setTitle("Authorization")
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            authGroupbox.sizePolicy().hasHeightForWidth())
        authGroupbox.setSizePolicy(sizePolicy)

        layoutAuth = QVBoxLayout(authGroupbox)
        self.__projectAuthExtRButton = QRadioButton("External", authGroupbox)
        self.__projectAuthExtRButton.clicked.connect(self.__projectAuthChanged)
        layoutAuth.addWidget(self.__projectAuthExtRButton)
        self.__projectAuthPasswdRButton = QRadioButton(
            "Use user name / password", authGroupbox)
        self.__projectAuthPasswdRButton.clicked.connect(
            self.__projectAuthChanged)
        layoutAuth.addWidget(self.__projectAuthPasswdRButton)

        upLayout = QGridLayout()
        self.__projectUser = QLineEdit()
        self.__projectUser.setToolTip("Attention: user name is "
                                      "saved unencrypted")
        self.__projectPasswd = QLineEdit()
        self.__projectPasswd.setToolTip("Attention: password is "
                                        "saved unencrypted")
        spacer = QWidget()
        spacer.setFixedWidth(16)
        upLayout.addWidget(spacer, 0, 0)
        upLayout.addWidget(QLabel("User name"), 0, 1)
        upLayout.addWidget(self.__projectUser, 0, 2)
        upLayout.addWidget(QLabel("Password"), 1, 1)
        upLayout.addWidget(self.__projectPasswd, 1, 2)
        layoutAuth.addLayout(upLayout)

        # Update status group box
        updateGroupbox = QGroupBox(self)
        updateGroupbox.setTitle("Update status policy")
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            updateGroupbox.sizePolicy().hasHeightForWidth())
        updateGroupbox.setSizePolicy(sizePolicy)

        layoutUpdate = QVBoxLayout(updateGroupbox)
        self.__projectReposRButton = QRadioButton("Check repository",
                                                  updateGroupbox)
        layoutUpdate.addWidget(self.__projectReposRButton)
        self.__projectLocalRButton = QRadioButton("Local only", updateGroupbox)
        layoutUpdate.addWidget(self.__projectLocalRButton)

        verticalLayout.addWidget(authGroupbox)
        verticalLayout.addWidget(updateGroupbox)
        return widget

    def __projectAuthChanged(self):
        """Triggered when authorization has been changed"""
        if self.__projectAuthExtRButton.isChecked():
            self.__projectUser.setEnabled(False)
            self.__projectPasswd.setEnabled(False)
        else:
            self.__projectUser.setEnabled(True)
            self.__projectPasswd.setEnabled(True)
            self.__projectUser.setFocus()
        self.__updateOKStatus()

    @staticmethod
    def __getSVNVersion():
        """Provides an svn binary version"""
        try:
            output = check_output(['svn', '--version'])
            for line in output.decode('utf-8').splitlines():
                parts = line.split(' ')
                for index, part in enumerate(parts):
                    if part.lower() == 'version':
                        return parts[index + 1]
        except Exception as exc:
            logging.error(str(exc))
            return None
        return None

    def __createVersionWidget(self):
        """Creates the version tab content"""
        svnVersion = str(self.__getSVNVersion())
        svnModuleVersion = str(svn.__version__)

        text = "<p>The major Codimension SVN plugin " \
               "components are listed below:</p>" \
               "<ul>" \
               "<li><a href='http://subversion.apache.org/'>" \
               "Subversion</a><br>" \
               "Version: " + svnVersion + "<br></li>" \
               "<li><a href='https://github.com/dsoprea/PySvn'>" \
               "Subversion wrapper</a><br>" \
               "Version: " + svnModuleVersion + "<br>" \
               "License: <a href='http://www.gnu.org/licenses/gpl-2.0.html'>" \
               "GPL 2</a>" \
               "<br></li>" \
               "</ul>"

        browser = QTextBrowser()
        browser.setHtml(text)
        browser.setOpenExternalLinks(True)
        return browser

    def userAccept(self):
        """Triggered when the user clicks OK"""
        # Collect IDE-wide values
        if self.__idewideAuthExtRButton.isChecked():
            self.ideWideSettings.authKind = AUTH_EXTERNAL
            self.ideWideSettings.userName = None
            self.ideWideSettings.password = None
        else:
            self.ideWideSettings.authKind = AUTH_PASSWD
            strippedUser = self.__idewideUser.text().strip()
            self.ideWideSettings.userName = strippedUser
            strippedPasswd = self.__idewidePasswd.text().strip()
            self.ideWideSettings.password = strippedPasswd

        if self.__idewideReposRButton.isChecked():
            self.ideWideSettings.statusKind = STATUS_REPOSITORY
        else:
            self.ideWideSettings.statusKind = STATUS_LOCAL_ONLY

        if self.projectSettings is not None:
            if self.__projectAuthExtRButton.isChecked():
                self.projectSettings.authKind = AUTH_EXTERNAL
                self.projectSettings.userName = None
                self.projectSettings.password = None
            else:
                self.projectSettings.authKind = AUTH_PASSWD
                strippedUser = self.__projectUser.text().strip()
                self.projectSettings.userName = strippedUser
                strippedPasswd = self.__projectPasswd.text().strip()
                self.projectSettings.password = strippedPasswd

            if self.__projectReposRButton.isChecked():
                self.projectSettings.statusKind = STATUS_REPOSITORY
            else:
                self.projectSettings.statusKind = STATUS_LOCAL_ONLY
        self.accept()

    def __updateOKStatus(self):
        """Updates the OK button status"""
        okButton = self.__buttonBox.button(QDialogButtonBox.Ok)
        if self.__idewideAuthPasswdRButton.isChecked():
            userName = self.__idewideUser.text().strip()
            if not userName:
                okButton.setEnabled(False)
                okButton.setToolTip("IDE wide SVN user name cannot be empty")
                return
        if self.projectSettings is not None:
            if self.__projectAuthPasswdRButton.isChecked():
                userName = self.__projectUser.text().strip()
                if not userName:
                    okButton.setEnabled(False)
                    okButton.setToolTip("Project specific SVN "
                                        "user name cannot be empty")
                    return

        okButton.setEnabled(True)
        okButton.setToolTip("")