Exemplo n.º 1
0
    def create_combobox ( self, parent, editable = False ):
        """ Returns an adapted QComboBox control.
        """
        control = QComboBox( check_parent( parent ) )
        control.setEditable( editable )

        return control_adapter( control )
Exemplo n.º 2
0
class DocPropsView(BaseView):
    def _setup(self):
        self._setupUi()
        self.currencyComboBox = ComboboxModel(model=self.model.currency_list, view=self.currencyComboBoxView)
        self.firstWeekdayComboBox = ComboboxModel(model=self.model.first_weekday_list,
            view=self.firstWeekdayComboBoxView)
        self.aheadMonthsComboBox = ComboboxModel(model=self.model.ahead_months_list,
            view=self.aheadMonthsComboBoxView)
        self.yearStartComboBox = ComboboxModel(model=self.model.year_start_month_list,
            view=self.yearStartComboBoxView)
    
    def _setupUi(self):
        self.mainLayout = QFormLayout(self)
        
        sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
        self.currencyComboBoxView = QComboBox()
        self.currencyComboBoxView.setEditable(True)
        self.currencyComboBoxView.setInsertPolicy(QComboBox.NoInsert)
        self.currencyComboBoxView.setSizePolicy(sizePolicy)
        self.mainLayout.addRow(tr("Native Currency:"), self.currencyComboBoxView)
        
        self.firstWeekdayComboBoxView = QComboBox(self)
        self.firstWeekdayComboBoxView.setSizePolicy(sizePolicy)
        self.mainLayout.addRow(tr("First day of the week:"), self.firstWeekdayComboBoxView)
        
        self.aheadMonthsComboBoxView = QComboBox(self)
        self.aheadMonthsComboBoxView.setSizePolicy(sizePolicy)
        self.mainLayout.addRow(tr("Ahead months in Running Year:"), self.aheadMonthsComboBoxView)
        
        self.yearStartComboBoxView = QComboBox(self)
        self.yearStartComboBoxView.setSizePolicy(sizePolicy)
        self.mainLayout.addRow(tr("Year starts in:"), self.yearStartComboBoxView)
        
Exemplo n.º 3
0
class FontLayout(QHBoxLayout):
    """Font selection"""
    def __init__(self, value, parent=None):
        QHBoxLayout.__init__(self)
        font = tuple_to_qfont(value)
        assert font is not None

        # Font family
        self.family = QFontComboBox(parent)
        self.family.setCurrentFont(font)
        self.addWidget(self.family)

        # Font size
        self.size = QComboBox(parent)
        self.size.setEditable(True)
        sizelist = list(itertools.chain(range(6, 12), range(12, 30, 2), [36, 48, 72]))
        size = font.pointSize()
        if size not in sizelist:
            sizelist.append(size)
            sizelist.sort()
        self.size.addItems([str(s) for s in sizelist])
        self.size.setCurrentIndex(sizelist.index(size))
        self.addWidget(self.size)

    def get_font(self):
        font = self.family.currentFont()
        font.setPointSize(int(self.size.currentText()))
        return qfont_to_tuple(font)
Exemplo n.º 4
0
 def createEditor(self, parent, option, index):
     if index.column() == TEU:
         spinbox = QSpinBox(parent)
         spinbox.setRange(0, 200000)
         spinbox.setSingleStep(1000)
         spinbox.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
         return spinbox
     elif index.column() == OWNER:
         combobox = QComboBox(parent)
         combobox.addItems(sorted(index.model().owners))
         combobox.setEditable(True)
         return combobox
     elif index.column() == COUNTRY:
         combobox = QComboBox(parent)
         combobox.addItems(sorted(index.model().countries))
         combobox.setEditable(True)
         return combobox
     elif index.column() == NAME:
         editor = QLineEdit(parent)
         self.connect(editor, SIGNAL("returnPressed()"),
                      self.commitAndCloseEditor)
         return editor
     elif index.column() == DESCRIPTION:
         editor = richtextlineedit.RichTextLineEdit(parent)
         self.connect(editor, SIGNAL("returnPressed()"),
                      self.commitAndCloseEditor)
         return editor
     else:
         return QStyledItemDelegate.createEditor(self, parent, option,
                                                 index)
Exemplo n.º 5
0
    def addSingleArgument(self, key, predefs, typeid, editable=False):
        if not self.overwriteKeys(key):
            if type(key) == types.StringType:
                if len(predefs) > 0:
                    w = QComboBox()
		    self.connect(w, SIGNAL("editTextChanged(QString)"), self.argumentChanged)
		    self.connect(w, SIGNAL("currentIndexChanged(QString)"), self.argumentChanged)
                    w.setEditable(editable)
                    for value in predefs:
                        w.addItem(value.toString())
                else:
                    w = QLineEdit()
		    self.connect(w, SIGNAL("editingFinished()"), self.argumentChanged)
                    if typeid not in (typeId.String, typeId.Char, typeId.Node, typeId.Path):
                        w.insert("0")
                    w.setReadOnly(not editable)
                w.setValidator(fieldValidator(self, typeid))
                if not self.displaykey:
                    self.layout.addRow(w)
                else:
                    self.layout.addRow(key, w)
                self.widgets[key] = w
                return 1
            else: 
                return -1
        else:
            return -1
Exemplo n.º 6
0
    def __init__(self, parent, message, title, options, default):
        super(OptionDialog, self).__init__(parent)

        self.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
        self.setIcon(QMessageBox.Question)
        self.setText(message)
        self.setWindowTitle(title)

        self.selection = default

        box = QWidget()
        box.setLayout(QGridLayout())
        box.setFixedHeight(40)

        box_combo = QWidget()
        combo = QComboBox(box_combo)
        combo.setEditable(False)
        combo.box = box_combo
        for item in options:
            combo.addItem(str(item))
        combo.setCurrentIndex(default)
        combo.currentIndexChanged.connect(self.set_selection)

        box.layout().addWidget(QLabel("Select Option"), 0, 0, 1, 1)
        box.layout().addWidget(box_combo, 0, 1, 1, 1)

        self.layout().addWidget(box, 1, 1, 1, 2)
Exemplo n.º 7
0
    def addList(self, key, predefs, editable=False):
        if len(predefs) > 0 and not self.overwriteKeys(key):
            # Check if value list has the same type
            if type(key) == types.StringType:
                w = QComboBox()
		self.connect(w, SIGNAL("currentIndexChanged(QString)"), self.argumentChanged)
                w.setEditable(editable)
                w.setValidator(QIntValidator())
                for value in predefs:
                    if type(value).__name__=='str':
                        if w.findText(value) == -1:
                            w.addItem(value)
                    elif type(value).__name__=='int':
                        if w.findText(str(value)) == -1:
                            w.addItem(str(value))
                    else:
                        return -1
                if not self.displaykey:
                    self.layout.addRow(w)
                else:
                    self.layout.addRow(key, w)
                self.widgets[key] = w
                return 1
            else: 
                return -1
        else:
            return -1
Exemplo n.º 8
0
class collectDelegate(QItemDelegate):

    def __init__(self, parent, module):
        self.module = module
        QItemDelegate.__init__(self, parent)

    def createEditor (self, parent, option, index):
        column = index.column()
        row = index.row()
        self.index = index
        content = index.model().data(index, Qt.EditRole)
        if column == 2:
            content = index.model().data(index, Qt.EditRole)
            label = index.model().data(index.model().index(row,1), Qt.EditRole)
            checkrowIndex = index.model().index(row,0)
            checkrowIndex = index.model().data(index.model().index(row,0), Qt.CheckStateRole)
            self.editorQWidget = QComboBox(parent)
            self.editorQWidget.setEditable(True)
            self.editorQWidget.addItems(self.module.fieldMapping.values())
            self.editorQWidget.addItems(['GEOMETRY','ODKUUID'])
            if content in self.module.fieldMapping.values():
                self.editorQWidget.setCurrentIndex(self.editorQWidget.findData(content))
                #self.module.fieldTable.item(row,0).setCheckState(Qt.Checked)
            else:
                #self.editorQWidget.insertItem(0,label)
                self.editorQWidget.insertItem(0,'')
                #self.module.fieldTable.item(row,0).setCheckState(Qt.Unchecked)
                self.editorQWidget.setCurrentIndex(0)
            return self.editorQWidget
        else:
            return None
        return QItemDelegate.createEditor(self, parent, option, index)
Exemplo n.º 9
0
 def createEditor(self, parent, option, index):
     if index.column() == TEU:
         spinbox = QSpinBox(parent)
         spinbox.setRange(0, 200000)
         spinbox.setSingleStep(1000)
         spinbox.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
         return spinbox
     elif index.column() == OWNER:
         combobox = QComboBox(parent)
         combobox.addItems(sorted(index.model().owners))
         combobox.setEditable(True)
         return combobox
     elif index.column() == COUNTRY:
         combobox = QComboBox(parent)
         combobox.addItems(sorted(index.model().countries))
         combobox.setEditable(True)
         return combobox
     elif index.column() == NAME:
         editor = QLineEdit(parent)
         editor.returnPressed.connect(self.commitAndCloseEditor)
         return editor
     elif index.column() == DESCRIPTION:
         editor = richtextlineedit.RichTextLineEdit(parent)
         editor.returnPressed.connect(self.commitAndCloseEditor)
         return editor
     else:
         return QStyledItemDelegate.createEditor(self, parent, option,
                                                 index)
Exemplo n.º 10
0
 def createEditor( self, parent, option, index ):
     if index.column() == DESCRIPCION:
         combo = QComboBox( parent )
         combo.setEditable( True )
         value = index.data().toString()
         self.filtrados.append( value )
         self.proxymodel.setFilterRegExp( self.filter() )
         combo.setModel( self.proxymodel )
         combo.setModelColumn( 1 )
         combo.setCompleter( self.completer )
         return combo
     elif index.column() == BANCO:
         combo = QComboBox( parent )
         #combo.setEditable(True)
         combo.setModel( self.bancosmodel )
         combo.setModelColumn( 1 )
         #combo.setCompleter(self.completer)
         return combo
     elif index.column() == MONTO:
         doublespinbox = QDoubleSpinBox( parent )
         doublespinbox.setMinimum( -1000000 )
         doublespinbox.setMaximum( 1000000 )
         doublespinbox.setDecimals( 4 )
         doublespinbox.setAlignment( Qt.AlignHCenter )
         return doublespinbox
     elif index.column() == REFERENCIA:
         textbox = QStyledItemDelegate.createEditor( self, parent, option, index )
         textbox.setAlignment( Qt.AlignHCenter )
         return textbox
Exemplo n.º 11
0
 def createEditor( self, parent, option, index ):
     combo = QComboBox(parent)
     
     keys = Q.Op.keys()
     keys = map(lambda x: projex.text.joinWords(x, ' ').lower(), keys)
     
     combo.addItems(sorted(keys))
     combo.setEditable(True)
     combo.setInsertPolicy(QComboBox.NoInsert)
     
     return combo
Exemplo n.º 12
0
    def createEditor(self, parent, option, index):
        combo = QComboBox(parent)

        keys = Q.Op.keys()
        keys = map(lambda x: projex.text.joinWords(x, ' ').lower(), keys)

        combo.addItems(sorted(keys))
        combo.setEditable(True)
        combo.setInsertPolicy(QComboBox.NoInsert)

        return combo
Exemplo n.º 13
0
 def createEditor(self, parent, option, index):
     # special combobox for field type
     if index.column() == 1:
         cbo = QComboBox(parent)
         cbo.setEditable(True)
         cbo.setAutoCompletion(True)
         cbo.setFrame(False)
         for item in self.fieldTypes:
             cbo.addItem(item)
         return cbo
     return QItemDelegate.createEditor(self, parent, option, index)
Exemplo n.º 14
0
 def createEditor(self, parent, option, index):
     # special combobox for field type
     if index.column() == 1:
         cbo = QComboBox(parent)
         cbo.setEditable(True)
         cbo.setAutoCompletion(True)
         cbo.setFrame(False)
         for item in self.fieldTypes:
             cbo.addItem(item)
         return cbo
     return QItemDelegate.createEditor(self, parent, option, index)
Exemplo n.º 15
0
 def createEditor( self, parent, option, index ):
     schema = self.parent().schema()
     if ( not schema ):
         return None
     
     colNames = map(lambda x: x.displayName(), schema.columns())
     
     combo = QComboBox(parent)
     combo.setEditable(True)
     combo.setInsertPolicy(QComboBox.NoInsert)
     combo.addItems(colNames)
     
     return combo
Exemplo n.º 16
0
    def createEditor(self, parent, option, index):
        schema = self.parent().schema()
        if (not schema):
            return None

        colNames = map(lambda x: x.displayName(), schema.columns())

        combo = QComboBox(parent)
        combo.setEditable(True)
        combo.setInsertPolicy(QComboBox.NoInsert)
        combo.addItems(colNames)

        return combo
Exemplo n.º 17
0
    def getWidgetFromParameter(self, param):
        if isinstance(param, ParameterBands):
            strings = self.getAvailableValuesOfType(ParameterBands)
            options = [(self.resolveValueDescription(s), s) for s in strings]
            item = QComboBox()
            item.setEditable(True)
            for desc, val in options:
                item.addItem(desc, val)
            item.setEditText(unicode(param.default or ""))
        else:
            item = ModelerParametersDialog.getWidgetFromParameter(self, param)

        return item
Exemplo n.º 18
0
class FontLayout(QGridLayout):

    """Font selection"""

    def __init__(self, value, parent=None):
        QGridLayout.__init__(self)
        font = tuple_to_qfont(value)
        assert font is not None

        # Font family
        self.family = QFontComboBox(parent)
        self.addWidget(self.family, 0, 0, 1, -1)

        # Font size
        self.size = QComboBox(parent)
        self.size.setEditable(True)
        sizelist = list(range(6, 12)) + list(range(12, 30, 2)) + [36, 48, 72]
        size = font.pointSize()
        if size not in sizelist:
            sizelist.append(size)
            sizelist.sort()
        self.size.addItems([str(s) for s in sizelist])
        self.addWidget(self.size, 1, 0)

        # Italic or not
        self.italic = QCheckBox(self.tr("Italic"), parent)
        self.addWidget(self.italic, 1, 1)

        # Bold or not
        self.bold = QCheckBox(self.tr("Bold"), parent)
        self.addWidget(self.bold, 1, 2)
        self.set_font(font)

    def set_font(self, font):
        self.family.setCurrentFont(font)
        size = font.pointSize()
        i = self.size.findText(str(size))
        if i >= 0:
            self.size.setCurrentIndex(i)
        self.italic.setChecked(font.italic())
        self.bold.setChecked(font.bold())

    def get_font(self):
        font = self.family.currentFont()
        font.setItalic(self.italic.isChecked())
        font.setBold(self.bold.isChecked())
        font.setPointSize(int(self.size.currentText()))
        return qfont_to_tuple(font)
Exemplo n.º 19
0
 def createEditor(self, parent, option, index):
     """
     Reimplementation of generic list column
     QItemDelegate createEditor method
     """
     data_source = index.model().data_source()
     if DelegateRoutine().is_pdf(data_source, index):
         return
     self.items = data_source.delimiter_names()
     regex = QRegExp(r"^[\w\W]{1}$")
     validator = QRegExpValidator(regex, parent)
     combobox = QComboBox(parent)
     combobox.addItems(sorted(self.items.values()))
     combobox.setEditable(True)
     combobox.setValidator(validator)
     return combobox
Exemplo n.º 20
0
class FontLayout(QGridLayout):
    """Font selection"""
    def __init__(self, value, parent=None):
        QGridLayout.__init__(self)
        font = tuple_to_qfont(value)
        assert font is not None

        # Font family
        self.family = QFontComboBox(parent)
        self.addWidget(self.family, 0, 0, 1, -1)

        # Font size
        self.size = QComboBox(parent)
        self.size.setEditable(True)
        sizelist = list(range(6, 12)) + list(range(12, 30, 2)) + [36, 48, 72]
        size = font.pointSize()
        if size not in sizelist:
            sizelist.append(size)
            sizelist.sort()
        self.size.addItems([str(s) for s in sizelist])
        self.addWidget(self.size, 1, 0)

        # Italic or not
        self.italic = QCheckBox(self.tr("Italic"), parent)
        self.addWidget(self.italic, 1, 1)

        # Bold or not
        self.bold = QCheckBox(self.tr("Bold"), parent)
        self.addWidget(self.bold, 1, 2)
        self.set_font(font)

    def set_font(self, font):
        self.family.setCurrentFont(font)
        size = font.pointSize()
        i = self.size.findText(str(size))
        if i >= 0:
            self.size.setCurrentIndex(i)
        self.italic.setChecked(font.italic())
        self.bold.setChecked(font.bold())

    def get_font(self):
        font = self.family.currentFont()
        font.setItalic(self.italic.isChecked())
        font.setBold(self.bold.isChecked())
        font.setPointSize(int(self.size.currentText()))
        return qfont_to_tuple(font)
Exemplo n.º 21
0
 def createEditor( self, parent, option, index ):
     tree = self.parent()
     querywidget = tree.parent()
     item = tree.itemFromIndex(index)
     if ( isinstance(item, XQueryItem) and not item.childCount() ):
         ttype = querywidget.tableType()
         options = querywidget.factory().columnOptions(ttype)
     
     elif ( isinstance(item, XJoinItem) ):
         options = ['and', 'or']
     
     combo = QComboBox(parent)
     combo.setEditable(True)
     combo.setInsertPolicy(QComboBox.NoInsert)
     combo.addItems(sorted(options))
     
     return combo
Exemplo n.º 22
0
    def addPath(self, key, typeid, predefs, selectednodes, editable=False, config=None):
        if config:
	  predefs.push_front(config[0]) 
        if not self.overwriteKeys(key) and type(key).__name__=='str':
            vbox = QVBoxLayout()
            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)
                vbox.addWidget(combo)
            layout = QHBoxLayout()
            if len(predefs) > 0 or len(selectednodes) > 0:
                pathcontainer = QComboBox()
	        self.connect(pathcontainer, SIGNAL("editTextChanged(QString)"), self.argumentChanged)
		self.connect(pathcontainer, SIGNAL("currentIndexChanged(QString)"), self.argumentChanged)
                pathcontainer.setEditable(editable)
                for value in predefs:
                    if typeid == typeId.Node:
                        pathcontainer.addItem(value.value().name())
                    else:
                        pathcontainer.addItem(value.toString())
                if typeid == typeId.Node:
                    for node in selectednodes:
                        pathcontainer.addItem(QString.fromUtf8(node.absolute()))
            else:
                pathcontainer = QLineEdit()
                pathcontainer.setReadOnly(not editable)
		self.connect(pathcontainer, SIGNAL("editingFinished()"), self.argumentChanged)
            if typeid == typeId.Path:
                browse = addLocalPathButton(self, key, pathcontainer, inputchoice=combo)
            else:
                browse = addLocalPathButton(self, key, pathcontainer, nodetype=True)
            layout.addWidget(pathcontainer, 2)
            layout.addWidget(browse, 0)
            vbox.addLayout(layout)
            if not self.displaykey:
                self.layout.addRow(vbox)
            else:
                self.layout.addRow(key, vbox)
            self.widgets[key] = pathcontainer
            return 1
        else:
            return -1
Exemplo n.º 23
0
 def createEditor(self, parent):
     """ Returns the correctly initialized editor for the item value. 
     
     @param parent: Parent widget of the created editor widget.
     @type parent: L{QWidget<PyQt4.QtGui.QWidget>}
     
     @return: Currently a combination box.
     @rtype: L{QComboBox<PyQt4.QtGui.QComboBox>}
     """
     
     editor = QComboBox(parent)
     currentName = unicode(self.text())
     index = 0
     for number, level in enumerate(self.accessLevels):
         editor.addItem(level.displayName)
         if level.displayName == currentName:
             index = number
     editor.setCurrentIndex(index)
     editor.setEditable(False)
     return editor
Exemplo n.º 24
0
 def createEditor( self, parent, option, index ):
     combo = QComboBox(parent)
     
     item = self.parent().itemFromIndex(index)
     columnType = item.columnType()
     
     operators = Q.ColumnOps.get(columnType,
                                 Q.ColumnOps[None])
     
     # create the keys based on the column type
     keys = []
     for operator in operators:
         op_name = Q.Op[operator]
         keys.append(projex.text.joinWords(op_name, ' ').lower())
     
     combo.addItems(sorted(keys))
     combo.setEditable(True)
     combo.setInsertPolicy(QComboBox.NoInsert)
     
     return combo
Exemplo n.º 25
0
    def createEditor(self, parent):
        """ Returns the correctly initialized editor for the item value. 
        
        @param parent: Parent widget of the created editor widget.
        @type parent: L{QWidget<PyQt4.QtGui.QWidget>}
        
        @return: Currently a combination box.
        @rtype: L{QComboBox<PyQt4.QtGui.QComboBox>}
        """

        editor = QComboBox(parent)
        currentName = unicode(self.text())
        index = 0
        for number, level in enumerate(self.accessLevels):
            editor.addItem(level.displayName)
            if level.displayName == currentName:
                index = number
        editor.setCurrentIndex(index)
        editor.setEditable(False)
        return editor
Exemplo n.º 26
0
class QuickWatch(QToolBar):
    def __init__(self, parent, distributedObjects):
        QToolBar.__init__(self, "QuickWatch")
        self.config = QuickWatchConfig()
        distributedObjects.configStore.registerConfigSet(self.config)

        self.setObjectName("QuickWatch")
        parent.addToolBar(self)
        self.watchedit = QComboBox()
        self.watchedit.setFixedHeight(28)
        self.watchedit.setInsertPolicy(QComboBox.NoInsert)
        self.watchedit.setEditable(True)
        self.watchedit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.addWidget(self.watchedit)
        self.distributedObjects = distributedObjects
        self.addAction(Icons.watch, "Add to Watch", self.addToWatch)
        self.addAction(Icons.datagraph, "Add to Data Graph", self.addToDG)
        self.watchedit.lineEdit().returnPressed.connect(self.returnPressed)

    def __addCurrentText(self):
        text = self.watchedit.lineEdit().text()
        idx = self.watchedit.findText(text)
        if idx == -1:
            self.watchedit.addItem(text)
        self.watchedit.setEditText("")

    def returnPressed(self):
        if self.config.addTo.value == "Watch View":
            self.addToWatch()
        elif self.config.addTo.value == "Data Graph View":
            self.addToDG()

    def addToWatch(self):
        self.distributedObjects.watchModel.addVar(
            self.watchedit.lineEdit().text())
        self.__addCurrentText()

    def addToDG(self):
        self.distributedObjects.datagraphController.addWatch(
            self.watchedit.lineEdit().text())
        self.__addCurrentText()
Exemplo n.º 27
0
 def setRockPropertyType(self):
     c_Row = self.dlg.bedRockSetTable.currentRow()
     box = self.dlg.bedRockSetTable.cellWidget(c_Row, 0)
     if box.currentIndex() == 0:
         self.dlg.bedRockSetTable.setItem(
             c_Row, 1, QTableWidgetItem('d_cover'))
         self.dlg.bedRockSetTable.setItem(
             c_Row, 2, QTableWidgetItem('K_h'))
         self.dlg.bedRockSetTable.setItem(
             c_Row, 3, QTableWidgetItem('TAU_cri'))
         self.dlg.bedRockSetTable.setItem(
             c_Row, 4, QTableWidgetItem('K_a'))
         self.dlg.bedRockSetTable.setItem(
             c_Row, 5, QTableWidgetItem('Young'))
         self.dlg.bedRockSetTable.setItem(
             c_Row, 6, QTableWidgetItem('Tensile'))
         if self.dlg.bedRockSetTable.cellWidget(c_Row+1, 5):
             self.dlg.bedRockSetTable.removeCellWidget(c_Row+1, 5)
             self.dlg.bedRockSetTable.setItem(
                 c_Row+1, 5, QTableWidgetItem(u''))
     elif box.currentIndex() == 1:
         self.dlg.bedRockSetTable.setItem(
             c_Row, 1, QTableWidgetItem('d_cover'))
         self.dlg.bedRockSetTable.setItem(
             c_Row, 2, QTableWidgetItem('E_h'))
         self.dlg.bedRockSetTable.setItem(
             c_Row, 3, QTableWidgetItem('Alpha'))
         self.dlg.bedRockSetTable.setItem(
             c_Row, 4, QTableWidgetItem('Beta'))
         self.dlg.bedRockSetTable.setItem(
             c_Row, 5, QTableWidgetItem('kh'))
         self.dlg.bedRockSetTable.setItem(
             c_Row, 6, QTableWidgetItem(''))
         KhSelector = QComboBox()
         KhSelector.setEditable(True)
         KhSelector.addItem(u'')
         KhSelector.addItem('Use File')
         KhSelector.currentIndexChanged.connect(self.useKhFile)
         self.dlg.bedRockSetTable.setCellWidget(c_Row+1, 5, KhSelector)
         self.dlg.bedRockSetTable.setItem(c_Row+1, 6, QTableWidgetItem(''))
Exemplo n.º 28
0
class GuiMock(object):

    def __init__(self):
        self._warning = None
        self._question = None
        self._text = {}
        self._text['FatalError'] = ''
        self._text['Account'] = ''
        self._text['SaveAccount'] = ''
        self.text_input = QComboBox()
        self.text_input.setEditable(True)
        self.list_account = QComboBox()

    def connect(self, widget, signal, callback):
        pass

    def displayWarning(self, title, message):
        self._warning = (title, message)

    def _displayQuestion(self, title, message):
        self._question = (title, message)
        return True
Exemplo n.º 29
0
class QuickWatch(QToolBar):
    def __init__(self, parent, distributedObjects):
        QToolBar.__init__(self, "QuickWatch")
        self.config = QuickWatchConfig()
        distributedObjects.configStore.registerConfigSet(self.config)

        self.setObjectName("QuickWatch")
        parent.addToolBar(self)
        self.watchedit = QComboBox()
        self.watchedit.setFixedHeight(28)
        self.watchedit.setInsertPolicy(QComboBox.NoInsert)
        self.watchedit.setEditable(True)
        self.watchedit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.addWidget(self.watchedit)
        self.distributedObjects = distributedObjects
        self.addAction(Icons.watch, "Add to Watch", self.addToWatch)
        self.addAction(Icons.datagraph, "Add to Data Graph", self.addToDG)
        self.watchedit.lineEdit().returnPressed.connect(self.returnPressed)

    def __addCurrentText(self):
        text = self.watchedit.lineEdit().text()
        idx = self.watchedit.findText(text)
        if idx == -1:
            self.watchedit.addItem(text)
        self.watchedit.setEditText("")

    def returnPressed(self):
        if self.config.addTo.value == "Watch View":
            self.addToWatch()
        elif self.config.addTo.value == "Data Graph View":
            self.addToDG()

    def addToWatch(self):
        self.distributedObjects.watchModel.addVar(self.watchedit.lineEdit().text())
        self.__addCurrentText()

    def addToDG(self):
        self.distributedObjects.datagraphController.addWatch(self.watchedit.lineEdit().text())
        self.__addCurrentText()
Exemplo n.º 30
0
class collectDelegate(QItemDelegate):
    def __init__(self, parent, module):
        self.module = module
        QItemDelegate.__init__(self, parent)

    def createEditor(self, parent, option, index):
        column = index.column()
        self.index = index
        content = index.model().data(index, Qt.EditRole)
        if column == 2:
            self.content = index.model().data(index, Qt.EditRole)
            self.editorQWidget = QComboBox(parent)
            self.editorQWidget.setEditable(True)
            self.editorQWidget.addItems(self.module.fieldMapping.values())
            if self.content in self.module.fieldMapping.values():
                self.editorQWidget.setCurrentIndex(
                    self.editorQWidget.findData(self.content))
            else:
                self.editorQWidget.insertItem(0, '')
                self.editorQWidget.setCurrentIndex(0)
            return self.editorQWidget
        else:
            return None
            return QItemDelegate.createEditor(self, parent, option, index)
Exemplo n.º 31
0
class XTimeDeltaEdit(QFrame):
    def __init__(self, parent=None):
        super(XTimeDeltaEdit, self).__init__(parent)
        
        # define custom properties
        self.setStyleSheet(COMBO_STYLE)
        
        self._numberSpinner = QSpinBox(self)
        self._numberSpinner.setRange(0, 100000)
        self._numberSpinner.setFrame(False)
        self._numberSpinner.setButtonSymbols(QSpinBox.NoButtons)
        self._numberSpinner.setSizePolicy(QSizePolicy.Expanding,
                                          QSizePolicy.Expanding)
        
        self._unitCombo = QComboBox(self)
        self._unitCombo.setEditable(True)
        self._unitCombo.setInsertPolicy(QComboBox.NoInsert)
        self._unitCombo.setFrame(False)
        self._unitCombo.addItems(['year(s)',
                                  'month(s)',
                                  'week(s)',
                                  'day(s)',
                                  'hour(s)',
                                  'minute(s)',
                                  'second(s)'])
        
        self._unitCombo.setCurrentIndex(3)
        self._unitCombo.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Expanding)
        
        self._directionCombo = QComboBox(self)
        self._directionCombo.addItems(['ago', 'from now'])
        self._directionCombo.setEditable(True)
        self._directionCombo.setInsertPolicy(QComboBox.NoInsert)
        self._directionCombo.setFrame(False)
        self._directionCombo.setSizePolicy(QSizePolicy.Expanding,
                                           QSizePolicy.Expanding)
        
        # setup ui
        self.setFrameShape(QFrame.StyledPanel)
        self.setFrameShadow(QFrame.Sunken)
        self.setBackgroundRole(QPalette.Base)
        self.setAutoFillBackground(True)
        
        layout = QHBoxLayout()
        layout.setContentsMargins(2, 2, 2, 2)
        layout.setSpacing(0)
        layout.addWidget(self._numberSpinner)
        layout.addWidget(self._unitCombo)
        layout.addWidget(self._directionCombo)
        self.setLayout(layout)
        
    def delta(self):
        """
        Returns a delta based on this widget's information.
        
        :return     <datetime.timedelta>
        """
        number      = self._numberSpinner.value()
        unit        = self._unitCombo.currentText()
        direction   = self._directionCombo.currentText()
        
        # use past tense
        if direction == 'ago':
            number = -number
        
        if unit == 'year(s)':
            return datetime.timedelta(number * 365)
        elif unit == 'month(s)':
            return datetime.timedelta(number * 30)
        elif unit == 'week(s)':
            return datetime.timedelta(number * 7)
        elif unit == 'day(s)':
            return datetime.timedelta(number)
        elif unit == 'hour(s)':
            return datetime.timedelta(0, number * 3600)
        elif unit == 'minute(s)':
            return datetime.timedelta(0, number * 60)
        else:
            return datetime.timedelta(0, number)
    
    def setDelta(self, delta):
        """
        Sets the time delta for this widget to the inputed delta.
        
        :param      delta | <datetime.timedelta>
        """
        days = int(delta.days)
        secs = int(delta.total_seconds())
        
        direction = 'from now'
        if secs < 0:
            direction = 'ago'
        
        if days and days % 365 == 0:
            number = days / 365
            unit = 'year(s)'
        elif days and days % 30 == 0:
            number = days / 30
            unit = 'month(s)'
        elif days and days % 7 == 0:
            number = days / 7
            unit = 'week(s)'
        elif days:
            number = days
            unit = 'day(s)'
        elif secs % 3600 == 0:
            number = secs / 3600
            unit = 'hour(s)'
        elif secs % 60 == 0:
            number = secs / 60
            unit = 'minute(s)'
        else:
            number = secs
            unit = 'second(s)'
        
        self._numberSpinner.setValue(abs(int(number)))
        self._unitCombo.setCurrentIndex(self._unitCombo.findText(unit))
        index = self._directionCombo.findText(direction)
        self._directionCombo.setCurrentIndex(index)
Exemplo n.º 32
0
 def getWidgetFromParameter(self, param):
     if isinstance(param, ParameterRaster):
         item = QComboBox()
         layers = self.getAvailableValuesOfType(ParameterRaster, OutputRaster)
         if param.optional:
             item.addItem(self.NOT_SELECTED, None)
         for layer in layers:
             item.addItem(self.resolveValueDescription(layer), layer)
     elif isinstance(param, ParameterVector):
         item = QComboBox()
         layers = self.getAvailableValuesOfType(ParameterVector, OutputVector)
         if param.optional:
             item.addItem(self.NOT_SELECTED, None)
         for layer in layers:
             item.addItem(self.resolveValueDescription(layer), layer)
     elif isinstance(param, ParameterTable):
         item = QComboBox()
         tables = self.getAvailableValuesOfType(ParameterTable, OutputTable)
         layers = self.getAvailableValuesOfType(ParameterVector, OutputVector)
         if param.optional:
             item.addItem(self.NOT_SELECTED, None)
         for table in tables:
             item.addItem(self.resolveValueDescription(table), table)
         for layer in layers:
             item.addItem(self.resolveValueDescription(layer), layer)
     elif isinstance(param, ParameterBoolean):
         item = QComboBox()
         item.addItem('Yes')
         item.addItem('No')
         bools = self.getAvailableValuesOfType(ParameterBoolean, None)
         for b in bools:
             item.addItem(self.resolveValueDescription(b), b)
     elif isinstance(param, ParameterSelection):
         item = QComboBox()
         item.addItems(param.options)
     elif isinstance(param, ParameterFixedTable):
         item = FixedTablePanel(param)
     elif isinstance(param, ParameterRange):
         item = RangePanel(param)
     elif isinstance(param, ParameterMultipleInput):
         if param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY:
             options = self.getAvailableValuesOfType(ParameterVector, OutputVector)
         else:
             options = self.getAvailableValuesOfType(ParameterRaster, OutputRaster)
         opts = []
         for opt in options:
             opts.append(self.resolveValueDescription(opt))
         item = MultipleInputPanel(opts)
     elif isinstance(param, ParameterString):
         strings = self.getAvailableValuesOfType(ParameterString, OutputString)
         options = [(self.resolveValueDescription(s), s) for s in strings]
         if param.multiline:
             item = MultilineTextPanel(options)
             item.setText(unicode(param.default))
         else:
             item = QComboBox()
             item.setEditable(True)
             for desc, val in options:
                 item.addItem(desc, val)
             item.setEditText(unicode(param.default))
     elif isinstance(param, ParameterTableField):
         item = QComboBox()
         item.setEditable(True)
         fields = self.getAvailableValuesOfType(ParameterTableField, None)
         for f in fields:
             item.addItem(self.resolveValueDescription(f), f)
     elif isinstance(param, ParameterNumber):
         item = QComboBox()
         item.setEditable(True)
         numbers = self.getAvailableValuesOfType(ParameterNumber, OutputNumber)
         for n in numbers:
             item.addItem(self.resolveValueDescription(n), n)
         item.setEditText(str(param.default))
     elif isinstance(param, ParameterCrs):
         item = CrsSelectionPanel(param.default)
     elif isinstance(param, ParameterExtent):
         item = QComboBox()
         item.setEditable(True)
         extents = self.getAvailableValuesOfType(ParameterExtent, OutputExtent)
         if self.canUseAutoExtent():
             item.addItem(self.USE_MIN_COVERING_EXTENT, None)
         for ex in extents:
             item.addItem(self.resolveValueDescription(ex), ex)
         if not self.canUseAutoExtent():
             item.setEditText(str(param.default))
     elif isinstance(param, ParameterFile):
         item = QComboBox()
         item.setEditable(True)
         files = self.getAvailableValuesOfType(ParameterFile, OutputFile)
         for f in files:
             item.addItem(self.resolveValueDescription(f), f)
     elif isinstance(param, ParameterGeometryPredicate):
         item = GeometryPredicateSelectionPanel(param.enabledPredicates)
     else:
         item = QLineEdit()
         try:
             item.setText(str(param.default))
         except:
             pass
     return item
Exemplo n.º 33
0
class FindInFilesDialog(QDialog):

    def __init__(self, result_widget, parent):
        QDialog.__init__(self, parent)
        self._find_thread = FindInFilesThread()
        self.setWindowTitle("Find in files")
        self.resize(400, 300)
        #MAIN LAYOUT
        main_vbox = QVBoxLayout(self)

        self.pattern_line_edit = QLineEdit()
        self.dir_name_root = None
        self.user_home = os.path.expanduser('~')
        self.dir_combo = QComboBox()
        self.dir_combo.addItem(self.user_home)
        self.dir_combo.setEditable(True)
        self.open_button = QPushButton(QIcon(resources.IMAGES['find']),
            self.tr("Open"))
        self.filters_line_edit = QLineEdit("*.py")
        self.replace_line = QLineEdit()
        self.replace_line.setEnabled(False)
        self.check_replace = QCheckBox(self.tr("Replace: "))
        self.case_checkbox = QCheckBox(self.tr("C&ase sensitive"))
        self.type_checkbox = QCheckBox(self.tr("R&egular Expression"))
        self.recursive_checkbox = QCheckBox(self.tr("Rec&ursive"))
        self.recursive_checkbox.setCheckState(Qt.Checked)
        self.phrase_radio = QRadioButton(
            self.tr("Search by Phrase (Exact Match)."))
        self.phrase_radio.setChecked(True)
        self.words_radio = QRadioButton(
            self.tr("Search for all the words "
                    "(anywhere in the document, not together)."))
        self.find_button = QPushButton(self.tr("Find!"))
        self.find_button.setMaximumWidth(150)
        self.cancel_button = QPushButton(self.tr("Cancel"))
        self.cancel_button.setMaximumWidth(150)
        self.result_widget = result_widget

        hbox = QHBoxLayout()
        hbox.addWidget(self.find_button)
        hbox.addWidget(self.cancel_button)

        #main section
        find_group_box = QGroupBox(self.tr("Main"))
        grid = QGridLayout()
        grid.addWidget(QLabel(self.tr("Text: ")), 0, 0)
        grid.addWidget(self.pattern_line_edit, 0, 1)
        grid.addWidget(QLabel(self.tr("Directory: ")), 1, 0)
        grid.addWidget(self.dir_combo, 1, 1)
        grid.addWidget(self.open_button, 1, 2)
        grid.addWidget(QLabel(self.tr("Filter: ")), 2, 0)
        grid.addWidget(self.filters_line_edit, 2, 1)
        grid.addWidget(self.check_replace, 3, 0)
        grid.addWidget(self.replace_line, 3, 1)

        find_group_box.setLayout(grid)
        #add main section to MAIN LAYOUT
        main_vbox.addWidget(find_group_box)

        #options sections
        options_group_box = QGroupBox(self.tr("Options"))
        gridOptions = QGridLayout()
        gridOptions.addWidget(self.case_checkbox, 0, 0)
        gridOptions.addWidget(self.type_checkbox, 1, 0)
        gridOptions.addWidget(self.recursive_checkbox, 2, 0)
        gridOptions.addWidget(self.phrase_radio, 0, 1)
        gridOptions.addWidget(self.words_radio, 1, 1)

        options_group_box.setLayout(gridOptions)
        #add options sections to MAIN LAYOUT
        main_vbox.addWidget(options_group_box)

        #add buttons to MAIN LAYOUT
        main_vbox.addLayout(hbox)

        #Focus
        self.pattern_line_edit.setFocus()
        self.open_button.setFocusPolicy(Qt.NoFocus)

        #signal
        self.connect(self.open_button, SIGNAL("clicked()"), self._select_dir)
        self.connect(self.find_button, SIGNAL("clicked()"),
            self._find_in_files)
        self.connect(self.cancel_button, SIGNAL("clicked()"),
            self._kill_thread)
        self.connect(self._find_thread, SIGNAL("found_pattern(PyQt_PyObject)"),
            self._found_match)
        self.connect(self._find_thread, SIGNAL("finished()"),
            self._find_thread_finished)
        self.connect(self.type_checkbox, SIGNAL("stateChanged(int)"),
            self._change_radio_enabled)
        self.connect(self.check_replace, SIGNAL("stateChanged(int)"),
            self._replace_activated)
        self.connect(self.words_radio, SIGNAL("clicked(bool)"),
            self._words_radio_pressed)

    def _replace_activated(self):
        self.replace_line.setEnabled(self.check_replace.isChecked())
        self.phrase_radio.setChecked(True)

    def _words_radio_pressed(self, value):
        self.replace_line.setEnabled(not value)
        self.check_replace.setChecked(not value)
        self.words_radio.setChecked(True)

    def _change_radio_enabled(self, val):
        enabled = not self.type_checkbox.isChecked()
        self.phrase_radio.setEnabled(enabled)
        self.words_radio.setEnabled(enabled)

    def show(self, actual_project=None, actual=None):
        self.dir_combo.clear()
        self.dir_name_root = actual_project if \
            actual_project else [self.user_home]
        self.dir_combo.addItems(self.dir_name_root)
        if actual:
            index = self.dir_combo.findText(actual)
            self.dir_combo.setCurrentIndex(index)
        super(FindInFilesDialog, self).show()
        self.pattern_line_edit.setFocus()

    def reject(self):
        self._kill_thread()
        # Crazy hack to avoid circular imports
        self.result_widget.parent().parent().parent().hide()
        super(FindInFilesDialog, self).reject()

    def _find_thread_finished(self):
        self.emit(SIGNAL("finished()"))
        self._find_thread.wait()

    def _select_dir(self):
        dir_name = QFileDialog.getExistingDirectory(self,
            self.tr("Open Directory"),
            self.dir_combo.currentText(),
            QFileDialog.ShowDirsOnly)
        index = self.dir_combo.findText(dir_name)
        if index >= 0:
            self.dir_combo.setCurrentIndex(index)
        else:
            self.dir_combo.insertItem(0, dir_name)
            self.dir_combo.setCurrentIndex(0)

    def _found_match(self, result):
        file_name = result[0]
        items = result[1]
        self.result_widget.update_result(
            self.dir_combo.currentText(), file_name, items)

    def _kill_thread(self):
        if self._find_thread.isRunning():
            self._find_thread.cancel()
        self.accept()

    def _find_in_files(self):
        self.emit(SIGNAL("findStarted()"))
        self._kill_thread()
        self.result_widget.clear()
        pattern = self.pattern_line_edit.text()
        dir_name = self.dir_combo.currentText()

        filters = re.split("[,;]", self.filters_line_edit.text())

        # Version of PyQt API 1
        # filters = self.filters_line_edit.text().split(QRegExp("[,;]"),
        #     QString.SkipEmptyParts)

        #remove the spaces in the words Ex. (" *.foo"--> "*.foo")
        filters = [f.strip() for f in filters]
        case_sensitive = self.case_checkbox.isChecked()
        type_ = QRegExp.RegExp if \
            self.type_checkbox.isChecked() else QRegExp.FixedString
        recursive = self.recursive_checkbox.isChecked()
        by_phrase = True
        if self.phrase_radio.isChecked() or self.type_checkbox.isChecked():
            regExp = QRegExp(pattern, case_sensitive, type_)
        elif self.words_radio.isChecked():
            by_phrase = False
            type_ = QRegExp.RegExp
            pattern = '|'.join(
                [word.strip() for word in pattern.split()])
            regExp = QRegExp(pattern, case_sensitive, type_)
        #save a reference to the root directory where we find
        self.dir_name_root = dir_name
        self._find_thread.find_in_files(dir_name, filters, regExp, recursive,
            by_phrase)
Exemplo n.º 34
0
    def _init_layout(self):
        """
        Create the GUI widgets (but leave them empty).
        """
        hostname_combobox = QComboBox(parent=self)
        self._hostname_combobox = hostname_combobox
        hostname_combobox.setEditable(True)
        hostname_combobox.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Maximum)
        for hostname in self._suggested_hostnames:
            hostname_combobox.addItem(hostname)

        # EventFilter is installed after everything else is initialized. (See below.)
        #hostname_combobox.installEventFilter(self)

        self._connect_button = QPushButton("Connect",
                                           parent=self,
                                           clicked=self._handle_new_hostname)

        hostname_layout = QHBoxLayout()
        hostname_layout.addWidget(hostname_combobox)
        hostname_layout.addWidget(self._connect_button)

        hostinfo_table = QTableWidget()
        hostinfo_table.setColumnCount(len(SERVER_INFO_FIELDS))
        hostinfo_table.setHorizontalHeaderLabels(SERVER_INFO_FIELDS)
        hostinfo_table.horizontalHeader().setVisible(True)
        hostinfo_table.verticalHeader().setVisible(False)
        hostinfo_table.setRowCount(1)
        hostinfo_table.setItem(0, 0, QTableWidgetItem("Placeholder"))
        hostinfo_table.setVisible(False)
        hostinfo_table.resizeRowsToContents()
        hostinfo_table.horizontalHeader().setStretchLastSection(True)
        table_height = hostinfo_table.verticalHeader().sectionSize(
            0) + hostinfo_table.rowHeight(0)
        hostinfo_table.resize(QSize(hostinfo_table.width(), table_height))
        hostinfo_table.setMaximumSize(QSize(1000, table_height))
        hostinfo_table.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)

        host_layout = QVBoxLayout()
        host_layout.addLayout(hostname_layout)
        host_layout.addWidget(hostinfo_table)

        host_groupbox = QGroupBox("DVID Host", parent=self)
        host_groupbox.setLayout(host_layout)
        host_groupbox.setSizePolicy(QSizePolicy.Preferred,
                                    QSizePolicy.Preferred)

        repo_treewidget = QTreeWidget(parent=self)
        repo_treewidget.setHeaderLabels(
            TREEVIEW_COLUMNS)  # TODO: Add type, shape, axes, etc.
        repo_treewidget.setSizePolicy(QSizePolicy.Preferred,
                                      QSizePolicy.Preferred)
        repo_treewidget.itemSelectionChanged.connect(
            self._handle_data_selection)

        data_layout = QVBoxLayout()
        data_layout.addWidget(repo_treewidget)
        data_groupbox = QGroupBox("Data Volumes", parent=self)
        data_groupbox.setLayout(data_layout)

        node_listwidget = QListWidget(parent=self)
        node_listwidget.setSizePolicy(QSizePolicy.Preferred,
                                      QSizePolicy.Preferred)
        node_listwidget.itemSelectionChanged.connect(self._update_status)

        node_layout = QVBoxLayout()
        node_layout.addWidget(node_listwidget)
        node_groupbox = QGroupBox("Nodes", parent=self)
        node_groupbox.setLayout(node_layout)

        new_data_edit = QLineEdit(parent=self)
        new_data_edit.textEdited.connect(self._update_status)
        full_url_label = QLabel(parent=self)
        full_url_label.setSizePolicy(QSizePolicy.Preferred,
                                     QSizePolicy.Maximum)
        text_flags = full_url_label.textInteractionFlags()
        full_url_label.setTextInteractionFlags(text_flags
                                               | Qt.TextSelectableByMouse)

        new_data_layout = QVBoxLayout()
        new_data_layout.addWidget(new_data_edit)
        new_data_groupbox = QGroupBox("New Data Volume", parent=self)
        new_data_groupbox.setLayout(new_data_layout)
        new_data_groupbox.setSizePolicy(QSizePolicy.Preferred,
                                        QSizePolicy.Maximum)

        buttonbox = QDialogButtonBox(Qt.Horizontal, parent=self)
        buttonbox.setStandardButtons(QDialogButtonBox.Ok
                                     | QDialogButtonBox.Cancel)
        buttonbox.accepted.connect(self.accept)
        buttonbox.rejected.connect(self.reject)
        buttonbox.button(QDialogButtonBox.Ok).setEnabled(False)

        layout = QVBoxLayout()
        layout.addWidget(host_groupbox)
        layout.addWidget(data_groupbox)
        layout.addWidget(node_groupbox)
        if self._mode == "specify_new":
            layout.addWidget(new_data_groupbox)
        else:
            new_data_groupbox.hide()
        layout.addWidget(full_url_label)
        layout.addWidget(buttonbox)

        # Stretch factors
        layout.setStretchFactor(data_groupbox, 3)
        layout.setStretchFactor(node_groupbox, 1)

        self.setLayout(layout)
        self.setWindowTitle("Select DVID Volume")
        self.resize(1000, 1000)

        # Initially disabled
        data_groupbox.setEnabled(False)
        node_groupbox.setEnabled(False)
        new_data_groupbox.setEnabled(False)

        # Set tab order
        self.setTabOrder(hostname_combobox, repo_treewidget)
        self.setTabOrder(repo_treewidget, node_listwidget)
        self.setTabOrder(node_listwidget, buttonbox)

        # Save instance members
        self._hostinfo_table = hostinfo_table
        self._data_groupbox = data_groupbox
        self._node_groupbox = node_groupbox
        self._new_data_groupbox = new_data_groupbox
        self._repo_treewidget = repo_treewidget
        self._node_listwidget = node_listwidget
        self._new_data_edit = new_data_edit
        self._full_url_label = full_url_label
        self._buttonbox = buttonbox

        # Finally install eventfilter (after everything is initialized)
        hostname_combobox.installEventFilter(self)
Exemplo n.º 35
0
 def addWidgets(self):
     layout = QVBoxLayout()
     self.setLayout(layout)
     grid = QGridLayout()
     layout.addLayout(grid)
     grid.setColumnMinimumWidth(1, 20)
     grid.setColumnStretch(2, 100)
     grid.setRowStretch(6, 100)
     label = QLabel('Group', self)
     grid.addWidget(label, 0, 0)
     combobox = QComboBox(self)
     combobox.setEditable(True)
     combobox.setInsertPolicy(QComboBox.InsertAtTop)
     grid.addWidget(combobox, 0, 2)
     self.combobox = combobox
     self.fields['group'] = (combobox.currentText, None)
     label = QLabel('Name', self)
     grid.addWidget(label, 1, 0)
     nameedt = QLineEdit(self)
     nameedt.textChanged.connect(self.fieldUpdated)
     grid.addWidget(nameedt, 1, 2)
     self.nameedt = nameedt
     self.fields['name'] = (nameedt.text, nameedt.setText)
     label = QLabel('Username', self)
     grid.addWidget(label, 2, 0)
     editor = QLineEdit(self)
     grid.addWidget(editor, 2, 2)
     self.fields['username'] = (editor.text, editor.setText)
     label = QLabel('Password', self)
     grid.addWidget(label, 3, 0)
     passwdedt = QLineEdit(self)
     passwdedt.setEchoMode(QLineEdit.Password)
     passwdedt.textChanged.connect(self.fieldUpdated)
     grid.addWidget(passwdedt, 3, 2)
     self.fields['password'] = (passwdedt.text, passwdedt.setText)
     self.passwdedt = passwdedt
     config = RandomPasswordConfiguration()
     icon = QIcon(QPixmap(asset('png', 'eye.png')))
     showbtn = QPushButton(icon, '', self)
     showbtn.setCheckable(True)
     showbtn.toggled.connect(self.setShowPassword)
     showbtn.setFixedHeight(passwdedt.sizeHint().height())
     grid.addWidget(showbtn, 3, 3)
     self.showbtn = showbtn
     passwdbtn = GeneratePasswordButton('Generate', config, self)
     passwdbtn.setFixedWidth(passwdbtn.sizeHint().width())
     grid.addWidget(passwdbtn, 3, 4)
     passwdbtn.passwordGenerated.connect(passwdedt.setText)
     label = QLabel('Website')
     grid.addWidget(label, 5, 0)
     editor = QLineEdit(self)
     grid.addWidget(editor, 5, 2, 1, 3)
     self.fields['url'] = (editor.text, editor.setText)
     label = QLabel('Comment')
     grid.addWidget(label, 6, 0)
     editor = QTextEdit(self)
     editor.setAcceptRichText(False)
     grid.addWidget(editor, 6, 2, 1, 3)
     self.fields['comment'] = (editor.toPlainText, editor.setPlainText)
     layout.addStretch(100)
     hbox = QHBoxLayout()
     layout.addLayout(hbox)
     cancelbtn = QPushButton('Cancel')
     cancelbtn.clicked.connect(self.hide)
     hbox.addWidget(cancelbtn)
     savebtn = QPushButton('Save')
     savebtn.setDefault(True)
     savebtn.setEnabled(False)
     savebtn.clicked.connect(self.savePassword)
     hbox.addWidget(savebtn)
     self.savebtn = savebtn
     hbox.addStretch(100)
Exemplo n.º 36
0
class LayerSelectionPage(QFrame):
    #TODO. Filtering, (visible) row selection, multi selection
    colparams = ((0,65,'Name'), (1,235,'Title'), (2,350,'Keywords'))
    XFER_BW = 40
    def __init__(self, parent=None):
        super(LayerSelectionPage, self).__init__(parent)
        self.parent = parent
        
        #convenience link
        self.confconn_link = self.parent.parent.confconn
        
        #flag top prevent read read action on keyword delete. New logic makes this redundant
        #self.keywordbypass = False

        QToolTip.setFont(QFont('SansSerif', 10))
        
        #label
        filterlabel = QLabel('Filter')
        availablelabel = QLabel('Available Layers')
        selectionlabel = QLabel('Layer Selections')
        keywordlabel = QLabel('Keyword')
        explainlabel = QLabel("Edit Group assignments using this dialog or to simply initialise the Layer-Config just click 'Finish'")
        
        #selection buttons
        chooseallbutton = QPushButton('>>')
        chooseallbutton.setFixedWidth(self.XFER_BW)
        chooseallbutton.clicked.connect(self.doChooseAllClickAction)
        
        choosebutton = QPushButton('>')
        choosebutton.setFixedWidth(self.XFER_BW)
        choosebutton.clicked.connect(self.doChooseClickAction)
        
        rejectbutton = QPushButton('<')
        rejectbutton.setFixedWidth(self.XFER_BW)
        rejectbutton.clicked.connect(self.doRejectClickAction)
        
        rejectallbutton = QPushButton('<<')
        rejectallbutton.setFixedWidth(self.XFER_BW)
        rejectallbutton.clicked.connect(self.doRejectAllClickAction)
        
        #operation buttons        
        finishbutton = QPushButton('Finish')
        finishbutton.setToolTip('Finish and Close layer selection dialog')
        finishbutton.clicked.connect(self.parent.close)
        
        resetbutton = QPushButton('Reset')
        resetbutton.font()
        resetbutton.setToolTip('Read Layer from LDS GetCapabilities request. Overwrites current Layer Config')       
        resetbutton.clicked.connect(self.doResetClickAction)
        
        self.available_sfpm = LDSSFPAvailableModel(self)
        self.selection_sfpm = LDSSFPSelectionModel(self)
        
        self.available_sfpm.setSourceModel(self.parent.available_model)
        self.selection_sfpm.setSourceModel(self.parent.selection_model)
        
        #textedits
        filteredit = QLineEdit('')
        filteredit.setToolTip('Filter Available-Layers pane (filter operates across Name and Title fields and accepts Regex expressions)')       
        filteredit.textChanged.connect(self.available_sfpm.setActiveFilter)
        
        self.keywordcombo = QComboBox()
        self.keywordcombo.setToolTip('Select or Add a unique identifier to be saved in layer config (keyword)')
        self.keywordcombo.addItems(list(self.confconn_link.assigned))
        self.keywordcombo.setEditable(True)
        self.keywordcombo.activated.connect(self.doKeyComboChangeAction)
        
        lgindex = self.confconn_link.getLayerGroupIndex(self.confconn_link.lgval,col=1)
        lgentry = self.confconn_link.lglist[lgindex] if LU.assessNone(lgindex) else None
        #keywordedit = self.keywordcombo.lineEdit().text().toUtf8().data().decode('utf8')# for writing
        #if no entry or layer indicated then blank 
        self.keywordcombo.lineEdit().setText('' if lgentry is None or lgentry[0]==LORG.LAYER else lgentry[1])#self.confconn_link.lgval)#TODO. group only
        
        #header
        headmodel = QStandardItemModel()
        headmodel.setHorizontalHeaderLabels([i[2] for i in self.colparams][:self.parent.available_model.columnCount()])
        
        headview1 = QHeaderView(Qt.Horizontal)
        headview1.setModel(headmodel)
        headview1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) 
        
        headview2 = QHeaderView(Qt.Horizontal)
        headview2.setModel(headmodel)
        headview2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)            

        #table
        self.available = QTableView()
        self.available.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.available.setSelectionMode(QAbstractItemView.MultiSelection)       
        
        self.selection = QTableView()
        self.selection.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.selection.setSelectionMode(QAbstractItemView.MultiSelection)
        
        #interesting, must set model after selection attributes but before headers else row selections/headers don't work properly
        self.available.setModel(self.available_sfpm)
        self.selection.setModel(self.selection_sfpm)
        
        self.available.setSortingEnabled(True)
        self.available.setHorizontalHeader(headview1)
        
        self.selection.setSortingEnabled(True)
        self.selection.setHorizontalHeader(headview2)

        for cp in self.colparams:
            self.available.setColumnWidth(cp[0],cp[1])
            self.selection.setColumnWidth(cp[0],cp[1])

        self.available.verticalHeader().setVisible(False)
        self.available.horizontalHeader().setVisible(True)
        
        self.selection.verticalHeader().setVisible(False)
        self.selection.horizontalHeader().setVisible(True)
        
        
        #layout  
        vbox00 = QVBoxLayout()
        vbox00.addWidget(availablelabel)
        vbox00.addWidget(self.available)
        
        vbox01 = QVBoxLayout()
        vbox01.addWidget(chooseallbutton)
        vbox01.addWidget(choosebutton)
        vbox01.addWidget(rejectbutton)
        vbox01.addWidget(rejectallbutton)
        
        vbox02 = QVBoxLayout()
        vbox02.addWidget(selectionlabel)
        vbox02.addWidget(self.selection)

        
        vbox10 = QVBoxLayout()
        vbox10.addWidget(filterlabel)
        vbox10.addWidget(filteredit)
        
        hbox12 = QHBoxLayout()
        hbox12.addWidget(keywordlabel)
        hbox12.addStretch(1)
        #hbox12.addWidget(inspbutton)
        #hbox12.addWidget(addbutton)
        #hbox12.addWidget(delbutton)
        
        vbox12 = QVBoxLayout()
        vbox12.addLayout(hbox12)
        vbox12.addWidget(self.keywordcombo)
                
        #00|01|02
        #10|11|12
        grid0 = QGridLayout()
        grid0.addLayout(vbox00,1,0)
        grid0.addLayout(vbox01,1,1)
        grid0.addLayout(vbox02,1,2)
        grid0.addLayout(vbox10,0,0)
        grid0.addLayout(vbox12,0,2)
        
        
        hbox2 = QHBoxLayout()
        hbox2.addWidget(resetbutton)
        hbox2.addStretch(1)
        hbox2.addWidget(explainlabel)
        hbox2.addWidget(finishbutton)
        #gbox1.setLayout(hbox2)
        
        
        
        vbox3 = QVBoxLayout()
        vbox3.addLayout(grid0)
        #vbox3.addLayout(hbox3)
        #vbox3.addWidget(line0)
        vbox3.addLayout(hbox2)
        
        self.setLayout(vbox3)


            
    def doChooseAllClickAction(self):
        '''Moves the lot to Selected'''
        #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data())
        ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text()))
        if not self.checkKeyword(ktext): return
        #------------------------------
        self.parent.signalModels(self.parent.STEP.PRE)
        #self.parent.selection_model.mdata += self.parent.available_model.mdata
        self.parent.selection_model.initData(self.confconn_link.complete)
        self.parent.available_model.initData([])
        self.parent.signalModels(self.parent.STEP.POST)
        #------------------------------
        self.parent.writeKeysToLayerConfig(ktext)
        #self.confconn_link.setupAssignedLayerList()
        if self.keywordcombo.findText(ktext) == -1:
            self.keywordcombo.addItem(ktext)
    
    def doChooseClickAction(self):
        '''Takes available selected and moves to selection'''
        #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data())
        ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text()))
        #ktext = str(self.keywordcombo.lineEdit().text())
        if not self.checkKeyword(ktext): return
        #------------------------------
        select = self.available.selectionModel()
        if select.hasSelection():
            self.transferSelectedRows(select.selectedRows(),self.available_sfpm,self.selection_sfpm)
            #------------------------------
            self.parent.writeKeysToLayerConfig(ktext)
            #self.confconn_link.assigned = self.confconn_link.setupAssignedLayerList()
            # -1 to indicate no index since 0,1,... are valid
            if self.keywordcombo.findText(ktext) == -1:
                self.keywordcombo.addItem(ktext)
        else:
            ldslog.warn('L2R > Transfer action without selection')        
        #TRACE#
        #pdb.set_trace()
        self.available.clearSelection()
          
        
    def transferSelectedRows(self,indices,from_model,to_model):
        tlist = []
        for proxymodelindex in indices:
            transfer = from_model.getData(proxymodelindex)
            tlist.append((proxymodelindex,transfer),)

        to_model.addData([t[1] for t in tlist])
        from_model.delData([t[0] for t in tlist])
        return tlist
            
    def doRejectClickAction(self):
        '''Takes available selected and moves to selection'''
        #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data())
        ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text()))
        if not self.checkKeyword(ktext): return
        #------------------------------
        select = self.selection.selectionModel()
        if select.hasSelection():
            tlist = self.transferSelectedRows(select.selectedRows(),self.selection_sfpm,self.available_sfpm)
            #------------------------------
            kindex = self.keywordcombo.findText(ktext)
            remainder = self.parent.deleteKeysFromLayerConfig([ll[1][0] for ll in tlist],ktext)
            if remainder > 0 and kindex == -1:
                #items+newkey -> add
                self.parent.writeKeysToLayerConfig(ktext)
                self.keywordcombo.addItem(ktext)
            elif remainder == 0 and kindex > -1:
                #empty+oldkey -> del
                self.keywordcombo.removeItem(kindex)
                self.keywordcombo.clearEditText()
        else:
            ldslog.warn('R2L < Transfer action without selection')
        #TRACE#
        #pdb.set_trace()
        self.selection.clearSelection()

                
    def doRejectAllClickAction(self):
        #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data())
        ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text()))
        if not self.checkKeyword(ktext): return
        #------------------------------
        self.parent.deleteKeysFromLayerConfig([ll[0] for ll in self.parent.selection_model.mdata],ktext)
        #------------------------------
        self.parent.signalModels(self.parent.STEP.PRE)
        #self.parent.available_model.mdata += self.parent.selection_model.mdata
        self.parent.available_model.initData(self.confconn_link.complete)
        self.parent.selection_model.initData([])
        self.parent.signalModels(self.parent.STEP.POST)        
        #------------------------------
        #self.confconn_link.setupAssignedLayerList()
        #self.keywordbypass = True
        self.keywordcombo.removeItem(self.keywordcombo.findText(ktext))
        self.keywordcombo.clearEditText()
        
    def doKeyComboChangeAction(self):
        '''Reset the available pane and if there is anything in the keyword box use this to init the selection pane'''
        #HACK
        #if self.keywordbypass:
        #    self.keywordbypass = False
        #    return
        #------------------------------
        #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data())
        ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text()))
        #------------------------------
        av_sl = self.parent.splitData(ktext,self.confconn_link.complete)
        #av_sl = self.parent.splitData(ktext,self.confconn_link.complete)
        self.parent.signalModels(self.parent.STEP.PRE)
        self.parent.available_model.initData(av_sl[0])
        self.parent.selection_model.initData(av_sl[1])
        self.parent.signalModels(self.parent.STEP.POST)
    
    def doResetClickAction(self):
        '''Dumps the LC and rebuilds from a fresh read of the caps doc'''
        #int warning (QWidget parent, QString title, QString text, QString button0Text, QString button1Text = QString(), QString button2Text = QString(), int defaultButtonNumber = 0, int escapeButtonNumber = -1)
        ans = QMessageBox.warning(self, "Reset","This action will overwrite your Layer Configuration using the current LDS settings (potentially adding new or removing layers). Continue?","Continue","Cancel")
        if ans:
            #Cancel
            ldslog.warn('Cancelling Reset operation')
            return
        #Continue
        ldslog.warn('Reset Layer Config')
        self.parent.resetLayers()
        self.keywordcombo.clear()

    def checkKeyword(self,ktext):
        '''Checks keyword isn't null and isn't part of the LDS supplied keywords'''
        if LU.assessNone(ktext) is None:
            QMessageBox.about(self, "Keyword Required","Please enter a Keyword to assign Layer(s) to")
            return False
        if ktext in self.confconn_link.reserved:
            QMessageBox.about(self, "Reserved Keyword","'{}' is a reserved keyword, please select again".format(ktext))
            return False
        return True
Exemplo n.º 37
0
class BookKeeping(QFrame):

    # =======================================================================
    def __init__(self, parent=None, _PARENT=None):

        # -------------------------------------------------------------------
        QFrame.__init__(self, parent);
        # -------------------------------------------------------------------
        self.PARENT                         = _PARENT;
        self.CONF                           = _PARENT.CONF;

        #self.SHA256                         = hashlib.sha256;
        #UID_SHA256 = self.SHA256( str(time.time()) ).hexdigest();
        self.SELECTED_BKKPG_UID             = None;

        # -------------------------------------------------------------------
        self.setGeometry( 3, 5, 975, 555 );
        self.setStyleSheet( "QFrame{ font: 12px 'monospace'; color: #000; background-color: transparent; background-image: url('./data/imgs/TAB_BookKeeping.png'); }" );

        self.PAIR_COMBO                     = QComboBox( self);
        self.PAIR_COMBO.setGeometry( 86, 20, 108, 44 ); 
        self.connect( self.PAIR_COMBO, SIGNAL('currentIndexChanged(int)'), self.CREATE_LISTS );
        #self.PAIR_COMBO.setStyleSheet( "QComboBox{ font: 16px 'monospace'; background-color: #333; color: #FFF; border-style: solid; border-width: 1px; border-color: #000; border-radius: none; }" );
        self.PAIR_COMBO.setEditable(False);

        """
        #self.PAIR_COMBO.setItemIcon( 0, QIcon("./data/imgs/500.png") );
        print(self.PAIR_COMBO.__len__());
        #set at tooltip
        combo.setItemData(0,"a tooltip",Qt.ToolTipRole)
        # set the Font Color
        combo.setItemData(0,QColor("#FF333D"), Qt.BackgroundColorRole)
        #set the font
        combo.setItemData(0, QtGui.QFont('Verdana', bold=True), Qt.FontRole)
        """

        # -------------------------------------------------------------------
        list_style                          = "QListWidget{ font: 10px 'monospace'; color: #fff;  background-color: #000; border-style: none; background-image: url('./data/imgs/TAB_BookKeeping_line.png'); }"; # ./data/imgs/BookKeeping_line.png
        lable_style                         = "QLabel{ font: 10px 'monospace'; color: #fff;  background-color: transparent; border-style: none; background-image: url(''); }"; 

        # -------------------------------------------------------------------
        self.DATA_TO_SEND                   = None;
        self._i_                            = "|"; # List delimiter
        self.CALCULATE_ONLY_COMPLETED       = True;
        self.DATA_TO_SEND_SELECTED          = False;
        
        # -------------------------------------------------------------------
        self.BOOKKEEPING_WIDGET             = QListWidget( self );
        self.BOOKKEEPING_WIDGET.setGeometry( 13, 144, 949, 259 );
        self.BOOKKEEPING_WIDGET.setStyleSheet( list_style );

        self.connect( self.BOOKKEEPING_WIDGET, SIGNAL('itemSelectionChanged()'), lambda: self.SEND_VALUES_TO_TRADE_TERMINAL("SOLD_WIDGET") );
        self.BOOKKEEPING_WIDGET.itemClicked.connect( lambda: self.SEND_VALUES_TO_TRADE_TERMINAL("SELECT_VALUES") );


        self.BOUGHT_TTL_LABLE               = QLabel("0.0", self);
        self.BOUGHT_TTL_LABLE.setGeometry( 304, 406, 85, 17 );
        #self.BOUGHT_TTL_LABLE.setEditable( False );
        self.BOUGHT_TTL_LABLE.setStyleSheet( lable_style );
        self.BOUGHT_TTL                     = 0;

        self.BOUGHT_TTL_PLUS_FEE_LABLE      = QLabel("0.0", self);
        self.BOUGHT_TTL_PLUS_FEE_LABLE.setGeometry( 396, 406, 85, 17 );
        #self.BOUGHT_TTL_PLUS_FEE_LABLE.setEditable( False );
        self.BOUGHT_TTL_PLUS_FEE_LABLE.setStyleSheet( lable_style );
        self.BOUGHT_TTL_PLUS_FEE            = 0;


        self.SOLD_TTL_LABLE                 = QLabel("0.0", self);
        self.SOLD_TTL_LABLE.setGeometry( 694, 406, 85, 17 );
        #self.SOLD_TTL_LABLE.setEditable( False );
        self.SOLD_TTL_LABLE.setStyleSheet( lable_style );
        self.SOLD_TTL                       = 0;

        self.SOLD_TTL_PLUS_FEE_LABLE        = QLabel("0.0", self);
        self.SOLD_TTL_PLUS_FEE_LABLE.setGeometry( 784, 406, 85, 17 );
        #self.SOLD_TTL_PLUS_FEE_LABLE.setEditable( False );
        self.SOLD_TTL_PLUS_FEE_LABLE.setStyleSheet( lable_style );
        self.SOLD_TTL_PLUS_FEE              = 0;

        self.PROFIT_TTL_LABLE               = QLabel("0.0", self);
        self.PROFIT_TTL_LABLE.setGeometry( 874, 406, 88, 17 );
        #self.PROFIT_TTL_LABLE.setEditable( False );
        self.PROFIT_TTL_LABLE.setStyleSheet( lable_style );
        self.PROFIT_TTL                     = 0;

        # -------------------------------------------------------------------
        self.SEND_ID_LABLE                  = QLabel("n/a", self);
        self.SEND_ID_LABLE.setGeometry( 18, 467, 43, 17 );
        self.SEND_ID_LABLE.setStyleSheet( lable_style );

        self.SEND_AMOUNT_LABLE              = QLabel("n/a", self);
        self.SEND_AMOUNT_LABLE.setGeometry( 66, 467, 85, 17 );
        self.SEND_AMOUNT_LABLE.setStyleSheet( lable_style );

        self.SEND_AT_PRICE_LABLE            = QLabel("n/a", self);
        self.SEND_AT_PRICE_LABLE.setGeometry( 156, 467, 43, 17 );
        self.SEND_AT_PRICE_LABLE.setStyleSheet( lable_style );

        self.SEND_VALUES_BTN                = QPushButton("", self); 
        self.SEND_VALUES_BTN.setGeometry( 60, 502, 131, 33 );
        self.SEND_VALUES_BTN.setStyleSheet( "QPushButton{ background-color: transparent; border-style: none; }" ); 
        self.connect( self.SEND_VALUES_BTN, SIGNAL('clicked()'), lambda: self.SEND_VALUES_TO_TRADE_TERMINAL("SEND_VALUES") );

        # -------------------------------------------------------------------
        self.ONLY_COMPLETED_CHECKBOX        = QCheckBox("", self);
        self.ONLY_COMPLETED_CHECKBOX.setGeometry( 665, 444, 17, 17 );
        self.ONLY_COMPLETED_CHECKBOX.setCheckState(Qt.Checked);
        #self.ONLY_COMPLETED_CHECKBOX.setEnabled(False);
        self.connect(self.ONLY_COMPLETED_CHECKBOX, SIGNAL('stateChanged(int)'), lambda: self.CHANGE_VALUES("only_completed") );

        # -------------------------------------------------------------------
        self.INIT();
        # -------------------------------------------------------------------

    # =======================================================================
    def INIT(self):

        # -------------------------------------------------------------------
        try:

            self.CREATE_PAIRS_SELECTOR();
            self.CREATE_LISTS();

        except Exception as _exception:

            print("-----------------------------------------------------");
            print("[INIT]"+str(_exception));
        # -------------------------------------------------------------------

    # =======================================================================
    def BKKPG_UID_ACTION(self, _ACTION, BKKPG_UID, _D):

        # -------------------------------------------------------------------
        #print("_ACTION: ", _ACTION, "BKKPG_UID: ", BKKPG_UID)
        # -------------------------------------------------------------------
        try:

            CURR_PAIR =  str(self.PAIR_COMBO.currentText()).lower().strip();

            order_id    = _D[0];
            unix_time   = _D[1];
            filled      = _D[2];
            amount      = _D[3];
            at_price    = _D[4];

            if _ACTION == "buy":

                # For CRYPTO
                ttl = amount;
                fee = ( ttl/100*self.PARENT.FEE );
            
            elif _ACTION == "sell":

                # For USD
                ttl = amount*at_price;
                fee = ( ttl/100*self.PARENT.FEE );

            grand_ttl = ttl-fee;

            # -------------------------------------------------------------------
            if BKKPG_UID == "": # Is New Record

                TPL = "buy_order_id, buy_unix_time, buy_filled, buy_amount, buy_at_price, buy_fee, buy_ttl, buy_grand_ttl, sell_order_id, sell_unix_time, sell_filled, sell_amount, sell_at_price, sell_fee, sell_ttl, sell_grand_ttl ";
                
                _SQL = "INSERT INTO "+CURR_PAIR+"( BKKPG_UID, completed, started, "+TPL+", profit_ttl ) ";

                if _ACTION == "buy":
                    _SQL += "VALUES( NULL,0,1,{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}, 0 )".format( _D[0],_D[1],_D[2],_D[3],_D[4],fee, ttl, grand_ttl, 0, 0, 0, 0, 0, 0, 0, 0 );

                else:
                    _SQL += "VALUES( NULL,0,1,{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}, 0 )".format( 0, 0, 0, 0, 0, 0, 0, 0, _D[0], _D[1],_D[2],_D[3],_D[4],fee, ttl, grand_ttl );


                self.PARENT.DB.EXEC("BOOK_DB", _SQL);

            else: # Existing Record

                # ------------------------------------------------
                if filled == 1:

                    completed = 1;

                    _SQL = "SELECT ACT_grand_ttl from "+CURR_PAIR+" WHERE BKKPG_UID="+BKKPG_UID;
                    
                    if _ACTION == "buy":

                        DATA = self.PARENT.DB.FETCH("BOOK_DB", _SQL.replace("ACT","sell"), ALL=False);
                        profit_ttl = DATA - grand_ttl;

                    else:

                        DATA = self.PARENT.DB.FETCH("BOOK_DB", _SQL.replace("ACT","buy"), ALL=False);
                        profit_ttl = grand_ttl - DATA;
                else:
                    profit_ttl = 0;
                    completed = 0;

                # ------------------------------------------------
                A = _ACTION;
                
                _SQL = "UPDATE "+CURR_PAIR+" SET completed={0}, "+A+"_order_id={1}, "+A+"_unix_time={2}, "+A+"_filled={3}, ";
                _SQL += A+"_amount={4}, "+A+"_at_price={5}, "+A+"_fee={6}, "+A+"_ttl={7}, "+A+"_grand_ttl={8}";
                _SQL += " WHERE BKKPG_UID="+BKKPG_UID;

                _SQL = _SQL.format( completed, order_id, unix_time, filled, amount, at_price, fee, ttl, grand_ttl );

                self.PARENT.DB.EXEC("BOOK_DB", _SQL);

        except Exception as _exception:

            print(" BOOKKEEPING[0:0]");
            print(_exception);
        # -------------------------------------------------------------------
        """
        BKKPG_UID, completed, started, 
        
        buy_order_id, buy_unix_time, buy_filled, buy_amount, buy_at_price, buy_fee, buy_ttl, buy_grand_ttl, 
        sell_order_id, sell_unix_time, sell_filled, sell_amount, sell_at_price, sell_fee, sell_ttl, sell_grand_ttl, 
        
        profit_ttl
        """
        # -------------------------------------------------------------------

    # =======================================================================
    def DELETE_ORDER(self, _order_id, _pair, _type):

        # -------------------------------------------------------------------

        _SQL = "SELECT buy_order_id, sell_order_id FROM "+_pair;
        _SQL += " WHERE buy_order_id="+str(_order_id)+" OR sell_order_id="+str(_order_id);

        DATA = self.PARENT.DB.FETCH("BOOK_DB", _SQL, ALL=False);

        if DATA is None:
            pass;

        if _type == "buy" and DATA[1] == 0:

            _SQL = "DELETE FROM "+_pair+" WHERE buy_order_id="+str(_order_id)+" OR sell_order_id="+str(_order_id);
            self.PARENT.DB.EXEC("BOOK_DB", _SQL);
            self.CREATE_LISTS();

        elif _type == "sell" and DATA[0] == 0:

            _SQL = "DELETE FROM "+_pair+" WHERE buy_order_id="+str(_order_id)+" OR sell_order_id="+str(_order_id);
            self.PARENT.DB.EXEC("BOOK_DB", _SQL);
            self.CREATE_LISTS();

        else:

            A = _type;

            _SQL = "UPDATE "+self.PARENT.CURR_PAIR+" SET ";
            _SQL += " completed=0, "+A+"_order_id=0, "+A+"_unix_time=0, "+A+"_filled=0, ";
            _SQL += A+"_amount=0, "+A+"_at_price=0, "+A+"_fee=0, "+A+"_ttl=0, "+A+"_grand_ttl=0 ";
            _SQL += "WHERE "+A+"_order_id="+str(_order_id);

            self.PARENT.DB.EXEC("BOOK_DB", _SQL);

        # -------------------------------------------------------------------

    # =======================================================================
    def CREATE_LISTS(self):

        # -------------------------------------------------------------------
        try:
            CURR_PAIR =  str(self.PAIR_COMBO.currentText()).lower();

            # -------------------------------------------------------------------
            self.BOOK = { "bought" : [], "sold" : [] };

            self.BOUGHT_TTL = 0;
            self.BOUGHT_TTL_PLUS_FEE = 0;

            self.SOLD_TTL = 0;
            self.SOLD_TTL_PLUS_FEE = 0;

            # -------------------------------------------------------------------
            #self.PARENT.DB.EXEC( "BOOK_DB", "DELETE FROM "+CURR_PAIR+" WHERE BKKPG_UID>7" );

            DATA = self.PARENT.DB.FETCH("BOOK_DB", "SELECT * FROM "+CURR_PAIR+" ORDER BY BKKPG_UID DESC", ALL=True);
            self.BOOKKEEPING_WIDGET.clear();

            for data in DATA:

                # ---------------------------------------------------------------
                """ " "" 
                print( data )
                for d in data:
                    print( d )
                exit();
                "" " """ 
                # ---------------------------------------------------------------
                # In-Memory DATA
                BKKPG_UID       = data[0]
                completed       = data[1]
                started         = data[2]

                buy_order_id    = data[3]
                buy_unix_time   = data[4]
                buy_filled      = data[5]
                buy_amount      = data[6]
                buy_at_price    = data[7]
                #buy_fee         = data[8]
                buy_ttl         = data[9]
                buy_grand_ttl   = data[10]

                sell_order_id   = data[11]
                sell_unix_time  = data[12]
                sell_filled     = data[13]
                sell_amount     = data[14]

                sell_at_price   = data[15]
                #sell_fee        = data[16]
                sell_ttl        = data[17]
                sell_grand_ttl  = data[18]

                profit_ttl      = data[19]

                # ---------------------------------------------------------------

                # ---------------------------------------------------------------
                """
                self.BOOK[ data[3] ].append( {
                                            
                                        BKKPG_UID,
                                        completed,
                                        started,

                                        buy_order_id,
                                        buy_unix_time,
                                        buy_filled,
                                        buy_amount,
                                        buy_at_price,
                                        buy_fee,
                                        buy_ttl,
                                        buy_grand_ttl,

                                        sell_order_id,
                                        sell_unix_time,
                                        sell_filled,
                                        sell_amount,
                                        sell_at_price,
                                        sell_fee,
                                        sell_ttl,
                                        sell_grand_ttl,

                                        profit_ttl

                                            } );

                """
                # ---------------------------------------------------------------
                if self.CALCULATE_ONLY_COMPLETED:

                    if buy_filled == 1 and sell_filled == 1:

                        self.BOUGHT_TTL += buy_ttl;
                        self.BOUGHT_TTL_PLUS_FEE += buy_grand_ttl*buy_at_price;

                        self.SOLD_TTL += sell_ttl;
                        self.SOLD_TTL_PLUS_FEE += sell_grand_ttl;

                else:

                    self.BOUGHT_TTL += buy_ttl;
                    self.BOUGHT_TTL_PLUS_FEE += buy_grand_ttl*buy_at_price;

                    self.SOLD_TTL += sell_ttl;
                    self.SOLD_TTL_PLUS_FEE += sell_grand_ttl;


                self.PROFIT_TTL_LABLE.setText( "{:10,.6f}".format(self.SOLD_TTL_PLUS_FEE - self.BOUGHT_TTL_PLUS_FEE) );


                # ---------------------------------------------------------------
                # Formating data to Display in BookKeeping Wodget

                item = "";

                item += "DEL{:7} ".format(str( BKKPG_UID )); # id

                # BUY / BOUGHT
                item += "#{:11} DEL".format( str(buy_order_id) ); # order_id
                item += "{:4} DEL".format( str(buy_filled) ); # filed
                item += "{:13} DEL".format( str("{:10,.6f}".format( float(buy_amount) )).strip() ); # Amount
                item += "{:13} DEL".format( str("{:10,.6f}".format( buy_at_price )).strip() ); # at_price
                #item += "{:13} DEL".format( str("{:10,.6f}".format( data[7] )).strip() ); # fee
                #item += "{:13} DEL".format( str("{:10,.6f}".format( buy_ttl )).strip() ); # ttl
                item += "{:14} ".format( str("{:10,.6f}".format( buy_grand_ttl )).strip() ); # grand_ttl

                # SELL / SOLD
                item += "#{:11} DEL".format( str(sell_order_id) ); # order_id
                item += "{:4} DEL".format( str(sell_filled) ); # filed
                item += "{:13} DEL".format( str("{:10,.6f}".format( sell_amount )).strip() ); # Amount
                item += "{:13} DEL".format( str("{:10,.6f}".format( sell_at_price )).strip() ); # at_price
                #item += "{:13} DEL".format( str("{:10,.6f}".format( data[7] )).strip() ); # fee
                #item += "{:13} DEL".format( str("{:10,.6f}".format( sell_ttl )).strip() ); # ttl
                item += "{:14} ".format( str("{:10,.6f}".format( sell_grand_ttl )).strip() ); # grand_ttl
                
                # PROFIT
                item += "{:13}".format( str("{:10,.6f}".format( profit_ttl )).strip() ); # grand_ttl

                newItem = QListWidgetItem( QIcon("./data/imgs/icon_filled_status_0.png"), item.replace("DEL", self._i_), self.BOOKKEEPING_WIDGET, 0);
                #newItemToolTip = "Order ID: #"+str()+" Created: "+time.ctime(int(data[2]));
                #newItem.setToolTip(newItemToolTip);

                # ---------------------------------------------------------------

            # / for
            # -------------------------------------------------------------------
            try: 
                self.BOUGHT_TTL_LABLE.setText( str("{:10,.6f}".format( self.BOUGHT_TTL ).strip()) );
                self.BOUGHT_TTL_PLUS_FEE_LABLE.setText( str("{:10,.6f}".format( self.BOUGHT_TTL_PLUS_FEE ).strip()) );

                self.SOLD_TTL_LABLE.setText( str("{:10,.6f}".format( self.SOLD_TTL ).strip()) );
                self.SOLD_TTL_PLUS_FEE_LABLE.setText( str("{:10,.6f}".format( self.SOLD_TTL_PLUS_FEE ).strip()) );

            except Exception as e:
                print("BOOKKEEPING[3:0]"+str(e))


        except Exception as _exception:

            print(" BOOKKEEPING[1:0]");
            print(_exception);
        # -------------------------------------------------------------------

    # =======================================================================
    def RESET_BKKPG_UID(self):

        # -------------------------------------------------------------------
        #CURR_PAIR =  str(self.PAIR_COMBO.currentText()).lower();
        self.PARENT.GUI.BKKPG_UID_VALUE.setText("");
        self.PARENT.GUI.CONTROL_TRADINGS_BTNS("buy", "show");
        self.PARENT.GUI.CONTROL_TRADINGS_BTNS("sell", "show");
        # -------------------------------------------------------------------

    # =======================================================================
    def CHANGE_VALUES(self, _this):

        # -------------------------------------------------------------------
        if _this == "only_completed":
            if self.ONLY_COMPLETED_CHECKBOX.isChecked():
                self.CALCULATE_ONLY_COMPLETED = True;
            else:
                self.CALCULATE_ONLY_COMPLETED = False;

        # -------------------------------------------------------------------
        self.CREATE_LISTS();
        # -------------------------------------------------------------------

    # =======================================================================
    def CREATE_PAIRS_SELECTOR(self, ALL=False):

        # -------------------------------------------------------------------
        if not ALL:
            for PAIR in self.CONF["API"]["PAIRS"]:
                self.PAIR_COMBO.addItem(PAIR.upper());

        else:
            for PAIR in self.CONF["API"]["ALL_PAIRS"]:
                self.PAIR_COMBO.addItem(PAIR.upper());

        for i in xrange(0, self.PAIR_COMBO.__len__()):

            self.PAIR_COMBO.setItemData( i, QColor("#333"),Qt.BackgroundRole );
            self.PAIR_COMBO.setItemData( i, QColor("#fff"),Qt.ForegroundRole );
            #self.PAIR_COMBO.setItemData( i, QFont('monospace', 16, -1, False), Qt.FontRole);
        # -------------------------------------------------------------------

    # =======================================================================
    def SEND_VALUES_TO_TRADE_TERMINAL(self, _action):

        # -------------------------------------------------------------------
        if _action == "SELECT_VALUES":

            self.DATA_TO_SEND_SELECTED = True;
            #self.DATA_TO_SEND = [ str(item).stip() for iten in str(self.BOOKKEEPING_WIDGET.currentItem().text()).strip().split("|")];
            self.DATA_TO_SEND = str(self.BOOKKEEPING_WIDGET.currentItem().text()).strip().split("|")[1].split("#")[0].strip();

        elif _action == "SEND_VALUES":

            if self.DATA_TO_SEND_SELECTED:

                _SQL = "SELECT buy_order_id, sell_order_id FROM "+self.PARENT.CURR_PAIR;
                _SQL += " WHERE BKKPG_UID="+self.DATA_TO_SEND;

                DATA = self.PARENT.DB.FETCH("BOOK_DB", _SQL, ALL=False);

                if DATA[0] != 0 and DATA[1] != 0:

                    self.PARENT.GUI.SHOW_QMESSAGE("info", "This UID is Full!<br> You can't add data to it enymore.<br>Bud You can delete sell and/or buy part<br/> and add new part.");
                    return;

                self.PARENT.GUI.BKKPG_UID_VALUE.setText( self.DATA_TO_SEND );

                self.PARENT.GUI.CONTROL_TRADINGS_BTNS("buy", "show");
                self.PARENT.GUI.CONTROL_TRADINGS_BTNS("sell", "show");

                self.DATA_TO_SEND_SELECTED = False;
                self.DATA_TO_SEND = None;

                # Clear Lables 
                self.SEND_ID_LABLE.setText( "n/a" );
                self.SEND_AMOUNT_LABLE.setText( "n/a" );
                self.SEND_AT_PRICE_LABLE.setText( "n/a" );


                if DATA[0] == 0:
                    self.PARENT.GUI.CONTROL_TRADINGS_BTNS("sell", "hide");

                else:
                    self.PARENT.GUI.CONTROL_TRADINGS_BTNS("buy", "hide");


                # Switch to Trader-Tab
                self.PARENT.GUI.MAIN_TABS.setCurrentIndex(0);

            else:

                self.PARENT.GUI.SHOW_QMESSAGE("info", " Select first item which one you would like<br/> send to the Trade-Terminal !");
                return; 
                
        # -------------------------------------------------------------------
        if self.DATA_TO_SEND is not None:
    
            self.SEND_ID_LABLE.setText( self.DATA_TO_SEND );
Exemplo n.º 38
0
class Chat(QFrame):

    # =======================================================================
    def __init__(self, parent=None, _PARENT=None):

        # -------------------------------------------------------------------
        QFrame.__init__(self, parent);
        # -------------------------------------------------------------------
        self.PARENT                         = _PARENT;
        self.CONF                           = _PARENT.CONF;

        self.setGeometry(3, 5, 975, 548);
        self.setStyleSheet( "QFrame{ font: 12px 'monospace'; color: #000; background-color: transparent; background-image: url('./data/imgs/TAB_Chat.png'); }" );

        # -------------------------------------------------------------------
        self.CHAT_URL                       = "https://btc-e.com/";
        self.CHAT_DATA                      = [];
        self.CHAT_LANG                      = self.CONF["USER"]["CHAT_LANG"];

        self.CHAT_HEADERS = {
            "User-Agent"        : "Mozilla/5.0 (Win-32; rv:24.0) Gecko/20140723 Firefox/24.0 Iceweasel/24.7.0",
            "Accept"            : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
            "Accept-Language"   : "en-US,en;q=0.5",
            "Referer"           : "https://btc-e.com/",
            "Connection"        : "keep-alive",
            "Cache-Control"     : "max-age=0",
            "Cookie"            : ""
        }

        self.CHAT_TIMER                     = QTimer();
        #self.CHAT_BG_COLOR                  = "#555";
        self.CHAT_BG_COLOR                  = "#0F0";
        self.CHAT_ALLOW_UPD                 = False;
        # -------------------------------------------------------------------
        self.CHAT_WIDGET                    = QTextEdit( self );
        self.CHAT_WIDGET.setGeometry( 13, 116, 690, 388 );
        self.CHAT_WIDGET.setStyleSheet( "QTextEdit{ background-color: transparent; color: #fff; background-image: url(''); }" );
        self.CHAT_WIDGET.setReadOnly( True );

        self.LANG_COMBO                     = QComboBox( self);
        self.LANG_COMBO.setGeometry( 86, 20, 108, 44 ); 
        self.connect( self.LANG_COMBO, SIGNAL('currentIndexChanged(int)'), self.CHANGE_CHAT_LANG );
        self.LANG_COMBO.setEditable(False);
        

        self.NEW_MSG                    = QLineEdit("", self);
        self.NEW_MSG.setGeometry( 20, 510, 500, 30 );
        self.NEW_MSG.setStyleSheet(" QLineEdit{ border-style: none; background-color: #333; color: #fff; background-image: url(''); }");
        self.NEW_MSG.setPlaceholderText(" Enter message:");



        self.SEND                       = QPushButton(" Send", self); 
        self.SEND.setGeometry( 593, 510, 90, 30 );
        #self.SEND.setStyleSheet( "QPushButton{ background-color: transparent; border-style: none; }" ); 
        #self.connect( self.SEND, SIGNAL('clicked()'), lambda: self.SEND_VALUES_TO_TRADE_TERMINAL("SEND_VALUES") );

        # -------------------------------------------------------------------
        self.ALLOW_UPDATE_CHECKBOX        = QCheckBox("", self);
        self.ALLOW_UPDATE_CHECKBOX.setGeometry( 335, 83, 17, 17 );
        self.ALLOW_UPDATE_CHECKBOX.setCheckState(Qt.Unchecked);
        self.connect(self.ALLOW_UPDATE_CHECKBOX, SIGNAL('stateChanged(int)'), self.CHANGE_VALUES );


        self.UPDATE_NOW_BTN               = QPushButton("Update Now!", self);
        self.UPDATE_NOW_BTN.setGeometry( 360, 74, 94, 24 );
        self.connect( self.UPDATE_NOW_BTN, SIGNAL('clicked()'), self.UPDATE_NOW );

        # -------------------------------------------------------------------
        self.INIT();
        # -------------------------------------------------------------------

    # =======================================================================
    def INIT(self):

        # -------------------------------------------------------------------
        try:
            self.INIT_CHAT_COMBO();
            self.UPDATE();

        except Exception as _exception:

            print("-----------------------------------------------------");
            print("[INIT]"+str(_exception));
        # -------------------------------------------------------------------

    # =======================================================================
    def UPDATE_NOW(self):

        # -------------------------------------------------------------------
        self.CHAT_ALLOW_UPD = True;

        self.UPDATE();

        self.CHAT_ALLOW_UPD = False;
        # -------------------------------------------------------------------

    # =======================================================================
    def UPDATE(self):

        # -------------------------------------------------------------------
        #print("UPDATE:")
        # -------------------------------------------------------------------
        try:

            if self.CHAT_ALLOW_UPD:

                self.GET_DATA();
                self.CHAT_WIDGET.clear();

                for msg in self.CHAT_DATA:

                    # ---------------------------------------------------------------
                    """
                    print(msg["time"]);
                    print(msg["nick"]);
                    print(msg["msg"]);
                    """

                    # ---------------------------------------------------------------
                    item = '<p style="background-color: #555;">';                
                    item += "[<span style='color: #000;'>"+msg["time"].split(" ")[1]+"</span>] : ";

                    if msg["nick"] == "admin":
                        item += "[<span style='color: #f00; font-weight: bold;'>"+msg["nick"]+"</span>]<br/><br/>";
                    else:
                        item += "[<span style='color: #000; font-weight: bold;'>"+msg["nick"]+"</span>]<br/><br/>";

                    item += msg["msg"]+"<br/>";
                    item += "</p>";

                    self.CHAT_WIDGET.append(item);


                    # ---------------------------------------------------------------

            self.CHAT_TIMER.singleShot( self.CONF["SYS"]["UPD_DELAY"], self.UPDATE );

        except Exception as e:
            
            print("CHAT[0:0]"+str(e))
            self.CHAT_TIMER.singleShot( self.CONF["SYS"]["UPD_DELAY"], self.UPDATE );

        # -------------------------------------------------------------------

    # =======================================================================
    def CHANGE_VALUES(self):

        # -------------------------------------------------------------------
        if self.ALLOW_UPDATE_CHECKBOX.isChecked():
            self.CHAT_ALLOW_UPD = True;

        else:
            self.CHAT_ALLOW_UPD = False;

        # -------------------------------------------------------------------

    # =======================================================================
    def GET_DATA(self):
        
        # -------------------------------------------------------------------
        try:

            self.CHAT_HEADERS["Cookie"] = "chatRefresh=1; locale="+self.CHAT_LANG+";"

            req = urllib2.Request(self.CHAT_URL, headers=self.CHAT_HEADERS);
            resp = urllib2.urlopen(req).read();

            CHAT = BeautifulSoup( resp ).body.find('div', attrs={'id':'nChat'});

            self.CHAT_DATA = [];

            for data in CHAT:

                self.CHAT_DATA.append( { "msg_id": data["id"], "nick":data.a.string, "time": data.a["title"], "msg": data.span.string } );


        except Exception as e:
            
            print("CHAT[0:1]"+str(e))
        # -------------------------------------------------------------------

    # =======================================================================
    def CHANGE_CHAT_LANG(self):

        # -------------------------------------------------------------------
        self.CHAT_LANG = str(self.LANG_COMBO.currentText()).lower().strip();
        #print(self.CHAT_LANG);
        # -------------------------------------------------------------------

    # =======================================================================
    def INIT_CHAT_COMBO(self):

        # -------------------------------------------------------------------
        for LANG in self.CONF["USER"]["CHAT_LANGS"]:
            self.LANG_COMBO.addItem(LANG.upper());

        for i in xrange(0, self.LANG_COMBO.__len__()):

            self.LANG_COMBO.setItemData( i, QColor("#333"),Qt.BackgroundRole );
            self.LANG_COMBO.setItemData( i, QColor("#fff"),Qt.ForegroundRole );
Exemplo n.º 39
0
class XTimeDeltaEdit(QFrame):
    def __init__(self, parent=None):
        super(XTimeDeltaEdit, self).__init__(parent)

        # define custom properties
        self.setStyleSheet(COMBO_STYLE)

        self._numberSpinner = QSpinBox(self)
        self._numberSpinner.setRange(0, 100000)
        self._numberSpinner.setFrame(False)
        self._numberSpinner.setButtonSymbols(QSpinBox.NoButtons)
        self._numberSpinner.setSizePolicy(QSizePolicy.Expanding,
                                          QSizePolicy.Expanding)

        self._unitCombo = QComboBox(self)
        self._unitCombo.setEditable(True)
        self._unitCombo.setInsertPolicy(QComboBox.NoInsert)
        self._unitCombo.setFrame(False)
        self._unitCombo.addItems([
            'year(s)', 'month(s)', 'week(s)', 'day(s)', 'hour(s)', 'minute(s)',
            'second(s)'
        ])

        self._unitCombo.setCurrentIndex(3)
        self._unitCombo.setSizePolicy(QSizePolicy.Expanding,
                                      QSizePolicy.Expanding)

        self._directionCombo = QComboBox(self)
        self._directionCombo.addItems(['ago', 'from now'])
        self._directionCombo.setEditable(True)
        self._directionCombo.setInsertPolicy(QComboBox.NoInsert)
        self._directionCombo.setFrame(False)
        self._directionCombo.setSizePolicy(QSizePolicy.Expanding,
                                           QSizePolicy.Expanding)

        # setup ui
        self.setFrameShape(QFrame.StyledPanel)
        self.setFrameShadow(QFrame.Sunken)
        self.setBackgroundRole(QPalette.Base)
        self.setAutoFillBackground(True)

        layout = QHBoxLayout()
        layout.setContentsMargins(2, 2, 2, 2)
        layout.setSpacing(0)
        layout.addWidget(self._numberSpinner)
        layout.addWidget(self._unitCombo)
        layout.addWidget(self._directionCombo)
        self.setLayout(layout)

    def delta(self):
        """
        Returns a delta based on this widget's information.
        
        :return     <datetime.timedelta>
        """
        number = self._numberSpinner.value()
        unit = self._unitCombo.currentText()
        direction = self._directionCombo.currentText()

        # use past tense
        if direction == 'ago':
            number = -number

        if unit == 'year(s)':
            return datetime.timedelta(number * 365)
        elif unit == 'month(s)':
            return datetime.timedelta(number * 30)
        elif unit == 'week(s)':
            return datetime.timedelta(number * 7)
        elif unit == 'day(s)':
            return datetime.timedelta(number)
        elif unit == 'hour(s)':
            return datetime.timedelta(0, number * 3600)
        elif unit == 'minute(s)':
            return datetime.timedelta(0, number * 60)
        else:
            return datetime.timedelta(0, number)

    def setDelta(self, delta):
        """
        Sets the time delta for this widget to the inputed delta.
        
        :param      delta | <datetime.timedelta>
        """
        days = int(delta.days)
        secs = int(delta.total_seconds())

        direction = 'from now'
        if secs < 0:
            direction = 'ago'

        if days and days % 365 == 0:
            number = days / 365
            unit = 'year(s)'
        elif days and days % 30 == 0:
            number = days / 30
            unit = 'month(s)'
        elif days and days % 7 == 0:
            number = days / 7
            unit = 'week(s)'
        elif days:
            number = days
            unit = 'day(s)'
        elif secs % 3600 == 0:
            number = secs / 3600
            unit = 'hour(s)'
        elif secs % 60 == 0:
            number = secs / 60
            unit = 'minute(s)'
        else:
            number = secs
            unit = 'second(s)'

        self._numberSpinner.setValue(abs(int(number)))
        self._unitCombo.setCurrentIndex(self._unitCombo.findText(unit))
        index = self._directionCombo.findText(direction)
        self._directionCombo.setCurrentIndex(index)
Exemplo n.º 40
0
class Window(QWidget):
    '''
    This is the GUI object.  Any gui-related operations happen here
    '''
    def __init__(self):

        self.internal_net = ''
        self.external_net = ''
        self.unconfigured = True

        self.searchfound = False
        self.foundunenc = False
        self.foundunprot = False
        self.foundprot = False

        if os.path.exists('tapioca.cfg'):
            with open('tapioca.cfg') as f:
                configlines = f.readlines()
            for line in configlines:
                if line.startswith('external_net'):
                    line = line.rstrip()
                    self.external_net = line.split('=')[1]
                if line.startswith('internal_net'):
                    line = line.rstrip()
                    self.internal_net = line.split('=')[1]

        if self.external_net != 'WAN_DEVICE' and self.internal_net != 'LAN_DEVICE':
            self.unconfigured = False

        QWidget.__init__(self)

        self.setWindowTitle('Tapioca')
        app_icon = QIcon()
        app_icon.addFile('cert.ico', QtCore.QSize(32, 32))
        self.setWindowIcon(app_icon)

        self.lblupstream = QLabel('<b>Upstream-network device:</b>')
        self.lblupstreamval = QLabel(self.external_net)
        self.lblupstreamval.setToolTip(
            'Ethernet device used for internet connectivity')
        self.lbllocal = QLabel('<b>Locally-provided-network device:</b>')
        self.lbllocalval = QLabel(self.internal_net)
        self.lbllocalval.setToolTip(
            'Ethernet device used for connectivity to device under test')
        self.spacer = QLabel()
        self.net_status = QLabel()
        self.appname = ''
        self.lblapp = QLabel('<b>Capture session:</b>')
        self.cboapp = QComboBox()
        self.cboapp.setEditable(True)
        self.cboapp.setToolTip(
            'Select an existing session from the dropdown or type a new one')
        #self.leapp = QLineEdit()
        self.btntcpdump = QPushButton('Capture - All traffic with tcpdump')
        self.btntcpdump.setToolTip(
            'Launch tcpdump to capture all traffic without interception')
        self.lbltcpdump = QLabel()
        self.chkrewrite = QCheckBox('Modify mitmproxy traffic')
        self.chkrewrite.setToolTip(
            'Edit mitmproxy rules for traffic modification.\nOnly affects "Verify SSL Validation" and "Full HTTPS inspection" tests'
        )
        self.btnrewrite = QPushButton('Edit modification rules')
        self.btnrewrite.setToolTip('Modify mitmproxy traffic rewriting rules')
        self.btnrewrite.setEnabled(False)
        self.btnssl = QPushButton('Capture - Verify SSL validation')
        self.btnssl.setToolTip(
            'Launch mitmproxy to capture HTTP(S) traffic with an invalid certificate'
        )
        self.lblssltest = QLabel()
        self.btnfull = QPushButton('Capture - Full HTTPS inspection')
        self.btnfull.setToolTip(
            'Launch mitmproxy to capture HTTP(S) traffic with an installed certificate'
        )
        self.lblfull = QLabel()
        self.btnstop = QPushButton('Stop current capture')
        self.allreports = QPushButton('Generate reports')
        self.allreports.setToolTip(
            'Generate reports for all tests performed for this capture')
        self.lblsslresults = QLabel('<b>SSL test results:</b>')
        self.lblsslresultsval = QLabel()
        self.lblcryptoresults = QLabel('<b>Crypto test results:</b>')
        self.lblcryptoresultsval = QLabel()
        self.lblnetresults = QLabel(
            '<b>Network connectivity test results:</b>')
        self.lblnetresultsval = QLabel()

        self.lblsearch = QLabel('<b>Search term:</b>')
        self.searchbox = QLineEdit()
        self.searchbox.setToolTip(
            'Case-insensitive perl-compatible regex pattern')
        self.chksearch = QCheckBox('Search multiple encodings')
        self.chksearch.setToolTip(
            'Search for base64, md5, and sha1 encodings as well - INCOMPATIBLE with Regex'
        )
        self.btnsearch = QPushButton('Search')
        self.btnsearch.setToolTip(
            'Search for term (perl-compatible regex) in all captures')
        self.lblsearchresults = QLabel()
        self.lblsearchfound = QLabel()
        self.lblsearchunprotfound = QLabel()
        self.lblsearchprotfound = QLabel()

        #layout = QVBoxLayout(self)
        layout = QFormLayout(self)
        layout.addRow(self.lblupstream, self.lblupstreamval)
        layout.addRow(self.lbllocal, self.lbllocalval)
        layout.addRow(self.net_status)
        #layout.addRow(self.lblapp, self.leapp)
        layout.addRow(self.lblapp, self.cboapp)
        layout.addRow(self.btntcpdump, self.lbltcpdump)
        layout.addRow(self.btnssl, self.lblssltest)
        layout.addRow(self.btnfull, self.lblfull)
        layout.addRow(self.chkrewrite, self.btnrewrite)
        layout.addRow(self.btnstop)
        layout.addRow(self.spacer)
        layout.addRow(self.spacer)
        layout.addRow(self.lblsearch, self.searchbox)
        layout.addRow(self.chksearch, self.btnsearch)
        layout.addRow(self.lblsearchresults, self.lblsearchfound)
        layout.addRow(self.spacer, self.lblsearchunprotfound)
        layout.addRow(self.spacer, self.lblsearchprotfound)
        layout.addRow(self.allreports)
        layout.addRow(self.lblsslresults, self.lblsslresultsval)
        layout.addRow(self.lblcryptoresults, self.lblcryptoresultsval)
        layout.addRow(self.lblnetresults, self.lblnetresultsval)

        self.setFixedSize(480, 420)
        self.center()

        if self.unconfigured:
            self.net_status.setText(
                '<font color="red"><b>Please enable soft AP or configure networks</b></font>'
            )
            self.disabletests()
            self.disablestop()

        if not self.checklan():
            self.net_status.setText(
                '<font color="red"><b>LAN device %s not found</b></font>' %
                self.internal_net)
            self.disabletests()
            self.disablestop()

    def checklan(self):
        landevice = subprocess.check_output([
            "nmcli device status | grep %s | awk '{print $1}'" %
            self.internal_net
        ],
                                            shell=True)
        if not landevice:
            return False
        else:
            return True

    @QtCore.pyqtSlot()
    def clearsearchresults(self):
        #print('Clearing search results...')
        self.lblsearchresults.setText('')
        self.lblsearchfound.setText('')
        self.lblsearchfound.setCursor(QCursor())
        self.lblsearchfound.setToolTip('')
        self.lblsearchunprotfound.setText('')
        self.lblsearchunprotfound.setCursor(QCursor())
        self.lblsearchunprotfound.setToolTip('')
        self.lblsearchprotfound.setText('')
        self.lblsearchprotfound.setCursor(QCursor())
        self.lblsearchprotfound.setToolTip('')

    @QtCore.pyqtSlot()
    def updatesearchresults(self):
        #print('Updating GUI search results...')
        #print('searchfound: %s' % self.searchfound)
        searchresults = ''
        if self.searchfound:
            self.lblsearchresults.setText('<b>Matches:</b>')
            if self.foundunenc:
                searchresults = 'Unencrypted traffic'
                self.lblsearchfound.setText(searchresults)
                self.lblsearchfound.setCursor(
                    QCursor(QtCore.Qt.PointingHandCursor))
                self.lblsearchfound.setToolTip('Open raw tcpdump capture')
            else:
                self.lblsearchfound.setText('')
                self.lblsearchfound.setCursor(QCursor())
                self.lblsearchfound.setToolTip('')

            if self.foundunprot:
                if searchresults != '':
                    searchresults = searchresults + ', '
                searchresults = 'Unprotected HTTPS traffic'
                self.lblsearchunprotfound.setText(searchresults)
                self.lblsearchunprotfound.setCursor(
                    QCursor(QtCore.Qt.PointingHandCursor))
                self.lblsearchunprotfound.setToolTip(
                    'Open SSL test mitmproxy capture')
            else:
                self.lblsearchunprotfound.setText('')
                self.lblsearchunprotfound.setCursor(QCursor())
                self.lblsearchunprotfound.setToolTip('')

            if self.foundprot:
                if searchresults != '':
                    searchresults = searchresults + ', '
                searchresults = 'Protected HTTPS traffic'
                self.lblsearchprotfound.setText(searchresults)
                self.lblsearchprotfound.setCursor(
                    QCursor(QtCore.Qt.PointingHandCursor))
                self.lblsearchprotfound.setToolTip(
                    'Open full HTTPS inspection mitmproxy capture')
            else:
                self.lblsearchprotfound.setText('')
                self.lblsearchprotfound.setCursor(QCursor())
                self.lblsearchprotfound.setToolTip('')

        else:
            self.lblsearchresults.setText('<b>No match</b>')
            self._clearsearchresult()

        # self.lblsearchfound.setText(searchresults)

    def _clearsearchresult(self):
        self.lblsearchprotfound.setText('')
        self.lblsearchprotfound.setCursor(QCursor())
        self.lblsearchprotfound.setToolTip('')
        self.lblsearchunprotfound.setText('')
        self.lblsearchunprotfound.setCursor(QCursor())
        self.lblsearchunprotfound.setToolTip('')
        self.lblsearchfound.setText('')
        self.lblsearchfound.setCursor(QCursor())
        self.lblsearchfound.setToolTip('')

    @QtCore.pyqtSlot(str)
    def check_addapp(self, appname):
        #print('Checking if %s is already there...') % appname
        appindex = self.cboapp.findText(appname)
        if appindex == -1:
            # Current app hasn't been added to combobox
            #print('Adding app %s' % appname)
            self.cboapp.addItem(appname)

    @QtCore.pyqtSlot()
    def disabletests(self):
        #print('Disabling test buttons')
        self.btntcpdump.setEnabled(False)
        self.btnssl.setEnabled(False)
        self.btnfull.setEnabled(False)

    @QtCore.pyqtSlot()
    def disablestop(self):
        #print('Disabling test buttons')
        self.btnstop.setEnabled(False)

    @QtCore.pyqtSlot()
    def enabletests(self):
        #print('Enabling test buttons again!')
        self.btntcpdump.setEnabled(True)
        self.btnssl.setEnabled(True)
        self.btnfull.setEnabled(True)

    @QtCore.pyqtSlot()
    def center(self):
        frameGm = self.frameGeometry()
        screen = QApplication.desktop().screenNumber(
            QApplication.desktop().cursor().pos())
        centerPoint = QApplication.desktop().screenGeometry(screen).center()
        frameGm.moveCenter(centerPoint)
        self.move(frameGm.topLeft())

    @QtCore.pyqtSlot(str)
    def getapp(self, appname):
        text, ok = QInputDialog.getText(self, 'Tapioca',
                                        'Enter capture session name:',
                                        QLineEdit.Normal, appname)
        appname = re.sub(r'\W+', '', str(text)).lower()

        if ok:
            appindex = self.cboapp.findText(appname)
            if appindex == -1:
                # New app
                # Create and select item in combobox
                self.cboapp.addItem(appname)
                self.cboapp.setCurrentIndex(self.cboapp.findText(appname))
            else:
                # existing app
                # Just select item in combobox
                self.cboapp.setCurrentIndex(self.cboapp.findText(appname))

        return appname

    def _reset_resultslinks(self):
        self.lblsslresultsval.setText('')
        self.lblsslresultsval.setToolTip('')
        self.lblsslresultsval.setCursor(QCursor())
        self.lblcryptoresultsval.setText('')
        self.lblcryptoresultsval.setToolTip('')
        self.lblcryptoresultsval.setCursor(QCursor())
        self.lblnetresultsval.setText('')
        self.lblnetresultsval.setToolTip('')
        self.lblnetresultsval.setCursor(QCursor())

    @QtCore.pyqtSlot(str)
    def updateStatus(self, test):
        '''
        GUI module updateStatus
        '''
        failures = {}
        #print('--- gui object updateStatus. test: %s' % test)
        test = str(test)
        if test.endswith('COMPLETE') or test.endswith('ERROR'):
            testname, status = str(test).split()
            #print('testname: %s' % testname)
            if testname == 'report':
                #print('*** %s Report done ***' % self.appname)
                failures = allreports.getfailures(self.appname)
                self._reset_resultslinks()
                #print('=== failures: %s ===' % failures)
                for test in failures:
                    #print('- Checking %s' % test)
                    if test == 'ssltest':
                        self.lblsslresultsval.setToolTip(
                            'Open SSL test report')
                        self.lblsslresultsval.setCursor(
                            QCursor(QtCore.Qt.PointingHandCursor))
                        if failures[test] is True:
                            #print('failed ssl!')
                            self.lblsslresultsval.setText(
                                '<font color="red">FAILED</font>')
                        elif failures[test] is False:
                            #print('passed ssl')
                            self.lblsslresultsval.setText(
                                '<font color="green">PASSED</font>')
                    elif test == 'crypto':
                        self.lblcryptoresultsval.setToolTip(
                            'Open SSL test report')
                        self.lblcryptoresultsval.setCursor(
                            QCursor(QtCore.Qt.PointingHandCursor))
                        if failures[test] is True:
                            self.lblcryptoresultsval.setText(
                                '<font color="red">FAILED</font>')
                        elif failures[test] is False:
                            self.lblcryptoresultsval.setText(
                                '<font color="green">PASSED</font>')
                    elif test == 'net':
                        self.lblnetresultsval.setToolTip(
                            'Open SSL test report')
                        self.lblnetresultsval.setCursor(
                            QCursor(QtCore.Qt.PointingHandCursor))
                        if test in failures:
                            self.lblnetresultsval.setText('VIEW')
                        else:
                            self.lblnetresultsval.setText('')

            elif testname == 'search':
                # Let main app object handle this to allow for value passing
                pass
                # self.lblsearchfound.setText(status)
                #print('*** Search complete! ***')
            elif testname == 'openssltest' or testname == 'openfulltest' \
                    or testname == 'opentcpdump' or testname == 'opensslreport' \
                    or testname == 'opencryptoreport' or testname == \
                    'opennetreport':
                # NO need to enable test buttons or so anything else
                pass
            else:
                # Test capture complete
                # Updating individual test status
                #print('gui.updatestatus() re-enabling test buttons')
                self.enabletests()
                #print('*** GUI updateStatus : %s' % test)

                if status == 'COMPLETE':
                    # A test has completed.  Add appname to combobox
                    #print('Finished a test... adding to combobox')
                    self.check_addapp(self.appname)

                if testname == 'tcpdump':
                    self.lbltcpdump.setText(status)
                    if status == 'COMPLETE':
                        self.lbltcpdump.setToolTip(
                            'Open tcpdump capture for %s' % self.appname)
                        self.lbltcpdump.setCursor(
                            QCursor(QtCore.Qt.PointingHandCursor))
                    else:
                        self.lbltcpdump.setToolTip('')
                        self.lbltcpdump.setCursor(QCursor())
                elif testname == 'ssltest':
                    self.lblssltest.setText(status)
                    if status == 'COMPLETE':
                        self.lblssltest.setToolTip(
                            'Open mitmproxy SSL test capture for %s' %
                            self.appname)
                        self.lblssltest.setCursor(
                            QCursor(QtCore.Qt.PointingHandCursor))
                    else:
                        self.lblssltest.setToolTip('')
                        self.lblssltest.setCursor(QCursor())
                elif testname == 'full':
                    self.lblfull.setText(status)
                    if status == 'COMPLETE':
                        self.lblfull.setToolTip(
                            'Open mitmproxy full inspection capture for %s' %
                            self.appname)
                        self.lblfull.setCursor(
                            QCursor(QtCore.Qt.PointingHandCursor))
                    else:
                        self.lblfull.setToolTip('')
                        self.lblfull.setCursor(QCursor())
class LayerSelectionPage(QFrame):
    #TODO. Filtering, (visible) row selection, multi selection
    colparams = ((0, 65, 'Name'), (1, 235, 'Title'), (2, 350, 'Keywords'))
    XFER_BW = 40

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

        #convenience link
        self.confconn_link = self.parent.parent.confconn

        #flag top prevent read read action on keyword delete. New logic makes this redundant
        #self.keywordbypass = False

        QToolTip.setFont(QFont('SansSerif', 10))

        #label
        filterlabel = QLabel('Filter')
        availablelabel = QLabel('Available Layers')
        selectionlabel = QLabel('Layer Selections')
        keywordlabel = QLabel('Keyword')
        explainlabel = QLabel(
            "Edit Group assignments using this dialog or to simply initialise the Layer-Config just click 'Finish'"
        )

        #selection buttons
        chooseallbutton = QPushButton('>>')
        chooseallbutton.setFixedWidth(self.XFER_BW)
        chooseallbutton.clicked.connect(self.doChooseAllClickAction)

        choosebutton = QPushButton('>')
        choosebutton.setFixedWidth(self.XFER_BW)
        choosebutton.clicked.connect(self.doChooseClickAction)

        rejectbutton = QPushButton('<')
        rejectbutton.setFixedWidth(self.XFER_BW)
        rejectbutton.clicked.connect(self.doRejectClickAction)

        rejectallbutton = QPushButton('<<')
        rejectallbutton.setFixedWidth(self.XFER_BW)
        rejectallbutton.clicked.connect(self.doRejectAllClickAction)

        #operation buttons
        finishbutton = QPushButton('Finish')
        finishbutton.setToolTip('Finish and Close layer selection dialog')
        finishbutton.clicked.connect(self.parent.close)

        resetbutton = QPushButton('Reset')
        resetbutton.font()
        resetbutton.setToolTip(
            'Read Layer from LDS GetCapabilities request. Overwrites current Layer Config'
        )
        resetbutton.clicked.connect(self.doResetClickAction)

        self.available_sfpm = LDSSFPAvailableModel(self)
        self.selection_sfpm = LDSSFPSelectionModel(self)

        self.available_sfpm.setSourceModel(self.parent.available_model)
        self.selection_sfpm.setSourceModel(self.parent.selection_model)

        #textedits
        filteredit = QLineEdit('')
        filteredit.setToolTip(
            'Filter Available-Layers pane (filter operates across Name and Title fields and accepts Regex expressions)'
        )
        filteredit.textChanged.connect(self.available_sfpm.setActiveFilter)

        self.keywordcombo = QComboBox()
        self.keywordcombo.setToolTip(
            'Select or Add a unique identifier to be saved in layer config (keyword)'
        )
        self.keywordcombo.addItems(list(self.confconn_link.assigned))
        self.keywordcombo.setEditable(True)
        self.keywordcombo.activated.connect(self.doKeyComboChangeAction)

        lgindex = self.confconn_link.getLayerGroupIndex(
            self.confconn_link.lgval, col=1)
        lgentry = self.confconn_link.lglist[lgindex] if LU.assessNone(
            lgindex) else None
        #keywordedit = self.keywordcombo.lineEdit().text().toUtf8().data().decode('utf8')# for writing
        #if no entry or layer indicated then blank
        self.keywordcombo.lineEdit().setText(
            '' if lgentry is None or lgentry[0] == LORG.LAYER else
            lgentry[1])  #self.confconn_link.lgval)#TODO. group only

        #header
        headmodel = QStandardItemModel()
        headmodel.setHorizontalHeaderLabels([
            i[2] for i in self.colparams
        ][:self.parent.available_model.columnCount()])

        headview1 = QHeaderView(Qt.Horizontal)
        headview1.setModel(headmodel)
        headview1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        headview2 = QHeaderView(Qt.Horizontal)
        headview2.setModel(headmodel)
        headview2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)

        #table
        self.available = QTableView()
        self.available.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.available.setSelectionMode(QAbstractItemView.MultiSelection)

        self.selection = QTableView()
        self.selection.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.selection.setSelectionMode(QAbstractItemView.MultiSelection)

        #interesting, must set model after selection attributes but before headers else row selections/headers don't work properly
        self.available.setModel(self.available_sfpm)
        self.selection.setModel(self.selection_sfpm)

        self.available.setSortingEnabled(True)
        self.available.setHorizontalHeader(headview1)

        self.selection.setSortingEnabled(True)
        self.selection.setHorizontalHeader(headview2)

        for cp in self.colparams:
            self.available.setColumnWidth(cp[0], cp[1])
            self.selection.setColumnWidth(cp[0], cp[1])

        self.available.verticalHeader().setVisible(False)
        self.available.horizontalHeader().setVisible(True)

        self.selection.verticalHeader().setVisible(False)
        self.selection.horizontalHeader().setVisible(True)

        #layout
        vbox00 = QVBoxLayout()
        vbox00.addWidget(availablelabel)
        vbox00.addWidget(self.available)

        vbox01 = QVBoxLayout()
        vbox01.addWidget(chooseallbutton)
        vbox01.addWidget(choosebutton)
        vbox01.addWidget(rejectbutton)
        vbox01.addWidget(rejectallbutton)

        vbox02 = QVBoxLayout()
        vbox02.addWidget(selectionlabel)
        vbox02.addWidget(self.selection)

        vbox10 = QVBoxLayout()
        vbox10.addWidget(filterlabel)
        vbox10.addWidget(filteredit)

        hbox12 = QHBoxLayout()
        hbox12.addWidget(keywordlabel)
        hbox12.addStretch(1)
        #hbox12.addWidget(inspbutton)
        #hbox12.addWidget(addbutton)
        #hbox12.addWidget(delbutton)

        vbox12 = QVBoxLayout()
        vbox12.addLayout(hbox12)
        vbox12.addWidget(self.keywordcombo)

        #00|01|02
        #10|11|12
        grid0 = QGridLayout()
        grid0.addLayout(vbox00, 1, 0)
        grid0.addLayout(vbox01, 1, 1)
        grid0.addLayout(vbox02, 1, 2)
        grid0.addLayout(vbox10, 0, 0)
        grid0.addLayout(vbox12, 0, 2)

        hbox2 = QHBoxLayout()
        hbox2.addWidget(resetbutton)
        hbox2.addStretch(1)
        hbox2.addWidget(explainlabel)
        hbox2.addWidget(finishbutton)
        #gbox1.setLayout(hbox2)

        vbox3 = QVBoxLayout()
        vbox3.addLayout(grid0)
        #vbox3.addLayout(hbox3)
        #vbox3.addWidget(line0)
        vbox3.addLayout(hbox2)

        self.setLayout(vbox3)

    def doChooseAllClickAction(self):
        '''Moves the lot to Selected'''
        #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data())
        ktext = LU.recode(
            LQ.readWidgetText(self.keywordcombo.lineEdit().text()))
        if not self.checkKeyword(ktext): return
        #------------------------------
        self.parent.signalModels(self.parent.STEP.PRE)
        #self.parent.selection_model.mdata += self.parent.available_model.mdata
        self.parent.selection_model.initData(self.confconn_link.complete)
        self.parent.available_model.initData([])
        self.parent.signalModels(self.parent.STEP.POST)
        #------------------------------
        self.parent.writeKeysToLayerConfig(ktext)
        #self.confconn_link.setupAssignedLayerList()
        if self.keywordcombo.findText(ktext) == -1:
            self.keywordcombo.addItem(ktext)

    def doChooseClickAction(self):
        '''Takes available selected and moves to selection'''
        #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data())
        ktext = LU.recode(
            LQ.readWidgetText(self.keywordcombo.lineEdit().text()))
        #ktext = str(self.keywordcombo.lineEdit().text())
        if not self.checkKeyword(ktext): return
        #------------------------------
        select = self.available.selectionModel()
        if select.hasSelection():
            self.transferSelectedRows(select.selectedRows(),
                                      self.available_sfpm, self.selection_sfpm)
            #------------------------------
            self.parent.writeKeysToLayerConfig(ktext)
            #self.confconn_link.assigned = self.confconn_link.setupAssignedLayerList()
            # -1 to indicate no index since 0,1,... are valid
            if self.keywordcombo.findText(ktext) == -1:
                self.keywordcombo.addItem(ktext)
        else:
            ldslog.warn('L2R > Transfer action without selection')
        #TRACE#
        #pdb.set_trace()
        self.available.clearSelection()

    def transferSelectedRows(self, indices, from_model, to_model):
        tlist = []
        for proxymodelindex in indices:
            transfer = from_model.getData(proxymodelindex)
            tlist.append((proxymodelindex, transfer), )

        to_model.addData([t[1] for t in tlist])
        from_model.delData([t[0] for t in tlist])
        return tlist

    def doRejectClickAction(self):
        '''Takes available selected and moves to selection'''
        #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data())
        ktext = LU.recode(
            LQ.readWidgetText(self.keywordcombo.lineEdit().text()))
        if not self.checkKeyword(ktext): return
        #------------------------------
        select = self.selection.selectionModel()
        if select.hasSelection():
            tlist = self.transferSelectedRows(select.selectedRows(),
                                              self.selection_sfpm,
                                              self.available_sfpm)
            #------------------------------
            kindex = self.keywordcombo.findText(ktext)
            remainder = self.parent.deleteKeysFromLayerConfig(
                [ll[1][0] for ll in tlist], ktext)
            if remainder > 0 and kindex == -1:
                #items+newkey -> add
                self.parent.writeKeysToLayerConfig(ktext)
                self.keywordcombo.addItem(ktext)
            elif remainder == 0 and kindex > -1:
                #empty+oldkey -> del
                self.keywordcombo.removeItem(kindex)
                self.keywordcombo.clearEditText()
        else:
            ldslog.warn('R2L < Transfer action without selection')
        #TRACE#
        #pdb.set_trace()
        self.selection.clearSelection()

    def doRejectAllClickAction(self):
        #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data())
        ktext = LU.recode(
            LQ.readWidgetText(self.keywordcombo.lineEdit().text()))
        if not self.checkKeyword(ktext): return
        #------------------------------
        self.parent.deleteKeysFromLayerConfig(
            [ll[0] for ll in self.parent.selection_model.mdata], ktext)
        #------------------------------
        self.parent.signalModels(self.parent.STEP.PRE)
        #self.parent.available_model.mdata += self.parent.selection_model.mdata
        self.parent.available_model.initData(self.confconn_link.complete)
        self.parent.selection_model.initData([])
        self.parent.signalModels(self.parent.STEP.POST)
        #------------------------------
        #self.confconn_link.setupAssignedLayerList()
        #self.keywordbypass = True
        self.keywordcombo.removeItem(self.keywordcombo.findText(ktext))
        self.keywordcombo.clearEditText()

    def doKeyComboChangeAction(self):
        '''Reset the available pane and if there is anything in the keyword box use this to init the selection pane'''
        #HACK
        #if self.keywordbypass:
        #    self.keywordbypass = False
        #    return
        #------------------------------
        #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data())
        ktext = LU.recode(
            LQ.readWidgetText(self.keywordcombo.lineEdit().text()))
        #------------------------------
        av_sl = self.parent.splitData(ktext, self.confconn_link.complete)
        #av_sl = self.parent.splitData(ktext,self.confconn_link.complete)
        self.parent.signalModels(self.parent.STEP.PRE)
        self.parent.available_model.initData(av_sl[0])
        self.parent.selection_model.initData(av_sl[1])
        self.parent.signalModels(self.parent.STEP.POST)

    def doResetClickAction(self):
        '''Dumps the LC and rebuilds from a fresh read of the caps doc'''
        #int warning (QWidget parent, QString title, QString text, QString button0Text, QString button1Text = QString(), QString button2Text = QString(), int defaultButtonNumber = 0, int escapeButtonNumber = -1)
        ans = QMessageBox.warning(
            self, "Reset",
            "This action will overwrite your Layer Configuration using the current LDS settings (potentially adding new or removing layers). Continue?",
            "Continue", "Cancel")
        if ans:
            #Cancel
            ldslog.warn('Cancelling Reset operation')
            return
        #Continue
        ldslog.warn('Reset Layer Config')
        self.parent.resetLayers()
        self.keywordcombo.clear()

    def checkKeyword(self, ktext):
        '''Checks keyword isn't null and isn't part of the LDS supplied keywords'''
        if LU.assessNone(ktext) is None:
            QMessageBox.about(self, "Keyword Required",
                              "Please enter a Keyword to assign Layer(s) to")
            return False
        if ktext in self.confconn_link.reserved:
            QMessageBox.about(
                self, "Reserved Keyword",
                "'{}' is a reserved keyword, please select again".format(
                    ktext))
            return False
        return True
Exemplo n.º 42
0
class QuestionDlg(QDialog):
    def __init__(self, parent=None):
        super(QuestionDlg,self).__init__(parent)
        # self.setStyleSheet("background-image:url('image/panelbg.jpg'); border: 2px; border-radius 2px;")
        # self.createDb()
        # return

        self.db = QSqlDatabase.addDatabase("QSQLITE");  
        self.db.setDatabaseName("studentNew.db")
        if not self.db.open():
            QMessageBox.warning(None, "错误",  "数据库连接失败: %s" % self.db.lastError().text())
            sys.exit(1)

        self.g_curClassName = ""
        self.deleteTmpdata()

        self.setWindowFlags(Qt.CustomizeWindowHint)
        # self.setStyleSheet("border: 2px; border-radius 2px;")
        # self.setWindowFlags(Qt.FramelessWindowHint)
        self.setStyleSheet("background-color: rgba(132, 171, 208, 200);")

        self.tabWidget=QTabWidget(self)
        self.tabWidget.currentChanged.connect(self.changeTab)
        # tabWidget.setTabShape(QTabWidget.Triangular)
        self.tabWidget.setStyleSheet("QTabWidget::pane{border-width:1px;border-color:rgb(48, 104, 151);\
            border-style: outset;background-color: rgb(132, 171, 208);\
            background: transparent;} \
            QTabWidget::tab-bar{border-width:0px;}\
            QTabBar::tab { height: 60px; width: 260px; color:rgb(0, 0, 255); font-size:20px; font-weight:bold;} \
            QTabBar::tab:hover{background:rgb(255,255, 255, 100);} \
            QTabBar::tab:selected{border-color:green;background-color:white;color:green;}")
        # tabWidget.setStyleSheet("QTabBar::tab:hover{background:rgb(255,255, 255, 100);}")
        self.btngroup = QButtonGroup()
        self.popMenu = QMenu(self)
        entry1 = self.popMenu.addAction("正确")
        self.connect(entry1,SIGNAL('triggered()'), lambda : self.answerRight())
        entry2 = self.popMenu.addAction("错误")
        self.connect(entry2,SIGNAL('triggered()'), lambda : self.answerWrong())
        entry3 = self.popMenu.addAction("替换")
        self.connect(entry3,SIGNAL('triggered()'), lambda : self.resetStudent())

        # Create the first tab page.
        self.w1=QWidget()
        self.w1.setAccessibleName("w1tab")
        self.genOneTab()
        
        # Create the second tab page.
        self.w2=QWidget()
        self.w2.setAccessibleName("w2tab")        
        self.genTwoTab()

        self.tabWidget.addTab(self.w1,"")
        self.tabWidget.addTab(self.w2,"班级学生信息管理")
        self.tabWidget.resize(940,700)

        btnclose = QPushButton(self)
        btnclose.setToolTip("关闭")
        btnclose.setText("╳")
        btnclose.setGeometry(915, 5, 20, 20)
        btnclose.setStyleSheet("background-color:rgb(0,100,0); color:rgb(255,255,255)")
        btnclose.clicked.connect(self.close)
        btnMinimized = QPushButton(self)
        btnMinimized.setToolTip("最小化")
        btnMinimized.setText("▁")
        btnMinimized.setGeometry(890, 5, 20, 20)
        btnMinimized.setStyleSheet("background-color:rgb(0,100,0); color:rgb(255,255,255)")
        btnMinimized.clicked.connect(lambda: self.showMinimized())
        self.btnSysMenu = QPushButton(self)
        # self.btnSysMenu.setText("▼")
        self.btnSysMenu.setGeometry(865, 5, 20, 20)
        self.btnSysMenu.setToolTip("系统设置")
        self.btnSysMenu.clicked.connect(lambda: self.showMinimized())
        menufont = QFont("宋体", 10)
        popMenu = QMenu(self)
        entry1 = popMenu.addAction("所有学生提问信息清零")
        entry1.setFont(menufont)
        self.connect(entry1,SIGNAL('triggered()'), self.initStudent)
        entry2 = popMenu.addAction("清除本堂课提问人员")
        entry2.setFont(menufont)
        self.connect(entry2,SIGNAL('triggered()'), self.deleteTmpdata)
        entry3 = popMenu.addAction("关于...")
        entry3.setFont(menufont)
        self.connect(entry3,SIGNAL('triggered()'), self.aboutMe)
        entry4 = popMenu.addAction("导出...")
        entry4.setFont(menufont)
        self.connect(entry4,SIGNAL('triggered()'), self.exportNotice)

        self.btnSysMenu.setMenu(popMenu)
        self.btnSysMenu.setStyleSheet("QPushButton::menu-indicator {image: url('image/sysmenu.png');subcontrol-position: right center;} ")
        # self.btnSysMenu.setStyleSheet("background-color:rgb(0,100,0); color:rgb(255,255,255);")

        authorinfo = QLabel(self.tabWidget)
        # authorinfo.setToolTip("关闭")
        authorinfo.setText("程序设计:汕头市大华路第一小学 赵小娜,有任何问题请反馈至[email protected]。")
        authorinfo.setGeometry(20, 665, 470, 26)
        authorinfo.setFont(QFont('Courier New'))
        authorinfo.setStyleSheet("background-color:rgba(255, 255, 255,160); font-size:12px;border: 1px solid rgb(60,200,255,200);color:rgba(0,0,0,220);border-radius:12px;")

        self.setWindowTitle("课堂随机提问")
        self.setWindowIcon(QIcon("image/start.ico"))
        self.setGeometry(100, 20, 940, 700)

        # self.changeTab()

        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)

        self.btn_start.setMyarg('start')
        
        # print(self.btn_start.getMyarg())

        self.connect(self.btn_start, SIGNAL("clicked()"), self.startChoice)
        # self.connect(self.w1title, SIGNAL("currentIndexChanged(int)"), self.changeTitle)
        # self.connect(self.btn_start2, SIGNAL("clicked()"), self.startChoice)
        # self.connect(self.w2title, SIGNAL("currentIndexChanged(int)"), self.changeTitle)
        self.btngroup.buttonClicked[int].connect(self.btns_click)
        # self.connect(self.btn_start,  SIGNAL("myslot(PyQt_PyObject)"), self.myslot)  
        # self.connect(self.btngroup, SIGNAL("buttonClicked(int)"), lambda:self.btns_click())

    def myslot(self, text):  
        # print(text, self.dict_choices)
        self.g_curbtn = text
        if self.g_curbtn not in self.dict_choices:
            self.btnSysMenu.setFocus()
            return

        # print(self.btngroup.button(int(self.g_curbtn)).parent())
        # print(type(self.btngroup.button(int(self.g_curbtn)).parentWidget()))
        pos = self.btngroup.button(int(self.g_curbtn)).parent().mapToGlobal(self.btngroup.button(int(self.g_curbtn)).pos())
        width = self.btngroup.button(int(self.g_curbtn)).rect().height()
        # print("-----", pos, width)
        pos.setY(pos.y()+width-5)

        indx = 0
        for istate in self.dict_choices[self.g_curbtn]:
            if istate == '1':
                self.popMenu.actions()[indx].setEnabled(True)
            elif istate == '0':
                self.popMenu.actions()[indx].setEnabled(False)
            indx += 1
        self.popMenu.exec_(pos)
        self.btnSysMenu.setFocus()
    # def on_context_menu(self, point):
    #     print(point)
    #     self.popMenu.exec_(self.button.mapToGlobal(point)) 

    def btns_click(self, btnid):
        # curclassname = self.tabWidget.tabText(0)
        query = QSqlQuery(self.db)
        # cur = conn.cursor()
        today = datetime.date.today()
        self.g_curbtn = str(btnid).zfill(2)
        if self.g_curbtn not in self.dict_choices:
            self.btngroup.button(int(self.g_curbtn)).setStyleSheet(stylesheetstr_new)
            query.exec_("select count(*) from tmprecord where stusn='" + str(self.g_curbtn) + "'")
            query.next()            
            if query.value(0) == 0:
                query.prepare("insert into tmprecord (classname, stusn, datequestion) values (:classname, :stusn, :datequestion)")
                query.bindValue(":classname", self.g_curClassName)
                query.bindValue(":stusn", self.g_curbtn)
                query.bindValue(":datequestion", today)
                query.exec_() 
                
            self.dict_choices[self.g_curbtn] = "111"
        else:
            self.btngroup.button(int(self.g_curbtn)).setStyleSheet(stylesheetstr_old)
            self.btngroup.button(int(self.g_curbtn)).setIcon(QIcon())            
            query.exec_("delete from tmprecord where stusn='"+ str(self.g_curbtn) + "'")            
            self.dict_choices.pop(self.g_curbtn)

        self.btnSysMenu.setFocus()

    def exportNotice(self):
        query = QSqlQuery(self.db)
        query.exec_("select stusn, stuname, classname, rightquestions, wrongquestions from student" ) 
        lstInfo = [["学号","姓名", "班级", "回答正确次数", "回答错误次数"]]
        while(query.next()):
            lstInfo.append([query.value(0),query.value(1),query.value(2),query.value(3),query.value(4)])

        from xlwt import Workbook,easyxf
        book = Workbook(encoding='ascii')
            # 'pattern: pattern solid,  fore_colour white;'
        style = easyxf(
            'font: height 280, name 黑体;'
            'align: vertical center, horizontal center;'
            )
        style2 = easyxf('font: height 260, name 仿宋_GB2312, bold True; align: vertical center, horizontal left;')
        style3 = easyxf('font: height 260, name 仿宋_GB2312, bold True; align: vertical center, horizontal left, wrap True;')

        sheet1 = book.add_sheet('学生提问情况汇总',cell_overwrite_ok=True)
        # sheet1.write(0,7,flagtxt, easyxf('font: height 200, name 黑体;align: vertical center, horizontal right;'))
        sheet1.write_merge(0,0,0,4, '学生提问情况汇总表',style)
        sheet1.row(0).height_mismatch = 1
        sheet1.row(0).height = 5*256

        sheet1.col(0).width = 10*256
        sheet1.col(1).width = 25*256
        sheet1.col(2).width = 25*256
        sheet1.col(3).width = 20*256
        sheet1.col(4).width = 20*256
        
        tmprows = 1
        for item in lstInfo:
            stusn               = item[0]
            stuname             = item[1]
            classname           = item[2]
            rightquestions      = item[3]
            wrongquestions      = item[4]

            sheet1.write(tmprows,0,stusn, style2)
            sheet1.write(tmprows,1,stuname, style2)
            sheet1.write(tmprows,2,classname, style2)
            sheet1.write(tmprows,3,rightquestions, style2)
            sheet1.write(tmprows,4,wrongquestions, style2)
            tmprows += 1
        # print(tmprows)
        sheet1.header_str = "".encode()
        sheet1.footer_str = "".encode()

        # book.save('d:/simple.xls')
        # print(QDir.home().dirName() , QDir.homePath ())
        filename = QDir.homePath () + "\学生提问情况汇总表.xls" 
        try:
            book.save(filename)
        except  Exception as e:
            QMessageBox.warning(self, "写入错误", "错误号:"+str(e.errno)+"\n错误描述:"+e.strerror+"\n请关闭已经打开的%s文档!" % filename)
        QMessageBox.about (self, "导出成功", "请查看文档:%s" % filename)

    def aboutMe(self):
        strinfo = """本软件采用python3.4编写,界面采用qt4.8的python绑定。
                    \n版本所有:汕头市大华路第一小学赵小娜老师。
                    \n有任何问题请反馈至[email protected]。
                    """
        QMessageBox.information(None, "关于", strinfo)
        
    def initStudent(self):
        query = QSqlQuery(self.db)
        ret = query.exec_("update student set wrongquestions=0") 
        ret = query.exec_("update student set rightquestions=0")  
        QMessageBox.information(None, "提示", "已清除所有学生的累计提问情况。")


    def deleteTmpdata(self):
        query = QSqlQuery(self.db)
        ret = query.exec_("delete from tmprecord where 1=1" )   
        if self.g_curClassName != "":     
            QMessageBox.information(None, "提示", "已清除本次软件启动后的所有已提问过的学生。")
  
    def changeTab(self):
        # pass
        curtab = self.tabWidget.currentIndex()
        # print(curtab, "-")
        if curtab == 1:  ## when click the second tab page ,then pass.
            return
            
        # cur = conn.cursor()
        query = QSqlQuery(self.db)

        ## if current classname is null, then set current tabpage display the first class of classtable
        if self.g_curClassName == "":
            ret = query.exec_("select classname from classtable")
            query.next()
            self.g_curClassName = query.value(0)
            
        self.tabWidget.setTabText(0, self.g_curClassName)
        # print(1)
        strwhere = " and classname like '" + self.g_curClassName + "' ORDER BY stusn"

        self.g_curbtn = ""
        self.dict_choices = {}
        self.studentSnlst = []

        ## clearn the question data of temp record .
        ret= query.exec_("delete from tmprecord where 1=1")
        ret = query.exec_("select stusn, stuname from student where 1=1 " + strwhere)

        ## now update the global data "self.btngroup"
        for indx in range(0, 56):
            self.btngroup.button(indx+1).setText("")
            self.btngroup.button(indx+1).setMyarg(None)       
            self.btngroup.button(indx+1).setStyleSheet(stylesheetstr_old)
            self.btngroup.button(indx+1).setIcon(QIcon())
            self.btngroup.button(indx+1).setEnabled(False)
            self.studentSnlst.append([indx+1,])

        inum = 0
        while (query.next()): 
            inum += 1            
            self.btngroup.button(inum).setText(query.value(1))
            self.btngroup.button(inum).setMyarg(query.value(0))       
            self.btngroup.button(inum).setStyleSheet(stylesheetstr_old)
            self.btngroup.button(inum).setIcon(QIcon())
            self.btngroup.button(inum).setEnabled(True)

        # print(inum, len(self.btngroup.buttons()))        

        self.group_animation = groupAnimation(self.studentSnlst, self.btngroup)

    def mousePressEvent(self, event):
        # print('a')
        if event.button() == Qt.RightButton:
            QDialog.mousePressEvent(self,event)
            return
        # print(event.sender(), event.button())
        self.offset = event.pos()
        # print(self.offset)

    def mouseMoveEvent(self, event):
        # print('sss')
        if hasattr(self, 'offset'):
            x=event.globalX()
            y=event.globalY()
            x_w = self.offset.x()
            y_w = self.offset.y()
            self.move(x-x_w, y-y_w)
        else:
            pass

    #######======= studentModel ============###############
    def newStudent(self):
        # Calc the missing number:
        row = self.StudentModel.rowCount()

        if row > 0:
            oldNumList = []
            for i in range(0, row):
                oldNumList.append(int(self.StudentModel.index(i,2).data()))
            
            allNumberList = list(range(1, oldNumList[-1]+1))
            for i in range(0, allNumberList[-1]):
                if oldNumList[i] != allNumberList[i]:
                    missingNum = allNumberList[i]
                    break
            if len(oldNumList) == len(allNumberList):
                missingNum = allNumberList[i] +1
        else:
            missingNum = 1

        self.StudentModel.insertRow(row)
        self.StudentView.scrollToBottom()
        self.StudentModel.setData(self.StudentModel.index(row, 1), self.g_curClassName)
        self.StudentModel.setData(self.StudentModel.index(row, 2), str(missingNum).zfill(2))
        self.StudentModel.setData(self.StudentModel.index(row, 4), 0)
        self.StudentModel.setData(self.StudentModel.index(row, 5), 0)

    def removeStudent(self):
        index = self.StudentView.currentIndex()
        row = index.row()             
        if QMessageBox.question(self, "删除确认", "是否要删除当前选中记录?", "确定", "取消") == 0:
            self.StudentModel.removeRows(row, 1)
            self.StudentModel.submitAll()
            self.StudentModel.database().commit()

    def revertStudent(self):
        self.StudentModel.revertAll()
        self.StudentModel.database().rollback()

    def saveStudent(self):
        self.StudentModel.database().transaction()
        if self.StudentModel.submitAll():
            self.StudentModel.database().commit()
            # print("save success!  ->commit")
        else:
            self.StudentModel.revertAll()
            self.StudentModel.database().rollback()

    #######======= classModel ============###############
    def newClass(self):
        row = self.ClassnameModel.rowCount()
        self.ClassnameModel.insertRow(row)

    def removeClass(self):
        index = self.ClassnameView.currentIndex()
        row = index.row()   
        curClassname =  index.sibling(index.row(),0).data()
        strwhere = "classname like '" + curClassname + "'"
        self.StudentModel.setFilter(strwhere)
        self.StudentModel.select()
        # print(self.StudentModel.rowCount(), "----", )
        if QMessageBox.question(self, "删除确认", "删除班级意味着会删除本班所有人员信息。是否要删除当前选中记录?", "确定", "取消") == 0:
            self.ClassnameModel.removeRows(row, 1)
            self.ClassnameModel.submitAll()
            self.ClassnameModel.database().commit()

            self.StudentModel.removeRows(0, self.StudentModel.rowCount())
            self.StudentModel.submitAll()
            self.StudentModel.database().commit()

    def revertClass(self):
        self.ClassnameModel.revertAll()
        self.ClassnameModel.database().rollback()

    def saveClass(self):
        query = QSqlQuery(self.db)

        # record the old class name
        lstOldClassName = {}
        lstOldClassid = []
        query.exec_("select rowid, classname from classtable" )        
        while(query.next()):
            lstOldClassName[query.value(0)] = query.value(1)
            lstOldClassid.append(query.value(0))
        # print(lstOldClassName)

        # Update the class Table
        self.ClassnameModel.database().transaction()
        if self.ClassnameModel.submitAll():
            self.ClassnameModel.database().commit()
            # print("save success!  ->commit")
        else:
            QMessageBox.warning(None, "错误",  "请检查班级中名称,不能出现同名班级!")
            self.ClassnameModel.revertAll()
            self.ClassnameModel.database().rollback()

        # print(lstOldClassid)

        lstNewClassName = {}
        query.exec_("select rowid, classname from classtable where rowid in " + str(tuple(lstOldClassid)) )        
        while(query.next()):
            lstNewClassName[query.value(0)] = query.value(1)            

        # print(lstOldClassName, '=========')
        # print(lstNewClassName, '~~~~~~~~~')

        for i in lstOldClassName:
            oldclassname = lstOldClassName[i]
            newclassname = lstNewClassName[i]
            if oldclassname != newclassname:
                # print(oldclassname, newclassname, '++++++++')
                # print("update student set classname=" + newclassname + " where classname='" + oldclassname + "'")
                query.exec_("update student set classname='" + newclassname + "' where classname='" + oldclassname + "'")
                self.StudentModel.setFilter("classname = '" + newclassname + "'")
                self.StudentModel.select()

        lstClassName = []      
        query.exec_("select classname from classtable" ) 
        while(query.next()):
            lstClassName.append(query.value(0))
        self.StudentView.setItemDelegateForColumn(1,  ComboBoxDelegate(self, lstClassName, self.db))

    def dbclick(self, indx):
        if type(indx.sibling(indx.row(),0).data()) != QPyNullVariant:
            classname = indx.sibling(indx.row(),0).data()
            
            strwhere = "classname like '" + classname + "'"
            self.StudentModel.setFilter(strwhere)
            self.StudentModel.setSort(2, Qt.AscendingOrder)
            self.StudentModel.select()
            
            self.g_curClassName = classname
            self.tabWidget.setTabText(0, self.g_curClassName)

    def dbclick2(self, indx):
        if indx.column() == 2:
            self.StudentView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        else:
            self.StudentView.setEditTriggers(QAbstractItemView.DoubleClicked)
        

    def genTwoTab(self, tabtitle=""):
        # Create the tab title sytle.
        tabtitle = QLabel()
        tabtitle.setFont(QFont('Courier New', 20))
        tabtitle.setText("班级学生信息管理")
        tabtitle.setStyleSheet("border: 1px solid blue; color:rgba(0,0,255, 220);\
            background-color:rgba(201,201,201,60);\
            border-radius: 6px; \
            padding: 1px 18px 1px 20px;\
            min-width: 8em;")
        tabtitle.setMinimumHeight(50);
        titleLayout = QHBoxLayout()
        titleLayout.addWidget(tabtitle)
        titleLayout.setAlignment(tabtitle, Qt.AlignCenter)

       
        # Create the classnameView
        self.ClassnameView = QTableView()
        self.ClassnameModel = QSqlTableModel(self.ClassnameView)
        self.ClassnameModel.setTable("classtable")
        # self.ClassnameModel.setRelation(2, QSqlRelation("mentalmodel", "id", "name"));
        self.ClassnameModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.ClassnameModel.select()

        self.ClassnameModel.setHeaderData(0, Qt.Horizontal, "班级名称")

        # for indx, iheader in enumerate(["classid", "classname"]):
        #     self.ClassnameModel.setHeaderData(indx+1, Qt.Horizontal, iheader)
    
        self.ClassnameView.setModel(self.ClassnameModel)
        # self.ClassnameView.setColumnHidden(0, True)
        # self.ClassnameView.show()
        self.ClassnameView.verticalHeader().setFixedWidth(30)
        self.ClassnameView.verticalHeader().setStyleSheet("color: red;font-size:20px; ");
        self.ClassnameView.setStyleSheet("QTableView{background-color: rgb(250, 250, 200, 0);"  
                    "alternate-background-color: rgb(141, 163, 0);}"
                    "QTableView::item:hover {background-color: rgba(100,200,220,100);} ") 
        self.ClassnameView.setStyleSheet("font-size:16px; ");
        self.ClassnameView.setSelectionMode(QAbstractItemView.SingleSelection)
        # self.ClassnameView.dataChanged.connect(self.dataChanged)

        # self.ClassnameView.setSizePolicy(QSizePolicy.Expanding,     QSizePolicy.Expanding)

        # the second list
        self.StudentView = QTableView()
        self.StudentModel = QSqlTableModel(self.StudentView)
        self.StudentModel.setTable("student")
        # self.StudentModel.setRelation(2, QSqlRelation("mentalmodel", "id", "name"));
        self.StudentModel.setEditStrategy(QSqlTableModel.OnManualSubmit)
        # self.StudentModel.select()

        query = QSqlQuery(self.db)
        strwhere = " 1=1 "
        if self.g_curClassName == "":
            ret = query.exec_("select classname from classtable")
            query.next()
            firstClassName = query.value(0)
            strwhere += " and classname like '" + firstClassName + "'"
            
        self.StudentModel.setFilter(strwhere)
        self.StudentModel.select()

        for indx, iheader in enumerate(["班级名称", "学生编号", "学生姓名", "答对次数", "答错次数"]):
            self.StudentModel.setHeaderData(indx+1, Qt.Horizontal, iheader)
    
        self.StudentView.setModel(self.StudentModel)
        self.StudentView.setColumnHidden(0, True)

        # query = QSqlQuery(self.db)  
        lstClassName = []      
        query.exec_("select classname from classtable" ) 
        while(query.next()):
            lstClassName.append(query.value(0))

        self.StudentView.setItemDelegateForColumn(1,  ComboBoxDelegate(self, lstClassName, self.db))
        # self.StudentView.show()
        self.StudentView.verticalHeader().setFixedWidth(30)
        self.StudentView.verticalHeader().setStyleSheet("color: red;font-size:20px; background-color: rgb(250, 250, 200, 100)");
        self.StudentView.setStyleSheet("QTableView{background-color: rgb(250, 250, 200, 0);"  
                    "alternate-background-color: rgb(141, 163, 250);}"
                    "QTableView::item:hover {background-color: rgba(10,200,100,200);} "
                    ) 
        self.StudentView.setStyleSheet("font-size:16px;")
        self.StudentView.setSelectionMode(QAbstractItemView.SingleSelection)
        self.StudentView.doubleClicked.connect(self.dbclick2)

        btn_lst1_layout = QGridLayout()
        newusrbtn       = QPushButton("新增")
        savebtn         = QPushButton("保存")
        revertbtn       = QPushButton("撤销")
        removebtn       = QPushButton("删除")
        btn_lst1_layout.addWidget(newusrbtn, 0, 0)
        btn_lst1_layout.addWidget(savebtn, 0, 1)
        btn_lst1_layout.addWidget(revertbtn, 1, 0)
        btn_lst1_layout.addWidget(removebtn, 1, 1)

        newusrbtn.clicked.connect(self.newClass)
        savebtn.clicked.connect(self.saveClass)
        revertbtn.clicked.connect(self.revertClass)
        removebtn.clicked.connect(self.removeClass)

        self.ClassnameView.doubleClicked.connect(self.dbclick)
        

        btnbox2 = QDialogButtonBox(Qt.Horizontal)
        newusrbtn2       = QPushButton("新增")
        savebtn2         = QPushButton("保存")
        revertbtn2       = QPushButton("撤销")
        removebtn2       = QPushButton("删除")
        btnbox2.addButton(newusrbtn2, QDialogButtonBox.ActionRole);
        btnbox2.addButton(savebtn2, QDialogButtonBox.ActionRole);
        btnbox2.addButton(revertbtn2, QDialogButtonBox.ActionRole);
        btnbox2.addButton(removebtn2, QDialogButtonBox.ActionRole);

        newusrbtn2.clicked.connect(self.newStudent)
        savebtn2.clicked.connect(self.saveStudent)
        revertbtn2.clicked.connect(self.revertStudent)
        removebtn2.clicked.connect(self.removeStudent)

        # left list layout
        lst_layout_1 = QVBoxLayout()
        lst_layout_1.addWidget(self.ClassnameView)
        lst_layout_1.addLayout(btn_lst1_layout)

        lst_layout_2 = QVBoxLayout()
        lst_layout_2.addWidget(self.StudentView)
        lst_layout_2.addWidget(btnbox2)
        
        lstlayout = QHBoxLayout()
        lstlayout.setMargin(5)
        # lstlayout.addLayout(findbox)
        lstlayout.addLayout(lst_layout_1, 2)
        lstlayout.setMargin(5)
        lstlayout.addLayout(lst_layout_2, 5)
            
        labelClass = QLabel("")
        labelClass.setStyleSheet("background-color:rgba(255, 255, 255,0); color:rgba(0,0,0,0);")
        labelClass.setFixedHeight(40)
        # labelClass.setFixedWidth(100)
        # labelClass.setFont(QFont('宋体', 10))

        bottomlayout = QHBoxLayout()        
        bottomlayout.addWidget(labelClass)        

        tab2layout = QVBoxLayout()
        tab2layout.addLayout(titleLayout)       
        tab2layout.addLayout(lstlayout)
        tab2layout.addLayout(bottomlayout)
        self.w2.setLayout(tab2layout)
        self.w2.setStyleSheet("background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #228888);")
      
    def genOneTab(self):

        tabtitle = QLabel()
        # tabtitle.setFixedHeight(40)
        # tabtitle.setFixedWidth(160)        
        self.btn_start = MyButton("开始")
        self.choicenum_text = QComboBox()
        self.choicenum_text.setObjectName('w1combonums')
        # self.w1title.setStyleSheet("background-image:url('image/panelbg.jpg');")
        
        # Set the title style                
        tabtitle.setFont(QFont('Courier New', 20))
        tabtitle.setText("随堂提问演板")
        tabtitle.setStyleSheet("border: 1px solid blue; color:rgba(0,0,255, 220);\
            background-color:rgba(201,201,201,60);\
            border-radius: 6px; \
            padding: 1px 18px 1px 20px;\
            min-width: 8em;")
        tabtitle.setMinimumHeight(50);
        titleLayout = QHBoxLayout()
        titleLayout.addWidget(tabtitle)
        titleLayout.setAlignment(tabtitle, Qt.AlignCenter)
       
        btnlayout = QGridLayout()
        tmpnum = 0
        for inum in range(0,56):
            irow = tmpnum // g_cols
            icol = tmpnum % g_cols
            tmpnum += 1
            btnlayout.setRowMinimumHeight(irow, 80)
            tmpbtn = MyButton("")
            tmpbtn.setMyarg(None)
            # tmpbtn.setFixedHeight(20)
            tmpbtn.setSizePolicy(QSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding))
            tmpbtn.setStyleSheet("border: 1px solid rgb(55,55,255,100);background-color: rgba(255,255,255,20);font-size:16px;")
            self.connect(tmpbtn,  SIGNAL("myslot(PyQt_PyObject)"), self.myslot)
            tmpbtn.setAutoDefault(False)
            self.btngroup.addButton(tmpbtn, inum+1) # stusn is from 1 start

            btnlayout.addWidget(tmpbtn, irow, icol)


        self.btn_start.setIcon(QIcon("image/start.png"))
        self.btn_start.setStyleSheet("border: 1px solid yellow;")
        self.btn_start.setFixedHeight(40)
        self.btn_start.setFixedWidth(100)
        self.btn_start.setFont(QFont('宋体', 18))
        # self.choicenum_text.setFixedHeight(45)
        # self.choicenum_text.setFixedWidth(60)

        ## Set the combox number style
        self.choicenum_text.setFont(QFont('Courier New', 20))
        self.choicenum_text.setFixedHeight(45)
        self.choicenum_text.setStyleSheet("border: 2px solid blue; color:red;font-weight:light;font-size:26px;\
            border-radius: 6px; \
            min-width: 2em; ")
        self.choicenum_text.setEditable(True)
        self.choicenum_text.lineEdit().setReadOnly(True);
        self.choicenum_text.lineEdit().setAlignment(Qt.AlignCenter);

        model = self.choicenum_text.model()
        for row in list(range(1, 7)):
            item = QStandardItem(str(row))
            item.setTextAlignment(Qt.AlignCenter)
            item.setForeground(QColor('red'))
            item.setBackground(QColor(0,200,50, 130))
            model.appendRow(item)
        self.choicenum_text.setCurrentIndex(2)
        # self.choicenum_text.setStyleSheet ("QComboBox::drop-down {border-width: 100px;}")
        # self.choicenum_text.setStyleSheet ("QComboBox::down-arrow {image: url(image/downarrow.png);top: 10px;left: 1px;}")

        bottomlayout = QHBoxLayout()
        bottomlayout.setSizeConstraint(QLayout.SetFixedSize)
        bottomlayout.addStretch(10)
        bottomlayout.addWidget(self.btn_start)
        bottomlayout.setSpacing(5)
        bottomlayout.addWidget(self.choicenum_text)

        tab1layout = QVBoxLayout()
        tab1layout.addLayout(titleLayout)       
        tab1layout.addLayout(btnlayout)
        tab1layout.addLayout(bottomlayout)
                
        self.w1.setLayout(tab1layout)
        self.w1.setStyleSheet("background-color: QLinearGradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #ffffff, stop: 1 #228888);")
         
    def startChoice(self, usernum="", oldbtn=""): 
        # print(oldbtn, 1)

        if oldbtn == "":
            self.dict_choices = {}

        strwhere = " and classname like '" + self.g_curClassName + "'"

        allstudent = []
        lstrecord = []
        query = QSqlQuery(self.db)        
        query.exec_("select stusn from tmprecord where 1=1 " + strwhere) 
        while(query.next()):
            lstrecord.append(query.value(0))
        # print(lstrecord, 'record', "select stusn from student where stusn not in " + str(tuple(lstrecord)))

        query.exec_("select stusn from student where stusn not in " + str(tuple(lstrecord)) + strwhere)
        while(query.next()):
            allstudent.append(query.value(0))

        if usernum == "":
            nums = int(self.choicenum_text.currentText())
        else:
            nums = usernum
        if nums >= len(allstudent):
            query.exec_("delete from tmprecord where 1=1 " + strwhere) #delete tmp date no today            
            allstudent = []
            query.exec_("select stusn from student where 1=1 " + strwhere)
            while(query.next()):
                allstudent.append(query.value(0))
        
        if oldbtn == "":
            random.seed()
            lstchoices = random.sample(allstudent, nums)
            for ibtn in lstchoices:
                self.dict_choices[ibtn] = "111"

            self.group_animation.start()
            QTimer.singleShot(1200, self.stopmovie)
        else:
            random.seed()
            otherbtn = random.sample(allstudent, 1)[0]
            # self.btngroup.button(int(otherbtn)).setFocus()
            self.dict_choices.pop(oldbtn)
            self.dict_choices[otherbtn] = '111'
            self.stopmovie()
        self.btnSysMenu.setFocus()

    def stopmovie(self):
        self.group_animation.stop()
        for isn in self.studentSnlst:
            # print(isn)
            self.btngroup.button(int(isn[0])).setStyleSheet(stylesheetstr_old)
            self.btngroup.button(int(isn[0])).setIcon(QIcon())
        
        classname = self.tabWidget.tabText(0)
        query = QSqlQuery(self.db)        
        today = datetime.date.today()
        for ibtn in self.dict_choices:
            self.btngroup.button(int(ibtn)).setStyleSheet(stylesheetstr_new)
            query.exec_("select count(*) from tmprecord where stusn='" + str(ibtn) + "'")
            query.next()
            if query.value(0) == 0:               
                query.prepare("insert into tmprecord (classname, stusn, datequestion) values (:classname, :stusn, :datequestion)")
                query.bindValue(":classname", classname)
                query.bindValue(":stusn", ibtn)
                query.bindValue(":datequestion", today)
                query.exec_()
    
    def answerRight(self):
        # print(self.g_curbtn)
        value = self.g_curbtn
        if value not in self.dict_choices:
            return

        self.btngroup.button(int(value)).setIcon(QIcon("image/smile.png"))
        self.btngroup.button(int(value)).setIconSize(QSize(20,20))
        
        query = QSqlQuery(self.db)
        query.exec_("select rightquestions from student where stusn='" + value + "'")
        query.next()
        studentRightQuestions = query.value(0) + 1
        query.exec_("update student set rightquestions=" + str(studentRightQuestions) + " where stusn='" + value + "'")
                
        ###########
        if self.dict_choices[value] == "101":
            query.exec_("select wrongquestions from student where stusn='" + value + "'")
            query.next()
            studentWrongQuestions = query.value(0) - 1
            query.exec_("update student set wrongquestions=" + str(studentWrongQuestions) + " where stusn='" + value + "'")
            
        self.dict_choices[value] = "011"

    def answerWrong(self):
        value = self.g_curbtn
        if value not in self.dict_choices:
            return

        self.btngroup.button(int(value)).setIcon(QIcon("image/cry.png"))
        self.btngroup.button(int(value)).setIconSize(QSize(20,20))
        # self.btngroup.button(int(value)).setStyleSheet("border-image: url(image/ex_stu.png);")
        
        query = QSqlQuery(self.db)
        query.exec_("select wrongquestions from student where stusn='" + value + "'")
        query.next()
        studentWrongQuestions = query.value(0) + 1
        query.exec_("update student set wrongquestions=" + str(studentWrongQuestions) + " where stusn='" + value + "'")
        
        if self.dict_choices[value] == "011":
            query.exec_("select rightquestions from student where stusn='" + value + "'")
            query.next()
            studentRightQuestions = query.value(0) - 1
            query.exec_("update student set rightquestions=" + str(studentRightQuestions) + " where stusn='" + value + "'")
            
        self.dict_choices[value] = "101"

    def resetStudent(self):
        value = self.g_curbtn
        if value not in self.dict_choices:
            return

        query = QSqlQuery(self.db)

        if self.dict_choices[value] == "011":        
            query.exec_("select rightquestions from student where stusn='" + value + "'")
            query.next()
            studentRightQuestions = query.value(0) - 1
            query.exec_("update student set rightquestions=" + str(studentRightQuestions) + " where stusn='" + value + "'")

        if self.dict_choices[value] == "101":
            query.exec_("select wrongquestions from student where stusn='" + value + "'")
            query.next()
            studentWrongQuestions = query.value(0) - 1
            query.exec_("update student set wrongquestions=" + str(studentWrongQuestions) + " where stusn='" + value + "'")
            
        self.startChoice(usernum=1, oldbtn=value)
        # print("---reset___")

        # curmenu.actions()[0].setEnabled(True)
        # curmenu.actions()[1].setEnabled(True)
        # self.choiceOneStudent(value)

    def createDb(self):
        conn = sqlite3.connect("studentNew.db") 
        cur = conn.cursor()
        sqlstr = 'create table student (id integer primary key, \
            classname varchar(20), \
            stusn varchar(20), \
            stuname varchar(20), \
            rightquestions integer, \
            wrongquestions integer, \
            FOREIGN KEY(classname) REFERENCES classtable(classname))'
        # print(sqlstr)

        sqlstr2 = 'create table tmprecord (id integer primary key, \
            classname varchar(20), \
            stusn varchar(20), \
            datequestion date)'

        sqlstr3 = 'create table classtable (classname varchar(20) PRIMARY KEY)'
        
        cur.execute(sqlstr3)
        conn.commit()
        cur.execute(sqlstr2)
        conn.commit()
        cur.execute(sqlstr)
        conn.commit()

        strdelete = "delete from student where 1=1"
        cur.execute(strdelete)
        conn.commit()
        strdelete = "delete from tmprecord where 1=1"
        cur.execute(strdelete)
        conn.commit()
        # print(sqlstr2)

        # cur.execute(sqlstr) 
        # conn.commit()
        # cur.execute(sqlstr2) 
        # conn.commit()

        # insert example data
        strsql = "insert into classtable values (?)"
        cur.execute(strsql, ("三(3)班",))
        conn.commit()
        cur.execute(strsql, ("三(4)班",))
        conn.commit()


        a03lst = ["曾忆谊","赵佳泉","翁文秀","林珑","郑铭洁","林泽思","吴崇霖","陈思嘉","欧阳月孜","郭展羽","詹伟哲","黄佳仪","杨秋霞","周奕子","林楚杰","欧伊涵","许腾誉","陈唯凯","陈树凯","林彦君","张钰佳","高锴","杨博凯","林妙菲","林楚鸿","陈展烯","姚静茵","吴欣桐","范思杰","肖佳","马思广","许一帆","姚奕帆","陈海珣","吴黛莹","吴育桐","肖凯帆","林欣阳","叶茂霖","姚楷臻","陈嘉豪","陈琦","杨子楷","陈炎宏","陈幸仪","杨景畅","罗暖婷","郑馨"]
        a04lst = ["罗恩琪","王可","曾祥威","谢濡婷","温嘉凯","许洁仪","肖欣淇","陈凯佳","林天倩","李乐海","吴文慧","黄文婷","万誉","陈进盛","张裕涵","陈振嘉","王巧玲","林珮琪","陈炜楷","杨健","赵泽锴","张凤临","蔡子丹","陈烨杰","廖妍希","林树超","夏培轩","陈锦森","李星","蔡依婷","姚容创","姚凯扬","沈嘉克","周凡","张玉川","邱金迅","陈菲敏","陈星翰","朱煜楷","郑泽洪","钱剑非","罗奕丰","陈杜炜","林知钦"]
        strsql = "insert into student values (?, ?, ?, ?,?,?)" 
        for i in list(range(0,len(a03lst))):
            cur.execute(strsql, (None, "三(3)班", str(i+1).zfill(2), a03lst[i], 0, 0))
            conn.commit()
        strsql = "insert into student values (?, ?, ?, ?,?,?)" 
        for i in list(range(0,len(a04lst))):
            cur.execute(strsql, (None, "三(4)班", str(i+1).zfill(2), a04lst[i], 0, 0))
            conn.commit()
        cur.close()
Exemplo n.º 43
0
class ChoirStaff(StaffBase):
    def __init__(self, dialog):
        StaffBase.__init__(self, dialog)
        self.staffCount = QSpinBox()
        self.staffCount.setRange(2, 8)
        l = QLabel(i18n("Staves per system:"))
        l.setBuddy(self.staffCount)
        self.layout().addWidget(l, 0, 1, Qt.AlignRight)
        self.layout().addWidget(self.staffCount, 0, 2)
        l = QLabel(i18n("Systems per page:"))
        l.setBuddy(self.systems)
        self.layout().addWidget(l, 1, 1, Qt.AlignRight)
        self.layout().addWidget(self.systems, 1, 2)
        self.clefs = QComboBox()
        self.clefs.setEditable(True)
        self.clefs.setCompleter(None)
        l = QLabel(i18n("Clefs:"))
        l.setBuddy(self.clefs)
        self.layout().addWidget(l, 2, 1, Qt.AlignRight)
        self.layout().addWidget(self.clefs, 2, 2)
        
        # tool tips
        self.clefs.setToolTip(i18n(
            "Enter as many letters (S, A, T or B) as there are staves.\n"
            "See \"What's This\" for more information."))
        self.clefs.setWhatsThis(i18n(
            "To configure clefs, first set the number of staves per system. "
            "Then enter as many letters (S, A, T or B) as there are staves.\n\n"
            "S or A: treble clef,\n"
            "T: treble clef with an \"8\" below,\n"
            "B: bass clef\n\n"
            "So when you want to create music paper for a four-part mixed "
            "choir score, first set the number of staves per system to 4. "
            "Then enter \"SATB\" (without the quotes) here."))
        
        self.staffCount.valueChanged.connect(self.slotStaffCountChanged)
        self.slotStaffCountChanged(2)    
        
    def name(self):
        return i18n("Choir Staff")
        
    def default(self):
        self.staffCount.setValue(2)
    
    def slotStaffCountChanged(self, value):
        self.clefs.clear()
        self.clefs.addItem(i18n("None"))
        self.clefs.addItems((
            ('SB', 'SS', 'ST', 'TT', 'TB', 'BB'), # 2
            ('SSB', 'SSS', 'TTB', 'TTT', 'TTB'), # 3
            ('SATB', 'STTB', 'TTBB'), # 4
            ('SSATB', 'SATTB'), # 5
            ('SSATTB', 'SSATBB'), #6
            ('SSATTBB', ), # 7
            ('SATBSATB', 'SSAATTBB') #8
            )[value - 2])
        self.clefs.setCurrentIndex(0)
        systemCount = int(12 / value)
        if systemCount == 1 and self.dialog.staffSize.value() <= 18:
            systemCount = 2
        self.systems.setValue(systemCount)

    def music(self, layout):
        clefs = self.clefs.currentText().upper()
        length = self.staffCount.value()
        if clefs and set(clefs) <= set("SATB"):
            # pad to staff count if necessary
            clefs = (clefs + clefs[-1] * length)[:length]
        else:
            clefs = [None] * length
            layout.add('Staff', "\\override Clef #'transparent = ##t")
        if lilyPondVersion() < (2, 13, 4):
            layout.add("Staff",
                "\\override VerticalAxisGroup #'minimum-Y-extent = #'(-6 . 4)")
        music = ['\\new ChoirStaff <<']
        for clef in clefs:
            music.append('\\new Staff {{{0} \\music }}'.format({
                'S': ' \\clef treble',
                'A': ' \\clef treble',
                'T': ' \\clef "treble_8"',
                'B': ' \\clef bass',
                None: '',
                }[clef]))
        music.append('>>')
        return music
Exemplo n.º 44
0
class GotoLineWidget( QWidget ):
    " goto bar widget "

    maxHistory = 12

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

        QWidget.__init__( self, parent )
        self.editorsManager = editorsManager

        self.__gotoHistory = []

        # Common graphics items
        closeButton = QToolButton( self )
        closeButton.setToolTip( "Click to close the dialog (ESC)" )
        closeButton.setIcon( PixmapCache().getIcon( "close.png" ) )
        closeButton.clicked.connect( self.hide )

        lineLabel = QLabel( self )
        lineLabel.setText( "Goto line:" )

        self.linenumberEdit = QComboBox( self )
        self.linenumberEdit.setEditable( True )
        self.linenumberEdit.setInsertPolicy( QComboBox.InsertAtTop )
        self.linenumberEdit.setAutoCompletion( False )
        self.linenumberEdit.setDuplicatesEnabled( False )
        sizePolicy = QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Fixed )
        sizePolicy.setHorizontalStretch( 0 )
        sizePolicy.setVerticalStretch( 0 )
        sizePolicy.setHeightForWidth(
                self.linenumberEdit.sizePolicy().hasHeightForWidth() )
        self.linenumberEdit.setSizePolicy( sizePolicy )
        self.validator = QIntValidator( 1, 100000, self )
        self.linenumberEdit.setValidator( self.validator )
        self.linenumberEdit.editTextChanged.connect( self.__onEditTextChanged )
        self.linenumberEdit.lineEdit().returnPressed.connect( self.__onEnter )

        self.goButton = QToolButton( self )
        self.goButton.setToolTip( "Click to jump to the line (ENTER)" )
        self.goButton.setIcon( PixmapCache().getIcon( "gotoline.png" ) )
        self.goButton.setFocusPolicy( Qt.NoFocus )
        self.goButton.setEnabled( False )
        self.goButton.clicked.connect( self.__onGo )

        spacer = QWidget()
        spacer.setFixedWidth( 1 )

        horizontalLayout = QHBoxLayout( self )
        horizontalLayout.setMargin( 0 )

        horizontalLayout.addWidget( closeButton )
        horizontalLayout.addWidget( lineLabel )
        horizontalLayout.addWidget( self.linenumberEdit )
        horizontalLayout.addWidget( self.goButton )
        horizontalLayout.addWidget( spacer )
        return

    def keyPressEvent( self, event ):
        """ Handles the key press events """

        if event.key() == Qt.Key_Escape:
            activeWindow = self.editorsManager.currentWidget()
            if activeWindow:
                activeWindow.setFocus()
            event.accept()
            self.hide()
        return

    def __updateHistory( self, txt ):
        " Updates the combo history "

        while txt in self.__gotoHistory:
            self.__gotoHistory.remove( txt )
        self.__gotoHistory = [ txt ] + self.__gotoHistory
        self.__gotoHistory = self.__gotoHistory[ : GotoLineWidget.maxHistory ]

        self.linenumberEdit.clear()
        self.linenumberEdit.addItems( self.__gotoHistory )
        return

    def show( self ):
        " Overriden show() method "
        self.linenumberEdit.lineEdit().selectAll()
        QWidget.show( self )
        self.activateWindow()
        return

    def setFocus( self ):
        " Overridded setFocus "
        self.linenumberEdit.setFocus()
        return

    def updateStatus( self ):
        " Triggered when the current tab is changed "
        currentWidget = self.editorsManager.currentWidget()
        status = currentWidget.getType() in \
                    [ MainWindowTabWidgetBase.PlainTextEditor,
                      MainWindowTabWidgetBase.VCSAnnotateViewer ]
        self.linenumberEdit.setEnabled( status )
        self.goButton.setEnabled( status and
                                  self.linenumberEdit.currentText() != "" )
        return

    def __onGo( self ):
        " Triggered when the 'Go!' button is clicked "
        if self.linenumberEdit.currentText() == "":
            return

        currentWidget = self.editorsManager.currentWidget()
        if not currentWidget.getType() in \
                    [ MainWindowTabWidgetBase.PlainTextEditor,
                      MainWindowTabWidgetBase.VCSAnnotateViewer ]:
            return

        txt = self.linenumberEdit.currentText()
        self.__updateHistory( txt )
        editor = currentWidget.getEditor()
        line = min( int( txt ), editor.lines() ) - 1

        editor.setCursorPosition( line, 0 )
        editor.ensureLineVisible( line )
        currentWidget.setFocus()
        return

    def __onEditTextChanged( self, text ):
        " Triggered when the text has been changed "
        self.goButton.setEnabled( text != "" )
        return

    def __onEnter( self ):
        " Triggered when 'Enter' or 'Return' is clicked "
        self.__onGo()
        return

    def selectAll( self ):
        " Selects the line edit content "
        self.linenumberEdit.lineEdit().selectAll()
        return
Exemplo n.º 45
0
class ProfileWizard(StandaloneWizardPage):
    """Wizard for the creation of a new database
profile.

.. attribute:: languages
.. attribute:: dialects

A list of languages allowed in the profile selection, an empty list will
allow all languages
    """

    languages = []
    dialects = []

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

        self._connection_valid = False
        self.network_reply = None
        self.profiles = profiles

        self.setWindowTitle(_('Profile Wizard'))
        self.set_banner_logo_pixmap(art.Icon('tango/22x22/categories/preferences-system.png').getQPixmap())
        self.set_banner_title(_('Create New/Edit Profile'))
        self.set_banner_subtitle(_('Please enter the database settings'))
        self.banner_widget().setStyleSheet('background-color: white;')

        self.manager = QtNetwork.QNetworkAccessManager( self )
        self.manager.finished.connect( self.update_network_status )
        #self.manager.networkAccessibleChanged.connect( self.network_accessible_changed )
        self.manager.proxyAuthenticationRequired.connect( self.proxy_authentication_required )
        
        self.create_labels_and_widgets()
        self.create_buttons()
        self.set_tab_order()
        self.set_widgets_values()
        # note: connections come after labels and widgets are created
        # and have default values
        self.connect_widgets()
        self.connect_buttons()
        
        timer = QtCore.QTimer(self)
        timer.timeout.connect( self.new_network_request )
        timer.setInterval( 3000 )
        timer.start()
        self.new_network_request()

    def create_labels_and_widgets(self):
        assert object_thread( self )
        self.profile_label = QLabel(_('Profile Name:'))
        self.dialect_label = QLabel(_('Driver:'))
        self.host_label = QLabel(_('Server Host:'))
        self.port_label = QLabel(_('Port:'))
        self.database_name_label = QLabel(_('Database Name:'))
        self.username_label = QLabel(_('Username:'******'Password:'******'Media Location:'))
        self.language_label = QLabel(_('Language:'))
        self.proxy_host_label = QLabel(_('Proxy Host:'))
        self.proxy_port_label = QLabel(_('Port:'))
        self.proxy_username_label = QLabel(_('Proxy Username:'******'Proxy Password:'******'Media location path '\
            'is not accessible.'))
        self.not_accessible_media_path_label.setStyleSheet('color: red')
        self.not_writable_media_path_label = QLabel(_('Media location path '\
            'is not writable.'))
        self.not_writable_media_path_label.setStyleSheet('color: red')

        layout = QGridLayout()

        layout.addWidget(self.profile_label, 0, 0, Qt.AlignRight)
        layout.addWidget(self.dialect_label, 1, 0, Qt.AlignRight)
        layout.addWidget(self.host_label, 2, 0, Qt.AlignRight)
        layout.addWidget(self.port_label, 2, 3, Qt.AlignRight)
        layout.addWidget(self.database_name_label, 3, 0, Qt.AlignRight)
        layout.addWidget(self.username_label, 4, 0, Qt.AlignRight)
        layout.addWidget(self.password_label, 5, 0, Qt.AlignRight)
        layout.addWidget(self.media_location_label, 7, 0, Qt.AlignRight)
        layout.addWidget(self.language_label, 8, 0, Qt.AlignRight)
        layout.addWidget(self.proxy_host_label,  10, 0, Qt.AlignRight)
        layout.addWidget(self.proxy_port_label,  10, 3, Qt.AlignRight)
        layout.addWidget(self.proxy_username_label, 11, 0, Qt.AlignRight)
        layout.addWidget(self.proxy_password_label, 12, 0, Qt.AlignRight)

        self.profile_editor = QComboBox(self)
        self.profile_editor.setEditable(True)

        # 32767 is Qt max length for string
        # should be more than enough for folders
        # http://doc.qt.nokia.com/latest/qlineedit.html#maxLength-prop
        self.dialect_editor = ChoicesEditor(parent=self)
        self.host_editor = TextLineEditor(self, length=32767)
        self.host_editor.set_value('')
        self.port_editor = TextLineEditor(self)
        self.port_editor.setFixedWidth(60)
        self.port_editor.set_value('')
        self.database_name_editor = TextLineEditor(self, length=32767)
        self.database_name_editor.set_value('')
        self.username_editor = TextLineEditor(self)
        self.username_editor.set_value('')
        self.password_editor = TextLineEditor(self)
        self.password_editor.setEchoMode(QLineEdit.Password)
        self.password_editor.set_value('')
        self.media_location_editor = TextLineEditor(self, length=32767)
        self.media_location_editor.set_value('')
        self.language_editor = LanguageEditor(languages=self.languages,
                                              parent=self)
        #
        # try to find a default language
        #
        system_language = QtCore.QLocale.system().name()
        if self.languages:
            if system_language in self.languages:
                self.language_editor.set_value( system_language )
            else:
                self.language_editor.set_value( self.languages[0] )
        else:
            self.language_editor.set_value( system_language )

        self.proxy_host_editor = TextLineEditor(self, length=32767)
        self.proxy_host_editor.set_value('')
        self.proxy_port_editor = TextLineEditor(self)
        self.proxy_port_editor.setFixedWidth(60)
        self.proxy_port_editor.set_value('')
        self.proxy_username_editor = TextLineEditor(self)
        self.proxy_username_editor.set_value('')
        self.proxy_password_editor = TextLineEditor(self)
        self.proxy_password_editor.set_value('')
        self.proxy_password_editor.setEchoMode(QLineEdit.Password)

        layout.addWidget(self.profile_editor, 0, 1, 1, 1)
        layout.addWidget(self.dialect_editor, 1, 1, 1, 1)
        layout.addWidget(self.host_editor, 2, 1, 1, 1)
        layout.addWidget(self.port_editor, 2, 4, 1, 1)
        layout.addWidget(self.database_name_editor, 3, 1, 1, 1)
        layout.addWidget(self.username_editor, 4, 1, 1, 1)
        layout.addWidget(self.password_editor, 5, 1, 1, 1)
        layout.addWidget(HSeparator(), 6, 0, 1, 5)
        layout.addWidget(self.media_location_editor, 7, 1, 1, 1)
        layout.addWidget(self.language_editor, 8, 1, 1, 1)
        layout.addWidget(HSeparator(), 9, 0, 1, 5)
        layout.addWidget(self.proxy_host_editor, 10, 1, 1, 1)
        layout.addWidget(self.proxy_port_editor, 10, 4, 1, 1)
        layout.addWidget(self.proxy_username_editor, 11, 1, 1, 1)
        layout.addWidget(self.proxy_password_editor, 12, 1, 1, 1)
        
        layout.addWidget(self.network_status_label, 13, 1, 1, 4)
        
        self.main_widget().setLayout(layout)

    def set_widgets_values(self):
        self.dialect_editor.clear()
        self.profile_editor.clear()
        
        if self.dialects:
            dialects = self.dialects
        else:
            import sqlalchemy.dialects
            dialects = [name for _importer, name, is_package in \
                        pkgutil.iter_modules(sqlalchemy.dialects.__path__) \
                        if is_package]
        self.dialect_editor.set_choices([(dialect, dialect.capitalize()) \
            for dialect in dialects])

        self.profile_editor.insertItems(1, [''] + \
            [item for item in fetch_profiles()])
        self.profile_editor.setFocus()
        self.update_wizard_values()

    def connect_widgets(self):
        self.profile_editor.editTextChanged.connect(self.update_wizard_values)
        # self.dialect_editor.currentIndexChanged.connect(self.update_wizard_values)    
    
    def create_buttons(self):
        self.more_button = QPushButton(_('More'))
        self.more_button.setCheckable(True)
        self.more_button.setAutoDefault(False)
        self.cancel_button = QPushButton(_('Cancel'))
        self.ok_button = QPushButton(_('OK'))

        layout = QHBoxLayout()
        layout.setDirection(QBoxLayout.RightToLeft)

        layout.addWidget(self.cancel_button)
        layout.addWidget(self.ok_button)
        layout.addStretch()
        layout.addWidget(self.more_button)

        self.buttons_widget().setLayout(layout)

        self.browse_button = QPushButton(_('Browse'))
        self.main_widget().layout().addWidget(self.browse_button, 7, 2, 1, 3)

        self.setup_extension()

    def setup_extension(self):
        self.extension = QWidget()

        self.load_button = QPushButton(_('Load profiles'))
        self.save_button = QPushButton(_('Save profiles'))

        extension_buttons_layout = QHBoxLayout()
        extension_buttons_layout.setContentsMargins(0, 0, 0, 0)
        extension_buttons_layout.addWidget(self.load_button)
        extension_buttons_layout.addWidget(self.save_button)
        extension_buttons_layout.addStretch()

        extension_layout = QVBoxLayout()
        extension_layout.setContentsMargins(0, 0, 0, 0)
        extension_layout.addWidget(HSeparator())
        extension_layout.addLayout(extension_buttons_layout)

        self.extension.setLayout(extension_layout)
        self.main_widget().layout().addWidget(self.extension, 15, 0, 1, 5)
        self.extension.hide()

    def set_tab_order(self):
        all_widgets = [self.profile_editor, self.dialect_editor,
            self.host_editor, self.port_editor,  self.database_name_editor,
            self.username_editor, self.password_editor,
            self.media_location_editor, self.browse_button,
            self.language_editor,
            self.proxy_host_editor, self.proxy_port_editor,
            self.proxy_username_editor, self.proxy_password_editor,
            self.ok_button, self.cancel_button]

        i = 1
        while i != len(all_widgets):
            self.setTabOrder(all_widgets[i-1], all_widgets[i])
            i += 1

    def connect_buttons(self):
        self.cancel_button.pressed.connect(self.reject)
        self.ok_button.pressed.connect(self.proceed)
        self.browse_button.pressed.connect(self.fill_media_location)
        self.more_button.toggled.connect(self.extension.setVisible)
        self.save_button.pressed.connect(self.save_profiles_to_file)
        self.load_button.pressed.connect(self.load_profiles_from_file)

    def proceed(self):
        if self.is_connection_valid():
            profilename, info = self.collect_info()
            if profilename in self.profiles:
                self.profiles[profilename].update(info)
            else:
                self.profiles[profilename] = info
            store_profiles(self.profiles)
            use_chosen_profile(profilename)
            self.accept()

    def is_connection_valid(self):
        profilename, info = self.collect_info()
        mt = SignalSlotModelThread(lambda:None)
        mt.start()
        progress = ProgressDialog(_('Verifying database settings'))
        mt.post(lambda:self.test_connection( info ),
            progress.finished, progress.exception)
        progress.exec_()
        return self._connection_valid

    def test_connection(self, profile):
        self._connection_valid = False
        connection_string = connection_string_from_profile( profile )
        engine = create_engine(connection_string, pool_recycle=True)
        try:
            connection = engine.raw_connection()
            cursor = connection.cursor()
            cursor.close()
            connection.close()
            self._connection_valid = True
        except Exception, e:
            self._connection_valid = False
            raise UserException( _('Could not connect to database, please check host and port'),
                                 resolution = _('Verify driver, host and port or contact your system administrator'),
                                 detail = unicode(e) )
Exemplo n.º 46
0
class GUI(QWidget):
    def __init__(self, parent=None):
        global f
        f = open(filename, "a")
        f.write("Widget init.\n")
        f.close()
        QWidget.__init__(self, parent, Qt.WindowStaysOnTopHint)
        self.__setup_gui__(self)
        self._flag = False
        self._change = False
        f = open(filename, "a")
        f.write("End of widget init.\n")
        f.close()

    def closeEvent(self, event):
        reply = QMessageBox.question(self, "Confirm",
                                     "Are you sure You want to quit?",
                                     QMessageBox.Yes | QMessageBox.No,
                                     QMessageBox.No)
        if reply == QMessageBox.Yes: event.accept()
        else: event.ignore()

    def __setup_gui__(self, Dialog):
        global f
        f = open(filename, "a")
        f.write("Setup of gui.\n")
        f.close()
        Dialog.setObjectName("Dialog")
        Dialog.resize(270, 145)
        self.setWindowTitle("Map Layer")
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)
        self.Render = QPushButton("Render", Dialog)
        self.Render.setGeometry(QRect(85, 90, 100, 25))
        self.Render.setObjectName("Render")
        self.comboBox = QComboBox(Dialog)
        self.comboBox.setGeometry(QRect(100, 34, 115, 18))
        self.comboBox.setEditable(False)
        self.comboBox.setMaxVisibleItems(11)
        self.comboBox.setInsertPolicy(QComboBox.InsertAtBottom)
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItems([
            "Google Roadmap", "Google Terrain", "Google Satellite",
            "Google Hybrid", "Yahoo Roadmap", "Yahoo Satellite",
            "Yahoo Hybrid", "Bing Roadmap", "Bing Satellite", "Bing Hybrid",
            "Open Street Maps"
        ])
        self.comboBox.setCurrentIndex(10)
        self.label1 = QLabel("Source:", Dialog)
        self.label1.setGeometry(QRect(55, 35, 35, 16))
        self.label1.setObjectName("label1")
        self.slider = QSlider(Dialog)
        self.slider.setOrientation(Qt.Horizontal)
        self.slider.setMinimum(1)
        self.slider.setMaximum(12)
        self.slider.setValue(4)
        self.slider.setGeometry(QRect(110, 61, 114, 16))
        self.label2 = QLabel("Quality: " + str(self.slider.value()), Dialog)
        self.label2.setGeometry(QRect(47, 61, 54, 16))
        self.label2.setObjectName("label2")
        self.doubleSpinBox = QDoubleSpinBox(Dialog)
        self.doubleSpinBox.setGeometry(QRect(160, 5, 40, 20))
        self.doubleSpinBox.setDecimals(0)
        self.doubleSpinBox.setObjectName("doubleSpinBox")
        self.doubleSpinBox.setMinimum(10.0)
        self.doubleSpinBox.setValue(20.0)
        self.doubleSpinBox.setEnabled(False)
        self.checkBox = QCheckBox("Auto refresh", Dialog)
        self.checkBox.setGeometry(QRect(50, 6, 100, 20))
        self.checkBox.setLayoutDirection(Qt.RightToLeft)
        self.checkBox.setObjectName("checkBox")
        self.progressBar = QProgressBar(Dialog)
        self.progressBar.setGeometry(QRect(5, 130, 260, 10))
        self.progressBar.setProperty("value", 0)
        self.progressBar.setTextVisible(False)
        self.progressBar.setObjectName("progressBar")
        self.progressBar.setVisible(False)
        QObject.connect(self.Render, SIGNAL("clicked()"), Dialog.__repaint__)
        QMetaObject.connectSlotsByName(Dialog)
        QObject.connect(self.slider, SIGNAL("valueChanged(int)"),
                        self.__update_slider_label__)
        QObject.connect(self.comboBox, SIGNAL("activated(int)"),
                        self.__combobox_changed__)
        self.timerRepaint = QTimer()
        QObject.connect(self.checkBox, SIGNAL("clicked()"),
                        self.__activate_timer__)
        QObject.connect(self.timerRepaint, SIGNAL("timeout()"),
                        self.__on_timer__)
        f = open(filename, "a")
        f.write("End of setup of gui.\n")
        f.close()

    def __combobox_changed__(self):
        self._change = True

    def __activate_timer__(self):
        self.doubleSpinBox.setEnabled(self.checkBox.isChecked())
        if self.checkBox.isChecked():
            self.timerRepaint.start(self.doubleSpinBox.value() * 1000)
            self.Render.setEnabled(False)
            if _progress == 0: self.__repaint__()
        else:
            self.timerRepaint.stop()
            self.Render.setEnabled(True)

    def __get_net_size__(self):
        global f
        f = open(filename, "a")
        f.write("Geting net size...\n")
        f.close()
        if not os.path.exists(Paths["Screenshot"]):
            Visum.Graphic.Screenshot(Paths["Screenshot"])
        size = Image.open(Paths["Screenshot"]).size
        f = open(filename, "a")
        f.write("Read net size:" + str(size) + ".\n")
        f.close()
        return size

    def __on_timer__(self):
        global _paramGlobal
        self._flag = False
        Visum.Graphic.MaximizeNetWindow()
        param = _paramGlobal
        _paramGlobal = Visum.Graphic.GetWindow()
        shift = abs((param[0] - _paramGlobal[0]) / (param[2] - param[0]))
        zoom = abs((param[2] - param[0]) /
                   (_paramGlobal[2] - _paramGlobal[0]) - 1)
        print _windowSizeGlobal
        if _windowSizeGlobal[2:4] != Visum.Graphic.GetMainWindowPos()[2:4]:
            self.__get_net_size__()
            self._flag = True
        elif shift > 0.4 or zoom > 0.2:
            self._flag = True
        if self._flag or self._change and _progress == 0:
            self.__repaint__()
            self._change = False

    def __update_slider_label__(self, value):
        self.label2.setText("Quality: " + str(value))
        self._change = True

    def __update_progress_bar__(self):
        if _progress != 0:
            self.progressBar.setVisible(True)
            self.progressBar.setValue(_progress)
        else:
            self.progressBar.setVisible(False)

    def __rebuild_paths__(self):
        global Paths
        Paths["Images"] = []
        list = os.listdir(Paths["ScriptFolder"])
        imageList = []
        for i in range(len(list)):
            if list[i][-3:] == "png": imageList.append(list[i])
        for i in range(len(imageList)):
            try:
                Visum.Graphic.Backgrounds.ItemByKey(imageList[i])
                Paths["Images"].append(Paths["ScriptFolder"] + "\\" +
                                       imageList[i])
            except:
                pass

    def __repaint__(self):
        global _progress, f
        if len(Visum.Graphic.Backgrounds.GetAll) != len(Paths["Images"]):
            self.__rebuild_paths__()
        if _progress == 0:
            f = open(filename, "a")
            f.write("Doing repaint...\n")
            f.close()
            QWebSettings.clearMemoryCaches()
            timer = QTimer()
            timer.start(100)
            QObject.connect(timer, SIGNAL("timeout()"),
                            self.__update_progress_bar__)
            Main(self.comboBox.currentIndex(), Visum.Graphic.GetWindow(),
                 self.slider.value() / 4.0, self.__get_net_size__())
        Visum.Graphic.Draw()
        self.__update_progress_bar__()
        _progress = 0
        QTimer().singleShot(1500, self.__update_progress_bar__)
        f = open(filename, "a")
        f.write("End of doing repaint.\n")
        f.close()
Exemplo n.º 47
0
class LDSControls(QFrame):
        
    STATIC_IMG = ('error_static.png','linz_static.png','busy_static.png','clean_static.png')
    ANIM_IMG   = ('error.gif','linz.gif','layer.gif','clean.gif')
    
    IMG_SPEED  = 100
    IMG_WIDTH  = 64
    IMG_HEIGHT = 64
    
    MAX_WD = 450
    
    GD_PATH = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../../bin/gdal/gdal-data'))
    STATUS = LU.enum('ERROR','IDLE','BUSY','CLEAN')
    
    def __init__(self,parent):
        super(LDSControls, self).__init__()
        self.parent = parent
        self.initConf()
        self.initEPSG()
        self.initUI()
        
    def initConf(self):
        '''Read files in conf dir ending in conf'''
        self.cflist = ConfigInitialiser.getConfFiles()
        #self.imgset = self.STATIC_IMG if ConfigWrapper().readDSProperty('Misc','indicator')=='static' else self.ANIM_IMG
        #self.imgset = self.STATIC_IMG if self.parent.confconn.tp.src.confwrap.readDSProperty('Misc','indicator')=='static' else self.ANIM_IMG
        sep = self.parent.confconn.reg.openEndPoint(self.parent.confconn.SRCNAME,self.parent.confconn.uconf)
        self.imgset = self.STATIC_IMG if sep.confwrap.readDSProperty('Misc','indicator')=='static' else self.ANIM_IMG
        self.parent.confconn.reg.closeEndPoint(self.parent.confconn.SRCNAME)
        
    def initEPSG(self):
        '''Read GDAL EPSG files, splitting by NZ(RSR) and RestOfTheWorld'''

        gcsf = gdal.FindFile('gdal','gcs.csv') 
        if not gcsf:
            gcsf = os.path.join(self.GD_PATH,'gcs.csv')
        pcsf = gdal.FindFile('gdal','pcs.csv') 
        if not pcsf: 
            pcsf = os.path.join(self.GD_PATH,'pcs.csv')
        gcs = ConfigInitialiser.readCSV(gcsf)
        pcs = ConfigInitialiser.readCSV(pcsf)

        self.nzlsr = [(e[0],e[0]+' - '+e[3]) for e in gcs if 'NZGD'     in e[1] or  'RSRGD'     in e[1]] \
                   + [(e[0],e[0]+' - '+e[1]) for e in pcs if 'NZGD'     in e[1] or  'RSRGD'     in e[1]]
        self.rowsr = [(e[0],e[0]+' - '+e[3]) for e in gcs if 'NZGD' not in e[1] and 'RSRGD' not in e[1]] \
                   + [(e[0],e[0]+' - '+e[1]) for e in pcs if 'NZGD' not in e[1] and 'RSRGD' not in e[1]]
                   
                   
    def initUI(self):
        
        # 0      1          2       3       4       5      6    7    8
        #'destname','lgselect','layer','uconf','group','epsg','fd','td','int'
        
        #self.rdest,rlgselect,self.rlayer,ruconf,self.rgroup,repsg,rfd,rtd,rint = readlist 
        
        QToolTip.setFont(QFont('SansSerif', 10))
        
        #labels
        destLabel = QLabel('Destination')
        lgLabel = QLabel('Group/Layer')
        epsgLabel = QLabel('EPSG')
        fromDateLabel = QLabel('From Date')
        toDateLabel = QLabel('To Date')
        confLabel = QLabel('User Config')
        
        self.view = QLabel() 
        self.view.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.view.setAlignment(Qt.AlignCenter)

        self.confcombo = QComboBox(self)
        self.confcombo.setToolTip('Enter your user config name (file) here')
        self.confcombo.addItems(self.cflist)
        self.confcombo.setEditable(False)
        #self.confcombo.currentIndexChanged.connect(self.doLGEditUpdate)
        
        #combos
        self.lgcombo = QComboBox(self)
        self.lgcombo.setMaximumWidth(self.MAX_WD)
        self.lgcombo.setDuplicatesEnabled(False)
        #self.lgcombo.setInsertPolicy(QComboBox.InsertAlphabetically)#?doesnt seem to work
        self.lgcombo.setToolTip('Select either Layer or Group entry')
        self.lgcombo.setEditable(False)
        self.sepindex = None
        #self.updateLGValues()
        
        self.epsgcombo = QComboBox(self)
        self.epsgcombo.setMaximumWidth(self.MAX_WD)
        self.epsgcombo.setToolTip('Setting an EPSG number here determines the output SR of the layer')  
        self.epsgcombo.addItems([i[1] for i in self.nzlsr])
        self.epsgcombo.insertSeparator(len(self.nzlsr))
        self.epsgcombo.addItems([i[1] for i in self.rowsr])
        self.epsgcombo.setEditable(True)
        self.epsgcombo.setEnabled(False)
        
        self.destlist = self.getConfiguredDestinations()
        self.destcombo = QComboBox(self)
        self.destcombo.setToolTip('Choose the desired output type')   
        self.destcombo.setEditable(False)
        self.destcombo.addItems(self.destlist)

        #date selection
        self.fromdateedit = QDateEdit()
        self.fromdateedit.setCalendarPopup(True)
        self.fromdateedit.setEnabled(False)
        
        self.todateedit = QDateEdit()
        self.todateedit.setCalendarPopup(True)
        self.todateedit.setEnabled(False)
        
        #check boxes
        self.epsgenable = QCheckBox()
        self.epsgenable.setCheckState(False)
        self.epsgenable.clicked.connect(self.doEPSGEnable)       
        
        self.fromdateenable = QCheckBox()
        self.fromdateenable.setCheckState(False)
        self.fromdateenable.clicked.connect(self.doFromDateEnable)
        
        self.todateenable = QCheckBox()
        self.todateenable.setCheckState(False) 
        self.todateenable.clicked.connect(self.doToDateEnable)
        
        self.progressbar = QProgressBar()
        self.progressbar.setRange(0,100)
        self.progressbar.setVisible(True)
        self.progressbar.setMinimumWidth(self.MAX_WD)
        
        
        #buttons        
        self.initbutton = QPushButton("waiting")
        self.initbutton.setToolTip('Initialise the Layer Configuration')
        self.initbutton.clicked.connect(self.doInitClickAction)
        
        self.cleanbutton = QPushButton("Clean")
        self.cleanbutton.setToolTip('Clean the selected layer/group from local storage')
        self.cleanbutton.clicked.connect(self.doCleanClickAction)
        
        self.replicatebutton = QPushButton("Replicate")
        self.replicatebutton.setToolTip('Execute selected replication')
        self.replicatebutton.clicked.connect(self.doReplicateClickAction)
        
        self.cancelbutton = QPushButton("Close")
        self.cancelbutton.setToolTip('Close the LDS Replicate application')       
        self.cancelbutton.clicked.connect(self.parent.close)


        #set dialog values using GPR
        self.updateGUIValues(self.parent.gvs)
        
        #set onchange here otherwise we get circular initialisation
        self.destcombo.currentIndexChanged.connect(self.doDestChanged)
        self.confcombo.currentIndexChanged.connect(self.doConfChanged)
        self.lgcombo.currentIndexChanged.connect(self.doLGComboChanged)

        self.setStatus(self.STATUS.IDLE)
        
        #grid
        grid = QGridLayout()
        grid.setSpacing(10)
        
        
        #placement section ------------------------------------
        #---------+---------+--------+---------+--------
        # dest LB |         | dest DD
        # grp LB  |         | grp DD
        # conf LB |         | conf DD
        # epsg L  | epsg CB | epsg DD
        # f dt L  | f dt CB | f dt DD
        # t td L  | t td CB | t td DD
        # icon    |       <- progress ->
        # layer B | <- . -> |repl B  | clean B | close B 
        #---------+---------+--------+---------+--------

        grid.addWidget(destLabel, 1, 0)
        grid.addWidget(self.destcombo, 1, 2)

        #grid.addWidget(layerLabel, 2, 0)
        grid.addWidget(lgLabel, 2, 0)
        grid.addWidget(self.lgcombo, 2, 2)
        
        grid.addWidget(confLabel, 3, 0)
        grid.addWidget(self.confcombo, 3, 2)
        
        #grid.addWidget(groupLabel, 4, 0)
        #grid.addWidget(self.groupEdit, 4, 2)
        
        grid.addWidget(epsgLabel, 5, 0)
        grid.addWidget(self.epsgenable, 5, 1)
        grid.addWidget(self.epsgcombo, 5, 2)

        grid.addWidget(fromDateLabel, 6, 0)
        grid.addWidget(self.fromdateenable, 6, 1)
        grid.addWidget(self.fromdateedit, 6, 2)
        
        grid.addWidget(toDateLabel, 7, 0)
        grid.addWidget(self.todateenable, 7, 1)
        grid.addWidget(self.todateedit, 7, 2)
        
        hbox3 = QHBoxLayout()
        hbox3.addWidget(self.view) 
        hbox3.addStretch(1)
        hbox3.addWidget(self.progressbar)

        #hbox3.addLayout(vbox2)
        #hbox3.addLayout(vbox3)
        
        hbox4 = QHBoxLayout()
        hbox4.addWidget(self.initbutton)
        hbox4.addStretch(1)
        hbox4.addWidget(self.replicatebutton)
        hbox4.addWidget(self.cleanbutton)
        hbox4.addWidget(self.cancelbutton)
        

        vbox = QVBoxLayout()
        #vbox.addStretch(1)
        vbox.addLayout(grid)
        vbox.addLayout(hbox3)
        vbox.addLayout(hbox4)
        
        self.setLayout(vbox)  
       
    #def setProgress(self,pct):
    #    self.progressbar.setValue(pct)
        
    def setStatus(self,status,message='',tooltip=None):
        '''Sets indicator icon and statusbar message'''
        self.parent.statusbar.showMessage(message)
        self.parent.statusbar.setToolTip(tooltip if tooltip else '')

        #progress
        loc = os.path.abspath(os.path.join(IMG_LOC,self.imgset[status]))
        #loc = os.path.abspath(os.path.join(os.path.dirname(__file__),self.parent.IMG_LOC,self.imgset[status]))
        self.progressbar.setVisible(status in (self.STATUS.BUSY, self.STATUS.CLEAN))
        
        #icon
        anim = QMovie(loc, QByteArray(), self)
        anim.setScaledSize(QSize(self.IMG_WIDTH,self.IMG_HEIGHT))
        anim.setCacheMode(QMovie.CacheAll)
        anim.setSpeed(self.IMG_SPEED)
        self.view.clear()
        self.view.setMovie(anim)
        anim.start()

        self.view.repaint()
        QApplication.processEvents(QEventLoop.AllEvents)

    def mainWindowEnable(self,enable=True):
        cons = (self.lgcombo, self.confcombo, self.destcombo, 
                self.initbutton, self.replicatebutton, self.cleanbutton, self.cancelbutton,
                self.epsgenable,self.fromdateenable,self.todateenable,
                self.parent.menubar)
        for c in cons:
            c.setEnabled(enable)
            
        if enable:
            self.epsgcombo.setEnabled(self.epsgenable.checkState())
            self.fromdateedit.setEnabled(self.fromdateenable.checkState())
            self.todateedit.setEnabled(self.todateenable.checkState())
        else:
            self.epsgcombo.setEnabled(False)
            self.fromdateedit.setEnabled(False)
            self.todateedit.setEnabled(False)
   
        QApplication.restoreOverrideCursor() if enable else QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 

    def refreshLGCombo(self):
        '''Re index LG combobox since a refreshLG call (new dest?) will usually mean new groups'''
        self.lgcombo.clear()
        self.lgcombo.addItems([i[2] for i in self.parent.confconn.lglist])
        #NOTE the separator consumes an index, if not clearing the combobox selectively remove the old sepindex (assumes g preceeds l)
        #if self.sepindex:
        #    self.lgcombo.removeItem(self.sepindex)
        self.sepindex = [i[0] for i in self.parent.confconn.lglist].count(LORG.GROUP)
        self.lgcombo.insertSeparator(self.sepindex)
        
    def updateLGValues(self,uconf,lgval,dest):
        '''Sets the values displayed in the Layer/Group combo'''
        #because we cant seem to sort combobox entries and want groups at the top, clear and re-add
        #TRACE#        
        #pdb.set_trace()
        sf = None
        try:
            self.parent.confconn.initConnections(uconf,lgval,dest)
        except Exception as e:
            sf=1
            ldslog.error('Error Updating UC Values. '+str(e))
            
        if sf:
            self.setStatus(self.STATUS.ERROR,'Error Updating UC Values', str(e))
        else:
            self.setStatus(self.STATUS.IDLE)
            
        self.refreshLGCombo()
        
    def centre(self):
        
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())
        
    
    def gprParameters(self,rdest):
        '''Zip default and GPR values'''
        return [x if LU.assessNone(x) else y for x,y in zip(self.parent.gpr.readsec(rdest),self.parent.DEF_RVALS[1:])]
    
    def getLCE(self,ln):
        '''Read layer parameters'''
        dep = self.parent.confconn.reg.openEndPoint(self.parent.confconn.destname,self.parent.confconn.uconf)
        #sep = self.parent.confconn.reg.openEndPoint('WFS',self.parent.confconn.uconf)
        self.parent.confconn.reg.setupLayerConfig(self.parent.confconn.tp,None,dep,initlc=False)
        lce = dep.getLayerConf().readLayerParameters(ln)
        #self.parent.confconn.reg.closeEndPoint('WFS')
        self.parent.confconn.reg.closeEndPoint(self.parent.confconn.destname)
        sep,dep = None,None
        return lce
    
    
    def doDestChanged(self):
        '''Read the destname parameter and fill dialog with matching GPR values'''
        rdest = str(self.destlist[self.destcombo.currentIndex()])
        rvals = self.gprParameters(rdest)
        self.updateGUIValues([rdest]+rvals)    
        
        
    def doConfChanged(self):
        '''Read the user conf parameter and fill dialog with matching GPR values'''
        rdest = str(self.destlist[self.destcombo.currentIndex()])
        rlg,_,rep,rfd,rtd = self.gprParameters(rdest)
        ruc = str(self.cflist[self.confcombo.currentIndex()])
        self.updateGUIValues((rdest,rlg,ruc,rep,rfd,rtd))
        
        
    def doLGComboChanged(self):
        '''Read the layer/group value and change epsg to layer or gpr match'''
        #get a matching LG entry and test whether its a layer or group
        #lgi = self.parent.confconn.getLayerGroupIndex(self.lgcombo.currentText().toUtf8().data())
        lgi = self.parent.confconn.getLayerGroupIndex(LQ.readWidgetText(self.lgcombo.currentText()))
        #lgi can be none if we init a new group, in which case we use the GPR value
        if lgi:
            lge = self.parent.confconn.lglist[lgi]
            lce = self.getLCE(lge[1]) if lge[0]==LORG.LAYER else None
        else:
            lce = None
        
        #look for filled layer conf epsg OR use prefs stored in gpr
        if lce and LU.assessNone(lce.epsg):
            epsgval = lce.epsg
        else:
            rdest = str(self.destlist[self.destcombo.currentIndex()])
            _,_,epsgval,_,_ = self.gprParameters(rdest)
        epsgindex = [i[0] for i in self.nzlsr+[(0,0)]+self.rowsr].index(epsgval)
        if self.epsgcombo.currentIndex() != epsgindex:
            self.epsgcombo.setCurrentIndex(int(epsgindex))

        
    def updateGUIValues(self,readlist):
        '''Fill dialog values from provided list'''
        #TODO. Remove circular references when setCurrentIndex() triggers do###Changed()
        #Read user input
        rdest,self.rlgval,ruconf,repsg,rfd,rtd = readlist
        
        #--------------------------------------------------------------------
        
        #Destination Menu
        selecteddest = LU.standardiseDriverNames(rdest)
        if selecteddest not in self.destlist:
            self.destlist = self.getConfiguredDestinations()
            self.destcombo.addItem(selecteddest)
        destindex = self.destlist.index(selecteddest) if selecteddest else 0
        
        if self.destcombo.currentIndex() != destindex:
            self.destcombo.setCurrentIndex(destindex)
        
        #InitButton
        self.initbutton.setText('Layer Select')
        
        #Config File
        confindex = 0
        if LU.assessNone(ruconf):
            ruconf = ruconf.split('.')[0]
            if ruconf not in self.cflist:
                self.cflist += [ruconf,]
                self.confcombo.addItem(ruconf)
            confindex = self.cflist.index(ruconf)
            
        if self.confcombo.currentIndex() != confindex:
            self.confcombo.setCurrentIndex(confindex)
        #self.confEdit.setText(ruconf if LU.assessNone(ruconf) else '')
        
        #Layer/Group Selection
        self.updateLGValues(ruconf,self.rlgval,rdest)
        lgindex = None
        if LU.assessNone(self.rlgval):
            #index of list value
            lgindex = self.parent.confconn.getLayerGroupIndex(self.rlgval,col=1)
            
        if LU.assessNone(lgindex):
            #advance by 1 for sep
            lgindex += 1 if lgindex>self.sepindex else 0 
        else:
            #using the separator index sets the combo to blank
            lgindex = self.sepindex
        if self.lgcombo.currentIndex() != lgindex:
            self.lgcombo.setCurrentIndex(lgindex)
        #self.doLGEditUpdate()
        
        #EPSG
        #                                user > layerconf
        #useepsg = LU.precedence(repsg, lce.epsg if lce else None, None)
        epsgindex = [i[0] for i in self.nzlsr+[(None,None)]+self.rowsr].index(repsg)
        if self.epsgcombo.currentIndex() != epsgindex:
            self.epsgcombo.setCurrentIndex(epsgindex)
            
        #epsgedit = self.epsgcombo.lineEdit()
        #epsgedit.setText([e[1] for e in self.nzlsr+self.rowsr if e[0]==repsg][0])
        
        #epsgedit.setText([e for e in self.nzlsr+self.rowsr if re.match('^\s*(\d+).*',e).group(1)==repsg][0])
        
        #To/From Dates
        if LU.assessNone(rfd):
            self.fromdateedit.setDate(QDate(int(rfd[0:4]),int(rfd[5:7]),int(rfd[8:10])))
        else:
            early = DataStore.EARLIEST_INIT_DATE
            self.fromdateedit.setDate(QDate(int(early[0:4]),int(early[5:7]),int(early[8:10])))
            
        if LU.assessNone(rtd):
            self.todateedit.setDate(QDate(int(rtd[0:4]),int(rtd[5:7]),int(rtd[8:10]))) 
        else:
            today = DataStore.getCurrent()
            self.todateedit.setDate(QDate(int(today[0:4]),int(today[5:7]),int(today[8:10])))
            
        #Internal/External CheckBox
#        if LU.assessNone(rint):
#            self.internalTrigger.setChecked(rint.lower()==DataStore.CONF_INT)
#        else:
#            self.internalTrigger.setChecked(DataStore.DEFAULT_CONF==DataStore.CONF_INT)
        
        
    def getConfiguredDestinations(self):
        defml = ['',]+DataStore.DRIVER_NAMES.values()
        return [d for d in self.parent.gpr.getDestinations() if d in defml]
        
    def doEPSGEnable(self):
        self.epsgcombo.setEnabled(self.epsgenable.isChecked())
        
    def doFromDateEnable(self):
        self.fromdateedit.setEnabled(self.fromdateenable.isChecked())
          
    def doToDateEnable(self):
        self.todateedit.setEnabled(self.todateenable.isChecked())  
          
    def readParameters(self):
        '''Read values out of dialogs'''
        destination = LU.assessNone(str(self.destlist[self.destcombo.currentIndex()]))
        #lgindex = self.parent.confconn.getLayerGroupIndex(self.lgcombo.currentText().toUtf8().data())
        lgindex = self.parent.confconn.getLayerGroupIndex(LQ.readWidgetText(self.lgcombo.currentText()))
        #NB need to test for None explicitly since zero is a valid index
        lgval = self.parent.confconn.lglist[lgindex][1] if LU.assessNone(lgindex) else None       
        #uconf = LU.standardiseUserConfigName(str(self.confcombo.lineEdit().text()))
        #uconf = str(self.confcombo.lineEdit().text())
        uconf = str(self.cflist[self.confcombo.currentIndex()])
        ee = self.epsgenable.isChecked()
        epsg = None if ee is False else re.match('^\s*(\d+).*',str(self.epsgcombo.lineEdit().text())).group(1)
        fe = self.fromdateenable.isChecked()
        te = self.todateenable.isChecked()
        fd = None if fe is False else str(self.fromdateedit.date().toString('yyyy-MM-dd'))
        td = None if te is False else str(self.todateedit.date().toString('yyyy-MM-dd'))
        
        return destination,lgval,uconf,epsg,fe,te,fd,td
    
    def doInitClickAction(self):
        '''Initialise the LC on LC-button-click, action'''
        try:
            try:
                self.setStatus(self.STATUS.BUSY,'Opening Layer-Config Editor')  
                self.progressbar.setValue(0)
                self.parent.runLayerConfigAction()
            finally:
                self.setStatus(self.STATUS.IDLE,'Ready')
        except Exception as e:
            self.setStatus(self.STATUS.ERROR,'Error in Layer-Config',str(sys.exc_info()))#e))
        
    def doCleanClickAction(self):
        '''Set clean anim and run clean'''
        #lgo = self.lgcombo.currentText().toUtf8().data()
        lgo = LQ.readWidgetText(self.lgcombo.currentText())
        
        try:
            self.setStatus(self.STATUS.CLEAN,'Running Clean '+lgo)
            self.progressbar.setValue(0)
            self.runReplicationScript(True)
        except Exception as e:
            self.setStatus(self.STATUS.ERROR,'Failed Clean of '+lgo,str(sys.exc_info()))#e))
        
    def doReplicateClickAction(self):
        '''Set busy anim and run repl'''
        lgo = self.lgcombo.currentText()#.toUtf8().data()#only used for error messages
        try:
            self.setStatus(self.STATUS.BUSY,'Running Replicate '+lgo)
            self.progressbar.setValue(0)
            self.runReplicationScript(False)
        except Exception as e:
            self.setStatus(self.STATUS.ERROR,'Failed Replication of '+lgo,str(sys.exc_info()))#e))

    def runReplicationScript(self,clean=False):
        '''Run the layer/group repliction script'''
        destination,lgval,uconf,epsg,fe,te,fd,td = self.readParameters()
        uconf_path = LU.standardiseUserConfigName(uconf)
        destination_path = LU.standardiseLayerConfigName(destination)
        destination_driver = LU.standardiseDriverNames(destination)

        if not os.path.exists(uconf_path):
            self.userConfMessage(uconf_path)
            return
        elif not MainFileReader(uconf_path).hasSection(destination_driver):
            self.userConfMessage(uconf_path,destination_driver)
            return
        #-----------------------------------------------------
        #'destname','layer','uconf','group','epsg','fd','td','int'
     
        self.parent.gpr.write((destination_driver,lgval,uconf,epsg,fd,td))        
        ldslog.info(u'dest={0}, lg={1}, conf={2}, epsg={3}'.format(destination_driver,lgval,uconf,epsg))
        ldslog.info('fd={0}, td={1}, fe={2}, te={3}'.format(fd,td,fe,te))
        lgindex = self.parent.confconn.getLayerGroupIndex(lgval,col=1)
        #lorg = self.parent.confconn.lglist[lgindex][0]
        #----------don't need lorg in TP anymore but it is useful for sorting/counting groups
        #self.parent.confconn.tp.setLayerOrGroup(lorg)
        self.parent.confconn.tp.setLayerGroupValue(lgval)
        if self.fromdateenable.isChecked(): self.parent.confconn.tp.setFromDate(fd)
        if self.todateenable.isChecked(): self.parent.confconn.tp.setToDate(td)
        self.parent.confconn.tp.setUserConf(uconf)
        if self.epsgenable: self.parent.confconn.tp.setEPSG(epsg)
        
        #because clean state persists in TP
        if clean:
            self.parent.confconn.tp.setCleanConfig()
        else:
            self.parent.confconn.tp.clearCleanConfig()
        #(re)initialise the data source since uconf may have changed
        #>>#self.parent.confconn.tp.src = self.parent.confconn.initSourceWrapper()
        #--------------------------
        ###ep = self.parent.confconn.reg.openEndPoint(self.parent.confconn.destname,self.parent.confconn.uconf)
        
        ###self.parent.confconn.reg.closeEndPoint(self.parent.confconn.destname)
        ###ep = None
        #Open ProcessRunner and run with TP(proc)/self(gui) instances
        #HACK temp add of dest_drv to PR call
        try:
            #TODO. Test for valid LC first
            self.tpr = ProcessRunner(self,destination_driver)
        except Exception as e:
            ldslog.error('Cannot create ProcessRunner {}. NB Possible missing Layer Config {}'.format(str(e),destination_path))
            self.layerConfMessage(destination_path)
            return
        #If PR has been successfully created we must vave a valid dst    
        self.tpr.start()
        
    def quitProcessRunner(self):
        self.tpr.join()
        self.tpr.quit()
        self.trp = None

        
    def userConfMessage(self,uconf,secname=None):
        ucans = QMessageBox.warning(self, 'User Config Missing/Incomplete', 
                                'Specified User-Config file, '+str(uconf)+' does not exist' if secname is None else 'User-Config file does not contain '+str(secname)+' section', 
                                'Back','Initialise User Config')
        if not ucans:
            #Retry
            ldslog.warn('Retry specifying UC')
            #self.confcombo.setCurrentIndex(0)
            return
        #Init
        ldslog.warn('Reset User Config Wizard')
        self.parent.runWizardAction()


    def layerConfMessage(self,dest):
        lcans = QMessageBox.warning(self, 'Layer Config Missing', 
                                'Required Layer-Config file, '+str(dest)+' does not exist', 
                                'Back','Run Layer Select')
        if not lcans:
            #Retry
            ldslog.warn('Retry specifying LC')
            #self.destcombo.setCurrentIndex(0)
            return
        #Init
        ldslog.warn('Reset Layer Config')
        self.doInitClickAction()
Exemplo n.º 48
0
 def getWidgetFromParameter(self, param):
     if isinstance(param, ParameterRaster):
         item = QComboBox()
         layers = self.getAvailableValuesOfType(ParameterRaster, OutputRaster)
         if param.optional:
             item.addItem(self.NOT_SELECTED, None)
         for layer in layers:
             item.addItem(self.resolveValueDescription(layer), layer)
     elif isinstance(param, ParameterVector):
         item = QComboBox()
         layers = self.getAvailableValuesOfType(ParameterVector, OutputVector)
         if param.optional:
             item.addItem(self.NOT_SELECTED, None)
         for layer in layers:
             item.addItem(self.resolveValueDescription(layer), layer)
     elif isinstance(param, ParameterTable):
         item = QComboBox()
         tables = self.getAvailableValuesOfType(ParameterTable, OutputTable)
         layers = self.getAvailableValuesOfType(ParameterVector, OutputVector)
         if param.optional:
             item.addItem(self.NOT_SELECTED, None)
         for table in tables:
             item.addItem(self.resolveValueDescription(table), table)
         for layer in layers:
             item.addItem(self.resolveValueDescription(layer), layer)
     elif isinstance(param, ParameterBoolean):
         item = QComboBox()
         item.addItem('Yes')
         item.addItem('No')
         bools = self.getAvailableValuesOfType(ParameterBoolean, None)
         for b in bools:
             item.addItem(self.resolveValueDescription(b), b)
     elif isinstance(param, ParameterSelection):
         item = QComboBox()
         item.addItems(param.options)
         item.setCurrentIndex(param.default)
     elif isinstance(param, ParameterFixedTable):
         item = FixedTablePanel(param)
     elif isinstance(param, ParameterRange):
         item = RangePanel(param)
     elif isinstance(param, ParameterMultipleInput):
         if param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY:
             options = self.getAvailableValuesOfType(ParameterVector, OutputVector)
         else:
             options = self.getAvailableValuesOfType(ParameterRaster, OutputRaster)
         opts = []
         for opt in options:
             opts.append(self.resolveValueDescription(opt))
         item = MultipleInputPanel(opts)
     elif isinstance(param, ParameterString):
         strings = self.getAvailableValuesOfType(ParameterString, OutputString)
         options = [(self.resolveValueDescription(s), s) for s in strings]
         if param.multiline:
             item = MultilineTextPanel(options)
             item.setText(unicode(param.default))
         else:
             item = QComboBox()
             item.setEditable(True)
             for desc, val in options:
                 item.addItem(desc, val)
             item.setEditText(unicode(param.default))
     elif isinstance(param, ParameterTableField):
         item = QComboBox()
         item.setEditable(True)
         fields = self.getAvailableValuesOfType(ParameterTableField, None)
         for f in fields:
             item.addItem(self.resolveValueDescription(f), f)
     elif isinstance(param, ParameterNumber):
         item = QComboBox()
         item.setEditable(True)
         numbers = self.getAvailableValuesOfType(ParameterNumber, OutputNumber)
         for n in numbers:
             item.addItem(self.resolveValueDescription(n), n)
         item.setEditText(unicode(param.default))
     elif isinstance(param, ParameterCrs):
         item = CrsSelectionPanel(param.default)
     elif isinstance(param, ParameterExtent):
         item = QComboBox()
         item.setEditable(True)
         extents = self.getAvailableValuesOfType(ParameterExtent, OutputExtent)
         if self.canUseAutoExtent():
             item.addItem(self.USE_MIN_COVERING_EXTENT, None)
         for ex in extents:
             item.addItem(self.resolveValueDescription(ex), ex)
         if not self.canUseAutoExtent():
             item.setEditText(unicode(param.default))
     elif isinstance(param, ParameterFile):
         item = QComboBox()
         item.setEditable(True)
         files = self.getAvailableValuesOfType(ParameterFile, OutputFile)
         for f in files:
             item.addItem(self.resolveValueDescription(f), f)
     elif isinstance(param, ParameterGeometryPredicate):
         item = GeometryPredicateSelectionPanel(param.enabledPredicates)
     else:
         item = QLineEdit()
         try:
             item.setText(unicode(param.default))
         except:
             pass
     return item
Exemplo n.º 49
0
class GearEntriesFrame(QFrame):
  read_block = pyqtSignal(int, int)  # start_addr, num_bytes
  poke_block = pyqtSignal(int, QByteArray, bool)  # start_addr, raw_bytes, is_ascii
  log = pyqtSignal(str, str)  # msg, color

  MISSING_SKILL_NAME = '[NOT IN DB]'

  def __init__(self, addr_start, addr_end, class_label, skill2id, id2skill, parent=None):
    super(GearEntriesFrame, self).__init__(parent)
    self.addr_start = addr_start
    self.addr_end = addr_end
    self.max_num_slots = (addr_end - addr_start) / 6 / 4 + 1
    self.class_label = class_label
    self.skill2id = skill2id
    self.id2skill = id2skill

    self.skill_names = self.skill2id.keys()
    self.skill_names.sort()

    self.slots_cache = []  # list of raw 6*4 bytes
    self.slots_txt = None
    self.cur_slot_idx = -1
    self.cur_slot_bytes = None

    self.lbl_label = QLabel(self.class_label, self)

    self.btn_read_slots = QPushButton(' Cache Slots', self)
    self.btn_read_slots.setIcon(QIcon('img/flaticon/data110.png'))
    self.btn_read_slots.setStyleSheet('background-color: white')
    self.btn_read_slots.clicked.connect(self.onReadSlots)

    self.cmb_slots = QComboBox(self)
    self.cmb_slots.setToolTip('')
    self.cmb_slots.setStyleSheet('background-color: white')
    self.cmb_slots.currentIndexChanged[str].connect(self.onChangeSlot)
    self.cmb_slots.setDisabled(True)

    self.btn_read = QPushButton(self)
    self.btn_read.setIcon(QIcon('img/flaticon/open135.png'))
    self.btn_read.setToolTip('Read item slot value from memory')
    self.btn_read.setStyleSheet('background-color: white')
    self.btn_read.clicked.connect(self.onReadSlot)

    self.txt_raw = QLineEdit(self)
    self.txt_raw.setPlaceholderText('Raw hex data')
    self.txt_raw.setMaxLength(8 * 6 + 5)
    self.txt_raw.editingFinished.connect(self.onChangeRaw)

    self.btn_poke = QPushButton(self)
    self.btn_poke.setIcon(QIcon('img/flaticon/draw39.png'))
    self.btn_poke.setToolTip('Poke new value for item slot')
    self.btn_poke.setStyleSheet('background-color: white')
    self.btn_poke.clicked.connect(self.onPokeSlot)

    self.cmb_skills_a = QComboBox(self)
    self.cmb_skills_a.setEditable(True)
    self.cmb_skills_a.addItems(self.skill_names)
    self.cmb_skills_a.lineEdit().setText(GearEntriesFrame.MISSING_SKILL_NAME)
    self.cmb_skills_a.currentIndexChanged[str].connect(self.onChangeSkillA)

    self.cmb_skills_b = QComboBox(self)
    self.cmb_skills_b.setEditable(True)
    self.cmb_skills_b.addItems(self.skill_names)
    self.cmb_skills_b.lineEdit().setText(GearEntriesFrame.MISSING_SKILL_NAME)
    self.cmb_skills_b.currentIndexChanged[str].connect(self.onChangeSkillB)

    self.cmb_skills_c = QComboBox(self)
    self.cmb_skills_c.setEditable(True)
    self.cmb_skills_c.addItems(self.skill_names)
    self.cmb_skills_c.lineEdit().setText(GearEntriesFrame.MISSING_SKILL_NAME)
    self.cmb_skills_c.currentIndexChanged[str].connect(self.onChangeSkillC)

    incr_labels = []
    for incr in xrange(16):
      incr_labels.append('+%d' % incr)

    self.cmb_incr_a = QComboBox(self)
    self.cmb_incr_a.addItems(incr_labels)
    self.cmb_incr_a.currentIndexChanged[int].connect(self.onChangeIncrA)

    self.cmb_incr_b = QComboBox(self)
    self.cmb_incr_b.addItems(incr_labels)
    self.cmb_incr_b.currentIndexChanged[int].connect(self.onChangeIncrB)

    self.cmb_incr_c = QComboBox(self)
    self.cmb_incr_c.addItems(incr_labels)
    self.cmb_incr_c.currentIndexChanged[int].connect(self.onChangeIncrC)

    slot_labels = []
    for incr in xrange(4):
      slot_labels.append('%d Augment Slots' % incr)

    self.cmb_augments = QComboBox(self)
    self.cmb_augments.addItems(slot_labels)
    self.cmb_augments.currentIndexChanged[int].connect(self.onChangeAugments)

    self.layout = QGridLayout(self)
    self.layout.addWidget(self.lbl_label, 0, 0)
    self.layout.addWidget(self.btn_read_slots, 0, 1)
    self.layout.addWidget(self.cmb_slots, 0, 2)
    self.layout.addWidget(self.btn_read, 0, 3)
    self.layout.addWidget(self.txt_raw, 1, 0, 1, 3)
    self.layout.addWidget(self.btn_poke, 1, 3)
    self.layout.addWidget(self.cmb_skills_a, 2, 0)
    self.layout.addWidget(self.cmb_incr_a, 2, 1)
    self.layout.addWidget(self.cmb_skills_b, 3, 0)
    self.layout.addWidget(self.cmb_incr_b, 3, 1)
    self.layout.addWidget(self.cmb_skills_c, 4, 0)
    self.layout.addWidget(self.cmb_incr_c, 4, 1)
    self.layout.addWidget(self.cmb_augments, 2, 2)

    self.layout.setColumnStretch(0, 7)
    self.layout.setColumnStretch(1, 3)
    self.layout.setColumnStretch(2, 3)
    self.layout.setColumnStretch(3, 1)
    self.layout.setContentsMargins(0, 2, 0, 2)

    icon_height = self.lbl_label.height() * 8 / 15
    icon_size = QSize(icon_height, icon_height)
    self.btn_read_slots.setIconSize(icon_size)
    self.btn_read.setIconSize(icon_size)
    self.btn_poke.setIconSize(icon_size)
    btn_size = QSize(icon_height * 1.5, icon_height * 1.5)
    self.btn_read.setFixedSize(btn_size)
    self.btn_poke.setFixedSize(btn_size)

    self.updateUI()

  def updateUI(self):
    # Disable editing if cache missing
    if not (0 <= self.cur_slot_idx < len(self.slots_cache)) or self.cur_slot_bytes is None:
      self.cur_slot_idx = -1
      self.cur_slot_bytes = None
      self.cmb_slots.setDisabled(True)
      self.cmb_skills_a.setDisabled(True)
      self.cmb_skills_b.setDisabled(True)
      self.cmb_skills_c.setDisabled(True)
      self.cmb_incr_a.setDisabled(True)
      self.cmb_incr_b.setDisabled(True)
      self.cmb_incr_c.setDisabled(True)
      self.cmb_augments.setDisabled(True)
      self.txt_raw.setDisabled(True)
      return
    else:
      self.cmb_slots.setDisabled(False)
      self.cmb_skills_a.setDisabled(False)
      self.cmb_skills_b.setDisabled(False)
      self.cmb_skills_c.setDisabled(False)
      self.cmb_incr_a.setDisabled(False)
      self.cmb_incr_b.setDisabled(False)
      self.cmb_incr_c.setDisabled(False)
      self.cmb_augments.setDisabled(False)
      self.txt_raw.setDisabled(False)

    # Validate current slot's raw bytes
    try:
      (gear_id_bytes, index, post_index, skill_a_id, skill_a_incr, skill_b_id, skill_b_incr,
       skill_c_id, skill_c_incr, augment_a_id, augment_b_id, augment_c_id) = parse_gear_bytes(self.cur_slot_bytes)
      cur_slot_words = struct.unpack('>IIIIII', self.cur_slot_bytes)
      num_augments = (augment_a_id != 0xFFFF) + (augment_b_id != 0xFFFF) + (augment_c_id != 0xFFFF)
    except ValueError, e:
      self.log.emit('Gear parsing failed: %s' % e.what(), 'red')
      return

    # Update UI
    self.txt_raw.setDisabled(False)
    self.txt_raw.editingFinished.disconnect()
    self.txt_raw.setText('%08X %08X %08X %08X %08X %08X' % cur_slot_words)
    self.txt_raw.editingFinished.connect(self.onChangeRaw)

    self.cmb_skills_a.setDisabled(False)
    self.cmb_skills_a.currentIndexChanged[str].disconnect()
    try:
      skill_name = self.id2skill[skill_a_id]
      skill_idx = self.skill_names.index(skill_name)
      self.cmb_skills_a.setCurrentIndex(skill_idx)
    except (KeyError, ValueError):
      self.cmb_skills_a.lineEdit().setText(GearEntriesFrame.MISSING_SKILL_NAME)
    self.cmb_skills_a.currentIndexChanged[str].connect(self.onChangeSkillA)

    self.cmb_skills_b.setDisabled(False)
    self.cmb_skills_b.currentIndexChanged[str].disconnect()
    try:
      skill_name = self.id2skill[skill_b_id]
      skill_idx = self.skill_names.index(skill_name)
      self.cmb_skills_b.setCurrentIndex(skill_idx)
    except (KeyError, ValueError):
      self.cmb_skills_b.lineEdit().setText(GearEntriesFrame.MISSING_SKILL_NAME)
    self.cmb_skills_b.currentIndexChanged[str].connect(self.onChangeSkillB)

    self.cmb_skills_c.setDisabled(False)
    self.cmb_skills_c.currentIndexChanged[str].disconnect()
    try:
      skill_name = self.id2skill[skill_c_id]
      skill_idx = self.skill_names.index(skill_name)
      self.cmb_skills_c.setCurrentIndex(skill_idx)
    except (KeyError, ValueError):
      self.cmb_skills_c.lineEdit().setText(GearEntriesFrame.MISSING_SKILL_NAME)
    self.cmb_skills_c.currentIndexChanged[str].connect(self.onChangeSkillC)

    self.cmb_incr_a.setDisabled(False)
    self.cmb_incr_a.currentIndexChanged[int].disconnect()
    self.cmb_incr_a.setCurrentIndex(skill_a_incr)
    self.cmb_incr_a.currentIndexChanged[int].connect(self.onChangeIncrA)

    self.cmb_incr_b.setDisabled(False)
    self.cmb_incr_b.currentIndexChanged[int].disconnect()
    self.cmb_incr_b.setCurrentIndex(skill_b_incr)
    self.cmb_incr_b.currentIndexChanged[int].connect(self.onChangeIncrB)

    self.cmb_incr_c.setDisabled(False)
    self.cmb_incr_c.currentIndexChanged[int].disconnect()
    self.cmb_incr_c.setCurrentIndex(skill_c_incr)
    self.cmb_incr_c.currentIndexChanged[int].connect(self.onChangeIncrC)

    self.cmb_augments.setDisabled(False)
    self.cmb_augments.currentIndexChanged[int].disconnect()
    self.cmb_augments.setCurrentIndex(num_augments)
    self.cmb_augments.currentIndexChanged[int].connect(self.onChangeAugments)
Exemplo n.º 50
0
class FindInFilesDialog(QDialog):
    def __init__(self, result_widget, parent):
        QDialog.__init__(self, parent)
        self._find_thread = FindInFilesThread()
        self.setWindowTitle("Find in files")
        self.resize(400, 300)
        #MAIN LAYOUT
        main_vbox = QVBoxLayout(self)

        self.pattern_line_edit = QLineEdit()
        self.dir_name_root = None
        self.user_home = os.path.expanduser('~')
        self.dir_combo = QComboBox()
        self.dir_combo.addItem(self.user_home)
        self.dir_combo.setEditable(True)
        self.open_button = QPushButton(QIcon(resources.IMAGES['find']),
                                       self.tr("Open"))
        self.filters_line_edit = QLineEdit("*.py")
        self.replace_line = QLineEdit()
        self.replace_line.setEnabled(False)
        self.check_replace = QCheckBox(self.tr("Replace: "))
        self.case_checkbox = QCheckBox(self.tr("C&ase sensitive"))
        self.type_checkbox = QCheckBox(self.tr("R&egular Expression"))
        self.recursive_checkbox = QCheckBox(self.tr("Rec&ursive"))
        self.recursive_checkbox.setCheckState(Qt.Checked)
        self.phrase_radio = QRadioButton(
            self.tr("Search by Phrase (Exact Match)."))
        self.phrase_radio.setChecked(True)
        self.words_radio = QRadioButton(
            self.tr("Search for all the words "
                    "(anywhere in the document, not together)."))
        self.find_button = QPushButton(self.tr("Find!"))
        self.find_button.setMaximumWidth(150)
        self.cancel_button = QPushButton(self.tr("Cancel"))
        self.cancel_button.setMaximumWidth(150)
        self.result_widget = result_widget

        hbox = QHBoxLayout()
        hbox.addWidget(self.find_button)
        hbox.addWidget(self.cancel_button)

        #main section
        find_group_box = QGroupBox(self.tr("Main"))
        grid = QGridLayout()
        grid.addWidget(QLabel(self.tr("Text: ")), 0, 0)
        grid.addWidget(self.pattern_line_edit, 0, 1)
        grid.addWidget(QLabel(self.tr("Directory: ")), 1, 0)
        grid.addWidget(self.dir_combo, 1, 1)
        grid.addWidget(self.open_button, 1, 2)
        grid.addWidget(QLabel(self.tr("Filter: ")), 2, 0)
        grid.addWidget(self.filters_line_edit, 2, 1)
        grid.addWidget(self.check_replace, 3, 0)
        grid.addWidget(self.replace_line, 3, 1)

        find_group_box.setLayout(grid)
        #add main section to MAIN LAYOUT
        main_vbox.addWidget(find_group_box)

        #options sections
        options_group_box = QGroupBox(self.tr("Options"))
        gridOptions = QGridLayout()
        gridOptions.addWidget(self.case_checkbox, 0, 0)
        gridOptions.addWidget(self.type_checkbox, 1, 0)
        gridOptions.addWidget(self.recursive_checkbox, 2, 0)
        gridOptions.addWidget(self.phrase_radio, 0, 1)
        gridOptions.addWidget(self.words_radio, 1, 1)

        options_group_box.setLayout(gridOptions)
        #add options sections to MAIN LAYOUT
        main_vbox.addWidget(options_group_box)

        #add buttons to MAIN LAYOUT
        main_vbox.addLayout(hbox)

        #Focus
        self.pattern_line_edit.setFocus()
        self.open_button.setFocusPolicy(Qt.NoFocus)

        #signal
        self.connect(self.open_button, SIGNAL("clicked()"), self._select_dir)
        self.connect(self.find_button, SIGNAL("clicked()"),
                     self._find_in_files)
        self.connect(self.cancel_button, SIGNAL("clicked()"),
                     self._kill_thread)
        self.connect(self._find_thread, SIGNAL("found_pattern(PyQt_PyObject)"),
                     self._found_match)
        self.connect(self._find_thread, SIGNAL("finished()"),
                     self._find_thread_finished)
        self.connect(self.type_checkbox, SIGNAL("stateChanged(int)"),
                     self._change_radio_enabled)
        self.connect(self.check_replace, SIGNAL("stateChanged(int)"),
                     self._replace_activated)
        self.connect(self.words_radio, SIGNAL("clicked(bool)"),
                     self._words_radio_pressed)

    def _replace_activated(self):
        self.replace_line.setEnabled(self.check_replace.isChecked())
        self.phrase_radio.setChecked(True)

    def _words_radio_pressed(self, value):
        self.replace_line.setEnabled(not value)
        self.check_replace.setChecked(not value)
        self.words_radio.setChecked(True)

    def _change_radio_enabled(self, val):
        enabled = not self.type_checkbox.isChecked()
        self.phrase_radio.setEnabled(enabled)
        self.words_radio.setEnabled(enabled)

    def show(self, actual_project=None, actual=None):
        self.dir_combo.clear()
        self.dir_name_root = actual_project if \
            actual_project else [self.user_home]
        self.dir_combo.addItems(self.dir_name_root)
        if actual:
            index = self.dir_combo.findText(actual)
            self.dir_combo.setCurrentIndex(index)
        super(FindInFilesDialog, self).show()
        self.pattern_line_edit.setFocus()

    def reject(self):
        self._kill_thread()
        # Crazy hack to avoid circular imports
        self.result_widget.parent().parent().parent().hide()
        super(FindInFilesDialog, self).reject()

    def _find_thread_finished(self):
        self.emit(SIGNAL("finished()"))
        self._find_thread.wait()

    def _select_dir(self):
        dir_name = QFileDialog.getExistingDirectory(
            self, self.tr("Open Directory"), self.dir_combo.currentText(),
            QFileDialog.ShowDirsOnly)
        index = self.dir_combo.findText(dir_name)
        if index >= 0:
            self.dir_combo.setCurrentIndex(index)
        else:
            self.dir_combo.insertItem(0, dir_name)
            self.dir_combo.setCurrentIndex(0)

    def _found_match(self, result):
        file_name = result[0]
        items = result[1]
        self.result_widget.update_result(self.dir_combo.currentText(),
                                         file_name, items)

    def _kill_thread(self):
        if self._find_thread.isRunning():
            self._find_thread.cancel()
        self.accept()

    def _find_in_files(self):
        self.emit(SIGNAL("findStarted()"))
        self._kill_thread()
        self.result_widget.clear()
        pattern = self.pattern_line_edit.text()
        dir_name = self.dir_combo.currentText()

        filters = re.split("[,;]", self.filters_line_edit.text())

        # Version of PyQt API 1
        # filters = self.filters_line_edit.text().split(QRegExp("[,;]"),
        #     QString.SkipEmptyParts)

        #remove the spaces in the words Ex. (" *.foo"--> "*.foo")
        filters = [f.strip() for f in filters]
        case_sensitive = self.case_checkbox.isChecked()
        type_ = QRegExp.RegExp if \
            self.type_checkbox.isChecked() else QRegExp.FixedString
        recursive = self.recursive_checkbox.isChecked()
        by_phrase = True
        if self.phrase_radio.isChecked() or self.type_checkbox.isChecked():
            regExp = QRegExp(pattern, case_sensitive, type_)
        elif self.words_radio.isChecked():
            by_phrase = False
            type_ = QRegExp.RegExp
            pattern = '|'.join([word.strip() for word in pattern.split()])
            regExp = QRegExp(pattern, case_sensitive, type_)
        #save a reference to the root directory where we find
        self.dir_name_root = dir_name
        self._find_thread.find_in_files(dir_name, filters, regExp, recursive,
                                        by_phrase)
Exemplo n.º 51
0
class ItemEntriesFrame(QFrame):
    read_block = pyqtSignal(int, int)  # start_addr, num_bytes
    poke_block = pyqtSignal(int, QByteArray,
                            bool)  # start_addr, raw_bytes, is_ascii
    log = pyqtSignal(str, str)  # msg, color

    MISSING_ITEM_NAME = '[NOT IN DB]'

    def __init__(self,
                 type_val,
                 addr_start,
                 addr_end,
                 label,
                 id2name,
                 idx2id,
                 names,
                 parent=None):
        super(ItemEntriesFrame, self).__init__(parent)
        self.type_val = type_val
        self.code_offset = 0
        self.addr_start = addr_start
        self.addr_end = addr_end
        self.max_num_slots = (addr_end - addr_start) / 3 / 4 + 1
        self.label = label
        self.id2name = id2name
        self.idx2id = idx2id
        self.names = names

        self.slots_cache = [
        ]  # tuple: (addr_hex, addr_val, slot_number, cur_val)
        self.cur_slot_idx = -1

        self.lbl_label = QLabel(self.label, self)

        self.btn_read_slots = QPushButton(' Cache Slots', self)
        self.btn_read_slots.setIcon(QIcon('img/flaticon/data110.png'))
        self.btn_read_slots.setStyleSheet('background-color: white')
        self.btn_read_slots.clicked.connect(self.onReadSlots)

        self.btn_search_cache = QPushButton(' Search ID', self)
        self.btn_search_cache.setIcon(QIcon('img/flaticon/magnifier13.png'))
        self.btn_search_cache.setToolTip(
            'Find slot in cache with specified item ID')
        self.btn_search_cache.setStyleSheet('background-color: white')
        self.btn_search_cache.clicked.connect(self.onSearchCacheForID)

        self.btn_read = QPushButton(self)
        self.btn_read.setIcon(QIcon('img/flaticon/open135.png'))
        self.btn_read.setToolTip('Read item slot value from memory')
        self.btn_read.setStyleSheet('background-color: white')
        self.btn_read.clicked.connect(self.onReadSlot)

        self.cmb_slots = QComboBox(self)
        self.cmb_slots.setStyleSheet('background-color: white')
        self.cmb_slots.currentIndexChanged[int].connect(self.onChangeSlot)
        self.cmb_slots.setDisabled(True)

        self.cmb_names = QComboBox(self)
        self.cmb_names.setEditable(True)
        self.cmb_names.addItems(self.names)
        self.cmb_names.lineEdit().setText(ItemEntriesFrame.MISSING_ITEM_NAME)
        self.cmb_names.currentIndexChanged[int].connect(self.fetchID)

        self.txt_id = QLineEdit(self)
        self.txt_id.setPlaceholderText('ID (hex)')
        self.txt_id.setMaxLength(3)
        self.txt_id.textChanged.connect(self.fetchName)

        self.btn_rename = QPushButton(' Fix Name', self)
        self.btn_rename.setIcon(QIcon('img/flaticon/cloud-storage3.png'))
        self.btn_rename.setToolTip(
            'Add/Correct Item Name for %s (type: %02X)' %
            (self.label, type_val))
        self.btn_rename.setStyleSheet('background-color: white')
        self.btn_rename.clicked.connect(self.onRename)

        self.txt_amount = QLineEdit(self)
        self.txt_amount.setPlaceholderText('Amount')
        self.txt_amount.setMaxLength(3)

        self.btn_poke = QPushButton(self)
        self.btn_poke.setIcon(QIcon('img/flaticon/draw39.png'))
        self.btn_poke.setToolTip('Poke new value for item slot')
        self.btn_poke.setStyleSheet('background-color: white')
        self.btn_poke.clicked.connect(self.onPokeSlot)

        self.layout = QGridLayout(self)
        self.layout.addWidget(self.lbl_label, 0, 0)
        self.layout.addWidget(self.btn_read_slots, 0, 1)
        self.layout.addWidget(self.btn_search_cache, 0, 2)
        self.layout.addWidget(self.cmb_slots, 0, 3)
        self.layout.addWidget(self.btn_read, 0, 4)
        self.layout.addWidget(self.cmb_names, 1, 0)
        self.layout.addWidget(self.txt_id, 1, 1)
        self.layout.addWidget(self.btn_rename, 1, 2)
        self.layout.addWidget(self.txt_amount, 1, 3)
        self.layout.addWidget(self.btn_poke, 1, 4)

        self.layout.setColumnStretch(0, 7)
        self.layout.setColumnStretch(1, 3)
        self.layout.setColumnStretch(2, 3)
        self.layout.setColumnStretch(3, 3)
        self.layout.setColumnStretch(4, 1)
        self.layout.setContentsMargins(0, 2, 0, 2)

        icon_height = self.lbl_label.height() * 8 / 15
        icon_size = QSize(icon_height, icon_height)
        self.btn_read_slots.setIconSize(icon_size)
        self.btn_search_cache.setIconSize(icon_size)
        self.btn_rename.setIconSize(icon_size)
        self.btn_read.setIconSize(icon_size)
        self.btn_poke.setIconSize(icon_size)
        btn_size = QSize(icon_height * 1.5, icon_height * 1.5)
        self.btn_read.setFixedSize(btn_size)
        self.btn_poke.setFixedSize(btn_size)

        self.updateUI()

    def updateUI(self):
        # Disable editing if cache missing
        if not (0 <= self.cur_slot_idx < len(self.slots_cache)):
            self.cmb_names.lineEdit().setText(
                ItemEntriesFrame.MISSING_ITEM_NAME)
            self.cmb_names.setDisabled(True)
            self.txt_id.setText('')
            self.txt_id.setDisabled(True)
            return

        # Validate current value
        cur_val = self.slots_cache[self.cur_slot_idx][3]
        (type_val, id_val, amount) = parse_item_word(cur_val)
        if type_val != self.type_val and type_val != 0:
            cur_addr = self.slots_cache[
                self.cur_slot_idx][1] + self.code_offset
            self.log.emit(
                'Cache error: val(0x%08X)=%08X, type (%02X) != expected (%02X)'
                % (cur_addr, cur_val, type_val, self.type_val), 'red')
            return

        # Update UI
        self.txt_id.setDisabled(False)
        self.txt_id.setText('%03X' % id_val)
        self.cmb_names.setDisabled(False)
        self.fetchName()
        self.txt_amount.setText(str(amount))

    def setAlternateBGColor(self):
        self.setStyleSheet(
            'ItemEntriesFrame { background-color:rgb(248,248,248) }')

    @pyqtSlot(int)
    def onSetCodeOffset(self, signed_offset):
        self.code_offset = signed_offset

    @pyqtSlot()
    def onRename(self):
        id_txt = str(self.txt_id.text())
        if len(id_txt) != 3:
            return
        dialog = FixItemNameDialog('%02X' % self.type_val, id_txt, self)
        dialog.log.connect(self.log)
        dialog.exec_()

    @pyqtSlot()
    def onReadSlots(self):
        self.read_block.emit(self.addr_start + self.code_offset,
                             self.max_num_slots * 4 * 3)

    @pyqtSlot(int, int, QByteArray)
    def onBlockRead(self, addr_start_w_code_offset, num_bytes, raw_bytes):
        # Determine whether block has cache or single slot
        if (addr_start_w_code_offset == (self.addr_start + self.code_offset)
            ) and (num_bytes == self.max_num_slots * 4 * 3):
            self.onCacheRead(addr_start_w_code_offset, raw_bytes)
        elif num_bytes == 4:  # Assume read slot
            # Ignore if no cache
            if not (0 <= self.cur_slot_idx < len(self.slots_cache)):
                return
            self.onSlotRead(addr_start_w_code_offset, raw_bytes)

    def onCacheRead(self, addr_start_w_code_offset, raw_bytes):
        slot_bytes = str(raw_bytes)
        self.slots_cache = []
        slots_txt = []
        for slot_i in xrange(self.max_num_slots):
            byte_offset = slot_i * 3 * 4
            cur_slot_bytes = slot_bytes[byte_offset:(byte_offset + 4)]
            if len(cur_slot_bytes) != 4:
                continue
            cur_slot_val = struct.unpack('>I', cur_slot_bytes)[0]
            (type_val, id_val, amount) = parse_item_word(cur_slot_val)
            if type_val == 0 or amount == 0:
                continue
            elif type_val != self.type_val:
                self.log.emit(
                    'val(%08X)=%08X, type_val(%02X) unexpected(%02X)' %
                    (addr_start_w_code_offset + byte_offset, cur_slot_val,
                     type_val, self.type_val), 'red')
                continue
            else:
                addr_val = addr_start_w_code_offset + byte_offset - self.code_offset  # remove code_offset since it may change later
                addr_hex = '%08X' % addr_val
                slot_number = slot_i + 1
                self.slots_cache.append(
                    (addr_hex, addr_val, slot_number, cur_slot_val))
                slots_txt.append('Slot %03d' % slot_number)

        # Update UI
        self.log.emit(
            'Found %d %s slots in memory' %
            (len(self.slots_cache), self.label), 'black')
        self.cmb_slots.clear()
        if len(self.slots_cache) <= 0:
            self.cmb_slots.setDisabled(True)
            self.cur_slot_idx = -1
        else:
            self.cmb_slots.setDisabled(False)
            self.cmb_slots.addItems(slots_txt)
            self.cur_slot_idx = 0
        self.updateUI()

    def onSlotRead(self, addr_word_w_code_offset, raw_bytes):
        addr_cur_slot = self.slots_cache[
            self.cur_slot_idx][1] + self.code_offset
        if addr_word_w_code_offset == addr_cur_slot:
            cur_cache = self.slots_cache[self.cur_slot_idx]
            new_val = struct.unpack('>I', str(raw_bytes))[0]
            new_cache = (cur_cache[0], cur_cache[1], cur_cache[2], new_val)
            self.slots_cache[self.cur_slot_idx] = new_cache
            self.updateUI()
        else:  # Update cached value of other slots
            addr_first_slot = self.slots_cache[0][1] + self.code_offset
            addr_last_slot = self.slots_cache[-1][1] + self.code_offset
            if (addr_first_slot <= addr_word_w_code_offset <= addr_last_slot) and \
               ((addr_word_w_code_offset - addr_first_slot) % 12 == 0):
                for slot_i in xrange(len(self.slots_cache)):
                    addr_cur_slot = self.slots_cache[slot_i][
                        1] + self.code_offset
                    if addr_word_w_code_offset == addr_cur_slot:
                        cur_cache = self.slots_cache[slot_i]
                        new_val = struct.unpack('>I', str(raw_bytes))[0]
                        new_cache = (cur_cache[0], cur_cache[1], cur_cache[2],
                                     new_val)
                        self.slots_cache[slot_i] = new_cache
                        return

    @pyqtSlot()
    def onSearchCacheForID(self):
        # Stop if no cache
        if not (0 <= self.cur_slot_idx < len(self.slots_cache)):
            self.log.emit('Must cache slots before searching', 'red')
            return

        # Fetch and validate target ID
        try:
            target_id_val = int(str(self.txt_id.text()), 16)
            if target_id_val < 0 or target_id_val > Item.MAX_ID_VAL:
                self.log.emit('Item ID out of [0, 0x%03X] range' %
                              Item.MAX_ID_VAL)
                return
        except ValueError:
            self.log.emit('Failed to parse item ID, expecting XXX', 'red')
            return

        # Search ID in cache
        for cand_slot_idx in xrange(len(self.slots_cache)):
            (type_val, id_val,
             amount) = parse_item_word(self.slots_cache[cand_slot_idx][3])
            if id_val == target_id_val and type_val == self.type_val:
                self.cur_slot_idx = cand_slot_idx
                self.cmb_slots.setCurrentIndex(self.cur_slot_idx)
                self.updateUI()
                return
        self.log.emit(
            'Did not find ID=%03X in %d cached %s slots' %
            (target_id_val, len(self.slots_cache), self.label), 'red')

    @pyqtSlot(int)
    def onChangeSlot(self, new_slot_idx):
        # Validate new_slot_idx
        if not (0 <= new_slot_idx < len(self.slots_cache)):
            return

        # Update slot idx and read value from memory
        self.cur_slot_idx = new_slot_idx
        self.cmb_names.lineEdit().setText(ItemEntriesFrame.MISSING_ITEM_NAME)
        self.cmb_names.setDisabled(True)
        self.txt_id.setText('')
        self.txt_id.setDisabled(True)
        self.onReadSlot()

    @pyqtSlot()
    def fetchName(self):
        try:
            id_val = int(str(self.txt_id.text()), 16)
        except ValueError:
            return
        name = self.MISSING_ITEM_NAME
        if id_val in self.id2name:
            name = self.id2name[id_val]
        self.cmb_names.lineEdit().setText(name)

    @pyqtSlot(int)
    def fetchID(self, cmb_idx):
        if cmb_idx < 0 or cmb_idx >= len(self.idx2id):
            self.txt_id.setText('')
        else:
            self.txt_id.setText(self.idx2id[cmb_idx])

    @pyqtSlot()
    def onReadSlot(self):
        try:
            if not (0 <= self.cur_slot_idx < len(self.slots_cache)):
                raise ValueError('must cache slots before reading')
            addr_cur_slot = self.slots_cache[
                self.cur_slot_idx][1] + self.code_offset
            self.read_block.emit(addr_cur_slot, 4)
        except ValueError, e:
            cur_slot_num = self.slots_cache[self.cur_slot_idx][2]
            self.log.emit(
                'READ %s Slot %03d failed: %s' %
                (self.label, cur_slot_num, str(e)), 'red')
        except BaseException, e:
            cur_slot_num = self.slots_cache[self.cur_slot_idx][2]
            self.log.emit(
                'READ %s Slot %03d failed: %s' %
                (self.label, cur_slot_num, str(e)), 'red')
            traceback.print_exc()
Exemplo n.º 52
0
    def _init_layout(self):
        """
        Create the GUI widgets (but leave them empty).
        """
        hostname_combobox = QComboBox(parent=self)
        self._hostname_combobox = hostname_combobox
        hostname_combobox.setEditable(True)
        hostname_combobox.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Maximum)
        hostname_combobox.installEventFilter(self)
        for hostname in self._suggested_hostnames:
            hostname_combobox.addItem(hostname)

        self._connect_button = QPushButton("Connect",
                                           parent=self,
                                           clicked=self._handle_new_hostname)

        hostname_layout = QHBoxLayout()
        hostname_layout.addWidget(hostname_combobox)
        hostname_layout.addWidget(self._connect_button)

        hostname_groupbox = QGroupBox("DVID Host", parent=self)
        hostname_groupbox.setLayout(hostname_layout)
        hostname_groupbox.setSizePolicy(QSizePolicy.Preferred,
                                        QSizePolicy.Maximum)

        data_treewidget = QTreeWidget(parent=self)
        data_treewidget.setHeaderLabels(
            ["Data"])  # TODO: Add type, shape, axes, etc.
        data_treewidget.setSizePolicy(QSizePolicy.Preferred,
                                      QSizePolicy.Preferred)
        data_treewidget.itemSelectionChanged.connect(
            self._handle_data_selection)

        data_layout = QVBoxLayout()
        data_layout.addWidget(data_treewidget)
        data_groupbox = QGroupBox("Data Volumes", parent=self)
        data_groupbox.setLayout(data_layout)

        node_listwidget = QListWidget(parent=self)
        node_listwidget.setSizePolicy(QSizePolicy.Preferred,
                                      QSizePolicy.Preferred)
        node_listwidget.itemSelectionChanged.connect(self._update_display)

        node_layout = QVBoxLayout()
        node_layout.addWidget(node_listwidget)
        node_groupbox = QGroupBox("Nodes", parent=self)
        node_groupbox.setLayout(node_layout)

        new_data_edit = QLineEdit(parent=self)
        new_data_edit.textEdited.connect(self._update_display)
        full_url_label = QLabel(parent=self)
        full_url_label.setSizePolicy(QSizePolicy.Preferred,
                                     QSizePolicy.Maximum)
        text_flags = full_url_label.textInteractionFlags()
        full_url_label.setTextInteractionFlags(text_flags
                                               | Qt.TextSelectableByMouse)

        new_data_layout = QVBoxLayout()
        new_data_layout.addWidget(new_data_edit)
        new_data_groupbox = QGroupBox("New Data Volume", parent=self)
        new_data_groupbox.setLayout(new_data_layout)
        new_data_groupbox.setSizePolicy(QSizePolicy.Preferred,
                                        QSizePolicy.Maximum)

        buttonbox = QDialogButtonBox(Qt.Horizontal, parent=self)
        buttonbox.setStandardButtons(QDialogButtonBox.Ok
                                     | QDialogButtonBox.Cancel)
        buttonbox.accepted.connect(self.accept)
        buttonbox.rejected.connect(self.reject)
        buttonbox.button(QDialogButtonBox.Ok).setEnabled(False)

        layout = QVBoxLayout()
        layout.addWidget(hostname_groupbox)
        layout.addWidget(data_groupbox)
        layout.addWidget(node_groupbox)
        if self._mode == "specify_new":
            layout.addWidget(new_data_groupbox)
        else:
            new_data_groupbox.hide()
        layout.addWidget(full_url_label)
        layout.addWidget(buttonbox)

        # Stretch factors
        layout.setStretchFactor(data_groupbox, 3)
        layout.setStretchFactor(node_groupbox, 1)

        self.setLayout(layout)
        self.setWindowTitle("Select DVID Volume")

        # Initially disabled
        data_groupbox.setEnabled(False)
        node_groupbox.setEnabled(False)
        new_data_groupbox.setEnabled(False)

        # Save instance members
        self._data_groupbox = data_groupbox
        self._node_groupbox = node_groupbox
        self._new_data_groupbox = new_data_groupbox
        self._data_treewidget = data_treewidget
        self._node_listwidget = node_listwidget
        self._new_data_edit = new_data_edit
        self._full_url_label = full_url_label
        self._buttonbox = buttonbox
Exemplo n.º 53
0
class mainUI(QWidget):

    def __init__(self):
        super(mainUI, self).__init__()
        self.btn_browse = QPushButton('Browse',self)
        self.btn_run = QPushButton('Run',self)
        self.lvd_dd = QComboBox(self)
        self.lvsub_dd = QComboBox(self)
        self.lid_dd = QComboBox(self)
        self.lisub_dd = QComboBox(self)
        self.lvd = QLabel('Vd' ,self)
        self.lvsub = QLabel('Vsub', self)
        self.lid = QLabel('Id', self)
        self.lisub = QLabel('Isub', self)
        self.la_vd = QLabel('Step', self)
        self.ln_vd_step = QLineEdit(self)
        self.initUI()

    def initUI(self):
        self.btn_browse.move(60,20)
        self.btn_browse.clicked.connect(self.showFolderDialog)

        self.btn_run.move(60,220)
        self.btn_run.clicked.connect(self.run)
        self.btn_run.setEnabled(False)

        self.lvd.move(38, 64)
        self.lvd_dd.setEditable(True)
        self.lvd_dd.addItems('none x y'.split())
        self.lvd_dd.move(60, 60)

        self.la_vd.move(150, 64)
        self.ln_vd_step.move(180, 60)
        self.ln_vd_step.resize(50,20)

        self.lvsub.move(38, 104)
        self.lvsub_dd.setEditable(True)
        self.lvsub_dd.addItems('none x y'.split())
        self.lvsub_dd.move(60, 100)

        self.lid.move(38, 144)
        self.lid_dd.setEditable(True)
        self.lid_dd.addItems('none x y'.split())
        self.lid_dd.move(60, 140)

        self.lisub.move(38, 184)
        self.lisub_dd.setEditable(True)
        self.lisub_dd.addItems('none x y'.split())
        self.lisub_dd.move(60, 180)

        # self.btn_save = QPushButton('Save', self)
        # self.btn_save.move(60, 100)
        # self.btn_save.clicked.connect(self.save)
        # self.btn_save.setEnabled(False)

        self.setGeometry(300,300,300,260)
        self.setWindowTitle('SnapBack')
        self.show()

    def showFolderDialog(self):
        global filelist
        index = 0
        basex = 60
        basey = 60
        try:
            filelist = QFileDialog.getOpenFileNames(self,'Select Files')
            self.btn_run.setEnabled(True)
            # print(os.path.dirname(os.path.realpath(filelist[0])))
            os.chdir(os.path.dirname(os.path.realpath(filelist[0])))
            # self.chk = QCheckBox('test',self)
            # self.chk.move(basex, basey)
            # self.chk.toggle()
            # self.show()
            # for item in filelist:
            #     basey = basey + (index + 1) * 40
                # self.addchkbox(item, basex, basey)
            # self.update()
            # print(filelist)
        except:
            print(sys.exc_info()[0])

    # def addchkbox(self, item, basex, basey):
    #     base = os.path.basename(item)
    #     l = os.path.splitext(base)[0]
    #     chk = QCheckBox(l,self)
    #     chk.move(basex, basey)
    #     chk.toggle()
        # print(basex)
        # print(basey)

    def run(self):
        global filelist
        # print(filelist)
        # newlist = list(map(self.xtr_plot,filelist))
        if filelist == []:
            QMessageBox.information(self,'Warning', 'Nothing to plot')
            return
        elif self.ln_vd_step.text() == '':
            QMessageBox.information(self, 'Warning', 'Please input step')
            return
        else:
            l_plot = []
            c_plot = []
            if self.lvd_dd.currentText() != 'none':
                l_plot.append('V3')
                c_plot.append(self.lvd_dd.currentText())
            if self.lid_dd.currentText() != 'none':
                l_plot.append('I3')
                c_plot.append(self.lid_dd.currentText())
            if self.lvsub_dd.currentText() != 'none':
                l_plot.append('V1')
                c_plot.append(self.lvsub_dd.currentText())
            if self.lisub_dd.currentText() != 'none':
                l_plot.append('I1')
                c_plot.append(self.lisub_dd.currentText())
            # print(l_plot)
            plt.ion()
            # fig = plt.figure()
            # ax = fig.add_subplot(111)
            # ax.minorticks_on()
            # ax.set_title("Id Vs Vd")
            # ax.set_xlabel('Vd(V)')
            # ax.set_ylabel('Id(A)')
            # ax.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.2e'))
            # ax.xaxis.set_minor_formatter(mtick.FormatStrFormatter('%.2f'))
            # ax.xaxis.set_minor_locator(mtick.AutoMinorLocator(2))
            # ax.yaxis.set_minor_formatter(mtick.FormatStrFormatter('%.2e'))
            # ax.yaxis.set_minor_locator(mtick.AutoMinorLocator(2))
            #
            # ax.grid(b=True, which='major', color='black', linestyle='-')
            # ax.grid(b=True, which='minor', color='r', linestyle='--')
            # i = 1
            for file in filelist:
                self.xtr_plot(file, l_plot, c_plot)
                # i = i + 1
            # plt.legend()
            # plt.show()
            # print(newlist)
            # self.btn_save.setEnabled(True)
            filelist = []
            return

    def closeEvent(self, QCloseEvent):
        plt.ioff()
        plt.close()
        QApplication.quit()
        sys.exit()

    def xtr_plot(self, item, l_plot, c_plot):
        # print(item)
        data1 = []
        i = 0
        with open(item) as f:
            data = f.read()
        data = data.split('\n')
        # print(data)
        for x in data:
            # if i > 2:
            data1.append(x)
            # i += 1
        i = 0
        while True:
            if '' in data1:
                data1.remove('')
            else:
                break
        del data[:]
        temp = []
        for i in range(0,len(data1)):
            if "NO." in data1[0]:
                temp = data1[0].split('\t')
                del data1[0:2]
                break
            else:
                data1.remove(data1[0])
        x = []
        y = []
        y.append([])
        y.append([])
        for s in l_plot:
            i = temp.index(s)
            # print(i)
            if s == 'V3':
                x = [row.split("\t")[i] for row in data1]
            elif s == 'V1':
                x = [row.split("\t")[i] for row in data1]
            elif s == 'I3':
                y[0] = [row.split("\t")[i] for row in data1]
            elif s == 'I1':
                y[1] = [row.split("\t")[i] for row in data1]
        i = 0

        for s in x:
            s = s.replace("V","")
            s = s.replace(" ","")
            if "f" in s:
                s = s.replace("f","")
                num = float(s)/1000000000000000
            elif "p" in s:
                s = s.replace("p","")
                num = float(s)/1000000000000
            elif "n" in s:
                s = s.replace("n","")
                num = float(s)/1000000000
            elif "u" in s:
                s = s.replace("u","")
                num = float(s)/1000000
            elif "m" in s:
                s = s.replace("m","")
                num = float(s)/1000
            else:
                num = float(s)
            x[i] = num
            i += 1
        # print(x)
        i = 0
        m = 0
        for s in y:
            # print(s)
            if s != []:
                for s1 in s:
                    s1 = s1.replace("A","")
                    s1 = s1.replace(" ","")
                    if "f" in s1:
                        s1 = s1.replace("f","")
                        num = float(s1)/1000000000000000
                    elif "p" in s1:
                        s1 = s1.replace("p","")
                        num = float(s1)/1000000000000
                    elif "n" in s1:
                        s1 = s1.replace("n","")
                        num = float(s1)/1000000000
                    elif "u" in s1:
                        s1 = s1.replace("u","")
                        num = float(s1)/1000000
                    elif "m" in s1:
                        s1 = s1.replace("m","")
                        num = float(s1)/1000
                    else:
                        num = float(s1)
                    y[m][i] = num
                    i += 1
                i = 0
            # print(m)
            # print(y[m])
            m += 1
        i = 0
        m = 0
        base = os.path.basename(item)
        l = os.path.splitext(base)[0]
        l = l.replace('T','')
        w_title = ' '.join(['Vg =', str(int(l)-1),'V'])
        # # print(Vd)
        # # print(Id)
        # print(y[0])
        # print(y[1])
        index = len(x)
        step = int(self.ln_vd_step.text())
        Vsub_step = 100
        cols = 5
        nrows = math.ceil(index/step/5)
        fig, ax = plt.subplots(nrows, cols)
        fig.canvas.set_window_title(w_title)
        ax_row = 0
        ax_col = 0
        max_I = max(y[0])
        if max_I < max(y[1]):
            max_I = max(y[1])
        min_I = min(y[0])
        if min_I > min(y[1]):
            min_I = min(y[0])
        max_V = max(x)
        min_V = min(x)
        Vsub = 0
        while True:
            # ax[ax_row][ax_col] = fig.add_subplot(111)
            # ax[ax_row][ax_col].minorticks_on()
            # ax[ax_row][ax_col].set_title("Id Vs Vd")
            ax[ax_row][ax_col].set_xlabel('Vd(V)')
            ax[ax_row][ax_col].set_ylabel('I(A)')
            ax[ax_row][ax_col].yaxis.set_major_formatter(mtick.FormatStrFormatter('%.2e'))
            # ax[ax_row][ax_col].xaxis.set_minor_formatter(mtick.FormatStrFormatter('%.2f'))
            # ax[ax_row][ax_col].xaxis.set_minor_locator(mtick.AutoMinorLocator(2))
            # ax[ax_row][ax_col].yaxis.set_minor_formatter(mtick.FormatStrFormatter('%.2e'))
            # ax[ax_row][ax_col].yaxis.set_minor_locator(mtick.AutoMinorLocator(2))

            # ax[ax_row][ax_col].grid(b=True, which='major', color='black', linestyle='--')
            # ax[ax_row][ax_col].grid(b=True, which='minor', color='red', linestyle='--')
            m += step
            x_temp = x[i:m]
            ax[ax_row][ax_col].set_autoscale_on(False)
            title = ' '.join(['Vsub=', str(Vsub/1000), 'V'])
            ax[ax_row][ax_col].set_title(title)
            if y[0] != []:
                y_temp = y[0][i:m]
                ax[ax_row][ax_col].plot(x_temp, y_temp, color='red',label='Id')
                # ax[ax_row][ax_col].plot(x_temp, y_temp)
                ax[ax_row][ax_col].set_ylim([min_I*1.1, max_I*1.1])
                ax[ax_row][ax_col].set_xlim([min_V, max_V*1.1])
            if y[1] != []:
                y_temp = y[1][i:m]
                ax[ax_row][ax_col].plot(x_temp, y_temp, color='green',label='Isub')
                # ax[ax_row][ax_col].plot(x_temp, y_temp)
                ax[ax_row][ax_col].set_ylim([min_I*1.1, max_I*1.1])
                ax[ax_row][ax_col].set_xlim([min_V, max_V*1.1])
            # plt.legend()
            ax[ax_row][ax_col].legend(prop={'size':10})
            plt.show()
            i = m
            ax_col += 1
            Vsub += Vsub_step
            if ax_col >= cols:
                ax_col = 0
                ax_row += 1
            if i >= index:
                break
Exemplo n.º 54
0
class FindInFilesDialog(QDialog):

    """Dialog to configure and trigger the search in the files."""

    def __init__(self, result_widget, parent):
        super(FindInFilesDialog, self).__init__(parent)
        self._find_thread = FindInFilesThread()
        self.setWindowTitle(translations.TR_FIND_IN_FILES)
        self.resize(400, 300)
        #MAIN LAYOUT
        main_vbox = QVBoxLayout(self)

        self.pattern_line_edit = QLineEdit()
        self.pattern_line_edit.setPlaceholderText(translations.TR_FIND + "...")
        self.dir_name_root = None
        self.user_home = os.path.expanduser('~')
        self.dir_combo = QComboBox()
        self.dir_combo.addItem(self.user_home)
        self.dir_combo.setEditable(True)
        self.open_button = QPushButton(QIcon(":img/find"), translations.TR_OPEN)
        self.filters_line_edit = QLineEdit("*.py")
        self.filters_line_edit.setPlaceholderText("*.py")
        self.filters_line_edit.setCompleter(QCompleter(
            ["*{}".format(item) for item in settings.SUPPORTED_EXTENSIONS]))
        self.replace_line = QLineEdit()
        self.replace_line.setEnabled(False)
        self.replace_line.setPlaceholderText(
            translations.TR_TEXT_FOR_REPLACE + "...")
        self.check_replace = QCheckBox(translations.TR_REPLACE)
        self.case_checkbox = QCheckBox(translations.TR_CASE_SENSITIVE)
        self.type_checkbox = QCheckBox(translations.TR_REGULAR_EXPRESSION)
        self.recursive_checkbox = QCheckBox(translations.TR_RECURSIVE)
        self.recursive_checkbox.setCheckState(Qt.Checked)
        self.phrase_radio = QRadioButton(translations.TR_SEARCH_BY_PHRASE)
        self.phrase_radio.setChecked(True)
        self.words_radio = QRadioButton(
            translations.TR_SEARCH_FOR_ALL_THE_WORDS)
        self.find_button = QPushButton(translations.TR_FIND + "!")
        self.find_button.setMaximumWidth(150)
        self.cancel_button = QPushButton(translations.TR_CANCEL)
        self.cancel_button.setMaximumWidth(150)
        self.result_widget = result_widget

        hbox = QHBoxLayout()
        hbox.addWidget(self.find_button)
        hbox.addWidget(self.cancel_button)

        #main section
        find_group_box = QGroupBox(translations.TR_MAIN)
        grid = QGridLayout()
        grid.addWidget(QLabel(translations.TR_TEXT), 0, 0)
        grid.addWidget(self.pattern_line_edit, 0, 1)
        grid.addWidget(QLabel(translations.TR_DIRECTORY), 1, 0)
        grid.addWidget(self.dir_combo, 1, 1)
        grid.addWidget(self.open_button, 1, 2)
        grid.addWidget(QLabel(translations.TR_FILTER), 2, 0)
        grid.addWidget(self.filters_line_edit, 2, 1)
        grid.addWidget(self.check_replace, 3, 0)
        grid.addWidget(self.replace_line, 3, 1)

        find_group_box.setLayout(grid)
        #add main section to MAIN LAYOUT
        main_vbox.addWidget(find_group_box)

        #options sections
        options_group_box = QGroupBox(translations.TR_OPTIONS)
        gridOptions = QGridLayout()
        gridOptions.addWidget(self.case_checkbox, 0, 0)
        gridOptions.addWidget(self.type_checkbox, 1, 0)
        gridOptions.addWidget(self.recursive_checkbox, 2, 0)
        gridOptions.addWidget(self.phrase_radio, 0, 1)
        gridOptions.addWidget(self.words_radio, 1, 1)

        options_group_box.setLayout(gridOptions)
        #add options sections to MAIN LAYOUT
        main_vbox.addWidget(options_group_box)

        #add buttons to MAIN LAYOUT
        main_vbox.addLayout(hbox)

        #Focus
        self.pattern_line_edit.setFocus()
        self.open_button.setFocusPolicy(Qt.NoFocus)

        #signal
        self.connect(self.open_button, SIGNAL("clicked()"), self._select_dir)
        self.connect(self.find_button, SIGNAL("clicked()"),
            self._find_in_files)
        self.connect(self.cancel_button, SIGNAL("clicked()"),
            self._kill_thread)
        self.connect(self._find_thread, SIGNAL("found_pattern(PyQt_PyObject)"),
            self._found_match)
        self.connect(self._find_thread, SIGNAL("finished()"),
            self._find_thread_finished)
        self.connect(self.type_checkbox, SIGNAL("stateChanged(int)"),
            self._change_radio_enabled)
        self.connect(self.check_replace, SIGNAL("stateChanged(int)"),
            self._replace_activated)
        self.connect(self.words_radio, SIGNAL("clicked(bool)"),
            self._words_radio_pressed)

    def _replace_activated(self):
        """If replace is activated, display the replace widgets."""
        self.replace_line.setEnabled(self.check_replace.isChecked())
        self.phrase_radio.setChecked(True)

    def _words_radio_pressed(self, value):
        """If search by independent words is activated, replace is not."""
        self.replace_line.setEnabled(not value)
        self.check_replace.setChecked(not value)
        self.words_radio.setChecked(True)

    def _change_radio_enabled(self, val):
        """Control the state of the radio buttons."""
        enabled = not self.type_checkbox.isChecked()
        self.phrase_radio.setEnabled(enabled)
        self.words_radio.setEnabled(enabled)

    def show(self, actual_project=None, actual=None):
        """Display the dialog and load the projects."""
        self.dir_combo.clear()
        self.dir_name_root = actual_project if \
            actual_project else [self.user_home]
        self.dir_combo.addItems(self.dir_name_root)
        if actual:
            index = self.dir_combo.findText(actual)
            self.dir_combo.setCurrentIndex(index)
        super(FindInFilesDialog, self).show()
        self.pattern_line_edit.setFocus()

    def reject(self):
        """Close the dialog and hide the tools dock."""
        self._kill_thread()
        tools_dock = IDE.get_service('tools_dock')
        if tools_dock:
            tools_dock.hide()
        super(FindInFilesDialog, self).reject()

    def _find_thread_finished(self):
        """Wait on thread finished."""
        self.emit(SIGNAL("finished()"))
        self._find_thread.wait()

    def _select_dir(self):
        """When a new folder is selected, add to the combo if needed."""
        dir_name = QFileDialog.getExistingDirectory(self, translations.TR_OPEN,
            self.dir_combo.currentText(),
            QFileDialog.ShowDirsOnly)
        index = self.dir_combo.findText(dir_name)
        if index >= 0:
            self.dir_combo.setCurrentIndex(index)
        else:
            self.dir_combo.insertItem(0, dir_name)
            self.dir_combo.setCurrentIndex(0)

    def _found_match(self, result):
        """Update the tree for each match found."""
        file_name = result[0]
        items = result[1]
        self.result_widget.update_result(
            self.dir_combo.currentText(), file_name, items)

    def _kill_thread(self):
        """Kill the thread."""
        if self._find_thread.isRunning():
            self._find_thread.cancel()
        self.accept()

    def _find_in_files(self):
        """Trigger the search on the files."""
        self.emit(SIGNAL("findStarted()"))
        self._kill_thread()
        self.result_widget.clear()
        pattern = self.pattern_line_edit.text()
        dir_name = self.dir_combo.currentText()

        filters = re.split("[,;]", self.filters_line_edit.text())

        #remove the spaces in the words Ex. (" *.foo"--> "*.foo")
        filters = [f.strip() for f in filters]
        case_sensitive = self.case_checkbox.isChecked()
        type_ = QRegExp.RegExp if \
            self.type_checkbox.isChecked() else QRegExp.FixedString
        recursive = self.recursive_checkbox.isChecked()
        by_phrase = True
        if self.phrase_radio.isChecked() or self.type_checkbox.isChecked():
            regExp = QRegExp(pattern, case_sensitive, type_)
        elif self.words_radio.isChecked():
            by_phrase = False
            type_ = QRegExp.RegExp
            pattern = '|'.join(
                [word.strip() for word in pattern.split()])
            regExp = QRegExp(pattern, case_sensitive, type_)
        #save a reference to the root directory where we find
        self.dir_name_root = dir_name
        self._find_thread.find_in_files(dir_name, filters, regExp, recursive,
            by_phrase)
Exemplo n.º 55
0
class SVDViewPanel(QWidget):
    svdSelectEvent = QtCore.pyqtSignal()

    axis_re = re.compile(r"^Axis (\d+)$")
    def __init__(self):
        QWidget.__init__(self)
        self.layout = QGridLayout(self)
        self.viewer = None
        
        self.x_label = QLabel("X axis:")
        self.x_chooser = QComboBox()
        self.x_chooser.setEditable(True)
        self.y_label = QLabel("Y axis:")
        self.y_chooser = QComboBox()
        self.y_chooser.setEditable(True)
        # TODO: add completers
        self.nav_reset = QPushButton("&Reset view")

        self.layout.addWidget(self.x_label, 1, 0)
        self.layout.addWidget(self.x_chooser, 1, 1)
        self.layout.addWidget(self.y_label, 1, 3)
        self.layout.addWidget(self.y_chooser, 1, 4)
        self.layout.addWidget(self.nav_reset, 1, 6)
        self.layout.setColumnStretch(1, 1)
        self.layout.setColumnStretch(4, 1)
        self.layout.setRowStretch(0, 1)

        self.nav_reset.clicked.connect(self.reset_view)
        self.x_chooser.currentIndexChanged['QString'].connect(self.set_x_from_string)
        self.y_chooser.currentIndexChanged['QString'].connect(self.set_y_from_string)
    
        self.x_chooser.activated['QString'].connect(self.set_x_from_string)
    
    def activate(self, docs, projections, magnitudes, canonical):
        self.deactivate()
        self.viewer = SVDViewer.make_svdview(docs, projections, magnitudes, canonical)
        self.layout.addWidget(self.viewer, 0, 0, 1, 7)
        self.setup_choosers(canonical)
        self.viewer.projection.rotated.connect(self.update_choosers)
        self.viewer.svdSelectEvent.connect(self.svdSelectEvent)
    

    #These should probably be placed somewhere else but oh well
    def get_selected_label(self):
        if self.viewer is not None:
            return self.viewer.selected_label()
        else:
            return None
            
    def setup_choosers(self, canonical=[]):
        for chooser in (self.x_chooser, self.y_chooser):
            chooser.clear()
            pcs = ["", "Default"] + ["Axis %d" % i for i in xrange(self.viewer.k)]
            chooser.insertItems(0, pcs)
            chooser.insertItems(2, canonical)
            # FIXME: why doesn't this work anymore?
            #chooser.setCompleter(QCompleter(self.viewer.labels))
            chooser.setCurrentIndex(1)

    def update_choosers(self):
        matrix = self.viewer.projection.target_matrix
        xmags = np.sort(matrix[:,0])
        xarg = np.argmax(matrix[:,0])
        ymags = np.sort(matrix[:,1])
        yarg = np.argmax(matrix[:,1])

        if xmags[-1] > 10*xmags[-2]:
            self.x_chooser.setCurrentIndex(self.x_chooser.findText("Axis %d" % xarg))
        else:
            self.x_chooser.setCurrentIndex(0)
        if ymags[-1] > 10*ymags[-2]:
            self.y_chooser.setCurrentIndex(self.y_chooser.findText("Axis %d" % yarg))
        else:
            self.y_chooser.setCurrentIndex(0)

    @QtCore.pyqtSlot(str)
    def set_x_from_string(self, string):
        self.set_axis_from_string(0, string)

    @QtCore.pyqtSlot(str)
    def set_y_from_string(self, string):
        self.set_axis_from_string(1, string)

    def set_axis_from_string(self, axis, string):
        if self.viewer is not None:
            axismatch = SVDViewPanel.axis_re.search(string)
            if axismatch:
                # This describes a particular principal component
                pc = int(axismatch.group(1))
                self.viewer.set_axis_to_pc(axis, pc)
            elif string == 'Default':
                if axis == 0: self.viewer.set_default_x_axis()
                if axis == 1: self.viewer.set_default_y_axis()
            else:
                self.viewer.set_axis_to_text(axis, string)

    def next_axis(self):
        if self.viewer is not None:
            if (self.x_chooser.currentIndex() == 1 and 
                self.y_chooser.currentIndex() == 1):
                self.first_two_axes()
            else:
                self.viewer.projection.next_axis()
                self.viewer.activate_timer()

    def prev_axis(self):
        if self.viewer is not None:
            if (self.x_chooser.currentIndex() == 1 and 
                self.y_chooser.currentIndex() == 1):
                self.first_two_axes()
            else:
                self.viewer.projection.prev_axis()
                self.viewer.activate_timer()

    def first_two_axes(self):
        """Go from the default projection to axes 0 and 1. Yes, those are
        different."""
        self.set_axis_from_string(0, "Axis 0")
        self.set_axis_from_string(1, "Axis 1")
        self.update_choosers()

    def deactivate(self):
        if self.viewer is not None:
            self.viewer.projection.rotated.disconnect(self.update_choosers)
            self.viewer.svdSelectEvent.disconnect(self.svdSelectEvent)
            self.viewer.hide()
            del self.viewer
            self.viewer = None

    def reset_view(self):
        if self.viewer is not None:
            self.viewer.reset_view()
            self.x_chooser.setCurrentIndex(self.x_chooser.findText("Default"))
            self.y_chooser.setCurrentIndex(self.y_chooser.findText("Default"))
            self.viewer.activate_timer()

    def write_svg(self, filename):
        if self.viewer is not None:
            self.viewer.write_svg(filename)

    def focus_on_point(self, text):
        if self.viewer is not None:
            self.viewer.focus_on_point(text)
            self.viewer.activate_timer()

    def sizeHint(self):
        return QSize(600, 800)

    def find_point(self, string):
        string = unicode(string)
        if self.viewer is not None:
            if string in self.viewer.labels:
                self.focus_on_point(string)
                return True
            else:
                return False
Exemplo n.º 56
0
class FindInFilesDialog(QDialog):
    """Dialog to configure and trigger the search in the files."""
    def __init__(self, result_widget, parent):
        super(FindInFilesDialog, self).__init__(parent)
        self._find_thread = FindInFilesThread()
        self.setWindowTitle(translations.TR_FIND_IN_FILES)
        self.resize(400, 300)
        #MAIN LAYOUT
        main_vbox = QVBoxLayout(self)

        self.pattern_line_edit = QLineEdit()
        self.pattern_line_edit.setPlaceholderText(translations.TR_FIND + "...")
        self.dir_name_root = None
        self.user_home = os.path.expanduser('~')
        self.dir_combo = QComboBox()
        self.dir_combo.addItem(self.user_home)
        self.dir_combo.setEditable(True)
        self.open_button = QPushButton(QIcon(":img/find"),
                                       translations.TR_OPEN)
        self.filters_line_edit = QLineEdit("*.py")
        self.filters_line_edit.setPlaceholderText("*.py")
        self.filters_line_edit.setCompleter(
            QCompleter([
                "*{}".format(item) for item in settings.SUPPORTED_EXTENSIONS
            ]))
        self.replace_line = QLineEdit()
        self.replace_line.setEnabled(False)
        self.replace_line.setPlaceholderText(translations.TR_TEXT_FOR_REPLACE +
                                             "...")
        self.check_replace = QCheckBox(translations.TR_REPLACE)
        self.case_checkbox = QCheckBox(translations.TR_CASE_SENSITIVE)
        self.type_checkbox = QCheckBox(translations.TR_REGULAR_EXPRESSION)
        self.recursive_checkbox = QCheckBox(translations.TR_RECURSIVE)
        self.recursive_checkbox.setCheckState(Qt.Checked)
        self.phrase_radio = QRadioButton(translations.TR_SEARCH_BY_PHRASE)
        self.phrase_radio.setChecked(True)
        self.words_radio = QRadioButton(
            translations.TR_SEARCH_FOR_ALL_THE_WORDS)
        self.find_button = QPushButton(translations.TR_FIND + "!")
        self.find_button.setMaximumWidth(150)
        self.cancel_button = QPushButton(translations.TR_CANCEL)
        self.cancel_button.setMaximumWidth(150)
        self.result_widget = result_widget

        hbox = QHBoxLayout()
        hbox.addWidget(self.find_button)
        hbox.addWidget(self.cancel_button)

        #main section
        find_group_box = QGroupBox(translations.TR_MAIN)
        grid = QGridLayout()
        grid.addWidget(QLabel(translations.TR_TEXT), 0, 0)
        grid.addWidget(self.pattern_line_edit, 0, 1)
        grid.addWidget(QLabel(translations.TR_DIRECTORY), 1, 0)
        grid.addWidget(self.dir_combo, 1, 1)
        grid.addWidget(self.open_button, 1, 2)
        grid.addWidget(QLabel(translations.TR_FILTER), 2, 0)
        grid.addWidget(self.filters_line_edit, 2, 1)
        grid.addWidget(self.check_replace, 3, 0)
        grid.addWidget(self.replace_line, 3, 1)

        find_group_box.setLayout(grid)
        #add main section to MAIN LAYOUT
        main_vbox.addWidget(find_group_box)

        #options sections
        options_group_box = QGroupBox(translations.TR_OPTIONS)
        gridOptions = QGridLayout()
        gridOptions.addWidget(self.case_checkbox, 0, 0)
        gridOptions.addWidget(self.type_checkbox, 1, 0)
        gridOptions.addWidget(self.recursive_checkbox, 2, 0)
        gridOptions.addWidget(self.phrase_radio, 0, 1)
        gridOptions.addWidget(self.words_radio, 1, 1)

        options_group_box.setLayout(gridOptions)
        #add options sections to MAIN LAYOUT
        main_vbox.addWidget(options_group_box)

        #add buttons to MAIN LAYOUT
        main_vbox.addLayout(hbox)

        #Focus
        self.pattern_line_edit.setFocus()
        self.open_button.setFocusPolicy(Qt.NoFocus)

        #signal
        self.connect(self.open_button, SIGNAL("clicked()"), self._select_dir)
        self.connect(self.find_button, SIGNAL("clicked()"),
                     self._find_in_files)
        self.connect(self.cancel_button, SIGNAL("clicked()"),
                     self._kill_thread)
        self.connect(self._find_thread, SIGNAL("found_pattern(PyQt_PyObject)"),
                     self._found_match)
        self.connect(self._find_thread, SIGNAL("finished()"),
                     self._find_thread_finished)
        self.connect(self.type_checkbox, SIGNAL("stateChanged(int)"),
                     self._change_radio_enabled)
        self.connect(self.check_replace, SIGNAL("stateChanged(int)"),
                     self._replace_activated)
        self.connect(self.words_radio, SIGNAL("clicked(bool)"),
                     self._words_radio_pressed)

    def _replace_activated(self):
        """If replace is activated, display the replace widgets."""
        self.replace_line.setEnabled(self.check_replace.isChecked())
        self.phrase_radio.setChecked(True)

    def _words_radio_pressed(self, value):
        """If search by independent words is activated, replace is not."""
        self.replace_line.setEnabled(not value)
        self.check_replace.setChecked(not value)
        self.words_radio.setChecked(True)

    def _change_radio_enabled(self, val):
        """Control the state of the radio buttons."""
        enabled = not self.type_checkbox.isChecked()
        self.phrase_radio.setEnabled(enabled)
        self.words_radio.setEnabled(enabled)

    def show(self, actual_project=None, actual=None):
        """Display the dialog and load the projects."""
        self.dir_combo.clear()
        self.dir_name_root = actual_project if \
            actual_project else [self.user_home]
        self.dir_combo.addItems(self.dir_name_root)
        if actual:
            index = self.dir_combo.findText(actual)
            self.dir_combo.setCurrentIndex(index)
        super(FindInFilesDialog, self).show()
        self.pattern_line_edit.setFocus()

    def reject(self):
        """Close the dialog and hide the tools dock."""
        self._kill_thread()
        tools_dock = IDE.get_service('tools_dock')
        if tools_dock:
            tools_dock.hide()
        super(FindInFilesDialog, self).reject()

    def _find_thread_finished(self):
        """Wait on thread finished."""
        self.emit(SIGNAL("finished()"))
        self._find_thread.wait()

    def _select_dir(self):
        """When a new folder is selected, add to the combo if needed."""
        dir_name = QFileDialog.getExistingDirectory(
            self, translations.TR_OPEN, self.dir_combo.currentText(),
            QFileDialog.ShowDirsOnly)
        index = self.dir_combo.findText(dir_name)
        if index >= 0:
            self.dir_combo.setCurrentIndex(index)
        else:
            self.dir_combo.insertItem(0, dir_name)
            self.dir_combo.setCurrentIndex(0)

    def _found_match(self, result):
        """Update the tree for each match found."""
        file_name = result[0]
        items = result[1]
        self.result_widget.update_result(self.dir_combo.currentText(),
                                         file_name, items)

    def _kill_thread(self):
        """Kill the thread."""
        if self._find_thread.isRunning():
            self._find_thread.cancel()
        self.accept()

    def _find_in_files(self):
        """Trigger the search on the files."""
        self.emit(SIGNAL("findStarted()"))
        self._kill_thread()
        self.result_widget.clear()
        pattern = self.pattern_line_edit.text()
        dir_name = self.dir_combo.currentText()

        filters = re.split("[,;]", self.filters_line_edit.text())

        #remove the spaces in the words Ex. (" *.foo"--> "*.foo")
        filters = [f.strip() for f in filters]
        case_sensitive = self.case_checkbox.isChecked()
        type_ = QRegExp.RegExp if \
            self.type_checkbox.isChecked() else QRegExp.FixedString
        recursive = self.recursive_checkbox.isChecked()
        by_phrase = True
        if self.phrase_radio.isChecked() or self.type_checkbox.isChecked():
            regExp = QRegExp(pattern, case_sensitive, type_)
        elif self.words_radio.isChecked():
            by_phrase = False
            type_ = QRegExp.RegExp
            pattern = '|'.join([word.strip() for word in pattern.split()])
            regExp = QRegExp(pattern, case_sensitive, type_)
        #save a reference to the root directory where we find
        self.dir_name_root = dir_name
        self._find_thread.find_in_files(dir_name, filters, regExp, recursive,
                                        by_phrase)
Exemplo n.º 57
0
 def addWidgets(self):
     layout = QVBoxLayout()
     self.setLayout(layout)
     grid = QGridLayout()
     layout.addLayout(grid)
     grid.setColumnMinimumWidth(1, 20)
     grid.setColumnStretch(2, 100)
     grid.setRowStretch(6, 100)
     label = QLabel('Group', self)
     grid.addWidget(label, 0, 0)
     combobox = QComboBox(self)
     combobox.setEditable(True)
     combobox.setInsertPolicy(QComboBox.InsertAtTop)
     grid.addWidget(combobox, 0, 2)
     self.combobox = combobox
     self.fields['group'] = (combobox.currentText, None)
     label = QLabel('Name', self)
     grid.addWidget(label, 1, 0)
     nameedt = QLineEdit(self)
     nameedt.textChanged.connect(self.fieldUpdated)
     grid.addWidget(nameedt, 1, 2)
     self.nameedt = nameedt
     self.fields['name'] = (nameedt.text, nameedt.setText)
     label = QLabel('Username', self)
     grid.addWidget(label, 2, 0)
     editor = QLineEdit(self)
     grid.addWidget(editor, 2, 2)
     self.fields['username'] = (editor.text, editor.setText)
     label = QLabel('Password', self)
     grid.addWidget(label, 3, 0)
     passwdedt = QLineEdit(self)
     passwdedt.setEchoMode(QLineEdit.Password)
     passwdedt.textChanged.connect(self.fieldUpdated)
     grid.addWidget(passwdedt, 3, 2)
     self.fields['password'] = (passwdedt.text, passwdedt.setText)
     self.passwdedt = passwdedt
     config = RandomPasswordConfiguration()
     icon = QIcon(QPixmap(asset('png', 'eye.png')))
     showbtn = QPushButton(icon, '', self)
     showbtn.setCheckable(True)
     showbtn.toggled.connect(self.setShowPassword)
     showbtn.setFixedHeight(passwdedt.sizeHint().height())
     grid.addWidget(showbtn, 3, 3)
     self.showbtn = showbtn
     passwdbtn = GeneratePasswordButton('Generate', config, self)
     passwdbtn.setFixedWidth(passwdbtn.sizeHint().width())
     grid.addWidget(passwdbtn, 3, 4)
     passwdbtn.passwordGenerated.connect(passwdedt.setText)
     label = QLabel('Website')
     grid.addWidget(label, 5, 0)
     editor = QLineEdit(self)
     grid.addWidget(editor, 5, 2, 1, 3)
     self.fields['url'] = (editor.text, editor.setText)
     label = QLabel('Comment')
     grid.addWidget(label, 6, 0)
     editor = QTextEdit(self)
     editor.setAcceptRichText(False)
     grid.addWidget(editor, 6, 2, 1, 3)
     self.fields['comment'] = (editor.toPlainText, editor.setPlainText)
     layout.addStretch(100)
     hbox = QHBoxLayout()
     layout.addLayout(hbox)
     cancelbtn = QPushButton('Cancel')
     cancelbtn.clicked.connect(self.hide)
     hbox.addWidget(cancelbtn)
     savebtn = QPushButton('Save')
     savebtn.setDefault(True)
     savebtn.setEnabled(False)
     savebtn.clicked.connect(self.savePassword)
     hbox.addWidget(savebtn)
     self.savebtn = savebtn
     hbox.addStretch(100)