Exemple #1
0
class GanttConfigure(QDialog):
    def __init__(self, sim, start, end):
        QDialog.__init__(self)
        #self.setCaption("Gantt configuration")
        self.layout = QVBoxLayout(self)

#        self._slider = QxtSpanSliderWidget(
#            sim.observe_window[0] // sim.cycles_per_ms,
#            min(sim.now(), sim.observe_window[1]) // sim.cycles_per_ms,
#            self)
        self._slider = QxtSpanSliderWidget(
            0,
            min(sim.now(), sim.duration) // sim.cycles_per_ms,
            self)
        self._slider.setSpan(start, end)
        self.layout.addWidget(self._slider)

        self._list_elements = QListWidget(self)
        for processor in sim.processors:
            item = QListWidgetItem(processor.name, self._list_elements)
            item.setData(Qt.UserRole, processor)
            self._list_elements.addItem(item)
        for task in sim.task_list:
            item = QListWidgetItem(task.name, self._list_elements)
            item.setData(Qt.UserRole, task)
            self._list_elements.addItem(item)
        #self._list_elements.setDragDropMode(QListWidget.InternalMove)
        for row in range(0, self._list_elements.count()):
            self._list_elements.item(row).setCheckState(Qt.Checked)
        self.layout.addWidget(self._list_elements)

        buttons = QWidget(self)
        buttons_layout = QHBoxLayout()
        buttons.setLayout(buttons_layout)
        buttons_layout.addStretch()
        ok_button = QPushButton("Ok")
        cancel_button = QPushButton("Cancel")
        ok_button.clicked.connect(self.accept)
        cancel_button.clicked.connect(self.reject)
        buttons_layout.addWidget(ok_button)
        buttons_layout.addWidget(cancel_button)
        self.layout.addWidget(buttons)

    def get_start_date(self):
        return self._slider.lowerValue

    def get_end_date(self):
        return self._slider.upperValue

    def get_selected_items(self):
        res = []
        for row in range(0, self._list_elements.count()):
            if self._list_elements.item(row).checkState() == Qt.Checked:
                try:
                    data = self._list_elements.item(row).data(Qt.UserRole).toPyObject()
                except AttributeError:
                    data = self._list_elements.item(row).data(Qt.UserRole)

                res.append(data)
        return res
Exemple #2
0
class SnappingDock(DockWidget):
    def __init__(self, iface, parent=None):
        super(SnappingDock, self).__init__(parent)
        self._iface = iface

        self.setWindowTitle(u'Snapping Panel')
        self.setObjectName(u'snappingDock')

        self._listWidget = QListWidget(self)
        self._listWidget.setSelectionMode(QAbstractItemView.NoSelection)
        self._listWidget.setDropIndicatorShown(False)

        self._dockLayout = QVBoxLayout(self)
        self._dockLayout.setObjectName(u'dockLayout')
        self._dockLayout.addWidget(self._listWidget)

        self._dockContents = QWidget(self)
        self._dockContents.setObjectName(u'dockContents')
        self._dockContents.setLayout(self._dockLayout)
        self.setWidget(self._dockContents)

        # Keep up-to-date with layers added and removed
        QgsMapLayerRegistry.instance().layersAdded.connect(self._layersAdded)
        QgsMapLayerRegistry.instance().layersRemoved.connect(
            self._layersRemoved)

    def refresh(self):
        self._listWidget.clear()
        layers = QgsMapLayerRegistry.instance().mapLayers()
        layerIds = layers.keys()
        sorted(layerIds)
        for layerId in layerIds:
            self.addLayer(layers[layerId])

    def addLayer(self, layer):
        if (layer is None or not layer.isValid()
                or layer.type() != QgsMapLayer.VectorLayer):
            return
        newItem = QListWidgetItem()
        newItem.setData(Qt.UserRole, layer.id())
        # newItem.setSizeHint(layerWidget.minimumSizeHint())
        self._listWidget.addItem(newItem)
        self._listWidget.setItemWidget(newItem,
                                       LayerSnappingWidget(layer, self))

    def removeLayer(self, layerId):
        for idx in range(0, self._listWidget.count() - 1):
            if self._listWidget.item(idx).data() == layerId:
                self._listWidget.takeItem(idx)
                return

    def _layersAdded(self, layers):
        for layer in layers:
            self.addLayer(layer)

    def _layersRemoved(self, layerIds):
        for idx in range(self._listWidget.count() - 1, 0):
            if self._listWidget.item(idx).data() in layerIds:
                self._listWidget.takeItem(idx)
class SnappingDock(DockWidget):

    def __init__(self, iface, parent=None):
        super(SnappingDock, self).__init__(parent)
        self._iface = iface

        self.setWindowTitle(u'Snapping Panel')
        self.setObjectName(u'snappingDock')

        self._listWidget = QListWidget(self)
        self._listWidget.setSelectionMode(QAbstractItemView.NoSelection)
        self._listWidget.setDropIndicatorShown(False)

        self._dockLayout = QVBoxLayout(self)
        self._dockLayout.setObjectName(u'dockLayout')
        self._dockLayout.addWidget(self._listWidget)

        self._dockContents = QWidget(self)
        self._dockContents.setObjectName(u'dockContents')
        self._dockContents.setLayout(self._dockLayout)
        self.setWidget(self._dockContents)

        # Keep up-to-date with layers added and removed
        QgsMapLayerRegistry.instance().layersAdded.connect(self._layersAdded)
        QgsMapLayerRegistry.instance().layersRemoved.connect(self._layersRemoved)

    def refresh(self):
        self._listWidget.clear()
        layers = QgsMapLayerRegistry.instance().mapLayers()
        layerIds = layers.keys()
        sorted(layerIds)
        for layerId in layerIds:
            self.addLayer(layers[layerId])

    def addLayer(self, layer):
        if (layer is None or not layer.isValid() or layer.type() != QgsMapLayer.VectorLayer):
            return
        newItem = QListWidgetItem()
        newItem.setData(Qt.UserRole, layer.id())
        # newItem.setSizeHint(layerWidget.minimumSizeHint())
        self._listWidget.addItem(newItem)
        self._listWidget.setItemWidget(newItem, LayerSnappingWidget(layer, self))

    def removeLayer(self, layerId):
        for idx in range(0, self._listWidget.count() - 1):
            if self._listWidget.item(idx).data() == layerId:
                self._listWidget.takeItem(idx)
                return

    def _layersAdded(self, layers):
        for layer in layers:
            self.addLayer(layer)

    def _layersRemoved(self, layerIds):
        for idx in range(self._listWidget.count() - 1, 0):
            if self._listWidget.item(idx).data() in layerIds:
                self._listWidget.takeItem(idx)
Exemple #4
0
class TagsWidget(QWidget):
    tagsChanged = pyqtSignal(list)

    def __init__(self, parent=None):
        super(TagsWidget, self).__init__(parent)
        self.lineEdit = TagLineEdit(self)
        self.lineEdit.returnPressed.connect(
            lambda: QTimer.singleShot(0, self.addTag))
        self.listWidget = QListWidget(self)
        l = QVBoxLayout(self)
        l.addWidget(self.lineEdit)
        l.addWidget(self.listWidget)

        self.availableTags = []
        self.reload()

    def reload(self):
        tags = Session.query(Tag.name, Tag.id).all()
        self.tagsdict = dict(tags)
        self.availableTags = self.tagsdict.keys()
        for i in xrange(self.listWidget.count()):
            tag = self.listWidget.item(i).text()
            if tag in self.availableTags:
                self.availableTags.remove(tag)
        self.lineEdit.completer().model().setStringList(self.availableTags)

    def addTag(self):
        text = self.lineEdit.text()
        if text in self.availableTags:
            self.availableTags.remove(text)
            self.lineEdit.completer().model().setStringList(self.availableTags)
            self.listWidget.addItem(text)
            self.lineEdit.clear()
            self.tagsChanged.emit(self.tags())

    def tags(self):
        tags = [
            self.tagsdict[self.listWidget.item(i).text()]
            for i in xrange(self.listWidget.count())
        ]
        return tags

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Delete:
            self.listWidget.takeItem(self.listWidget.currentRow())
            self.tagsChanged.emit(self.tags())
        else:
            super(TagsWidget, self).keyPressEvent(event)
Exemple #5
0
    def addPathList(self, key, typeid, predefs, selectednodes):
        if not self.overwriteKeys(key) and type(key).__name__=='str':
            layout = QVBoxLayout()
            listpathcontainer = QListWidget() ##XXX
            listpathcontainer.setDragDropMode(QAbstractItemView.InternalMove)
            if len(predefs) > 0:
                if not self.checkUnifiedTypes(predefs):
                    return -1
                for predef in predefs:
                    listpathcontainer.insertItem(listpathcontainer.count() + 1, str(predef))
            if selectednodes and len(selectednodes) > 0:
                for node in selectednodes:
		   if type(node) == Node and typeid == typeId.Node:
                        listpathcontainer.insertItem(listpathcontainer.count() + 1, QString.fromUtf8(node.absolute())) 
		   elif type(node) != Node:
			listpathcontainer.insertItem(listpathcontainer.count() + 1, node)
            hbox = QHBoxLayout()
            buttonbox = QDialogButtonBox()
            if typeid == typeId.Path:
                combo = QComboBox()
	        self.connect(combo, SIGNAL("editTextChanged(QString)"), self.argumentChanged)
		self.connect(combo, SIGNAL("currentIndexChanged(QString)"), self.argumentChanged)
                combo.addItem(self.inputFile)
                combo.addItem(self.inputDirectory)
                add = addLocalPathButton(self, key, listpathcontainer, combo)
            else:
                add = addLocalPathButton(self, key, listpathcontainer, nodetype=True)
            buttonbox.addButton(add, QDialogButtonBox.ActionRole)
            rm = rmLocalPathButton(self, listpathcontainer)
            buttonbox.addButton(rm, QDialogButtonBox.ActionRole)

            self.connect(add, SIGNAL("clicked()"), self.argumentChanged)
            self.connect(rm, SIGNAL("clicked()"), self.argumentChanged)

            hbox.addWidget(buttonbox, 3, Qt.AlignLeft)
            if typeid == typeId.Path:
                hbox.addWidget(combo, 1, Qt.AlignRight)
            layout.addLayout(hbox, 0)
            layout.addWidget(listpathcontainer, 2)

            if not self.displaykey:
                self.layout.addRow(layout)
            else:
                self.layout.addRow(key, layout)
            self.widgets[key] = listpathcontainer
            return 1
        else:
            return -1
Exemple #6
0
class TagsWidget(QWidget):
    tagsChanged = pyqtSignal(list)

    def __init__(self, parent=None):
        super(TagsWidget, self).__init__(parent)
        self.lineEdit = TagLineEdit(self)
        self.lineEdit.returnPressed.connect(
            lambda: QTimer.singleShot(0, self.addTag))
        self.listWidget = QListWidget(self)
        l = QVBoxLayout(self)
        l.addWidget(self.lineEdit)
        l.addWidget(self.listWidget)

        self.availableTags = []
        self.reload()

    def reload(self):
        tags = Session.query(Tag.name, Tag.id).all()
        self.tagsdict = dict(tags)
        self.availableTags = self.tagsdict.keys()
        for i in xrange(self.listWidget.count()):
            tag = self.listWidget.item(i).text()
            if tag in self.availableTags:
                self.availableTags.remove(tag)
        self.lineEdit.completer().model().setStringList(self.availableTags)

    def addTag(self):
        text = self.lineEdit.text()
        if text in self.availableTags:
            self.availableTags.remove(text)
            self.lineEdit.completer().model().setStringList(self.availableTags)
            self.listWidget.addItem(text)
            self.lineEdit.clear()
            self.tagsChanged.emit(self.tags())

    def tags(self):
        tags = [self.tagsdict[self.listWidget.item(i).text()]
                for i in xrange(self.listWidget.count())]
        return tags

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Delete:
            self.listWidget.takeItem(self.listWidget.currentRow())
            self.tagsChanged.emit(self.tags())
        else:
            super(TagsWidget, self).keyPressEvent(event)
Exemple #7
0
class InterfacePage(QWizardPage):

    def __init__(self):
        super(InterfacePage,self).__init__()
        self.completed = False
        self.setTitle('接口设置')
        self.setSubTitle('设置需要实现的接口')
        rootLayout = QVBoxLayout()
        rootLayout.setContentsMargins(20, 30, 20, 30)

        self.lw_interface = QListWidget()
        rootLayout.addWidget(self.lw_interface)
        self.setLayout(rootLayout)

    def initializePage(self):
        super(InterfacePage, self).initializePage()
        exsits = []
        for key in app.g_configurations.interfaces:
            if app.g_configurations.interfaces[key]:
                exsits.append(key)

        for interface in app.g_configurations.config['interfaces']:
            litem = QListWidgetItem(interface['name'])
            litem.setToolTip(interface['description'])
            litem.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            if app.g_configurations.initialized:
                if interface['name'] in exsits:
                    litem.setCheckState(Qt.Checked)
                else:
                    litem.setCheckState(Qt.Unchecked)
            else:
                isdefault = False
                if app.g_configurations.component_type == "window":
                    if interface['default'] & 2:
                        isdefault = True
                else:
                    if interface['default'] & 1:
                        isdefault = True
                if isdefault:
                    litem.setCheckState(Qt.Checked)
                else:
                    litem.setCheckState(Qt.Unchecked)
            self.lw_interface.addItem(litem)

    def validatePage(self):
        interfaces = {}
        for i in range(self.lw_interface.count()):
            litem = self.lw_interface.item(i)
            key = app.QString2str(litem.text())
            if litem.checkState() == 2:
                interfaces[key] = True;
            else:
                interfaces[key] = False;

        app.g_configurations.interfaces = interfaces
        return True
Exemple #8
0
class InterfacePage(QWizardPage):
    def __init__(self):
        super(InterfacePage, self).__init__()
        self.completed = False
        self.setTitle('接口设置')
        self.setSubTitle('设置需要实现的接口')
        rootLayout = QVBoxLayout()
        rootLayout.setContentsMargins(20, 30, 20, 30)

        self.lw_interface = QListWidget()
        rootLayout.addWidget(self.lw_interface)
        self.setLayout(rootLayout)

    def initializePage(self):
        super(InterfacePage, self).initializePage()
        exsits = []
        for key in app.g_configurations.interfaces:
            if app.g_configurations.interfaces[key]:
                exsits.append(key)

        for interface in app.g_configurations.config['interfaces']:
            litem = QListWidgetItem(interface['name'])
            litem.setToolTip(interface['description'])
            litem.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
            if app.g_configurations.initialized:
                if interface['name'] in exsits:
                    litem.setCheckState(Qt.Checked)
                else:
                    litem.setCheckState(Qt.Unchecked)
            else:
                isdefault = False
                if app.g_configurations.component_type == "window":
                    if interface['default'] & 2:
                        isdefault = True
                else:
                    if interface['default'] & 1:
                        isdefault = True
                if isdefault:
                    litem.setCheckState(Qt.Checked)
                else:
                    litem.setCheckState(Qt.Unchecked)
            self.lw_interface.addItem(litem)

    def validatePage(self):
        interfaces = {}
        for i in range(self.lw_interface.count()):
            litem = self.lw_interface.item(i)
            key = app.QString2str(litem.text())
            if litem.checkState() == 2:
                interfaces[key] = True
            else:
                interfaces[key] = False

        app.g_configurations.interfaces = interfaces
        return True
Exemple #9
0
class ChainComposerDialog(QDialog):
    def __init__(self, parent=None):
        super(ChainComposerDialog, self).__init__(parent)
        self.setWindowTitle("Composer Chain")

        layout = QVBoxLayout()

        mainLayout = QHBoxLayout()

        selectionLayout = QVBoxLayout()
        label = QLabel("Available Filters:")
        selectionLayout.addWidget(label)
        self.__selectionList = QListWidget()
        selectionLayout.addWidget(self.__selectionList)
        mainLayout.addLayout(selectionLayout)

        actionsLayout = QVBoxLayout()
        actionsLayout.addStretch()
        addButton = QPushButton("Add>>")
        addButton.clicked.connect(self.__handleAdd)
        actionsLayout.addWidget(addButton)
        removeButton = QPushButton("Remove")
        actionsLayout.addWidget(removeButton)
        removeAllButton = QPushButton("Remove All")
        actionsLayout.addWidget(removeAllButton)
        actionsLayout.addStretch()
        mainLayout.addLayout(actionsLayout)

        chainLayout = QVBoxLayout()
        chainLayout.addWidget(QLabel("Chain:"))
        self.__chainList = QListWidget()
        chainLayout.addWidget(self.__chainList)
        mainLayout.addLayout(chainLayout)

        layout.addLayout(mainLayout)

        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        buttonBox.accepted.connect(self.okClick)
        buttonBox.rejected.connect(self.cancelClick)
        layout.addWidget(buttonBox)

        #         buttonLayout = QHBoxLayout()
        #         okButton = QPushButton('OK')
        #         okButton.clicked.connect(self.accept)
        #         buttonLayout.addWidget(okButton)
        #         cancelButton = QPushButton('Cancel')
        #         cancelButton.clicked.connect(self.reject)
        #         buttonLayout.addWidget(cancelButton)
        #         layout.addLayout(buttonLayout)

        self.setLayout(layout)

        self.__composer = None

    def okClick(self):
        print "OK!"
        self.accept()

    def cancelClick(self):
        print "Cancel"
        self.reject()

    def setComposer(self, composer):
        self.__composer = composer

    @property
    def selectionList(self):
        return self.__getStrings(self.__selectionList)

    @selectionList.setter
    def setSelectionList(self, filters):
        for i in xrange(self.__selectionList.count()):
            self.__selectionList.takeItem(i)
        self.__selectionList.addItems(filters)

    def filterAt(self, row):
        return self.__selectionList.item(row).text()

    def addToChain(self, filterName):
        self.__chainList.addItem(filterName)

    @property
    def composedFilter(self):
        return self.__getStrings(self.__chainList)

    @staticmethod
    def __getStrings(listWidget):
        return tuple(listWidget.item(i) for i in range(listWidget.count()))

    def __handleAdd(self):
        if self.__composer is None:
            return
        for item in self.__selectionList.selectedItems():
            row = self.__selectionList.row(item)
            self.__composer.add(row)
Exemple #10
0
class SolverGenerator(QWidget):
    def __init__(self):
        super().__init__()

        self._init_info_base()
        self._init_ui()

    def _init_info_base(self):
        f = open('base')
        lines = [line for line in f.readlines() if line.split()]
        count = int(lines[0])

        self._names = {}
        for line in lines[1:1 + count]:
            line = line.split(' ', 1)
            self._names[line[1].rstrip()] = line[0]

        model = [Formula(info=line1, code=line2) for line1, line2 in
                 zip(lines[1 + count::2], lines[2 + count::2])]
        self._info_base = InfoBase(model)

    def _init_ui(self):
        main = QVBoxLayout(self)

        up_label = QLabel('Входные параметры:')
        up_label.setAlignment(Qt.AlignCenter)
        main.addWidget(up_label)
        up = QHBoxLayout(self)
        self.up_left = QListWidget(self)
        self.up_left.addItems(list(self._names.keys()))
        self.up_left.sortItems()
        up.addWidget(self.up_left)

        up_buttons = QVBoxLayout(self)
        up_to_right = QPushButton('>')
        self.connect(up_to_right, SIGNAL('pressed()'), self._up_to_right)
        up_buttons.addWidget(up_to_right)
        up_to_left = QPushButton('<')
        self.connect(up_to_left, SIGNAL('pressed()'), self._up_to_left)
        up_buttons.addWidget(up_to_left)
        up_buttons.setAlignment(Qt.AlignCenter)
        up.addLayout(up_buttons)

        self.up_right = QListWidget(self)
        up.addWidget(self.up_right)
        self.up_right.sortItems()
        main.addLayout(up)

        down_label = QLabel('Выходные параметры:')
        down_label.setAlignment(Qt.AlignCenter)
        main.addWidget(down_label)

        down = QHBoxLayout(self)
        self.down_left = QListWidget(self)
        self.down_left.addItems(list(self._names.keys()))
        self.down_left.sortItems()
        down.addWidget(self.down_left)

        down_buttons = QVBoxLayout(self)
        down_to_right = QPushButton('>')
        self.connect(down_to_right, SIGNAL('pressed()'), self._down_to_right)
        down_buttons.addWidget(down_to_right)
        down_to_left = QPushButton('<')
        self.connect(down_to_left, SIGNAL('pressed()'), self._down_to_left)
        down_buttons.addWidget(down_to_left)
        down_buttons.setAlignment(Qt.AlignCenter)
        down.addLayout(down_buttons)

        self.down_right = QListWidget(self)
        down.addWidget(self.down_right)
        self.down_right.sortItems()
        main.addLayout(down)

        solve = QPushButton('Решить')
        self.connect(solve, SIGNAL('pressed()'), self._solve)
        main.addWidget(solve)

        self.setLayout(main)
        self.setWindowTitle('SolverGenerator')
        self.resize(600, 600)
        self._center()
        self.show()

    def _solve(self):
        input_definition = [self.up_right.item(i).text() for i in
                            range(self.up_right.count())]
        input_params = [self._names[item] for item in input_definition]
        output_definition = [self.down_right.item(i).text() for i in
                             range(self.down_right.count())]
        output_params = [self._names[item] for item in output_definition]

        algorithm = self._info_base.get_algorithm(input_params, output_params)
        if algorithm:
            self._generate_code(input_definition, input_params,
                                output_definition, output_params, algorithm)
        else:
            QMessageBox().warning(self, 'Решения нет',
                                  'Для выбранных данных решения нет')

    def _up_to_right(self):
        item = self.up_left.takeItem(self.up_left.currentRow())
        self.up_right.addItem(item)
        self.up_right.sortItems()

    def _up_to_left(self):
        item = self.up_right.takeItem(self.up_right.currentRow())
        self.up_left.addItem(item)
        self.up_left.sortItems()

    def _down_to_right(self):
        item = self.down_left.takeItem(self.down_left.currentRow())
        self.down_right.addItem(item)
        self.down_right.sortItems()

    def _down_to_left(self):
        item = self.down_right.takeItem(self.down_right.currentRow())
        self.down_left.addItem(item)
        self.down_left.sortItems()

    def _center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    @staticmethod
    def _generate_code(input_definition, input_params, output_definition,
                       output_params, algorithm):
        code = []
        if any('math' in formula.code for formula in algorithm):
            code.append('import math')
        for name, definition in zip(input_params, input_definition):
            code.append(
                    '{0} = float(input("Введите {0} ({1}): "))'.format(name,
                                                                       definition.lower()))

        for formula in algorithm:
            code.append(formula.code)

        for name, definition in zip(output_params, output_definition):
            code.append('print("{0} = %f" % {1})'.format(definition, name))

        code.append('input("Нажмите Enter для завершения.")')
        code.append('')

        code = '\n'.join(code)

        file = open('program.py', 'w')
        file.write(code)
        file.close()

        xterm = sh.Command('xterm')
        xterm('-e', 'python3 program.py')
class CodeCompletionWidget(QFrame):
    def __init__(self, editor):
        super(CodeCompletionWidget, self).__init__(None, Qt.FramelessWindowHint | Qt.ToolTip)
        self._editor = editor
        self.stack_layout = QStackedLayout(self)
        self.stack_layout.setContentsMargins(0, 0, 0, 0)
        self.stack_layout.setSpacing(0)
        self.completion_list = QListWidget()
        self.completion_list.setMinimumHeight(200)
        self.completion_list.setAlternatingRowColors(True)
        self._list_index = self.stack_layout.addWidget(self.completion_list)

        self._icons = {
            "a": resources.IMAGES["attribute"],
            "f": resources.IMAGES["function"],
            "c": resources.IMAGES["class"],
        }

        self.cc = code_completion.CodeCompletion()
        self._completion_results = []
        self._prefix = u""
        self.setVisible(False)
        self.source = ""
        self._key_operations = {
            Qt.Key_Up: self._select_previous_row,
            Qt.Key_Down: self._select_next_row,
            Qt.Key_PageUp: (lambda: self._select_previous_row(6)),
            Qt.Key_PageDown: (lambda: self._select_next_row(6)),
            Qt.Key_Right: lambda: None,
            Qt.Key_Left: lambda: None,
            Qt.Key_Enter: self.pre_key_insert_completion,
            Qt.Key_Return: self.pre_key_insert_completion,
            Qt.Key_Tab: self.pre_key_insert_completion,
            Qt.Key_Space: self.hide_completer,
            Qt.Key_Escape: self.hide_completer,
            Qt.Key_Backtab: self.hide_completer,
            Qt.NoModifier: self.hide_completer,
            Qt.ShiftModifier: self.hide_completer,
        }

        desktop = QApplication.instance().desktop()
        self._desktop_geometry = desktop.availableGeometry()

        self.connect(self._editor.document(), SIGNAL("blockCountChanged(int)"), self.update_metadata)

    def _select_next_row(self, move=1):
        new_row = self.completion_list.currentRow() + move
        if new_row < self.completion_list.count():
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(0)
        return True

    def _select_previous_row(self, move=1):
        new_row = self.completion_list.currentRow() - move
        if new_row >= 0:
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(self.completion_list.count() - move)
        return True

    def update_metadata(self):
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        self.cc.analyze_file("", source)

    def insert_completion(self, insert):
        if insert != self._prefix:
            extra = len(self._prefix) - len(insert)
            self._editor.textCursor().insertText(insert[extra:])
        self.hide_completer()

    def _get_geometry(self):
        cr = self._editor.cursorRect()
        point = self._editor.mapToGlobal(cr.topLeft())
        cr.moveTopLeft(point)
        # Check new position according desktop geometry
        width = (
            self.completion_list.sizeHintForColumn(0) + self.completion_list.verticalScrollBar().sizeHint().width() + 10
        )
        height = 200
        orientation = (point.y() + height) < self._desktop_geometry.height()
        if orientation:
            cr.moveTop(cr.bottom())
        cr.setWidth(width)
        cr.setHeight(height)
        if not orientation:
            cr.moveBottom(cr.top())
        xpos = self._desktop_geometry.width() - (point.x() + width)
        if xpos < 0:
            cr.moveLeft(cr.left() + xpos)
        return cr

    def complete(self, results):
        self.add_list_items(results)
        self.completion_list.setCurrentRow(0)
        cr = self._get_geometry()
        self.setGeometry(cr)
        self.completion_list.updateGeometries()
        self.show()

    def add_list_items(self, proposals):
        self.completion_list.clear()
        for p in proposals:
            self.completion_list.addItem(
                QListWidgetItem(QIcon(self._icons.get(p[0], resources.IMAGES["attribute"])), p[1])
            )

    def set_completion_prefix(self, prefix):
        self._prefix = prefix
        proposals = []
        proposals += [("c", item) for item in self.completion_results.get("classes", []) if item.startswith(prefix)]
        proposals += [("a", item) for item in self.completion_results.get("attributes", []) if item.startswith(prefix)]
        proposals += [("f", item) for item in self.completion_results.get("functions", []) if item.startswith(prefix)]
        if proposals:
            self.complete(proposals)
        else:
            self.hide_completer()

    def fill_completer(self):
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        offset = self._editor.textCursor().position()
        results = self.cc.get_completion(source, offset)
        self.completion_results = results
        prefix = self._editor._text_under_cursor()
        self.set_completion_prefix(prefix)

    def hide_completer(self):
        self._prefix = ""
        self.hide()

    def pre_key_insert_completion(self):
        insert = unicode(self.completion_list.currentItem().text())
        self.insert_completion(insert)
        self.hide_completer()
        return True

    def process_pre_key_event(self, event):
        if not self.isVisible():
            return False
        skip = self._key_operations.get(event.key(), lambda: False)()
        self._key_operations.get(event.modifiers(), lambda: False)()
        if skip is None:
            skip = False
        return skip

    def process_post_key_event(self, event):
        if not settings.CODE_COMPLETION or self._editor.lang != "python":
            return
        if self.isVisible():
            source = self._editor.get_text()
            source = source.encode(self._editor.encoding)
            offset = self._editor.textCursor().position()
            prefix = self.cc.get_prefix(source, offset)
            self.set_completion_prefix(prefix)
            self.completion_list.setCurrentRow(0)
        if event.key() == Qt.Key_Period or (event.key() == Qt.Key_Space and event.modifiers() == Qt.ControlModifier):
            self.fill_completer()
Exemple #12
0
class NotebookListDialog(QDialog):
    """ Funtions to display, create, remove, modify notebookList """

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

        self.notebookList = QListWidget()
        self.moveUp = QPushButton('<<')
        self.moveDown = QPushButton('>>')
        self.add = QPushButton('Add')
        self.remove = QPushButton('Remove')
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok |
                                          QDialogButtonBox.Cancel)
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
        layout = QGridLayout()
        layout.addWidget(self.notebookList, 0, 0, 4, 6)
        layout.addWidget(self.moveUp, 1, 6)
        layout.addWidget(self.moveDown, 2, 6)
        layout.addWidget(self.add, 4, 0)
        layout.addWidget(self.remove, 4, 1)
        layout.addWidget(self.buttonBox, 4, 5, 1, 2)
        self.setLayout(layout)

        self.notebookList.setItemDelegate(ListDelegate(self.notebookList))

        self.notebookList.currentRowChanged.connect(self.updateUi)
        self.add.clicked.connect(self.actionAdd)
        self.remove.clicked.connect(self.actionRemove)
        self.moveUp.clicked.connect(self.moveItemUp)
        self.moveDown.clicked.connect(self.moveItemDown)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.initList()

    def initList(self):
        self.notebookList.clear()
        notebooks = Mikibook.read()
        for nb in notebooks:
            item = QListWidgetItem()
            item.setData(Qt.DisplayRole, nb[0])
            item.setData(Qt.UserRole, nb[1])
            self.notebookList.addItem(item)

        self.updateUi(len(notebooks) != 0)
        self.notebookList.setCurrentRow(0)
            # QListWidgetItem(nb, self.notebookList)

    def updateUi(self, row):
        flag = (row != -1)
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(flag)
        self.remove.setEnabled(flag)
        self.moveUp.setEnabled(flag)
        self.moveDown.setEnabled(flag)

    def actionAdd(self):
        Mikibook.create()
        self.initList()
        count = self.notebookList.count()
        self.notebookList.setCurrentRow(count-1)

    def actionRemove(self):
        item = self.notebookList.currentItem()
        row = self.notebookList.currentRow()
        name = item.data(Qt.DisplayRole)
        path = item.data(Qt.UserRole)
        self.notebookList.takeItem(row)

        Mikibook.remove(name, path)

    def moveItemUp(self):
        item = self.notebookList.currentItem()
        row = self.notebookList.currentRow()
        if row != 0:
            # self.notebookList.removeItemWidget(item)
            self.notebookList.takeItem(row)
            self.notebookList.insertItem(row-1, item)
            self.notebookList.setCurrentRow(row-1)

    def moveItemDown(self):
        item = self.notebookList.currentItem()
        row = self.notebookList.currentRow()
        count = self.notebookList.count()
        if row != count-1:
            self.notebookList.takeItem(row)
            self.notebookList.insertItem(row+1, item)
            self.notebookList.setCurrentRow(row+1)

    def accept(self):
        notebookPath = self.notebookList.currentItem().data(Qt.UserRole)
        notebookName = self.notebookList.currentItem().data(Qt.DisplayRole)
        settings = Setting([[notebookName, notebookPath]])
        window = mikidown.MikiWindow(settings)
        window.show()
        count = self.notebookList.count()
        notebooks = []
        for i in range(count):
            name = self.notebookList.item(i).data(Qt.DisplayRole)
            path = self.notebookList.item(i).data(Qt.UserRole)
            notebooks.append([name, path])
            Mikibook.write(notebooks)

        QDialog.accept(self)
Exemple #13
0
class CodeCompletionWidget(QFrame):
    def __init__(self, editor):
        super(CodeCompletionWidget,
              self).__init__(None, Qt.FramelessWindowHint | Qt.ToolTip)
        self._editor = editor
        self._revision = 0
        self._block = 0
        self.stack_layout = QStackedLayout(self)
        self.stack_layout.setContentsMargins(0, 0, 0, 0)
        self.stack_layout.setSpacing(0)
        self.completion_list = QListWidget()
        self.completion_list.setMinimumHeight(200)
        self.completion_list.setAlternatingRowColors(True)
        self._list_index = self.stack_layout.addWidget(self.completion_list)

        self._icons = {
            'a': resources.IMAGES['attribute'],
            'f': resources.IMAGES['function'],
            'c': resources.IMAGES['class'],
            'm': resources.IMAGES['module']
        }

        self.cc = code_completion.CodeCompletion()
        self._completion_results = {}
        self._prefix = ''
        self.setVisible(False)
        self.source = ''
        self._key_operations = {
            Qt.Key_Up: self._select_previous_row,
            Qt.Key_Down: self._select_next_row,
            Qt.Key_PageUp: (lambda: self._select_previous_row(6)),
            Qt.Key_PageDown: (lambda: self._select_next_row(6)),
            Qt.Key_Right: lambda: None,
            Qt.Key_Left: lambda: None,
            Qt.Key_Enter: self.pre_key_insert_completion,
            Qt.Key_Return: self.pre_key_insert_completion,
            Qt.Key_Tab: self.pre_key_insert_completion,
            Qt.Key_Space: self.hide_completer,
            Qt.Key_Escape: self.hide_completer,
            Qt.Key_Backtab: self.hide_completer,
            Qt.NoModifier: self.hide_completer,
            Qt.ShiftModifier: self.hide_completer,
        }

        self.desktop = QApplication.instance().desktop()

        self.connect(self.completion_list,
                     SIGNAL("itemClicked(QListWidgetItem*)"),
                     self.pre_key_insert_completion)
        self.connect(self._editor.document(),
                     SIGNAL("cursorPositionChanged(QTextCursor)"),
                     self.update_metadata)

    def _select_next_row(self, move=1):
        new_row = self.completion_list.currentRow() + move
        if new_row < self.completion_list.count():
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(0)
        return True

    def _select_previous_row(self, move=1):
        new_row = self.completion_list.currentRow() - move
        if new_row >= 0:
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(self.completion_list.count() -
                                               move)
        return True

    def update_metadata(self, cursor):
        if settings.CODE_COMPLETION:
            if self._editor.document().revision() != self._revision and \
               cursor.block().blockNumber() != self._block:
                source = self._editor.get_text()
                source = source.encode(self._editor.encoding)
                self.cc.analyze_file(self._editor.ID, source,
                                     self._editor.indent, self._editor.useTabs)
                self._revision = self._editor.document().revision()
                self._block = cursor.block().blockNumber()

    def insert_completion(self, insert, type_=ord('a')):
        if insert != self._prefix:
            closing = ''
            if type_ in (ord('f'), ord('c')):
                closing = '()'
            extra = len(self._prefix) - len(insert)
            insertion = '%s%s' % (insert[extra:], closing)
            self._editor.textCursor().insertText(insertion)
        self.hide_completer()

    def _get_geometry(self):
        cr = self._editor.cursorRect()
        desktop_geometry = self.desktop.availableGeometry(self._editor)
        point = self._editor.mapToGlobal(cr.topLeft())
        cr.moveTopLeft(point)
        #Check new position according desktop geometry
        width = (self.completion_list.sizeHintForColumn(0) +
                 self.completion_list.verticalScrollBar().sizeHint().width() +
                 10)
        height = 200
        orientation = (point.y() + height) < desktop_geometry.height()
        if orientation:
            cr.moveTop(cr.bottom())
        cr.setWidth(width)
        cr.setHeight(height)
        if not orientation:
            cr.moveBottom(cr.top())
        xpos = desktop_geometry.width() - (point.x() + width)
        if xpos < 0:
            cr.moveLeft(cr.left() + xpos)
        return cr

    def complete(self, results):
        self.add_list_items(results)
        self.completion_list.setCurrentRow(0)
        cr = self._get_geometry()
        self.setGeometry(cr)
        self.completion_list.updateGeometries()
        self.show()

    def add_list_items(self, proposals):
        self.completion_list.clear()
        for p in proposals:
            self.completion_list.addItem(
                QListWidgetItem(QIcon(
                    self._icons.get(p[0], resources.IMAGES['attribute'])),
                                p[1],
                                type=ord(p[0])))

    def set_completion_prefix(self, prefix, valid=True):
        self._prefix = prefix
        proposals = []
        proposals += [('m', item)
                      for item in self._completion_results.get('modules', [])
                      if item.startswith(prefix)]
        proposals += [('c', item)
                      for item in self._completion_results.get('classes', [])
                      if item.startswith(prefix)]
        proposals += [
            ('a', item)
            for item in self._completion_results.get('attributes', [])
            if item.startswith(prefix)
        ]
        proposals += [
            ('f', item)
            for item in self._completion_results.get('functions', [])
            if item.startswith(prefix)
        ]
        if proposals and valid:
            self.complete(proposals)
        else:
            self.hide_completer()

    def _invalid_completion_position(self):
        result = False
        cursor = self._editor.textCursor()
        cursor.movePosition(QTextCursor.StartOfLine, QTextCursor.KeepAnchor)
        selection = cursor.selectedText()[:-1].split(' ')
        if len(selection) == 0 or selection[-1] == '' or \
           selection[-1].isdigit():
            result = True
        return result

    def fill_completer(self, force_completion=False):
        if not force_completion and (self._editor.cursor_inside_string()
                                     or self._editor.cursor_inside_comment()
                                     or self._invalid_completion_position()):
            return
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        offset = self._editor.textCursor().position()
        results = self.cc.get_completion(source, offset)
        self._completion_results = results
        if force_completion:
            cursor = self._editor.textCursor()
            cursor.movePosition(QTextCursor.StartOfWord,
                                QTextCursor.KeepAnchor)
            prefix = cursor.selectedText()
        else:
            prefix = self._editor._text_under_cursor()
        self.set_completion_prefix(prefix)

    def hide_completer(self):
        self._prefix = ''
        self.hide()

    def pre_key_insert_completion(self):
        type_ = ord('a')
        current = self.completion_list.currentItem()
        insert = current.text()
        if not insert.endswith(')'):
            type_ = current.type()
        self.insert_completion(insert, type_)
        self.hide_completer()
        return True

    def process_pre_key_event(self, event):
        if not self.isVisible() or self._editor.lang != "python":
            return False
        skip = self._key_operations.get(event.key(), lambda: False)()
        self._key_operations.get(event.modifiers(), lambda: False)()
        if skip is None:
            skip = False
        return skip

    def process_post_key_event(self, event):
        if not settings.CODE_COMPLETION or self._editor.lang != "python":
            return
        if self.isVisible():
            source = self._editor.get_text()
            source = source.encode(self._editor.encoding)
            offset = self._editor.textCursor().position()
            prefix, valid = self.cc.get_prefix(source, offset)
            self.set_completion_prefix(prefix, valid)
            self.completion_list.setCurrentRow(0)
        force_completion = (event.key() == Qt.Key_Space
                            and event.modifiers() == Qt.ControlModifier)
        if event.key() == Qt.Key_Period or force_completion:
            self.fill_completer(force_completion)
class AdvancedVisualizationForm(QWidget):
    def __init__(self, mainwindow, result_manager):
        QWidget.__init__(self, mainwindow)
        #mainwindow is an OpusGui
        self.mainwindow = mainwindow
        self.result_manager = result_manager
        self.toolboxBase = self.result_manager.mainwindow.toolboxBase

        self.inGui = False
        self.logFileKey = 0
        
        self.xml_helper = ResultsManagerXMLHelper(toolboxBase = self.toolboxBase)
        self.result_generator = OpusResultGenerator(
                                    toolboxBase = self.toolboxBase)
            
        self.result_generator.guiElement = self
        
        self.tabIcon = QIcon(':/Images/Images/cog.png')
        self.tabLabel = 'Advanced Visualization'

        self.widgetLayout = QVBoxLayout(self)
        self.widgetLayout.setAlignment(Qt.AlignTop)

        self.resultsGroupBox = QGroupBox(self)
        self.widgetLayout.addWidget(self.resultsGroupBox)
        
        self.dataGroupBox = QGroupBox(self)
        self.widgetLayout.addWidget(self.dataGroupBox)
        
        self.optionsGroupBox = QGroupBox(self)
        self.widgetLayout.addWidget(self.optionsGroupBox)
                
        self._setup_definition_widget()

        self._setup_buttons()
        self._setup_tabs()
        
    def _setup_buttons(self):
        # Add Generate button...
        self.pbn_go = QPushButton(self.resultsGroupBox)
        self.pbn_go.setObjectName('pbn_go')
        self.pbn_go.setText(QString('Go!'))
        
        QObject.connect(self.pbn_go, SIGNAL('released()'),
                        self.on_pbn_go_released)
        self.widgetLayout.addWidget(self.pbn_go)
        
        self.pbn_set_esri_storage_location = QPushButton(self.optionsGroupBox)
        self.pbn_set_esri_storage_location.setObjectName('pbn_set_esri_storage_location')
        self.pbn_set_esri_storage_location.setText(QString('...'))
        self.pbn_set_esri_storage_location.hide()
        
        QObject.connect(self.pbn_set_esri_storage_location, SIGNAL('released()'),
                        self.on_pbn_set_esri_storage_location_released)
        
    def _setup_tabs(self):
        # Add a tab widget and layer in a tree view and log panel
        self.tabWidget = QTabWidget(self.resultsGroupBox)
    
        # Log panel
        self.logText = QTextEdit(self.resultsGroupBox)
        self.logText.setReadOnly(True)
        self.logText.setLineWidth(0)
        self.tabWidget.addTab(self.logText,'Log')

        # Finally add the tab to the model page
        self.widgetLayout.addWidget(self.tabWidget)
        
#
    def _setup_definition_widget(self):
        
        #### setup results group box ####
        
        self.gridlayout = QGridLayout(self.resultsGroupBox)
        self.gridlayout.setObjectName('gridlayout')

        self.lbl_results = QLabel(self.resultsGroupBox)
        self.lbl_results.setObjectName('lbl_results')
        self.lbl_results.setText(QString('Results'))
        self.gridlayout.addWidget(self.lbl_results,0,0,1,3)

        self._setup_co_results()
        self.gridlayout.addWidget(self.co_results,0,3,1,10)

        self.pbn_add = QPushButton(self.resultsGroupBox)
        self.pbn_add.setObjectName('pbn_add')
        self.pbn_add.setText(QString('+'))
        
        QObject.connect(self.pbn_add, SIGNAL('released()'),
                        self.on_pbn_add_released)
        self.gridlayout.addWidget(self.pbn_add, 0, 14, 1, 1)

        self.lw_indicators = QListWidget(self.resultsGroupBox)
        self.lw_indicators.setObjectName('lw_indicators')
        self.gridlayout.addWidget(self.lw_indicators,1,1,1,13)

        self.pbn_remove = QPushButton(self.resultsGroupBox)
        self.pbn_remove.setObjectName('pbn_remove')
        self.pbn_remove.setText(QString('-'))
        
        QObject.connect(self.pbn_remove, SIGNAL('released()'),
                        self.on_pbn_remove_released)
        self.gridlayout.addWidget(self.pbn_remove, 1, 14, 1, 1)


        #### setup data group box ####

        self.gridlayout2 = QGridLayout(self.dataGroupBox)
        self.gridlayout2.setObjectName('gridlayout2')

        self._setup_co_result_style()
        self.gridlayout2.addWidget(self.co_result_style,1,0,1,2)
                
        self.lbl_result_style_sep = QLabel(self.resultsGroupBox)
        self.lbl_result_style_sep.setObjectName('lbl_result_style_sep')
        self.lbl_result_style_sep.setText(QString('<center>as</center>'))
        self.gridlayout2.addWidget(self.lbl_result_style_sep,1,2,1,1)

        self._setup_co_result_type()
        self.gridlayout2.addWidget(self.co_result_type,1,3,1,2)

        ##### setup options group box ####
        
        self.gridlayout3 = QGridLayout(self.optionsGroupBox)
        self.gridlayout3.setObjectName('gridlayout3')
        
        self.le_esri_storage_location = QLineEdit(self.optionsGroupBox)
        self.le_esri_storage_location.setObjectName('le_esri_storage_location')
        self.le_esri_storage_location.setText('[set path]')
        self.le_esri_storage_location.hide()
        self.optionsGroupBox.hide()

        
        QObject.connect(self.co_result_style, SIGNAL('currentIndexChanged(int)'),
                self.on_co_result_style_changed)
        QObject.connect(self.co_result_type, SIGNAL('currentIndexChanged(int)'),
                self.on_co_result_type_changed)

    def _setup_co_results(self):
        
        self.co_results = QComboBox(self.resultsGroupBox)
        self.co_results.setObjectName('co_results')
        self.co_results.addItem(QString('[select]'))
        
        results = self.xml_helper.get_available_results()
            
        for result in results:
            name = '%i.%s'%(result['run_id'],result['indicator_name'])
            self.co_results.addItem(QString(name))

    def _setup_co_result_style(self):
        available_styles = [
            'visualize',
            'export',
        ]
        self.co_result_style = QComboBox(self.dataGroupBox)
        self.co_result_style.setObjectName('co_result_style')
        
        for dataset in available_styles:
            self.co_result_style.addItem(QString(dataset))

    def _setup_co_result_type(self):
        available_types = [
            'Table (per year, spans indicators)',
            'Chart (per indicator, spans years)',
            'Map (per indicator per year)',
            'Chart (per indicator, spans years)',
        ]
                
        self.co_result_type = QComboBox(self.dataGroupBox)
        self.co_result_type.setObjectName('co_result_type')
        
        for dataset in available_types:
            self.co_result_type.addItem(QString(dataset))
                    
    def on_pbnRemoveModel_released(self):
        self.result_manager.removeTab(self)
        self.result_manager.updateGuiElements()
        
    def on_pbn_add_released(self):
        cur_selected = self.co_results.currentText()        
        for i in range(self.lw_indicators.count()):
            if self.lw_indicators.item(i).text() == cur_selected:
                return
        
        self.lw_indicators.addItem(cur_selected)
        
    def on_pbn_remove_released(self):
        selected_idxs = self.lw_indicators.selectedIndexes()
        for idx in selected_idxs:
            self.lw_indicators.takeItem(idx.row())
        
    def on_co_result_style_changed(self, ind):
        available_viz_types = [
            'Table (per year, spans indicators)',
            'Chart (per indicator, spans years)',
            'Map (per indicator per year)',
            'Chart (per indicator, spans years)',
        ]
        
        available_export_types = [
            'ESRI table (for loading in ArcGIS)'
        ]
                
        txt = self.co_result_style.currentText()
        if txt == 'visualize':
            available_types = available_viz_types
        else:
            available_types = available_export_types
            
        self.co_result_type.clear()
        for result_type in available_types:
            r_type = QString(result_type)
            self.co_result_type.addItem(r_type)
    
    def on_co_result_type_changed(self, ind):
        self.gridlayout3.removeWidget(self.le_esri_storage_location)
        self.gridlayout3.removeWidget(self.pbn_set_esri_storage_location)
        self.optionsGroupBox.hide()
        
        self.pbn_set_esri_storage_location.hide()
        self.le_esri_storage_location.hide()
        
        txt = self.co_result_type.currentText()

        print txt
        if txt == 'ESRI table (for loading in ArcGIS)':
            self.pbn_set_esri_storage_location.show()   
            self.le_esri_storage_location.show()   
            self.gridlayout3.addWidget(self.le_esri_storage_location,0,1,1,6)
            self.gridlayout3.addWidget(self.pbn_set_esri_storage_location,0,7,1,1)   
            self.optionsGroupBox.show()   
            
    def on_pbn_set_esri_storage_location_released(self):
        print 'pbn_set_esri_storage_location released'
        from opus_core.misc import directory_path_from_opus_path
        start_dir = directory_path_from_opus_path('opus_gui.projects')

        configDialog = QFileDialog()
        filter_str = QString("*.gdb")
        fd = configDialog.getExistingDirectory(self,QString("Please select an ESRI geodatabase (*.gdb)..."), #, *.sde, *.mdb)..."),
                                          QString(start_dir), QFileDialog.ShowDirsOnly)
        if len(fd) != 0:
            fileName = QString(fd)
            fileNameInfo = QFileInfo(QString(fd))
            fileNameBaseName = fileNameInfo.completeBaseName()
            self.le_esri_storage_location.setText(fileName)
            
                
    def on_pbn_go_released(self):
        # Fire up a new thread and run the model
        print 'Go button pressed'

        # References to the GUI elements for status for this run...
        #self.statusLabel = self.runStatusLabel
        #self.statusLabel.setText(QString('Model initializing...'))
        
        indicator_names = []
        for i in range(self.lw_indicators.count()):
            indicator_names.append(str(self.lw_indicators.item(i).text()))
                
        if indicator_names == []:
            print 'no indicators selected'
            return
                
        indicator_type = str(self.co_result_type.currentText())
        indicator_type = {
            #'Map (per indicator per year)':'matplotlib_map',
            'Map (per indicator per year)':'mapnik_map',
            'Chart (per indicator, spans years)':'matplotlib_chart',
            'Table (per indicator, spans years)':'table_per_attribute',
            'Table (per year, spans indicators)':'table_per_year',
            'ESRI table (for loading in ArcGIS)':'table_esri'
        }[indicator_type]
        
        kwargs = {}
        if indicator_type == 'table_esri':
            storage_location = str(self.le_esri_storage_location.text())
            if not os.path.exists(storage_location):
                print 'Warning: %s does not exist!!'%storage_location
            kwargs['storage_location'] = storage_location
        
        self.result_manager.addIndicatorForm(indicator_type = indicator_type,
                                             indicator_names = indicator_names,
                                             kwargs = kwargs)

    def runUpdateLog(self):
        self.logFileKey = self.result_generator._get_current_log(self.logFileKey)


    def runErrorFromThread(self,errorMessage):
        QMessageBox.warning(self.mainwindow, 'Warning', errorMessage)
class statisticsInfoWidget(infoWidget):
	__chart = None
	__mainLayout = None
	__statistics = None
	__projectsList = None
	__buttonsLayout = None
	__statisticGroupBox = None
	__statisticLayout = None
	__modeGroupBox = None
	__modeLayout = None
	__colors = [Qt.red, QColor(200, 160, 30), Qt.darkGreen, Qt.blue, Qt.black, Qt.darkRed, Qt.darkBlue]

	def __init__(self, client, parent = None):
		infoWidget.__init__(self, client, parent)
		self.__mainLayout = QHBoxLayout()
		self.__chart = LineChartFrame()

		self.__projectsList = QListWidget()
		self.__projectsList.setFixedWidth(200)

		self.__statisticGroupBox = QGroupBox(self.tr("Statistics type"))
		self.__statisticLayout = QVBoxLayout()
		self.__statisticGroupBox.setLayout(self.__statisticLayout)

		userTotalRadio   = QRadioButton(self.tr("User total"), self.__statisticGroupBox)
		userAverageRadio = QRadioButton(self.tr("User average"), self.__statisticGroupBox)
		hostTotalRadio   = QRadioButton(self.tr("Host total"), self.__statisticGroupBox)
		hostAverageRadio = QRadioButton(self.tr("Host average"), self.__statisticGroupBox)

		self.__statisticLayout.addWidget(userTotalRadio)
		self.__statisticLayout.addWidget(userAverageRadio)
		self.__statisticLayout.addWidget(hostTotalRadio)
		self.__statisticLayout.addWidget(hostAverageRadio)

		self.__buttonsLayout = QVBoxLayout()
		self.__buttonsLayout.addWidget(self.__projectsList)
		self.__buttonsLayout.addWidget(self.__statisticGroupBox)

		self.__mainLayout.addWidget(self.__chart)
		self.__mainLayout.addLayout(self.__buttonsLayout)
		self.setMainLayout(self.__mainLayout)

		userTotalRadio.setChecked(True)
		self.connect(userTotalRadio, SIGNAL("toggled(bool)"), self.__setUserTotalGraph)
		self.connect(userAverageRadio, SIGNAL("toggled(bool)"), self.__setUserAverageGraph)
		self.connect(hostTotalRadio, SIGNAL("toggled(bool)"), self.__setHostTotalGraph)
		self.connect(hostAverageRadio, SIGNAL("toggled(bool)"), self.__setHostAverageGraph)

		self.connect(self.__projectsList, SIGNAL("itemChanged(QListWidgetItem *)"), self.__updateStatisticsGraph)
		self.connect(client, SIGNAL("getStatisticsRecv(PyQt_PyObject)"), self.__updateStatistics)
		client.getStatistics()

	def __setUserTotalGraph(self, checked):
		if checked:
			self.__chart.setIndex(0)

	def __setUserAverageGraph(self, checked):
		if checked:
			self.__chart.setIndex(1)

	def __setHostTotalGraph(self, checked):
		if checked:
			self.__chart.setIndex(2)

	def __setHostAverageGraph(self, checked):
		if checked:
			self.__chart.setIndex(3)

	def __updateStatistics(self, statistics):
		self.disconnect(self.sender(), SIGNAL("getStatisticsRecv(PyQt_PyObject)"), self.__updateStatistics)
		self.__statistics = statistics
		self.__addListItems()
		self.__updateStatisticsGraph()

	def __addListItems(self):
		i = 0
		for key in self.__statistics.keys():
			name = self.sender().getProjectName(key)
			if name is None:
				name = key
			color = self.__colors[i]

			item = QListWidgetItem(name)
			item.setData(Qt.DecorationRole, QVariant(QColor(color)))
			item.setData(Qt.UserRole, QVariant(key))
			item.setFlags(Qt.ItemIsSelectable|Qt.ItemIsUserCheckable|Qt.ItemIsEnabled)
			item.setCheckState(Qt.Checked)
			self.__projectsList.addItem(item)

			i = i + 1
			if i >= len(self.__colors):
				i = 0

	def __updateStatisticsGraph(self):
		self.__chart.removeGraphs()
		for i in range(self.__projectsList.count()):
			item = self.__projectsList.item(i)
			color = item.data(Qt.DecorationRole)
			name = str(item.data(Qt.DisplayRole).toString())
			key = str(item.data(Qt.UserRole).toString())
			if item.checkState() == Qt.Checked:
				self.__chart.addGraph(self.__statistics[key], name, color)
Exemple #16
0
class GroupSelectParameterWidget(GenericParameterWidget):
    """Widget class for Group Select Parameter."""
    def __init__(self, parameter, parent=None):
        """Constructor.

        :param parameter: A GroupSelectParameter object.
        :type parameter: GroupSelectParameter
        """
        QWidget.__init__(self, parent)
        self._parameter = parameter

        # Store spin box
        self.spin_boxes = {}

        # Create elements
        # Label (name)
        self.label = QLabel(self._parameter.name)

        # Layouts
        self.main_layout = QVBoxLayout()
        self.input_layout = QVBoxLayout()

        # _inner_input_layout must be filled with widget in the child class
        self.inner_input_layout = QVBoxLayout()

        self.radio_button_layout = QGridLayout()

        # Create radio button group
        self.input_button_group = QButtonGroup()

        # List widget
        self.list_widget = QListWidget()
        self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.list_widget.setDragDropMode(QAbstractItemView.DragDrop)
        self.list_widget.setDefaultDropAction(Qt.MoveAction)
        self.list_widget.setEnabled(False)
        self.list_widget.setSizePolicy(QSizePolicy.Maximum,
                                       QSizePolicy.Expanding)

        for i, key in enumerate(self._parameter.options):
            value = self._parameter.options[key]
            radio_button = QRadioButton(value.get('label'))
            self.radio_button_layout.addWidget(radio_button, i, 0)
            if value.get('type') == SINGLE_DYNAMIC:
                double_spin_box = QDoubleSpinBox()
                self.radio_button_layout.addWidget(double_spin_box, i, 1)
                double_spin_box.setValue(value.get('value', 0))
                double_spin_box.setMinimum(
                    value.get('constraint', {}).get('min', 0))
                double_spin_box.setMaximum(
                    value.get('constraint', {}).get('max', 1))
                double_spin_box.setSingleStep(
                    value.get('constraint', {}).get('step', 0.01))
                step = double_spin_box.singleStep()
                if step > 1:
                    precision = 0
                else:
                    precision = len(str(step).split('.')[1])
                    if precision > 3:
                        precision = 3
                double_spin_box.setDecimals(precision)
                self.spin_boxes[key] = double_spin_box

                # Enable spin box depends on the selected option
                if self._parameter.selected == key:
                    double_spin_box.setEnabled(True)
                else:
                    double_spin_box.setEnabled(False)

            elif value.get('type') == STATIC:
                static_value = value.get('value', 0)
                if static_value is not None:
                    self.radio_button_layout.addWidget(
                        QLabel(str(static_value)), i, 1)
            elif value.get('type') == MULTIPLE_DYNAMIC:
                selected_fields = value.get('value', [])
                if self._parameter.selected == key:
                    self.list_widget.setEnabled(True)
                else:
                    self.list_widget.setEnabled(False)

            self.input_button_group.addButton(radio_button, i)
            if self._parameter.selected == key:
                radio_button.setChecked(True)

        # Help text
        self.help_label = QLabel(self._parameter.help_text)
        self.help_label.setSizePolicy(QSizePolicy.Maximum,
                                      QSizePolicy.Expanding)
        self.help_label.setWordWrap(True)
        self.help_label.setAlignment(Qt.AlignTop)

        self.inner_input_layout.addLayout(self.radio_button_layout)
        self.inner_input_layout.addWidget(self.list_widget)

        # Put elements into layouts
        self.input_layout.addWidget(self.label)
        self.input_layout.addLayout(self.inner_input_layout)

        self.help_layout = QVBoxLayout()
        self.help_layout.addWidget(self.help_label)

        self.main_layout.addLayout(self.input_layout)
        self.main_layout.addLayout(self.help_layout)

        self.setLayout(self.main_layout)

        self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding)

        # Update list widget
        self.update_list_widget()

        # Connect signal
        self.input_button_group.buttonClicked.connect(
            self.radio_buttons_clicked)

    def get_parameter(self):
        """Obtain list parameter object from the current widget state.

        :returns: A DefaultValueParameter from the current state of widget
        :rtype: DefaultValueParameter
        """
        # Set value for each key
        for key, value in self._parameter.options.items():
            if value.get('type') == STATIC:
                continue
            elif value.get('type') == SINGLE_DYNAMIC:
                new_value = self.spin_boxes.get(key).value()
                self._parameter.set_value_for_key(key, new_value)
            elif value.get('type') == MULTIPLE_DYNAMIC:
                # Need to iterate through all items
                items = []
                for index in xrange(self.list_widget.count()):
                    items.append(self.list_widget.item(index))
                new_value = [i.text() for i in items]
                self._parameter.set_value_for_key(key, new_value)

        # Get selected radio button
        radio_button_checked_id = self.input_button_group.checkedId()
        # No radio button checked, then default value = None
        if radio_button_checked_id == -1:
            self._parameter.selected = None
        else:
            self._parameter.selected = self._parameter.options.keys(
            )[radio_button_checked_id]

        return self._parameter

    def update_list_widget(self):
        """Update list widget when radio button is clicked."""
        # Get selected radio button
        radio_button_checked_id = self.input_button_group.checkedId()
        # No radio button checked, then default value = None
        if radio_button_checked_id > -1:
            selected_dict = self._parameter.options.values(
            )[radio_button_checked_id]
            if selected_dict.get('type') == MULTIPLE_DYNAMIC:
                for field in selected_dict.get('value'):
                    # Update list widget
                    field_item = QListWidgetItem(self.list_widget)
                    field_item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable
                                        | Qt.ItemIsDragEnabled)
                    field_item.setData(Qt.UserRole, field)
                    field_item.setText(field)
                    self.list_widget.addItem(field_item)

    def radio_buttons_clicked(self):
        """Handler when selected radio button changed."""
        # Disable all spin boxes
        for spin_box in self.spin_boxes.values():
            spin_box.setEnabled(False)
        # Disable list widget
        self.list_widget.setEnabled(False)

        # Get selected radio button
        radio_button_checked_id = self.input_button_group.checkedId()

        if radio_button_checked_id > -1:
            selected_value = self._parameter.options.values(
            )[radio_button_checked_id]
            if selected_value.get('type') == MULTIPLE_DYNAMIC:
                # Enable list widget
                self.list_widget.setEnabled(True)
            elif selected_value.get('type') == SINGLE_DYNAMIC:
                selected_key = self._parameter.options.keys(
                )[radio_button_checked_id]
                self.spin_boxes[selected_key].setEnabled(True)

    def select_radio_button(self, key):
        """Helper to select a radio button with key.

        :param key: The key of the radio button.
        :type key: str
        """
        key_index = self._parameter.options.keys().index(key)
        radio_button = self.input_button_group.button(key_index)
        radio_button.click()
class StringListDlg(QDialog):

    acceptedList = Signal(QStringList)

    def __init__(self, name, stringlist=None, parent=None):
        super(StringListDlg, self).__init__(parent)
        self.name = name
        self.create_widgets(stringlist)
        self.layout_widgets()
        self.setWindowTitle("Edit {0} List".format(self.name))


    def create_widgets(self, stringlist):
        self.listWidget = QListWidget()
        if stringlist is not None:
            self.listWidget.addItems(stringlist)
            self.listWidget.setCurrentRow(0)


    def layout_widgets(self):
        buttonLayout = QVBoxLayout()
        for text, slot in (("&Add...", self.add),
                           ("&Edit...", self.edit),
                           ("&Remove...", self.remove),
                           ("&Up", self.up),
                           ("&Down", self.down),
                           ("&Sort", self.listWidget.sortItems),
                           ("Close", self.accept)):
            button = QPushButton(text)
            if not MAC:
                button.setFocusPolicy(Qt.NoFocus)
            if text == "Close":
                buttonLayout.addStretch()
            buttonLayout.addWidget(button)
            button.clicked.connect(slot)
        layout = QHBoxLayout()
        layout.addWidget(self.listWidget)
        layout.addLayout(buttonLayout)
        self.setLayout(layout)


    def add(self):
        row = self.listWidget.currentRow()
        title = "Add {0}".format(self.name)
        string, ok = QInputDialog.getText(self, title, title)
        if ok and not string.isEmpty():
            self.listWidget.insertItem(row, string)


    def edit(self):
        row = self.listWidget.currentRow()
        item = self.listWidget.item(row)
        if item is not None:
            title = "Edit {0}".format(self.name)
            string, ok = QInputDialog.getText(self, title, title,
                    QLineEdit.Normal, item.text())
            if ok and not string.isEmpty():
                item.setText(string)


    def remove(self):
        row = self.listWidget.currentRow()
        item = self.listWidget.item(row)
        if item is None:
            return
        reply = QMessageBox.question(self, "Remove {0}".format(
                self.name), "Remove {0} `{1}'?".format(
                self.name, unicode(item.text())),
                QMessageBox.Yes|QMessageBox.No)
        if reply == QMessageBox.Yes:
            item = self.listWidget.takeItem(row)
            del item


    def up(self):
        row = self.listWidget.currentRow()
        if row >= 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(row - 1, item)
            self.listWidget.setCurrentItem(item)


    def down(self):
        row = self.listWidget.currentRow()
        if row < self.listWidget.count() - 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(row + 1, item)
            self.listWidget.setCurrentItem(item)


    def reject(self):
        self.accept()


    def accept(self):
        self.stringlist = QStringList()
        for row in range(self.listWidget.count()):
            self.stringlist.append(self.listWidget.item(row).text())
        self.acceptedList.emit(self.stringlist)
        QDialog.accept(self)
Exemple #18
0
class GitStatus(QDialog):
    def __init__(self, plugin, git, path):
        QDialog.__init__(self)
        self.git = git
        self.plugin = plugin
        self.setWindowTitle('Git status')

        layout = QGridLayout(self)

        branches = self.git.branch(unicode(path))

        self.s_branches = QListWidget()

        if len(branches) > 0:
            self.s_branches.addItems(branches[1:])
            self.actual_branch = QLabel("<h2>{0}</h2>".format(branches[0]))
        else:
            self.actual_branch = QLabel()

        branch = QLabel("<h2>Branches</h2>")
        change_branch = QPushButton("Change to")
        merge_branches = QPushButton("Merge branch")

        H = QHBoxLayout()
        delete_branch = QPushButton("Delete branch")
        add_branch = QPushButton("Add branch")
        H.addWidget(add_branch)
        H.addWidget(delete_branch)

        self.lists = []

        no_staged = QLabel("<h2>No staged</h2>")

        untracked_files = QLabel("Untracked files")
        self.untracked_files = QListWidget()
        self.lists.append(self.untracked_files)

        modified_files = QLabel("Modified files")
        self.modified_files = QListWidget()
        self.lists.append(self.modified_files)

        deleted_files = QLabel("Deleted files")
        self.deleted_files = QListWidget()
        self.lists.append(self.deleted_files)

        staged = QLabel("<h2>Staged</h2>")

        added_files = QLabel("Added files")
        self.added_files = QListWidget()
        self.lists.append(self.added_files)

        s_modified_files = QLabel("Modified files")
        self.s_modified_files = QListWidget()
        self.lists.append(self.s_modified_files)

        s_deleted_files = QLabel("Deleted files")
        self.s_deleted_files = QListWidget()
        self.lists.append(self.s_deleted_files)

        layout.addWidget(self.actual_branch, 0, 0, Qt.AlignHCenter)
        layout.addWidget(change_branch, 1, 0)
        layout.addWidget(merge_branches, 2, 0)
        layout.addWidget(no_staged, 3, 0)
        layout.addWidget(untracked_files, 4, 0)
        layout.addWidget(self.untracked_files, 5, 0)
        layout.addWidget(modified_files, 6, 0)
        layout.addWidget(self.modified_files, 7, 0)
        layout.addWidget(deleted_files, 8, 0)
        layout.addWidget(self.deleted_files, 9, 0)

        layout.addWidget(branch, 0, 1)
        layout.addWidget(self.s_branches, 1, 1)
        layout.addLayout(H, 2, 1)
        layout.addWidget(staged, 3, 1)
        layout.addWidget(added_files, 4, 1)
        layout.addWidget(self.added_files, 5, 1)
        layout.addWidget(s_modified_files, 6, 1)
        layout.addWidget(self.s_modified_files, 7, 1)
        layout.addWidget(s_deleted_files, 8, 1)
        layout.addWidget(self.s_deleted_files, 9, 1)

        self.fill(self.git.no_staged["?"], self.untracked_files)
        self.fill(self.git.no_staged["M"], self.modified_files)
        self.fill(self.git.no_staged["D"], self.deleted_files)

        self.fill(self.git.staged["A"], self.added_files)
        self.fill(self.git.staged["M"], self.s_modified_files)
        self.fill(self.git.staged["D"], self.s_deleted_files)

        self.staged_b = QPushButton('Stage files', self)
        self.unstage_b = QPushButton("Unstage files", self)
        self.commit_b = QPushButton('Commit files', self)
        self.uncommit_b = QPushButton("Uncommit files", self)

        layout.addWidget(self.staged_b, 10, 0)
        layout.addWidget(self.unstage_b, 11, 0)
        layout.addWidget(self.commit_b, 10, 1)
        layout.addWidget(self.uncommit_b, 11, 1)

        self.setLayout(layout)

        self.connect(self.staged_b, SIGNAL('clicked()'), self.add)
        self.connect(self.unstage_b, SIGNAL('clicked()'), self.unstage)
        self.connect(self.commit_b, SIGNAL('clicked()'), self.commit)
        self.connect(self.uncommit_b, SIGNAL('clicked()'), self.uncommit)
        self.connect(change_branch, SIGNAL("clicked()"), self.change_branch)
        self.connect(add_branch, SIGNAL("clicked()"), self.add_branch)
        self.connect(delete_branch, SIGNAL("clicked()"), self.delete_branch)
        self.connect(merge_branches, SIGNAL("clicked()"), self.merge_branches)

    def fill(self, a_list, widget_list):
        for x in a_list:

            item = QListWidgetItem()
            widget_list.addItem(item)
            check_box = QCheckBox(x)
            widget_list.setItemWidget(item, check_box)

    def add(self):
        path = self.plugin.editor.get_project_owner()
        for pos in reversed(xrange(self.untracked_files.count())):

            item = self.untracked_files.item(pos)
            widget = self.untracked_files.itemWidget(item)
            text = widget.text()

            if widget.isChecked():
                self.git.add(path, text)
                self.untracked_files.removeItemWidget(item)
                self.untracked_files.takeItem(pos)
                item = QListWidgetItem()
                self.added_files.addItem(item)
                check_box = QCheckBox(text)
                self.added_files.setItemWidget(item, check_box)

        for pos in reversed(xrange(self.modified_files.count())):

            item = self.modified_files.item(pos)
            widget = self.modified_files.itemWidget(item)
            text = widget.text()

            if widget.isChecked():
                self.git.add(path, widget.text())
                self.modified_files.removeItemWidget(item)
                self.modified_files.takeItem(pos)
                item = QListWidgetItem()
                self.s_modified_files.addItem(item)
                check_box = QCheckBox(text)
                self.s_modified_files.setItemWidget(item, check_box)

        for pos in reversed(xrange(self.deleted_files.count())):

            item = self.deleted_files.item(pos)
            widget = self.deleted_files.itemWidget(item)
            text = widget.text()

            if widget.isChecked():
                self.git.add(path, widget.text())
                self.deleted_files.removeItemWidget(item)
                self.deleted_files.takeItem(pos)
                item = QListWidgetItem()
                self.s_deleted_files.addItem(item)
                check_box = QCheckBox(text)
                self.s_deleted_files.setItemWidget(item, check_box)

    def unstage(self):

        path = self.plugin.editor.get_project_owner()
        for pos in reversed(xrange(self.untracked_files.count())):

            item = self.untracked_files.item(pos)
            widget = self.untracked_files.itemWidget(item)

            if widget.isChecked():
                self.git.unstage(path, widget.text())
                self.untracked_files.removeItemWidget(item)
                self.untracked_files.takeItem(pos)

        for pos in reversed(xrange(self.modified_files.count())):

            item = self.modified_files.item(pos)
            widget = self.modified_files.itemWidget(item)

            if widget.isChecked():
                self.git.unstage(path, widget.text())
                self.modified_files.removeItemWidget(item)
                self.modified_files.takeItem(pos)

        for pos in reversed(xrange(self.deleted_files.count())):

            item = self.deleted_files.item(pos)
            widget = self.deleted_files.itemWidget(item)

            if widget.isChecked():
                self.git.unstage(path, widget.text())
                self.deleted_files.removeItemWidget(item)
                self.deleted_files.takeItem(pos)

    def commit(self):

        msg = QInputDialog.getText(self, "Commit message", "Commit Message:")

        if msg[1] == False:
            return (0)

        path = self.plugin.editor.get_project_owner()
        for pos in reversed(xrange(self.added_files.count())):

            item = self.added_files.item(pos)
            widget = self.added_files.itemWidget(item)

            if widget.isChecked():
                self.git.commit(path, str(widget.text()), msg[0])
                self.added_files.removeItemWidget(item)
                self.added_files.takeItem(pos)

        for pos in reversed(xrange(self.s_modified_files.count())):

            item = self.s_modified_files.item(pos)
            widget = self.s_modified_files.itemWidget(item)

            if widget.isChecked():
                self.git.commit(path, widget.text(), msg[0])
                self.s_modified_files.removeItemWidget(item)
                self.s_modified_files.takeItem(pos)

        for pos in reversed(xrange(self.s_deleted_files.count())):

            item = self.s_deleted_files.item(pos)
            widget = self.s_deleted_files.itemWidget(item)

            if widget.isChecked():
                self.git.commit(path, widget.text(), msg[0])
                self.s_deleted_files.takeItem(pos)
                self.s_deleted_files.removeItemWidget(item)

    def uncommit(self):
        path = self.plugin.editor.get_project_owner()
        for pos in reversed(xrange(self.added_files.count())):

            item = self.added_files.item(pos)
            widget = self.added_files.itemWidget(item)
            text = widget.text()

            if widget.isChecked():
                self.git.uncommit(path, str(widget.text()))
                self.added_files.removeItemWidget(item)
                self.added_files.takeItem(pos)
                item = QListWidgetItem()
                self.untracked_files.addItem(item)
                check_box = QCheckBox(text)
                self.untracked_files.setItemWidget(item, check_box)

        for pos in reversed(xrange(self.s_modified_files.count())):

            item = self.s_modified_files.item(pos)
            widget = self.s_modified_files.itemWidget(item)
            text = widget.text()

            if widget.isChecked():
                self.git.uncommit(path, widget.text())
                self.s_modified_files.removeItemWidget(item)
                self.s_modified_files.takeItem(pos)
                item = QListWidgetItem()
                self.modified_files.addItem(item)
                check_box = QCheckBox(text)
                self.modified_files.setItemWidget(item, check_box)

        for pos in reversed(xrange(self.s_deleted_files.count())):

            item = self.s_deleted_files.item(pos)
            widget = self.s_deleted_files.itemWidget(item)
            text = widget.text()

            if widget.isChecked():
                self.git.uncommit(path, widget.text())
                self.s_deleted_files.removeItemWidget(item)
                self.s_deleted_files.takeItem(pos)
                item = QListWidgetItem()
                self.deleted_files.addItem(item)
                check_box = QCheckBox(text)
                self.deleted_files.setItemWidget(item, check_box)

    def change_branch(self):

        path = self.plugin.editor.get_project_owner()

        item = self.s_branches.currentItem()

        if item and not self.something():
            text = item.text()
            self.git.change_branch(path, text)
            self.s_branches.clear()
            self.s_branches.addItems(self.git.branch(unicode(path))[1:])
            self.actual_branch.setText("<h2>{0}<h2>".format(text))
        if self.something():
            v = QMessageBox()
            v.setText("Error: you have unsaved changes")
            v.setIcon(v.Warning)
            v.exec_()

    def add_branch(self):

        path = self.plugin.editor.get_project_owner()

        msg = QInputDialog.getText(self, "New branch", "Branch Name:")

        if msg[1] == False:
            return (0)

        self.git.add_branch(path, msg[0])
        self.s_branches.clear()
        self.s_branches.addItems(self.git.branch(unicode(path))[1:])

    def delete_branch(self):
        path = self.plugin.editor.get_project_owner()
        item = self.s_branches.currentItem()
        if item:
            text = str(item.text())
            call = self.git.delete_branch(path, text)

            if not call:
                self.s_branches.clear()
                self.s_branches.addItems(self.git.branch(unicode(path))[1:])

            else:
                m = QMessageBox()
                m.setText("<h2>" + call + "</h2>")
                m.setInformativeText("Force deletion?")
                m.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
                m.setDefaultButton(QMessageBox.Cancel)
                c = m.exec_()
                if c == QMessageBox.Ok:

                    self.git.force_delete_branch(path, text)
                    self.s_branches.clear()

                    self.s_branches.addItems(
                        self.git.branch(unicode(path))[1:])

    def merge_branches(self):
        path = self.plugin.editor.get_project_owner()
        item = self.s_branches.currentItem()
        if item:
            text = str(item.text())
            call = self.git.merge_branches(path, text)
            if call:
                m = QMessageBox()
                m.setText(call)
                m.setInformativeText("Unknown")
                m.setIcon(m.Critical)
                m.exec_()

    def something(self):
        for x in self.lists:
            if x.count() > 0:
                return True
        return False
Exemple #19
0
class ConfigDialog(QDialog):
    """Spyder configuration ('Preferences') dialog box"""
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)
        
        # Destroying the C++ object right after closing the dialog box,
        # otherwise it may be garbage-collected in another QThread
        # (e.g. the editor's analysis thread in Spyder), thus leading to
        # a segmentation fault on UNIX or an application crash on Windows
        self.setAttribute(Qt.WA_DeleteOnClose)

        self.contents_widget = QListWidget()
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setSpacing(1)

        bbox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Apply
                                |QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
        self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"),
                     self.button_clicked)

        self.pages_widget = QStackedWidget()
        self.connect(self.pages_widget, SIGNAL("currentChanged(int)"),
                     self.current_page_changed)

        self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"),
                     self.pages_widget.setCurrentIndex)
        self.contents_widget.setCurrentRow(0)

        hsplitter = QSplitter()
        hsplitter.addWidget(self.contents_widget)
        hsplitter.addWidget(self.pages_widget)

        btnlayout = QHBoxLayout()
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addWidget(hsplitter)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        self.setWindowTitle(_("Preferences"))
        self.setWindowIcon(get_icon("configure.png"))
        
    def get_current_index(self):
        """Return current page index"""
        return self.contents_widget.currentRow()
        
    def set_current_index(self, index):
        """Set current page index"""
        self.contents_widget.setCurrentRow(index)
        
    def get_page(self, index=None):
        """Return page widget"""
        if index is None:
            widget = self.pages_widget.currentWidget()
        else:
            widget = self.pages_widget.widget(index)
        return widget.widget()
        
    def accept(self):
        """Reimplement Qt method"""
        for index in range(self.pages_widget.count()):
            configpage = self.get_page(index)
            if not configpage.is_valid():
                return
            configpage.apply_changes()
        QDialog.accept(self)
        
    def button_clicked(self, button):
        if button is self.apply_btn:
            # Apply button was clicked
            configpage = self.get_page()
            if not configpage.is_valid():
                return
            configpage.apply_changes()
            
    def current_page_changed(self, index):
        widget = self.get_page(index)
        self.apply_btn.setVisible(widget.apply_callback is not None)
        self.apply_btn.setEnabled(widget.is_modified)
        
    def add_page(self, widget):
        self.connect(self, SIGNAL('check_settings()'), widget.check_settings)
        self.connect(widget, SIGNAL('show_this_page()'),
                     lambda row=self.contents_widget.count():
                     self.contents_widget.setCurrentRow(row))
        self.connect(widget, SIGNAL("apply_button_enabled(bool)"),
                     self.apply_btn.setEnabled)
        scrollarea = QScrollArea(self)
        scrollarea.setWidgetResizable(True)
        scrollarea.setWidget(widget)
        self.pages_widget.addWidget(scrollarea)
        item = QListWidgetItem(self.contents_widget)
        item.setIcon(widget.get_icon())
        item.setText(widget.get_name())
        item.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)
        item.setSizeHint(QSize(0, 25))
        
    def check_all_settings(self):
        """This method is called to check all configuration page settings
        after configuration dialog has been shown"""
        self.emit(SIGNAL('check_settings()'))
    
    def resizeEvent(self, event):
        """
        Reimplement Qt method to be able to save the widget's size from the
        main application
        """
        QDialog.resizeEvent(self, event)
        self.emit(SIGNAL("size_change(QSize)"), self.size())
Exemple #20
0
class ListEdit(QWidget):
    """A widget to edit a list of items (e.g. a list of directories)."""
    
    # emitted when anything changed in the listbox.
    changed = pyqtSignal()
    
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        layout = QGridLayout(self)
        self.setLayout(layout)
        
        self.addButton = QPushButton(icons.get('list-add'), '')
        self.editButton = QPushButton(icons.get('document-edit'), '')
        self.removeButton = QPushButton(icons.get('list-remove'), '')
        self.listBox = QListWidget()
        
        layout.setContentsMargins(1, 1, 1, 1)
        layout.setSpacing(0)
        layout.addWidget(self.listBox, 0, 0, 8, 1)
        layout.addWidget(self.addButton, 0, 1)
        layout.addWidget(self.editButton, 1, 1)
        layout.addWidget(self.removeButton, 2, 1)
        
        @self.addButton.clicked.connect
        def addClicked():
            item = self.createItem()
            if self.openEditor(item):
                self.addItem(item)
                
        @self.editButton.clicked.connect
        def editClicked():
            item = self.listBox.currentItem()
            item and self.editItem(item)
        
        @self.removeButton.clicked.connect
        def removeClicked():
            item = self.listBox.currentItem()
            if item:
                self.removeItem(item)
        
        @self.listBox.itemDoubleClicked.connect
        def itemDoubleClicked(item):
            item and self.editItem(item)
            
        self.listBox.model().layoutChanged.connect(self.changed)
    
        def updateSelection():
            selected = bool(self.listBox.currentItem())
            self.editButton.setEnabled(selected)
            self.removeButton.setEnabled(selected)
        
        self.changed.connect(updateSelection)
        self.listBox.itemSelectionChanged.connect(updateSelection)
        updateSelection()
        app.translateUI(self)
    
    def translateUI(self):
        self.addButton.setText(_("&Add..."))
        self.editButton.setText(_("&Edit..."))
        self.removeButton.setText(_("&Remove"))
    
    def createItem(self):
        return QListWidgetItem()
        
    def addItem(self, item):
        self.listBox.addItem(item)
        self.itemChanged(item)
        self.changed.emit()
        
    def removeItem(self, item):
        self.listBox.takeItem(self.listBox.row(item))
        self.changed.emit()
        
    def editItem(self, item):
        if self.openEditor(item):
            self.itemChanged(item)
            self.changed.emit()
            
    def setCurrentItem(self, item):
        self.listBox.setCurrentItem(item)
        
    def setCurrentRow(self, row):
        self.listBox.setCurrentRow(row)
        
    def openEditor(self, item):
        """Opens an editor (dialog) for the item.
        
        Returns True if the dialog was accepted and the item edited.
        Returns False if the dialog was cancelled (the item must be left
        unedited).
        """
        pass
    
    def itemChanged(self, item):
        """Called after an item has been added or edited.
        
        Re-implement to do something at this moment if needed, e.g. alter the
        text or display of other items.
        """
        pass
    
    def setValue(self, strings):
        """Sets the listbox to a list of strings."""
        self.listBox.clear()
        self.listBox.addItems(strings)
        self.changed.emit()
        
    def value(self):
        """Returns the list of paths in the listbox."""
        return [self.listBox.item(i).text()
            for i in range(self.listBox.count())]
    
    def setItems(self, items):
        """Sets the listbox to a list of items."""
        self.listBox.clear()
        for item in items:
            self.listBox.addItem(item)
            self.itemChanged(item)
        self.changed.emit()
    
    def items(self):
        """Returns the list of items in the listbox."""
        return [self.listBox.item(i)
            for i in range(self.listBox.count())]
        
    def clear(self):
        """Clears the listbox."""
        self.listBox.clear()
        self.changed.emit()
Exemple #21
0
class CheckList(HelpedWidget):
    
    def __init__(self, model, label="", help_link=""):
        HelpedWidget.__init__(self, "", help_link)

        layout = QVBoxLayout()

        widget = QWidget()
        widget.setLayout(layout)

        self.checkAllButton = QToolButton()
        self.checkAllButton.setIcon(resourceIcon("checked"))
        self.checkAllButton.setIconSize(QSize(16, 16))
        self.checkAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.checkAllButton.setAutoRaise(True)
        self.checkAllButton.setToolTip("Select all")

        self.uncheckAllButton = QToolButton()
        self.uncheckAllButton.setIcon(resourceIcon("notchecked"))
        self.uncheckAllButton.setIconSize(QSize(16, 16))
        self.uncheckAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.uncheckAllButton.setAutoRaise(True)
        self.uncheckAllButton.setToolTip("Unselect all")

        self.list = QListWidget()
        self.list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.list.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.search_box = SearchBox()

        check_button_layout = QHBoxLayout()

        check_button_layout.setMargin(0)
        check_button_layout.setSpacing(0)
        check_button_layout.addWidget(QLabel(label))
        check_button_layout.addStretch(1)
        check_button_layout.addWidget(self.checkAllButton)
        check_button_layout.addWidget(self.uncheckAllButton)

        layout.addLayout(check_button_layout)
        layout.addWidget(self.list)
        layout.addWidget(self.search_box)

        self.addWidget(widget)

        self.connect(self.checkAllButton, SIGNAL('clicked()'), self.checkAll)
        self.connect(self.uncheckAllButton, SIGNAL('clicked()'), self.uncheckAll)
        self.connect(self.list, SIGNAL('itemChanged(QListWidgetItem*)'), self.itemChanged)
        self.search_box.filterChanged.connect(self.filterList)
        # self.connect(self.search_box, SIGNAL('filterChanged(str)'), self.filterList)

        self.connect(self.list, SIGNAL('customContextMenuRequested(QPoint)'), self.showContextMenu)

        assert isinstance(model, (SelectableModelMixin, ListModelMixin))
        self.model = model
        self.model.observable().attach(SelectableModelMixin.SELECTION_CHANGED_EVENT, self.modelChanged)
        self.model.observable().attach(ListModelMixin.LIST_CHANGED_EVENT, self.modelChanged)
        self.modelChanged()

    def itemChanged(self, item):
        """@type item: QListWidgetItem"""
        if item.checkState() == Qt.Checked:
            self.model.selectValue(str(item.text()))
        elif item.checkState() == Qt.Unchecked:
            self.model.unselectValue(str(item.text()))
        else:
            raise AssertionError("Unhandled checkstate!")

    def modelChanged(self):
        self.list.clear()

        items = self.model.getList()

        for item in items:
            list_item = QListWidgetItem(item)
            list_item.setFlags(list_item.flags() | Qt.ItemIsUserCheckable)

            if self.model.isValueSelected(item):
                list_item.setCheckState(Qt.Checked)
            else:
                list_item.setCheckState(Qt.Unchecked)

            self.list.addItem(list_item)

        self.filterList(self.search_box.filter())

    def setSelectionEnabled(self, enabled):
        self.setEnabled(enabled)
        self.checkAllButton.setEnabled(enabled)
        self.uncheckAllButton.setEnabled(enabled)

    def filterList(self, filter):
        filter = filter.lower()

        for index in range(0, self.list.count()):
            item = self.list.item(index)
            text = str(item.text()).lower()

            if filter == "":
                item.setHidden(False)
            elif filter in text:
                item.setHidden(False)
            else:
                item.setHidden(True)


    def checkAll(self):
        self.model.selectAll()

    def uncheckAll(self):
        self.model.unselectAll()

    def checkSelected(self):
        items = []
        for item in self.list.selectedItems():
            items.append(str(item.text()))

        for item in items:
            self.model.selectValue(item)

    def uncheckSelected(self):
        items = []
        for item in self.list.selectedItems():
            items.append(str(item.text()))

        for item in items:
            self.model.unselectValue(item)

    def showContextMenu(self, point):
        p = self.list.mapToGlobal(point)
        menu = QMenu()
        check_selected = menu.addAction("Check selected")
        uncheck_selected = menu.addAction("Uncheck selected")
        menu.addSeparator()
        clear_selection = menu.addAction("Clear selection")

        selected_item = menu.exec_(p)

        if selected_item == check_selected:
            self.checkSelected()
        elif selected_item == uncheck_selected:
            self.uncheckSelected()
        elif selected_item == clear_selection:
            self.list.clearSelection()
Exemple #22
0
class CheckList(QWidget):
    def __init__(self,
                 model,
                 label="",
                 help_link="",
                 custom_filter_button=None):
        """
        :param custom_filter_button:  if needed, add a button that opens a custom filter menu. Useful when search alone
        isn't enough to filter the list.
        :type custom_filter_button: QToolButton
        """
        QWidget.__init__(self)

        self._model = model

        if help_link != "":
            addHelpToWidget(self, help_link)

        layout = QVBoxLayout()

        self._createCheckButtons()

        self._list = QListWidget()
        self._list.setContextMenuPolicy(Qt.CustomContextMenu)
        self._list.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self._search_box = SearchBox()

        check_button_layout = QHBoxLayout()

        check_button_layout.setMargin(0)
        check_button_layout.setSpacing(0)
        check_button_layout.addWidget(QLabel(label))
        check_button_layout.addStretch(1)
        check_button_layout.addWidget(self._checkAllButton)
        check_button_layout.addWidget(self._uncheckAllButton)

        layout.addLayout(check_button_layout)
        layout.addWidget(self._list)
        """
        Inserts the custom filter button, if provided. The caller is responsible for all related actions.
        """
        if custom_filter_button is not None:
            search_bar_layout = QHBoxLayout()
            search_bar_layout.addWidget(self._search_box)
            search_bar_layout.addWidget(custom_filter_button)
            layout.addLayout(search_bar_layout)
        else:
            layout.addWidget(self._search_box)

        self.setLayout(layout)

        self._checkAllButton.clicked.connect(self.checkAll)
        self._uncheckAllButton.clicked.connect(self.uncheckAll)
        self._list.itemChanged.connect(self.itemChanged)
        self._search_box.filterChanged.connect(self.filterList)
        self._list.customContextMenuRequested.connect(self.showContextMenu)

        self._model.selectionChanged.connect(self.modelChanged)
        self._model.modelChanged.connect(self.modelChanged)

        self.modelChanged()

    def _createCheckButtons(self):
        self._checkAllButton = QToolButton()
        self._checkAllButton.setIcon(resourceIcon("checked"))
        self._checkAllButton.setIconSize(QSize(16, 16))
        self._checkAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self._checkAllButton.setAutoRaise(True)
        self._checkAllButton.setToolTip("Select all")
        self._uncheckAllButton = QToolButton()
        self._uncheckAllButton.setIcon(resourceIcon("notchecked"))
        self._uncheckAllButton.setIconSize(QSize(16, 16))
        self._uncheckAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self._uncheckAllButton.setAutoRaise(True)
        self._uncheckAllButton.setToolTip("Unselect all")

    def itemChanged(self, item):
        """@type item: QListWidgetItem"""
        if item.checkState() == Qt.Checked:
            self._model.selectValue(str(item.text()))
        elif item.checkState() == Qt.Unchecked:
            self._model.unselectValue(str(item.text()))
        else:
            raise AssertionError("Unhandled checkstate!")

    def modelChanged(self):
        self._list.clear()

        items = self._model.getList()

        for item in items:
            list_item = QListWidgetItem(item)
            list_item.setFlags(list_item.flags() | Qt.ItemIsUserCheckable)

            if self._model.isValueSelected(item):
                list_item.setCheckState(Qt.Checked)
            else:
                list_item.setCheckState(Qt.Unchecked)

            self._list.addItem(list_item)

        self.filterList(self._search_box.filter())

    def setSelectionEnabled(self, enabled):
        self.setEnabled(enabled)
        self._checkAllButton.setEnabled(enabled)
        self._uncheckAllButton.setEnabled(enabled)

    def filterList(self, filter):
        filter = filter.lower()

        for index in range(0, self._list.count()):
            item = self._list.item(index)
            text = str(item.text()).lower()

            if filter == "":
                item.setHidden(False)
            elif filter in text:
                item.setHidden(False)
            else:
                item.setHidden(True)

    def checkAll(self):
        """
        Checks all visible items in the list.
        """
        for index in range(0, self._list.count()):
            item = self._list.item(index)
            if not item.isHidden():
                self._model.selectValue(str(item.text()))

    def uncheckAll(self):
        """
        Unchecks all items in the list, visible or not
        """
        self._model.unselectAll()

    def checkSelected(self):
        items = []
        for item in self._list.selectedItems():
            items.append(str(item.text()))

        for item in items:
            self._model.selectValue(item)

    def uncheckSelected(self):
        items = []
        for item in self._list.selectedItems():
            items.append(str(item.text()))

        for item in items:
            self._model.unselectValue(item)

    def showContextMenu(self, point):
        p = self._list.mapToGlobal(point)
        menu = QMenu()
        check_selected = menu.addAction("Check selected")
        uncheck_selected = menu.addAction("Uncheck selected")
        menu.addSeparator()
        clear_selection = menu.addAction("Clear selection")

        selected_item = menu.exec_(p)

        if selected_item == check_selected:
            self.checkSelected()
        elif selected_item == uncheck_selected:
            self.uncheckSelected()
        elif selected_item == clear_selection:
            self._list.clearSelection()
Exemple #23
0
class ProjectPropertiesDialog( QDialog, object ):
    """ project properties dialog implementation """

    def __init__( self, project = None, parent = None ):

        QDialog.__init__( self, parent )

        # The dialog caller reads this member if the dialog was finished
        # successfully.
        self.absProjectFileName = None

        self.__createLayout()
        self.__project = project

        if project is None:
            # It a new project creation
            self.setWindowTitle( "New Project Properties" )

            userRecord = pwd.getpwuid( os.getuid() )

            if not userRecord[ 5 ].endswith( os.path.sep ):
                self.dirEdit.setText( userRecord[ 5 ] + os.path.sep )
            else:
                self.dirEdit.setText( userRecord[ 5 ] )
            self.initialDirName = self.dirEdit.text()
            self.lastProjectName = ""

            if userRecord[ 4 ] != "":
                self.authorEdit.setText( userRecord[ 4 ].split( ',' )[ 0 ].strip() )
            else:
                self.authorEdit.setText( userRecord[ 0 ] )

            try:
                self.emailEdit.setText( userRecord[ 0 ] +
                                        "@" + socket.gethostname() )
            except:
                pass

            self.versionEdit.setText( "0.0.1" )
            self.licenseEdit.setText( "GPL v3" )
            self.copyrightEdit.setText( "Copyright (c) " +
                                        self.authorEdit.text() + ", " +
                                        str( datetime.date.today().year ) )
            self.creationDateEdit.setText( getLocaleDate() )
            self.nameEdit.setFocus()

        elif type( project ) == type( "" ):
            self.setWindowTitle( "Viewing Project Properties" )

            # This is viewing properties and the argument is the path to the
            # project file
            scriptName, importDirs, creationDate, author, lic, \
            copy_right, description, \
            version, email, uuid = getProjectProperties( project )

            if not os.path.isabs( scriptName ) and scriptName != "":
                scriptName = os.path.normpath( os.path.dirname( project ) +
                                               os.path.sep + scriptName )

            self.nameEdit.setText( os.path.basename( project ) )
            self.nameEdit.setToolTip( "" )
            self.dirEdit.setText( os.path.dirname( project ) )
            self.dirEdit.setToolTip( "" )
            self.scriptEdit.setText( scriptName )
            self.versionEdit.setText( version )
            self.authorEdit.setText( author )
            self.emailEdit.setText( email )
            self.licenseEdit.setText( lic )
            self.copyrightEdit.setText( copy_right )
            self.descriptionEdit.setText( description )
            self.creationDateEdit.setText( creationDate )
            self.uuidEdit.setText( str( uuid ) )
            self.uuidEdit.setToolTip( settingsDir + str( uuid ) + os.path.sep +
                                      " (double click to copy path)"  )

            for item in importDirs:
                self.importDirList.addItem( item )

            self.disableEditing()

        else:
            self.setWindowTitle( "Editing Project Properties" )

            # This is editing the loaded project.
            self.nameEdit.setText( os.path.basename( project.fileName ) )
            self.nameEdit.setToolTip( "" )
            self.dirEdit.setText( project.getProjectDir() )
            self.dirEdit.setToolTip( "" )
            self.scriptEdit.setText( project.getProjectScript() )
            self.versionEdit.setText( project.version )
            self.authorEdit.setText( project.author )
            self.emailEdit.setText( project.email )
            self.licenseEdit.setText( project.license )
            self.copyrightEdit.setText( project.copyright )
            self.descriptionEdit.setText( project.description )
            self.creationDateEdit.setText( project.creationDate )
            self.uuidEdit.setText( str( project.uuid ) )
            self.uuidEdit.setToolTip( project.userProjectDir +
                                      " (double click to copy path)" )
            self.setReadOnly()

            for item in project.importDirs:
                self.importDirList.addItem( item )
            if self.importDirList.count() > 0:
                self.importDirList.setCurrentRow( 0 )
                self.delImportDirButton.setEnabled( True )

            # The project could be the one belonging to another user
            # so there might be no write permissions.
            if not os.access( project.fileName, os.W_OK ):
                # Disable editing
                self.setWindowTitle( "Viewing Project Properties (no write permissions)" )
                self.disableEditing()
            else:
                self.scriptEdit.setFocus()

        return

    def __createLayout( self ):
        """ Creates the dialog layout """

        self.resize( 600, 400 )
        self.setSizeGripEnabled( True )

        verticalLayout = QVBoxLayout( self )
        gridLayout = QGridLayout()

        # Project name
        nameLabel = QLabel( self )
        nameLabel.setText( "Project name:" )
        gridLayout.addWidget( nameLabel, 0, 0, 1, 1 )
        self.nameEdit = QLineEdit( self )
        self.nameEdit.setToolTip( "Type a project name without a path" )
        self.nameEdit.installEventFilter( self )
        gridLayout.addWidget( self.nameEdit, 0, 1, 1, 1 )

        # Project dir
        dirLabel = QLabel( self )
        dirLabel.setText( "Project directory:" )
        gridLayout.addWidget( dirLabel, 1, 0, 1, 1 )
        self.dirEdit = QLineEdit( self )
        self.dirEdit.setToolTip( "Not existed directories will be created" )
        gridLayout.addWidget( self.dirEdit, 1, 1, 1, 1 )
        self.dirButton = QPushButton( self )
        self.dirButton.setText( "..." )
        gridLayout.addWidget( self.dirButton, 1, 2, 1, 1 )
        self.dirCompleter = DirCompleter( self.dirEdit )

        # Project script
        mainScriptLabel = QLabel( "Main script:", self )
        gridLayout.addWidget( mainScriptLabel, 2, 0, 1, 1 )
        self.scriptEdit = QLineEdit( self )
        self.scriptEdit.setToolTip( "Project main script, "
                                    "used when the project is run" )
        gridLayout.addWidget( self.scriptEdit, 2, 1, 1, 1 )
        self.scriptButton = QPushButton( "...", self )
        gridLayout.addWidget( self.scriptButton, 2, 2, 1, 1 )
        self.fileCompleter = FileCompleter( self.scriptEdit )

        # Import dirs
        importLabel = QLabel( self )
        importLabel.setText( "Import directories:" )
        importLabel.setAlignment( Qt.AlignTop )
        gridLayout.addWidget( importLabel, 3, 0, 1, 1 )
        self.importDirList = QListWidget( self )
        self.importDirList.setAlternatingRowColors( True )
        self.importDirList.setSelectionMode( QAbstractItemView.SingleSelection )
        self.importDirList.setSelectionBehavior( QAbstractItemView.SelectRows )
        self.importDirList.setItemDelegate( NoOutlineHeightDelegate( 4 ) )
        self.importDirList.setToolTip( "Directories where to look for "
                                       "project specific imports" )
        gridLayout.addWidget( self.importDirList, 3, 1, 1, 1 )

        self.addImportDirButton = QPushButton( self )
        self.addImportDirButton.setText( "Add dir" )
        self.delImportDirButton = QPushButton( self )
        self.delImportDirButton.setText( "Delete dir" )
        self.delImportDirButton.setEnabled( False )
        vLayout = QVBoxLayout()
        vLayout.addWidget( self.addImportDirButton )
        vLayout.addWidget( self.delImportDirButton )
        vLayout.addStretch( 0 )
        gridLayout.addLayout( vLayout, 3, 2, 1, 1 )

        # Version
        versionLabel = QLabel( self )
        versionLabel.setText( "Version:" )
        gridLayout.addWidget( versionLabel, 4, 0, 1, 1 )
        self.versionEdit = QLineEdit( self )
        gridLayout.addWidget( self.versionEdit, 4, 1, 1, 1 )

        # Author
        authorLabel = QLabel( self )
        authorLabel.setText( "Author:" )
        gridLayout.addWidget( authorLabel, 5, 0, 1, 1 )
        self.authorEdit = QLineEdit( self )
        gridLayout.addWidget( self.authorEdit, 5, 1, 1, 1 )

        # E-mail
        emailLabel = QLabel( self )
        emailLabel.setText( "E-mail:" )
        gridLayout.addWidget( emailLabel, 6, 0, 1, 1 )
        self.emailEdit = QLineEdit( self )
        gridLayout.addWidget( self.emailEdit, 6, 1, 1, 1 )

        # License
        licenseLabel = QLabel( self )
        licenseLabel.setText( "License:" )
        gridLayout.addWidget( licenseLabel, 7, 0, 1, 1 )
        self.licenseEdit = QLineEdit( self )
        gridLayout.addWidget( self.licenseEdit, 7, 1, 1, 1 )

        # Copyright
        copyrightLabel = QLabel( self )
        copyrightLabel.setText( "Copyright:" )
        gridLayout.addWidget( copyrightLabel, 8, 0, 1, 1 )
        self.copyrightEdit = QLineEdit( self )
        gridLayout.addWidget( self.copyrightEdit, 8, 1, 1, 1 )

        # Description
        descriptionLabel = QLabel( self )
        descriptionLabel.setText( "Description:" )
        descriptionLabel.setAlignment( Qt.AlignTop )
        gridLayout.addWidget( descriptionLabel, 9, 0, 1, 1 )
        self.descriptionEdit = QTextEdit( self )
        self.descriptionEdit.setTabChangesFocus( True )
        self.descriptionEdit.setAcceptRichText( False )
        gridLayout.addWidget( self.descriptionEdit, 9, 1, 1, 1 )

        # Creation date
        creationDateLabel = QLabel( self )
        creationDateLabel.setText( "Creation date:" )
        gridLayout.addWidget( creationDateLabel, 10, 0, 1, 1 )
        self.creationDateEdit = FramedLabelWithDoubleClick()
        self.creationDateEdit.setToolTip( "Double click to copy" )
        gridLayout.addWidget( self.creationDateEdit, 10, 1, 1, 1 )

        # Project UUID
        uuidLabel = QLabel( self )
        uuidLabel.setText( "UUID:" )
        gridLayout.addWidget( uuidLabel, 11, 0, 1, 1 )
        self.uuidEdit = FramedLabelWithDoubleClick( "", self.__copyProjectPath )
        gridLayout.addWidget( self.uuidEdit, 11, 1, 1, 1 )

        verticalLayout.addLayout( gridLayout )

        # Buttons at the bottom
        buttonBox = QDialogButtonBox( self )
        buttonBox.setOrientation( Qt.Horizontal )
        buttonBox.setStandardButtons( QDialogButtonBox.Cancel | \
                                      QDialogButtonBox.Ok )
        verticalLayout.addWidget( buttonBox )

        nameLabel.setBuddy( self.nameEdit )
        dirLabel.setBuddy( self.dirEdit )
        versionLabel.setBuddy( self.versionEdit )
        authorLabel.setBuddy( self.authorEdit )
        emailLabel.setBuddy( self.emailEdit )
        licenseLabel.setBuddy( self.licenseEdit )
        copyrightLabel.setBuddy( self.copyrightEdit )
        descriptionLabel.setBuddy( self.descriptionEdit )

        buttonBox.accepted.connect( self.onOKButton )
        buttonBox.rejected.connect( self.reject )
        self.dirButton.clicked.connect( self.onDirButton )
        self.scriptButton.clicked.connect( self.onScriptButton )
        self.importDirList.currentRowChanged.connect( self.onImportDirRowChanged )
        self.addImportDirButton.clicked.connect( self.onAddImportDir )
        self.delImportDirButton.clicked.connect( self.onDelImportDir )
        self.nameEdit.textEdited.connect( self.onProjectNameChanged )

        self.setTabOrder( self.nameEdit, self.dirEdit )
        self.setTabOrder( self.dirEdit, self.dirButton )
        self.setTabOrder( self.dirButton, self.scriptEdit )
        self.setTabOrder( self.scriptEdit, self.scriptButton )
        self.setTabOrder( self.scriptButton, self.importDirList )
        self.setTabOrder( self.importDirList, self.addImportDirButton )
        self.setTabOrder( self.addImportDirButton, self.delImportDirButton )
        self.setTabOrder( self.delImportDirButton, self.versionEdit )
        self.setTabOrder( self.versionEdit, self.authorEdit )
        self.setTabOrder( self.authorEdit, self.emailEdit )
        self.setTabOrder( self.emailEdit, self.licenseEdit )
        self.setTabOrder( self.licenseEdit, self.copyrightEdit )
        self.setTabOrder( self.copyrightEdit, self.descriptionEdit )
        self.setTabOrder( self.descriptionEdit, buttonBox )
        return

    def eventFilter( self, obj, event ):
        " Event filter for the project name field "

        # Do not allow path separators
        if event.type() == QEvent.KeyPress:
            if event.key() == ord( os.path.sep ):
                return True
        return QObject.eventFilter( self, obj, event )


    def onDirButton( self ):
        " Displays a directory selection dialog "

        dirName = QFileDialog.getExistingDirectory( self,
                    "Select project directory",
                    self.dirEdit.text(),
                    QFileDialog.Options( QFileDialog.ShowDirsOnly ) )

        if dirName:
            self.dirEdit.setText( os.path.normpath( dirName ) )
        return

    def onScriptButton( self ):
        " Displays a file selection dialog "
        scriptName = QFileDialog.getOpenFileName( self,
                        "Select project main script",
                        self.dirEdit.text() )

        if scriptName:
            self.scriptEdit.setText( os.path.normpath( scriptName ) )
        return

    def onImportDirRowChanged( self, row ):
        " Triggered when a current row in the import dirs is changed "
        self.delImportDirButton.setEnabled( row != -1 )
        return

    def onAddImportDir( self ):
        " Displays a directory selection dialog "

        dirName = QFileDialog.getExistingDirectory( self,
                    "Select import directory",
                    self.dirEdit.text(),
                    QFileDialog.Options( QFileDialog.ShowDirsOnly ) )

        if not dirName:
            return

        # There are 2 cases: new project or
        # editing the existed project properties
        if self.__project is None:
            # It a new project; the project path could be editedd
            dirToInsert = dirName
        else:
            # This is an existed project; no way the project path is changed
            # Let's decide it a relative path should be used here
            if self.__project.isProjectDir( dirName ):
                dirToInsert = relpath( dirName, self.dirEdit.text() )
            else:
                dirToInsert = dirName

        index = 0
        while index < self.importDirList.count():
            if self.importDirList.item( index ).text() == dirToInsert:
                logging.warning( "The directory '" + dirName +
                                 "' is already in the list of "
                                 "imported directories and is not added." )
                return
            index += 1

        self.importDirList.addItem( dirToInsert )
        self.importDirList.setCurrentRow( self.importDirList.count() - 1 )
        return

    def onDelImportDir( self ):
        " Triggered when an import dir should be deleted "

        rowToDelete = self.importDirList.currentRow()
        if  rowToDelete == -1:
            self.delImportDirButton.setEnabled( False )
            return

        self.importDirList.takeItem( rowToDelete )
        if self.importDirList.count() == 0:
            self.delImportDirButton.setEnabled( False )
        else:
            self.importDirList.setCurrentRow( self.importDirList.count() - 1 )
        return

    def onOKButton( self ):
        " Checks that the mandatory fields are filled properly "

        # The checks must be done for a new project only
        if not self.nameEdit.isEnabled():
            self.accept()
            return

        # Check that the project name does not have path separators and is not
        # empty
        if not self.nameEdit.text().strip():
            QMessageBox.critical( self, "Error",
                                  "The project name must not be empty" )
            return
        if os.path.sep in self.nameEdit.text():
            QMessageBox.critical( self, "Error",
                                  "The project name must not "
                                  "contain path separators" )
            return

        # Check that the project directory is given
        dirName = self.dirEdit.text().strip()
        if not dirName:
            QMessageBox.critical( self, "Error",
                                  "The project directory must not be empty" )
            return

        dirName = os.path.abspath( dirName )
        self.dirEdit.setText( dirName )
        # Check that the project file does not exist
        projectFileName = dirName
        if not projectFileName.endswith( os.path.sep ):
            projectFileName += os.path.sep
        projectFileName += self.nameEdit.text().strip()
        if not projectFileName.endswith( ".cdm" ):
            projectFileName += ".cdm"

        if os.path.exists( projectFileName ):
            QMessageBox.critical( self, "Error",
                                  "The project file " + projectFileName +
                                  " exists. Please provide another "
                                  "directory / project name." )
            return

        # Check that the project dir is not a file
        if os.path.exists( dirName ):
            # It might be a link, so read it first
            dirName = os.path.realpath( dirName )
            if not os.path.exists( dirName ):
                QMessageBox.critical( self, "Error",
                                      "Broken link: " + dirName )
                return
            if not os.path.isdir( dirName ):
                QMessageBox.critical( self, "Error",
                                      "The project directory "
                                      "may not be a file" )
                return
            # Check that the dir is writable
            if not os.access( dirName, os.W_OK ):
                QMessageBox.critical( self, "Error",
                                      "You don't have write permissions on " +
                                      dirName )
                return
        else:
            # Create the directory
            try:
                os.makedirs( dirName )
            except OSError:
                QMessageBox.critical( self, "Error",
                                      "Cannot create the project directory" )
                return

        # Save the absolute file name for further reading it by the caller
        self.absProjectFileName = projectFileName

        # The minimum is provided so we can accept it
        self.accept()
        return

    def onProjectNameChanged( self, newName ):
        " Called when the project name changed "

        if newName.endswith( ".cdm" ):
            newName = newName[ :-4 ]
        if self.dirEdit.text().strip() == (self.initialDirName +
                                           self.lastProjectName):
            self.dirEdit.setText( self.initialDirName + newName )
            self.lastProjectName = newName
        return

    def setReadOnly( self ):
        """ Disables editing some fields """

        self.dirEdit.setReadOnly( True )
        self.dirEdit.setFocusPolicy( Qt.NoFocus )
        self.dirEdit.setDisabled( True )
        self.dirButton.setDisabled( True )
        self.dirButton.setFocusPolicy( Qt.NoFocus )
        self.nameEdit.setReadOnly( True )
        self.nameEdit.setFocusPolicy( Qt.NoFocus )
        self.nameEdit.setDisabled( True )
        return

    def disableEditing( self ):
        " Disables all the editing "

        self.nameEdit.setDisabled( True )
        self.dirEdit.setDisabled( True )
        self.dirButton.setDisabled( True )
        self.scriptEdit.setDisabled( True )
        self.scriptButton.setDisabled( True )
        self.importDirList.setDisabled( True )
        self.addImportDirButton.setDisabled( True )
        self.delImportDirButton.setDisabled( True )
        self.versionEdit.setDisabled( True )
        self.authorEdit.setDisabled( True )
        self.emailEdit.setDisabled( True )
        self.licenseEdit.setDisabled( True )
        self.copyrightEdit.setDisabled( True )
        self.descriptionEdit.setDisabled( True )
        return

    def __copyProjectPath( self ):
        " Copies the project path when a label is double clicked "
        text = self.uuidEdit.text().strip()
        if text:
            path = settingsDir + text + os.path.sep
            QApplication.clipboard().setText( path )
        return
class AdvancedVisualizationForm(QWidget):
    def __init__(self, mainwindow, result_manager):
        QWidget.__init__(self, mainwindow)
        #mainwindow is an OpusGui
        self.mainwindow = mainwindow
        self.result_manager = result_manager
        self.toolboxBase = self.result_manager.mainwindow.toolboxBase

        self.inGui = False
        self.logFileKey = 0

        self.xml_helper = ResultsManagerXMLHelper(toolboxBase=self.toolboxBase)
        self.result_generator = OpusResultGenerator(
            toolboxBase=self.toolboxBase)

        self.result_generator.guiElement = self

        self.tabIcon = QIcon(':/Images/Images/cog.png')
        self.tabLabel = 'Advanced Visualization'

        self.widgetLayout = QVBoxLayout(self)
        self.widgetLayout.setAlignment(Qt.AlignTop)

        self.resultsGroupBox = QGroupBox(self)
        self.widgetLayout.addWidget(self.resultsGroupBox)

        self.dataGroupBox = QGroupBox(self)
        self.widgetLayout.addWidget(self.dataGroupBox)

        self.optionsGroupBox = QGroupBox(self)
        self.widgetLayout.addWidget(self.optionsGroupBox)

        self._setup_definition_widget()

        self._setup_buttons()
        self._setup_tabs()

    def _setup_buttons(self):
        # Add Generate button...
        self.pbn_go = QPushButton(self.resultsGroupBox)
        self.pbn_go.setObjectName('pbn_go')
        self.pbn_go.setText(QString('Go!'))

        QObject.connect(self.pbn_go, SIGNAL('released()'),
                        self.on_pbn_go_released)
        self.widgetLayout.addWidget(self.pbn_go)

        self.pbn_set_esri_storage_location = QPushButton(self.optionsGroupBox)
        self.pbn_set_esri_storage_location.setObjectName(
            'pbn_set_esri_storage_location')
        self.pbn_set_esri_storage_location.setText(QString('...'))
        self.pbn_set_esri_storage_location.hide()

        QObject.connect(self.pbn_set_esri_storage_location,
                        SIGNAL('released()'),
                        self.on_pbn_set_esri_storage_location_released)

    def _setup_tabs(self):
        # Add a tab widget and layer in a tree view and log panel
        self.tabWidget = QTabWidget(self.resultsGroupBox)

        # Log panel
        self.logText = QTextEdit(self.resultsGroupBox)
        self.logText.setReadOnly(True)
        self.logText.setLineWidth(0)
        self.tabWidget.addTab(self.logText, 'Log')

        # Finally add the tab to the model page
        self.widgetLayout.addWidget(self.tabWidget)

#

    def _setup_definition_widget(self):

        #### setup results group box ####

        self.gridlayout = QGridLayout(self.resultsGroupBox)
        self.gridlayout.setObjectName('gridlayout')

        self.lbl_results = QLabel(self.resultsGroupBox)
        self.lbl_results.setObjectName('lbl_results')
        self.lbl_results.setText(QString('Results'))
        self.gridlayout.addWidget(self.lbl_results, 0, 0, 1, 3)

        self._setup_co_results()
        self.gridlayout.addWidget(self.co_results, 0, 3, 1, 10)

        self.pbn_add = QPushButton(self.resultsGroupBox)
        self.pbn_add.setObjectName('pbn_add')
        self.pbn_add.setText(QString('+'))

        QObject.connect(self.pbn_add, SIGNAL('released()'),
                        self.on_pbn_add_released)
        self.gridlayout.addWidget(self.pbn_add, 0, 14, 1, 1)

        self.lw_indicators = QListWidget(self.resultsGroupBox)
        self.lw_indicators.setObjectName('lw_indicators')
        self.gridlayout.addWidget(self.lw_indicators, 1, 1, 1, 13)

        self.pbn_remove = QPushButton(self.resultsGroupBox)
        self.pbn_remove.setObjectName('pbn_remove')
        self.pbn_remove.setText(QString('-'))

        QObject.connect(self.pbn_remove, SIGNAL('released()'),
                        self.on_pbn_remove_released)
        self.gridlayout.addWidget(self.pbn_remove, 1, 14, 1, 1)

        #### setup data group box ####

        self.gridlayout2 = QGridLayout(self.dataGroupBox)
        self.gridlayout2.setObjectName('gridlayout2')

        self._setup_co_result_style()
        self.gridlayout2.addWidget(self.co_result_style, 1, 0, 1, 2)

        self.lbl_result_style_sep = QLabel(self.resultsGroupBox)
        self.lbl_result_style_sep.setObjectName('lbl_result_style_sep')
        self.lbl_result_style_sep.setText(QString('<center>as</center>'))
        self.gridlayout2.addWidget(self.lbl_result_style_sep, 1, 2, 1, 1)

        self._setup_co_result_type()
        self.gridlayout2.addWidget(self.co_result_type, 1, 3, 1, 2)

        ##### setup options group box ####

        self.gridlayout3 = QGridLayout(self.optionsGroupBox)
        self.gridlayout3.setObjectName('gridlayout3')

        self.le_esri_storage_location = QLineEdit(self.optionsGroupBox)
        self.le_esri_storage_location.setObjectName('le_esri_storage_location')
        self.le_esri_storage_location.setText('[set path]')
        self.le_esri_storage_location.hide()
        self.optionsGroupBox.hide()

        QObject.connect(self.co_result_style,
                        SIGNAL('currentIndexChanged(int)'),
                        self.on_co_result_style_changed)
        QObject.connect(self.co_result_type,
                        SIGNAL('currentIndexChanged(int)'),
                        self.on_co_result_type_changed)

    def _setup_co_results(self):

        self.co_results = QComboBox(self.resultsGroupBox)
        self.co_results.setObjectName('co_results')
        self.co_results.addItem(QString('[select]'))

        results = self.xml_helper.get_available_results()

        for result in results:
            name = '%i.%s' % (result['run_id'], result['indicator_name'])
            self.co_results.addItem(QString(name))

    def _setup_co_result_style(self):
        available_styles = [
            'visualize',
            'export',
        ]
        self.co_result_style = QComboBox(self.dataGroupBox)
        self.co_result_style.setObjectName('co_result_style')

        for dataset in available_styles:
            self.co_result_style.addItem(QString(dataset))

    def _setup_co_result_type(self):
        available_types = [
            'Table (per year, spans indicators)',
            'Chart (per indicator, spans years)',
            'Map (per indicator per year)',
            'Chart (per indicator, spans years)',
        ]

        self.co_result_type = QComboBox(self.dataGroupBox)
        self.co_result_type.setObjectName('co_result_type')

        for dataset in available_types:
            self.co_result_type.addItem(QString(dataset))

    def on_pbnRemoveModel_released(self):
        self.result_manager.removeTab(self)
        self.result_manager.updateGuiElements()

    def on_pbn_add_released(self):
        cur_selected = self.co_results.currentText()
        for i in range(self.lw_indicators.count()):
            if self.lw_indicators.item(i).text() == cur_selected:
                return

        self.lw_indicators.addItem(cur_selected)

    def on_pbn_remove_released(self):
        selected_idxs = self.lw_indicators.selectedIndexes()
        for idx in selected_idxs:
            self.lw_indicators.takeItem(idx.row())

    def on_co_result_style_changed(self, ind):
        available_viz_types = [
            'Table (per year, spans indicators)',
            'Chart (per indicator, spans years)',
            'Map (per indicator per year)',
            'Chart (per indicator, spans years)',
        ]

        available_export_types = ['ESRI table (for loading in ArcGIS)']

        txt = self.co_result_style.currentText()
        if txt == 'visualize':
            available_types = available_viz_types
        else:
            available_types = available_export_types

        self.co_result_type.clear()
        for result_type in available_types:
            r_type = QString(result_type)
            self.co_result_type.addItem(r_type)

    def on_co_result_type_changed(self, ind):
        self.gridlayout3.removeWidget(self.le_esri_storage_location)
        self.gridlayout3.removeWidget(self.pbn_set_esri_storage_location)
        self.optionsGroupBox.hide()

        self.pbn_set_esri_storage_location.hide()
        self.le_esri_storage_location.hide()

        txt = self.co_result_type.currentText()

        print txt
        if txt == 'ESRI table (for loading in ArcGIS)':
            self.pbn_set_esri_storage_location.show()
            self.le_esri_storage_location.show()
            self.gridlayout3.addWidget(self.le_esri_storage_location, 0, 1, 1,
                                       6)
            self.gridlayout3.addWidget(self.pbn_set_esri_storage_location, 0,
                                       7, 1, 1)
            self.optionsGroupBox.show()

    def on_pbn_set_esri_storage_location_released(self):
        print 'pbn_set_esri_storage_location released'
        from opus_core.misc import directory_path_from_opus_path
        start_dir = directory_path_from_opus_path('opus_gui.projects')

        configDialog = QFileDialog()
        filter_str = QString("*.gdb")
        fd = configDialog.getExistingDirectory(
            self,
            QString("Please select an ESRI geodatabase (*.gdb)..."
                    ),  #, *.sde, *.mdb)..."),
            QString(start_dir),
            QFileDialog.ShowDirsOnly)
        if len(fd) != 0:
            fileName = QString(fd)
            fileNameInfo = QFileInfo(QString(fd))
            fileNameBaseName = fileNameInfo.completeBaseName()
            self.le_esri_storage_location.setText(fileName)

    def on_pbn_go_released(self):
        # Fire up a new thread and run the model
        print 'Go button pressed'

        # References to the GUI elements for status for this run...
        #self.statusLabel = self.runStatusLabel
        #self.statusLabel.setText(QString('Model initializing...'))

        indicator_names = []
        for i in range(self.lw_indicators.count()):
            indicator_names.append(str(self.lw_indicators.item(i).text()))

        if indicator_names == []:
            print 'no indicators selected'
            return

        indicator_type = str(self.co_result_type.currentText())
        indicator_type = {
            #'Map (per indicator per year)':'matplotlib_map',
            'Map (per indicator per year)': 'mapnik_map',
            'Chart (per indicator, spans years)': 'matplotlib_chart',
            'Table (per indicator, spans years)': 'table_per_attribute',
            'Table (per year, spans indicators)': 'table_per_year',
            'ESRI table (for loading in ArcGIS)': 'table_esri'
        }[indicator_type]

        kwargs = {}
        if indicator_type == 'table_esri':
            storage_location = str(self.le_esri_storage_location.text())
            if not os.path.exists(storage_location):
                print 'Warning: %s does not exist!!' % storage_location
            kwargs['storage_location'] = storage_location

        self.result_manager.addIndicatorForm(indicator_type=indicator_type,
                                             indicator_names=indicator_names,
                                             kwargs=kwargs)

    def runUpdateLog(self):
        self.logFileKey = self.result_generator._get_current_log(
            self.logFileKey)

    def runErrorFromThread(self, errorMessage):
        QMessageBox.warning(self.mainwindow, 'Warning', errorMessage)
Exemple #25
0
class VocDialog(QDialog) :

    """This is the dialog which presents the interface and organise everything."""

    MAGICWORD = 'CHANGEME'
    findDight = reCompile(r'\d+')
    baseURL = 'http://www.gstatic.com/dictionary/static/sounds/de/0/CHANGEME.mp3'

    def __init__(self, autoProxy=False, parent=None) :
        super(VocDialog, self).__init__(parent)
        self.logger = getLogger('VocVoc.VocDialog')
        self.info = self.logger.info
        self.warn = self.logger.warn
        self.debug = self.logger.debug
        if autoProxy :
            self.info('Starting VocDialog with autoProxy.')
        else :
            self.info('Starting VocDialog without autoProxy.')
        self.mediaObeject = Phonon.createPlayer(Phonon.MusicCategory, Phonon.MediaSource(''))
        self.setupUi()
        self.connect()
        self.initCountWord()
        self.candidates = None
        self.autoProxy = autoProxy
        self.spellChecker = SpellChecker()
        self.correct = self.spellChecker.correct
        self.corpusDir = self.spellChecker.corpusDir
        self.info('VocDialog started.')

    def keyPressEvent(self, event) :
        self.debug('Key is {}.'.format(event.key()))
        super(VocDialog, self).keyPressEvent(event)

    def resizeEvent(self, event) :
        self.debug("Resized to {}.".format(self.size()))
        super(VocDialog, self).resizeEvent(event)

    def initCountWord(self) :
        """
        The first one is a count about how many time the input is wrong.
          WRONG : Not collected in or can be corrected by the wordModel.
        The second one is the last time's wrong input.
        """
        self.countWord = [0, '']

    def setupUi(self) :
        "Setup the UI."
        self.info('Seting up the UI.')
        self.fileDialog = QFileDialog()
        self.fileDialog.setFileMode(QFileDialog.AnyFile)
        self.fileDialog.setViewMode(QFileDialog.Detail)

        self.loadButton = QPushButton( r'Open/New :', self)
        self.loadButton.setAutoDefault(False)

        self.textList = QListWidget(self)

        self.inputLine = tabEnabledLineEdit(self)

        self.toggleButton = QPushButton(r'Show/Hide', self)
        self.toggleButton.setAutoDefault(False)
        self.toggleButton.setCheckable(True)

        self.textLabel = QLabel()

        self.hBox = QHBoxLayout()
        self.hBox.addWidget(self.inputLine)
        self.hBox.addWidget(self.toggleButton)

        self.statusBar = QStatusBar(self)
        msg = 'Hello World! I love YOU!!!'
        self.statusBar.showMessage(msg, 5000)

        vBox = QVBoxLayout()
        items = [self.loadButton, self.textList, self.hBox, self.statusBar]
        for item in items :
            try :
                vBox.addWidget(item)
            except :
                vBox.addLayout(item)

        self.textViewer = QTextEdit()
        self.textViewer.setHidden(True)
        self.textViewer.setReadOnly(True)

        HBox = QHBoxLayout()

        items = [vBox, self.textViewer]
        for item in items :
            try :
                HBox.addWidget(item)
            except :
                HBox.addLayout(item)
                
        self.setLayout(HBox)
        self.resize(350, 500)
        self.setWindowTitle("VocVoc -- Your Vocabulary Helper")
        self.info('UI is set up now.')

    def connect(self) :
        "Connect signals and slots in the UI."
        self.info('Connecting signals and slots.')
        self.loadButton.clicked.connect(self.loadFile)
        self.inputLine.returnPressed.connect(self.enteredText)
        self.inputLine.ctrlN.connect(self.completeHandler)
        self.inputLine.ctrlP.connect(lambda : self.completeHandler(False))
        self.textList.itemActivated.connect(self.itemActivated)
        self.toggleButton.clicked.connect(self.toggleViewer)
        if self.logger.isEnabledFor(DEBUG) :
            self.mediaObeject.stateChanged.connect( self.errorState )
        self.info('Signals and slots connected.')

    def errorState(self, state) :
        errorStates = {
                        0: 'Loading',
                        1: 'Stopped',
                        2: 'Playing',
                        3: 'Buffering',
                        4: 'Paused',
                        5: 'Error'
                        }
        msg ='{} state in Phonon!'.format( errorStates[state]) 
        self.info(self.mediaObeject.errorType())
        if state == 5 :
            self.warn(msg)
        else :
            self.info(msg)

    def itemActivated(self, item) :
        row = self.textList.row(item)
        text = item.text()
        if not text.startswith('#') :
            self.pronounce(item.text())
            self.findWord(text)
        if row+1 != self.textList.count() :
            self.debug('NOT last row!')
            self.textList.setCurrentRow(row+1)
        else :
            self.debug('Last row!')

    def toggleViewer(self) :
        if self.textViewer.isHidden() :
            self.resize(700, 500)
            self.textViewer.show()
        else :
            self.textViewer.hide()
            self.resize(350, 500)

    def backAndForward(self, forward=True) :
        inputLine = self.inputLine
        word = inputLine.text()
        setText = inputLine.setText
        candidates = self.candidates
        count = len(candidates)
        try :
            position = candidates.index(word)
            self.debug('Position found.')
        except :
            position = None
            self.debug('Position not found.')
        if forward :
            if position is None or position == count - 1 : # At end
                position = -1
            setText( candidates[position+1] )
        else :
            if position is None or position == 0 :
                position = count
            setText( candidates[position-1] )

    def completeHandler(self, goNext=True) :
        inputLine = self.inputLine
        candidates = self.candidates
        word = inputLine.text()
        if candidates :
            self.backAndForward(goNext)

    def play(self, path) :
        self.mediaObeject.setCurrentSource(Phonon.MediaSource(path))
        self.mediaObeject.play()
        
    def pronounce(self, word) :
        self.info('Preparing the url to pronounce.')
        url = self.baseURL.replace(self.MAGICWORD, word)
        if not self.autoProxy :
            self.debug('Without the autoProxy, play it using the url as the source.')
            self.play(url)
        else :
            self.info('With the autoProxy, play it after downloading the file.')
            try : # May happen HTTPError.
                resource = urlopen(url).read()
                tempFile = NamedTemporaryFile()
                tempFile.write(resource)
                self.play(tempFile.name)
            except HTTPError as error :
                self.warn(repr(error))
                self.warn('Pronounciation FAILED.')
        self.info('Pronounciation ended.')

    def findWord(self, word) :
        self.info('Finding word in the text file.')
        textViewer = self.textViewer
        if textViewer.isHidden() :
            return
        else :
            pass
        limit = 5
        contexts = list()
        textLines = list()
        corpuses = glob(''.join([self.corpusDir, '/*']))
        self.debug('Found corpuses : {}.'.format(corpuses))
        textViewer.clear()
        for corpus in corpuses :
            textLines.append(locateWord(corpus, word))
        for textLine in textLines :
            text, lines = textLine[0], textLine[1]
            title = ''.join( ['Title : ', basename(text[-1])] )
            if lines :
                for line in lines :
                    wantedLines = text[line-limit: line+limit]
                    #cleanLines = map(self.replace, wantedLines)
                    context = ''.join(wantedLines)
                    context = context.replace(word, ' '.join(['*', word, '*']))
                    context = context.replace('\n\n', self.MAGICWORD)
                    context = context.replace('\n', ' ')
                    context = context.replace(self.MAGICWORD, '\n\n')
                    contexts.append(''.join([title, '\n', context, '\n\n']))
        if contexts :
            for context in contexts :
                textViewer.append(context)
        else :
            textViewer.append('Sorry, {} not found.'.format(word))
        self.info('Word found and showed in the textViewer.')

    def wordCount(self, word=None) :
        """
        This function uses self.countWord to decide whether record and pronounce the input or not.
        RECORD : Add the input into the textList and write it into the file.
        If the word itself is correct, return True.
        Or if a wrong input were entered twice, return True.
        Otherwise with a one-time-entered wrong input, return False.
        """
        if self.countWord[0] == 0 : # The word is correct.
            self.countWord[1] = ''
            return True
        elif self.countWord[0] == 1 :
            msg = 'Maybe the word is WRONG? Playing beep and saving the word.'
            self.debug(msg)
            self.countWord[1] = word
            self.play('beep.mp3')
            return False
        elif self.countWord[0] == 2 :
            if word != self.countWord[1] : # Different word.
                self.debug('DIFEFRENT WORD.')
                self.countWord[0] = 1 # Check again.
                self.countWord[1] = word # Update it.
                self.play('beep.mp3')
                return False
            else :
                self.countWord[0] = 0
                self.countWord[1] = ''
            return True
        else :
            self.countWord[0] = 0

    def checkWord(self, word) :
        statusBar = self.statusBar
        showMessage = statusBar.showMessage

        candidates = self.correct(word)
        if candidates is None : # Not collected.
            self.countWord[0] += 1
            showMessage('Are you sure?', 3000)
        elif candidates[0] != word : # Can be corrected.
            self.countWord[0] += 1
            self.candidates = candidates
            msg = 'Do you mean {} ?'.format(' ,'.join(candidates))
            showMessage(msg, 5000)
        else : # Collected in the wordModel.
            self.findWord(word)
            self.countWord[0] = 0
            self.debug('Word collected in the wordModel.')
            return True

        msg = 'wrongTime = {} with the word {}.'.format(self.countWord[0], word)
        self.logger.debug(msg)

        return self.wordCount(word)

    def addText(self, text) :
        self.info('Starting to add text.')
        textList = self.textList

        if text.startswith('#') : # It is a comment.
            pass
        else : # It is a word.
            if self.checkWord(text) :
                self.pronounce(text)
            else : # self.checkWord(text) return False
                return

        self.inputLine.clear()
        textList.addItem(text)
        self.statusBar.clearMessage()
        textList.setCurrentRow( textList.count() - 1 )

        try : # With the try statement, it can be used as a pronunciation helper.
            flush(self.filePath, text)
        except Exception :
            self.debug('Using this freely without writing to a file as a pronunciation helper.')
        self.info('Text added.')

    def enteredText(self) :
        "Get the text from the input line and add it to the file and the list."
        self.info('Adding text to textList and the file.')
        textList = self.textList
        text = self.inputLine.text().strip().lower()
        self.debug( 'Input is {}.'.format(text) )

        self.addText(text)

        self.info('Text added.')

    def loadFile(self) :
        "Open the file dialog to select the file and try to start."
        # Open the file dialog.
        logger = getLogger('VocVoc.VocDialog.loadFile')
        info = logger.info
        debug = logger.debug
        debug('Preparing to load file.')
        textList = self.textList
        if ( self.fileDialog.exec() ) :
            debug('Dialog executed sucessfully.')
            filePath = self.fileDialog.selectedFiles()[0]
            fileName = basename(filePath)
            # Create or read file.
            try :
                with open(filePath, 'r+') as textFile :
                    debug('File exists, openning up.')
                    writenText = textFile.read()
                writenText = writenText.splitlines()
                textList.clear()
                textList.addItems( writenText )
                if not 'end' in writenText[-1].strip().lower() :
                    textList.setCurrentRow( len(writenText)-1 )
                else :
                    textList.setCurrentRow( 0 )
                debug('Added items to list and set current row to the last row.')
            except IOError as error : # File does not exist. We create one.
                debug('File does not exist. Trying to find the dight in the name.')
                listNumber = self.findDight.search(fileName)
                if listNumber is None : # No number found in the text.
                    logger.warn('Dight not found in the filename. Try again.')
                    msg = 'No number found in the file name.\nPlease try again.'
                    QMessageBox.warning(self, 'List number NOT found.',
                            msg,
                            QMessageBox.Ok)
                    return msg
                else : # No existing file but found the number in the file name.
                    debug('Dight Found. Creating file and adding first line.')
                    with open(filePath, 'x') as textFile :
                        firstLine = ''.join( ['# list ' ,str( listNumber.group() )] ) # Cannot put '\n' here.
                        textFile.write( ''.join([firstLine ,'\n']) )
                    textList.clear()
                    textList.addItem(firstLine) # Otherwise there would be a new line in the list.

            debug('Set inputLine to write-enabled.')
            self.inputLine.setReadOnly(False)
            debug('Pass textFile to the dialog')
            self.filePath = filePath
            info('File loaded.')
Exemple #26
0
class ChainComposerDialog(QDialog):
 
    def __init__(self, parent=None):
        super(ChainComposerDialog, self).__init__(parent)
        self.setWindowTitle('Composer Chain')
 
        layout = QVBoxLayout()
 
        mainLayout = QHBoxLayout()
 
        selectionLayout = QVBoxLayout()
        label = QLabel('Available Filters:')
        selectionLayout.addWidget(label)
        self.__selectionList = QListWidget()
        selectionLayout.addWidget(self.__selectionList)
        mainLayout.addLayout(selectionLayout)
 
        actionsLayout = QVBoxLayout()
        actionsLayout.addStretch()
        addButton = QPushButton('Add>>')
        addButton.clicked.connect(self.__handleAdd)
        actionsLayout.addWidget(addButton)
        removeButton = QPushButton('Remove')
        actionsLayout.addWidget(removeButton)
        removeAllButton = QPushButton('Remove All')
        actionsLayout.addWidget(removeAllButton)
        actionsLayout.addStretch()
        mainLayout.addLayout(actionsLayout)
 
        chainLayout = QVBoxLayout()
        chainLayout.addWidget(QLabel('Chain:'))
        self.__chainList = QListWidget()
        chainLayout.addWidget(self.__chainList)
        mainLayout.addLayout(chainLayout)
 
        layout.addLayout(mainLayout)
        
        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        buttonBox.accepted.connect(self.okClick)
        buttonBox.rejected.connect(self.cancelClick)
        layout.addWidget(buttonBox)
 
#         buttonLayout = QHBoxLayout()
#         okButton = QPushButton('OK')
#         okButton.clicked.connect(self.accept)
#         buttonLayout.addWidget(okButton)
#         cancelButton = QPushButton('Cancel')
#         cancelButton.clicked.connect(self.reject)
#         buttonLayout.addWidget(cancelButton)
#         layout.addLayout(buttonLayout)
 
        self.setLayout(layout)
 
        self.__composer = None
    
    def okClick(self):
        print "OK!"
        self.accept()
    
    def cancelClick(self):
        print "Cancel"
        self.reject()
 
    def setComposer(self, composer):
        self.__composer = composer
 
    @property
    def selectionList(self):
        return self.__getStrings(self.__selectionList)
 
    @selectionList.setter
    def setSelectionList(self, filters):
        for i in xrange(self.__selectionList.count()):
            self.__selectionList.takeItem(i)
        self.__selectionList.addItems(filters)
 
    def filterAt(self, row):
        return self.__selectionList.item(row).text()
 
    def addToChain(self, filterName):
        self.__chainList.addItem(filterName)
 
    @property
    def composedFilter(self):
        return self.__getStrings(self.__chainList)
 
    @staticmethod
    def __getStrings(listWidget):
        return tuple(listWidget.item(i) for i in
                     range(listWidget.count()))
 
    def __handleAdd(self):
        if self.__composer is None:
            return
        for item in self.__selectionList.selectedItems():
            row = self.__selectionList.row(item)
            self.__composer.add(row)
Exemple #27
0
class FileArgs(QtHelper.EnhancedQDialog, Logger.ClassLogger):
    """
    File arguments dialog
    """
    def __init__(self, dataArgs, parent=None):
        """
        Dialog to fill arguments for the file probe

        @param dataArgs: 
        @type dataArgs: 

        @param parent: 
        @type parent:
        """
        super(FileArgs, self).__init__(parent)
        self.dataArgs = dataArgs
        self.createDialog()
        self.createConnections()
        self.loadDefaultData()

    def createDialog(self):
        """
        Create qt dialog
        """
        mainLayout = QHBoxLayout()

        dataLayout = QVBoxLayout()
        self.labelHelp = QLabel("Path of the file to retrieve:")
        self.lineEdit = QLineEdit()
        self.listBox = QListWidget()
        dataLayout.addWidget(self.labelHelp)
        dataLayout.addWidget(self.lineEdit)
        dataLayout.addWidget(self.listBox)

        buttonLayout = QVBoxLayout()
        self.addButton = QPushButton("Add", self)
        self.delButton = QPushButton("Remove", self)
        self.delButton.setEnabled(False)
        self.editButton = QPushButton("Edit", self)
        self.editButton.setEnabled(False)
        self.clearButton = QPushButton("Clear", self)
        self.okButton = QPushButton("Ok", self)
        self.cancelButton = QPushButton("Cancel", self)
        buttonLayout.addWidget(self.addButton)
        buttonLayout.addWidget(self.delButton)
        buttonLayout.addWidget(self.editButton)
        buttonLayout.addWidget(self.clearButton)
        buttonLayout.addWidget(self.okButton)
        buttonLayout.addWidget(self.cancelButton)

        mainLayout.addLayout(dataLayout)
        mainLayout.addLayout(buttonLayout)

        self.setLayout(mainLayout)

        self.setWindowTitle("File Probe > Arguments")

    def createConnections(self):
        """
        Create qt connections
        """
        self.okButton.clicked.connect(self.accept)
        self.cancelButton.clicked.connect(self.reject)
        self.addButton.clicked.connect(self.addItem)
        self.delButton.clicked.connect(self.delItem)
        self.editButton.clicked.connect(self.editItem)
        self.clearButton.clicked.connect(self.clearList)
        self.listBox.itemClicked.connect(self.onItemSelected)

    def clearList(self):
        """
        Clear the list
        """
        self.listBox.clear()

    def onItemSelected(self, itm):
        """
        Called when an item is selected
        """
        self.delButton.setEnabled(True)
        self.editButton.setEnabled(True)

    def editItem(self):
        """
        Edit the selected item
        """
        self.delButton.setEnabled(False)
        self.editButton.setEnabled(False)
        # retrieve value to put it in the line edit and then remove item
        model = self.listBox.model()
        for selectedItem in self.listBox.selectedItems():
            qIndex = self.listBox.indexFromItem(selectedItem)
            if sys.version_info > (3, ):
                self.lineEdit.setText(model.data(qIndex))
            else:
                self.lineEdit.setText(model.data(qIndex).toString())
            model.removeRow(qIndex.row())

    def delItem(self):
        """
        Delete the selected item
        """
        self.delButton.setEnabled(False)
        self.editButton.setEnabled(False)
        # remove item
        model = self.listBox.model()
        for selectedItem in self.listBox.selectedItems():
            qIndex = self.listBox.indexFromItem(selectedItem)
            model.removeRow(qIndex.row())

    def addItem(self):
        """
        Add item
        """
        txt = self.lineEdit.text()
        if txt != '':
            self.listBox.insertItem(0, txt)
            self.lineEdit.setText('')

    def loadDefaultData(self):
        """
        Load the default data
        """
        try:
            if len(self.dataArgs) == 0:
                return
            dat = eval(self.dataArgs)
            if 'files' in dat:
                list_files = dat['files']
                self.listBox.insertItems(0, list_files)
        except Exception as e:
            self.error(e)

    def getArgs(self):
        """
        Returns arguments
        Examples: {'files': [ '/etc/init.d/ntpd', '/root/wmi-1.3.14-2.el5.art.x86_64.rpm' ] }
        """
        listFiles = []
        model = self.listBox.model()
        # iterate all items in a QListWidget
        for index in xrange(self.listBox.count()):
            itm = self.listBox.item(index)
            qIndex = self.listBox.indexFromItem(itm)
            if sys.version_info > (3, ):
                listFiles.append(model.data(qIndex))
            else:
                listFiles.append(str(model.data(qIndex).toString()))
        ret = {'files': listFiles}
        if len(listFiles) == 0:
            ret = ''
        return str(ret)
class TracklistWidget(QWidget):

    requestUpload = pyqtSignal(list)


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

        self.tracklist = QListWidget(self)
        self.tracklist.setSelectionMode(QListWidget.NoSelection)

        self.upload_button = QPushButton(
            QIcon(resource_path('images/strava-button.png')),
                  'Upload to Strava', self)
        self.upload_button.setMinimumHeight(50)
        self.upload_button.setIconSize(QSize(40, 40))

        self.clear_password = QPushButton(
            QIcon(resource_path('images/cross.png')),
                  'Clear password', self)
        self.clear_password.setMinimumHeight(50)
        self.clear_password.setIconSize(QSize(20, 20))
        self.clear_password.hide()


        self.upload_button.clicked.connect(self._onUploadClicked)

        self._createLayout()



    def setTracks(self, tracks):
        self.tracklist.clear()
        self.tracklist.addItems(tracks)

        for i, name in enumerate(tracks):
            self.tracklist.item(i).setCheckState(Qt.Unchecked)
            self.tracklist.item(i).setSizeHint(QSize(200, 25))

        if tracks:
            self.tracklist.item(i).setCheckState(Qt.Checked)
            self.upload_button.setEnabled(True)
        else:
            self.upload_button.setEnabled(False)


    def _onUploadClicked(self):

        ids = []
        for i in range(self.tracklist.count()):

            item = self.tracklist.item(i)
            if item.checkState() == Qt.Checked:
                ids.append(i)


        if ids:
            self.requestUpload.emit(ids)



    def _createLayout(self):

        l = QVBoxLayout()
        l.addWidget(self.tracklist)

        h = QHBoxLayout()
        h.addWidget(self.upload_button)
        h.addWidget(self.clear_password)
        l.addLayout(h)

        self.setLayout(l)
Exemple #29
0
class PathManager(QDialog):
    def __init__(self, parent=None, pathlist=None):
        QDialog.__init__(self, parent)
        
        assert isinstance(pathlist, list)
        self.pathlist = pathlist
        
        self.last_path = os.getcwdu()
        
        self.setWindowTitle(self.tr("Path manager"))
        self.resize(500, 300)
        
        self.selection_widgets = []
        
        layout = QVBoxLayout()
        self.setLayout(layout)
        
        top_layout = QHBoxLayout()
        layout.addLayout(top_layout)
        self.toolbar_widgets1 = self.setup_top_toolbar(top_layout)

        self.listwidget = QListWidget(self)
        self.connect(self.listwidget, SIGNAL("currentRowChanged(int)"),
                     self.refresh)
        layout.addWidget(self.listwidget)

        bottom_layout = QHBoxLayout()
        layout.addLayout(bottom_layout)
        self.toolbar_widgets2 = self.setup_bottom_toolbar(bottom_layout)        
        
        # Buttons configuration
        bbox = QDialogButtonBox(QDialogButtonBox.Close)
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
        bottom_layout.addWidget(bbox)
        
        self.update_list()
        self.refresh()
        
    def _add_widgets_to_layout(self, layout, widgets):
        layout.setAlignment(Qt.AlignLeft)
        for widget in widgets:
            layout.addWidget(widget)
        
    def setup_top_toolbar(self, layout):
        toolbar = []
        movetop_button = create_toolbutton(self,
                                    text=self.tr("Move to top"),
                                    icon=get_icon('2uparrow.png'),
                                    triggered=lambda: self.move_to(absolute=0))
        toolbar.append(movetop_button)
        moveup_button = create_toolbutton(self,
                                    text=self.tr("Move up"),
                                    icon=get_icon('1uparrow.png'),
                                    triggered=lambda: self.move_to(relative=-1))
        toolbar.append(moveup_button)
        movedown_button = create_toolbutton(self,
                                    text=self.tr("Move down"),
                                    icon=get_icon('1downarrow.png'),
                                    triggered=lambda: self.move_to(relative=1))
        toolbar.append(movedown_button)
        movebottom_button = create_toolbutton(self,
                                    text=self.tr("Move to bottom"),
                                    icon=get_icon('2downarrow.png'),
                                    triggered=lambda: self.move_to(absolute=1))
        toolbar.append(movebottom_button)
        self.selection_widgets.extend(toolbar)
        self._add_widgets_to_layout(layout, toolbar)
        return toolbar
    
    def setup_bottom_toolbar(self, layout):
        toolbar = []
        add_button = create_toolbutton(self, text=self.tr("Add path"),
                                       icon=get_icon('edit_add.png'),
                                       triggered=self.add_path)
        toolbar.append(add_button)
        remove_button = create_toolbutton(self, text=self.tr("Remove path"),
                                          icon=get_icon('edit_remove.png'),
                                          triggered=self.remove_path)
        toolbar.append(remove_button)
        self.selection_widgets.append(remove_button)
        self._add_widgets_to_layout(layout, toolbar)
        layout.addStretch(1)
        if os.name == 'nt':
            self.sync_button = create_toolbutton(self,
                  text=self.tr("Synchronize..."),
                  icon=get_icon('synchronize.png'), triggered=self.synchronize,
                  tip=self.tr("Synchronize Spyder's path list with PYTHONPATH "
                              "environment variable"))
            layout.addWidget(self.sync_button)
        return toolbar
    
    def synchronize(self):
        """
        Synchronize Spyder's path list with PYTHONPATH environment variable
        Only apply to: current user, on Windows platforms
        """
        answer = QMessageBox.question(self, self.tr("Synchronize"),
            self.tr("This will synchronize Spyder's path list with "
                    "<b>PYTHONPATH</b> environment variable for current user, "
                    "allowing you to run your Python modules outside Spyder "
                    "without having to configure sys.path. "
                    "<br>Do you want to clear contents of PYTHONPATH before "
                    "adding Spyder's path list?"),
            QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
        if answer == QMessageBox.Cancel:
            return
        elif answer == QMessageBox.Yes:
            remove = True
        else:
            remove = False
        from spyderlib.utils.environ import (get_user_env, set_user_env,
                                             listdict2envdict)
        env = get_user_env()
        if remove:
            ppath = self.pathlist
        else:
            ppath = env.get('PYTHONPATH', [])
            if not isinstance(ppath, list):
                ppath = [ppath]
            ppath = [path for path in ppath if path not in self.pathlist]
            ppath.extend(self.pathlist)
        env['PYTHONPATH'] = ppath
        set_user_env( listdict2envdict(env) )
        
    def get_path_list(self):
        """Return path list"""
        return self.pathlist
        
    def update_list(self):
        """Update path list"""
        self.listwidget.clear()
        for name in self.pathlist:
            item = QListWidgetItem(name)
            item.setIcon(get_std_icon('DirClosedIcon'))
            self.listwidget.addItem(item)
        self.refresh()
        
    def refresh(self, row=None):
        """Refresh widget"""
        for widget in self.selection_widgets:
            widget.setEnabled(self.listwidget.currentItem() is not None)
        not_empty = self.listwidget.count() > 0
        if os.name == 'nt':
            self.sync_button.setEnabled(not_empty)
    
    def move_to(self, absolute=None, relative=None):
        index = self.listwidget.currentRow()
        if absolute is not None:
            if absolute:
                new_index = len(self.pathlist)-1
            else:
                new_index = 0
        else:
            new_index = index + relative        
        new_index = max(0, min(len(self.pathlist)-1, new_index))
        path = self.pathlist.pop(index)
        self.pathlist.insert(new_index, path)
        self.update_list()
        self.listwidget.setCurrentRow(new_index)
        
    def remove_path(self):
        answer = QMessageBox.warning(self, self.tr("Remove path"),
            self.tr("Do you really want to remove selected path?"),
            QMessageBox.Yes | QMessageBox.No)
        if answer == QMessageBox.Yes:
            self.pathlist.pop(self.listwidget.currentRow())
            self.update_list()
    
    def add_path(self):
        self.emit(SIGNAL('redirect_stdio(bool)'), False)
        directory = QFileDialog.getExistingDirectory(self,
                                 self.tr("Select directory"), self.last_path)
        self.emit(SIGNAL('redirect_stdio(bool)'), True)
        if not directory.isEmpty():
            directory = osp.abspath(unicode(directory))
            self.last_path = directory
            if directory in self.pathlist:
                answer = QMessageBox.question(self, self.tr("Add path"),
                    self.tr("This directory is already included in Spyder path "
                            "list.<br>Do you want to move it to the top of "
                            "the list?"),
                    QMessageBox.Yes | QMessageBox.No)
                if answer == QMessageBox.Yes:
                    self.pathlist.remove(directory)
                else:
                    return
            self.pathlist.insert(0, directory)
            self.update_list()
Exemple #30
0
class NotebookSettingsDialog(QDialog):
    """GUI for adjusting notebook settings"""
    def __init__(self, parent=None):
        super(NotebookSettingsDialog, self).__init__(parent)
        #widgets for tab 1
        self.mdExts = QListWidget()
        self.mjEdit = QLineEdit()
        self.moveUp = QPushButton('<<')
        self.moveDown = QPushButton('>>')
        self.configureExtension = QPushButton('Edit Settings for this extension')
        self.tmpdict = deepcopy(self.parent().settings.extcfg)
        
        #widgets for tab 2
        self.fExtEdit = QLineEdit()
        self.attImgEdit = QLineEdit()
        self.attDocEdit = QLineEdit()
        # mandatory button box
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok |
                                          QDialogButtonBox.Cancel)
        
        #tab panels
        tabs = QTabWidget()
        markupTab = QWidget()
        fileExtsTab = QWidget()
        tabs.addTab(markupTab, "Markdown")
        tabs.addTab(fileExtsTab, "File extensions")
        
        #initialization functions
        self.initExtList()
        self.mdExts.setDragDropMode(QAbstractItemView.InternalMove)
        self.mjEdit.setText(self.parent().settings.mathjax)
        self.attImgEdit.setText(', '.join(self.parent().settings.attachmentImage))
        self.attDocEdit.setText(', '.join(self.parent().settings.attachmentDocument))
        self.fExtEdit.setText(self.parent().settings.fileExt)
        
        #set up tab 1
        layout=QGridLayout(markupTab)
        layout.addWidget(QLabel("Markdown extensions"),0,0,1,4)
        layout.addWidget(self.mdExts,1,0,1,4)
        layout.addWidget(self.moveUp,2,0,1,1)
        layout.addWidget(self.moveDown,2,1,1,1)
        layout.addWidget(self.configureExtension,2,2,1,2)
        layout.addWidget(QLabel("MathJax Location"),3,0,1,1)
        layout.addWidget(self.mjEdit,3,1,1,3)
        
        #set up tab 2
        layout=QGridLayout(fileExtsTab)
        layout.addWidget(QLabel("Note file extension"),0,0,1,1)
        layout.addWidget(QLabel("Image file extension"),1,0,1,1)
        layout.addWidget(QLabel("Document file extension"),2,0,1,1)
        layout.addWidget(self.fExtEdit,0,1,1,1)
        layout.addWidget(self.attImgEdit,1,1,1,1)
        layout.addWidget(self.attDocEdit,2,1,1,1)
        
        #put it together
        vlayout = QVBoxLayout(self)
        vlayout.addWidget(tabs)
        vlayout.addWidget(self.buttonBox)

        #setup signal handlers
        self.moveUp.clicked.connect(self.moveItemUp)
        self.configureExtension.clicked.connect(self.configExt)
        self.moveDown.clicked.connect(self.moveItemDown)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def configExt(self, checked=False, ext=None):
        if ext is None:
            ext = self.mdExts.currentItem().text()
        cfg = self.tmpdict.get(ext,[])
        dialog = NotebookExtSettingsDialog(cfg_list=cfg)
        done = dialog.exec()
        if done:
            self.tmpdict[ext] = dialog.configToList()

    def initExtList(self):
        extset=set(self.parent().settings.extensions)
        #for easier performance in checking
        for ext in self.parent().settings.extensions:
            item = QListWidgetItem(ext, self.mdExts)
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setCheckState(Qt.Checked)

        for ext in self.parent().settings.faulty_exts:
            item = QListWidgetItem(ext, self.mdExts)
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setBackground(QBrush(QColor('red')))
            item.setForeground(QBrush(QColor('black')))
            item.setCheckState(Qt.Checked)

        for ext in allMDExtensions():
            if ext in extset: continue
            item = QListWidgetItem(ext, self.mdExts)
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setCheckState(Qt.Unchecked)
            #self.mdExts.addItem(item)

    def moveItemUp(self):
        item = self.mdExts.currentItem()
        row = self.mdExts.currentRow()
        if row != 0:
            # self.mdExts.removeItemWidget(item)
            self.mdExts.takeItem(row)
            self.mdExts.insertItem(row-1, item)
            self.mdExts.setCurrentRow(row-1)

    def moveItemDown(self):
        item = self.mdExts.currentItem()
        row = self.mdExts.currentRow()
        count = self.mdExts.count()
        if row != count-1:
            self.mdExts.takeItem(row)
            self.mdExts.insertItem(row+1, item)
            self.mdExts.setCurrentRow(row+1)


    def accept(self):
        #write to settings first
        msettings = self.parent().settings
        nbsettings = msettings.qsettings
        
        nbsettings.setValue('mathJax', self.mjEdit.text())
        extlist = []
        for i in range(self.mdExts.count()):
            item = self.mdExts.item(i)
            if item.checkState() == Qt.Checked:
                extlist.append(item.text())
        writeListToSettings(nbsettings, 'extensions', extlist)
        writeListToSettings(nbsettings, 'attachmentImage', self.attImgEdit.text().split(", "))
        writeListToSettings(nbsettings, 'attachmentDocument', self.attDocEdit.text().split(", "))
        writeDictToSettings(nbsettings, 'extensionsConfig', self.tmpdict)
        
        #then to memory
        msettings.extensions = extlist
        msettings.mathjax = self.mjEdit.text()
        msettings.attachmentDocument = readListFromSettings(nbsettings, 'attachmentDocument')
        msettings.attachmentImage = readListFromSettings(nbsettings, 'attachmentImage')
        msettings.extcfg.update(self.tmpdict)
        msettings.md = markdown.Markdown(msettings.extensions, extension_configs=msettings.extcfg)
        
        #then make mikidown use these settings NOW
        curitem=self.parent().notesTree.currentItem()
        self.parent().currentItemChangedWrapper(curitem, curitem)
        QDialog.accept(self)
Exemple #31
0
class ConfigDialog(QDialog):
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        self.contents_widget = QListWidget()
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setMinimumWidth(120)
        self.contents_widget.setMaximumWidth(120)
        self.contents_widget.setSpacing(1)

        bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply
                                | QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
        self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"),
                     self.button_clicked)

        self.pages_widget = QStackedWidget()
        self.connect(self.pages_widget, SIGNAL("currentChanged(int)"),
                     self.current_page_changed)

        self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"),
                     self.pages_widget.setCurrentIndex)
        self.contents_widget.setCurrentRow(0)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.contents_widget)
        hlayout.addWidget(self.pages_widget)
        hlayout.setStretch(1, 1)

        btnlayout = QHBoxLayout()
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addLayout(hlayout)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        self.setWindowTitle("Preferences")
        self.setWindowIcon(get_icon("configure.png"))

    def get_current_index(self):
        """Return current page index"""
        return self.contents_widget.currentRow()

    def set_current_index(self, index):
        """Set current page index"""
        self.contents_widget.setCurrentRow(index)

    def accept(self):
        """Reimplement Qt method"""
        for index in range(self.pages_widget.count()):
            configpage = self.pages_widget.widget(index)
            if not configpage.is_valid():
                return
            configpage.apply_changes()
        QDialog.accept(self)

    def button_clicked(self, button):
        if button is self.apply_btn:
            # Apply button was clicked
            configpage = self.pages_widget.currentWidget()
            if not configpage.is_valid():
                return
            configpage.apply_changes()

    def current_page_changed(self, index):
        widget = self.pages_widget.widget(index)
        self.apply_btn.setVisible(widget.apply_callback is not None)
        self.apply_btn.setEnabled(widget.is_modified)

    def add_page(self, widget):
        self.connect(self, SIGNAL('check_settings()'), widget.check_settings)
        self.connect(widget,
                     SIGNAL('show_this_page()'),
                     lambda row=self.contents_widget.count(): self.
                     contents_widget.setCurrentRow(row))
        self.connect(widget, SIGNAL("apply_button_enabled(bool)"),
                     self.apply_btn.setEnabled)
        self.pages_widget.addWidget(widget)
        item = QListWidgetItem(self.contents_widget)
        item.setIcon(widget.get_icon())
        item.setText(widget.get_name())
        item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
        item.setSizeHint(QSize(0, 25))

    def check_all_settings(self):
        """This method is called to check all configuration page settings
        after configuration dialog has been shown"""
        self.emit(SIGNAL('check_settings()'))
Exemple #32
0
class CodeCompletionWidget(QFrame):
    def __init__(self, editor):
        super(CodeCompletionWidget,
              self).__init__(None, Qt.FramelessWindowHint | Qt.ToolTip)
        self._editor = editor
        self.stack_layout = QStackedLayout(self)
        self.stack_layout.setContentsMargins(0, 0, 0, 0)
        self.stack_layout.setSpacing(0)
        self.completion_list = QListWidget()
        self.completion_list.setMinimumHeight(200)
        self.completion_list.setAlternatingRowColors(True)
        self._list_index = self.stack_layout.addWidget(self.completion_list)

        self._icons = {
            'a': resources.IMAGES['attribute'],
            'f': resources.IMAGES['function'],
            'c': resources.IMAGES['class'],
            'm': resources.IMAGES['module']
        }

        self.cc = code_completion.CodeCompletion()
        self._completion_results = {}
        self._prefix = u''
        self.setVisible(False)
        self.source = ''
        self._key_operations = {
            Qt.Key_Up: self._select_previous_row,
            Qt.Key_Down: self._select_next_row,
            Qt.Key_PageUp: (lambda: self._select_previous_row(6)),
            Qt.Key_PageDown: (lambda: self._select_next_row(6)),
            Qt.Key_Right: lambda: None,
            Qt.Key_Left: lambda: None,
            Qt.Key_Enter: self.pre_key_insert_completion,
            Qt.Key_Return: self.pre_key_insert_completion,
            Qt.Key_Tab: self.pre_key_insert_completion,
            Qt.Key_Space: self.hide_completer,
            Qt.Key_Escape: self.hide_completer,
            Qt.Key_Backtab: self.hide_completer,
            Qt.NoModifier: self.hide_completer,
            Qt.ShiftModifier: self.hide_completer,
        }

        desktop = QApplication.instance().desktop()
        self._desktop_geometry = desktop.availableGeometry()

        self.connect(self._editor.document(), SIGNAL("blockCountChanged(int)"),
                     self.update_metadata)

    def _select_next_row(self, move=1):
        new_row = self.completion_list.currentRow() + move
        if new_row < self.completion_list.count():
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(0)
        return True

    def _select_previous_row(self, move=1):
        new_row = self.completion_list.currentRow() - move
        if new_row >= 0:
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(self.completion_list.count() -
                                               move)
        return True

    def update_metadata(self):
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        self.cc.analyze_file('', source)

    def insert_completion(self, insert):
        if insert != self._prefix:
            extra = len(self._prefix) - len(insert)
            self._editor.textCursor().insertText(insert[extra:])
        self.hide_completer()

    def _get_geometry(self):
        cr = self._editor.cursorRect()
        point = self._editor.mapToGlobal(cr.topLeft())
        cr.moveTopLeft(point)
        #Check new position according desktop geometry
        width = (self.completion_list.sizeHintForColumn(0) + \
            self.completion_list.verticalScrollBar().sizeHint().width() + 10)
        height = 200
        orientation = (point.y() + height) < self._desktop_geometry.height()
        if orientation:
            cr.moveTop(cr.bottom())
        cr.setWidth(width)
        cr.setHeight(height)
        if not orientation:
            cr.moveBottom(cr.top())
        xpos = self._desktop_geometry.width() - (point.x() + width)
        if xpos < 0:
            cr.moveLeft(cr.left() + xpos)
        return cr

    def complete(self, results):
        self.add_list_items(results)
        self.completion_list.setCurrentRow(0)
        cr = self._get_geometry()
        self.setGeometry(cr)
        self.completion_list.updateGeometries()
        self.show()

    def add_list_items(self, proposals):
        self.completion_list.clear()
        for p in proposals:
            self.completion_list.addItem(
                QListWidgetItem(
                    QIcon(self._icons.get(p[0],
                                          resources.IMAGES['attribute'])),
                    p[1]))

    def set_completion_prefix(self, prefix, valid=True):
        self._prefix = prefix
        proposals = []
        proposals += [('m', item) \
            for item in self._completion_results.get('modules', []) \
            if item.startswith(prefix)]
        proposals += [('c', item) \
            for item in self._completion_results.get('classes', []) \
            if item.startswith(prefix)]
        proposals += [('a', item) \
            for item in self._completion_results.get('attributes', []) \
            if item.startswith(prefix)]
        proposals += [('f', item) \
            for item in self._completion_results.get('functions', []) \
            if item.startswith(prefix)]
        if proposals and valid:
            self.complete(proposals)
        else:
            self.hide_completer()

    def fill_completer(self):
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        offset = self._editor.textCursor().position()
        results = self.cc.get_completion(source, offset)
        self._completion_results = results
        prefix = self._editor._text_under_cursor()
        self.set_completion_prefix(prefix)

    def hide_completer(self):
        self._prefix = ''
        self.hide()

    def pre_key_insert_completion(self):
        insert = unicode(self.completion_list.currentItem().text())
        self.insert_completion(insert)
        self.hide_completer()
        return True

    def process_pre_key_event(self, event):
        if not self.isVisible() or self._editor.lang != "python":
            return False
        skip = self._key_operations.get(event.key(), lambda: False)()
        self._key_operations.get(event.modifiers(), lambda: False)()
        if skip is None:
            skip = False
        return skip

    def process_post_key_event(self, event):
        if not settings.CODE_COMPLETION or self._editor.lang != "python":
            return
        if self.isVisible():
            source = self._editor.get_text()
            source = source.encode(self._editor.encoding)
            offset = self._editor.textCursor().position()
            prefix, valid = self.cc.get_prefix(source, offset)
            self.set_completion_prefix(prefix, valid)
            self.completion_list.setCurrentRow(0)
        if event.key() == Qt.Key_Period  or (event.key() == Qt.Key_Space and \
           event.modifiers() == Qt.ControlModifier):
            self.fill_completer()
Exemple #33
0
class ListEdit(QWidget):
    """A widget to edit a list of items (e.g. a list of directories)."""

    # emitted when anything changed in the listbox.
    changed = pyqtSignal()

    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        layout = QGridLayout(self)
        self.setLayout(layout)

        self.addButton = QPushButton(icons.get('list-add'), '')
        self.editButton = QPushButton(icons.get('document-edit'), '')
        self.removeButton = QPushButton(icons.get('list-remove'), '')
        self.listBox = QListWidget()

        layout.setContentsMargins(1, 1, 1, 1)
        layout.setSpacing(0)
        layout.addWidget(self.listBox, 0, 0, 4, 1)
        layout.addWidget(self.addButton, 0, 1)
        layout.addWidget(self.editButton, 1, 1)
        layout.addWidget(self.removeButton, 2, 1)

        @self.addButton.clicked.connect
        def addClicked():
            item = self.createItem()
            if self.openEditor(item):
                self.addItem(item)

        @self.editButton.clicked.connect
        def editClicked():
            item = self.listBox.currentItem()
            item and self.editItem(item)

        @self.removeButton.clicked.connect
        def removeClicked():
            item = self.listBox.currentItem()
            if item:
                self.removeItem(item)

        @self.listBox.itemDoubleClicked.connect
        def itemDoubleClicked(item):
            item and self.editItem(item)

        self.listBox.model().layoutChanged.connect(self.changed)

        def updateSelection():
            selected = bool(self.listBox.currentItem())
            self.editButton.setEnabled(selected)
            self.removeButton.setEnabled(selected)

        self.changed.connect(updateSelection)
        self.listBox.itemSelectionChanged.connect(updateSelection)
        updateSelection()
        app.translateUI(self)

    def translateUI(self):
        self.addButton.setText(_("&Add..."))
        self.editButton.setText(_("&Edit..."))
        self.removeButton.setText(_("&Remove"))

    def createItem(self):
        return QListWidgetItem()

    def addItem(self, item):
        self.listBox.addItem(item)
        self.itemChanged(item)
        self.changed.emit()

    def removeItem(self, item):
        self.listBox.takeItem(self.listBox.row(item))
        self.changed.emit()

    def editItem(self, item):
        if self.openEditor(item):
            self.itemChanged(item)
            self.changed.emit()

    def setCurrentItem(self, item):
        self.listBox.setCurrentItem(item)

    def setCurrentRow(self, row):
        self.listBox.setCurrentRow(row)

    def openEditor(self, item):
        """Opens an editor (dialog) for the item.
        
        Returns True if the dialog was accepted and the item edited.
        Returns False if the dialog was cancelled (the item must be left
        unedited).
        """
        pass

    def itemChanged(self, item):
        """Called after an item has been added or edited.
        
        Re-implement to do something at this moment if needed, e.g. alter the
        text or display of other items.
        """
        pass

    def setValue(self, strings):
        """Sets the listbox to a list of strings."""
        self.listBox.clear()
        self.listBox.addItems(strings)
        self.changed.emit()

    def value(self):
        """Returns the list of paths in the listbox."""
        return [
            self.listBox.item(i).text() for i in range(self.listBox.count())
        ]

    def setItems(self, items):
        """Sets the listbox to a list of items."""
        self.listBox.clear()
        for item in items:
            self.listBox.addItem(item)
            self.itemChanged(item)
        self.changed.emit()

    def items(self):
        """Returns the list of items in the listbox."""
        return [self.listBox.item(i) for i in range(self.listBox.count())]

    def clear(self):
        """Clears the listbox."""
        self.listBox.clear()
        self.changed.emit()
Exemple #34
0
class GraphDialog(QDialog):

    edit_patterns = 0
    edit_curves = 1

    titles = {edit_patterns: 'Pattern editor', edit_curves: 'Curve editor'}

    labels = {edit_patterns: 'Patterns', edit_curves: 'Curves'}

    def __init__(self, dockwidget, parent, params, edit_type):

        QDialog.__init__(self, parent)
        main_lay = QVBoxLayout(self)
        self.dockwidget = dockwidget
        self.params = params
        self.edit_type = edit_type

        self.x_label = ''
        self.y_label = ''

        self.setMinimumWidth(600)
        self.setMinimumHeight(400)

        self.setWindowTitle(self.titles[edit_type])  # TODO: softcode
        self.setWindowModality(QtCore.Qt.ApplicationModal)

        self.current = None

        self.current_saved = False

        # File
        self.lbl_file = QLabel('File:')
        self.fra_file = QFrame()
        self.fra_file.setContentsMargins(0, 0, 0, 0)
        fra_file_lay = QHBoxLayout(self.fra_file)

        if edit_type == self.edit_patterns:
            self.txt_file = QLineEdit(self.params.patterns_file)
        elif edit_type == self.edit_curves:
            self.txt_file = QLineEdit(self.params.curves_file)

        self.txt_file.setReadOnly(True)
        self.txt_file.setAlignment(QtCore.Qt.AlignLeft
                                   | QtCore.Qt.AlignVCenter)
        self.txt_file.setSizePolicy(QSizePolicy.MinimumExpanding,
                                    QSizePolicy.Minimum)
        fra_file_lay.addWidget(self.txt_file)
        self.btn_file = QPushButton('Change')  # TODO: softcode
        self.btn_file.clicked.connect(self.import_file)
        fra_file_lay.addWidget(self.btn_file)
        fra_file_lay.setContentsMargins(0, 0, 0, 0)

        self.lbl_list = QLabel(self.labels[edit_type])
        self.lst_list = QListWidget()
        self.lst_list.currentItemChanged.connect(self.list_item_changed)

        # Form
        self.fra_form = QFrame()
        fra_form1_lay = QFormLayout(self.fra_form)
        fra_form1_lay.setContentsMargins(0, 0, 0, 0)
        fra_form1_lay.addRow(self.lbl_list, self.lst_list)

        # Buttons
        self.fra_buttons = QFrame()
        fra_buttons_lay = QHBoxLayout(self.fra_buttons)
        fra_buttons_lay.setContentsMargins(0, 0, 0, 0)

        if self.edit_type == self.edit_patterns:
            ele_name = 'pattern'
        elif self.edit_type == self.edit_curves:
            ele_name = 'curve'

        self.btn_new = QPushButton('New ' + ele_name)  # TODO: softcode
        self.btn_new.clicked.connect(self.new_element)
        fra_buttons_lay.addWidget(self.btn_new)

        self.btn_import = QPushButton('Import ' + ele_name +
                                      's')  # TODO: softcode
        self.btn_import.clicked.connect(self.import_file)
        fra_buttons_lay.addWidget(self.btn_import)

        self.btn_save = QPushButton('Save current ' +
                                    ele_name)  # TODO: softcode
        self.btn_save.clicked.connect(self.save)
        fra_buttons_lay.addWidget(self.btn_save)

        self.btn_del = QPushButton('Delete current ' +
                                   ele_name)  # TODO: softcode
        self.btn_del.clicked.connect(self.del_item)
        fra_buttons_lay.addWidget(self.btn_del)

        # ID
        self.lbl_id = QLabel('ID:')
        self.txt_id = QLineEdit()
        self.txt_id.setSizePolicy(QSizePolicy.Maximum,
                                  QSizePolicy.MinimumExpanding)
        self.lbl_desc = QLabel('Desc.:')
        self.txt_desc = QLineEdit()

        self.fra_id = QFrame()
        fra_id_lay = QHBoxLayout(self.fra_id)
        fra_id_lay.addWidget(self.lbl_id)
        fra_id_lay.addWidget(self.txt_id)
        fra_id_lay.addWidget(self.lbl_desc)
        fra_id_lay.addWidget(self.txt_desc)

        # Table form
        self.table = QTableWidget(self)
        self.rows_nr = 24
        self.cols_nr = 2
        self.table.setRowCount(self.rows_nr)
        self.table.setColumnCount(self.cols_nr)
        self.table.verticalHeader().setVisible(False)

        # Initialize empty table
        self.clear_table()

        self.table.itemChanged.connect(self.data_changed)

        self.fra_table = QFrame()
        fra_table_lay = QVBoxLayout(self.fra_table)
        fra_table_lay.setContentsMargins(0, 0, 0, 0)

        if edit_type == self.edit_curves:
            self.fra_pump_type = QFrame()
            fra_pump_type_lay = QFormLayout(self.fra_pump_type)

            self.lbl_pump_type = QLabel('Curve type:')  # TODO: softcode
            self.cbo_pump_type = QComboBox()

            for key, name in Curve.type_names.iteritems():
                self.cbo_pump_type.addItem(name, key)

            fra_pump_type_lay.addRow(self.lbl_pump_type, self.cbo_pump_type)

            fra_table_lay.addWidget(self.fra_pump_type)

            self.cbo_pump_type.activated.connect(self.cbo_pump_type_activated)

        fra_table_lay.addWidget(self.table)
        self.btn_add_row = QPushButton('Add row')
        self.btn_add_row.clicked.connect(self.add_row)
        fra_table_lay.addWidget(self.btn_add_row)

        # Graph canvas
        self.fra_graph = QFrame()
        self.static_canvas = StaticMplCanvas(self.fra_graph,
                                             width=5,
                                             height=4,
                                             dpi=100)
        fra_graph_lay = QVBoxLayout(self.fra_graph)
        fra_graph_lay.addWidget(self.static_canvas)

        # Top frame
        self.fra_top = QFrame()
        fra_top_lay = QVBoxLayout(self.fra_top)
        fra_top_lay.addWidget(self.fra_form)
        fra_top_lay.addWidget(self.fra_id)
        fra_top_lay.addWidget(self.fra_buttons)

        # Bottom frame
        self.fra_bottom = QFrame()
        fra_bottom_lay = QHBoxLayout(self.fra_bottom)
        fra_bottom_lay.addWidget(self.fra_table)
        fra_bottom_lay.addWidget(self.fra_graph)

        # Main
        main_lay.addWidget(self.fra_top)
        main_lay.addWidget(self.fra_bottom)

        # Get existing patterns/curves
        self.need_to_update_graph = False
        if self.edit_type == self.edit_patterns:
            for pattern_id, pattern in self.params.patterns.iteritems():
                self.lst_list.addItem(pattern.id)

        elif self.edit_type == self.edit_curves:
            for curve_id, curve in self.params.curves.iteritems():
                self.lst_list.addItem(curve.id)

        if self.lst_list.count() > 0:
            self.lst_list.setCurrentRow(0)
            self.txt_id.setEnabled(True)
            self.txt_desc.setEnabled(True)
            self.btn_save.setEnabled(True)
            self.btn_del.setEnabled(True)
            self.table.setEnabled(True)
            self.table.setEditTriggers(QAbstractItemView.AllEditTriggers)
        else:
            self.txt_id.setEnabled(False)
            self.txt_desc.setEnabled(False)
            self.btn_save.setEnabled(False)
            self.btn_del.setEnabled(False)
            self.table.setEnabled(False)
            self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)

        self.new_dialog = None
        self.need_to_update_graph = True

    def cbo_pump_type_activated(self):
        self.update_table_headers()
        self.update_graph()

    def add_row(self):
        row_pos = self.table.rowCount()
        self.table.insertRow(row_pos)
        col = 0
        item = QTableWidgetItem(str(row_pos))

        if self.edit_type == self.edit_patterns:
            self.table.setItem(row_pos, col, item)
            item.setFlags(QtCore.Qt.ItemIsSelectable)

    def setVisible(self, bool):
        QDialog.setVisible(self, bool)

        self.update_table_headers()
        self.update_graph()

    def list_item_changed(self):

        p_index = self.lst_list.currentRow()

        flags = Qt.ItemFlags()
        flags != Qt.ItemIsEnabled

        # Clear table
        self.clear_table()

        self.need_to_update_graph = False
        if p_index >= 0:

            self.table.setRowCount(0)

            if self.edit_type == self.edit_patterns:
                self.current = self.params.patterns[
                    self.lst_list.currentItem().text()]
                for v in range(len(self.current.values)):

                    row_pos = self.table.rowCount()
                    self.table.insertRow(row_pos)

                    item = QTableWidgetItem(str(v))
                    item.setFlags(flags)
                    self.table.setItem(v, 0, item)
                    self.table.setItem(
                        v, 1, QTableWidgetItem(str(self.current.values[v])))

            elif self.edit_type == self.edit_curves:
                self.current = self.params.curves[
                    self.lst_list.currentItem().text()]
                for v in range(len(self.current.xs)):

                    row_pos = self.table.rowCount()
                    self.table.insertRow(row_pos)

                    self.table.setItem(
                        v, 0, QTableWidgetItem(str(self.current.xs[v])))
                    self.table.setItem(
                        v, 1, QTableWidgetItem(str(self.current.ys[v])))

                curve_type = self.current.type
                self.cbo_pump_type.setCurrentIndex(curve_type)

            # Update GUI
            self.txt_id.setText(self.current.id)
            self.txt_desc.setText(self.current.desc)

            self.update_table_headers()

            # Update graph
            self.need_to_update_graph = True
            self.update_graph()

        else:

            # No curves
            self.txt_id.setText('')
            self.txt_desc.setText('')

            # Update table and chart
            self.need_to_update_graph = False
            for v in range(self.table.columnCount()):
                self.table.setItem(v, 1, QTableWidgetItem(''))

            self.need_to_update_graph = True
            self.update_graph()

    def import_file(self):

        config_file = ConfigFile(Parameters.config_file_path)

        directory = None
        if self.edit_type == GraphDialog.edit_curves:
            directory = self.params.last_curves_dir
        elif self.edit_type == GraphDialog.edit_patterns:
            directory = self.params.last_patterns_dir

        if directory is None:
            directory = self.params.last_project_dir

        file_path = QFileDialog.getOpenFileName(self, 'Select file', directory,
                                                'Files (*.txt *.inp)')

        if file_path is None or file_path == '':
            return
        else:
            if self.edit_type == GraphDialog.edit_patterns:
                # Save patterns file path in configuration file
                config_file.set_patterns_file_path(file_path)
                Parameters.patterns_file = file_path
            elif self.edit_type == GraphDialog.edit_curves:
                # Save curve file path in configuration file
                config_file.set_curves_file_path(file_path)
                Parameters.curves_file = file_path

        self.read(file_path)

    def read(self, file_path):

        self.lst_list.clear()

        if self.edit_type == self.edit_patterns:
            InpFile.read_patterns(self.params, file_path)
            for pattern_id, pattern in self.params.patterns.iteritems():
                # desc = ' (' + pattern.desc + ')' if pattern.desc is not None else ''
                self.lst_list.addItem(pattern.id)
                self.params.patterns[pattern.id] = pattern

        elif self.edit_type == self.edit_curves:
            InpFile.read_curves(self.params, file_path)
            for curve_id, curve in self.params.curves.iteritems():
                # desc = ' (' + curve.desc + ')' if curve.desc is not None else ''
                self.lst_list.addItem(curve.id)
                self.params.curves[curve.id] = curve

        if self.lst_list.count() > 0:
            self.lst_list.setCurrentRow(0)

    def new_element(self):

        old_ids = []
        if self.edit_type == self.edit_patterns:
            for pattern in self.params.patterns.itervalues():
                old_ids.append(pattern.id)
        elif self.edit_type == self.edit_curves:
            for curve in self.params.curves.itervalues():
                old_ids.append(curve.id)
        self.new_dialog = NewIdDialog(self, old_ids)
        self.new_dialog.exec_()

        new_id = self.new_dialog.get_newid()
        description = self.new_dialog.get_description()
        if new_id is None or description is None:
            return

        if self.edit_type == self.edit_patterns:
            new_pattern = Pattern(new_id, description)
            self.params.patterns[new_pattern.id] = new_pattern
            self.lst_list.addItem(new_pattern.id)
        elif self.edit_type == self.edit_curves:
            curve_type = self.cbo_pump_type.itemData(
                self.cbo_pump_type.currentIndex())
            new_curve = Curve(new_id, curve_type, desc=description)
            self.params.curves[new_curve.id] = new_curve
            self.lst_list.addItem(new_curve.id)

        self.lst_list.setCurrentRow(self.lst_list.count() - 1)

        self.txt_id.setText(new_id)
        self.txt_desc.setText(description)

        # Clear table
        self.clear_table()
        self.static_canvas.axes.clear()

        self.txt_id.setEnabled(True)
        self.txt_desc.setEnabled(True)
        self.btn_save.setEnabled(True)
        self.btn_del.setEnabled(True)
        self.table.setEnabled(True)
        self.table.setEditTriggers(QAbstractItemView.AllEditTriggers)

    def save(self):

        self.need_to_update_graph = False

        # Check for ID
        if not self.txt_id.text():
            QMessageBox.warning(
                self,
                Parameters.plug_in_name,
                u'Please specify the ID.',  # TODO: softcode
                QMessageBox.Ok)
            return

        if self.edit_type == GraphDialog.edit_patterns:
            values = []
            for row in range(self.table.rowCount()):
                item = self.table.item(row, 1)
                if item is not None and item.text() != '':
                    values.append(self.from_item_to_val(item))
                else:
                    values.append('0')

            pattern = Pattern(self.txt_id.text(), self.txt_desc.text(), values)

            old_patterns = self.params.patterns
            old_patterns[pattern.id] = pattern
            self.params.patterns = old_patterns

            self.lst_list.currentItem().setText(pattern.id)

        elif self.edit_type == GraphDialog.edit_curves:

            # Check for ID unique
            xs = []
            ys = []
            for row in range(self.table.rowCount()):
                item_x = self.table.item(row, 0)
                item_y = self.table.item(row, 1)

                if item_x.text() != '' and item_y.text() != '':
                    xs.append(self.from_item_to_val(item_x))
                    ys.append(self.from_item_to_val(item_y))

            curve_type = self.cbo_pump_type.itemData(
                self.cbo_pump_type.currentIndex())
            curve = Curve(self.txt_id.text(), curve_type, self.txt_desc.text())
            for v in range(len(xs)):
                curve.append_xy(xs[v], ys[v])

            old_curves = self.params.curves
            old_curves[curve.id] = curve
            self.params.curves = old_curves

            self.lst_list.currentItem().setText(curve.id)

            # Update GUI
            self.dockwidget.update_curves_combo()

        # self.read()
        self.need_to_update_graph = True

    def clear_table(self):

        self.need_to_update_graph = False
        for r in range(self.table.rowCount()):
            self.table.setItem(r, 0, QTableWidgetItem(None))
            self.table.setItem(r, 1, QTableWidgetItem(None))

        for row in range(self.rows_nr):
            for col in range(self.cols_nr):
                if self.edit_type == self.edit_patterns:
                    if col == 0:
                        item = QTableWidgetItem(str(row))
                        self.table.setItem(row, col, item)
                        item.setFlags(QtCore.Qt.ItemIsSelectable)
                    # elif col == 1 and row == 0:
                    #     item = QTableWidgetItem(str(1))
                    #     self.table.setItem(row, col, item)
                    #     item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)

                # elif self.edit_type == self.edit_curves:
                # if row == 0:
                # item = QTableWidgetItem(str(0))
                # self.table.setItem(row, 0, item)
                # item = QTableWidgetItem(str(1))
                # self.table.setItem(row, 1, item)
                # item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
        self.need_to_update_graph = True

    def del_item(self):
        selected_row = self.lst_list.currentRow()
        name = self.lst_list.currentItem().text()
        if selected_row < 0:
            return

        self.lst_list.takeItem(selected_row)
        if self.lst_list.count() == 0:
            self.txt_id.setEnabled(False)
            self.txt_desc.setEnabled(False)
            self.btn_save.setEnabled(False)
            self.btn_del.setEnabled(False)
            self.table.setEnabled(False)
            self.table.setEditTriggers(QAbstractItemView.NoEditTriggers)

        if self.edit_type == GraphDialog.edit_curves:
            del self.params.curves[name]
            # Update GUI
            self.dockwidget.update_curves_combo()
        elif self.edit_type == GraphDialog.edit_patterns:
            del self.params.patterns[name]
            # Update GUI
            self.dockwidget.update_patterns_combo()

    def data_changed(self):

        if self.need_to_update_graph:
            self.update_graph()

    def update_table_headers(self):
        if self.edit_type == self.edit_patterns:
            self.x_label = 'Time period'
            self.y_label = 'Multiplier'
        elif self.edit_type == self.edit_curves:
            cbo_data = self.cbo_pump_type.itemData(
                self.cbo_pump_type.currentIndex())
            if cbo_data == Curve.type_efficiency:
                self.x_label = 'Flow ' + '[' + self.params.options.flow_units + ']'
                self.y_label = 'Efficiency ' + '[' + self.params.options.units_deltaz[
                    self.params.options.units] + ']'
            if cbo_data == Curve.type_headloss:
                self.x_label = 'Flow ' + '[' + self.params.options.flow_units + ']'
                self.y_label = 'Headloss ' + '[' + self.params.options.units_deltaz[
                    self.params.options.units] + ']'
            if cbo_data == Curve.type_pump:
                self.x_label = 'Flow ' + '[' + self.params.options.flow_units + ']'
                self.y_label = 'Head ' + '[' + self.params.options.units_deltaz[
                    self.params.options.units] + ']'
            if cbo_data == Curve.type_volume:
                self.x_label = 'Height ' + '[' + self.params.options.flow_units + ']'
                self.y_label = 'Volume ' + '[' + self.params.options.units_deltaz[
                    self.params.options.units] + ']'

        self.table.setHorizontalHeaderLabels([self.x_label,
                                              self.y_label])  # TODO: softcode

    def update_graph(self):

        if not self.need_to_update_graph:
            return

        xs = []
        ys = []

        for row in range(self.table.rowCount()):
            item = self.table.item(row, 0)
            x = self.from_item_to_val(item)
            item = self.table.item(row, 1)
            y = self.from_item_to_val(item)

            if x is not None:
                xs.append(float(x))
            if y is not None:
                ys.append(float(y))

        if len(xs) == 0 or len(ys) == 0:
            self.static_canvas.clear()
            return

        xys_t = zip(xs, ys)
        xys_t.sort()

        xys = zip(*xys_t)
        xs = xys[0]
        ys = xys[1]

        if self.edit_type == self.edit_patterns:
            y_axis_label = 'Mult. avg.: ' + '{0:.2f}'.format(
                (numpy.average(ys)))
            self.static_canvas.draw_bars_graph(
                ys,
                time_period=self.params.times.pattern_timestep,
                y_axes_label=y_axis_label)

        elif self.edit_type == self.edit_curves:

            # Account for different types of curves
            cbo_data = self.cbo_pump_type.itemData(
                self.cbo_pump_type.currentIndex())

            series_length = min(len(xs), len(ys))

            # Need to account for different types of curves
            if cbo_data == Curve.type_efficiency or cbo_data == Curve.type_headloss or cbo_data == Curve.type_volume:
                self.static_canvas.draw_line_graph(xs[:series_length],
                                                   ys[:series_length],
                                                   self.x_label, self.y_label)

            elif cbo_data == Curve.type_pump:
                if series_length == 1 or series_length == 3:
                    if series_length == 1:
                        # 3 curve points
                        curve_xs = [0, xs[0], xs[0] * 2]
                        curve_ys = [ys[0] * 1.33, ys[0], 0]
                        # y = a * x^2 + b * x + c

                    elif series_length == 3:
                        # 3 curve points
                        curve_xs = [xs[0], xs[1], xs[2]]
                        curve_ys = [ys[0], ys[1], ys[2]]

                    (a, b, c) = numpy.polyfit(curve_xs, curve_ys, 2)

                    # Create a few interpolated values
                    interp_xs = []
                    interp_ys = []
                    n_vals = 30
                    for v in range(n_vals + 1):
                        x = (curve_xs[2] - curve_xs[0]) / n_vals * v
                        interp_xs.append(x)
                        y = a * x**2 + b * x + c
                        interp_ys.append(y)

                    self.static_canvas.draw_line_graph(interp_xs, interp_ys,
                                                       self.x_label,
                                                       self.y_label)

                else:
                    self.static_canvas.draw_line_graph(xs[:series_length],
                                                       ys[:series_length],
                                                       self.x_label,
                                                       self.y_label)

    def from_item_to_val(self, item):

        if item is None:
            value = None
        else:
            value = item.text()
        try:
            value = float(value)
            value = max(value, 0)

        except:
            value = None

        return value
Exemple #35
0
class NotebookSettingsDialog(QDialog):
    """GUI for adjusting notebook settings"""
    def __init__(self, parent=None):
        super(NotebookSettingsDialog, self).__init__(parent)
        #widgets for tab 1
        self.mdExts = QListWidget()
        self.mjEdit = QLineEdit()
        self.moveUp = QPushButton('<<')
        self.moveDown = QPushButton('>>')
        self.configureExtension = QPushButton(
            'Edit Settings for this extension')
        self.tmpdict = deepcopy(self.parent().settings.extcfg)

        #widgets for tab 2
        self.fExtEdit = QLineEdit()
        self.attImgEdit = QLineEdit()
        self.attDocEdit = QLineEdit()
        # mandatory button box
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)

        #tab panels
        tabs = QTabWidget()
        markupTab = QWidget()
        fileExtsTab = QWidget()
        tabs.addTab(markupTab, "Markdown")
        tabs.addTab(fileExtsTab, "File extensions")

        #initialization functions
        self.initExtList()
        self.mdExts.setDragDropMode(QAbstractItemView.InternalMove)
        self.mjEdit.setText(self.parent().settings.mathjax)
        self.attImgEdit.setText(', '.join(
            self.parent().settings.attachmentImage))
        self.attDocEdit.setText(', '.join(
            self.parent().settings.attachmentDocument))
        self.fExtEdit.setText(self.parent().settings.fileExt)

        #set up tab 1
        layout = QGridLayout(markupTab)
        layout.addWidget(QLabel("Markdown extensions"), 0, 0, 1, 4)
        layout.addWidget(self.mdExts, 1, 0, 1, 4)
        layout.addWidget(self.moveUp, 2, 0, 1, 1)
        layout.addWidget(self.moveDown, 2, 1, 1, 1)
        layout.addWidget(self.configureExtension, 2, 2, 1, 2)
        layout.addWidget(QLabel("MathJax Location"), 3, 0, 1, 1)
        layout.addWidget(self.mjEdit, 3, 1, 1, 3)

        #set up tab 2
        layout = QGridLayout(fileExtsTab)
        layout.addWidget(QLabel("Note file extension"), 0, 0, 1, 1)
        layout.addWidget(QLabel("Image file extension"), 1, 0, 1, 1)
        layout.addWidget(QLabel("Document file extension"), 2, 0, 1, 1)
        layout.addWidget(self.fExtEdit, 0, 1, 1, 1)
        layout.addWidget(self.attImgEdit, 1, 1, 1, 1)
        layout.addWidget(self.attDocEdit, 2, 1, 1, 1)

        #put it together
        vlayout = QVBoxLayout(self)
        vlayout.addWidget(tabs)
        vlayout.addWidget(self.buttonBox)

        #setup signal handlers
        self.moveUp.clicked.connect(self.moveItemUp)
        self.configureExtension.clicked.connect(self.configExt)
        self.moveDown.clicked.connect(self.moveItemDown)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def configExt(self, checked=False, ext=None):
        if ext is None:
            ext = self.mdExts.currentItem().text()
        cfg = self.tmpdict.get(ext, [])
        dialog = NotebookExtSettingsDialog(cfg_list=cfg)
        done = dialog.exec()
        if done:
            self.tmpdict[ext] = dialog.configToList()

    def initExtList(self):
        extset = set(self.parent().settings.extensions)
        #for easier performance in checking
        for ext in self.parent().settings.extensions:
            item = QListWidgetItem(ext, self.mdExts)
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setCheckState(Qt.Checked)

        for ext in self.parent().settings.faulty_exts:
            item = QListWidgetItem(ext, self.mdExts)
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setBackground(QBrush(QColor('red')))
            item.setForeground(QBrush(QColor('black')))
            item.setCheckState(Qt.Checked)

        for ext in allMDExtensions():
            if ext in extset: continue
            item = QListWidgetItem(ext, self.mdExts)
            item.setFlags(item.flags() | Qt.ItemIsUserCheckable)
            item.setCheckState(Qt.Unchecked)
            #self.mdExts.addItem(item)

    def moveItemUp(self):
        item = self.mdExts.currentItem()
        row = self.mdExts.currentRow()
        if row != 0:
            # self.mdExts.removeItemWidget(item)
            self.mdExts.takeItem(row)
            self.mdExts.insertItem(row - 1, item)
            self.mdExts.setCurrentRow(row - 1)

    def moveItemDown(self):
        item = self.mdExts.currentItem()
        row = self.mdExts.currentRow()
        count = self.mdExts.count()
        if row != count - 1:
            self.mdExts.takeItem(row)
            self.mdExts.insertItem(row + 1, item)
            self.mdExts.setCurrentRow(row + 1)

    def accept(self):
        #write to settings first
        msettings = self.parent().settings
        nbsettings = msettings.qsettings

        nbsettings.setValue('mathJax', self.mjEdit.text())
        extlist = []
        for i in range(self.mdExts.count()):
            item = self.mdExts.item(i)
            if item.checkState() == Qt.Checked:
                extlist.append(item.text())
        writeListToSettings(nbsettings, 'extensions', extlist)
        writeListToSettings(nbsettings, 'attachmentImage',
                            self.attImgEdit.text().split(", "))
        writeListToSettings(nbsettings, 'attachmentDocument',
                            self.attDocEdit.text().split(", "))
        writeDictToSettings(nbsettings, 'extensionsConfig', self.tmpdict)

        #then to memory
        msettings.extensions = extlist
        msettings.mathjax = self.mjEdit.text()
        msettings.attachmentDocument = readListFromSettings(
            nbsettings, 'attachmentDocument')
        msettings.attachmentImage = readListFromSettings(
            nbsettings, 'attachmentImage')
        msettings.extcfg.update(self.tmpdict)
        msettings.md = markdown.Markdown(msettings.extensions,
                                         extension_configs=msettings.extcfg)

        #then make mikidown use these settings NOW
        curitem = self.parent().notesTree.currentItem()
        self.parent().currentItemChangedWrapper(curitem, curitem)
        QDialog.accept(self)
class WellExportDialog(QDialog):
    def __init__(self):
        super(WellExportDialog, self).__init__()
        self.resize(400, 300)
        self.initUI()
        self.export_Button.clicked.connect(self.export_well)
        self.button_box.rejected.connect(self.close)
        self.select_Button.clicked.connect(self.select_file)
        self.well_comboBox.currentIndexChanged.connect(
            self.populate_log_listWidget)

        self.update_well_comboBox()

    def initUI(self):
        self.setWindowIcon(QIcon(':/icon/export'))
        self.setWindowTitle("Export Well")
        self.layout = QGridLayout(self)
        # add QLabel
        self.label_0 = QLabel(self)
        self.label_0.setGeometry(QRect(0, 24, 31, 20))
        self.label_0.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                  | Qt.AlignVCenter)
        self.label_0.setText("Well to export:")
        self.layout.addWidget(self.label_0, 0, 0)
        # add QComboBox
        self.well_comboBox = QComboBox(self)
        self.well_comboBox.setGeometry(QRect(10, 10, 101, 24))
        self.layout.addWidget(self.well_comboBox, 0, 1, 1, 1)
        # add QCheckBox
        self.checkbox = QCheckBox(self)
        self.checkbox.setText("Full LAS")
        self.checkbox.setCheckState(Qt.Unchecked)
        self.layout.addWidget(self.checkbox, 0, 2)
        # add QListWidget
        self.logs_listWidget = QListWidget(self)
        self.logs_listWidget.setGeometry(QRect(0, 0, 101, 201))
        # self.well_comboBox.setMaximumHeight(151)
        self.layout.addWidget(self.logs_listWidget, 1, 1)
        # add QLabel
        self.label_1 = QLabel(self)
        self.label_1.setGeometry(QRect(0, 24, 31, 20))
        self.label_1.setAlignment(Qt.AlignRight | Qt.AlignTrailing
                                  | Qt.AlignVCenter)
        self.label_1.setText("Output File:")
        self.layout.addWidget(self.label_1, 2, 0)
        # add QLineEdit
        self.file_path_lineEdit = QLineEdit(self)
        self.file_path_lineEdit.setGeometry(QRect(50, 24, 81, 20))
        self.layout.addWidget(self.file_path_lineEdit, 2, 1)
        # add Button
        self.select_Button = QPushButton(self)
        self.select_Button.setMaximumSize(QSize(61, 24))
        self.select_Button.setText("Select")
        self.layout.addWidget(self.select_Button, 2, 2)
        # add QDialogButtonBox
        self.button_box = QDialogButtonBox(self)
        self.export_Button = self.button_box.addButton(
            "Export", QDialogButtonBox.ApplyRole)
        self.button_box.addButton(QDialogButtonBox.Cancel)
        self.layout.addWidget(self.button_box, 3, 0, 1, 3)

    def update_well_comboBox(self):
        survey_file = CONF.survey_dir / '.survey'
        if survey_file.exists():
            dnames = get_data_files(CONF.well_dir)
            self.well_comboBox.addItems(dnames)

    def populate_log_listWidget(self):
        self.logs_listWidget.clear()
        well = ppp.Well(
            str(CONF.well_dir /
                ".{}".format(self.well_comboBox.currentText())))
        # self.logs_listWidget.addItems(well.logs)
        for name in well.logs:
            new_item = QListWidgetItem(name, self.logs_listWidget)
            new_item.setFlags(new_item.flags() | Qt.ItemIsUserCheckable)
            new_item.setCheckState(Qt.Unchecked)

    def export_well(self):
        file_name = str(self.file_path_lineEdit.text())
        if not file_name:
            QMessageBox().information(self, "Info",
                                      "Please select ouput file.")
            pass
        else:
            well = well = ppp.Well(
                str(CONF.well_dir /
                    ".{}".format(self.well_comboBox.currentText())))
            logs_to_export = []
            for i in range(self.logs_listWidget.count()):
                item = self.logs_listWidget.item(i)
                if item.checkState() == Qt.Checked:
                    logs_to_export.append(str(item.text()))
            full = True if self.checkbox.checkState() == Qt.Checked \
                else False
            well.export(file_name, logs_to_export, full)
            QMessageBox().information(self, "Info", "Succeed!")

    def select_file(self):
        fl = QFileDialog.getSaveFileName(self, 'Save File', str(CONF.well_dir))
        self.file_path_lineEdit.setText(fl)
class RunsDialog(QtHelper.EnhancedQDialog):
    """
    Runs several dialog
    """
    RefreshRepository = pyqtSignal(str)
    def __init__(self, dialogName, parent = None, iRepo=None, lRepo=None, rRepo=None):
        """
        Constructor
        """
        QtHelper.EnhancedQDialog.__init__(self, parent)

        self.name = self.tr("Prepare a group of runs")
        self.projectReady = False
        self.iRepo = iRepo
        self.lRepo = lRepo
        self.rRepo = rRepo

        self.createDialog()
        self.createConnections()

    def createDialog(self):
        """
        Create qt dialog
        """
        self.setWindowTitle( self.name )

        mainLayout = QHBoxLayout()
        layoutTests = QHBoxLayout()
        layoutRepoTest = QVBoxLayout()

        self.prjCombo = QComboBox(self)
        self.prjCombo.setEnabled(False)

        self.repoTests = QTreeWidget(self)
        self.repoTests.setFrameShape(QFrame.NoFrame)
        if USE_PYQT5:
            self.repoTests.header().setSectionResizeMode(QHeaderView.Stretch)
        else:
            self.repoTests.header().setResizeMode(QHeaderView.Stretch)
        self.repoTests.setHeaderHidden(True)
        self.repoTests.setContextMenuPolicy(Qt.CustomContextMenu)
        self.repoTests.setIndentation(10)

        layoutRepoTest.addWidget(self.prjCombo)
        layoutRepoTest.addWidget(self.repoTests)

        self.testsList = QListWidget(self)

        layoutTests.addLayout( layoutRepoTest )
        layoutTests.addWidget( self.testsList )
        mainLayout.addLayout( layoutTests )

        buttonLayout = QVBoxLayout()

        self.okButton = QPushButton(self.tr("Execute All"), self)
        self.okButton.setEnabled(False)
        self.cancelButton = QPushButton(self.tr("Cancel"), self)
        self.upButton = QPushButton(self.tr("UP"), self)
        self.upButton.setEnabled(False)
        self.downButton = QPushButton(self.tr("DOWN"), self)
        self.downButton.setEnabled(False)
        self.clearButton = QPushButton(self.tr("Remove All"), self)
        self.delButton = QPushButton(self.tr("Remove"), self)
        self.delButton.setEnabled(False)

        self.runSimultaneous = QCheckBox(self.tr("Simultaneous Run"))
        
        self.schedImmed = QRadioButton(self.tr("Run Immediately"))
        self.schedImmed.setChecked(True)
        self.schedAt = QRadioButton(self.tr("Run At:"))
        self.schedAtDateTimeEdit = QDateTimeEdit(QDateTime.currentDateTime())
        self.schedAtDateTimeEdit.setEnabled(False)

        buttonLayout.addWidget(self.okButton)
        buttonLayout.addWidget(self.runSimultaneous)
        buttonLayout.addWidget(self.schedImmed)
        buttonLayout.addWidget(self.schedAt)
        buttonLayout.addWidget(self.schedAtDateTimeEdit)

        
        buttonLayout.addWidget( self.upButton )
        buttonLayout.addWidget( self.downButton )
        buttonLayout.addWidget( self.delButton )
        buttonLayout.addWidget( self.clearButton )

        buttonLayout.addWidget(self.cancelButton)

        mainLayout.addLayout(buttonLayout)

        self.setMinimumHeight(400)
        self.setMinimumWidth(750)
        self.setLayout(mainLayout)

    def initProjects(self, projects=[], defaultProject=1):
        """
        Initialize projects
        """
        # init date and time
        self.schedAtDateTimeEdit.setDateTime(QDateTime.currentDateTime()) 

        self.projectReady = False

        self.repoTests.clear()
        self.prjCombo.clear()
        self.testsList.clear()

        self.prjCombo.setEnabled(True)
        
        # insert data
        pname = ''
        for p in projects:
            self.prjCombo.addItem ( p['name']  )
            if defaultProject == p['project_id']:
                pname = p['name']
        
        for i in xrange(self.prjCombo.count()):
            item_text = self.prjCombo.itemText(i)
            if str(pname) == str(item_text):
                self.prjCombo.setCurrentIndex(i)

        self.projectReady = True
        self.RefreshRepository.emit(pname)

    def initializeTests(self, listing):
        """
        Initialize tests
        """
        self.repoTests.clear()
        self.testRoot = self.rRepo.Item(repo = self.iRepo.remote(), 
                                        parent = self.repoTests, txt = "Root", 
                                        type = QTreeWidgetItem.UserType+10, 
                                        isRoot = True )
        self.testRoot.setSelected(True)
        self.createRepository(listing=listing, parent=self.testRoot,fileincluded=True)
        self.repoTests.sortItems(0, Qt.AscendingOrder)

        self.hideItems(hideTsx=False, hideTpx=False, hideTcx=True, hideTdx=True, hideTxt=True, hidePy=True,
                                hideTux=False, hidePng=True, hideTgx=False, hideTax=False)

    def createRepository(self, listing, parent, fileincluded=True):
        """
        Create repository

        @param listing: 
        @type listing: list

        @param parent: 
        @type parent:

        @param fileincluded: 
        @type fileincluded: boolean
        """
        try:
            for dct in  listing:
                if dct["type"] == "folder":
                    item = self.rRepo.Item(repo = self.iRepo.remote(), parent = parent, 
                                           txt = dct["name"], propertiesFile=dct )
                    self.createRepository(  dct["content"] , item, fileincluded )
                else:
                    if fileincluded:
                        if dct["type"] == "file":
                            pname = self.iRepo.remote().getProjectName(dct["project"])
                            # {'modification': 1342259500, 'type': 'file', 'name': '__init__.py', 'size': '562 }
                            item = self.rRepo.Item(repo = self.iRepo.remote(), parent = parent, txt = dct["name"] ,
                                                   propertiesFile=dct, type = QTreeWidgetItem.UserType+0, 
                                                   projectId=dct["project"], projectName=pname )

        except Exception as e:
            self.error( "unable to create tree for runs: %s" % e )

    def onProjectChanged(self, projectItem):
        """
        Called when the project changed on the combo box
        """
        if self.projectReady:
            item_text = self.prjCombo.itemText(projectItem)
            self.RefreshRepository.emit(item_text)

    def createConnections (self):
        """
        create qt connections
         * ok
         * cancel
        """
        self.prjCombo.currentIndexChanged.connect(self.onProjectChanged)
        self.okButton.clicked.connect( self.acceptClicked )
        self.cancelButton.clicked.connect( self.reject )
        self.upButton.clicked.connect(self.upTest)
        self.downButton.clicked.connect(self.downTest)
        self.clearButton.clicked.connect(self.clearList)
        self.delButton.clicked.connect(self.delTest)

        self.testsList.itemClicked.connect(self.onItemSelected)
        self.testsList.itemSelectionChanged.connect(self.onItemSelectionChanged)

        self.schedAt.toggled.connect(self.onSchedAtActivated)

        self.repoTests.itemDoubleClicked.connect( self.onTestDoucleClicked )

    def onSchedAtActivated(self, toggled):
        """
        On sched at button activated
        """
        if toggled:
            self.schedAtDateTimeEdit.setEnabled(True)
        else:
            self.schedAtDateTimeEdit.setEnabled(False)

    def onItemSelectionChanged(self):
        """
        Called on item selection changed
        """
        self.onItemSelected(itm=None)

    def onItemSelected(self, itm):
        """
        Call on item selected
        """
        selectedItems = self.testsList.selectedItems()
        if len(selectedItems):
            self.delButton.setEnabled(True)
            self.upButton.setEnabled(True)
            self.downButton.setEnabled(True)
        else:
            self.delButton.setEnabled(False)
            self.upButton.setEnabled(False)
            self.downButton.setEnabled(False)

        if not self.testsList.count():
            self.okButton.setEnabled(False)

    def upTest(self):
        """
        Up test
        """
        currentRow = self.testsList.currentRow()
        currentItem = self.testsList.takeItem(currentRow)
        self.testsList.insertItem(currentRow - 1, currentItem)

    def downTest(self):
        """
        Down test
        """
        currentRow = self.testsList.currentRow()
        currentItem = self.testsList.takeItem(currentRow)
        self.testsList.insertItem(currentRow + 1, currentItem)


    def delTest(self):
        """
        Del test
        """
        currentRow = self.testsList.currentRow()
        currentItem = self.testsList.takeItem(currentRow)

    def clearList(self):
        """
        Clear test
        """
        self.testsList.clear()
        self.delButton.setEnabled(False)
        self.upButton.setEnabled(False)
        self.downButton.setEnabled(False)

        self.okButton.setEnabled(False)

    def iterateTree(self, item, hideTsx, hideTpx, hideTcx, hideTdx, hideTxt, 
                          hidePy, hideTux, hidePng, hideTgx, hideTax):
        """
        Iterate tree
        """
        child_count = item.childCount()
        for i in range(child_count):
            subitem = item.child(i)
            subchild_count = subitem.childCount()
            if subchild_count > 0:
                self.iterateTree(item=subitem, hideTsx=hideTsx, 
                                 hideTpx=hideTpx, hideTcx=hideTcx, 
                                 hideTdx=hideTdx, hideTxt=hideTxt,
                                 hidePy=hidePy, hideTux=hideTux, 
                                 hidePng=hidePng, hideTgx=hideTgx, hideTax=hideTax)
            else:
                if hideTux and subitem.getExtension() == self.rRepo.EXTENSION_TUX:
                    subitem.setHidden (True)
                elif hideTpx and subitem.getExtension() == self.rRepo.EXTENSION_TPX:
                    subitem.setHidden (True)
                elif hideTgx and subitem.getExtension() == self.rRepo.EXTENSION_TGX:
                    subitem.setHidden (True)
                elif hideTcx and subitem.getExtension() == self.rRepo.EXTENSION_TCX:
                    subitem.setHidden (True)
                elif hideTsx and  subitem.getExtension() == self.rRepo.EXTENSION_TSX:
                    subitem.setHidden (True)
                elif hideTdx and  subitem.getExtension() == self.rRepo.EXTENSION_TDX:
                    subitem.setHidden (True)
                elif hideTxt and  subitem.getExtension() == self.rRepo.EXTENSION_TXT:
                    subitem.setHidden (True)
                elif hidePy and  subitem.getExtension() == self.rRepo.EXTENSION_PY:
                    subitem.setHidden (True)
                elif hidePng and  subitem.getExtension() == self.rRepo.EXTENSION_PNG:
                    subitem.setHidden (True)
                elif hideTax and  subitem.getExtension() == self.rRepo.EXTENSION_TAx:
                    subitem.setHidden (True)
                else:
                    subitem.setHidden(False)

    def hideItems(self, hideTsx=False, hideTpx=False, hideTcx=False, hideTdx=False, hideTxt=False, hidePy=False, 
                        hideTux=False, hidePng=False, hideTgx=False, hideTax=False):
        """
        Hide items
        """
        root = self.repoTests.invisibleRootItem()
        self.iterateTree(item=root, hideTsx=hideTsx, hideTpx=hideTpx, hideTcx=hideTcx, 
                         hideTdx=hideTdx, hideTxt=hideTxt, hidePy=hidePy,
                         hideTux=hideTux, hidePng=hidePng, hideTgx=hideTgx, hideTax=hideTax)

    def onTestDoucleClicked(self, testItem):
        """
        On tests double clicked
        """
        if testItem.type() != QTreeWidgetItem.UserType+0:
            return

        self.okButton.setEnabled(True)

        currentProject = self.prjCombo.currentText()

        testName = "%s:%s" % (str(currentProject),testItem.getPath(withFileName = True))
        testItem = QListWidgetItem(testName )

        if testName.endswith(self.rRepo.EXTENSION_TUX):
            testItem.setIcon(QIcon(":/tux.png"))
        if testName.endswith(self.rRepo.EXTENSION_TSX):
            testItem.setIcon(QIcon(":/tsx.png"))
        if testName.endswith(self.rRepo.EXTENSION_TPX):
            testItem.setIcon(QIcon(":/tpx.png"))
        if testName.endswith(self.rRepo.EXTENSION_TGX):
            testItem.setIcon(QIcon(":/tgx.png"))
        if testName.endswith(self.rRepo.EXTENSION_TAX):
            testItem.setIcon(QIcon(":/tax.png"))
            
        self.testsList.addItem( testItem )

    def acceptClicked (self):
        """
        Called on accept button
        """
        self.accept()
    
    def getTests(self):
        """
        Returns all tests in the list
        """
        tests = []
        for i in xrange(self.testsList.count()):
            testItem = self.testsList.item(i)
            tests.append( str(testItem.text()) )

        runSimultaneous = False
        if self.runSimultaneous.isChecked(): runSimultaneous = True
        
        if self.schedImmed.isChecked():
            runAt = (0,0,0,0,0,0)
            return (tests, False, runAt, runSimultaneous)
        else:
            pydt = self.schedAtDateTimeEdit.dateTime().toPyDateTime()
            runAt = (pydt.year, pydt.month, pydt.day, pydt.hour, pydt.minute, pydt.second)
            return (tests, True, runAt, runSimultaneous)
Exemple #38
0
class multipleListWidget(QWidget):
    def __init__(self, parent, typeid, predefs, editable):
        QWidget.__init__(self)
        self.parent = parent
        self.typeid = typeid
        self.editable = editable
        self.predefs = predefs
        self.init()

    def init(self):
        self.vbox = QVBoxLayout()
        self.vbox.setSpacing(5)
        self.vbox.setMargin(0)
        self.createHeader()
        self.valuelist = QListWidget()
        self.vbox.addWidget(self.valuelist)
        self.setLayout(self.vbox)

    def createHeader(self):
        self.whead = QWidget()
        self.headerlayout = QHBoxLayout()
        self.headerlayout.setSpacing(0)
        self.headerlayout.setMargin(0)
        if self.typeid in (typeId.Node, typeId.Path) and self.editable:
            self.addPath()
        else:
            self.addSingleArgument()

        self.addButton = QPushButton(QIcon(":add.png"), "")
        self.rmButton = QPushButton(QIcon(":del_dump.png"), "")
        self.addButton.setIconSize(QSize(16, 16))
        self.rmButton.setIconSize(QSize(16, 16))

        self.connect(self.addButton, SIGNAL("clicked()"), self.addParameter)
        self.connect(self.rmButton, SIGNAL("clicked()"), self.rmParameter)
        self.connect(self.addButton, SIGNAL("clicked()"), self.parent.argumentChanged)
        self.connect(self.rmButton, SIGNAL("clicked()"), self.parent.argumentChanged)

        self.headerlayout.addWidget(self.addButton, 0)
        self.headerlayout.addWidget(self.rmButton, 0)
        self.whead.setLayout(self.headerlayout)
        self.vbox.addWidget(self.whead)

    def addParameterConfig(self, config):
       try : 
        if len(config) :
          for item in config:  
            self.valuelist.insertItem(self.valuelist.count() + 1, item)
       except TypeError:
	 self.valuelist.insertItem(self.valuelist.count() + 1, config)

    def addParameter(self):
        if isinstance(self.container, QComboBox):
            item = self.container.currentText()
        else:
            item = self.container.text()
        if len(self.valuelist.findItems(item, Qt.MatchExactly)) == 0:
            self.valuelist.insertItem(self.valuelist.count() + 1, item) 

    def rmParameter(self):
        selected = self.valuelist.selectedItems()
        for item in selected:
            row = self.valuelist.row(item)
            self.valuelist.takeItem(row)        

    def addSingleArgument(self):
        if len(self.predefs) > 0:
            self.container = QComboBox()
            for value in self.predefs:
                if self.typeid == typeId.Node:
                    self.container.addItem(value.value().name())
                else:
                    self.container.addItem(value.toString())
                self.container.setEditable(self.editable)
        else:
            self.container = QLineEdit()
            self.container.setReadOnly(self.editable)
        self.headerlayout.addWidget(self.container, 2)

    def addPath(self):
        if len(self.predefs) > 0:
            self.container = QComboBox()
            self.container.setReadOnly(False)
            for value in self.predefs:
                self.container.addItem(value.toString())
        else:
            self.container = QLineEdit()
            self.container.setReadOnly(False)
            if self.typeid == typeId.Path:
                browse = addLocalPathButton(self, key, self.container, isdir=False)
            else:
                browse = addLocalPathButton(self, key, self.container, isdir=False, nodetype=True)
        self.headerlayout.addWidget(self.container, 2)
        self.headerlayout.addWidget(browse, 0)

    def addPredefValue(self):
        selected = self.predefs.selectedItems()
        for item in selected:
            self.valuelist.insertItem(self.valuelist.count() + 1, item.text())
Exemple #39
0
class TagsDialog(QDialog):
    def __init__(self, dockwidget, parent, params):

        QDialog.__init__(self, parent)
        main_lay = QVBoxLayout(self)
        self.dockwidget = dockwidget
        self.params = params

        self.setWindowTitle('Tags editor')

        # Top frame
        self.fra_top = QFrame()
        fra_top_lay = QVBoxLayout(self.fra_top)

        self.lst_main = QListWidget(self)
        self.btn_add = QPushButton('Add tag')
        self.btn_add.clicked.connect(self.add_tag)
        self.btn_remove = QPushButton('Remove tag')
        self.btn_remove.clicked.connect(self.remove_tag)

        fra_top_lay.addWidget(self.lst_main)
        fra_top_lay.addWidget(self.btn_add)
        fra_top_lay.addWidget(self.btn_remove)

        # Bottom frame
        self.fra_bottom = QFrame()
        fra_bottom_lay = QHBoxLayout(self.fra_bottom)

        btb_main = QDialogButtonBox(QDialogButtonBox.Ok
                                    | QDialogButtonBox.Cancel)
        btb_main.accepted.connect(self.ok)
        btb_main.rejected.connect(self.reject)

        fra_bottom_lay.addWidget(btb_main)

        # Main
        main_lay.addWidget(self.fra_top)
        main_lay.addWidget(self.fra_bottom)

        self.initialize()

    def initialize(self):
        for tag_name in self.params.tag_names:
            self.lst_main.insertItem(self.lst_main.count(),
                                     QListWidgetItem(tag_name, self.lst_main))

    def ok(self):
        tag_names = []
        for r in range(self.lst_main.count()):
            tag_names.append(self.lst_main.item(r).text())

        self.params.tag_names = tag_names

        self.setVisible(False)

    def reject(self):
        self.setVisible(False)

    def add_tag(self):

        tag_name_dialog = TagNameDialog(self.dockwidget, self)
        tag_name_dialog.exec_()
        tag_name = tag_name_dialog.get_tag_name()

        if tag_name is not None:
            current_row = self.lst_main.currentRow()
            if current_row is None:
                current_row = self.lst_main.count()
            self.lst_main.insertItem(current_row,
                                     QListWidgetItem(tag_name, self.lst_main))

    def remove_tag(self):
        sel_items = self.lst_main.selectedItems()
        for sel_item in sel_items:
            self.lst_main.takeItem(self.lst_main.row(sel_item))
Exemple #40
0
class CheckList(HelpedWidget):
    def __init__(self, model, label="", help_link=""):
        HelpedWidget.__init__(self, "", help_link)

        layout = QVBoxLayout()

        widget = QWidget()
        widget.setLayout(layout)

        self.checkAllButton = QToolButton()
        self.checkAllButton.setIcon(resourceIcon("checked"))
        self.checkAllButton.setIconSize(QSize(16, 16))
        self.checkAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.checkAllButton.setAutoRaise(True)
        self.checkAllButton.setToolTip("Select all")

        self.uncheckAllButton = QToolButton()
        self.uncheckAllButton.setIcon(resourceIcon("notchecked"))
        self.uncheckAllButton.setIconSize(QSize(16, 16))
        self.uncheckAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self.uncheckAllButton.setAutoRaise(True)
        self.uncheckAllButton.setToolTip("Unselect all")

        self.list = QListWidget()
        self.list.setContextMenuPolicy(Qt.CustomContextMenu)
        self.list.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.search_box = SearchBox()

        check_button_layout = QHBoxLayout()

        check_button_layout.setMargin(0)
        check_button_layout.setSpacing(0)
        check_button_layout.addWidget(QLabel(label))
        check_button_layout.addStretch(1)
        check_button_layout.addWidget(self.checkAllButton)
        check_button_layout.addWidget(self.uncheckAllButton)

        layout.addLayout(check_button_layout)
        layout.addWidget(self.list)
        layout.addWidget(self.search_box)

        self.addWidget(widget)

        self.connect(self.checkAllButton, SIGNAL('clicked()'), self.checkAll)
        self.connect(self.uncheckAllButton, SIGNAL('clicked()'),
                     self.uncheckAll)
        self.connect(self.list, SIGNAL('itemChanged(QListWidgetItem*)'),
                     self.itemChanged)
        self.search_box.filterChanged.connect(self.filterList)
        # self.connect(self.search_box, SIGNAL('filterChanged(str)'), self.filterList)

        self.connect(self.list, SIGNAL('customContextMenuRequested(QPoint)'),
                     self.showContextMenu)

        assert isinstance(model, (SelectableModelMixin, ListModelMixin))
        self.model = model
        self.model.observable().attach(
            SelectableModelMixin.SELECTION_CHANGED_EVENT, self.modelChanged)
        self.model.observable().attach(ListModelMixin.LIST_CHANGED_EVENT,
                                       self.modelChanged)
        self.modelChanged()

    def itemChanged(self, item):
        """@type item: QListWidgetItem"""
        if item.checkState() == Qt.Checked:
            self.model.selectValue(str(item.text()))
        elif item.checkState() == Qt.Unchecked:
            self.model.unselectValue(str(item.text()))
        else:
            raise AssertionError("Unhandled checkstate!")

    def modelChanged(self):
        self.list.clear()

        items = self.model.getList()

        for item in items:
            list_item = QListWidgetItem(item)
            list_item.setFlags(list_item.flags() | Qt.ItemIsUserCheckable)

            if self.model.isValueSelected(item):
                list_item.setCheckState(Qt.Checked)
            else:
                list_item.setCheckState(Qt.Unchecked)

            self.list.addItem(list_item)

        self.filterList(self.search_box.filter())

    def setSelectionEnabled(self, enabled):
        self.setEnabled(enabled)
        self.checkAllButton.setEnabled(enabled)
        self.uncheckAllButton.setEnabled(enabled)

    def filterList(self, filter):
        filter = filter.lower()

        for index in range(0, self.list.count()):
            item = self.list.item(index)
            text = str(item.text()).lower()

            if filter == "":
                item.setHidden(False)
            elif filter in text:
                item.setHidden(False)
            else:
                item.setHidden(True)

    def checkAll(self):
        self.model.selectAll()

    def uncheckAll(self):
        self.model.unselectAll()

    def checkSelected(self):
        items = []
        for item in self.list.selectedItems():
            items.append(str(item.text()))

        for item in items:
            self.model.selectValue(item)

    def uncheckSelected(self):
        items = []
        for item in self.list.selectedItems():
            items.append(str(item.text()))

        for item in items:
            self.model.unselectValue(item)

    def showContextMenu(self, point):
        p = self.list.mapToGlobal(point)
        menu = QMenu()
        check_selected = menu.addAction("Check selected")
        uncheck_selected = menu.addAction("Uncheck selected")
        menu.addSeparator()
        clear_selection = menu.addAction("Clear selection")

        selected_item = menu.exec_(p)

        if selected_item == check_selected:
            self.checkSelected()
        elif selected_item == uncheck_selected:
            self.uncheckSelected()
        elif selected_item == clear_selection:
            self.list.clearSelection()
Exemple #41
0
class ListBox(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self, parent)
        while not isinstance(parent, QDialog):
            parent = parent.parent()
        self.setObjectName("ListBox" + str(len(parent.findChildren(ListBox))))

        self.hLayoutBoxPanel = QHBoxLayout(self)
        self.hLayoutBoxPanel.setSpacing(0)
        self.hLayoutBoxPanel.setContentsMargins(3, 3, 3, 3)
        self.hLayoutBoxPanel.setObjectName(("hLayoutBoxPanel"))
        self.frameBoxPanel = QFrame(self)
        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.frameBoxPanel.sizePolicy().hasHeightForWidth())
        self.frameBoxPanel.setSizePolicy(sizePolicy)
        self.frameBoxPanel.setFrameShape(QFrame.NoFrame)
        self.frameBoxPanel.setFrameShadow(QFrame.Raised)
        self.frameBoxPanel.setObjectName(("frameBoxPanel"))
        self.hLayoutframeBoxPanel = QHBoxLayout(self.frameBoxPanel)
        self.hLayoutframeBoxPanel.setSpacing(0)
        self.hLayoutframeBoxPanel.setMargin(0)
        self.hLayoutframeBoxPanel.setObjectName(("hLayoutframeBoxPanel"))
        self.captionLabel = QLabel(self.frameBoxPanel)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.captionLabel.sizePolicy().hasHeightForWidth())
        self.captionLabel.setSizePolicy(sizePolicy)
        self.captionLabel.setMinimumSize(QSize(200, 0))
        self.captionLabel.setMaximumSize(QSize(200, 16777215))
        font = QFont()
        font.setBold(False)
        font.setWeight(50)
        self.captionLabel.setFont(font)
        self.captionLabel.setObjectName(("captionLabel"))
        self.hLayoutframeBoxPanel.addWidget(self.captionLabel)

        self.listBox = QListWidget(self.frameBoxPanel)
        self.listBox.setEnabled(True)
        font = QFont()
        font.setBold(False)
        font.setWeight(50)
        self.listBox.setFont(font)
        self.listBox.setObjectName(("listBox"))
        # self.listBox.setText("0.0")
        self.hLayoutframeBoxPanel.addWidget(self.listBox)

        self.imageButton = QToolButton(self.frameBoxPanel)
        self.imageButton.setText((""))
        icon = QIcon()
        icon.addPixmap(QPixmap(("Resource/convex_hull.png")), QIcon.Normal,
                       QIcon.Off)
        self.imageButton.setIcon(icon)
        self.imageButton.setObjectName(("imageButton"))
        self.imageButton.setVisible(False)
        self.hLayoutframeBoxPanel.addWidget(self.imageButton)

        self.hLayoutBoxPanel.addWidget(self.frameBoxPanel)

        self.listBox.currentRowChanged.connect(self.listBoxChanged)
        self.imageButton.clicked.connect(self.imageButtonClicked)

        self.captionUnits = ""

        self.hasObject = False

        self.objectList = []
        self.captionLabel.setVisible(False)

    def get_Count(self):
        return self.listBox.count()

    Count = property(get_Count, None, None, None)

    def method_3(self, string_0):
        return self.listBox.row(self.listBox.findItems(string_0)[0])

    def method_11(self, string_0):
        if (self.IsEmpty):
            return "%s%s\t" % (string_0, self.Caption)
        return "%s%s\t%s %s" % (string_0, self.Caption, self.Value,
                                self.CaptionUnits)

    def listBoxChanged(self, index):
        i = index
        self.emit(SIGNAL("Event_0"), self)

    def IndexOf(self, item):
        if isinstance(item, str):
            return self.listBox.row(self.listBox.findItems(item)[0])
        else:
            return self.listBox.row(
                self.listBox.findItems(item.ToString())[0])

    def Contains(self, item):
        compStr = None
        if isinstance(item, str):
            compStr = item
        elif isinstance(item, float) or isinstance(item, int):
            compStr = str(item)
        else:
            compStr = item.ToString()
        for i in range(self.listBox.count()):
            comboItemstr = self.listBox.item(i).text()
            if compStr == comboItemstr:
                return True
        return False

    def Clear(self):
        self.listBox.clear()
        self.objectList = []
        self.hasObject = False

    def Add(self, item):
        if not isinstance(item, str) and not isinstance(item, QString):
            self.listBox.addItem(item.ToString())
            self.objectList.append(item)
            self.hasObject = True
            return
        self.listBox.addItem(item)
        self.hasObject = False
        return self.listBox.count() - 1

    def Insert(self, index, item):
        if not isinstance(item, str):
            self.listBox.insertItem(index, item.ToString())
            self.objectList.insert(index, item)
            self.hasObject = True
            return
        self.listBox.insertItem(index, item)
        self.hasObject = False

    def imageButtonClicked(self):
        self.emit(SIGNAL("Event_3"), self)

    def get_Caption(self):
        caption = self.captionLabel.text()
        findIndex = caption.indexOf("(")
        if findIndex > 0:
            val = caption.left(findIndex)
            return val
        return caption

    def set_Caption(self, captionStr):
        if captionStr == "":
            self.captionLabel.setText("")
            self.LabelWidth = 0
            return
        if self.CaptionUnits != "" and self.CaptionUnits != None:
            self.captionLabel.setText(captionStr + "(" +
                                      str(self.CaptionUnits) + ")" + ":")
        else:
            self.captionLabel.setText(captionStr + ":")

    Caption = property(get_Caption, set_Caption, None, None)

    def get_CaptionUnits(self):
        return self.captionUnits

    def set_CaptionUnits(self, captionUnits):
        self.captionUnits = captionUnits

    CaptionUnits = property(get_CaptionUnits, set_CaptionUnits, None, None)

    def set_ButtonVisible(self, bool):
        self.imageButton.setVisible(bool)

    ButtonVisible = property(None, set_ButtonVisible, None, None)

    # def get_Value(self):
    #     return self.listBox.currentIndex()
    #
    # def set_Value(self, value):
    #     try:
    #         self.listBox.setCurrentIndex(value)
    #     except:
    #         self.textBox.setText("")
    # Value = property(get_Value, set_Value, None, None)

    # def get_IsEmpty(self):
    #     return self.listBox.currentText() == "" or self.listBox.currentIndex() == -1
    # IsEmpty = property(get_IsEmpty, None, None, None)

    # def get_ReadOnly(self):
    #     return self.listBox.isReadOnly()
    # # def set_ReadOnly(self, bool):
    # #     self.listBox.setR.setReadOnly(bool)
    # # ReadOnly = property(get_ReadOnly, set_ReadOnly, None, None)

    def set_LabelWidth(self, width):
        self.captionLabel.setMinimumSize(QSize(width, 0))
        self.captionLabel.setMaximumSize(QSize(width, 16777215))

    LabelWidth = property(None, set_LabelWidth, None, None)

    def set_Width(self, width):
        self.listBox.setMinimumSize(QSize(width, 0))
        self.listBox.setMaximumSize(QSize(width, 16777215))

    Width = property(None, set_Width, None, None)

    def set_Button(self, imageName):
        if imageName == None or imageName == "":
            self.imageButton.setVisible(False)
            return
        icon = QIcon()
        icon.addPixmap(QPixmap(("Resource/" + imageName)), QIcon.Normal,
                       QIcon.Off)
        self.imageButton.setIcon(icon)
        self.imageButton.setVisible(True)

    Button = property(None, set_Button, None, None)

    def get_SelectedIndex(self):
        try:
            return self.listBox.currentRow()
        except:
            return 0

    def set_SelectedIndex(self, index):
        if self.listBox.count() == 0:
            return
        if index > self.listBox.count() - 1:
            self.listBox.setCurrentRow(0)
        else:
            self.listBox.setCurrentRow(index)

    SelectedIndex = property(get_SelectedIndex, set_SelectedIndex, None, None)

    # def get_Value(self):
    #     return self.listBox.currentIndex()
    # def set_Value(self, valueStr):
    #     if self.listBox.count() == 0:
    #         return
    #     self.listBox.setCurrentIndex(self.listBox.findText(valueStr))
    # Value = property(get_Value, set_Value, None, None)

    def get_Items(self):
        if self.hasObject:
            return self.objectList
        itemList = []
        if self.listBox.count() > 0:
            for i in range(self.listBox.count()):
                itemList.append(self.listBox.item(i).text())
        return itemList

    def set_AddItems(self, strList):
        if len(strList) != 0 and not isinstance(
                strList[0], str) and not isinstance(strList[0], QString):
            for obj in strList:
                self.listBox.addItem(obj.ToString())
                self.objectList.append(obj)
            self.hasObject = True
            return
        self.listBox.addItems(strList)

    Items = property(get_Items, set_AddItems, None, None)

    def get_Enabled(self):
        return self.listBox.isEnabled()

    def set_Enabled(self, bool):
        self.listBox.setEnabled(bool)

    Enabled = property(get_Enabled, set_Enabled, None, None)

    def get_Visible(self):
        return self.isVisible()

    def set_Visible(self, bool):
        self.setVisible(bool)

    Visible = property(get_Visible, set_Visible, None, None)

    def get_SelectedItem(self):
        if self.listBox.count() == 0:
            return None
        if self.hasObject:
            return self.objectList[self.SelectedIndex]
        return self.listBox.currentItem().text()

    # def set_SelectedItem(self, val):
    #     index = self.listBox.findText(val)
    #     self.listBox.setCurrentIndex(index)
    SelectedItem = property(get_SelectedItem, None, None, None)
Exemple #42
0
class NotebookListDialog(QDialog):
    """ Functions to display, create, remove, modify notebookList """
    def __init__(self, parent=None):
        super(NotebookListDialog, self).__init__(parent)

        self.notebookList = QListWidget()
        self.moveUp = QPushButton('<<')
        self.moveDown = QPushButton('>>')
        self.add = QPushButton('Add')
        self.remove = QPushButton('Remove')
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False)
        layout = QGridLayout()
        layout.addWidget(self.notebookList, 0, 0, 4, 6)
        layout.addWidget(self.moveUp, 1, 6)
        layout.addWidget(self.moveDown, 2, 6)
        layout.addWidget(self.add, 4, 0)
        layout.addWidget(self.remove, 4, 1)
        layout.addWidget(self.buttonBox, 4, 5, 1, 2)
        self.setLayout(layout)

        self.notebookList.setItemDelegate(ListDelegate(self.notebookList))

        self.notebookList.currentRowChanged.connect(self.updateUi)
        self.add.clicked.connect(self.actionAdd)
        self.remove.clicked.connect(self.actionRemove)
        self.moveUp.clicked.connect(self.moveItemUp)
        self.moveDown.clicked.connect(self.moveItemDown)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        self.initList()

    def initList(self):
        self.notebookList.clear()
        notebooks = Mikibook.read()
        for nb in notebooks:
            item = QListWidgetItem()
            item.setData(Qt.DisplayRole, nb[0])
            item.setData(Qt.UserRole, nb[1])
            self.notebookList.addItem(item)

        self.updateUi(len(notebooks) != 0)
        self.notebookList.setCurrentRow(0)
        # QListWidgetItem(nb, self.notebookList)

    def updateUi(self, row):
        flag = (row != -1)
        self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(flag)
        self.remove.setEnabled(flag)
        self.moveUp.setEnabled(flag)
        self.moveDown.setEnabled(flag)

    def actionAdd(self):
        Mikibook.create()
        self.initList()
        count = self.notebookList.count()
        self.notebookList.setCurrentRow(count - 1)

    def actionRemove(self):
        item = self.notebookList.currentItem()
        row = self.notebookList.currentRow()
        name = item.data(Qt.DisplayRole)
        path = item.data(Qt.UserRole)
        self.notebookList.takeItem(row)

        Mikibook.remove(name, path)

    def moveItemUp(self):
        item = self.notebookList.currentItem()
        row = self.notebookList.currentRow()
        if row != 0:
            # self.notebookList.removeItemWidget(item)
            self.notebookList.takeItem(row)
            self.notebookList.insertItem(row - 1, item)
            self.notebookList.setCurrentRow(row - 1)

    def moveItemDown(self):
        item = self.notebookList.currentItem()
        row = self.notebookList.currentRow()
        count = self.notebookList.count()
        if row != count - 1:
            self.notebookList.takeItem(row)
            self.notebookList.insertItem(row + 1, item)
            self.notebookList.setCurrentRow(row + 1)

    def accept(self):
        notebookPath = self.notebookList.currentItem().data(Qt.UserRole)
        notebookName = self.notebookList.currentItem().data(Qt.DisplayRole)
        settings = Setting([[notebookName, notebookPath]])
        window = mikidown.MikiWindow(settings)
        window.show()
        count = self.notebookList.count()
        notebooks = []
        for i in range(count):
            name = self.notebookList.item(i).data(Qt.DisplayRole)
            path = self.notebookList.item(i).data(Qt.UserRole)
            notebooks.append([name, path])
            Mikibook.write(notebooks)

        QDialog.accept(self)
Exemple #43
0
class Img2GifWidget(QDialog):
    AppName = u"GIF生成工具"
    
    def __init__(self, parent=None):
        super(Img2GifWidget, self).__init__(parent)
        self.setWindowTitle(Img2GifWidget.AppName)

        self.listWidget = QListWidget()
        self.listWidget.setMinimumSize(400, 300)
        self.btnAdd = QPushButton("&Add")
        self.btnUp = QPushButton("&Up")
        self.btnDown = QPushButton("&Down")
        self.btnDel = QPushButton("&Delete")
        self.btnClear = QPushButton("&Clear")
        topLeftLay = QVBoxLayout()
        topLeftLay.addWidget(self.btnAdd)
        topLeftLay.addWidget(self.btnUp)
        topLeftLay.addWidget(self.btnDown)
        topLeftLay.addWidget(self.btnDel)
        topLeftLay.addWidget(self.btnClear)
        topLeftLay.addStretch()
        topLay = QHBoxLayout()
        topLay.addWidget(self.listWidget)
        topLay.addLayout(topLeftLay)
        
        label = QLabel(u"Gif文件路径:")
        self.txtGifPath = QLineEdit()
        self.btnBrowser = QPushButton('...')
        midLay = QHBoxLayout()
        midLay.addWidget(label)
        midLay.addWidget(self.txtGifPath)
        midLay.addWidget(self.btnBrowser)

        timeLabel = QLabel(u"时间间隔:")
        self.spbTime = QDoubleSpinBox()
        self.spbTime.setRange(0.001, 10)
        self.spbTime.setSingleStep(0.001)
        self.spbTime.setValue(1)
        self.spbTime.setSuffix('s')
        loopLabel = QLabel(u"循环:")
        self.spbLoop = QDoubleSpinBox()
        self.spbLoop = QSpinBox()
        self.spbLoop.setRange(0, 1000)
        self.spbLoop.setSingleStep(1)
        self.spbLoop.setValue(0)
        self.spbLoop.setToolTip(u"0次循环表示永久循环")
        self.spbLoop.setSuffix(u"次")
        self.btnBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        bottomLay = QHBoxLayout()
        bottomLay.addWidget(timeLabel)
        bottomLay.addWidget(self.spbTime)
        bottomLay.addWidget(loopLabel)
        bottomLay.addWidget(self.spbLoop)
        bottomLay.addStretch()
        bottomLay.addWidget(self.btnBox)
        
        mainLay = QVBoxLayout()
        mainLay.addLayout(topLay)
        mainLay.addLayout(midLay)
        mainLay.addLayout(bottomLay)
        self.setLayout(mainLay)

        self.btnAdd.clicked.connect(self.itemAdd)
        self.btnUp.clicked.connect(self.itemUp)
        self.btnDown.clicked.connect(self.itemDown)
        self.btnDel.clicked.connect(self.itemDel)
        self.btnClear.clicked.connect(self.listWidget.clear)
        self.btnBrowser.clicked.connect(self.setGifPath)
        self.btnBox.rejected.connect(self.close)
        self.btnBox.accepted.connect(self.makeGif)

        self.txtGifPath.returnPressed.connect(self.updateGifPath)

    def itemAdd(self):
        fileNames = QFileDialog.getOpenFileNames(None, u"{0} -- {1}".format(qApp.applicationName(), Img2GifWidget.AppName),
                                                 '.', u'所有文件(*.*);;BMP文件(*.bmp);;PNG文件(*.png);;JPG文件(*.jpg *.jpeg)')
        for fn in fileNames:
            f = QFileInfo(fn)
            if unicode(f.suffix().toLower()) in ['jpg', 'png', 'bmp', 'jpeg']:
                self.listWidget.addItem(fn)

    def itemUp(self):
        row = self.listWidget.currentRow()
        if row <= 0:
            return
        item = self.listWidget.currentItem()
        self.listWidget.takeItem(row)
        self.listWidget.insertItem(row - 1, item)
        self.listWidget.setCurrentRow(row - 1)

    def itemDown(self):
        rows = self.listWidget.count()
        row = self.listWidget.currentRow()
        if (row < 0) or (row == rows - 1):
            return
        item = self.listWidget.currentItem()
        self.listWidget.takeItem(row)
        self.listWidget.insertItem(row + 1, item)
        self.listWidget.setCurrentRow(row + 1)

    def itemDel(self):
        row = self.listWidget.currentRow()
        if row >= 0:
            self.listWidget.takeItem(row)

    def setGifPath(self):
        filename = QFileDialog.getSaveFileName(self, u"{0} -- {1}".format(qApp.applicationName(), Img2GifWidget.AppName),
                                               ".", "Gif(*.gif)")
        self.txtGifPath.setText(filename)

    def updateGifPath(self):
        fileName = self.txtGifPath.text()
        f = QFileInfo(fileName)
        if f.dir().exists and not f.baseName().isEmpty() and not f.suffix().isEmpty():
            self.txtGifPath.setText(fileName)
            return True
        else:
            QMessageBox.warning(self, u"{0} -- warning".format(Img2GifWidget.AppName),
                                u"要生成的GIF存储路径{0}不是有效的GIF文件".format(unicode(fileName)))
            return False

    def makeGif(self):

        imgs = [unicode(self.listWidget.item(i).text()) for i in range(self.listWidget.count())]
        if len(imgs) <= 1:
            QMessageBox.warning(self, u"{0} - {1}".format(qApp.applicationName(), Img2GifWidget.AppName),
                                u"GIF动画文件必须要给定大于一张图片。")
            return
        if not self.updateGifPath():
            return
        durations = self.spbTime.value()
        loops = self.spbLoop.value()
        ok, msg = img2gif.images2gif(imgs, self.txtGifPath.text(), durations=durations, loops=loops)
        if ok:
            QMessageBox.about(self, u"{0} - {1}".format(qApp.applicationName(), Img2GifWidget.AppName),
                              u"Succeed!\n{0}".format(msg))
            qApp.processEvents()
        else:
            QMessageBox.about(u"{0} - {1}".format(qApp.applicationName(), Img2GifWidget.AppName),
                              u"sorry! Failed to generate the {0}".format(unicode(self.txtGifPath)))
Exemple #44
0
class ConfigDialog(QDialog):
    def __init__(self, parent=None):
        QDialog.__init__(self, parent)

        self.contents_widget = QListWidget()
        self.contents_widget.setMovement(QListView.Static)
        self.contents_widget.setMinimumWidth(120)
        self.contents_widget.setMaximumWidth(120)
        self.contents_widget.setSpacing(1)

        bbox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Apply
                                     |QDialogButtonBox.Cancel)
        self.apply_btn = bbox.button(QDialogButtonBox.Apply)
        self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()"))
        self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()"))
        self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"),
                     self.button_clicked)

        self.pages_widget = QStackedWidget()
        self.connect(self.pages_widget, SIGNAL("currentChanged(int)"),
                     self.current_page_changed)

        self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"),
                     self.pages_widget.setCurrentIndex)
        self.contents_widget.setCurrentRow(0)

        hlayout = QHBoxLayout()
        hlayout.addWidget(self.contents_widget)
        hlayout.addWidget(self.pages_widget)
        hlayout.setStretch(1,1)

        btnlayout = QHBoxLayout()
        btnlayout.addStretch(1)
        btnlayout.addWidget(bbox)

        vlayout = QVBoxLayout()
        vlayout.addLayout(hlayout)
        vlayout.addLayout(btnlayout)

        self.setLayout(vlayout)

        self.setWindowTitle("Preferences")
        self.setWindowIcon(get_icon("configure.png"))
        
    def get_current_index(self):
        """Return current page index"""
        return self.contents_widget.currentRow()
        
    def set_current_index(self, index):
        """Set current page index"""
        self.contents_widget.setCurrentRow(index)
        
    def accept(self):
        """Reimplement Qt method"""
        for index in range(self.pages_widget.count()):
            configpage = self.pages_widget.widget(index)
            if not configpage.is_valid():
                return
            configpage.apply_changes()
        QDialog.accept(self)
        
    def button_clicked(self, button):
        if button is self.apply_btn:
            # Apply button was clicked
            configpage = self.pages_widget.currentWidget()
            if not configpage.is_valid():
                return
            configpage.apply_changes()
            
    def current_page_changed(self, index):
        widget = self.pages_widget.widget(index)
        self.apply_btn.setVisible(widget.apply_callback is not None)
        self.apply_btn.setEnabled(widget.is_modified)
        
    def add_page(self, widget):
        self.connect(self, SIGNAL('check_settings()'), widget.check_settings)
        self.connect(widget, SIGNAL('show_this_page()'),
                     lambda row=self.contents_widget.count():
                     self.contents_widget.setCurrentRow(row))
        self.connect(widget, SIGNAL("apply_button_enabled(bool)"),
                     self.apply_btn.setEnabled)
        self.pages_widget.addWidget(widget)
        item = QListWidgetItem(self.contents_widget)
        item.setIcon(widget.get_icon())
        item.setText(widget.get_name())
        item.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled)
        item.setSizeHint(QSize(0, 25))
        
    def check_all_settings(self):
        """This method is called to check all configuration page settings
        after configuration dialog has been shown"""
        self.emit(SIGNAL('check_settings()'))
Exemple #45
0
class GitStatus(QDialog):

    def __init__(self, plugin, git, path):
        QDialog.__init__(self)
        self.git = git
        self.plugin = plugin
        self.setWindowTitle('Git status')

        layout = QGridLayout(self)

        branches = self.git.branch(unicode(path))

        self.s_branches = QListWidget()

        if len(branches) > 0:
            self.s_branches.addItems(branches[1:])
            self.actual_branch = QLabel("<h2>{0}</h2>".format(branches[0]))
        else:
            self.actual_branch = QLabel()

        branch = QLabel("<h2>Branches</h2>")
        change_branch = QPushButton("Change to")
        merge_branches = QPushButton("Merge branch")

        H = QHBoxLayout()
        delete_branch = QPushButton("Delete branch")
        add_branch = QPushButton("Add branch")
        H.addWidget(add_branch)
        H.addWidget(delete_branch)

        self.lists = []

        no_staged = QLabel("<h2>No staged</h2>")

        untracked_files = QLabel("Untracked files")
        self.untracked_files = QListWidget()
        self.lists.append(self.untracked_files)

        modified_files = QLabel("Modified files")
        self.modified_files = QListWidget()
        self.lists.append(self.modified_files)

        deleted_files = QLabel("Deleted files")
        self.deleted_files = QListWidget()
        self.lists.append(self.deleted_files)

        staged = QLabel("<h2>Staged</h2>")

        added_files = QLabel("Added files")
        self.added_files = QListWidget()
        self.lists.append(self.added_files)

        s_modified_files = QLabel("Modified files")
        self.s_modified_files = QListWidget()
        self.lists.append(self.s_modified_files)

        s_deleted_files = QLabel("Deleted files")
        self.s_deleted_files = QListWidget()
        self.lists.append(self.s_deleted_files)

        layout.addWidget(self.actual_branch, 0, 0, Qt.AlignHCenter)
        layout.addWidget(change_branch, 1, 0)
        layout.addWidget(merge_branches, 2, 0)
        layout.addWidget(no_staged, 3, 0)
        layout.addWidget(untracked_files, 4, 0)
        layout.addWidget(self.untracked_files, 5, 0)
        layout.addWidget(modified_files, 6, 0)
        layout.addWidget(self.modified_files, 7, 0)
        layout.addWidget(deleted_files, 8, 0)
        layout.addWidget(self.deleted_files, 9, 0)

        layout.addWidget(branch, 0, 1)
        layout.addWidget(self.s_branches, 1, 1)
        layout.addLayout(H, 2, 1)
        layout.addWidget(staged, 3, 1)
        layout.addWidget(added_files, 4, 1)
        layout.addWidget(self.added_files, 5, 1)
        layout.addWidget(s_modified_files, 6, 1)
        layout.addWidget(self.s_modified_files, 7, 1)
        layout.addWidget(s_deleted_files, 8, 1)
        layout.addWidget(self.s_deleted_files, 9, 1)

        self.fill(self.git.no_staged["?"], self.untracked_files)
        self.fill(self.git.no_staged["M"], self.modified_files)
        self.fill(self.git.no_staged["D"], self.deleted_files)

        self.fill(self.git.staged["A"], self.added_files)
        self.fill(self.git.staged["M"], self.s_modified_files)
        self.fill(self.git.staged["D"], self.s_deleted_files)

        self.staged_b = QPushButton('Stage files', self)
        self.unstage_b = QPushButton("Unstage files", self)
        self.commit_b = QPushButton('Commit files', self)
        self.uncommit_b = QPushButton("Uncommit files", self)

        layout.addWidget(self.staged_b, 10, 0)
        layout.addWidget(self.unstage_b, 11, 0)
        layout.addWidget(self.commit_b, 10, 1)
        layout.addWidget(self.uncommit_b, 11, 1)

        self.setLayout(layout)

        self.connect(self.staged_b, SIGNAL('clicked()'), self.add)
        self.connect(self.unstage_b, SIGNAL('clicked()'), self.unstage)
        self.connect(self.commit_b, SIGNAL('clicked()'), self.commit)
        self.connect(self.uncommit_b, SIGNAL('clicked()'), self.uncommit)
        self.connect(change_branch, SIGNAL("clicked()"), self.change_branch)
        self.connect(add_branch, SIGNAL("clicked()"), self.add_branch)
        self.connect(delete_branch, SIGNAL("clicked()"), self.delete_branch)
        self.connect(merge_branches, SIGNAL("clicked()"), self.merge_branches)

    def fill(self, a_list, widget_list):
        for x in a_list:

            item = QListWidgetItem()
            widget_list.addItem(item)
            check_box = QCheckBox(x)
            widget_list.setItemWidget(item, check_box)

    def add(self):
        path = self.plugin.editor.get_project_owner()
        for pos in reversed(xrange(self.untracked_files.count())):

            item = self.untracked_files.item(pos)
            widget = self.untracked_files.itemWidget(item)
            text = widget.text()

            if widget.isChecked():
                self.git.add(path, text)
                self.untracked_files.removeItemWidget(item)
                self.untracked_files.takeItem(pos)
                item = QListWidgetItem()
                self.added_files.addItem(item)
                check_box = QCheckBox(text)
                self.added_files.setItemWidget(item, check_box)

        for pos in reversed(xrange(self.modified_files.count())):

            item = self.modified_files.item(pos)
            widget = self.modified_files.itemWidget(item)
            text = widget.text()

            if widget.isChecked():
                self.git.add(path, widget.text())
                self.modified_files.removeItemWidget(item)
                self.modified_files.takeItem(pos)
                item = QListWidgetItem()
                self.s_modified_files.addItem(item)
                check_box = QCheckBox(text)
                self.s_modified_files.setItemWidget(item, check_box)

        for pos in reversed(xrange(self.deleted_files.count())):

            item = self.deleted_files.item(pos)
            widget = self.deleted_files.itemWidget(item)
            text = widget.text()

            if widget.isChecked():
                self.git.add(path, widget.text())
                self.deleted_files.removeItemWidget(item)
                self.deleted_files.takeItem(pos)
                item = QListWidgetItem()
                self.s_deleted_files.addItem(item)
                check_box = QCheckBox(text)
                self.s_deleted_files.setItemWidget(item, check_box)

    def unstage(self):

        path = self.plugin.editor.get_project_owner()
        for pos in reversed(xrange(self.untracked_files.count())):

            item = self.untracked_files.item(pos)
            widget = self.untracked_files.itemWidget(item)

            if widget.isChecked():
                self.git.unstage(path, widget.text())
                self.untracked_files.removeItemWidget(item)
                self.untracked_files.takeItem(pos)

        for pos in reversed(xrange(self.modified_files.count())):

            item = self.modified_files.item(pos)
            widget = self.modified_files.itemWidget(item)

            if widget.isChecked():
                self.git.unstage(path, widget.text())
                self.modified_files.removeItemWidget(item)
                self.modified_files.takeItem(pos)

        for pos in reversed(xrange(self.deleted_files.count())):

            item = self.deleted_files.item(pos)
            widget = self.deleted_files.itemWidget(item)

            if widget.isChecked():
                self.git.unstage(path, widget.text())
                self.deleted_files.removeItemWidget(item)
                self.deleted_files.takeItem(pos)

    def commit(self):

        msg = QInputDialog.getText(self, "Commit message", "Commit Message:")

        if msg[1] == False:
            return(0)

        path = self.plugin.editor.get_project_owner()
        for pos in reversed(xrange(self.added_files.count())):

            item = self.added_files.item(pos)
            widget = self.added_files.itemWidget(item)

            if widget.isChecked():
                self.git.commit(path, str(widget.text()), msg[0])
                self.added_files.removeItemWidget(item)
                self.added_files.takeItem(pos)

        for pos in reversed(xrange(self.s_modified_files.count())):

            item = self.s_modified_files.item(pos)
            widget = self.s_modified_files.itemWidget(item)

            if widget.isChecked():
                self.git.commit(path, widget.text(), msg[0])
                self.s_modified_files.removeItemWidget(item)
                self.s_modified_files.takeItem(pos)

        for pos in reversed(xrange(self.s_deleted_files.count())):

            item = self.s_deleted_files.item(pos)
            widget = self.s_deleted_files.itemWidget(item)

            if widget.isChecked():
                self.git.commit(path, widget.text(), msg[0])
                self.s_deleted_files.takeItem(pos)
                self.s_deleted_files.removeItemWidget(item)

    def uncommit(self):
        path = self.plugin.editor.get_project_owner()
        for pos in reversed(xrange(self.added_files.count())):

            item = self.added_files.item(pos)
            widget = self.added_files.itemWidget(item)
            text = widget.text()

            if widget.isChecked():
                self.git.uncommit(path, str(widget.text()))
                self.added_files.removeItemWidget(item)
                self.added_files.takeItem(pos)
                item = QListWidgetItem()
                self.untracked_files.addItem(item)
                check_box = QCheckBox(text)
                self.untracked_files.setItemWidget(item, check_box)

        for pos in reversed(xrange(self.s_modified_files.count())):

            item = self.s_modified_files.item(pos)
            widget = self.s_modified_files.itemWidget(item)
            text = widget.text()

            if widget.isChecked():
                self.git.uncommit(path, widget.text())
                self.s_modified_files.removeItemWidget(item)
                self.s_modified_files.takeItem(pos)
                item = QListWidgetItem()
                self.modified_files.addItem(item)
                check_box = QCheckBox(text)
                self.modified_files.setItemWidget(item, check_box)

        for pos in reversed(xrange(self.s_deleted_files.count())):

            item = self.s_deleted_files.item(pos)
            widget = self.s_deleted_files.itemWidget(item)
            text = widget.text()

            if widget.isChecked():
                self.git.uncommit(path, widget.text())
                self.s_deleted_files.removeItemWidget(item)
                self.s_deleted_files.takeItem(pos)
                item = QListWidgetItem()
                self.deleted_files.addItem(item)
                check_box = QCheckBox(text)
                self.deleted_files.setItemWidget(item, check_box)

    def change_branch(self):

        path = self.plugin.editor.get_project_owner()

        item = self.s_branches.currentItem()

        if item and not self.something():
            text = item.text()
            self.git.change_branch(path, text)
            self.s_branches.clear()
            self.s_branches.addItems(self.git.branch(unicode(path))[1:])
            self.actual_branch.setText("<h2>{0}<h2>".format(text))
        if self.something():
            v = QMessageBox()
            v.setText("Error: you have unsaved changes")
            v.setIcon(v.Warning)
            v.exec_()

    def add_branch(self):

        path = self.plugin.editor.get_project_owner()

        msg = QInputDialog.getText(self, "New branch", "Branch Name:")

        if msg[1] == False:
            return(0)

        self.git.add_branch(path, msg[0])
        self.s_branches.clear()
        self.s_branches.addItems(self.git.branch(unicode(path))[1:])

    def delete_branch(self):
        path = self.plugin.editor.get_project_owner()
        item = self.s_branches.currentItem()
        if item:
            text = str(item.text())
            call = self.git.delete_branch(path, text)

            if not call:
                self.s_branches.clear()
                self.s_branches.addItems(self.git.branch(unicode(path))[1:])

            else:
                m = QMessageBox()
                m.setText("<h2>" + call + "</h2>")
                m.setInformativeText("Force deletion?")
                m.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
                m.setDefaultButton(QMessageBox.Cancel)
                c = m.exec_()
                if c == QMessageBox.Ok:

                    self.git.force_delete_branch(path, text)
                    self.s_branches.clear()

                    self.s_branches.addItems(self.git.branch(unicode(path))[1:])

    def merge_branches(self):
        path = self.plugin.editor.get_project_owner()
        item = self.s_branches.currentItem()
        if item:
            text = str(item.text())
            call = self.git.merge_branches(path, text)
            if call:
                m = QMessageBox()
                m.setText(call)
                m.setInformativeText("Unknown")
                m.setIcon(m.Critical)
                m.exec_()

    def something(self):
        for x in self.lists:
            if x.count() > 0:
                return True
        return False
Exemple #46
0
class EkdConfigBox(QDialog) :
    """
    EkdConfigBox permet à l'utilisateur de configurer EkdConfig
    """
    def __init__(self, w=550, h=480, titre=u"Configuration de Ekd", parent=None):
        super(EkdConfigBox, self).__init__(parent)
        self.resize(w,h)
        self.w = w
        self.h = h
        self.setWindowTitle(titre)

        self.layout = QVBoxLayout(self)
        ## Menu contient l'ensemble des sections à paramétrer
        self.menu = QListWidget(self)
        self.layout.addWidget(self.menu)
        ## Pour chaque section à paramétrer, on utilise un Stack d'objets
        self.leftpart = QStackedLayout()
        self.leftpart.setSizeConstraint(QLayout.SetNoConstraint)
        self.layout.addLayout(self.leftpart)

        ## propWidget contient l'ensemble des objets propriété de toutes les section
        ## (il est nécessaire de les stocker pour être capable de les faire interagir)
        self.propWidget=[]
        wid = 0

        ## On crée les différentes parties de configuration qui ne sont pas inclues dans le tableau SECTION_MASK de EkdConfig
        for section in EkdConfig.SECTIONS :
            if not section in EkdConfig.SECTION_MASK :
                self.menu.addItem(EkdConfig.SECTIONS[section])
                allprops = EkdConfig.getAllProperties(EkdConfig.getConfigSection(section))
                scroll = QScrollArea()
                frame = QFrame()
                frame.setMinimumSize(self.w-50, self.h/2) # Ajouté le 10/12/2009 Pour que la partie réglage prenne toute la place dispo.
                frame.setMaximumSize(self.w, self.h)
                linelayout = QGridLayout(frame)

                linelayout.setSizeConstraint(QLayout.SetMinAndMaxSize)
                row = 0
                ## Insertion des propriété de la section en fonction de son type
                allkeys = allprops.keys()
                found = False
                for prop in allkeys :
                    if not prop in EkdConfig.PROPERTIES_MASK :
                        if prop in EkdConfig.PATH_PROPERTIES :
                            self.propWidget.append( EkdPathPropertie(prop, EkdConfig.PROPERTIES[prop], allprops[prop], section=section) )
                            linelayout.addWidget(self.propWidget[wid].label, row, 0)
                            linelayout.addWidget(self.propWidget[wid].widget, row, 1)
                            wid += 1
                            found = True
                        row += 1
                for prop in allkeys :
                    if not prop in EkdConfig.PROPERTIES_MASK :
                        if prop in EkdConfig.STYLE_PROPERTIES :
                            self.propWidget.append( EkdStylePropertie(prop, EkdConfig.PROPERTIES[prop], allprops[prop], EkdConfig.STYLE_PROPERTIES[prop], section=section ) )
                            linelayout.addWidget(self.propWidget[wid].label, row, 0)
                            linelayout.addWidget(self.propWidget[wid].widget, row, 1)
                            wid += 1
                            found = True
                        row += 1
                for prop in allkeys :
                    if not prop in EkdConfig.PROPERTIES_MASK :
                        if prop in EkdConfig.CODEC_PROPERTIES :
                            self.propWidget.append( EkdCodecPropertie(prop, EkdConfig.PROPERTIES[prop], allprops[prop], EkdConfig.CODEC_PROPERTIES[prop], section=section ) )
                            linelayout.addWidget(self.propWidget[wid].label, row, 0)
                            linelayout.addWidget(self.propWidget[wid].widget, row, 1)
                            wid += 1
                            found = True
                        row += 1
                for prop in allkeys :
                    if not prop in EkdConfig.PROPERTIES_MASK :
                        if prop in EkdConfig.BOOLEAN_PROPERTIES :
                            self.propWidget.append( EkdBoolPropertie(prop, EkdConfig.PROPERTIES[prop], allprops[prop], section=section) )
                            linelayout.addWidget(self.propWidget[wid].widget, row, 0, 1, 2)
                            wid += 1
                            found = True
                        row += 1
                for prop in allkeys :
                    if not prop in EkdConfig.PROPERTIES_MASK :
                        if prop in EkdConfig.NUM_PROPERTIES :
                            self.propWidget.append( EkdNumPropertie(prop, EkdConfig.PROPERTIES[prop], allprops[prop], section=section) )
                            linelayout.addWidget(self.propWidget[wid].label, row, 0)
                            linelayout.addWidget(self.propWidget[wid].widget, row, 1)
                            wid += 1
                            found = True
                        row += 1
                for prop in allkeys :
                    if not prop in EkdConfig.PROPERTIES_MASK :
                        if prop in EkdConfig.TIME_PROPERTIES :
                            self.propWidget.append( EkdTimePropertie(prop, EkdConfig.PROPERTIES[prop], allprops[prop], section=section) )
                            linelayout.addWidget(self.propWidget[wid].label, row, 0)
                            linelayout.addWidget(self.propWidget[wid].widget, row, 1)
                            wid += 1
                            found = True
                        row += 1
                for prop in allkeys :
                    if not prop in EkdConfig.PROPERTIES_MASK :
                        if prop in EkdConfig.COLOR_PROPERTIES :
                            self.propWidget.append( EkdColorPropertie(prop, EkdConfig.PROPERTIES[prop], allprops[prop], section=section) )
                            linelayout.addWidget(self.propWidget[wid].label, row, 0)
                            linelayout.addWidget(self.propWidget[wid].widget, row, 1)
                            wid += 1
                            found = True
                        elif not found:
                            line = QLineEdit(allprops[prop])
                            linelayout.addWidget(QLabel(prop), row, 0)
                            linelayout.addWidget(line, row, 1)
                        row += 1

                frame.setLineWidth(0)
                scroll.setWidget(frame)
                self.leftpart.addWidget(scroll)

        self.menu.setAlternatingRowColors(True)
        # Define the size of the list depending of its content
        self.menu.setFixedHeight(( self.menu.sizeHintForRow(0) + self.menu.verticalStepsPerItem() + 1)* self.menu.count())
        self.menu.updateGeometries()

        ## Boutton pour  fermer la boite de dialogue
        self.fermer = QPushButton(_(u"Fermer"))
        self.layout.addWidget(self.fermer)

        ## Lorsqu'on clique sur fermer, la fenêtre se ferme
        self.connect(self.fermer, SIGNAL("clicked()"), self.close)

        ## Lorsqu'on selectionne un élément du menu, on met à jour la partie droite du menu
        self.connect(self.menu, SIGNAL("currentItemChanged(QListWidgetItem *,QListWidgetItem *)"), self.updateMenu)

    def updateMenu(self):
        propriete = self.menu.currentRow()
        self.leftpart.setCurrentIndex(propriete)
Exemple #47
0
class StringListDlg(QDialog):

    acceptedList = Signal(QStringList)

    def __init__(self, name, stringlist=None, parent=None):
        super(StringListDlg, self).__init__(parent)
        self.name = name
        self.create_widgets(stringlist)
        self.layout_widgets()
        self.setWindowTitle("Edit {0} List".format(self.name))

    def create_widgets(self, stringlist):
        self.listWidget = QListWidget()
        if stringlist is not None:
            self.listWidget.addItems(stringlist)
            self.listWidget.setCurrentRow(0)

    def layout_widgets(self):
        buttonLayout = QVBoxLayout()
        for text, slot in (("&Add...", self.add), ("&Edit...", self.edit),
                           ("&Remove...", self.remove), ("&Up", self.up),
                           ("&Down", self.down), ("&Sort",
                                                  self.listWidget.sortItems),
                           ("Close", self.accept)):
            button = QPushButton(text)
            if not MAC:
                button.setFocusPolicy(Qt.NoFocus)
            if text == "Close":
                buttonLayout.addStretch()
            buttonLayout.addWidget(button)
            button.clicked.connect(slot)
        layout = QHBoxLayout()
        layout.addWidget(self.listWidget)
        layout.addLayout(buttonLayout)
        self.setLayout(layout)

    def add(self):
        row = self.listWidget.currentRow()
        title = "Add {0}".format(self.name)
        string, ok = QInputDialog.getText(self, title, title)
        if ok and not string.isEmpty():
            self.listWidget.insertItem(row, string)

    def edit(self):
        row = self.listWidget.currentRow()
        item = self.listWidget.item(row)
        if item is not None:
            title = "Edit {0}".format(self.name)
            string, ok = QInputDialog.getText(self, title, title,
                                              QLineEdit.Normal, item.text())
            if ok and not string.isEmpty():
                item.setText(string)

    def remove(self):
        row = self.listWidget.currentRow()
        item = self.listWidget.item(row)
        if item is None:
            return
        reply = QMessageBox.question(
            self, "Remove {0}".format(self.name),
            "Remove {0} `{1}'?".format(self.name, unicode(item.text())),
            QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes:
            item = self.listWidget.takeItem(row)
            del item

    def up(self):
        row = self.listWidget.currentRow()
        if row >= 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(row - 1, item)
            self.listWidget.setCurrentItem(item)

    def down(self):
        row = self.listWidget.currentRow()
        if row < self.listWidget.count() - 1:
            item = self.listWidget.takeItem(row)
            self.listWidget.insertItem(row + 1, item)
            self.listWidget.setCurrentItem(item)

    def reject(self):
        self.accept()

    def accept(self):
        self.stringlist = QStringList()
        for row in range(self.listWidget.count()):
            self.stringlist.append(self.listWidget.item(row).text())
        self.acceptedList.emit(self.stringlist)
        QDialog.accept(self)
Exemple #48
0
class NewSessionPagePermutations(QWizardPage):
    def __init__(self):
        super(NewSessionPagePermutations, self).__init__()
        self.setTitle(_('Configuration of permutations'))
        self.setSubTitle(
            _('Select the position of each question'
              ' and its choices in every model of the exam.'))
        layout = QGridLayout()
        self.question_list = QListWidget()
        self.permutation_grid = QGridLayout()
        self.alternatives_rows = {}
        layout.addWidget(QLabel(_('Questions of model A')), 0, 0, 1, 1)
        layout.addWidget(self.question_list, 1, 0, 1, 1)
        layout.addWidget(QLabel(_('Model equivalence')), 0, 1, 1, 5)
        self.permutation_grid.setVerticalSpacing(20)
        layout.addLayout(self.permutation_grid, 1, 1, 1, 5)
        layout.setColumnStretch(0, 1)
        layout.setColumnStretch(1, 5)
        self.setLayout(layout)

    def initializePage(self):
        paramNAlts = int(self.field("paramNAlts").toString())
        paramNPerm = int(self.field("paramNPerm").toString())
        self.question_list.clear()
        # Creation of the list section
        paramNCols_array = self.field("paramNCols").toString().split(',')
        total_questions = 1 + (int(paramNCols_array[0]) \
                               if len(paramNCols_array) == 1 \
                               else reduce(lambda x, y: int(x) + int(y),
                                           paramNCols_array))
        for i in range(1, total_questions):
            questions_list = QListWidgetItem(_('Question ') + str(i))
            questions_list.setData(Qt.UserRole,
                                   widgets.ItemList(
                                       optionName=_('Question ') + str(i),
                                       optionNumber=i))  # Custom item list
            self.question_list.addItem(questions_list)
        self.question_list.setCurrentRow(0)
        self.question_list.itemClicked.connect(self._on_item_changed)
        # Creation of the grid section
        add_header = True  # Header of the columns (Name of alternatives)
        for j in range(0, paramNPerm):
            self.permutation_grid.addWidget( \
                                QLabel(_('Model ') + chr(97 + j).upper()), j, 1)
            self.alternatives_rows[j] = {}
            for k in range(0, paramNAlts):
                if add_header:
                    if k == 0:
                        self.permutation_grid.addWidget(QLabel(''), 0, 1)
                    self.permutation_grid.addWidget( \
                                        QLabel(chr(97 + k).upper()), 0, k + 2)
                self.alternatives_rows[j][k] = \
                    widgets.InputComboBox(self, c_type='alternative',
                                          form=j, alternative=k)
                self.alternatives_rows[j][k].addItems( \
                            [chr(97+x).upper() for x in range(0,paramNAlts)])
                self.alternatives_rows[j][k].setCurrentIndex(0)
                self.permutation_grid.addWidget(self.alternatives_rows[j][k],
                                                j, k + 2)
            add_header = False
            self.alternatives_rows[j][k + 1] = \
                widgets.InputComboBox(self, c_type='question', form=j,
                                      alternative=self.question_list.\
                                          currentItem().\
                                          data(Qt.UserRole).toPyObject().\
                                               get_question_number())
            self.alternatives_rows[j][k + 1].addItems( \
                                [str(x) for x in range(1,total_questions)])
            self.alternatives_rows[j][k + 1].setCurrentIndex(0)
            self.permutation_grid.addWidget(QLabel(_('Question Number')), j,
                                            k + 3)
            self.permutation_grid.addWidget(self.alternatives_rows[j][k + 1],
                                            j, k + 4)
        button_save = QPushButton(_('Save values'))
        self.permutation_grid.addWidget(button_save, j + 1, 1, 1, k + 4)
        button_save.clicked.connect(self._save_values)

    def _on_item_changed(self, arg=None):
        permutation = arg.data(Qt.UserRole).toPyObject().get_permutation()
        for k, v in self.alternatives_rows.iteritems():
            for sk, sv in v.iteritems():
                if not permutation:
                    sv.setCurrentIndex(0)
                else:
                    sv.setCurrentIndex( \
                        [x for x in permutation \
                         if (x['altr'] == sv.alternative
                             and x['form'] == sv.form
                             and x['c_type'] == sv.c_type)][0]['perm'] - 1)
        return True

    def _save_values(self):
        localItem = self.question_list.currentItem()
        formatted_grid = self._get_formatted_permutation_grid()
        if self._validate_grid(formatted_grid):
            localItem.setBackgroundColor(QColor(0, 255, 68))
            localItem.data(Qt.UserRole).toPyObject()\
                     .set_permutation(formatted_grid)
            self._reset_permutation_grid()
            QMessageBox.information(
                self, _('Information status'),
                _('The values for the question have been successfully saved'))
            return True
        else:
            QMessageBox.critical(self, _('Error in grid'),
                                 _('There is an inconsistence in the options'))
            return False

    def _get_formatted_permutation_grid(self):
        local_alternatives_rows = []
        for k, v in self.alternatives_rows.iteritems():
            for sk, sv in v.iteritems():
                alternative = {
                    'c_type': sv.c_type,
                    'form': sv.form,
                    'altr': sv.alternative,
                    'perm': sv.currentIndex() + 1
                }
                local_alternatives_rows.append(alternative)
        return local_alternatives_rows

    def _validate_grid(self, grid):
        #validate current grid and questions number
        forms = {}
        for row in grid:
            if row['c_type'] == 'alternative':
                if row['form'] not in forms:
                    forms[row['form']] = []
                if row['perm'] in forms[row['form']]:
                    return False
                else:
                    forms[row['form']].append(row['perm'])
            if row['c_type'] == 'question':
                for i in xrange(self.question_list.count()):
                    if i == self.question_list.currentRow():
                        continue
                    perm = self.question_list.item(i).data(Qt.UserRole)\
                               .toPyObject().get_permutation()
                    for perm_row in perm:
                        if (perm_row['c_type'] == 'question'
                                and perm_row['form'] == row['form']
                                and perm_row['perm'] == row['perm']):
                            return False
        return True

    def _reset_permutation_grid(self):
        for k, v in self.alternatives_rows.iteritems():
            for sk, sv in v.iteritems():
                sv.setCurrentIndex(0)

    def _get_values(self):
        formated_permutation = {}
        formated_permutation_m = {}
        for i in xrange(self.question_list.count()):
            permutations = self.question_list.item(i).data(Qt.UserRole)\
                               .toPyObject().get_permutation()
            a = {}
            for p in permutations:
                if p['form'] not in formated_permutation:
                    formated_permutation[p['form']] = []
                if p['form'] not in a:
                    a[p['form']] = []
                if p['c_type'] == 'alternative':
                    a[p['form']].append(p['perm'])
                if p['c_type'] == 'question':
                    formated_permutation[p['form']].append( \
                        "%s{%s}" % (p['perm'], ','.join(str(x) \
                                                       for x in a[p['form']])))
        for k, v in formated_permutation.iteritems():
            formated_permutation_m[chr(97 + k).upper()] = '/'.join(v)
        return formated_permutation_m

    def validatePage(self):
        valid = True
        msg = ''
        for i in xrange(self.question_list.count()):
            if not self.question_list.item(i).data(Qt.UserRole)\
                .toPyObject().get_permutation():
                valid = False
                msg = _('You must select all permutations for all questions')
                break
        if not valid:
            QMessageBox.critical(self, _('Error'), msg)
        else:
            current_permutations = self._get_values()
            for k, v in current_permutations.iteritems():
                self.wizard().exam_config.set_permutations(k, v)
        return valid

    def nextId(self):
        return WizardNewSession.PageIdFiles
Exemple #49
0
class FiltersDialog(Window):
    def __init__(self, base):
        Window.__init__(self, base, i18n.get('filters'))
        self.setFixedSize(280, 360)

        self.expression = QLineEdit()
        self.expression.returnPressed.connect(self.__new_filter)

        self.new_button = QPushButton(i18n.get('add_filter'))
        self.new_button.setToolTip(i18n.get('create_a_new_filter'))
        self.new_button.clicked.connect(self.__new_filter)

        expression_box = QHBoxLayout()
        expression_box.addWidget(self.expression)
        expression_box.addWidget(self.new_button)

        self.list_ = QListWidget()
        self.list_.clicked.connect(self.__filter_clicked)

        self.delete_button = QPushButton(i18n.get('delete'))
        self.delete_button.setEnabled(False)
        self.delete_button.setToolTip(i18n.get('delete_selected_filter'))
        self.delete_button.clicked.connect(self.__delete_filter)

        self.clear_button = QPushButton(i18n.get('delete_all'))
        self.clear_button.setEnabled(False)
        self.clear_button.setToolTip(i18n.get('delete_all_filters'))
        self.clear_button.clicked.connect(self.__delete_all)

        button_box = QHBoxLayout()
        button_box.addStretch(1)
        button_box.addWidget(self.clear_button)
        button_box.addWidget(self.delete_button)

        layout = QVBoxLayout()
        layout.addLayout(expression_box)
        layout.addWidget(self.list_, 1)
        layout.addLayout(button_box)
        layout.setSpacing(5)
        layout.setContentsMargins(5, 5, 5, 5)
        self.setLayout(layout)
        self.__update()
        self.show()

    def __update(self):
        row = 0
        self.expression.setText('')
        self.list_.clear()
        for expression in self.base.core.list_filters():
            self.list_.addItem(expression)
            row += 1

        self.__enable(True)
        self.delete_button.setEnabled(False)
        if row == 0:
            self.clear_button.setEnabled(False)
        self.expression.setFocus()

    def __filter_clicked(self, point):
        self.delete_button.setEnabled(True)
        self.clear_button.setEnabled(True)

    def __new_filter(self):
        expression = str(self.expression.text())
        self.list_.addItem(expression)
        self.__save_filters()

    def __delete_filter(self):
        self.list_.takeItem(self.list_.currentRow())
        self.__save_filters()

    def __delete_all(self):
        self.__enable(False)
        message = i18n.get('clear_filters_confirm')
        confirmation = self.base.show_confirmation_message(i18n.get('confirm_delete'),
            message)
        if not confirmation:
            self.__enable(True)
            return
        self.list_.clear()
        self.__save_filters()

    def __enable(self, value):
        self.list_.setEnabled(value)
        self.delete_button.setEnabled(value)
        self.clear_button.setEnabled(value)

    def __save_filters(self):
        filters = []
        for i in range(self.list_.count()):
            filters.append(str(self.list_.item(i).text()))
        self.base.save_filters(filters)
        self.__update()
class Window(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.media = Phonon.MediaObject(self)
        ### video widget ####
        self.video = Phonon.VideoWidget(self)
        self.video.setMinimumSize(320,200)
        self.videoCuts = []
        self.myfilename = ""
        self.extension = ""
        self.t1 = ""
        self.t2 = ""
        self.t3 = ""
        self.t4 = ""
        self.t5 = ""
        self.t6 = ""

        ### open button ###
        self.button = QtGui.QPushButton('Choose Video', self)
        self.button.setFixedWidth(90)
        self.button.clicked.connect(self.handleButton)
        self.button.setStyleSheet(stylesheet(self))

		### context menu ####
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.popup2)

        ### play / pause button ###
        self.playbutton = QtGui.QPushButton('Play', self)
        self.playbutton.setFixedWidth(70)
        self.playbutton.clicked.connect(self.handlePlayButton)
        self.playbutton.setStyleSheet(stylesheet(self))
        self.connect(QtGui.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Space), self), QtCore.SIGNAL('activated()'), self.handlePlayButton)
        self.connect(QtGui.QShortcut(QtGui.QKeySequence("Ctrl+o"), self), QtCore.SIGNAL('activated()'), self.handleButton)
        self.connect(QtGui.QShortcut(QtGui.QKeySequence("Ctrl+s"), self), QtCore.SIGNAL('activated()'), self.handleSaveVideo)
        self.connect(QtGui.QShortcut(QtGui.QKeySequence("Ctrl+q"), self), QtCore.SIGNAL('activated()'), self.handleQuit)
        ### save button ###
        self.savebutton = QtGui.QPushButton('Save Video', self)
        self.savebutton.setFixedWidth(90)
        self.savebutton.clicked.connect(self.handleSaveVideo)
        self.savebutton.setStyleSheet(stylesheet(self))

        ### seek slider ###
        self.slider = Phonon.SeekSlider(self.media)
        self.slider.setStyleSheet(stylesheet(self))
        isize = QSize(16,16)
        self.slider.setIconSize(isize)
        self.slider.setFocus()
       # self.slider.connect(self.handleLabel)

        ### connection position to label ###
        self.media.isSeekable()
        self.media.tick.connect(self.handleLabel)
        self.media.seekableChanged.connect(self.handleLabel)
        #self.slider.wheel.connect(self.handleLabel)

        ### table view ###
        self.iconList = QListWidget()
        self.iconList.setAlternatingRowColors(True)
        self.iconList.setFixedWidth(200)
        self.iconList.setContextMenuPolicy(Qt.CustomContextMenu)
        self.iconList.setStyleSheet("QListWidget::item:selected:active { background: #7D8ED9; color:#FFFFFF; } ")
        self.iconList.setViewMode(0)
        self.iconList.setSelectionBehavior(1)
        self.iconList.setIconSize(QSize(80, 80/1.78))
        self._hookListActions()
        self.iconList.customContextMenuRequested.connect(self._openListMenu)

                ### set start button ###
        self.startbutton = QtGui.QPushButton('set Start', self)
        self.startbutton.setFixedWidth(70)
        self.startbutton.clicked.connect(self.handleStartButton)
        self.startbutton.setStyleSheet(stylesheet(self))
        self.connect(QtGui.QShortcut(QtGui.QKeySequence("s"), self), QtCore.SIGNAL('activated()'), self.handleStartButton)

                ### set end button ###
        self.endbutton = QtGui.QPushButton('set End', self)
        self.endbutton.setFixedWidth(70)
        self.endbutton.clicked.connect(self.handleEndButton)
        self.endbutton.setStyleSheet(stylesheet(self))
        self.connect(QtGui.QShortcut(QtGui.QKeySequence("e"), self), QtCore.SIGNAL('activated()'), self.handleEndButton)
                ### label ###
        self.mlabel = QtGui.QLabel('Frame', self)
        self.mlabel.setStyleSheet('QLabel \
				{background-color: transparent; color: white;}\nQLabel{color: darkcyan; font-size: 12px; background-color: transparent; border-radius: 5px; padding: 6px; text-align: center;}\n QLabel:hover{color: red;}')
        #self.mlabel.setFixedWidth(80)

        ### layout ###
        layout = QtGui.QGridLayout(self)
        layout.addWidget(self.iconList, 0, 0, 1, 1)
        layout.addWidget(self.video, 0, 1, 1, 6)
        layout.addWidget(self.slider, 1, 1, 1, 6)
        layout.addWidget(self.button, 2, 0, 1, 1)
        layout.addWidget(self.savebutton, 2, 1, 1, 1)
        layout.addWidget(self.playbutton, 2, 3, 1, 1)
        layout.addWidget(self.startbutton, 2, 5, 1, 1)
        layout.addWidget(self.endbutton, 2, 6, 1, 1)
        layout.addWidget(self.mlabel, 2, 4, 1, 1)

    def popup2(self, pos):	
        contextmenu = QMenu()
        contextmenu.addAction("Play / Pause (SPACE)", self.handlePlayButton)
        contextmenu.addSeparator()
        contextmenu.addAction("Load Video (Ctrl-O)", self.handleButton)
        contextmenu.addAction("Save Video (Ctrl-S)", self.handleSaveVideo)
        contextmenu.addSeparator()
        contextmenu.addAction("Info", self.handleInfo)
        contextmenu.addSeparator()
        contextmenu.addAction("Exit (q)", self.handleQuit)
        contextmenu.exec_(QCursor.pos())

    def handleInfo(self):
            msg = QMessageBox()
            #msg.setFixedSize(500, 300)
            #msg.setGeometry(100,100, 400, 200)
            msg.setIcon(QMessageBox.Information)
            msg.setText("Axel Schneider")
            msg.setInformativeText(unicode(u"©2016"))
            msg.setWindowTitle("Cut Video")
            msg.setDetailedText("Python Qt4")
            msg.setStandardButtons(QMessageBox.Ok)
	
            retval = msg.exec_()
            print "value of pressed message box button:", retval

    def handleQuit(self):
        app.quit()

    def handleButton(self):
        if self.media.state() == Phonon.PlayingState:
            self.media.stop()
        else:
            path = QtGui.QFileDialog.getOpenFileName(self, ("Video laden"),
                                                	'/Axel_1/Filme',
                                                	"Videos (*.ts *.mp4)")
            if path:
                self.myfilename = unicode(path) #.encode("utf-8")
                window.setWindowTitle(self.myfilename.split("/")[-1])
                self.extension = path.split(".")[1]
                print(self.extension)
                self.media.setCurrentSource(Phonon.MediaSource(path))
                self.video.setScaleMode(1)
                self.video.setAspectRatio(1)
                self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self)
                Phonon.createPath(self.media, self.audio)
                Phonon.createPath(self.media, self.video)
                self.media.play()
                self.playbutton.setText('Pause')

    def handleSaveVideo(self):
        result = QFileDialog.getSaveFileName(self, ("Video speichern"),
             						'/tmp/film.' + str(self.extension),
             						"Videos (*.ts *.mp4)")
        if result:
            target = unicode(result)
            self.t1 = float(self.videoCuts[0])
            self.t2 = float(self.videoCuts[1])
            ffmpeg_extract_subclip(self.myfilename, self.t1, self.t2, targetname=target)
            window.setWindowTitle("Film gespeichert")
            self.purgeMarker()

    def handlePlayButton(self):
        if self.media.state() == Phonon.PlayingState:
            self.media.pause()
            self.playbutton.setText('Play')
				
        else:
            #print(self.iconList.count())
            self.media.play()
            self.playbutton.setText('Pause')

    def handleStartButton(self):
        if self.iconList.count() < 2:
            rm = str(self.media.currentTime() / 100.00 / 10.00)
            item = QListWidgetItem()
            img = QImage(self.video.snapshot())
            pix = QtGui.QPixmap.fromImage(img)
            item.setIcon(QIcon(pix))
            item.setText("Start: " + rm)
            self.iconList.addItem(item)
            self.videoCuts.append(rm)
        else:
            return

    def handleEndButton(self):
        if self.iconList.count() < 2:
            rm = str(self.media.currentTime() / 100.00 / 10.00)
            item = QListWidgetItem()
            #item.setSizeHint(QSize(150, 40))
            img = QImage(self.video.snapshot())
            pix = QtGui.QPixmap.fromImage(img)
            item.setIcon(QIcon(pix))
            item.setText("End: " + rm)
            self.iconList.addItem(item)
            self.videoCuts.append(rm)
            self.t3 = float(str(self.media.remainingTime()))
            print(self.t3)
            self.media.stop()
            self.playbutton.setText('Play')
        else:
            return

    def handleLabel(self):
            ms = self.media.currentTime()
            seconds=str((ms/1000)%60)
            minutes=str((ms/(1000*60))%60)
            hours=str((ms/(1000*60*60))%24)
            if int(seconds) < 10:
                seconds = "0" + seconds
            if int(minutes) < 10:
                minutes = "0" + minutes
            if int(hours) < 10:
                hours = "0" + hours
                s = hours + ":" + minutes + ":" + seconds
                self.mlabel.setText(s)

    def _hookListActions(self):
        #TOO bad-the list model -should be here...
        rmAction = QtGui.QAction(QtGui.QIcon('icons/close-x.png'), 'entfernen', self)
        rmAction.triggered.connect(self._removeMarker)
        rmAllAction = QtGui.QAction(QtGui.QIcon('icons/clear-all.png'), 'alle entfernen', self)
        rmAllAction.triggered.connect(self.purgeMarker)
        self.gotoAction = QtGui.QAction(QtGui.QIcon('icons/go-next.png'), 'zu dieser Position springen', self)
        self.gotoAction.triggered.connect(self._gotoFromMarker)

        #menus
        self._listMenu = QMenu()
        self._listMenu.addAction(self.gotoAction)
        self._listMenu.addSeparator()
        self._listMenu.addAction(rmAction)
        self._listMenu.addAction(rmAllAction)

    #---List widget context menu
    def _removeMarker(self,whatis):
        selectionList = self.iconList.selectedIndexes()
        if len(selectionList)==0:
            return
        item = selectionList[0]
        self.iconList.takeItem(item.row())
        #self.videoCuts.remove[1])

    def clearMarkerList(self):
        self.iconList.clear()

    #remove contents, remove file
    def purgeMarker(self):
        self.iconList.clear()
        self.videoCuts = []

    def _gotoFromMarker(self,whatis):
        selectionList = self.iconList.selectedIndexes()
        if len(selectionList)==0:
            return
        item = selectionList[0]
        pos = item.data().toString().replace("Start: ", "").replace("End: ", "")
        #frame = pos.ToInt()
        #self.video.currentTime = 1589
        self.setWindowTitle(pos)

    def _openListMenu(self,position):
        selectionList = self.iconList.selectedIndexes()
        if len(selectionList)==0:
            return
        self._listMenu.exec_(self.iconList.viewport().mapToGlobal(position))
Exemple #51
0
 def add_list_box(self, choicesL, 
                       name='isBell', init_val=3, layout=None,
                       advance_n=True, fulldesc='Nozzle Geometry', 
                       connect_function=None, text_font=ARIAL_10, col=0,
                       parent=None, fit_size_to_contents=True,  width=1, height=1):
                    
     # if parent is input, add widget to parent
     if parent is None:
         parent = self
     
     if layout is None:
         NRow = parent.get_next_row_number(advance_n)
         # Need to change next row number by length of choicesL
         #if advance_n:
         #    for i in range(1, len(choicesL)):
         #        parent.get_next_row_number(advance_n)
     
     self.selection_textD[name] = ''
     
     listWidget = QListWidget()
     for i,choice in enumerate( choicesL ):
         item = QListWidgetItem(choice)
         listWidget.addItem(item)
         if i == init_val:
             #item.setChecked(True)
             listWidget.setItemSelected( item, True )
             self.selection_textD[name] = choice
     
     if fulldesc:
         vbox = QtGui.QVBoxLayout()
         lbl = QLabel(fulldesc, parent)
         lbl.setFont( text_font )
         vbox.addWidget( lbl )
         
         self.objectD['%s_listbox_label'%name] = lbl
         self.input_widget_by_nameD['%s_listbox_label'%name] = (lbl , 'label')
         
         vbox.addWidget( listWidget )
         grid_child = QtGui.QWidget()
         grid_child.setLayout(vbox)
         
         vbox.addStretch(1)
     else:
         grid_child = listWidget
     
     if layout is None:
         if width==1 and height==1:
             parent.grid.addWidget(grid_child,  NRow, col)
         else:
             parent.grid.addWidget(grid_child,  NRow, col, height, width)
             #parent.grid.addWidget(grid_child,  NRow, col, len(choicesL), 1)
     else:
         layout.addWidget( grid_child )
     
     self.objectD['%s_list_box'%name] = listWidget
     self.input_widget_by_nameD[name] = (listWidget , 'list_box_list')
     
     listWidget.itemClicked.connect( lambda: self.list_box_changed( '%s_list_box'%name ) ) 
         
     if fit_size_to_contents:
         listWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
         listWidget.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
         listWidget.setFixedSize(listWidget.sizeHintForColumn(0) + 2 * listWidget.frameWidth(), 
                                 listWidget.sizeHintForRow(0) * listWidget.count() + \
                                 2 * listWidget.frameWidth())
Exemple #52
0
class CheckList(QWidget):
    def __init__(self, model, label="", help_link="", custom_filter_button=None):
        """
        :param custom_filter_button:  if needed, add a button that opens a custom filter menu. Useful when search alone
        isn't enough to filter the list.
        :type custom_filter_button: QToolButton
        """
        QWidget.__init__(self)

        self._model = model

        if help_link != "":
            addHelpToWidget(self, help_link)

        layout = QVBoxLayout()

        self._createCheckButtons()

        self._list = QListWidget()
        self._list.setContextMenuPolicy(Qt.CustomContextMenu)
        self._list.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self._search_box = SearchBox()

        check_button_layout = QHBoxLayout()

        check_button_layout.setMargin(0)
        check_button_layout.setSpacing(0)
        check_button_layout.addWidget(QLabel(label))
        check_button_layout.addStretch(1)
        check_button_layout.addWidget(self._checkAllButton)
        check_button_layout.addWidget(self._uncheckAllButton)

        layout.addLayout(check_button_layout)
        layout.addWidget(self._list)

        """
        Inserts the custom filter button, if provided. The caller is responsible for all related actions.
        """
        if custom_filter_button is not None:
            search_bar_layout = QHBoxLayout()
            search_bar_layout.addWidget(self._search_box)
            search_bar_layout.addWidget(custom_filter_button)
            layout.addLayout(search_bar_layout)
        else:
            layout.addWidget(self._search_box)

        self.setLayout(layout)

        self._checkAllButton.clicked.connect(self.checkAll)
        self._uncheckAllButton.clicked.connect(self.uncheckAll)
        self._list.itemChanged.connect(self.itemChanged)
        self._search_box.filterChanged.connect(self.filterList)
        self._list.customContextMenuRequested.connect(self.showContextMenu)

        self._model.selectionChanged.connect(self.modelChanged)
        self._model.modelChanged.connect(self.modelChanged)

        self.modelChanged()

    def _createCheckButtons(self):
        self._checkAllButton = QToolButton()
        self._checkAllButton.setIcon(resourceIcon("checked"))
        self._checkAllButton.setIconSize(QSize(16, 16))
        self._checkAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self._checkAllButton.setAutoRaise(True)
        self._checkAllButton.setToolTip("Select all")
        self._uncheckAllButton = QToolButton()
        self._uncheckAllButton.setIcon(resourceIcon("notchecked"))
        self._uncheckAllButton.setIconSize(QSize(16, 16))
        self._uncheckAllButton.setToolButtonStyle(Qt.ToolButtonIconOnly)
        self._uncheckAllButton.setAutoRaise(True)
        self._uncheckAllButton.setToolTip("Unselect all")

    def itemChanged(self, item):
        """@type item: QListWidgetItem"""
        if item.checkState() == Qt.Checked:
            self._model.selectValue(str(item.text()))
        elif item.checkState() == Qt.Unchecked:
            self._model.unselectValue(str(item.text()))
        else:
            raise AssertionError("Unhandled checkstate!")

    def modelChanged(self):
        self._list.clear()

        items = self._model.getList()

        for item in items:
            list_item = QListWidgetItem(item)
            list_item.setFlags(list_item.flags() | Qt.ItemIsUserCheckable)

            if self._model.isValueSelected(item):
                list_item.setCheckState(Qt.Checked)
            else:
                list_item.setCheckState(Qt.Unchecked)

            self._list.addItem(list_item)

        self.filterList(self._search_box.filter())

    def setSelectionEnabled(self, enabled):
        self.setEnabled(enabled)
        self._checkAllButton.setEnabled(enabled)
        self._uncheckAllButton.setEnabled(enabled)

    def filterList(self, filter):
        filter = filter.lower()

        for index in range(0, self._list.count()):
            item = self._list.item(index)
            text = str(item.text()).lower()

            if filter == "":
                item.setHidden(False)
            elif filter in text:
                item.setHidden(False)
            else:
                item.setHidden(True)

    def checkAll(self):
        """
        Checks all visible items in the list.
        """
        for index in range(0, self._list.count()):
            item = self._list.item(index)
            if not item.isHidden():
                self._model.selectValue(str(item.text()))

    def uncheckAll(self):
        """
        Unchecks all items in the list, visible or not
        """
        self._model.unselectAll()

    def checkSelected(self):
        items = []
        for item in self._list.selectedItems():
            items.append(str(item.text()))

        for item in items:
            self._model.selectValue(item)

    def uncheckSelected(self):
        items = []
        for item in self._list.selectedItems():
            items.append(str(item.text()))

        for item in items:
            self._model.unselectValue(item)

    def showContextMenu(self, point):
        p = self._list.mapToGlobal(point)
        menu = QMenu()
        check_selected = menu.addAction("Check selected")
        uncheck_selected = menu.addAction("Uncheck selected")
        menu.addSeparator()
        clear_selection = menu.addAction("Clear selection")

        selected_item = menu.exec_(p)

        if selected_item == check_selected:
            self.checkSelected()
        elif selected_item == uncheck_selected:
            self.uncheckSelected()
        elif selected_item == clear_selection:
            self._list.clearSelection()
class GroupSelectParameterWidget(GenericParameterWidget):

    """Widget class for Group Select Parameter."""

    def __init__(self, parameter, parent=None):
        """Constructor.

        :param parameter: A GroupSelectParameter object.
        :type parameter: GroupSelectParameter
        """
        QWidget.__init__(self, parent)
        self._parameter = parameter

        # Store spin box
        self.spin_boxes = {}

        # Create elements
        # Label (name)
        self.label = QLabel(self._parameter.name)

        # Layouts
        self.main_layout = QVBoxLayout()
        self.input_layout = QVBoxLayout()

        # _inner_input_layout must be filled with widget in the child class
        self.inner_input_layout = QVBoxLayout()

        self.radio_button_layout = QGridLayout()

        # Create radio button group
        self.input_button_group = QButtonGroup()

        # List widget
        self.list_widget = QListWidget()
        self.list_widget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.list_widget.setDragDropMode(QAbstractItemView.DragDrop)
        self.list_widget.setDefaultDropAction(Qt.MoveAction)
        self.list_widget.setEnabled(False)
        self.list_widget.setSizePolicy(
            QSizePolicy.Maximum, QSizePolicy.Expanding)

        for i, key in enumerate(self._parameter.options):
            value = self._parameter.options[key]
            radio_button = QRadioButton(value.get('label'))
            self.radio_button_layout.addWidget(radio_button, i, 0)
            if value.get('type') == SINGLE_DYNAMIC:
                double_spin_box = QDoubleSpinBox()
                self.radio_button_layout.addWidget(double_spin_box, i, 1)
                double_spin_box.setValue(value.get('value', 0))
                double_spin_box.setMinimum(
                    value.get('constraint', {}).get('min', 0))
                double_spin_box.setMaximum(value.get(
                    'constraint', {}).get('max', 1))
                double_spin_box.setSingleStep(
                    value.get('constraint', {}).get('step', 0.01))
                step = double_spin_box.singleStep()
                if step > 1:
                    precision = 0
                else:
                    precision = len(str(step).split('.')[1])
                    if precision > 3:
                        precision = 3
                double_spin_box.setDecimals(precision)
                self.spin_boxes[key] = double_spin_box

                # Enable spin box depends on the selected option
                if self._parameter.selected == key:
                    double_spin_box.setEnabled(True)
                else:
                    double_spin_box.setEnabled(False)

            elif value.get('type') == STATIC:
                static_value = value.get('value', 0)
                if static_value is not None:
                    self.radio_button_layout.addWidget(
                        QLabel(str(static_value)), i, 1)
            elif value.get('type') == MULTIPLE_DYNAMIC:
                selected_fields = value.get('value', [])
                if self._parameter.selected == key:
                    self.list_widget.setEnabled(True)
                else:
                    self.list_widget.setEnabled(False)

            self.input_button_group.addButton(radio_button, i)
            if self._parameter.selected == key:
                radio_button.setChecked(True)

        # Help text
        self.help_label = QLabel(self._parameter.help_text)
        self.help_label.setSizePolicy(
            QSizePolicy.Maximum, QSizePolicy.Expanding)
        self.help_label.setWordWrap(True)
        self.help_label.setAlignment(Qt.AlignTop)

        self.inner_input_layout.addLayout(self.radio_button_layout)
        self.inner_input_layout.addWidget(self.list_widget)

        # Put elements into layouts
        self.input_layout.addWidget(self.label)
        self.input_layout.addLayout(self.inner_input_layout)

        self.help_layout = QVBoxLayout()
        self.help_layout.addWidget(self.help_label)

        self.main_layout.addLayout(self.input_layout)
        self.main_layout.addLayout(self.help_layout)

        self.setLayout(self.main_layout)

        self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Expanding)

        # Update list widget
        self.update_list_widget()

        # Connect signal
        self.input_button_group.buttonClicked.connect(
            self.radio_buttons_clicked)

    def get_parameter(self):
        """Obtain list parameter object from the current widget state.

        :returns: A DefaultValueParameter from the current state of widget
        :rtype: DefaultValueParameter
        """
        # Set value for each key
        for key, value in self._parameter.options.items():
            if value.get('type') == STATIC:
                continue
            elif value.get('type') == SINGLE_DYNAMIC:
                new_value = self.spin_boxes.get(key).value()
                self._parameter.set_value_for_key(key, new_value)
            elif value.get('type') == MULTIPLE_DYNAMIC:
                # Need to iterate through all items
                items = []
                for index in xrange(self.list_widget.count()):
                    items.append(self.list_widget.item(index))
                new_value = [i.text() for i in items]
                self._parameter.set_value_for_key(key, new_value)

        # Get selected radio button
        radio_button_checked_id = self.input_button_group.checkedId()
        # No radio button checked, then default value = None
        if radio_button_checked_id == -1:
            self._parameter.selected = None
        else:
            self._parameter.selected = self._parameter.options.keys()[
                radio_button_checked_id]

        return self._parameter

    def update_list_widget(self):
        """Update list widget when radio button is clicked."""
        # Get selected radio button
        radio_button_checked_id = self.input_button_group.checkedId()
        # No radio button checked, then default value = None
        if radio_button_checked_id > -1:
            selected_dict = self._parameter.options.values()[
                radio_button_checked_id]
            if selected_dict.get('type') == MULTIPLE_DYNAMIC:
                for field in selected_dict.get('value'):
                    # Update list widget
                    field_item = QListWidgetItem(self.list_widget)
                    field_item.setFlags(
                        Qt.ItemIsEnabled |
                        Qt.ItemIsSelectable |
                        Qt.ItemIsDragEnabled)
                    field_item.setData(Qt.UserRole, field)
                    field_item.setText(field)
                    self.list_widget.addItem(field_item)

    def radio_buttons_clicked(self):
        """Handler when selected radio button changed."""
        # Disable all spin boxes
        for spin_box in self.spin_boxes.values():
            spin_box.setEnabled(False)
        # Disable list widget
        self.list_widget.setEnabled(False)

        # Get selected radio button
        radio_button_checked_id = self.input_button_group.checkedId()

        if radio_button_checked_id > -1:
            selected_value = self._parameter.options.values()[
                radio_button_checked_id]
            if selected_value.get('type') == MULTIPLE_DYNAMIC:
                # Enable list widget
                self.list_widget.setEnabled(True)
            elif selected_value.get('type') == SINGLE_DYNAMIC:
                selected_key = self._parameter.options.keys()[
                    radio_button_checked_id]
                self.spin_boxes[selected_key].setEnabled(True)

    def select_radio_button(self, key):
        """Helper to select a radio button with key.

        :param key: The key of the radio button.
        :type key: str
        """
        key_index = self._parameter.options.keys().index(key)
        radio_button = self.input_button_group.button(key_index)
        radio_button.click()
Exemple #54
0
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle('Address Book')
        self.resize(704, 459)
        self.db_file = self.database_file()
        self.db = database.Database(self.db_file)

        dialog = dialogs.UserPanelDlg(self)
        if dialog.exec_():
            self.user = dialog.user
        else:
            self.close()

        self.categComboBox = QComboBox()
        self.cont_numLabel = QLabel()
        self.contactsListWidget = QListWidget()
        self.searchLineEdit = QLineEdit()

        widgets = ((QLabel('Category:'), self.categComboBox),
                   (self.cont_numLabel, None),
                   (self.contactsListWidget,),
                   (QLabel('Search:'), self.searchLineEdit))
        vlayout1 = QVBoxLayout()

        for i in widgets:
            hlayout = pyqttools.add_to_layout(QHBoxLayout(), i)
            vlayout1.addLayout(hlayout)

        addToolButton = QToolButton()
        addToolButton.setIcon(QIcon(':addcontact.jpeg'))
        addToolButton.setIconSize(QSize(45, 45))
        self.showLabel = QLabel()
        self.showLabel.setFrameShape(QFrame.StyledPanel)
        self.showLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop)
        self.editButton = QPushButton('Edit')
        self.delButton = QPushButton('Delete')

        widgets = ((None, addToolButton, None),
                   (self.showLabel,),
                   (None, self.editButton, self.delButton))
        vlayout2 = QVBoxLayout()

        for i in widgets:
            hlayout = pyqttools.add_to_layout(QHBoxLayout(), i)
            vlayout2.addLayout(hlayout)

        f_layout = pyqttools.add_to_layout(QHBoxLayout(), (vlayout1, vlayout2))

        Widget = QWidget()
        Widget.setLayout(f_layout)
        self.setCentralWidget(Widget)

        self.statusBar = self.statusBar()
        self.userLabel = QLabel()
        self.statusBar.addPermanentWidget(self.userLabel)

        c_action = pyqttools.create_action
        panelAction = c_action(self, 'User panel', triggered=self.user_panel)
        quitAction = c_action(self, 'Quit', 'Ctrl+Q',triggered=self.close)
        add_contactAction = c_action(self, 'Add contact', 'Ctrl+N',
                                                    triggered=self.add_contact)
        delete_allAction = c_action(self, 'Delete all contacts',
                                                     triggered=self.delete_all)
        delete_categAction = c_action(self, 'Delete categories',
                                              triggered=self.delete_categories)
        backupAction = c_action(self, 'Backup', triggered=self.backup)
        restoreAction = c_action(self, 'Restore', triggered=self.restore)
        aboutAction = c_action(self, 'About', 'Ctrl+?', triggered=self.about)

        fileMenu = self.menuBar().addMenu('File')
        contactsMenu = self.menuBar().addMenu('Contacts')
        deleteMenu = self.menuBar().addMenu(self.tr('Delete'))
        backupMenu = self.menuBar().addMenu(self.tr('Backup'))
        helpMenu = self.menuBar().addMenu('Help')

        pyqttools.add_actions(fileMenu, [panelAction, None, quitAction])
        pyqttools.add_actions(contactsMenu, [add_contactAction])
        pyqttools.add_actions(deleteMenu,[delete_allAction,delete_categAction])
        pyqttools.add_actions(backupMenu, [backupAction, restoreAction])
        pyqttools.add_actions(helpMenu, [aboutAction])

        addToolButton.clicked.connect(self.add_contact)
        self.editButton.clicked.connect(self.edit_contact)
        self.delButton.clicked.connect(self.delete_contact)
        self.categComboBox.currentIndexChanged.connect(self.fill_ListWidget)
        self.contactsListWidget.currentRowChanged.connect(self.show_contact)
        self.searchLineEdit.textEdited.connect(self.search)

        self.fill_categComboBox()
        self.refresh_userLabel()

    def fill_categComboBox(self):
        categories = ['All']
        categories.extend([i[1] for i in self.db.get_categories(self.user)])
        self.categComboBox.currentIndexChanged.disconnect(self.fill_ListWidget)
        self.categComboBox.clear()
        self.categComboBox.addItems(categories)
        self.categComboBox.currentIndexChanged.connect(self.fill_ListWidget)
        self.fill_ListWidget()

    def fill_ListWidget(self):
        self.showLabel.clear()
        self.contactsListWidget.clear()
        if self.categComboBox.currentIndex() != 0: self.searchLineEdit.clear()

        category = self.categComboBox.currentText()
        if category == 'All':
            contacts = self.db.get_all_contacts(self.user)
        else:
            categ_id = self.db.get_category_id(category, self.user)
            if categ_id is None: return
            contacts = self.db.get_contacts(categ_id)
        for i in contacts:
            self.contactsListWidget.addItem(MyListItem(i[1]+' '+i[2], i[0]))

        self.contactsListWidget.setCurrentRow(0)
        self.refresh_contacts_number()
        self.set_buttons_enabled()

    def refresh_userLabel(self):
        self.userLabel.setText('User:  '******'Contacts Numer:  {0}'.format(self.contactsListWidget.count())
        self.cont_numLabel.setText(text)

    def set_buttons_enabled(self):
        enable = bool(self.contactsListWidget)
        self.editButton.setEnabled(enable)
        self.delButton.setEnabled(enable)

    def user_panel(self):
        dialog = dialogs.UserPanelDlg(self)
        if dialog.exec_():
            self.user = dialog.user
            self.fill_categComboBox()
            self.refresh_userLabel()

    def show_contact(self):
        try:
            _id = self.contactsListWidget.currentItem()._id
        except AttributeError:
            return
        _id, name, surname, mail, address, tel, categ_id = \
                                           self.db.get_contact_from_id(_id)[0]
        category = self.db.get_category_from_id(categ_id)
        text = ''
        data = (name, surname, mail, address, tel, category)
        labs = ('Name', 'Surname', 'e-mail', 'Address', 'Telephone', 'Category')
        for i, y in zip(labs, data):
            text += '''<p style=\' margin-top:0px; margin-bottom:0px; \'>
                  <span style=\' font-weight:600;\'>{0}:</span> {1} </p>\n'''\
                                                                  .format(i, y)
        self.showLabel.setText(text)

    def add_contact(self):
        categories = [i[1] for i in self.db.get_categories(self.user)]
        dialog = dialogs.AddorEditContactDlg(categories)
        if dialog.exec_():
            data = dialog.values
            if data[-1] not in categories:
                self.db.addto_categories(data[-1], self.user)
            categ_id = self.db.get_category_id(data[-1], self.user)
            data[-1] = categ_id
            self.db.addto_contacts(data)
            self.fill_categComboBox()

    def edit_contact(self):
        _id = self.contactsListWidget.currentItem()._id
        data = list(self.db.get_contact_from_id(_id)[0])
        categ = self.db.get_category_from_id(data[-1])
        data[-1] = categ
        categories = [i[1] for i in self.db.get_categories(self.user)]
        dialog = dialogs.AddorEditContactDlg(categories, True, data)
        if dialog.exec_():
            new_data = dialog.values
            if new_data[-1] not in categories:
                self.db.addto_categories(new_data[-1], self.user)
            categ_id = self.db.get_category_id(new_data[-1], self.user)
            new_data[-1] = categ_id
            self.db.edit_contact(new_data, _id)
            self.fill_categComboBox()

    def delete_contact(self):
        reply = QMessageBox.question(self, 'Address Book - Delete Contact',
        'Are you sure that you want to delete this contact?',
        QMessageBox.Yes|QMessageBox.Cancel)
        if reply == QMessageBox.Yes:
            _id = self.contactsListWidget.currentItem()._id
            self.db.delete_contact(_id)
            self.fill_ListWidget()

    def delete_all(self):
        reply = QMessageBox.question(self, 'Address Book - Delete Contact',
        'Are you sure that you want to delete all contacts?',
        QMessageBox.Yes|QMessageBox.Cancel)
        if reply == QMessageBox.Yes:
            self.db.delete_all_contacts()
            self.fill_ListWidget()

    def delete_categories(self):
        categories = [i[1] for i in self.db.get_categories(self.user)]
        dialogs.DelCategoriesDlg(categories, self).exec_()
        self.fill_categComboBox()

    def search(self):
        self.categComboBox.setCurrentIndex(0)
        self.showLabel.clear()
        self.contactsListWidget.clear()

        txt = self.searchLineEdit.text()

        if all(i == ' ' for i in txt):
            self.fill_ListWidget()
            return

        must_appear = []
        contacts = self.db.get_all_contacts(self.user)

        if not ' ' in txt:
            for i in contacts:
                if txt.lower() in i[1].lower() or txt.lower() in i[2].lower():
                    must_appear.append(i)
        else:
            try:
                first, last = txt.split()
            except ValueError:
                return
            for i in contacts:
                _bool = bool(first.lower() in i[1].lower() or first.lower() in
                             i[2].lower() or last.lower() in i[1].lower() or
                             last.lower() in i[2].lower())
                if _bool: must_appear.append(i)

        for i in must_appear:
            item = MyListItem(i[1] + ' ' + i[2], i[0])
            self.contactsListWidget.addItem(item)

        self.contactsListWidget.setCurrentRow(0)
        self.refresh_contacts_number()
        self.set_buttons_enabled()

    def backup(self):
        fname = QFileDialog.getSaveFileName(self,'Address Book - Backup','.db')
        if fname:
            try:
                shutil.copy(self.db_file, fname)
            except IOError:
                pass

    def restore(self):
        reply = QMessageBox.question(self, 'Address Book - Restore',
            'All current contacts will be deleted.\nAre you sure that you want'
            ' to continue?', QMessageBox.Yes|QMessageBox.Cancel)
        if reply == QMessageBox.Yes:
            fname = QFileDialog.getOpenFileName(self, 'Address Book - Restore')
            if fname:
                msg = 'Succesful restore!'
                try:
                    os.remove(self.db_file)
                    shutil.copy(fname, self.db_file)
                except (OSError, IOError):
                    msg = 'Restore failed!'
                QMessageBox.information(self, 'Addess Book - Restore', msg)
                self.db = database.Database(self.db_file)
                self.fill_categComboBox()

    def database_file(self):
        _file = 'addressbook.db'
        if not platform.platform().startswith('Windows'):
            folder = os.getenv('HOME') + os.sep + '.addressbook'
            if not os.path.exists(folder): os.mkdir(folder)
            _file = folder + os.sep + _file
        return _file

    def about(self):
        link = 'http://wiki.ubuntu-gr.org/Address%20Book'
        QMessageBox.about(self, self.tr('About') + ' FF Multi Converter',
            '''<b> Address Book {0} </b>
            <p>Gui application to organize your contacts!
            <p>Copyright &copy; 2012 Ilias Stamatis
            <br>License: GNU GPL3
            <p><a href='{1}'>http://wiki.ubuntu-gr.org/Address Book</a>
            <p>Python {2} - Qt {3} - PyQt {4} on {5}'''
            .format(__version__, link, platform.python_version()[:5],
            QT_VERSION_STR, PYQT_VERSION_STR, platform.system()))

    def close(self):
        self.db.close()
        sys.exit()
Exemple #55
0
class ImportDataDlg(QDialog):
    __isJy = False  # 数据校验成功的标志
    __mlist = []  # 定义一个列表用于保存从excel表中取出的数据

    def __init__(self, iface, parent=None, impType=ImpDateType.SITEANDCELL):
        super(ImportDataDlg, self).__init__()
        self.iface = iface
        self.parent = parent
        self.impType = impType
        self.initView()

    def initView(self):
        if self.impType == ImpDateType.SERVINGCELL:
            self.setWindowTitle(u'相邻小区数据导入')
        else:
            self.setWindowTitle(u'基站和小区数据导入')
        self.setWindowIcon(QIcon('images/logo.png'))
        self.resize(620, 480)

        # 数据表格
        self.tableWidget = QTableWidget(self)
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setRowCount(7)
        # 设置当前Table不能编辑
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # 初始化表格上下文菜单
        self.initTableContextMenu()
        # 初始化表头
        self.initTableHeader()
        # 导入出错列表
        self.listWidget = QListWidget(self)
        # 按钮组
        impBtn = QPushButton(u"导入EXCEL表", self)
        yzBtn = QPushButton(u"数据检验", self)
        impdateBtn = QPushButton(u"导入数据", self)
        btnVBox = QVBoxLayout()
        btnVBox.addWidget(impBtn)
        btnVBox.addWidget(yzBtn)
        btnVBox.addWidget(impdateBtn)
        # 错误列表与按钮组
        hBox = QHBoxLayout()
        hBox.setMargin(20)
        hBox.addWidget(self.listWidget)
        hBox.addLayout(btnVBox)

        self.mbar = QStatusBar(self)
        self.mbar.showMessage(u'准备就绪...')

        self.maction = QToolBar(self)
        self.editAction = QAction(u'编辑', self.maction)
        self.editAction.setCheckable(True)

        self.combox = QComboBox(self)
        self.combox.addItems(HeadsConfig.ImpExcelName)

        self.maction.addWidget(self.combox)
        self.maction.addAction(self.editAction)

        vBox = QVBoxLayout()
        vBox.addWidget(self.maction)
        vBox.addWidget(self.tableWidget)
        vBox.addLayout(hBox)
        vBox.addWidget(self.mbar)

        vBox.setStretchFactor(self.tableWidget, 9)
        vBox.setStretchFactor(hBox, 5)
        vBox.setStretchFactor(self.mbar, 1)

        self.setLayout(vBox)

        QObject.connect(impBtn, SIGNAL('clicked()'), self.impClick)
        QObject.connect(yzBtn, SIGNAL('clicked()'), self.yzClick)
        QObject.connect(impdateBtn, SIGNAL('clicked()'), self.impdateClick)
        QObject.connect(self.editAction, SIGNAL('triggered()'), self.editClick)
        QObject.connect(self.combox, SIGNAL('currentIndexChanged(int)'),
                        self.comboxChange)

        self.listWidget.doubleClicked.connect(self.mlistClicked)
        # self.connect(self.listWidget, SIGNAL("itemDoubleClicked (QListWidgetItem)"), self.mlistClicked)

    def initTableContextMenu(self):
        self.tableWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.popMenu = QMenu(self.tableWidget)
        delAction = QAction(u'删除', self)  # 删除
        self.popMenu.addAction(delAction)

    # 设置表格可以双击修改数据
    def setEditTriggers(self, isTrigger):
        if isTrigger:
            self.tableWidget.setEditTriggers(QAbstractItemView.DoubleClicked)
        else:
            self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)

    # 提供给外部修改状态栏消息
    def setStatusBarMsg(self, msg):
        self.mbar.showMessage(msg)

    # 选框改变时,清空当前表格的全部内容,包括表格头
    def updateType(self, mtype):
        self.impType = mtype
        self.tableWidget.clear()  # 清空表格所有内容
        self.initTableHeader()

    # 初始化表格的每个Item
    def initTable(self, mlist):
        self.tableWidget.setRowCount(len(mlist))
        for (i, v) in enumerate(mlist):
            for (j, item) in enumerate(v):
                if type(item) != str:
                    item = unicode(item)
                if item == None:
                    item = u""
                tabItem = QTableWidgetItem(item)
                tabItem.setTextAlignment(Qt.AlignCenter)
                self.tableWidget.setItem(i, j, tabItem)

    # 初始化错误信息列表
    def initListView(self, mlist):

        for iv in mlist:
            lisItm = QListWidgetItem(self.listWidget)
            lisItm.setTextColor(Qt.red)
            lisItm.setData(Qt.UserRole, iv)
            if isinstance(iv, basestring):
                # 如果错误信息是一行字符串
                lisItm.setText(iv)
            else:
                lisItm.setText(u'第' + unicode(str(iv['row'] + 1)) + u'行,第' +
                               unicode(str(iv['col'] + 1)) + u'列:' + iv['msg'])

    # 初始化Table的头
    def initTableHeader(self):
        self.heads = []
        if self.impType == ImpDateType.SITEANDCELL:
            # 获取当前项目图层的字段名
            cell_layer = getLayerByName(u"小区", self.iface)
            for head in HeadsConfig.SiteANDCellHead:
                self.heads.append(head)
            if len(cell_layer.pendingFields()) > 55:
                for (index, field) in enumerate(cell_layer.pendingFields()):
                    if index > 54:
                        field_name = field.name().strip()
                        self.heads.append(field_name)

        else:
            self.heads = HeadsConfig.ServingCellHead

        self.tableWidget.setColumnCount(len(self.heads))  # 设置表格的列数
        for (i, h) in enumerate(self.heads):
            tabItem = QTableWidgetItem(h)
            self.tableWidget.setHorizontalHeaderItem(i, tabItem)

    # 自定义为Table添加Item
    def addTableItem(self, row, col, content):
        tabItem = QTableWidgetItem(content)
        self.tableWidget.setItem(row, col, tabItem)

    # 修改Item的内容
    def editTableItem(self, row, col, content):
        tabItem = self.tableWidget.item(row, col)
        tabItem.setText(content)
        self.tableWidget.setItem(row, col, tabItem)

    # 从Excel表读取数据(导入Excel表)
    def impClick(self):
        fileName = QFileDialog.getOpenFileName(self, u'基站小区数据导入', '/',
                                               'Excel Files (*.xls *.xlsx)')
        if fileName.strip() != "":
            self.setStatusBarMsg(u'选择完毕:' + fileName)
            importData = GetDataFromExcel(fileName, self.impType, self.heads)
            self.__mlist = []
            self.__mlist.extend(importData.getData())
            self.tableWidget.clearContents()
            self.listWidget.clear()
            self.initTable(self.__mlist)
            self.setStatusBarMsg(u'数据导入完成...')
            self.__isJy = False  # 导入完数据后,说明需要重新验证数据的正确性

        else:
            QMessageBox.information(self.parent, u"错误", u"请选中文件")

    # 数据验证按钮点击事件处理
    def yzClick(self):
        if len(self.__mlist) > 0:
            self.erlist = []  # 定义一个列表用于保存数据验证错误的数据
            # 清楚全部的Item
            if self.listWidget.count() > 0:
                self.listWidget.clear()

            # 根据tableWidget更新self.__mlist
            for (r, items) in enumerate(self.__mlist):
                for (v, item) in enumerate(self.__mlist[r]):
                    if self.tableWidget.item(r, v).text() == u"":
                        continue
                    else:
                        # 跟据self.__mlist[r][v]数据类型进行比对
                        if type(self.__mlist[r][v]) == int:
                            if unicode(self.__mlist[r][v]) != (
                                    self.tableWidget.item(r, v).text()):
                                self.__mlist[r][v] = int(
                                    self.tableWidget.item(r, v).text())
                        elif type(self.__mlist[r][v]) == float:
                            if unicode(self.__mlist[r][v]) != (
                                    self.tableWidget.item(r, v).text()):
                                self.__mlist[r][v] = float(
                                    self.tableWidget.item(r, v).text())
                        elif type(self.__mlist[r][v]) == str:
                            if unicode(self.__mlist[r][v]
                                       ) != self.tableWidget.item(r, v).text():
                                self.__mlist[r][v] = str(
                                    self.tableWidget.item(r, v).text())
                        elif type(self.__mlist[r][v]) == unicode:
                            if (self.__mlist[r][v]) != self.tableWidget.item(
                                    r, v).text():
                                self.__mlist[r][v] = self.tableWidget.item(
                                    r, v).text()
                        else:
                            print type(self.__mlist[r][v])
            # 执行数据校验函数
            self.erlist = checkDataByDataType(self.__mlist, self.impType)
            if len(self.erlist) > 0:
                self.initListView(self.erlist)
                QMessageBox.information(self.parent, u'数据校验',
                                        u'数据校验失败,请检查数据正确性后,再导入到地图中')
                self.__isJy = False
            else:
                QMessageBox.information(self.parent, u'数据校验', u'数据校验成功,没有错误数据')
                self.__isJy = True
        else:
            QMessageBox.warning(self.parent, u'数据校验', u'请先导入Excel数据后再操作!')

    # 导入数据到地图中
    def impdateClick(self):
        if self.__isJy:  # 如果数据校验成功
            if self.impType == ImpDateType.SITEANDCELL:
                # 导入基站小区
                importDataToLayer = ImportDataToLayer(self.iface, self.__mlist,
                                                      self.parent)
                if importDataToLayer.importSiteAndCellData():
                    QMessageBox.information(self.parent, u"导入数据", u"导入数据成功!")
                else:
                    QMessageBox.critical(self.parent, u"导入数据", u"导入数据失败!")

            else:
                # 导入相邻小区
                importDataToLayer = ImportDataToLayer(self.iface, self.__mlist,
                                                      self.parent)
                if importDataToLayer.importSCellData():
                    QMessageBox.information(self.parent, u"导入数据", u"导入数据成功!")
                else:
                    QMessageBox.critical(self.parent, u"导入数据", u"导入数据失败!")
        else:
            QMessageBox.warning(self.parent, u'数据导入', u'请确保校验数据成功后,再导入到地图中')

    # 编辑Action点击事件
    def editClick(self):
        self.setEditTriggers(self.editAction.isChecked())

    # 错误列表双击事件处理
    def mlistClicked(self, listItem):
        itemData = listItem.data(Qt.UserRole)
        self.tableWidget.setFocus()
        self.tableWidget.setCurrentCell(itemData['row'], itemData['col'])

    # 选框改变事件
    def comboxChange(self, index):
        self.updateType(index)

    # 字段验证是否为空
    def __validNull(self, name, col, row, itm, rowitm):
        if itm is None or itm == '':
            tmpMap = {}
            tmpMap['col'] = col
            tmpMap['row'] = row
            tmpMap['msg'] = unicode(name) + u'不能为空'
            tmpMap['item'] = rowitm
            return tmpMap
        else:
            return None

    # 导入数据线程开始信号  绑定函数
    def impStart(self):
        self.setStatusBarMsg(u'准备导入...')

    # 导入数据线程发生异常信号 绑定函数
    def impError(self, e, exception_string):
        self.setStatusBarMsg(u'发生错误:' + unicode(e))
        QMessageBox.warning(self.parent, u'Excel数据导入', u'发生错误:' + unicode(e))

    # 导入数据线程完成信号 绑定函数
    def impFinish(self, mylist):
        self.__mlist = []
        self.__mlist.extend(mylist)
        self.mthread.quit()
        self.mthread.wait()
        self.mthread.deleteLater()
        self.impDateThread.deleteLater()

        self.tableWidget.clearContents()
        self.listWidget.clear()
        self.initTable(self.__mlist)
        self.setStatusBarMsg(u'数据导入完成...')
        self.__isJy = False  # 导入完数据后,说明需要重新验证数据的正确性

    # 导入数据到地图线程发生异常信号 绑定函数
    def impError1(self, e, exception_string):
        self.setStatusBarMsg(u"导入数据发生错误")
        QMessageBox.critical(self, u'数据导入', u"发生错误:" + unicode(e))

    # 导入数据到地图线程完成信号 绑定函数
    def impFinish1(self, mylist):
        self.threadImp.quit()
        self.threadImp.wait()
        self.threadImp.deleteLater()
        self.impFeatureThread.deleteLater()
        remsg = u'数据导入完成!'
        layer = None
        if self.impType == LayerType.SITE:
            # remsg = u'基站' + remsg
            layer = getLayerByName(u'基站', self.iface)
        elif self.impType == LayerType.CELL:
            # remsg = u'小区' + remsg
            layer = getLayerByName(u'小区', self.iface)
        else:
            remsg = u'相邻小区' + remsg
            layer = getLayerByName(u'相邻小区', self.iface)
        self.setStatusBarMsg(remsg)
        layer.updateExtents()  # 更新地图数据
        self.iface.actionDraw().trigger()
        QMessageBox.information(self, u'数据导入', remsg)

        merlist = []
        for eritm in self.erlist:
            merlist.append(eritm['item'])
        self.tableWidget.clearContents()  # 先清楚表格的内容,再将错误的行显示到表格中
        self.initTable(merlist)
Exemple #56
0
class CodeCompletionWidget(QFrame):

    def __init__(self, editor):
        super(CodeCompletionWidget, self).__init__(
            None, Qt.FramelessWindowHint | Qt.ToolTip)
        self._editor = editor
        self._revision = 0
        self._block = 0
        self.stack_layout = QStackedLayout(self)
        self.stack_layout.setContentsMargins(0, 0, 0, 0)
        self.stack_layout.setSpacing(0)
        self.completion_list = QListWidget()
        self.completion_list.setMinimumHeight(200)
        self.completion_list.setAlternatingRowColors(True)
        self._list_index = self.stack_layout.addWidget(self.completion_list)

        self._icons = {'a': resources.IMAGES['attribute'],
            'f': resources.IMAGES['function'],
            'c': resources.IMAGES['class'],
            'm': resources.IMAGES['module']}

        self.cc = code_completion.CodeCompletion()
        self._completion_results = {}
        self._prefix = u''
        self.setVisible(False)
        self.source = ''
        self._key_operations = {
            Qt.Key_Up: self._select_previous_row,
            Qt.Key_Down: self._select_next_row,
            Qt.Key_PageUp: (lambda: self._select_previous_row(6)),
            Qt.Key_PageDown: (lambda: self._select_next_row(6)),
            Qt.Key_Right: lambda: None,
            Qt.Key_Left: lambda: None,
            Qt.Key_Enter: self.pre_key_insert_completion,
            Qt.Key_Return: self.pre_key_insert_completion,
            Qt.Key_Tab: self.pre_key_insert_completion,
            Qt.Key_Space: self.hide_completer,
            Qt.Key_Escape: self.hide_completer,
            Qt.Key_Backtab: self.hide_completer,
            Qt.NoModifier: self.hide_completer,
            Qt.ShiftModifier: self.hide_completer,
        }

        self.desktop = QApplication.instance().desktop()

        self.connect(self.completion_list,
            SIGNAL("itemClicked(QListWidgetItem*)"),
            self.pre_key_insert_completion)
        self.connect(self._editor.document(),
            SIGNAL("cursorPositionChanged(QTextCursor)"),
            self.update_metadata)

    def _select_next_row(self, move=1):
        new_row = self.completion_list.currentRow() + move
        if new_row < self.completion_list.count():
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(0)
        return True

    def _select_previous_row(self, move=1):
        new_row = self.completion_list.currentRow() - move
        if new_row >= 0:
            self.completion_list.setCurrentRow(new_row)
        else:
            self.completion_list.setCurrentRow(
                self.completion_list.count() - move)
        return True

    def update_metadata(self, cursor):
        if settings.CODE_COMPLETION:
            if self._editor.document().revision() != self._revision and \
               cursor.block().blockNumber() != self._block:
                source = self._editor.get_text()
                source = source.encode(self._editor.encoding)
                self.cc.analyze_file(self._editor.ID, source)
                self._revision = self._editor.document().revision()
                self._block = cursor.block().blockNumber()

    def insert_completion(self, insert, type_=ord('a')):
        if insert != self._prefix:
            closing = ''
            if type_ in (ord('f'), ord('c')):
                closing = '()'
            extra = len(self._prefix) - len(insert)
            insertion = '%s%s' % (insert[extra:], closing)
            self._editor.textCursor().insertText(insertion)
        self.hide_completer()

    def _get_geometry(self):
        cr = self._editor.cursorRect()
        desktop_geometry = self.desktop.availableGeometry(self._editor)
        point = self._editor.mapToGlobal(cr.topLeft())
        cr.moveTopLeft(point)
        #Check new position according desktop geometry
        width = (self.completion_list.sizeHintForColumn(0) +
            self.completion_list.verticalScrollBar().sizeHint().width() + 10)
        height = 200
        orientation = (point.y() + height) < desktop_geometry.height()
        if orientation:
            cr.moveTop(cr.bottom())
        cr.setWidth(width)
        cr.setHeight(height)
        if not orientation:
            cr.moveBottom(cr.top())
        xpos = desktop_geometry.width() - (point.x() + width)
        if xpos < 0:
            cr.moveLeft(cr.left() + xpos)
        return cr

    def complete(self, results):
        self.add_list_items(results)
        self.completion_list.setCurrentRow(0)
        cr = self._get_geometry()
        self.setGeometry(cr)
        self.completion_list.updateGeometries()
        self.show()

    def add_list_items(self, proposals):
        self.completion_list.clear()
        for p in proposals:
            self.completion_list.addItem(
                QListWidgetItem(
                QIcon(self._icons.get(p[0], resources.IMAGES['attribute'])),
                p[1], type=ord(p[0])))

    def set_completion_prefix(self, prefix, valid=True):
        self._prefix = prefix
        proposals = []
        proposals += [('m', item)
            for item in self._completion_results.get('modules', [])
            if item.startswith(prefix)]
        proposals += [('c', item)
            for item in self._completion_results.get('classes', [])
            if item.startswith(prefix)]
        proposals += [('a', item)
            for item in self._completion_results.get('attributes', [])
            if item.startswith(prefix)]
        proposals += [('f', item)
            for item in self._completion_results.get('functions', [])
            if item.startswith(prefix)]
        if proposals and valid:
            self.complete(proposals)
        else:
            self.hide_completer()

    def _invalid_completion_position(self):
        result = False
        cursor = self._editor.textCursor()
        cursor.movePosition(QTextCursor.StartOfLine,
            QTextCursor.KeepAnchor)
        selection = unicode(cursor.selectedText())[:-1].split(' ')
        if len(selection) == 0 or selection[-1] == '' or \
           selection[-1].isdigit():
            result = True
        return result

    def fill_completer(self, force_completion=False):
        if not force_completion and (self._editor.cursor_inside_string() or
           self._editor.cursor_inside_comment() or
           self._invalid_completion_position()):
            return
        source = self._editor.get_text()
        source = source.encode(self._editor.encoding)
        offset = self._editor.textCursor().position()
        results = self.cc.get_completion(source, offset)
        self._completion_results = results
        if force_completion:
            cursor = self._editor.textCursor()
            cursor.movePosition(QTextCursor.StartOfWord,
                QTextCursor.KeepAnchor)
            prefix = cursor.selectedText()
        else:
            prefix = self._editor._text_under_cursor()
        self.set_completion_prefix(prefix)

    def hide_completer(self):
        self._prefix = ''
        self.hide()

    def pre_key_insert_completion(self):
        type_ = ord('a')
        current = self.completion_list.currentItem()
        insert = unicode(current.text())
        if not insert.endswith(')'):
            type_ = current.type()
        self.insert_completion(insert, type_)
        self.hide_completer()
        return True

    def process_pre_key_event(self, event):
        if not self.isVisible() or self._editor.lang != "python":
            return False
        skip = self._key_operations.get(event.key(), lambda: False)()
        self._key_operations.get(event.modifiers(), lambda: False)()
        if skip is None:
            skip = False
        return skip

    def process_post_key_event(self, event):
        if not settings.CODE_COMPLETION or self._editor.lang != "python":
            return
        if self.isVisible():
            source = self._editor.get_text()
            source = source.encode(self._editor.encoding)
            offset = self._editor.textCursor().position()
            prefix, valid = self.cc.get_prefix(source, offset)
            self.set_completion_prefix(prefix, valid)
            self.completion_list.setCurrentRow(0)
        force_completion = (event.key() == Qt.Key_Space and
                            event.modifiers() == Qt.ControlModifier)
        if event.key() == Qt.Key_Period or force_completion:
            self.fill_completer(force_completion)
Exemple #57
0
class NewSessionPagePermutations(QWizardPage):
    def __init__(self):
        super(NewSessionPagePermutations, self).__init__()
        self.setTitle(_('Configuration of permutations'))
        self.setSubTitle(_('Select the position of each question'
                           ' and its choices in every model of the exam.'))
        layout = QGridLayout()
        self.question_list = QListWidget()
        self.permutation_grid = QGridLayout()
        self.alternatives_rows = {}
        layout.addWidget(QLabel(_('Questions of model A')), 0, 0, 1, 1)
        layout.addWidget(self.question_list, 1, 0, 1, 1)
        layout.addWidget(QLabel(_('Model equivalence')), 0, 1, 1, 5)
        self.permutation_grid.setVerticalSpacing(20)
        layout.addLayout(self.permutation_grid, 1, 1, 1, 5)
        layout.setColumnStretch(0, 1)
        layout.setColumnStretch(1, 5)
        self.setLayout(layout)

    def initializePage(self):
        paramNAlts = int(self.field("paramNAlts").toString())
        paramNPerm = int(self.field("paramNPerm").toString())
        self.question_list.clear()
        # Creation of the list section
        paramNCols_array = self.field("paramNCols").toString().split(',')
        total_questions = 1 + (int(paramNCols_array[0]) \
                               if len(paramNCols_array) == 1 \
                               else reduce(lambda x, y: int(x) + int(y),
                                           paramNCols_array))
        for i in range(1,total_questions):
            questions_list = QListWidgetItem(_('Question ') + str(i))
            questions_list.setData(Qt.UserRole,
                        widgets.ItemList(optionName=_('Question ') + str(i),
                                         optionNumber=i)) # Custom item list
            self.question_list.addItem(questions_list)
        self.question_list.setCurrentRow(0)
        self.question_list.itemClicked.connect(self._on_item_changed)
        # Creation of the grid section
        add_header = True # Header of the columns (Name of alternatives)
        for j in range(0, paramNPerm):
            self.permutation_grid.addWidget( \
                                QLabel(_('Model ') + chr(97 + j).upper()), j, 1)
            self.alternatives_rows[j] = {}
            for k in range(0, paramNAlts):
                if add_header:
                    if k == 0:
                        self.permutation_grid.addWidget(QLabel(''), 0, 1)
                    self.permutation_grid.addWidget( \
                                        QLabel(chr(97 + k).upper()), 0, k + 2)
                self.alternatives_rows[j][k] = \
                    widgets.InputComboBox(self, c_type='alternative',
                                          form=j, alternative=k)
                self.alternatives_rows[j][k].addItems( \
                            [chr(97+x).upper() for x in range(0,paramNAlts)])
                self.alternatives_rows[j][k].setCurrentIndex(0)
                self.permutation_grid.addWidget(self.alternatives_rows[j][k],
                                                j, k + 2)
            add_header = False
            self.alternatives_rows[j][k + 1] = \
                widgets.InputComboBox(self, c_type='question', form=j,
                                      alternative=self.question_list.\
                                          currentItem().\
                                          data(Qt.UserRole).toPyObject().\
                                               get_question_number())
            self.alternatives_rows[j][k + 1].addItems( \
                                [str(x) for x in range(1,total_questions)])
            self.alternatives_rows[j][k + 1].setCurrentIndex(0)
            self.permutation_grid.addWidget(QLabel(_('Question Number')),
                                            j, k + 3)
            self.permutation_grid.addWidget(self.alternatives_rows[j][k + 1],
                                            j, k + 4)
        button_save = QPushButton(_('Save values'))
        self.permutation_grid.addWidget(button_save, j + 1, 1, 1, k + 4)
        button_save.clicked.connect(self._save_values)

    def _on_item_changed(self, arg=None):
        permutation = arg.data(Qt.UserRole).toPyObject().get_permutation()
        for k, v in self.alternatives_rows.iteritems():
            for sk, sv in v.iteritems():
                if not permutation:
                    sv.setCurrentIndex(0)
                else:
                    sv.setCurrentIndex( \
                        [x for x in permutation \
                         if (x['altr'] == sv.alternative
                             and x['form'] == sv.form
                             and x['c_type'] == sv.c_type)][0]['perm'] - 1)
        return True

    def _save_values(self):
        localItem = self.question_list.currentItem()
        formatted_grid  = self._get_formatted_permutation_grid()
        if self._validate_grid(formatted_grid):
            localItem.setBackgroundColor(QColor(0, 255, 68))
            localItem.data(Qt.UserRole).toPyObject()\
                     .set_permutation(formatted_grid)
            self._reset_permutation_grid()
            QMessageBox.information(self, _('Information status'),
                _('The values for the question have been successfully saved'))
            return True
        else:
            QMessageBox.critical(self, _('Error in grid'),
                _('There is an inconsistence in the options'))
            return False

    def _get_formatted_permutation_grid(self):
        local_alternatives_rows = []
        for k, v in self.alternatives_rows.iteritems():
            for sk, sv in v.iteritems():
                alternative = {
                    'c_type': sv.c_type,
                    'form': sv.form,
                    'altr': sv.alternative,
                    'perm': sv.currentIndex() + 1
                }
                local_alternatives_rows.append(alternative)
        return local_alternatives_rows

    def _validate_grid(self, grid):
        #validate current grid and questions number
        forms = {}
        for row in grid:
            if row['c_type'] == 'alternative':
                if row['form'] not in forms:
                    forms[row['form']] = []
                if row['perm'] in forms[row['form']]:
                    return False
                else:
                    forms[row['form']].append(row['perm'])
            if row['c_type'] == 'question':
                for i in xrange(self.question_list.count()):
                    if i == self.question_list.currentRow():
                        continue
                    perm = self.question_list.item(i).data(Qt.UserRole)\
                               .toPyObject().get_permutation()
                    for perm_row in perm:
                        if (perm_row['c_type'] == 'question'
                            and perm_row['form'] == row['form']
                            and perm_row['perm'] == row['perm']):
                            return False
        return True

    def _reset_permutation_grid(self):
        for k,v in self.alternatives_rows.iteritems():
            for sk, sv in v.iteritems():
                sv.setCurrentIndex(0)

    def _get_values(self):
        formated_permutation = {}
        formated_permutation_m = {}
        for i in xrange(self.question_list.count()):
            permutations = self.question_list.item(i).data(Qt.UserRole)\
                               .toPyObject().get_permutation()
            a = {}
            for p in permutations:
                if p['form'] not in formated_permutation:
                    formated_permutation[p['form']] = []
                if p['form'] not in a:
                    a[p['form']] = []
                if p['c_type'] == 'alternative':
                    a[p['form']].append(p['perm'])
                if p['c_type'] == 'question':
                    formated_permutation[p['form']].append( \
                        "%s{%s}" % (p['perm'], ','.join(str(x) \
                                                       for x in a[p['form']])))
        for k,v in formated_permutation.iteritems():
            formated_permutation_m[chr(97+k).upper()] = '/'.join(v)
        return formated_permutation_m

    def validatePage(self):
        valid = True
        msg = ''
        for i in xrange(self.question_list.count()):
            if not self.question_list.item(i).data(Qt.UserRole)\
                .toPyObject().get_permutation():
                valid = False
                msg = _('You must select all permutations for all questions')
                break
        if not valid:
            QMessageBox.critical(self, _('Error'), msg)
        else:
            current_permutations = self._get_values()
            for k, v in current_permutations.iteritems():
                self.wizard().exam_config.set_permutations(k, v)
        return valid

    def nextId(self):
        return WizardNewSession.PageIdFiles