Esempio n. 1
0
class NameList(QDockWidget):
    def __init__(self, window):
        super(NameList, self).__init__('Current Plots')
        self.namelist_model = QStandardItemModel()
        self.namelist_view = QListView()
        self.namelist_view.setModel(self.namelist_model)
        self.setWidget(self.namelist_view)
        self.window = window
        self.plot_dict = {}

        self.namelist_view.doubleClicked.connect(self.activate_item)
        self.namelist_view.setContextMenuPolicy(QtConst.ActionsContextMenu)
        delete_action = QAction("Delete Selected", self.namelist_view)
        delete_action.triggered.connect(self.delete_item)
        self.namelist_view.addAction(delete_action)

    def activate_item(self, index):
        item = self.namelist_model.itemFromIndex(index)
        plot = self.plot_dict[str(item.text())]
        if plot.closed:
            plot.closed = False
            self.window.add_plot(plot)

    def delete_item(self):
        index = self.namelist_view.currentIndex()
        item = self.namelist_model.itemFromIndex(index)
        del self[str(item.text())]

    def __getitem__(self, item):
        return self.plot_dict[item]

    def __setitem__(self, name, plot):
        model = QStandardItem(name)
        model.setEditable(False)
        self.namelist_model.appendRow(model)
        self.plot_dict[name] = plot

    def __contains__(self, value):
        return value in self.plot_dict

    def __delitem__(self, name):
        self.namelist_model.removeRow(
            self.namelist_model.findItems(name)[0].index().row())
        self.plot_dict[name].close()
        del self.plot_dict[name]

    def keys(self):
        return self.plot_dict.keys()
Esempio n. 2
0
class HistoryDialog(QDialog, Ui_HistoryDialogPythonConsole):
    def __init__(self, parent):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.parent = parent
        self.setWindowTitle(
            QCoreApplication.translate("PythonConsole",
                                       "Python Console - Command History"))
        self.listView.setToolTip(
            QCoreApplication.translate("PythonConsole",
                                       "Double click on item to execute"))
        self.model = QStandardItemModel(self.listView)

        self._reloadHistory()

        self.deleteScut = QShortcut(QKeySequence(Qt.Key_Delete), self)
        self.deleteScut.activated.connect(self._deleteItem)
        self.listView.doubleClicked.connect(self._runHistory)
        self.reloadHistory.clicked.connect(self._reloadHistory)
        self.saveHistory.clicked.connect(self._saveHistory)

    def _runHistory(self, item):
        cmd = item.data(Qt.DisplayRole)
        self.parent.runCommand(unicode(cmd))

    def _saveHistory(self):
        self.parent.writeHistoryFile(True)

    def _reloadHistory(self):
        self.model.clear()
        for i in self.parent.history:
            item = QStandardItem(i)
            if sys.platform.startswith('win'):
                item.setSizeHint(QSize(18, 18))
            self.model.appendRow(item)

        self.listView.setModel(self.model)
        self.listView.scrollToBottom()

    def _deleteItem(self):
        itemsSelected = self.listView.selectionModel().selectedIndexes()
        if itemsSelected:
            item = itemsSelected[0].row()
            ## Remove item from the command history (just for the current session)
            self.parent.history.pop(item)
            self.parent.historyIndex -= 1
            ## Remove row from the command history dialog
            self.model.removeRow(item)
Esempio n. 3
0
class HistoryDialog(QDialog, Ui_HistoryDialogPythonConsole):

    def __init__(self, parent):
        QDialog.__init__(self, parent)
        self.setupUi(self)
        self.parent = parent
        self.setWindowTitle(QCoreApplication.translate("PythonConsole",
                                                       "Python Console - Command History"))
        self.listView.setToolTip(QCoreApplication.translate("PythonConsole",
                                                            "Double click on item to execute"))
        self.model = QStandardItemModel(self.listView)

        self._reloadHistory()

        self.deleteScut = QShortcut(QKeySequence(Qt.Key_Delete), self)
        self.deleteScut.activated.connect(self._deleteItem)
        self.listView.doubleClicked.connect(self._runHistory)
        self.reloadHistory.clicked.connect(self._reloadHistory)
        self.saveHistory.clicked.connect(self._saveHistory)

    def _runHistory(self, item):
        cmd = item.data(Qt.DisplayRole)
        self.parent.runCommand(unicode(cmd))

    def _saveHistory(self):
        self.parent.writeHistoryFile(True)

    def _reloadHistory(self):
        self.model.clear()
        for i in self.parent.history:
            item = QStandardItem(i)
            if sys.platform.startswith('win'):
                item.setSizeHint(QSize(18, 18))
            self.model.appendRow(item)

        self.listView.setModel(self.model)
        self.listView.scrollToBottom()

    def _deleteItem(self):
        itemsSelected = self.listView.selectionModel().selectedIndexes()
        if itemsSelected:
            item = itemsSelected[0].row()
            ## Remove item from the command history (just for the current session)
            self.parent.history.pop(item)
            self.parent.historyIndex -= 1
            ## Remove row from the command history dialog
            self.model.removeRow(item)
class TemplateDocumentSelector(QDialog, Ui_frmDocumentSelector):
    """
    Dialog for selecting a document template from the saved list.
    """
    def __init__(self, parent=None, selectMode=True):
        QDialog.__init__(self, parent)
        self.setupUi(self)

        self.notifBar = NotificationBar(self.vlNotification)

        if selectMode:
            self.buttonBox.setVisible(True)
            self.manageButtonBox.setVisible(False)
            currHeight = self.size().height()
            self.resize(200, currHeight)

        else:
            self.buttonBox.setVisible(False)
            self.manageButtonBox.setVisible(True)
            self.setWindowTitle(
                QApplication.translate("TemplateDocumentSelector",
                                       "Template Manager"))

        #Configure manage buttons
        btnEdit = self.manageButtonBox.button(QDialogButtonBox.Ok)
        btnEdit.setText(
            QApplication.translate("TemplateDocumentSelector", "Edit..."))
        btnEdit.setIcon(QIcon(":/plugins/stdm/images/icons/edit.png"))

        btnDelete = self.manageButtonBox.button(QDialogButtonBox.Save)
        btnDelete.setText(
            QApplication.translate("TemplateDocumentSelector", "Delete"))
        btnDelete.setIcon(QIcon(":/plugins/stdm/images/icons/delete.png"))

        #Connect signals
        self.buttonBox.accepted.connect(self.onAccept)
        btnEdit.clicked.connect(self.onEditTemplate)
        btnDelete.clicked.connect(self.onDeleteTemplate)

        #Get saved document templates then add to the model
        templates = documentTemplates()

        self._docItemModel = QStandardItemModel(parent)
        self._docItemModel.setColumnCount(2)

        for name, path in templates.iteritems():
            docNameItem = self._createDocNameItem(name)
            filePathItem = QStandardItem(path)
            self._docItemModel.appendRow([docNameItem, filePathItem])

        self.lstDocs.setModel(self._docItemModel)

    def _createDocNameItem(self, docName):
        """
        Create a template document standard item.
        """
        #Set icon
        icon = QIcon()
        icon.addPixmap(QPixmap(":/plugins/stdm/images/icons/document.png"),
                       QIcon.Normal, QIcon.Off)

        dnItem = QStandardItem(icon, docName)

        return dnItem

    def onEditTemplate(self):
        """
        Slot raised to edit document template.
        """
        self.notifBar.clear()

        if self.documentMapping() == None:
            self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "Please select a document template to edit"))
            return

        templateName, filePath = self.documentMapping()

        docName,ok = QInputDialog.getText(self, \
                                              QApplication.translate("TemplateDocumentSelector","Edit Template"), \
                                              QApplication.translate("TemplateDocumentSelector","Please enter the new template name below"), \
                                              text = templateName)
        if ok and docName == "":
            self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "Template name cannot be empty"))
            return

        elif docName == templateName:
            return

        elif ok and docName != "":
            result, newTemplatePath = self._editTemplate(filePath, docName)

            if result:
                #Update view
                mIndices = self._selectedMappings()

                docNameItem = self._docItemModel.itemFromIndex(mIndices[0])
                filePathItem = self._docItemModel.itemFromIndex(mIndices[1])

                docNameItem.setText(docName)
                filePathItem.setText(newTemplatePath)

                self.notifBar.insertInfoNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "'{0}' template has been successfully updated".format(docName)))

            else:
                self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "Error: '{0}' template could not be updated".format(templateName)))

    def onDeleteTemplate(self):
        """
        Slot raised to delete document template.
        """
        self.notifBar.clear()

        if self.documentMapping() == None:
            self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "Please select a document template to delete"))
            return

        templateName, filePath = self.documentMapping()

        result = QMessageBox.warning(self, QApplication.translate("TemplateDocumentSelector", \
                                                                         "Confirm delete"),
                                     QApplication.translate("TemplateDocumentSelector", \
                                                                         "Are you sure you want to delete '{0}' template?" \
                                                                         "This action cannot be undone.\nClick Yes to proceed " \
                                                                         "or No to cancel.".format(templateName)),
                                     QMessageBox.Yes|QMessageBox.No)

        if result == QMessageBox.No:
            return

        status = self._deleteDocument(filePath)

        if status:
            #Remove item from list using model index row number
            selectedDocNameIndices = self.lstDocs.selectionModel(
            ).selectedRows(0)
            row = selectedDocNameIndices[0].row()
            self._docItemModel.removeRow(row)
            self.notifBar.insertInfoNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "'{0}' template has been successfully removed".format(templateName)))

        else:
            self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "Error: '{0}' template could not be removed".format(templateName)))

    def onAccept(self):
        """
        Slot raised to close the dialog only when a selection has been made by the user.
        """
        self.notifBar.clear()

        if self.documentMapping() == None:
            self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "Please select a document"))
            return

        self.accept()

    def _selectedMappings(self):
        """
        Returns the model indices for the selected row.
        """
        selectedDocNameIndices = self.lstDocs.selectionModel().selectedRows(0)
        selectedFilePathIndices = self.lstDocs.selectionModel().selectedRows(1)

        if len(selectedDocNameIndices) == 0:
            return None

        docNameIndex = selectedDocNameIndices[0]
        filePathIndex = selectedFilePathIndices[0]

        return (docNameIndex, filePathIndex)

    def documentMapping(self):
        """
        Returns a tuple containing the selected document name and the corresponding file name.
        """
        mIndices = self._selectedMappings()

        if mIndices == None:
            return None

        docNameItem = self._docItemModel.itemFromIndex(mIndices[0])
        filePathItem = self._docItemModel.itemFromIndex(mIndices[1])

        return (docNameItem.text(), filePathItem.text())

    def _editTemplate(self, templatePath, newName):
        """
        Updates the template document to use the new name.
        """
        templateFile = QFile(templatePath)

        if not templateFile.open(QIODevice.ReadOnly):
            QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector","Open Operation Error"), \
                                            "{0}\n{1}".format(QApplication.translate("TemplateDocumentSelector","Cannot read template file."), \
                                                      templateFile.errorString()
                                                      ))
            return (False, "")

        templateDoc = QDomDocument()

        if templateDoc.setContent(templateFile):
            composerElement = templateDoc.documentElement()
            titleAttr = composerElement.attributeNode("title")
            if not titleAttr.isNull():
                titleAttr.setValue(newName)

            #Try remove file
            status = templateFile.remove()

            if not status:
                return (False, "")

            #Create new file
            newTemplatePath = self._composerTemplatesPath(
            ) + "/" + newName + ".sdt"
            newTemplateFile = QFile(newTemplatePath)

            if not newTemplateFile.open(QIODevice.WriteOnly):
                QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector","Save Operation Error"), \
                                                "{0}\n{1}".format(QApplication.translate("TemplateDocumentSelector","Could not save template file."), \
                                                          newTemplateFile.errorString()
                                                          ))
                return (False, "")

            if newTemplateFile.write(templateDoc.toByteArray()) == -1:
                QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector","Save Error"), \
                                                QApplication.translate("TemplateDocumentSelector","Could not save template file."))
                return (False, "")

            newTemplateFile.close()

            return (True, newTemplatePath)

    def _deleteDocument(self, templatePath):
        """
        Delete the document template from the file system.
        """
        docFile = QFile(templatePath)

        return docFile.remove()

    def _composerTemplatesPath(self):
        """
        Reads the path of composer templates in the registry.
        """
        regConfig = RegistryConfig()
        keyName = "ComposerTemplates"

        valueCollection = regConfig.read([keyName])

        if len(valueCollection) == 0:
            return None

        else:
            return valueCollection[keyName]
Esempio n. 5
0
class TreeView(QTreeView):
    def __init__(self, parent):
        QTreeView.__init__(self, parent)
        while not isinstance(parent, QDialog) and not isinstance(parent, QMainWindow):
            parent = parent.parent()
        self.setObjectName("TreeView" + str(len(parent.findChildren(TreeView))))

        # self.setObjectName("TreeViewWidget")
        # self.hLayout = QHBoxLayout(self)
        # self.hLayout.setObjectName("hLayout")
        # 
        # sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        # sizePolicy.setHorizontalStretch(0)
        # sizePolicy.setVerticalStretch(0)
        # sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
        # self.setSizePolicy(sizePolicy)
        # 
        # # self.frame = Frame()
        # self = QTreeView(self)
        # self.hLayout.addWidget(self)

        self.stdModel = QStandardItemModel()
        self.setModel(self.stdModel)

        self.hasObject = False
        self.treeNodeList = []

        self.checkBoxList = []
        self.setHeaderHidden(True)
        # self.stdModel.appendRow(TreeNode("P"))
        # rootIndex = self.rootIndex()

        # rootItem = self.stdModel.itemFromIndex(rootIndex)
        # rootItem.setText("Root")

    def mouseMoveEvent(self, mouseEvent):
        pt = mouseEvent.pos()
        pass
    def Clear(self):
        self.stdModel.clear()
        self.hasObject = False
        self.treeNodeList = []
    def Add(self, caption):
        item = TreeNode(caption)
        if len(self.treeNodeList) > 0:
            item.PrevNode = self.treeNodeList[len(self.treeNodeList) - 1]
            item.PrevNode.NextNode = item
            item.Index = len(self.treeNodeList)
        # item.nodeIndex = len(self.treeNodeList)
        self.treeNodeList.append(item)
        self.stdModel.appendRow(item)
        return item
    def RemoveNode(self, i):
        self.stdModel.removeRow(i)
        self.treeNodeList.pop(i)
        for j in range(i, len(self.treeNodeList)):
            self.treeNodeList[j].nodeIndex -= 1
    def Remove(self, item):
        removedIndex = self.treeNodeList.index(item)
        if removedIndex == 0:
            self.treeNodeList[1].PrevNode = None
        elif removedIndex == len(self.treeNodeList) - 1:
            self.treeNodeList[len(self.treeNodeList) - 2].NextNode = None
        else:
            self.treeNodeList[removedIndex + 1].PrevNode = self.treeNodeList[removedIndex - 1]
            self.treeNodeList[removedIndex - 1].NextNode = self.treeNodeList[removedIndex + 1]
        self.treeNodeList.pop(removedIndex)
        self.stdModel.removeRow(removedIndex)
        i = 0
        for node in self.treeNodeList:
            node.Index = i
            node.LastNode = self.treeNodeList[len(self.treeNodeList) - 1]
            i += 1
    def Insert(self, index, text):
        if index == 0 and len(self.treeNodeList) == 0:
            self.Add(text)
            return
        node = TreeNode(text)
        node.Parent = self
        self.treeNodeList.insert(index, node)
        i = 0
        for node0 in self.treeNodeList:
            node0.Index = i
            i += 1
        if index == 0:
            self.treeNodeList[index].PrevNode = None
            if len(self.treeNodeList) == 1:
                self.treeNodeList[index].NextNode = None
                self.treeNodeList[index].LastNode = self.treeNodeList[index]
            else:
                self.treeNodeList[index].NextNode = self.treeNodeList[index + 1]
                self.treeNodeList[index].LastNode = self.treeNodeList[len(self.treeNodeList) - 1]
            
            self.treeNodeList[index + 1].PrevNode = self.treeNodeList[index]
            
        else:
            self.treeNodeList[index].PrevNode = self.treeNodeList[index - 1]
            self.treeNodeList[index].NextNode = self.treeNodeList[index + 1]
            self.treeNodeList[index].LastNode = self.treeNodeList[len(self.treeNodeList) - 1]
            
            self.treeNodeList[index + 1].PrevNode = self.treeNodeList[index]
            self.treeNodeList[index - 1].NextNode = self.treeNodeList[index]
            

        self.stdModel.insertRow(index, node)
        return node

    def get_Items(self):
        return self.treeNodeList
    Nodes = property(get_Items, None, None, None)

    def Node(self, index):
        if not self.stdModel.rowCount() > 0:
            return None
        return self.treeNodeList[index]

    def getSelectedNode(self):
        if not self.stdModel.rowCount() > 0:
            return None
        index = self.currentIndex()
        return self.stdModel.itemFromIndex(index)
    def setSelectedNode(self, node):
        if not self.stdModel.rowCount() > 0:
            return
        # self.s
        index = self.stdModel.indexFromItem(node)
        self.setCurrentIndex(index)
        # self.treeNodeList.pop(index)
        # self.treeNodeList.insert(index, node)
        # self.stdModel.setItem(index, node)

    SelectedNode = property(getSelectedNode, setSelectedNode, None, None)




    def get_Enabled(self):
        return self.isEnabled()
    def set_Enabled(self, bool):
        self.setEnabled(bool)
    Enabled = property(get_Enabled, set_Enabled, None, None)

    def get_Visible(self):
        return self.isVisible()
    def set_Visible(self, bool):
        self.setVisible(bool)
    Visible = property(get_Visible, set_Visible, None, None)
class PosiviewProperties(QgsOptionsDialogBase, Ui_PosiviewPropertiesBase):
    '''
    GUI class classdocs for the Configuration dialog
    '''
    applyChanges = pyqtSignal(dict)

    def __init__(self, project, parent=None):
        '''
        Setup dialog widgets with the project properties
        '''
        super(PosiviewProperties, self).__init__("PosiViewProperties", parent)
        self.setupUi(self)
        self.groupBox_6.hide()
        self.initOptionsBase(False)
        self.restoreOptionsBaseUi()
        self.comboBoxParser.addItems(PARSERS)
        self.comboBoxProviderType.addItems(DEVICE_TYPES)
        self.project = project
        self.projectProperties = project.properties()
        self.mToolButtonLoad.setDefaultAction(self.actionLoadConfiguration)
        self.mToolButtonSave.setDefaultAction(self.actionSaveConfiguration)

        self.mobileModel = QStringListModel()
        self.mobileListModel = QStringListModel()
        self.mMobileListView.setModel(self.mobileListModel)
        self.mobileProviderModel = QStandardItemModel()
        self.mobileProviderModel.setHorizontalHeaderLabels(('Provider', 'Filter'))
        self.mMobileProviderTableView.setModel(self.mobileProviderModel)

        self.providerListModel = QStringListModel()
        self.mDataProviderListView.setModel(self.providerListModel)
        self.comboBoxProviders.setModel(self.providerListModel)
        self.setupModelData(self.projectProperties)
        self.setupGeneralData(self.projectProperties)

    def setupModelData(self, properties):
        self.mobileListModel.setStringList(sorted(properties['Mobiles'].keys()))
        self.providerListModel.setStringList(sorted(properties['Provider'].keys()))

    def setupGeneralData(self, properties):
        self.lineEditCruise.setText(properties['Mission']['cruise'])
        self.lineEditDive.setText(properties['Mission']['dive'])
        self.lineEditStation.setText(properties['Mission']['station'])
        self.lineEditRecorderPath.setText(properties['RecorderPath'])
        self.checkBoxAutoRecording.setChecked(properties['AutoRecord'])
        self.spinBoxNotifyDuration.setValue(properties['NotifyDuration'])
        self.checkBoxUtcClock.setChecked((properties['ShowUtcClock']))

    def updateGeneralData(self):
        self.projectProperties['Mission']['cruise'] = self.lineEditCruise.text()
        self.projectProperties['Mission']['dive'] = self.lineEditDive.text()
        self.projectProperties['Mission']['station'] = self.lineEditStation.text()
        self.projectProperties['RecorderPath'] = self.lineEditRecorderPath.text()
        self.projectProperties['AutoRecord'] = self.checkBoxAutoRecording.isChecked()
        self.projectProperties['NotifyDuration'] = self.spinBoxNotifyDuration.value()
        self.projectProperties['ShowUtcClock'] = self.checkBoxUtcClock.isChecked()

    def getColor(self, value):
        try:
            return QColor.fromRgba(int(value))
        except ValueError:
            return QColor(value)

    @pyqtSlot(QAbstractButton, name='on_buttonBox_clicked')
    def onButtonBoxClicked(self, button):
        role = self.buttonBox.buttonRole(button)
        if role == QDialogButtonBox.ApplyRole or role == QDialogButtonBox.AcceptRole:
            self.updateGeneralData()
            self.applyChanges.emit(self.projectProperties)

    @pyqtSlot(name='on_actionSaveConfiguration_triggered')
    def onActionSaveConfigurationTriggered(self):
        ''' Save the current configuration
        '''
        fn = QFileDialog.getSaveFileName(None, 'Save PosiView configuration', '', 'Configuration (*.ini *.conf)')
        self.project.store(fn)

    @pyqtSlot(name='on_actionLoadConfiguration_triggered')
    def onActionLoadConfigurationTriggered(self):
        ''' Load configuration from file
        '''
        fn = QFileDialog.getOpenFileName(None, 'Save PosiView configuration', '', 'Configuration (*.ini *.conf)')
        self.projectProperties = self.project.read(fn)
        self.setupModelData(self.projectProperties)
        self.setupGeneralData(self.projectProperties)

    @pyqtSlot(QModelIndex, name='on_mMobileListView_clicked')
    def editMobile(self, index):
        ''' Populate the widgets with the selected mobiles properties
        '''
        if index.isValid():
            self.populateMobileWidgets(index)

    @pyqtSlot(str, name='on_comboBoxMobileType_currentIndexChanged')
    def mobileTypeChanged(self, mType):
        if mType == 'SHAPE':
#             self.lineEditMobileShape.setText(str(mobile['shape']))
            self.lineEditMobileShape.setEnabled(True)
        else:
            self.lineEditMobileShape.setEnabled(False)

    @pyqtSlot(QModelIndex, name='on_mMobileListView_activated')
    def activated(self, index):
        pass

    @pyqtSlot(name='on_toolButtonAddMobile_clicked')
    def addMobile(self):
        self.mobileListModel.insertRow(self.mobileListModel.rowCount())
        index = self.mobileListModel.index(self.mobileListModel.rowCount() - 1)
        self.lineEditMobileName.setText('NewMobile')
        self.mobileListModel.setData(index, 'NewMobile', Qt.DisplayRole)
        self.mMobileListView.setCurrentIndex(index)
        self.applyMobile()

    @pyqtSlot(name='on_pushButtonApplyMobile_clicked')
    def applyMobile(self):
        index = self.mMobileListView.currentIndex()
        if index.isValid() and not self.lineEditMobileName.text() == '':
            mobile = dict()
            mobile['Name'] = self.lineEditMobileName.text()
            mobile['type'] = self.comboBoxMobileType.currentText()
            try:
                t = eval(self.lineEditMobileShape.text())
                if t.__class__ is tuple or t.__class__ is dict:
                    mobile['shape'] = t
            except SyntaxError:
                mobile['shape'] = ((0.0, -0.5), (0.3, 0.5), (0.0, 0.2), (-0.5, 0.5))
            mobile['length'] = self.doubleSpinBoxMobileLength.value()
            mobile['width'] = self.doubleSpinBoxMobileWidth.value()
            mobile['zValue'] = self.spinBoxZValue.value()
            mobile['color'] = self.mColorButtonMobileColor.color().rgba()
            mobile['fillColor'] = self.mColorButtonMobileFillColor.color().rgba()
            mobile['timeout'] = self.spinBoxMobileTimeout.value() * 1000
            mobile['nofixNotify'] = self.spinBoxMobileNotification.value()
            mobile['trackLength'] = self.spinBoxTrackLength.value()
            mobile['trackColor'] = self.mColorButtonMobileTrackColor.color().rgba()
            provs = dict()
            for r in range(self.mobileProviderModel.rowCount()):
                try:
                    fil = int(self.mobileProviderModel.item(r, 1).data(Qt.DisplayRole))
                except:
                    fil = self.mobileProviderModel.item(r, 1).data(Qt.DisplayRole)
                    if not fil:
                        fil = None
                provs[self.mobileProviderModel.item(r, 0).data(Qt.DisplayRole)] = fil
            mobile['provider'] = provs
            currName = self.mobileListModel.data(index, Qt.DisplayRole)
            if not currName == mobile['Name']:
                del self.projectProperties['Mobiles'][currName]
                self.mobileListModel.setData(index, mobile['Name'], Qt.DisplayRole)
            self.projectProperties['Mobiles'][mobile['Name']] = mobile

    def populateMobileWidgets(self, index):
        mobile = self.projectProperties['Mobiles'][self.mobileListModel.data(index, Qt.DisplayRole)]
        self.lineEditMobileName.setText(mobile.get('Name'))
        self.comboBoxMobileType.setCurrentIndex(self.comboBoxMobileType.findText(mobile.setdefault('type', 'BOX').upper()))
        if mobile['type'] == 'SHAPE':
            self.lineEditMobileShape.setText(str(mobile['shape']))
            self.lineEditMobileShape.setEnabled(True)
        else:
            self.lineEditMobileShape.setEnabled(False)
            self.lineEditMobileShape.clear()
        self.doubleSpinBoxMobileLength.setValue(mobile.get('length', 20.0))
        self.doubleSpinBoxMobileWidth.setValue(mobile.get('width', 5.0))
        self.spinBoxZValue.setValue(mobile.get('zValue', 100))
        self.mColorButtonMobileColor.setColor(self.getColor(mobile.get('color', 'black')))
        self.mColorButtonMobileFillColor.setColor(self.getColor(mobile.get('fillColor', 'green')))
        self.spinBoxMobileTimeout.setValue(mobile.get('timeout', 3000) / 1000)
        self.spinBoxMobileNotification.setValue(mobile.get('nofixNotify', 0))
        self.spinBoxTrackLength.setValue(mobile.get('trackLength', 100))
        self.mColorButtonMobileTrackColor.setColor(self.getColor(mobile.get('trackColor', 'green')))

        r = 0
        self.mobileProviderModel.removeRows(0, self.mobileProviderModel.rowCount())
        if 'provider' in mobile:
            for k, v in mobile['provider'].items():
                prov = QStandardItem(k)
                val = QStandardItem(str(v))
                self.mobileProviderModel.setItem(r, 0, prov)
                self.mobileProviderModel.setItem(r, 1, val)
                r += 1

    @pyqtSlot(name='on_toolButtonRemoveMobile_clicked')
    def removeMobile(self):
        idx = self.mMobileListView.currentIndex()
        if idx.isValid():
            self.projectProperties['Mobiles'].pop(self.mobileListModel.data(idx, Qt.DisplayRole))
            self.mobileListModel.removeRows(idx.row(), 1)
            idx = self.mMobileListView.currentIndex()
            if idx.isValid():
                self.populateMobileWidgets(idx)

    @pyqtSlot(name='on_toolButtonRefreshMobileProvider_clicked')
    def refreshMobileProvider(self):
        prov = self.comboBoxProviders.currentText()
        if prov == '':
            return
        fil = None
        if self.lineEditProviderFilter.text() != '':
            fil = self.lineEditProviderFilter.text()
        items = self.mobileProviderModel.findItems(prov, Qt.MatchExactly, 0)
        if items:
            for item in items:
                self.mobileProviderModel.setItem(item.row(), 1, QStandardItem(fil))
        else:
            self.mobileProviderModel.appendRow([QStandardItem(prov), QStandardItem(fil)])

    @pyqtSlot(name='on_toolButtonRemoveMobileProvider_clicked')
    def removeMobileProvider(self):
        idx = self.mMobileProviderTableView.currentIndex()
        if idx.isValid():
            self.mobileProviderModel.removeRow(idx.row())

    @pyqtSlot(name='on_pushButtonApplyDataProvider_clicked')
    def applyDataProvider(self):
        index = self.mDataProviderListView.currentIndex()
        if index.isValid() and not self.lineEditProviderName.text() == '':
            provider = dict()
            provider['Name'] = self.lineEditProviderName.text()
            provider['DataDeviceType'] = self.comboBoxProviderType.currentText()
            if provider['DataDeviceType'] in NETWORK_TYPES:
                provider['Host'] = self.lineEditProviderHostName.text()
                provider['Port'] = self.spinBoxProviderPort.value()
            provider['Parser'] = self.comboBoxParser.currentText()
            currName = self.providerListModel.data(index, Qt.DisplayRole)
            if not currName == provider['Name']:
                del self.projectProperties['Provider'][currName]
                self.providerListModel.setData(index, provider['Name'], Qt.DisplayRole)
            self.projectProperties['Provider'][provider['Name']] = provider

    @pyqtSlot(QModelIndex, name='on_mDataProviderListView_clicked')
    def editDataProvider(self, index):
        '''
        '''
        if index.isValid():
            self.populateDataProviderWidgets(index)

    def populateDataProviderWidgets(self, index):
        provider = self.projectProperties['Provider'][self.providerListModel.data(index, Qt.DisplayRole)]
        self.lineEditProviderName.setText(provider.get('Name'))
        self.comboBoxProviderType.setCurrentIndex(self.comboBoxProviderType.findText(provider.setdefault('DataDeviceType', 'UDP').upper()))
        if provider['DataDeviceType'] in NETWORK_TYPES:
            self.stackedWidgetDataDevice.setCurrentIndex(0)
            self.lineEditProviderHostName.setText(provider.setdefault('Host', '0.0.0.0'))
            self.spinBoxProviderPort.setValue(int(provider.setdefault('Port', 2000)))

        self.comboBoxParser.setCurrentIndex(self.comboBoxParser.findText(provider.setdefault('Parser', 'NONE').upper()))

    @pyqtSlot(name='on_toolButtonAddDataProvider_clicked')
    def addDataProvider(self):
        self.providerListModel.insertRow(self.providerListModel.rowCount())
        index = self.providerListModel.index(self.providerListModel.rowCount() - 1)
        self.lineEditProviderName.setText('NewDataProvider')
        self.providerListModel.setData(index, 'NewDataProvider', Qt.DisplayRole)
        self.mDataProviderListView.setCurrentIndex(index)
        self.applyDataProvider()

    @pyqtSlot(name='on_toolButtonRemoveDataProvider_clicked')
    def removeDataProvider(self):
        idx = self.mDataProviderListView.currentIndex()
        if idx.isValid():
            self.projectProperties['Provider'].pop(self.providerListModel.data(idx, Qt.DisplayRole))
            self.providerListModel.removeRows(idx.row(), 1)
            idx = self.mDataProviderListView.currentIndex()
            if idx.isValid():
                self.populateDataProviderWidgets(idx)

    @pyqtSlot(name='on_toolButtonSelectLogPath_clicked')
    def selectRecorderPath(self):
        path = QFileDialog.getExistingDirectory(self, self.tr('Select Recorder Path'), self.lineEditRecorderPath.text(),
                                                QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)
        if path != '':
            self.lineEditRecorderPath.setText(path)

    @pyqtSlot(QPoint, name='on_lineEditMobileShape_customContextMenuRequested')
    def mobileShapeContextMenu(self, pos):
        menu = QMenu(self.lineEditMobileShape)
        vesselAction = menu.addAction(self.tr('Vessel'))
        rovAction = menu.addAction(self.tr('ROV'))
        auvAction = menu.addAction(self.tr('AUV'))
        arrowAction = menu.addAction(self.tr('Arrow'))
        selectedAction = menu.exec_(self.lineEditMobileShape.mapToGlobal(pos))
        if selectedAction == vesselAction:
            self.lineEditMobileShape.setText(u'((0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3))')
        elif selectedAction == rovAction:
            self.lineEditMobileShape.setText(u'((0.3, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3), (-0.3, -0.5))')
        elif selectedAction == auvAction:
            self.lineEditMobileShape.setText(u'((0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3))')
        elif selectedAction == arrowAction:
            self.lineEditMobileShape.setText(u'((0, -0.5), (0.5, 0.5), (0, 0), (-0.5, 0.5))')

    @pyqtSlot(name='on_buttonBox_helpRequested')
    def showHelp(self):
        """Display application help to the user."""
        help_file = os.path.join(os.path.split(os.path.dirname(__file__))[0], 'help', 'index.html')
        QDesktopServices.openUrl(QUrl.fromLocalFile(help_file))
Esempio n. 7
0
class TemplateDocumentSelector(QDialog,Ui_frmDocumentSelector):
    """
    Dialog for selecting a document template from the saved list.
    """
    def __init__(self, parent=None,selectMode=True, filter_data_source=''):
        QDialog.__init__(self,parent)
        self.setupUi(self)
        
        self.notifBar = NotificationBar(self.vlNotification)

        self._mode = selectMode

        #Filter templates by the specified table name
        self._filter_data_source = filter_data_source

        #Document templates in current profile
        self._profile_templates = []

        self._current_profile = current_profile()

        #Load current profile templates
        self._load_current_profile_templates()
        
        if selectMode:
            self.buttonBox.setVisible(True)
            self.manageButtonBox.setVisible(False)
            currHeight = self.size().height()
            self.resize(200,currHeight)
            
        else:
            self.buttonBox.setVisible(False)
            self.manageButtonBox.setVisible(True)
            self.setWindowTitle(
                QApplication.translate(
                    "TemplateDocumentSelector",
                    "Template Manager"
                )
            )
            
        #Configure manage buttons
        btnEdit = self.manageButtonBox.button(QDialogButtonBox.Ok)
        btnEdit.setText(QApplication.translate("TemplateDocumentSelector","Edit..."))
        btnEdit.setIcon(QIcon(":/plugins/stdm/images/icons/edit.png"))
        
        btnDelete = self.manageButtonBox.button(QDialogButtonBox.Save)
        btnDelete.setText(QApplication.translate("TemplateDocumentSelector","Delete"))
        btnDelete.setIcon(QIcon(":/plugins/stdm/images/icons/delete.png"))
        
        #Connect signals
        self.buttonBox.accepted.connect(self.onAccept)
        btnEdit.clicked.connect(self.onEditTemplate)
        btnDelete.clicked.connect(self.onDeleteTemplate)
        
        #Get saved document templates then add to the model
        templates = documentTemplates()

        self._docItemModel = QStandardItemModel(parent)
        self._docItemModel.setColumnCount(2)

        #Append current profile templates to the model.
        for dt in self._profile_templates:

            if self._template_contains_filter_table(dt):
                doc_name_item = self._createDocNameItem(dt.name)
                file_path_item = QStandardItem(dt.path)
                self._docItemModel.appendRow([doc_name_item,file_path_item])

        self.lstDocs.setModel(self._docItemModel)

    def _load_current_profile_templates(self):
        # Loads only those templates that refer to tables in the current
        # profile.
        if self._current_profile is None:
            return

        #Get saved document templates then add to the model
        templates = documentTemplates()

        profile_tables = self._current_profile.table_names()

        #Get templates for the current profile
        for name, path in templates.iteritems():
            doc_temp = _DocumentTemplate.build_from_path(name, path)
            if doc_temp.data_source is None:
                continue

            #Assert data source is in the current profile
            if doc_temp.data_source.referenced_table_name in profile_tables:
                self._add_doc_temp(doc_temp)
                #self._profile_templates.append(doc_temp)

            if doc_temp.data_source._dataSourceName in user_non_profile_views():
                self._add_doc_temp(doc_temp)
                #self._profile_templates.append(doc_temp)

    def _add_doc_temp(self, doc_temp):
        found = False
        for template in self._profile_templates:
            if template.name == doc_temp.name:
                found = True
                break
        if not found:
            self._profile_templates.append(doc_temp)

    def _template_contains_filter_table(self, document_template):
        #Returns true if the template refers to the filter data source

        #If no filter data source defined then always return True

        if document_template.data_source._dataSourceName in user_non_profile_views():
            return True

        if not self._filter_data_source:
            return True

        referenced_table = document_template.referenced_table_name

        if referenced_table == self._filter_data_source:
            return True

        return False

    @property
    def mode(self):
        return self._mode

    @property
    def filter_data_source(self):
        return self._filter_data_source
        
    def _createDocNameItem(self,docName):
        """
        Create a template document standard item.
        """
        #Set icon
        icon = QIcon()
        icon.addPixmap(
            QPixmap(
                ":/plugins/stdm/images/icons/document.png"
            ),
            QIcon.Normal,
            QIcon.Off
        )
        
        dnItem = QStandardItem(icon,docName)
        
        return dnItem
    
    def onEditTemplate(self):
        """
        Slot raised to edit document template.
        """
        self.notifBar.clear()
        
        if self.documentMapping() == None:
            self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "Please select a document template to edit"))
            return
        
        templateName,filePath = self.documentMapping()
        
        docName,ok = QInputDialog.getText(self, \
                                              QApplication.translate("TemplateDocumentSelector","Edit Template"), \
                                              QApplication.translate("TemplateDocumentSelector","Please enter the new template name below"), \
                                              text = templateName)
        if ok and docName == "":
            self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "Template name cannot be empty"))
            return
        
        elif docName == templateName:
            return
        
        elif ok and docName != "":
            result,newTemplatePath = self._editTemplate(filePath, docName)
            
            if result:
                #Update view
                mIndices = self._selectedMappings()
        
                docNameItem = self._docItemModel.itemFromIndex(mIndices[0])
                filePathItem = self._docItemModel.itemFromIndex(mIndices[1])
                
                docNameItem.setText(docName)
                filePathItem.setText(newTemplatePath)
                
                self.notifBar.insertSuccessNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "'{0}' template has been successfully updated".format(docName)))
                
            else:
                self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "Error: '{0}' template could not be updated".format(templateName)))
            
    def onDeleteTemplate(self):
        """
        Slot raised to delete document template.
        """
        self.notifBar.clear()
        
        if self.documentMapping() == None:
            self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "Please select a document template to delete"))
            return
        
        templateName,filePath = self.documentMapping()
        
        result = QMessageBox.warning(self, QApplication.translate("TemplateDocumentSelector", \
                                                                         "Confirm delete"), 
                                     QApplication.translate("TemplateDocumentSelector", \
                                                                         "Are you sure you want to delete '{0}' template?" \
                                                                         "This action cannot be undone.\nClick Yes to proceed " \
                                                                         "or No to cancel.".format(templateName)), 
                                     QMessageBox.Yes|QMessageBox.No)
        
        if result == QMessageBox.No:
            return
        
        status = self._deleteDocument(filePath)
        
        if status:
            #Remove item from list using model index row number
            selectedDocNameIndices = self.lstDocs.selectionModel().selectedRows(0)
            row = selectedDocNameIndices[0].row()
            self._docItemModel.removeRow(row)
            self.notifBar.insertSuccessNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "'{0}' template has been successfully removed".format(templateName)))
        
        else:
            self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "Error: '{0}' template could not be removed".format(templateName)))
    
    def onAccept(self):
        """
        Slot raised to close the dialog only when a selection has been made by the user.
        """
        self.notifBar.clear()
        
        if self.documentMapping() == None:
            self.notifBar.insertErrorNotification(QApplication.translate("TemplateDocumentSelector", \
                                                                         "Please select a document"))
            return
        
        self.accept()
        
    def _selectedMappings(self):
        """
        Returns the model indices for the selected row.
        """
        selectedDocNameIndices = self.lstDocs.selectionModel().selectedRows(0)
        selectedFilePathIndices = self.lstDocs.selectionModel().selectedRows(1)
        
        if len(selectedDocNameIndices) == 0:
            return None
        
        docNameIndex = selectedDocNameIndices[0]
        filePathIndex = selectedFilePathIndices[0]
        
        return (docNameIndex,filePathIndex)
    
    def documentMapping(self):
        """
        Returns a tuple containing the selected document name and the corresponding file name.
        """
        mIndices = self._selectedMappings()
        
        if mIndices == None:
            return None
        
        docNameItem = self._docItemModel.itemFromIndex(mIndices[0])
        filePathItem = self._docItemModel.itemFromIndex(mIndices[1])
        
        return (docNameItem.text(),filePathItem.text())
    
    def _editTemplate(self,templatePath,newName):
        """
        Updates the template document to use the new name.
        """
        templateFile = QFile(templatePath)
        
        if not templateFile.open(QIODevice.ReadOnly):
            QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector","Open Operation Error"), \
                                            "{0}\n{1}".format(QApplication.translate("TemplateDocumentSelector","Cannot read template file."), \
                                                      templateFile.errorString()
                                                      ))
            return (False,"")
         
        templateDoc = QDomDocument()
        
        if templateDoc.setContent(templateFile):
            composerElement = templateDoc.documentElement()
            titleAttr = composerElement.attributeNode("_title")
            if not titleAttr.isNull():
                titleAttr.setValue(newName)
                
            #Try remove file
            status = templateFile.remove()
            
            if not status:
                return (False,"")
            
            #Create new file
            newTemplatePath = self._composerTemplatesPath() + "/" + newName + ".sdt"  
            newTemplateFile = QFile(newTemplatePath)
            
            if not newTemplateFile.open(QIODevice.WriteOnly):
                QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector","Save Operation Error"), \
                                                "{0}\n{1}".format(QApplication.translate("TemplateDocumentSelector","Could not save template file."), \
                                                          newTemplateFile.errorString()
                                                          ))
                return (False,"")
            
            if newTemplateFile.write(templateDoc.toByteArray()) == -1:
                QMessageBox.critical(self, QApplication.translate("TemplateDocumentSelector","Save Error"), \
                                                QApplication.translate("TemplateDocumentSelector","Could not save template file."))
                return (False,"")
            
            newTemplateFile.close()  
            
            return (True,newTemplatePath)
    
    def _deleteDocument(self,templatePath):
        """
        Delete the document template from the file system.
        """
        docFile = QFile(templatePath)
        
        return docFile.remove()
    
    def _composerTemplatesPath(self):
        """
        Reads the path of composer templates in the registry.
        """
        regConfig = RegistryConfig()
        keyName = "ComposerTemplates"
        
        valueCollection = regConfig.read([keyName])
        
        if len(valueCollection) == 0:
            return None
        
        else:
            return valueCollection[keyName]
Esempio n. 8
0
class FileTypes(base2, form2):
    def __init__(self, parent=None):
        super(base2, self).__init__(parent)
        self.setupUi(self)

        self.model = QStandardItemModel()
        self.model.itemChanged.connect(self.on_item_changed)
        self.model.setHorizontalHeaderItem(0, QStandardItem(""))
        self.model_init()

        self.saveButton.clicked.connect(self.save)
        self.okCancelBox.accepted.connect(self.accept)
        self.okCancelBox.rejected.connect(self.reject)
        self.treeView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.treeView.customContextMenuRequested.connect(self.openMenu)
        self.treeView.setToolTip(
            'Here you can select file types that you want to find. Also you can\nadd new category or file type. Click right button on it.'
        )

    def model_init(self):
        categories = {}
        if not categories:
            with open('categories.json') as f:
                categories = load(f)

        for element in categories:
            catItem = QStandardItem(element.keys()[0])
            catItem.setCheckable(True)
            catItem.setCheckState(element[element.keys()[0]])
            for type_name, check_state in element["Types"].items():
                typeItem = QStandardItem(type_name)
                typeItem.setCheckable(True)
                typeItem.setCheckState(check_state)
                catItem.appendRow(typeItem)
            self.model.appendRow(catItem)
        self.treeView.setModel(self.model)
        self.submit_file_types()

    def quit(self):
        self.close()

    def on_item_changed(self, item):
        if item.checkState() == Qt.Checked:
            if item.hasChildren():
                for row in range(item.rowCount()):
                    item.child(row).setCheckState(Qt.Checked)
            else:
                item.parent().setCheckState(Qt.PartiallyChecked)

        elif item.checkState() == Qt.Unchecked:
            if item.hasChildren():
                for row in range(item.rowCount()):
                    item.child(row).setCheckState(Qt.Unchecked)
            else:
                children = range(item.parent().rowCount())
                children.pop(item.index().row())
                for row in children:
                    if item.parent().child(row).checkState():
                        return
                item.parent().setCheckState(Qt.Unchecked)

    def submit_file_types(self):
        categories = []
        root = self.model.invisibleRootItem()

        for num_cat in range(root.rowCount()):
            category = root.child(num_cat, 0)
            categories.append({
                str(category.text()): category.checkState(),
                "Types": {}
            })
            for num_type in range(category.rowCount()):
                type = category.child(num_type, 0)
                categories[-1]["Types"].update(
                    {str(type.text()): type.checkState()})
        return categories

    def openMenu(self, position):
        level = 0
        index = self.treeView.selectedIndexes()[0]
        while index.parent().isValid():
            index = index.parent()
            level += 1

        menu = QMenu()
        if level == 0:
            menu.addAction(self.tr("Add category"), self.add_category)
            menu.addAction(self.tr("Add type"), self.add_type)
            menu.addAction(self.tr("Remove"), self.remove)
        elif level == 1:
            menu.addAction(self.tr("Add type"), self.add_type)
            menu.addAction(self.tr("Remove"), self.remove)

        menu.exec_(self.treeView.viewport().mapToGlobal(position))

    def add_category(self):
        text, ok = QInputDialog.getText(self, 'Create new category',
                                        'Category name:')
        if ok:
            catItem = QStandardItem(text)
            catItem.setCheckable(True)
            self.model.appendRow(catItem)
            #self.label.setText(unicode(text))

    def add_type(self):
        text, ok = QInputDialog.getText(self, 'Add new type', 'Postfix:')
        if ok:
            catType = QStandardItem(text)
            catType.setCheckable(True)
            index = self.treeView.selectedIndexes()[0]
            if self.model.itemFromIndex(index).hasChildren():
                self.model.itemFromIndex(index).appendRow(catType)
            else:
                self.model.itemFromIndex(index).parent().appendRow(catType)

    def save(self):
        with open('categories.json', 'w') as f:
            dump(self.submit_file_types(), f)

    def remove(self):
        index = self.treeView.selectedIndexes()[0]
        parent = self.model.itemFromIndex(index).parent()
        if parent:
            self.model.removeRow(index.row(), parent.index())
        else:
            parent = self.model.invisibleRootItem()
            self.model.removeRow(index.row(), parent.index())

    @staticmethod
    def call():
        dialog = FileTypes()
        result = dialog.exec_()
        categories = dialog.submit_file_types()
        return categories, result == QDialog.Accepted
class DlgComplexAreas(QDialog):
    def __init__(self, parent):
        QDialog.__init__(self, parent)
        self.ui = Ui_DlgComplexAreas()
        self.ui.setupUi(self)

        self.stdItemModel = QStandardItemModel()
        self.ui.lstAreas.setModel(self.stdItemModel)

              
        ''' buttons clicked connect '''
        self.ui.btnAddPrimaryArea.clicked.connect(self.btnAddPrimaryArea_Click)
        self.ui.btnAddSecondaryArea.clicked.connect(self.btnAddSecondaryArea_Click)
        self.ui.btnRemove.clicked.connect(self.btnRemove_Click)
        self.ui.btnCaptureTrack.clicked.connect(self.btnCaptureTrack_Click)
        self.ui.buttonBoxOkCancel.accepted.connect(self.acceptEvent)
        self.ui.buttonBoxOkCancel.rejected.connect(self.rejectedEvent)
        self.ui.txtTrack.textChanged.connect(self.txtTrack_TextChanged)
        self.ui.lstAreas.clicked.connect(self.lstAreas_Click)

        self.ui.btnCaptureTrack.clicked.connect(self.captureTrack)

        self.complexObstacleArea = ComplexObstacleArea()
        self.itemCount = 0
        self.selectedModelIndex = None
        self.resultPolylineAreaListForDrawing = []
        self.method_9()


        self.constructionLayer = AcadHelper.createVectorLayer("TempComplexObstacleAreaLayer");
        QgisHelper.appendToCanvas(define._canvas, [self.constructionLayer], "Temp")
    def txtTrack_TextChanged(self):
        self.complexObstacleArea[self.selectedModelIndex.row()].nominalTrack = Unit.smethod_0(float(self.ui.txtTrack.text()));
    def btnAddPrimaryArea_Click(self):
        if QMessageBox.question(self, "Question", "Please click \"Yes\" if you want to create new area.\nPlease click \"No\" if you want to select any area.", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes:
            # if self.comboBox.currentIndex() == ProtectionAreaType.Primary:
            obstacleAreaJig= ObstacleAreaJigCreateArea(define._canvas, ProtectionAreaType.Primary)
            define._canvas.setMapTool(obstacleAreaJig)
            self.connect(obstacleAreaJig, SIGNAL("outputResult"), self.AreaResult)
            # elif self.comboBox.currentIndex() == ProtectionAreaType.Secondary:
        else:
            obstacleAreaJig= ObstacleAreaJigSelectArea(define._canvas, ProtectionAreaType.Primary)
            define._canvas.setMapTool(obstacleAreaJig)
            self.connect(obstacleAreaJig, SIGNAL("outputResult"), self.AreaResult)
    def btnAddSecondaryArea_Click(self):
        if QMessageBox.question(self, "Question", "Please click \"Yes\" if you want to create new area.\nPlease click \"No\" if you want to select any area.", QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes:
            # if self.comboBox.currentIndex() == ProtectionAreaType.Primary:
            obstacleAreaJig= ObstacleAreaJigCreateArea(define._canvas, ProtectionAreaType.Secondary)
            define._canvas.setMapTool(obstacleAreaJig)
            self.connect(obstacleAreaJig, SIGNAL("outputResult"), self.AreaResult)
            # elif self.comboBox.currentIndex() == ProtectionAreaType.Secondary:
        else:
            obstacleAreaJig= ObstacleAreaJigSelectArea(define._canvas, ProtectionAreaType.Secondary)
            define._canvas.setMapTool(obstacleAreaJig)
            self.connect(obstacleAreaJig, SIGNAL("outputResult"), self.AreaResult)
    def AreaResult(self, area, rubberBand):
        if area != None:
            rubberBand.setFillColor( QColor(46, 64, 142, 100) )
            rubberBand.setBorderColor( QColor(0, 10, 238) )
            define._canvas.refresh()

            QgisHelper.ClearRubberBandInCanvas(define._canvas)
            self.complexObstacleArea.Add(area)
            self.stdItemModel.setItem(self.itemCount, QStandardItem(area.ToString()))
            # polygon  = rubberBand.asGeometry()
            # lineList = polygon.asPolygon()
            # self.resultPolylineAreaListForDrawing.append(PolylineArea(lineList[0]))
            self.itemCount += 1

            AcadHelper.setGeometryAndAttributesInLayer(self.constructionLayer, area.PreviewArea, True)
            # self.constructionLayer.startEditing()
            # feature = QgsFeature()
            # feature.setGeometry(QgsGeometry.fromPolyline(area.PreviewArea.method_14_closed()))
            # self.constructionLayer.addFeature(feature)
            # self.constructionLayer.commitChanges()
    def btnRemove_Click(self):
        if self.selectedModelIndex != None:
            if QMessageBox.question(self, "Question", "Do you want to remove the selected item?", QMessageBox.Ok | QMessageBox.Cancel) == QMessageBox.Ok:
                n = self.selectedModelIndex.row()

                self.complexObstacleArea.pop(n)
                self.stdItemModel.removeRow(self.selectedModelIndex.row())
                self.itemCount -= 1

                self.constructionLayer = AcadHelper.createVectorLayer("TempComplexObstacleAreaLayer")
                for area in self.complexObstacleArea:
                    AcadHelper.setGeometryAndAttributesInLayer(self.constructionLayer, area.PreviewArea, True)
                QgisHelper.appendToCanvas(define._canvas, [self.constructionLayer], "Temp")
                QgisHelper.ClearRubberBandInCanvas(define._canvas)



            pass
    def btnCaptureTrack_Click(self):
        pass
    def acceptEvent(self):
        QgisHelper.removeGroupFromName(define._mLayerTreeView, "Temp")

        # for node in define._mLayerTreeView.selectedNodes( True ) :
        #     item = node.parent()
        #     item._class_ = QgsLayerTreeGroup
        #     if isinstance(item, QgsLayerTreeGroup):
        #         if node.name() == "Temp":
        #             node.parent().removeChildNode( node )
        # QgisHelper.removeFromCanvas(define._canvas, [self.constructionLayer])
        self.accept()
    def rejectedEvent(self):
        QgisHelper.removeGroupFromName(define._mLayerTreeView, "Temp")
        self.reject()
    def lstAreas_Click(self, modelIndex):
        self.selectedModelIndex = modelIndex
        self.method_9()
    def method_9(self):
        if self.selectedModelIndex == None:
            self.ui.frame_Track.setVisible(False)
            return
        else:
            selectedArea = self.complexObstacleArea[self.selectedModelIndex.row()]
            QgisHelper.ClearRubberBandInCanvas(define._canvas)
            rBand = QgsRubberBand(define._canvas, QGis.Polygon)

            for point in selectedArea.PreviewArea.method_14_closed():
                rBand.addPoint(point)
            rBand.setFillColor( QColor(46, 64, 142, 100) )
            rBand.setBorderColor( QColor(0, 10, 238) )
            rBand.show()


            if not isinstance(selectedArea, SecondaryObstacleArea) or  not isinstance(selectedArea.area, SecondaryAreaStraight):
                self.ui.frame_Track.setVisible(False)
                return
            else:
                self.ui.txtTrack.setText(str(round(Unit.smethod_1(selectedArea.nominalTrack), 4)));
                self.ui.frame_Track.setVisible(True)
        # self.pnlTrack.Visible = true;
        # selectedItem = self.lstAreas.SelectedItem as SecondaryObstacleArea;
        # if (selectedItem == null || !(selectedItem.Area is SecondaryObstacleArea.SecondaryAreaStraight))
        # {
        #     self.pnlTrack.Value = double.NaN;
        #     self.pnlTrack.Visible = false;
        #     return;
        # }
        # self.pnlTrack.Value = Units.smethod_1(selectedItem.NominalTrack);
        # self.pnlTrack.Visible = true;
    def captureTrack(self):
        captureTrackTool= CaptureBearingTool(define._canvas, self.ui.txtTrack)
        define._canvas.setMapTool(captureTrackTool)
Esempio n. 10
0
class SetupDialog(QDialog, Ui_SetupDialog):
    """
        Function and Event handling class for the Ui_SetupDialog.
    """
    def __init__(self, parent):
        QDialog.__init__(self, parent)

        self._gui_logger = GUILogger("GUILogger", logging.INFO)
        self._gui_job = None
        EventLogger.add_logger(self._gui_logger)

        # FIXME better way to find interval and uids in tree_widget?!
        self.__tree_interval_tooltip = "Update interval in seconds"
        self.__tree_uid_tooltip = "UID cannot be empty"
        self.data_logger_thread = None
        self.tab_debug_warning = False

        self.device_dialog = None

        self.host_infos = None
        self.last_host = None
        self.host_index_changing = None

        self.setupUi(self)

        self.model_data = QStandardItemModel(self)
        self.model_data.setHorizontalHeaderLabels(
            ['Time', 'Name', 'UID', 'Var', 'Raw', 'Unit'])
        self.table_data.setModel(self.model_data)
        self.table_data.setColumnWidth(0, 160)
        self.table_data.setColumnWidth(1, 170)
        self.table_data.setColumnWidth(2, 50)
        self.table_data.setColumnWidth(3, 110)
        self.table_data.setColumnWidth(4, 70)
        self.table_data.setColumnWidth(5, 100)

        self.model_devices = QStandardItemModel(self)
        self.model_devices.setHorizontalHeaderLabels(['Device', 'Value'])
        self.tree_devices.setModel(self.model_devices)
        self.tree_devices.setColumnWidth(0, 300)

        self.widget_initialization()

        self.btn_start_logging.setIcon(
            QIcon(load_pixmap('data_logger/start-icon.png')))

        timestamp = int(time.time())
        self.edit_csv_file_name.setText(
            os.path.join(get_home_path(),
                         'logger_data_{0}.csv'.format(timestamp)))
        self.edit_log_file_name.setText(
            os.path.join(get_home_path(),
                         'logger_debug_{0}.log'.format(timestamp)))

        self.combo_data_time_format.addItem(
            utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso')
        self.combo_data_time_format.addItem(
            utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix')

        self.combo_debug_time_format.addItem(
            utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_debug_time_format.addItem(
            utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_debug_time_format.addItem(
            utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso')
        self.combo_debug_time_format.addItem(
            utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix')

        self.combo_log_level.addItem('Debug', 'debug')
        self.combo_log_level.addItem('Info', 'info')
        self.combo_log_level.addItem('Warning', 'warning')
        self.combo_log_level.addItem('Error', 'error')
        self.combo_log_level.addItem('Critical', 'critical')
        self.combo_log_level.setCurrentIndex(0)  # debug

        self.combo_debug_level.addItem('Debug', logging.DEBUG)
        self.combo_debug_level.addItem('Info', logging.INFO)
        self.combo_debug_level.addItem('Warning', logging.WARNING)
        self.combo_debug_level.addItem('Error', logging.ERROR)
        self.combo_debug_level.addItem('Critical', logging.CRITICAL)
        self.combo_debug_level.setCurrentIndex(1)  # info

        self.update_ui_state()

    def update_ui_state(self):
        data_to_csv_file = self.check_data_to_csv_file.isChecked()
        debug_to_log_file = self.check_debug_to_log_file.isChecked()

        self.label_csv_file_name.setVisible(data_to_csv_file)
        self.edit_csv_file_name.setVisible(data_to_csv_file)
        self.btn_browse_csv_file_name.setVisible(data_to_csv_file)

        self.label_log_file_name.setVisible(debug_to_log_file)
        self.edit_log_file_name.setVisible(debug_to_log_file)
        self.btn_browse_log_file_name.setVisible(debug_to_log_file)
        self.label_log_level.setVisible(debug_to_log_file)
        self.combo_log_level.setVisible(debug_to_log_file)

    def widget_initialization(self):
        """
            Sets default values for some widgets
        """
        # Login data
        self.host_info_initialization()

        self.signal_initialization()

    def signal_initialization(self):
        """
            Init of all important Signals and connections.
        """
        # Buttons
        self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked)
        self.btn_save_config.clicked.connect(self.btn_save_config_clicked)
        self.btn_load_config.clicked.connect(self.btn_load_config_clicked)
        self.check_data_to_csv_file.stateChanged.connect(self.update_ui_state)
        self.check_debug_to_log_file.stateChanged.connect(self.update_ui_state)
        self.btn_browse_csv_file_name.clicked.connect(
            self.btn_browse_csv_file_name_clicked)
        self.btn_browse_log_file_name.clicked.connect(
            self.btn_browse_log_file_name_clicked)
        self.btn_clear_debug.clicked.connect(self.btn_clear_debug_clicked)
        self.combo_debug_level.currentIndexChanged.connect(
            self.combo_debug_level_changed)
        self.btn_add_device.clicked.connect(self.btn_add_device_clicked)
        self.btn_remove_device.clicked.connect(self.btn_remove_device_clicked)
        self.btn_remove_all_devices.clicked.connect(
            self.btn_remove_all_devices_clicked)

        self.tab_widget.currentChanged.connect(self.tab_reset_warning)
        self.btn_clear_data.clicked.connect(self.btn_clear_data_clicked)

        self.connect(self._gui_logger,
                     QtCore.SIGNAL(GUILogger.SIGNAL_NEW_MESSAGE),
                     self.add_debug_message)
        self.connect(self._gui_logger,
                     QtCore.SIGNAL(GUILogger.SIGNAL_NEW_MESSAGE_TAB_HIGHLIGHT),
                     self.highlight_debug_tab)

        self.combo_host.currentIndexChanged.connect(self._host_index_changed)
        self.spin_port.valueChanged.connect(self._port_changed)

    def host_info_initialization(self):
        """
            initialize host by getting information out of brickv.config
        """
        self.host_infos = config.get_host_infos(config.HOST_INFO_COUNT)
        self.host_index_changing = True

        for host_info in self.host_infos:
            self.combo_host.addItem(host_info.host)

        self.last_host = None
        self.combo_host.setCurrentIndex(0)
        self.spin_port.setValue(self.host_infos[0].port)
        self.host_index_changing = False

    def btn_start_logging_clicked(self):
        """
            Start/Stop of the logging process
        """
        if (self.data_logger_thread
                is not None) and (not self.data_logger_thread.stopped):
            self.btn_start_logging.clicked.disconnect()

            self.data_logger_thread.stop()
            self._reset_stop()

        elif self.data_logger_thread is None:
            from brickv.data_logger import main

            self._gui_job = GuiDataJob(name="GuiData-Writer")
            self.connect(self._gui_job,
                         QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA),
                         self.table_add_row)

            self.data_logger_thread = main.main(
                None, GuiConfigHandler.create_config(self), self._gui_job)

            if self.data_logger_thread is not None:
                self.btn_start_logging.setText("Stop Logging")
                self.btn_start_logging.setIcon(
                    QIcon(load_pixmap('data_logger/stop-icon.png')))
                self.tab_devices.setEnabled(False)
                self.tab_setup.setEnabled(False)
                self.tab_widget.setCurrentIndex(
                    self.tab_widget.indexOf(self.tab_data))
                self.tab_reset_warning()

    def _reset_stop(self):
        self.tab_devices.setEnabled(True)
        self.tab_setup.setEnabled(True)
        self.btn_start_logging.setText("Start Logging")
        self.btn_start_logging.setIcon(
            QIcon(load_pixmap('data_logger/start-icon.png')))

        self.disconnect(self._gui_job,
                        QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA),
                        self.table_add_row)
        self.data_logger_thread = None
        self._gui_job = None

        self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked)

    def btn_save_config_clicked(self):
        filename = get_save_file_name(get_main_window(), 'Save Config',
                                      get_home_path(), 'JSON Files (*.json)')

        if len(filename) == 0:
            return

        if not filename.lower().endswith('.json'):
            filename += '.json'

        config = GuiConfigHandler.create_config(self)

        if not save_config(config, filename):
            QMessageBox.warning(
                get_main_window(), 'Save Config',
                'Could not save config to file! See Debug tab for details.',
                QMessageBox.Ok)

    def btn_load_config_clicked(self):
        filename = get_open_file_name(get_main_window(), 'Load Config',
                                      get_home_path(), 'JSON Files (*.json)')

        if len(filename) == 0:
            return

        config = load_and_validate_config(filename)

        if config == None:
            QMessageBox.warning(
                get_main_window(), 'Load Config',
                'Could not load config from file! See Debug tab for details.',
                QMessageBox.Ok)
            return

        self.update_setup_tab(config)
        self.update_devices_tab(config)

    def btn_browse_csv_file_name_clicked(self):
        if len(self.edit_csv_file_name.text()) > 0:
            last_dir = os.path.dirname(
                os.path.realpath(self.edit_csv_file_name.text()))
        else:
            last_dir = get_home_path()

        filename = get_save_file_name(get_main_window(), 'Choose CSV File',
                                      last_dir, "CSV Files (*.csv)")

        if len(filename) > 0:
            if not filename.lower().endswith('.csv'):
                filename += '.csv'

            self.edit_csv_file_name.setText(filename)

    def btn_browse_log_file_name_clicked(self):
        if len(self.edit_log_file_name.text()) > 0:
            last_dir = os.path.dirname(
                os.path.realpath(self.edit_log_file_name.text()))
        else:
            last_dir = get_home_path()

        filename = get_save_file_name(get_main_window(), 'Choose Log File',
                                      last_dir, "Log Files (*.log)")

        if len(filename) > 0:
            if not filename.lower().endswith('.log'):
                filename += '.log'

            self.edit_log_file_name.setText(filename)

    def btn_add_device_clicked(self):
        """
            Opens the DeviceDialog in Add-Mode.
        """
        if self.device_dialog is None:
            self.device_dialog = DeviceDialog(self)

        self.device_dialog.btn_refresh_clicked()
        self.device_dialog.show()

    def btn_remove_device_clicked(self):
        selection = self.tree_devices.selectionModel().selectedIndexes()

        while len(selection) > 0:
            index = selection[0]

            while index.parent() != self.model_devices.invisibleRootItem(
            ).index():
                index = index.parent()

            self.model_devices.removeRows(index.row(), 1)

            # get new selection, because row removal might invalid indices
            selection = self.tree_devices.selectionModel().selectedIndexes()

    def btn_remove_all_devices_clicked(self):
        self.model_devices.removeRows(0, self.model_devices.rowCount())

    def btn_clear_data_clicked(self):
        self.model_data.removeRows(0, self.model_data.rowCount())

    def tab_reset_warning(self):
        """
            Resets the Warning @ the debug tab.
        """
        if not self.tab_debug_warning or self.tab_widget.currentWidget(
        ).objectName() != self.tab_debug.objectName():
            return

        self.tab_debug_warning = False

        self.tab_set(self.tab_widget.indexOf(self.tab_debug),
                     self.palette().color(QPalette.WindowText), None)

    def combo_debug_level_changed(self):
        """
            Changes the log level dynamically.
        """
        self._gui_logger.level = self.combo_debug_level.itemData(
            self.combo_debug_level.currentIndex())

    def tab_set(self, tab_index, color, icon=None):
        """
            Sets the font Color and an icon, if given, at a specific tab.
        """
        from PyQt4.QtGui import QIcon

        self.tab_widget.tabBar().setTabTextColor(tab_index, color)
        if icon is not None:
            self.tab_widget.setTabIcon(tab_index, QIcon(icon))
        else:
            self.tab_widget.setTabIcon(tab_index, QIcon())

    def _host_index_changed(self, i):
        """
            Persists host information changes like in brickv.mainwindow
            Changes port if the host was changed
        """
        if i < 0:
            return

        self.host_index_changing = True
        self.spin_port.setValue(self.host_infos[i].port)
        self.host_index_changing = False

    def _port_changed(self, value):
        """
            Persists host information changes like in brickv.mainwindow
        """
        if self.host_index_changing:
            return

        i = self.combo_host.currentIndex()
        if i < 0:
            return

        self.host_infos[i].port = self.spin_port.value()

    def update_setup_tab(self, config):
        EventLogger.debug('Updating setup tab from config')

        self.combo_host.setEditText(config['hosts']['default']['name'])
        self.spin_port.setValue(config['hosts']['default']['port'])

        self.combo_data_time_format.setCurrentIndex(
            max(
                self.combo_data_time_format.findData(
                    config['data']['time_format']), 0))
        self.check_data_to_csv_file.setChecked(
            config['data']['csv']['enabled'])
        self.edit_csv_file_name.setText(
            config['data']['csv']['file_name'].decode('utf-8'))

        self.combo_debug_time_format.setCurrentIndex(
            max(
                self.combo_debug_time_format.findData(
                    config['debug']['time_format']), 0))
        self.check_debug_to_log_file.setChecked(
            config['debug']['log']['enabled'])
        self.edit_log_file_name.setText(
            config['debug']['log']['file_name'].decode('utf-8'))
        self.combo_log_level.setCurrentIndex(
            max(
                self.combo_debug_time_format.findData(
                    config['debug']['log']['level']), 0))

    def update_devices_tab(self, config):
        EventLogger.debug('Updating devices tab from config')

        self.model_devices.removeRows(0, self.model_data.rowCount())

        for device in config['devices']:
            self.add_device_to_tree(device)

    def add_device_to_tree(self, device):
        # check if device is already added
        if len(device['uid']) > 0:
            for row in range(self.model_devices.rowCount()):
                existing_name = self.model_devices.item(row, 0).text()
                exisitng_uid = self.tree_devices.indexWidget(
                    self.model_devices.item(row, 1).index()).text()

                if device['name'] == existing_name and device[
                        'uid'] == exisitng_uid:
                    EventLogger.info(
                        'Ignoring duplicate device "{0}" with UID "{1}"'.
                        format(device['name'], device['uid']))
                    return

        # add device
        name_item = QStandardItem(device['name'])
        uid_item = QStandardItem('')

        self.model_devices.appendRow([name_item, uid_item])

        edit_uid = QLineEdit()
        edit_uid.setPlaceholderText('Enter UID')
        edit_uid.setValidator(
            QRegExpValidator(QRegExp(
                '^[{0}]{{1,6}}$'.format(BASE58))))  # FIXME: use stricter logic
        edit_uid.setText(device['uid'])

        self.tree_devices.setIndexWidget(uid_item.index(), edit_uid)

        value_specs = device_specs[device['name']]['values']
        parent_item = QStandardItem('Values')

        name_item.appendRow([parent_item, QStandardItem('')])
        self.tree_devices.expand(parent_item.index())

        # add values
        for value_spec in value_specs:
            value_name_item = QStandardItem(value_spec['name'])
            value_interval_item = QStandardItem('')

            parent_item.appendRow([value_name_item, value_interval_item])

            spinbox_interval = QSpinBox()
            spinbox_interval.setRange(0, (1 << 31) - 1)
            spinbox_interval.setSingleStep(1)
            spinbox_interval.setValue(
                device['values'][value_spec['name']]['interval'])
            spinbox_interval.setSuffix(' seconds')

            self.tree_devices.setIndexWidget(value_interval_item.index(),
                                             spinbox_interval)

            if value_spec['subvalues'] != None:
                for subvalue_name in value_spec['subvalues']:
                    subvalue_name_item = QStandardItem(subvalue_name)
                    subvalue_check_item = QStandardItem('')

                    value_name_item.appendRow(
                        [subvalue_name_item, subvalue_check_item])

                    check_subvalue = QCheckBox()
                    check_subvalue.setChecked(device['values'][
                        value_spec['name']]['subvalues'][subvalue_name])

                    self.tree_devices.setIndexWidget(
                        subvalue_check_item.index(), check_subvalue)

        self.tree_devices.expand(name_item.index())

        # add options
        option_specs = device_specs[device['name']]['options']

        if option_specs != None:
            parent_item = QStandardItem('Options')

            name_item.appendRow([parent_item, QStandardItem('')])

            for option_spec in option_specs:
                option_name_item = QStandardItem(option_spec['name'])
                option_widget_item = QStandardItem('')

                parent_item.appendRow([option_name_item, option_widget_item])

                if option_spec['type'] == 'choice':
                    widget_option_value = QComboBox()

                    for option_value_spec in option_spec['values']:
                        widget_option_value.addItem(
                            option_value_spec[0].decode('utf-8'),
                            option_value_spec[1])

                    widget_option_value.setCurrentIndex(
                        widget_option_value.findText(device['options'][
                            option_spec['name']]['value'].decode('utf-8')))
                elif option_spec['type'] == 'int':
                    widget_option_value = QSpinBox()
                    widget_option_value.setRange(option_spec['minimum'],
                                                 option_spec['maximum'])
                    widget_option_value.setSuffix(option_spec['suffix'])
                    widget_option_value.setValue(
                        device['options'][option_spec['name']]['value'])
                elif option_spec['type'] == 'bool':
                    widget_option_value = QCheckBox()
                    widget_option_value.setChecked(
                        device['options'][option_spec['name']]['value'])

                self.tree_devices.setIndexWidget(option_widget_item.index(),
                                                 widget_option_value)

    def add_debug_message(self, message):
        self.text_debug.append(message)

        while self.text_debug.document().blockCount() > 1000:
            cursor = QTextCursor(self.text_debug.document().begin())
            cursor.select(QTextCursor.BlockUnderCursor)
            cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor)
            cursor.removeSelectedText()

        if self.checkbox_debug_auto_scroll.isChecked():
            self.text_debug.verticalScrollBar().setValue(
                self.text_debug.verticalScrollBar().maximum())

    def btn_clear_debug_clicked(self):
        self.text_debug.clear()

    def highlight_debug_tab(self):
        """
            SIGNAL function:
            Highlight the debug tab when an error occurs.
        """
        if not self.tab_debug_warning and self.tab_widget.currentWidget(
        ).objectName() != self.tab_debug.objectName():
            self.tab_debug_warning = True
            self.tab_set(
                self.tab_widget.indexOf(self.tab_debug), QColor(255, 0, 0),
                os.path.join(get_resources_path(), "warning-icon.png"))

    def table_add_row(self, csv_data):
        """
            SIGNAL function:
            Adds new CSV Data into the Table.
        """
        rows = self.model_data.rowCount()

        while rows >= 1000:
            self.model_data.removeRow(0)
            rows = self.model_data.rowCount()

        row_number = None

        if rows > 0:
            try:
                row_number = int(
                    self.model_data.headerData(rows - 1, Qt.Vertical))
            except ValueError:
                pass

        self.model_data.appendRow([
            QStandardItem(csv_data.timestamp),
            QStandardItem(csv_data.name),
            QStandardItem(csv_data.uid),
            QStandardItem(csv_data.var_name),
            QStandardItem(str(csv_data.raw_data)),
            QStandardItem(csv_data.var_unit.decode('utf-8'))
        ])

        if row_number != None:
            self.model_data.setHeaderData(rows, Qt.Vertical,
                                          str(row_number + 1))

        if self.checkbox_data_auto_scroll.isChecked():
            self.table_data.scrollToBottom()
Esempio n. 11
0
class SetupDialog(QDialog, Ui_SetupDialog):
    """
        Function and Event handling class for the Ui_SetupDialog.
    """

    def __init__(self, parent):
        QDialog.__init__(self, parent)

        self._gui_logger = GUILogger("GUILogger", logging.INFO)
        self._gui_job = None
        EventLogger.add_logger(self._gui_logger)

        # FIXME better way to find interval and uids in tree_widget?!
        self.__tree_interval_tooltip = "Update interval in seconds"
        self.__tree_uid_tooltip = "UID cannot be empty"
        self.data_logger_thread = None
        self.tab_debug_warning = False

        self.device_dialog = None

        self.host_infos = None
        self.last_host = None
        self.host_index_changing = None

        self.setupUi(self)

        self.model_data = QStandardItemModel(self)
        self.model_data.setHorizontalHeaderLabels(['Time', 'Name', 'UID', 'Var', 'Raw', 'Unit'])
        self.table_data.setModel(self.model_data)
        self.table_data.setColumnWidth(0, 160)
        self.table_data.setColumnWidth(1, 170)
        self.table_data.setColumnWidth(2, 50)
        self.table_data.setColumnWidth(3, 110)
        self.table_data.setColumnWidth(4, 70)
        self.table_data.setColumnWidth(5, 100)

        self.model_devices = QStandardItemModel(self)
        self.model_devices.setHorizontalHeaderLabels(['Device', 'Value'])
        self.tree_devices.setModel(self.model_devices)
        self.tree_devices.setColumnWidth(0, 300)

        self.widget_initialization()

        self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/start-icon.png')))

        timestamp = int(time.time())
        self.edit_csv_file_name.setText(os.path.join(get_home_path(), 'logger_data_{0}.csv'.format(timestamp)))
        self.edit_log_file_name.setText(os.path.join(get_home_path(), 'logger_debug_{0}.log'.format(timestamp)))

        self.combo_data_time_format.addItem(utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_data_time_format.addItem(utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_data_time_format.addItem(utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso')
        self.combo_data_time_format.addItem(utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix')

        self.combo_debug_time_format.addItem(utils.timestamp_to_de(timestamp) + ' (DD.MM.YYYY HH:MM:SS)', 'de')
        self.combo_debug_time_format.addItem(utils.timestamp_to_us(timestamp) + ' (MM/DD/YYYY HH:MM:SS)', 'us')
        self.combo_debug_time_format.addItem(utils.timestamp_to_iso(timestamp) + ' (ISO 8601)', 'iso')
        self.combo_debug_time_format.addItem(utils.timestamp_to_unix(timestamp) + ' (Unix)', 'unix')

        self.combo_log_level.addItem('Debug', 'debug')
        self.combo_log_level.addItem('Info', 'info')
        self.combo_log_level.addItem('Warning', 'warning')
        self.combo_log_level.addItem('Error', 'error')
        self.combo_log_level.addItem('Critical', 'critical')
        self.combo_log_level.setCurrentIndex(0) # debug

        self.combo_debug_level.addItem('Debug', logging.DEBUG)
        self.combo_debug_level.addItem('Info', logging.INFO)
        self.combo_debug_level.addItem('Warning', logging.WARNING)
        self.combo_debug_level.addItem('Error', logging.ERROR)
        self.combo_debug_level.addItem('Critical', logging.CRITICAL)
        self.combo_debug_level.setCurrentIndex(1) # info

        self.update_ui_state()

    def update_ui_state(self):
        data_to_csv_file = self.check_data_to_csv_file.isChecked()
        debug_to_log_file = self.check_debug_to_log_file.isChecked()

        self.label_csv_file_name.setVisible(data_to_csv_file)
        self.edit_csv_file_name.setVisible(data_to_csv_file)
        self.btn_browse_csv_file_name.setVisible(data_to_csv_file)

        self.label_log_file_name.setVisible(debug_to_log_file)
        self.edit_log_file_name.setVisible(debug_to_log_file)
        self.btn_browse_log_file_name.setVisible(debug_to_log_file)
        self.label_log_level.setVisible(debug_to_log_file)
        self.combo_log_level.setVisible(debug_to_log_file)

    def widget_initialization(self):
        """
            Sets default values for some widgets
        """
        # Login data
        self.host_info_initialization()

        self.signal_initialization()

    def signal_initialization(self):
        """
            Init of all important Signals and connections.
        """
        # Buttons
        self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked)
        self.btn_save_config.clicked.connect(self.btn_save_config_clicked)
        self.btn_load_config.clicked.connect(self.btn_load_config_clicked)
        self.check_data_to_csv_file.stateChanged.connect(self.update_ui_state)
        self.check_debug_to_log_file.stateChanged.connect(self.update_ui_state)
        self.btn_browse_csv_file_name.clicked.connect(self.btn_browse_csv_file_name_clicked)
        self.btn_browse_log_file_name.clicked.connect(self.btn_browse_log_file_name_clicked)
        self.btn_clear_debug.clicked.connect(self.btn_clear_debug_clicked)
        self.combo_debug_level.currentIndexChanged.connect(self.combo_debug_level_changed)
        self.btn_add_device.clicked.connect(self.btn_add_device_clicked)
        self.btn_remove_device.clicked.connect(self.btn_remove_device_clicked)
        self.btn_remove_all_devices.clicked.connect(self.btn_remove_all_devices_clicked)

        self.tab_widget.currentChanged.connect(self.tab_reset_warning)
        self.btn_clear_data.clicked.connect(self.btn_clear_data_clicked)

        self.connect(self._gui_logger, QtCore.SIGNAL(GUILogger.SIGNAL_NEW_MESSAGE), self.add_debug_message)
        self.connect(self._gui_logger, QtCore.SIGNAL(GUILogger.SIGNAL_NEW_MESSAGE_TAB_HIGHLIGHT),
                     self.highlight_debug_tab)

        self.combo_host.currentIndexChanged.connect(self._host_index_changed)
        self.spin_port.valueChanged.connect(self._port_changed)

    def host_info_initialization(self):
        """
            initialize host by getting information out of brickv.config
        """
        self.host_infos = config.get_host_infos(config.HOST_INFO_COUNT)
        self.host_index_changing = True

        for host_info in self.host_infos:
            self.combo_host.addItem(host_info.host)

        self.last_host = None
        self.combo_host.setCurrentIndex(0)
        self.spin_port.setValue(self.host_infos[0].port)
        self.host_index_changing = False

    def btn_start_logging_clicked(self):
        """
            Start/Stop of the logging process
        """
        if (self.data_logger_thread is not None) and (not self.data_logger_thread.stopped):
            self.btn_start_logging.clicked.disconnect()

            self.data_logger_thread.stop()
            self._reset_stop()

        elif self.data_logger_thread is None:
            from brickv.data_logger import main

            self._gui_job = GuiDataJob(name="GuiData-Writer")
            self.connect(self._gui_job, QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA), self.table_add_row)

            self.data_logger_thread = main.main(None, GuiConfigHandler.create_config(self), self._gui_job)

            if self.data_logger_thread is not None:
                self.btn_start_logging.setText("Stop Logging")
                self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/stop-icon.png')))
                self.tab_devices.setEnabled(False)
                self.tab_setup.setEnabled(False)
                self.tab_widget.setCurrentIndex(self.tab_widget.indexOf(self.tab_data))
                self.tab_reset_warning()

    def _reset_stop(self):
        self.tab_devices.setEnabled(True)
        self.tab_setup.setEnabled(True)
        self.btn_start_logging.setText("Start Logging")
        self.btn_start_logging.setIcon(QIcon(load_pixmap('data_logger/start-icon.png')))

        self.disconnect(self._gui_job, QtCore.SIGNAL(GuiDataJob.SIGNAL_NEW_DATA), self.table_add_row)
        self.data_logger_thread = None
        self._gui_job = None

        self.btn_start_logging.clicked.connect(self.btn_start_logging_clicked)

    def btn_save_config_clicked(self):
        filename = get_save_file_name(get_main_window(), 'Save Config',
                                      get_home_path(), 'JSON Files (*.json)')

        if len(filename) == 0:
            return

        if not filename.lower().endswith('.json'):
            filename += '.json'

        config = GuiConfigHandler.create_config(self)

        if not save_config(config, filename):
            QMessageBox.warning(get_main_window(), 'Save Config',
                                'Could not save config to file! See Debug tab for details.',
                                QMessageBox.Ok)

    def btn_load_config_clicked(self):
        filename = get_open_file_name(get_main_window(), 'Load Config',
                                      get_home_path(), 'JSON Files (*.json)')

        if len(filename) == 0:
            return

        config = load_and_validate_config(filename)

        if config == None:
            QMessageBox.warning(get_main_window(), 'Load Config',
                                'Could not load config from file! See Debug tab for details.',
                                QMessageBox.Ok)
            return

        self.update_setup_tab(config)
        self.update_devices_tab(config)

    def btn_browse_csv_file_name_clicked(self):
        if len(self.edit_csv_file_name.text()) > 0:
            last_dir = os.path.dirname(os.path.realpath(self.edit_csv_file_name.text()))
        else:
            last_dir = get_home_path()

        filename = get_save_file_name(get_main_window(), 'Choose CSV File',
                                      last_dir, "CSV Files (*.csv)")

        if len(filename) > 0:
            if not filename.lower().endswith('.csv'):
                filename += '.csv'

            self.edit_csv_file_name.setText(filename)

    def btn_browse_log_file_name_clicked(self):
        if len(self.edit_log_file_name.text()) > 0:
            last_dir = os.path.dirname(os.path.realpath(self.edit_log_file_name.text()))
        else:
            last_dir = get_home_path()

        filename = get_save_file_name(get_main_window(), 'Choose Log File',
                                      last_dir, "Log Files (*.log)")

        if len(filename) > 0:
            if not filename.lower().endswith('.log'):
                filename += '.log'

            self.edit_log_file_name.setText(filename)

    def btn_add_device_clicked(self):
        """
            Opens the DeviceDialog in Add-Mode.
        """
        if self.device_dialog is None:
            self.device_dialog = DeviceDialog(self)

        self.device_dialog.btn_refresh_clicked()
        self.device_dialog.show()

    def btn_remove_device_clicked(self):
        selection = self.tree_devices.selectionModel().selectedIndexes()

        while len(selection) > 0:
            index = selection[0]

            while index.parent() != self.model_devices.invisibleRootItem().index():
                index = index.parent()

            self.model_devices.removeRows(index.row(), 1)

            # get new selection, because row removal might invalid indices
            selection = self.tree_devices.selectionModel().selectedIndexes()

    def btn_remove_all_devices_clicked(self):
        self.model_devices.removeRows(0, self.model_devices.rowCount())

    def btn_clear_data_clicked(self):
        self.model_data.removeRows(0, self.model_data.rowCount())

    def tab_reset_warning(self):
        """
            Resets the Warning @ the debug tab.
        """
        if not self.tab_debug_warning or self.tab_widget.currentWidget().objectName() != self.tab_debug.objectName():
            return

        self.tab_debug_warning = False

        self.tab_set(self.tab_widget.indexOf(self.tab_debug), self.palette().color(QPalette.WindowText), None)

    def combo_debug_level_changed(self):
        """
            Changes the log level dynamically.
        """
        self._gui_logger.level = self.combo_debug_level.itemData(self.combo_debug_level.currentIndex())

    def tab_set(self, tab_index, color, icon=None):
        """
            Sets the font Color and an icon, if given, at a specific tab.
        """
        from PyQt4.QtGui import QIcon

        self.tab_widget.tabBar().setTabTextColor(tab_index, color)
        if icon is not None:
            self.tab_widget.setTabIcon(tab_index, QIcon(icon))
        else:
            self.tab_widget.setTabIcon(tab_index, QIcon())

    def _host_index_changed(self, i):
        """
            Persists host information changes like in brickv.mainwindow
            Changes port if the host was changed
        """
        if i < 0:
            return

        self.host_index_changing = True
        self.spin_port.setValue(self.host_infos[i].port)
        self.host_index_changing = False

    def _port_changed(self, value):
        """
            Persists host information changes like in brickv.mainwindow
        """
        if self.host_index_changing:
            return

        i = self.combo_host.currentIndex()
        if i < 0:
            return

        self.host_infos[i].port = self.spin_port.value()

    def update_setup_tab(self, config):
        EventLogger.debug('Updating setup tab from config')

        self.combo_host.setEditText(config['hosts']['default']['name'])
        self.spin_port.setValue(config['hosts']['default']['port'])

        self.combo_data_time_format.setCurrentIndex(max(self.combo_data_time_format.findData(config['data']['time_format']), 0))
        self.check_data_to_csv_file.setChecked(config['data']['csv']['enabled'])
        self.edit_csv_file_name.setText(config['data']['csv']['file_name'].decode('utf-8'))

        self.combo_debug_time_format.setCurrentIndex(max(self.combo_debug_time_format.findData(config['debug']['time_format']), 0))
        self.check_debug_to_log_file.setChecked(config['debug']['log']['enabled'])
        self.edit_log_file_name.setText(config['debug']['log']['file_name'].decode('utf-8'))
        self.combo_log_level.setCurrentIndex(max(self.combo_debug_time_format.findData(config['debug']['log']['level']), 0))

    def update_devices_tab(self, config):
        EventLogger.debug('Updating devices tab from config')

        self.model_devices.removeRows(0, self.model_data.rowCount())

        for device in config['devices']:
            self.add_device_to_tree(device)

    def add_device_to_tree(self, device):
        # check if device is already added
        if len(device['uid']) > 0:
            for row in range(self.model_devices.rowCount()):
                existing_name = self.model_devices.item(row, 0).text()
                exisitng_uid = self.tree_devices.indexWidget(self.model_devices.item(row, 1).index()).text()

                if device['name'] == existing_name and device['uid'] == exisitng_uid:
                    EventLogger.info('Ignoring duplicate device "{0}" with UID "{1}"'
                                     .format(device['name'], device['uid']))
                    return

        # add device
        name_item = QStandardItem(device['name'])
        uid_item = QStandardItem('')

        self.model_devices.appendRow([name_item, uid_item])

        edit_uid = QLineEdit()
        edit_uid.setPlaceholderText('Enter UID')
        edit_uid.setValidator(QRegExpValidator(QRegExp('^[{0}]{{1,6}}$'.format(BASE58)))) # FIXME: use stricter logic
        edit_uid.setText(device['uid'])

        self.tree_devices.setIndexWidget(uid_item.index(), edit_uid)

        value_specs = device_specs[device['name']]['values']
        parent_item = QStandardItem('Values')

        name_item.appendRow([parent_item, QStandardItem('')])
        self.tree_devices.expand(parent_item.index())

        # add values
        for value_spec in value_specs:
            value_name_item = QStandardItem(value_spec['name'])
            value_interval_item = QStandardItem('')

            parent_item.appendRow([value_name_item, value_interval_item])

            spinbox_interval = QSpinBox()
            spinbox_interval.setRange(0, (1 << 31) - 1)
            spinbox_interval.setSingleStep(1)
            spinbox_interval.setValue(device['values'][value_spec['name']]['interval'])
            spinbox_interval.setSuffix(' seconds')

            self.tree_devices.setIndexWidget(value_interval_item.index(), spinbox_interval)

            if value_spec['subvalues'] != None:
                for subvalue_name in value_spec['subvalues']:
                    subvalue_name_item = QStandardItem(subvalue_name)
                    subvalue_check_item = QStandardItem('')

                    value_name_item.appendRow([subvalue_name_item, subvalue_check_item])

                    check_subvalue = QCheckBox()
                    check_subvalue.setChecked(device['values'][value_spec['name']]['subvalues'][subvalue_name])

                    self.tree_devices.setIndexWidget(subvalue_check_item.index(), check_subvalue)

        self.tree_devices.expand(name_item.index())

        # add options
        option_specs = device_specs[device['name']]['options']

        if option_specs != None:
            parent_item = QStandardItem('Options')

            name_item.appendRow([parent_item, QStandardItem('')])

            for option_spec in option_specs:
                option_name_item = QStandardItem(option_spec['name'])
                option_widget_item = QStandardItem('')

                parent_item.appendRow([option_name_item, option_widget_item])

                if option_spec['type'] == 'choice':
                    widget_option_value = QComboBox()

                    for option_value_spec in option_spec['values']:
                        widget_option_value.addItem(option_value_spec[0].decode('utf-8'), option_value_spec[1])

                    widget_option_value.setCurrentIndex(widget_option_value.findText(device['options'][option_spec['name']]['value'].decode('utf-8')))
                elif option_spec['type'] == 'int':
                    widget_option_value = QSpinBox()
                    widget_option_value.setRange(option_spec['minimum'], option_spec['maximum'])
                    widget_option_value.setSuffix(option_spec['suffix'])
                    widget_option_value.setValue(device['options'][option_spec['name']]['value'])
                elif option_spec['type'] == 'bool':
                    widget_option_value = QCheckBox()
                    widget_option_value.setChecked(device['options'][option_spec['name']]['value'])

                self.tree_devices.setIndexWidget(option_widget_item.index(), widget_option_value)

    def add_debug_message(self, message):
        self.text_debug.append(message)

        while self.text_debug.document().blockCount() > 1000:
            cursor = QTextCursor(self.text_debug.document().begin())
            cursor.select(QTextCursor.BlockUnderCursor)
            cursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor)
            cursor.removeSelectedText()

        if self.checkbox_debug_auto_scroll.isChecked():
            self.text_debug.verticalScrollBar().setValue(self.text_debug.verticalScrollBar().maximum())

    def btn_clear_debug_clicked(self):
        self.text_debug.clear()

    def highlight_debug_tab(self):
        """
            SIGNAL function:
            Highlight the debug tab when an error occurs.
        """
        if not self.tab_debug_warning and self.tab_widget.currentWidget().objectName() != self.tab_debug.objectName():
            self.tab_debug_warning = True
            self.tab_set(self.tab_widget.indexOf(self.tab_debug), QColor(255, 0, 0),
                         os.path.join(get_resources_path(), "warning-icon.png"))

    def table_add_row(self, csv_data):
        """
            SIGNAL function:
            Adds new CSV Data into the Table.
        """
        rows = self.model_data.rowCount()

        while rows >= 1000:
            self.model_data.removeRow(0)
            rows = self.model_data.rowCount()

        row_number = None

        if rows > 0:
            try:
                row_number = int(self.model_data.headerData(rows - 1, Qt.Vertical))
            except ValueError:
                pass

        self.model_data.appendRow([QStandardItem(csv_data.timestamp),
                                   QStandardItem(csv_data.name),
                                   QStandardItem(csv_data.uid),
                                   QStandardItem(csv_data.var_name),
                                   QStandardItem(str(csv_data.raw_data)),
                                   QStandardItem(csv_data.var_unit.decode('utf-8'))])

        if row_number != None:
            self.model_data.setHeaderData(rows, Qt.Vertical, str(row_number + 1))

        if self.checkbox_data_auto_scroll.isChecked():
            self.table_data.scrollToBottom()
Esempio n. 12
0
class DlgTextItemEditor(QDialog, Ui_TextItemEditor):
    def __init__(self, parent):
        QDialog.__init__(self, parent)
        Ui_TextItemEditor.__init__(self)
        self.setupUi(self)
        self.itemName = "Value"
        # Create an empty model for the list's data
        self._model = QStandardItemModel(self.list_view)

    def setupUi(self, TextItemEditor):
        super().setupUi(TextItemEditor)
        TextItemEditor.btn_add.clicked.connect(self.on_add_click)
        TextItemEditor.btn_edit.clicked.connect(self.on_edit_click)
        TextItemEditor.btn_delete.clicked.connect(self.on_delete_click)

    def get_items(self):
        for i in range(self._model.rowCount()):
            yield self._model.item(i).text()

    def set_items(self, items):
        self._model.clear()
        for item in items:
            list_item = QStandardItem(item)
            self._model.appendRow(list_item)
        self.list_view.setModel(self._model)

    def get_selected(self):
        indexes = self.list_view.selectedIndexes()
        index = indexes[0] if indexes else None
        if not index:
            return None, None

        return self._model.itemFromIndex(index).text(), index

    def on_add_click(self):
        item, ok = utils.input_query(None, "Adding %s" % self.itemName.lower(),
                                     self.itemName + ":")
        if ok:
            list_item = QStandardItem(item)
            self._model.appendRow(list_item)
            self.list_view.setCurrentIndex(
                self._model.indexFromItem(list_item))
            self.event_add(item)

    def on_edit_click(self):
        text, index = self.get_selected()
        if not index:
            QMessageBox.question(None, 'Information',
                                 "Select %s from list" % self.itemName.lower(),
                                 QMessageBox.Ok)
            return

        item, ok = utils.input_query(None,
                                     "Editing %s" % self.itemName.lower(),
                                     self.itemName + ":", text)
        if ok:
            self._model.itemFromIndex(index).setText(item)
            self.event_edit(item)

    def on_delete_click(self):
        text, index = self.get_selected()
        if not index:
            QMessageBox.question(None, 'Information',
                                 "Select %s from list" % self.itemName.lower(),
                                 QMessageBox.Ok)
            return

        should_delete = QMessageBox.question(
            None, "Deleting %s" % self.itemName.lower(), "Delete '%s'?" % text,
            QMessageBox.Yes, QMessageBox.No)
        if should_delete == QMessageBox.Yes:
            self.event_delete(text)
            self._model.removeRow(index.row())

    @Event
    def event_add(self, item):
        """Signals the parent that an item has been added to the list
        :param item: str
        """

    @Event
    def event_edit(self, item):
        """Signals the parent that an item has been added to the list
        :param item: str
        """

    @Event
    def event_delete(self, item):
        """Signals the parent that an item has been removed from the list
Esempio n. 13
0
class PosiviewProperties(QgsOptionsDialogBase, Ui_PosiviewPropertiesBase):
    '''
    GUI class classdocs for the Configuration dialog
    '''
    applyChanges = pyqtSignal(dict)

    def __init__(self, project, parent=None):
        '''
        Setup dialog widgets with the project properties
        '''
        super(PosiviewProperties, self).__init__("PosiViewProperties", parent)
        self.setupUi(self)
        self.groupBox_6.hide()
        self.initOptionsBase(False)
        self.restoreOptionsBaseUi()
        self.comboBoxParser.addItems(PARSERS)
        self.comboBoxProviderType.addItems(DEVICE_TYPES)
        self.project = project
        self.projectProperties = project.properties()
        self.mToolButtonLoad.setDefaultAction(self.actionLoadConfiguration)
        self.mToolButtonSave.setDefaultAction(self.actionSaveConfiguration)

        self.mobileModel = QStringListModel()
        self.mobileListModel = QStringListModel()
        self.mMobileListView.setModel(self.mobileListModel)
        self.mobileProviderModel = QStandardItemModel()
        self.mobileProviderModel.setHorizontalHeaderLabels(
            ('Provider', 'Filter'))
        self.mMobileProviderTableView.setModel(self.mobileProviderModel)

        self.providerListModel = QStringListModel()
        self.mDataProviderListView.setModel(self.providerListModel)
        self.comboBoxProviders.setModel(self.providerListModel)
        self.setupModelData(self.projectProperties)
        self.setupGeneralData(self.projectProperties)

    def setupModelData(self, properties):
        self.mobileListModel.setStringList(sorted(
            properties['Mobiles'].keys()))
        self.providerListModel.setStringList(
            sorted(properties['Provider'].keys()))

    def setupGeneralData(self, properties):
        self.lineEditCruise.setText(properties['Mission']['cruise'])
        self.lineEditDive.setText(properties['Mission']['dive'])
        self.lineEditStation.setText(properties['Mission']['station'])
        self.lineEditRecorderPath.setText(properties['RecorderPath'])
        self.checkBoxAutoRecording.setChecked(properties['AutoRecord'])
        self.spinBoxNotifyDuration.setValue(properties['NotifyDuration'])
        self.checkBoxUtcClock.setChecked((properties['ShowUtcClock']))

    def updateGeneralData(self):
        self.projectProperties['Mission']['cruise'] = self.lineEditCruise.text(
        )
        self.projectProperties['Mission']['dive'] = self.lineEditDive.text()
        self.projectProperties['Mission'][
            'station'] = self.lineEditStation.text()
        self.projectProperties[
            'RecorderPath'] = self.lineEditRecorderPath.text()
        self.projectProperties[
            'AutoRecord'] = self.checkBoxAutoRecording.isChecked()
        self.projectProperties[
            'NotifyDuration'] = self.spinBoxNotifyDuration.value()
        self.projectProperties[
            'ShowUtcClock'] = self.checkBoxUtcClock.isChecked()

    def getColor(self, value):
        try:
            return QColor.fromRgba(int(value))
        except ValueError:
            return QColor(value)

    @pyqtSlot(QAbstractButton, name='on_buttonBox_clicked')
    def onButtonBoxClicked(self, button):
        role = self.buttonBox.buttonRole(button)
        if role == QDialogButtonBox.ApplyRole or role == QDialogButtonBox.AcceptRole:
            self.updateGeneralData()
            self.applyChanges.emit(self.projectProperties)

    @pyqtSlot(name='on_actionSaveConfiguration_triggered')
    def onActionSaveConfigurationTriggered(self):
        ''' Save the current configuration
        '''
        fn = QFileDialog.getSaveFileName(None, 'Save PosiView configuration',
                                         '', 'Configuration (*.ini *.conf)')
        self.project.store(fn)

    @pyqtSlot(name='on_actionLoadConfiguration_triggered')
    def onActionLoadConfigurationTriggered(self):
        ''' Load configuration from file
        '''
        fn = QFileDialog.getOpenFileName(None, 'Save PosiView configuration',
                                         '', 'Configuration (*.ini *.conf)')
        self.projectProperties = self.project.read(fn)
        self.setupModelData(self.projectProperties)
        self.setupGeneralData(self.projectProperties)

    @pyqtSlot(QModelIndex, name='on_mMobileListView_clicked')
    def editMobile(self, index):
        ''' Populate the widgets with the selected mobiles properties
        '''
        if index.isValid():
            self.populateMobileWidgets(index)

    @pyqtSlot(str, name='on_comboBoxMobileType_currentIndexChanged')
    def mobileTypeChanged(self, mType):
        if mType == 'SHAPE':
            self.lineEditMobileShape.setEnabled(True)
        else:
            self.lineEditMobileShape.setEnabled(False)

    @pyqtSlot(QModelIndex, name='on_mMobileListView_activated')
    def activated(self, index):
        pass

    @pyqtSlot(name='on_toolButtonAddMobile_clicked')
    def addMobile(self):
        self.mobileListModel.insertRow(self.mobileListModel.rowCount())
        index = self.mobileListModel.index(self.mobileListModel.rowCount() - 1)
        self.lineEditMobileName.setText('NewMobile')
        self.mobileListModel.setData(index, 'NewMobile', Qt.DisplayRole)
        self.mMobileListView.setCurrentIndex(index)
        self.applyMobile()

    @pyqtSlot(name='on_pushButtonApplyMobile_clicked')
    def applyMobile(self):
        index = self.mMobileListView.currentIndex()
        if index.isValid() and not self.lineEditMobileName.text() == '':
            mobile = dict()
            mobile['Name'] = self.lineEditMobileName.text()
            mobile['type'] = self.comboBoxMobileType.currentText()
            try:
                t = eval(self.lineEditMobileShape.text())
                if t.__class__ is tuple or t.__class__ is dict:
                    mobile['shape'] = t
            except SyntaxError:
                mobile['shape'] = ((0.0, -0.5), (0.3, 0.5), (0.0, 0.2), (-0.5,
                                                                         0.5))
            mobile['length'] = self.doubleSpinBoxMobileLength.value()
            mobile['width'] = self.doubleSpinBoxMobileWidth.value()
            mobile['offsetX'] = self.doubleSpinBoxXOffset.value()
            mobile['offsetY'] = self.doubleSpinBoxYOffset.value()
            mobile['zValue'] = self.spinBoxZValue.value()
            mobile['color'] = self.mColorButtonMobileColor.color().rgba()
            mobile['fillColor'] = self.mColorButtonMobileFillColor.color(
            ).rgba()
            mobile['timeout'] = self.spinBoxMobileTimeout.value() * 1000
            mobile['nofixNotify'] = self.spinBoxMobileNotification.value()
            mobile['trackLength'] = self.spinBoxTrackLength.value()
            mobile['trackColor'] = self.mColorButtonMobileTrackColor.color(
            ).rgba()
            mobile['showLabel'] = self.checkBoxShowLabel.isChecked()
            provs = dict()
            for r in range(self.mobileProviderModel.rowCount()):
                try:
                    fil = int(
                        self.mobileProviderModel.item(r,
                                                      1).data(Qt.DisplayRole))
                except:
                    fil = self.mobileProviderModel.item(r,
                                                        1).data(Qt.DisplayRole)
                    if not fil:
                        fil = None
                provs[self.mobileProviderModel.item(r, 0).data(
                    Qt.DisplayRole)] = fil
            mobile['provider'] = provs
            currName = self.mobileListModel.data(index, Qt.DisplayRole)
            if not currName == mobile['Name']:
                del self.projectProperties['Mobiles'][currName]
                self.mobileListModel.setData(index, mobile['Name'],
                                             Qt.DisplayRole)
            self.projectProperties['Mobiles'][mobile['Name']] = mobile

    def populateMobileWidgets(self, index):
        mobile = self.projectProperties['Mobiles'][self.mobileListModel.data(
            index, Qt.DisplayRole)]
        self.lineEditMobileName.setText(mobile.get('Name'))
        self.comboBoxMobileType.setCurrentIndex(
            self.comboBoxMobileType.findText(
                mobile.setdefault('type', 'BOX').upper()))
        if mobile['type'] == 'SHAPE':
            self.lineEditMobileShape.setText(str(mobile['shape']))
            self.lineEditMobileShape.setEnabled(True)
            self.doubleSpinBoxXOffset.setEnabled(True)
            self.doubleSpinBoxYOffset.setEnabled(True)
        else:
            self.lineEditMobileShape.setEnabled(False)
            self.doubleSpinBoxXOffset.setEnabled(False)
            self.doubleSpinBoxYOffset.setEnabled(False)
            self.lineEditMobileShape.clear()
        self.doubleSpinBoxMobileLength.setValue(mobile.get('length', 20.0))
        self.doubleSpinBoxMobileWidth.setValue(mobile.get('width', 5.0))
        self.doubleSpinBoxXOffset.setValue(mobile.get('offsetX', 0.0))
        self.doubleSpinBoxYOffset.setValue(mobile.get('offsetY', 0.0))
        self.spinBoxZValue.setValue(mobile.get('zValue', 100))
        self.mColorButtonMobileColor.setColor(
            self.getColor(mobile.get('color', 'black')))
        self.mColorButtonMobileFillColor.setColor(
            self.getColor(mobile.get('fillColor', 'green')))
        self.spinBoxMobileTimeout.setValue(mobile.get('timeout', 3000) / 1000)
        self.spinBoxMobileNotification.setValue(mobile.get('nofixNotify', 0))
        self.spinBoxTrackLength.setValue(mobile.get('trackLength', 100))
        self.mColorButtonMobileTrackColor.setColor(
            self.getColor(mobile.get('trackColor', 'green')))
        self.checkBoxShowLabel.setChecked(mobile.get('showLabel', False))
        r = 0
        self.mobileProviderModel.removeRows(
            0, self.mobileProviderModel.rowCount())
        if 'provider' in mobile:
            for k, v in mobile['provider'].items():
                prov = QStandardItem(k)
                val = QStandardItem(str(v))
                self.mobileProviderModel.setItem(r, 0, prov)
                self.mobileProviderModel.setItem(r, 1, val)
                r += 1

    @pyqtSlot(name='on_toolButtonRemoveMobile_clicked')
    def removeMobile(self):
        idx = self.mMobileListView.currentIndex()
        if idx.isValid():
            self.projectProperties['Mobiles'].pop(
                self.mobileListModel.data(idx, Qt.DisplayRole))
            self.mobileListModel.removeRows(idx.row(), 1)
            idx = self.mMobileListView.currentIndex()
            if idx.isValid():
                self.populateMobileWidgets(idx)

    @pyqtSlot(name='on_toolButtonRefreshMobileProvider_clicked')
    def refreshMobileProvider(self):
        prov = self.comboBoxProviders.currentText()
        if prov == '':
            return
        fil = None
        if self.lineEditProviderFilter.text() != '':
            fil = self.lineEditProviderFilter.text()
        items = self.mobileProviderModel.findItems(prov, Qt.MatchExactly, 0)
        if items:
            for item in items:
                self.mobileProviderModel.setItem(item.row(), 1,
                                                 QStandardItem(fil))
        else:
            self.mobileProviderModel.appendRow(
                [QStandardItem(prov), QStandardItem(fil)])

    @pyqtSlot(name='on_toolButtonRemoveMobileProvider_clicked')
    def removeMobileProvider(self):
        idx = self.mMobileProviderTableView.currentIndex()
        if idx.isValid():
            self.mobileProviderModel.removeRow(idx.row())

    @pyqtSlot(name='on_pushButtonApplyDataProvider_clicked')
    def applyDataProvider(self):
        index = self.mDataProviderListView.currentIndex()
        if index.isValid() and not self.lineEditProviderName.text() == '':
            provider = dict()
            provider['Name'] = self.lineEditProviderName.text()
            provider['DataDeviceType'] = self.comboBoxProviderType.currentText(
            )
            if provider['DataDeviceType'] in NETWORK_TYPES:
                provider['Host'] = self.lineEditProviderHostName.text()
                provider['Port'] = self.spinBoxProviderPort.value()
            provider['Parser'] = self.comboBoxParser.currentText()
            currName = self.providerListModel.data(index, Qt.DisplayRole)
            if not currName == provider['Name']:
                del self.projectProperties['Provider'][currName]
                self.providerListModel.setData(index, provider['Name'],
                                               Qt.DisplayRole)
            self.projectProperties['Provider'][provider['Name']] = provider

    @pyqtSlot(QModelIndex, name='on_mDataProviderListView_clicked')
    def editDataProvider(self, index):
        '''
        '''
        if index.isValid():
            self.populateDataProviderWidgets(index)

    def populateDataProviderWidgets(self, index):
        provider = self.projectProperties['Provider'][
            self.providerListModel.data(index, Qt.DisplayRole)]
        self.lineEditProviderName.setText(provider.get('Name'))
        self.comboBoxProviderType.setCurrentIndex(
            self.comboBoxProviderType.findText(
                provider.setdefault('DataDeviceType', 'UDP').upper()))
        if provider['DataDeviceType'] in NETWORK_TYPES:
            self.stackedWidgetDataDevice.setCurrentIndex(0)
            self.lineEditProviderHostName.setText(
                provider.setdefault('Host', '0.0.0.0'))
            self.spinBoxProviderPort.setValue(
                int(provider.setdefault('Port', 2000)))

        self.comboBoxParser.setCurrentIndex(
            self.comboBoxParser.findText(
                provider.setdefault('Parser', 'NONE').upper()))

    @pyqtSlot(name='on_toolButtonAddDataProvider_clicked')
    def addDataProvider(self):
        self.providerListModel.insertRow(self.providerListModel.rowCount())
        index = self.providerListModel.index(
            self.providerListModel.rowCount() - 1)
        self.lineEditProviderName.setText('NewDataProvider')
        self.providerListModel.setData(index, 'NewDataProvider',
                                       Qt.DisplayRole)
        self.mDataProviderListView.setCurrentIndex(index)
        self.applyDataProvider()

    @pyqtSlot(name='on_toolButtonRemoveDataProvider_clicked')
    def removeDataProvider(self):
        idx = self.mDataProviderListView.currentIndex()
        if idx.isValid():
            self.projectProperties['Provider'].pop(
                self.providerListModel.data(idx, Qt.DisplayRole))
            self.providerListModel.removeRows(idx.row(), 1)
            idx = self.mDataProviderListView.currentIndex()
            if idx.isValid():
                self.populateDataProviderWidgets(idx)

    @pyqtSlot(name='on_toolButtonSelectLogPath_clicked')
    def selectRecorderPath(self):
        path = QFileDialog.getExistingDirectory(
            self, self.tr('Select Recorder Path'),
            self.lineEditRecorderPath.text(),
            QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)
        if path != '':
            self.lineEditRecorderPath.setText(path)

    @pyqtSlot(QPoint, name='on_lineEditMobileShape_customContextMenuRequested')
    def mobileShapeContextMenu(self, pos):
        menu = QMenu(self.lineEditMobileShape)
        vesselAction = menu.addAction(self.tr('Vessel'))
        rovAction = menu.addAction(self.tr('ROV'))
        auvAction = menu.addAction(self.tr('AUV'))
        arrowAction = menu.addAction(self.tr('Arrow'))
        selectedAction = menu.exec_(self.lineEditMobileShape.mapToGlobal(pos))
        if selectedAction == vesselAction:
            self.lineEditMobileShape.setText(
                u'((0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3))'
            )
        elif selectedAction == rovAction:
            self.lineEditMobileShape.setText(
                u'((0.3, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3), (-0.3, -0.5))'
            )
        elif selectedAction == auvAction:
            self.lineEditMobileShape.setText(
                u'((0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3))'
            )
        elif selectedAction == arrowAction:
            self.lineEditMobileShape.setText(
                u'((0, -0.5), (0.5, 0.5), (0, 0), (-0.5, 0.5))')

    @pyqtSlot(name='on_buttonBox_helpRequested')
    def showHelp(self):
        """Display application help to the user."""
        help_file = os.path.join(
            os.path.split(os.path.dirname(__file__))[0], 'help', 'index.html')
        QDesktopServices.openUrl(QUrl.fromLocalFile(help_file))
Esempio n. 14
-1
    def _guiUpdate_metaTable(self,uuid):
        dbconn=DbConn()
        meta=dbconn.get_meta_kv()

        stream=meta[str(uuid)]
        print stream

        model=QStandardItemModel()
        model.setHorizontalHeaderItem(0,QStandardItem("Attribute"))
        model.setHorizontalHeaderItem(1,QStandardItem("Value"))


        while model.rowCount() > 0:
            model.removeRow(0)

        for k in stream.keys():
            name=stream[k]
            # print name
            # print k
            item1 = QStandardItem(k)
            item2 = QStandardItem(name)
            # item=QTableWidgetItem()
            # item.setText(1,name)
            # item.setText(2,k)
            # self.ui.metaEditor
            # model.appendRow([item1,item2])
            # self.ui.metaEditor.appendI
            model.appendRow([item1,item2])
        self.ui.metaEditor.setModel(model)

        # self.ui.metaEditor.addTopLevelItem(item)
        # self.ui.metaEditor.

        # model.itemChanged.connect(lambda: on_item_changed())

        self.metamodel=model

        # self.ui.met
        self.ui.metaEditor.setModel(model)
        # self.ui.metaEditor.setEditTriggers(QAbstractItemView.NoEditTriggers)
        # self.ui.metaEditor.sortByColumn(1)
        self.ui.metaEditor.resizeColumnsToContents()