class LateralPanel(QWidget): def __init__(self, parent=None): super(LateralPanel, self).__init__(parent) self.has_component = False self.vbox = QVBoxLayout(self) self.vbox.setContentsMargins(0, 0, 0, 0) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) self.combo = QComboBox() ui_tools.ComboBoxButton(self.combo, self.combo.clear, self.style().standardPixmap(self.style().SP_TrashIcon)) self.combo.setToolTip(self.trUtf8("Select the item from the Paste " "History list.\nYou can Copy items into this list with: " "%s\nor Paste them using: %s") % (resources.get_shortcut("History-Copy").toString( QKeySequence.NativeText), resources.get_shortcut("History-Paste").toString( QKeySequence.NativeText))) self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox.addWidget(self.combo) self.vbox.addLayout(hbox) def add_component(self, widget): self.vbox.insertWidget(0, widget) self.has_component = True def add_new_copy(self, copy): self.combo.insertItem(0, copy) self.combo.setCurrentIndex(0) if self.combo.count() > settings.COPY_HISTORY_BUFFER: self.combo.removeItem(self.combo.count() - 1) def get_paste(self): return self.combo.currentText()
class ComboTabWidget(QWidget): def __init__(self, parent): super(ComboTabWidget, self).__init__(parent) layout = QVBoxLayout(self) layout.setSpacing(0) self.switchCombo = QComboBox(self) layout.addWidget(self.switchCombo, 0, Qt.AlignCenter) groupBox = QGroupBox(self) groupBoxLayout = QVBoxLayout(groupBox) groupBoxLayout.setSpacing(0) self.pageArea = QStackedWidget(groupBox) groupBoxLayout.addWidget(self.pageArea) layout.addWidget(groupBox, 1) self.switchCombo.currentIndexChanged.connect(self.pageArea.setCurrentIndex) def setTabPosition(self, tabPos): pass def addTab(self, w, tabText): self.pageArea.addWidget(w) self.switchCombo.addItem(tabText) def insertTab(self, pos, w, tabText): self.pageArea.insertWidget(pos, w) self.switchCombo.insertItem(pos, tabText) def removeTab(self, index=-1): if index < 0: index = self.currentIndex() w = self.pageArea.widget(index) self.pageArea.removeWidget(w) self.switchCombo.removeItem(index) def updateTab(self, w, tabText, index=-1): if index < 0: index = self.switchCombo.currentIndex() self.removeTab(index) self.insertTab(index, w, tabText) self.setCurrentIndex(index) def setCurrentIndex(self, index): self.switchCombo.setCurrentIndex(index) def widget(self, index): return self.pageArea.widget(index) def currentIndex(self): return self.switchCombo.currentIndex() def count(self): return self.switchCombo.count()
class LateralPanel(QWidget): def __init__(self, parent=None): super(LateralPanel, self).__init__(parent) self.has_component = False self.vbox = QVBoxLayout(self) self.vbox.setContentsMargins(0, 0, 0, 0) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) self.labelText = "Ln: %s, Col: %s" self.labelCursorPosition = QLabel(self.trUtf8(self.labelText % (0, 0))) hbox.addWidget(self.labelCursorPosition) self.combo = QComboBox() ui_tools.ComboBoxButton( self.combo, self.combo.clear, self.style().standardPixmap(self.style().SP_TrashIcon)) self.combo.setToolTip( self.trUtf8( "Select the item from the Paste " "Historial list.\nYou can Copy items into this list with: " "%s\nor Paste them using: %s") % (resources.get_shortcut("History-Copy").toString( QKeySequence.NativeText), resources.get_shortcut("History-Paste").toString( QKeySequence.NativeText))) self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox.addWidget(self.combo) self.vbox.addLayout(hbox) def add_component(self, widget): self.vbox.insertWidget(0, widget) self.has_component = True def update_line_col(self, line, col): self.labelCursorPosition.setText( self.trUtf8(self.labelText % (line, col))) def add_new_copy(self, copy): self.combo.insertItem(0, copy) self.combo.setCurrentIndex(0) if self.combo.count() > settings.COPY_HISTORY_BUFFER: self.combo.removeItem(self.combo.count() - 1) def get_paste(self): return self.combo.currentText()
class LateralPanel(QWidget): def __init__(self, explorer): QWidget.__init__(self) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.addWidget(explorer) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) self.labelText = "Ln: %1, Col: %2" self.labelCursorPosition = QLabel( self.tr(self.labelText).arg(0).arg(0)) hbox.addWidget(self.labelCursorPosition) self.combo = QComboBox() ui_tools.ComboBoxButton( self.combo, self.combo.clear, self.style().standardPixmap(self.style().SP_TrashIcon)) self.combo.setToolTip( self.tr( "Select the item from the Paste " "Historial list.\nYou can Copy items into this list with: " "%1\nor Paste them using: %2").arg( resources.get_shortcut("History-Copy").toString( QKeySequence.NativeText)).arg( resources.get_shortcut("History-Paste").toString( QKeySequence.NativeText))) self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox.addWidget(self.combo) vbox.addLayout(hbox) def update_line_col(self, line, col): self.labelCursorPosition.setText( self.tr(self.labelText).arg(line).arg(col)) def add_new_copy(self, copy): self.combo.insertItem(0, copy) self.combo.setCurrentIndex(0) if self.combo.count() > settings.COPY_HISTORY_BUFFER: self.combo.removeItem(self.combo.count() - 1) def get_paste(self): return unicode(self.combo.currentText())
class LateralPanel(QWidget): def __init__(self, explorer): QWidget.__init__(self) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.addWidget(explorer) hbox = QHBoxLayout() hbox.setContentsMargins(0, 0, 0, 0) self.labelText = "Ln: %s, Col: %s" self.labelCursorPosition = QLabel(self.trUtf8(self.labelText % (0, 0))) hbox.addWidget(self.labelCursorPosition) self.combo = QComboBox() ui_tools.ComboBoxButton(self.combo, self.combo.clear, self.style().standardPixmap(self.style().SP_TrashIcon)) self.combo.setToolTip( self.trUtf8( "Select the item from the Paste " "Historial list.\nYou can Copy items into this list with: " "%s\nor Paste them using: %s" % ( resources.get_shortcut("History-Copy").toString(QKeySequence.NativeText), resources.get_shortcut("History-Paste").toString(QKeySequence.NativeText), ) ) ) self.combo.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) hbox.addWidget(self.combo) vbox.addLayout(hbox) def update_line_col(self, line, col): self.labelCursorPosition.setText(self.trUtf8(self.labelText % (line, col))) def add_new_copy(self, copy): self.combo.insertItem(0, copy) self.combo.setCurrentIndex(0) if self.combo.count() > settings.COPY_HISTORY_BUFFER: self.combo.removeItem(self.combo.count() - 1) def get_paste(self): return self.combo.currentText()
class ProjectTreeColumn(QDialog): def __init__(self, parent=None): super(ProjectTreeColumn, self).__init__(parent, Qt.WindowStaysOnTopHint) vbox = QVBoxLayout(self) vbox.setSizeConstraint(QVBoxLayout.SetDefaultConstraint) vbox.setContentsMargins(0, 0, 0, 0) self._buttons = [] self._combo_project = QComboBox() self._combo_project.setMinimumHeight(30) self._combo_project.setContextMenuPolicy(Qt.CustomContextMenu) vbox.addWidget(self._combo_project) self._projects_area = QStackedLayout() logger.debug("This is the projects area") logger.debug(self._projects_area) vbox.addLayout(self._projects_area) self.projects = [] self.connect(self._combo_project, SIGNAL("currentIndexChanged(int)"), self._change_current_project) self.connect(self._combo_project, SIGNAL( "customContextMenuRequested(const QPoint &)"), self.context_menu_for_root) connections = ( {'target': 'main_container', 'signal_name': 'addToProject(QString)', 'slot': self._add_file_to_project}, {'target': 'main_container', 'signal_name': 'showFileInExplorer(QString)', 'slot': self._show_file_in_explorer}, ) IDE.register_service('projects_explorer', self) IDE.register_signals('projects_explorer', connections) ExplorerContainer.register_tab(translations.TR_TAB_PROJECTS, self) #FIXME: Should have a ninja settings object that stores tree state #FIXME: Or bettter, application data object #TODO: check this: #self.connect(ide, SIGNAL("goingDown()"), #self.tree_projects.shutdown) #def close_project_signal(): #self.emit(SIGNAL("updateLocator()")) def install_tab(self): ide = IDE.get_service('ide') ui_tools.install_shortcuts(self, actions.PROJECTS_TREE_ACTIONS, ide) self.connect(ide, SIGNAL("goingDown()"), self.close) def load_session_projects(self, projects): for project in projects: if os.path.exists(project): self._open_project_folder(project) def open_project_folder(self, folderName=None): if settings.WORKSPACE: directory = settings.WORKSPACE else: directory = os.path.expanduser("~") if folderName is None: folderName = QFileDialog.getExistingDirectory( self, translations.TR_OPEN_PROJECT_DIRECTORY, directory) logger.debug("Choosing Foldername") if folderName: logger.debug("Opening %s" % folderName) self._open_project_folder(folderName) def _open_project_folder(self, folderName): ninjaide = IDE.get_service("ide") project = NProject(folderName) qfsm = ninjaide.filesystem.open_project(project) if qfsm: self.add_project(project) self.emit(SIGNAL("updateLocator()")) self.save_recent_projects(folderName) main_container = IDE.get_service('main_container') if main_container: main_container.show_editor_area() def _add_file_to_project(self, path): """Add the file for 'path' in the project the user choose here.""" if self._active_project: pathProject = [self._active_project.project] addToProject = add_to_project.AddToProject(pathProject, self) addToProject.exec_() if not addToProject.pathSelected: return main_container = IDE.get_service('main_container') if not main_container: return editorWidget = main_container.get_current_editor() if not editorWidget.file_path: name = QInputDialog.getText(None, translations.TR_ADD_FILE_TO_PROJECT, translations.TR_FILENAME + ": ")[0] if not name: QMessageBox.information( self, translations.TR_INVALID_FILENAME, translations.TR_INVALID_FILENAME_ENTER_A_FILENAME) return else: name = file_manager.get_basename(editorWidget.file_path) new_path = file_manager.create_path(addToProject.pathSelected, name) ide_srv = IDE.get_service("ide") old_file = ide_srv.get_or_create_nfile(path) new_file = old_file.save(editorWidget.get_text(), new_path) #FIXME: Make this file replace the original in the open tab else: pass # Message about no project def _show_file_in_explorer(self, path): '''Iterate through the list of available projects and show the current file in the explorer view for the first project that contains it (i.e. if the same file is included in multiple open projects, the path will be expanded for the first project only). Note: This slot is connected to the main container's "showFileInExplorer(QString)" signal.''' for project in self.projects: index = project.model().index(path) if index.isValid(): # Show the explorer if it is currently hidden central = IDE.get_service('central_container') if central and not central.is_lateral_panel_visible(): central.change_lateral_visibility() # This highlights the index in the tree for us project.setCurrentIndex(index) # Loop through the parents to expand the tree # all the way up to the selected index. while index.isValid(): project.expand(index) index = index.parent() break def add_project(self, project): if project not in self.projects: self._combo_project.addItem(project.name) ptree = TreeProjectsWidget(project) self._projects_area.addWidget(ptree) self.connect(ptree, SIGNAL("closeProject(PyQt_PyObject)"), self._close_project) pmodel = project.model ptree.setModel(pmodel) pindex = pmodel.index(pmodel.rootPath()) ptree.setRootIndex(pindex) self.projects.append(ptree) current_index = self._projects_area.count() self._projects_area.setCurrentIndex(current_index - 1) self._combo_project.setCurrentIndex(current_index - 1) def _close_project(self, widget): """Close the project related to the tree widget.""" index = self._projects_area.currentIndex() self.projects.remove(widget) self._projects_area.takeAt(index) self._combo_project.removeItem(index) index = self._combo_project.currentIndex() self._projects_area.setCurrentIndex(index) ninjaide = IDE.get_service('ide') ninjaide.filesystem.close_project(widget.project.path) widget.deleteLater() def _change_current_project(self, index): self._projects_area.setCurrentIndex(index) def close_opened_projects(self): for project in reversed(self.projects): self._close_project(project) def save_project(self): """Save all the opened files that belongs to the actual project.""" if self._active_project: path = self._projects_area.currentWidget().project.path main_container = IDE.get_service('main_container') if path and main_container: main_container.save_project(path) def create_new_project(self): wizard = new_project_manager.NewProjectManager(self) wizard.show() @property def current_project(self): if self._projects_area.count() > 0: return self._projects_area.currentWidget().project @property def current_tree(self): return self._projects_area.currentWidget() def save_recent_projects(self, folder): settings = IDE.data_settings() recent_project_list = settings.value('recentProjects', {}) #if already exist on the list update the date time projectProperties = json_manager.read_ninja_project(folder) name = projectProperties.get('name', '') description = projectProperties.get('description', '') if name == '': name = file_manager.get_basename(folder) if description == '': description = translations.TR_NO_DESCRIPTION if folder in recent_project_list: properties = recent_project_list[folder] properties["lastopen"] = QDateTime.currentDateTime() properties["name"] = name properties["description"] = description recent_project_list[folder] = properties else: recent_project_list[folder] = { "name": name, "description": description, "isFavorite": False, "lastopen": QDateTime.currentDateTime()} #if the length of the project list it's high that 10 then delete #the most old #TODO: add the length of available projects to setting if len(recent_project_list) > 10: del recent_project_list[self.find_most_old_open( recent_project_list)] settings.setValue('recentProjects', recent_project_list) def find_most_old_open(self, recent_project_list): listFounder = [] for recent_project_path, content in list(recent_project_list.items()): listFounder.append((recent_project_path, int( content["lastopen"].toString("yyyyMMddHHmmzzz")))) listFounder = sorted(listFounder, key=lambda date: listFounder[1], reverse=True) # sort by date last used return listFounder[0][0] def reject(self): if self.parent() is None: self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self) def closeEvent(self, event): self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self) event.ignore() def context_menu_for_root(self): menu = QMenu(self) path = self.current_tree.project.path action_add_file = menu.addAction(QIcon(":img/new"), translations.TR_ADD_NEW_FILE) action_add_folder = menu.addAction(QIcon( ":img/openProj"), translations.TR_ADD_NEW_FOLDER) action_create_init = menu.addAction(translations.TR_CREATE_INIT) self.connect(action_add_file, SIGNAL("triggered()"), lambda: self.current_tree._add_new_file(path)) self.connect(action_add_folder, SIGNAL("triggered()"), lambda: self.current_tree._add_new_folder(path)) self.connect(action_create_init, SIGNAL("triggered()"), lambda: self.current_tree._create_init(path)) menu.addSeparator() actionRunProject = menu.addAction(QIcon( ":img/play"), translations.TR_RUN_PROJECT) self.connect(actionRunProject, SIGNAL("triggered()"), self.current_tree._execute_project) if self.current_tree._added_to_console: actionRemoveFromConsole = menu.addAction( translations.TR_REMOVE_PROJECT_FROM_PYTHON_CONSOLE) self.connect(actionRemoveFromConsole, SIGNAL("triggered()"), self.current_tree._remove_project_from_console) else: actionAdd2Console = menu.addAction( translations.TR_ADD_PROJECT_TO_PYTHON_CONSOLE) self.connect(actionAdd2Console, SIGNAL("triggered()"), self.current_tree._add_project_to_console) actionShowFileSizeInfo = menu.addAction(translations.TR_SHOW_FILESIZE) self.connect(actionShowFileSizeInfo, SIGNAL("triggered()"), self.current_tree.show_filesize_info) actionProperties = menu.addAction(QIcon(":img/pref"), translations.TR_PROJECT_PROPERTIES) self.connect(actionProperties, SIGNAL("triggered()"), self.current_tree.open_project_properties) menu.addSeparator() action_close = menu.addAction( self.style().standardIcon(QStyle.SP_DialogCloseButton), translations.TR_CLOSE_PROJECT) self.connect(action_close, SIGNAL("triggered()"), self.current_tree._close_project) #menu for the project for m in self.current_tree.extra_menus_by_scope['project']: if isinstance(m, QMenu): menu.addSeparator() menu.addMenu(m) #show the menu! menu.exec_(QCursor.pos())
class LayerSelectionPage(QFrame): #TODO. Filtering, (visible) row selection, multi selection colparams = ((0, 65, 'Name'), (1, 235, 'Title'), (2, 350, 'Keywords')) XFER_BW = 40 def __init__(self, parent=None): super(LayerSelectionPage, self).__init__(parent) self.parent = parent #convenience link self.confconn_link = self.parent.parent.confconn #flag top prevent read read action on keyword delete. New logic makes this redundant #self.keywordbypass = False QToolTip.setFont(QFont('SansSerif', 10)) #label filterlabel = QLabel('Filter') availablelabel = QLabel('Available Layers') selectionlabel = QLabel('Layer Selections') keywordlabel = QLabel('Keyword') explainlabel = QLabel( "Edit Group assignments using this dialog or to simply initialise the Layer-Config just click 'Finish'" ) #selection buttons chooseallbutton = QPushButton('>>') chooseallbutton.setFixedWidth(self.XFER_BW) chooseallbutton.clicked.connect(self.doChooseAllClickAction) choosebutton = QPushButton('>') choosebutton.setFixedWidth(self.XFER_BW) choosebutton.clicked.connect(self.doChooseClickAction) rejectbutton = QPushButton('<') rejectbutton.setFixedWidth(self.XFER_BW) rejectbutton.clicked.connect(self.doRejectClickAction) rejectallbutton = QPushButton('<<') rejectallbutton.setFixedWidth(self.XFER_BW) rejectallbutton.clicked.connect(self.doRejectAllClickAction) #operation buttons finishbutton = QPushButton('Finish') finishbutton.setToolTip('Finish and Close layer selection dialog') finishbutton.clicked.connect(self.parent.close) resetbutton = QPushButton('Reset') resetbutton.font() resetbutton.setToolTip( 'Read Layer from LDS GetCapabilities request. Overwrites current Layer Config' ) resetbutton.clicked.connect(self.doResetClickAction) self.available_sfpm = LDSSFPAvailableModel(self) self.selection_sfpm = LDSSFPSelectionModel(self) self.available_sfpm.setSourceModel(self.parent.available_model) self.selection_sfpm.setSourceModel(self.parent.selection_model) #textedits filteredit = QLineEdit('') filteredit.setToolTip( 'Filter Available-Layers pane (filter operates across Name and Title fields and accepts Regex expressions)' ) filteredit.textChanged.connect(self.available_sfpm.setActiveFilter) self.keywordcombo = QComboBox() self.keywordcombo.setToolTip( 'Select or Add a unique identifier to be saved in layer config (keyword)' ) self.keywordcombo.addItems(list(self.confconn_link.assigned)) self.keywordcombo.setEditable(True) self.keywordcombo.activated.connect(self.doKeyComboChangeAction) lgindex = self.confconn_link.getLayerGroupIndex( self.confconn_link.lgval, col=1) lgentry = self.confconn_link.lglist[lgindex] if LU.assessNone( lgindex) else None #keywordedit = self.keywordcombo.lineEdit().text().toUtf8().data().decode('utf8')# for writing #if no entry or layer indicated then blank self.keywordcombo.lineEdit().setText( '' if lgentry is None or lgentry[0] == LORG.LAYER else lgentry[1]) #self.confconn_link.lgval)#TODO. group only #header headmodel = QStandardItemModel() headmodel.setHorizontalHeaderLabels([ i[2] for i in self.colparams ][:self.parent.available_model.columnCount()]) headview1 = QHeaderView(Qt.Horizontal) headview1.setModel(headmodel) headview1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) headview2 = QHeaderView(Qt.Horizontal) headview2.setModel(headmodel) headview2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) #table self.available = QTableView() self.available.setSelectionBehavior(QAbstractItemView.SelectRows) self.available.setSelectionMode(QAbstractItemView.MultiSelection) self.selection = QTableView() self.selection.setSelectionBehavior(QAbstractItemView.SelectRows) self.selection.setSelectionMode(QAbstractItemView.MultiSelection) #interesting, must set model after selection attributes but before headers else row selections/headers don't work properly self.available.setModel(self.available_sfpm) self.selection.setModel(self.selection_sfpm) self.available.setSortingEnabled(True) self.available.setHorizontalHeader(headview1) self.selection.setSortingEnabled(True) self.selection.setHorizontalHeader(headview2) for cp in self.colparams: self.available.setColumnWidth(cp[0], cp[1]) self.selection.setColumnWidth(cp[0], cp[1]) self.available.verticalHeader().setVisible(False) self.available.horizontalHeader().setVisible(True) self.selection.verticalHeader().setVisible(False) self.selection.horizontalHeader().setVisible(True) #layout vbox00 = QVBoxLayout() vbox00.addWidget(availablelabel) vbox00.addWidget(self.available) vbox01 = QVBoxLayout() vbox01.addWidget(chooseallbutton) vbox01.addWidget(choosebutton) vbox01.addWidget(rejectbutton) vbox01.addWidget(rejectallbutton) vbox02 = QVBoxLayout() vbox02.addWidget(selectionlabel) vbox02.addWidget(self.selection) vbox10 = QVBoxLayout() vbox10.addWidget(filterlabel) vbox10.addWidget(filteredit) hbox12 = QHBoxLayout() hbox12.addWidget(keywordlabel) hbox12.addStretch(1) #hbox12.addWidget(inspbutton) #hbox12.addWidget(addbutton) #hbox12.addWidget(delbutton) vbox12 = QVBoxLayout() vbox12.addLayout(hbox12) vbox12.addWidget(self.keywordcombo) #00|01|02 #10|11|12 grid0 = QGridLayout() grid0.addLayout(vbox00, 1, 0) grid0.addLayout(vbox01, 1, 1) grid0.addLayout(vbox02, 1, 2) grid0.addLayout(vbox10, 0, 0) grid0.addLayout(vbox12, 0, 2) hbox2 = QHBoxLayout() hbox2.addWidget(resetbutton) hbox2.addStretch(1) hbox2.addWidget(explainlabel) hbox2.addWidget(finishbutton) #gbox1.setLayout(hbox2) vbox3 = QVBoxLayout() vbox3.addLayout(grid0) #vbox3.addLayout(hbox3) #vbox3.addWidget(line0) vbox3.addLayout(hbox2) self.setLayout(vbox3) def doChooseAllClickAction(self): '''Moves the lot to Selected''' #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode( LQ.readWidgetText(self.keywordcombo.lineEdit().text())) if not self.checkKeyword(ktext): return #------------------------------ self.parent.signalModels(self.parent.STEP.PRE) #self.parent.selection_model.mdata += self.parent.available_model.mdata self.parent.selection_model.initData(self.confconn_link.complete) self.parent.available_model.initData([]) self.parent.signalModels(self.parent.STEP.POST) #------------------------------ self.parent.writeKeysToLayerConfig(ktext) #self.confconn_link.setupAssignedLayerList() if self.keywordcombo.findText(ktext) == -1: self.keywordcombo.addItem(ktext) def doChooseClickAction(self): '''Takes available selected and moves to selection''' #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode( LQ.readWidgetText(self.keywordcombo.lineEdit().text())) #ktext = str(self.keywordcombo.lineEdit().text()) if not self.checkKeyword(ktext): return #------------------------------ select = self.available.selectionModel() if select.hasSelection(): self.transferSelectedRows(select.selectedRows(), self.available_sfpm, self.selection_sfpm) #------------------------------ self.parent.writeKeysToLayerConfig(ktext) #self.confconn_link.assigned = self.confconn_link.setupAssignedLayerList() # -1 to indicate no index since 0,1,... are valid if self.keywordcombo.findText(ktext) == -1: self.keywordcombo.addItem(ktext) else: ldslog.warn('L2R > Transfer action without selection') #TRACE# #pdb.set_trace() self.available.clearSelection() def transferSelectedRows(self, indices, from_model, to_model): tlist = [] for proxymodelindex in indices: transfer = from_model.getData(proxymodelindex) tlist.append((proxymodelindex, transfer), ) to_model.addData([t[1] for t in tlist]) from_model.delData([t[0] for t in tlist]) return tlist def doRejectClickAction(self): '''Takes available selected and moves to selection''' #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode( LQ.readWidgetText(self.keywordcombo.lineEdit().text())) if not self.checkKeyword(ktext): return #------------------------------ select = self.selection.selectionModel() if select.hasSelection(): tlist = self.transferSelectedRows(select.selectedRows(), self.selection_sfpm, self.available_sfpm) #------------------------------ kindex = self.keywordcombo.findText(ktext) remainder = self.parent.deleteKeysFromLayerConfig( [ll[1][0] for ll in tlist], ktext) if remainder > 0 and kindex == -1: #items+newkey -> add self.parent.writeKeysToLayerConfig(ktext) self.keywordcombo.addItem(ktext) elif remainder == 0 and kindex > -1: #empty+oldkey -> del self.keywordcombo.removeItem(kindex) self.keywordcombo.clearEditText() else: ldslog.warn('R2L < Transfer action without selection') #TRACE# #pdb.set_trace() self.selection.clearSelection() def doRejectAllClickAction(self): #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode( LQ.readWidgetText(self.keywordcombo.lineEdit().text())) if not self.checkKeyword(ktext): return #------------------------------ self.parent.deleteKeysFromLayerConfig( [ll[0] for ll in self.parent.selection_model.mdata], ktext) #------------------------------ self.parent.signalModels(self.parent.STEP.PRE) #self.parent.available_model.mdata += self.parent.selection_model.mdata self.parent.available_model.initData(self.confconn_link.complete) self.parent.selection_model.initData([]) self.parent.signalModels(self.parent.STEP.POST) #------------------------------ #self.confconn_link.setupAssignedLayerList() #self.keywordbypass = True self.keywordcombo.removeItem(self.keywordcombo.findText(ktext)) self.keywordcombo.clearEditText() def doKeyComboChangeAction(self): '''Reset the available pane and if there is anything in the keyword box use this to init the selection pane''' #HACK #if self.keywordbypass: # self.keywordbypass = False # return #------------------------------ #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode( LQ.readWidgetText(self.keywordcombo.lineEdit().text())) #------------------------------ av_sl = self.parent.splitData(ktext, self.confconn_link.complete) #av_sl = self.parent.splitData(ktext,self.confconn_link.complete) self.parent.signalModels(self.parent.STEP.PRE) self.parent.available_model.initData(av_sl[0]) self.parent.selection_model.initData(av_sl[1]) self.parent.signalModels(self.parent.STEP.POST) def doResetClickAction(self): '''Dumps the LC and rebuilds from a fresh read of the caps doc''' #int warning (QWidget parent, QString title, QString text, QString button0Text, QString button1Text = QString(), QString button2Text = QString(), int defaultButtonNumber = 0, int escapeButtonNumber = -1) ans = QMessageBox.warning( self, "Reset", "This action will overwrite your Layer Configuration using the current LDS settings (potentially adding new or removing layers). Continue?", "Continue", "Cancel") if ans: #Cancel ldslog.warn('Cancelling Reset operation') return #Continue ldslog.warn('Reset Layer Config') self.parent.resetLayers() self.keywordcombo.clear() def checkKeyword(self, ktext): '''Checks keyword isn't null and isn't part of the LDS supplied keywords''' if LU.assessNone(ktext) is None: QMessageBox.about(self, "Keyword Required", "Please enter a Keyword to assign Layer(s) to") return False if ktext in self.confconn_link.reserved: QMessageBox.about( self, "Reserved Keyword", "'{}' is a reserved keyword, please select again".format( ktext)) return False return True
class preferencesDialog(QDialog): newMailerMessage = QtCore.Signal(str, str) def __init__(self, parent): QDialog.__init__(self, parent) self.tmpPref = {} self.tmpPref['pref'] = copy.deepcopy(self.parent().prm['pref']) self.currLocale = self.parent().prm['currentLocale'] self.currLocale.setNumberOptions(self.currLocale.OmitGroupSeparator | self.currLocale.RejectGroupSeparator) self.audioManager = parent.audioManager self.mailer = emailSender(self) self.newMailerMessage.connect(self.popMailerMessage) self.tabWidget = QTabWidget() self.tabWidget.currentChanged.connect(self.tabChanged) self.appPrefWidget = QWidget() self.soundPrefWidget = QWidget() self.notificationPrefWidget = QWidget() self.eegPrefWidget = QWidget() #the gui widget for these are in an external dialog self.wavsPref = {} self.wavsPref['endMessageFiles'] = self.tmpPref['pref']['general']['endMessageFiles'] self.wavsPref['endMessageFilesUse'] = self.tmpPref['pref']['general']['endMessageFilesUse'] self.wavsPref['endMessageFilesID'] = self.tmpPref['pref']['general']['endMessageFilesID'] self.wavsPref['endMessageLevels'] = self.tmpPref['pref']['general']['endMessageLevels'] #GENERAL PREF appPrefGrid = QGridLayout() n = 0 self.languageChooserLabel = QLabel(self.tr('Language (requires restart):')) appPrefGrid.addWidget(self.languageChooserLabel, n, 0) self.languageChooser = QComboBox() self.languageChooser.addItems(self.parent().prm['appData']['available_languages']) self.languageChooser.setCurrentIndex(self.languageChooser.findText(self.tmpPref['pref']['language'])) self.languageChooser.currentIndexChanged[int].connect(self.onLanguageChooserChange) appPrefGrid.addWidget(self.languageChooser, n, 1) n = n+1 self.countryChooserLabel = QLabel(self.tr('Country (requires restart):')) appPrefGrid.addWidget(self.countryChooserLabel, n, 0) self.countryChooser = QComboBox() self.countryChooser.addItems(self.parent().prm['appData']['available_countries'][self.tmpPref['pref']['language']]) self.countryChooser.setCurrentIndex(self.countryChooser.findText(self.tmpPref['pref']['country'])) appPrefGrid.addWidget(self.countryChooser, n, 1) n = n+1 self.responseBoxLanguageChooserLabel = QLabel(self.tr('Response Box Language (requires restart):')) appPrefGrid.addWidget(self.responseBoxLanguageChooserLabel, n, 0) self.responseBoxLanguageChooser = QComboBox() self.responseBoxLanguageChooser.addItems(self.parent().prm['appData']['available_languages']) self.responseBoxLanguageChooser.setCurrentIndex(self.responseBoxLanguageChooser.findText(self.tmpPref['pref']['responseBoxLanguage'])) self.responseBoxLanguageChooser.currentIndexChanged[int].connect(self.onResponseBoxLanguageChooserChange) appPrefGrid.addWidget(self.responseBoxLanguageChooser, n, 1) n = n+1 self.responseBoxCountryChooserLabel = QLabel(self.tr('Response Box Country (requires restart):')) appPrefGrid.addWidget(self.responseBoxCountryChooserLabel, n, 0) self.responseBoxCountryChooser = QComboBox() self.responseBoxCountryChooser.addItems(self.parent().prm['appData']['available_countries'][self.tmpPref['pref']['responseBoxLanguage']]) self.responseBoxCountryChooser.setCurrentIndex(self.responseBoxCountryChooser.findText(self.tmpPref['pref']['responseBoxCountry'])) appPrefGrid.addWidget(self.responseBoxCountryChooser, n, 1) n = n+1 self.csvSeparatorLabel = QLabel(self.tr('csv separator:')) appPrefGrid.addWidget(self.csvSeparatorLabel, n, 0) self.csvSeparatorWidget = QLineEdit(self.tmpPref['pref']["general"]["csvSeparator"]) appPrefGrid.addWidget(self.csvSeparatorWidget, n, 1) n = n+1 self.listenerNameWarnCheckBox = QCheckBox(self.tr('Warn if listener name missing')) self.listenerNameWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["listenerNameWarn"]) appPrefGrid.addWidget(self.listenerNameWarnCheckBox, n, 0) n = n+1 self.sessionLabelWarnCheckBox = QCheckBox(self.tr('Warn if session label missing')) self.sessionLabelWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["sessionLabelWarn"]) appPrefGrid.addWidget(self.sessionLabelWarnCheckBox, n, 0) n = n+1 self.dpCorrCheckBox = QCheckBox(self.tr('d-prime correction')) self.dpCorrCheckBox.setChecked(self.tmpPref['pref']['general']['dprimeCorrection']) self.dpCorrCheckBox.setWhatsThis(self.tr("If checked, when automatically processing result files, convert hit rates of 0 and 1 to 1/2N and 1-1/(2N) respectively, where N is the number of trials, to avoid infinite values of d'")) appPrefGrid.addWidget(self.dpCorrCheckBox, n, 0) n = n+1 self.recursionLimitLabel = QLabel(self.tr('Max Recursion Depth (requires restart):')) appPrefGrid.addWidget(self.recursionLimitLabel, n, 0) self.recursionLimitWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["maxRecursionDepth"])) self.recursionLimitWidget.setValidator(QIntValidator(self)) appPrefGrid.addWidget(self.recursionLimitWidget, n, 1) n = n+1 n = n+1 self.startupCommandLabel = QLabel(self.tr('Execute command at startup:')) appPrefGrid.addWidget(self.startupCommandLabel, n, 0) self.startupCommandWidget = QLineEdit(self.tmpPref["pref"]["general"]["startupCommand"]) appPrefGrid.addWidget(self.startupCommandWidget, n, 1) n = n+1 self.appPrefWidget.setLayout(appPrefGrid) self.appPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize) #SOUND PREF soundPrefGrid = QGridLayout() n = 0 self.playChooser = QComboBox() self.playChooser.addItems(self.parent().prm['appData']['available_play_commands']) self.playChooser.setCurrentIndex(self.playChooser.findText(self.tmpPref['pref']['sound']['playCommandType'])) self.playChooser.currentIndexChanged[int].connect(self.onPlayChooserChange) self.playChooserLabel = QLabel(self.tr('Play Command:')) soundPrefGrid.addWidget(self.playChooserLabel, 0, 0) soundPrefGrid.addWidget(self.playChooser, 0, 1) n = n+1 self.playCommandLabel = QLabel(self.tr('Command:')) soundPrefGrid.addWidget(self.playCommandLabel, n, 0) self.playCommandWidget = QLineEdit(self.tmpPref['pref']['sound']['playCommand']) if self.playChooser.currentText() != self.tr('custom'): self.playCommandWidget.setReadOnly(True) soundPrefGrid.addWidget(self.playCommandWidget, n, 1) n = n+1 foo = self.playChooser.currentText() if foo != self.tr('custom'): self.playCommandLabel.hide() self.playCommandWidget.hide() #if alsaaudio is selected, provide device list chooser if self.parent().prm["appData"]["alsaaudioAvailable"] == True: self.alsaaudioPlaybackCardList = self.listAlsaaudioPlaybackCards() self.alsaaudioDeviceLabel = QLabel(self.tr('Device:')) soundPrefGrid.addWidget(self.alsaaudioDeviceLabel, n, 0) self.alsaaudioDeviceChooser = QComboBox() self.alsaaudioDeviceChooser.addItems(self.alsaaudioPlaybackCardList) self.alsaaudioDeviceChooser.setCurrentIndex(self.alsaaudioDeviceChooser.findText(self.tmpPref["pref"]["sound"]["alsaaudioDevice"])) soundPrefGrid.addWidget(self.alsaaudioDeviceChooser, n, 1) n = n+1 if self.tmpPref['pref']['sound']['playCommandType'] != "alsaaudio": self.alsaaudioDeviceLabel.hide() self.alsaaudioDeviceChooser.hide() #if pyaudio is selected, provide device list chooser if self.parent().prm["appData"]["pyaudioAvailable"] == True: self.listPyaudioPlaybackDevices() self.pyaudioDeviceLabel = QLabel(self.tr('Device:')) soundPrefGrid.addWidget(self.pyaudioDeviceLabel, n, 0) self.pyaudioDeviceChooser = QComboBox() self.pyaudioDeviceChooser.addItems(self.pyaudioDeviceListName) try: self.pyaudioDeviceChooser.setCurrentIndex(self.pyaudioDeviceListIdx.index(self.tmpPref["pref"]["sound"]["pyaudioDevice"])) except: self.tmpPref["pref"]["sound"]["pyaudioDevice"] = self.pyaudioDeviceListIdx[0] self.parent().prm["pref"]["sound"]["pyaudioDevice"] = self.pyaudioDeviceListIdx[0] self.pyaudioDeviceChooser.setCurrentIndex(self.pyaudioDeviceListIdx.index(self.tmpPref["pref"]["sound"]["pyaudioDevice"])) soundPrefGrid.addWidget(self.pyaudioDeviceChooser, n, 1) n = n+1 if self.tmpPref['pref']['sound']['playCommandType'] != "pyaudio": self.pyaudioDeviceLabel.hide() self.pyaudioDeviceChooser.hide() if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True: self.bufferSizeLabel = QLabel(self.tr('Buffer Size (samples):')) soundPrefGrid.addWidget(self.bufferSizeLabel, n, 0) self.bufferSizeWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["sound"]["bufferSize"])) self.bufferSizeWidget.setValidator(QIntValidator(self)) soundPrefGrid.addWidget(self.bufferSizeWidget, n, 1) n = n+1 if self.tmpPref['pref']['sound']['playCommandType'] not in ["alsaaudio", "pyaudio"]: self.bufferSizeLabel.hide() self.bufferSizeWidget.hide() self.samplerateLabel = QLabel(self.tr('Default Sampling Rate:')) soundPrefGrid.addWidget(self.samplerateLabel, n, 0) self.samplerateWidget = QLineEdit(self.tmpPref["pref"]["sound"]["defaultSampleRate"]) #self.samplerateWidget.setValidator(QIntValidator(self)) soundPrefGrid.addWidget(self.samplerateWidget, n, 1) n = n+1 self.nbitsLabel = QLabel(self.tr('Default Bits:')) self.nbitsChooser = QComboBox() self.nbitsChooser.addItems(self.parent().prm["nBitsChoices"]) self.nbitsChooser.setCurrentIndex(self.parent().prm["nBitsChoices"].index(self.tmpPref["pref"]["sound"]["defaultNBits"])) soundPrefGrid.addWidget(self.nbitsLabel, n, 0) soundPrefGrid.addWidget(self.nbitsChooser, n, 1) n = n+1 self.wavmanagerLabel = QLabel(self.tr('Wav Manager (requires restart):')) self.wavmanagerChooser = QComboBox() self.wavmanagerChooser.addItems(self.parent().prm['appData']['wavmanagers']) self.wavmanagerChooser.setCurrentIndex(self.wavmanagerChooser.findText(self.tmpPref['pref']['sound']['wavmanager'])) soundPrefGrid.addWidget(self.wavmanagerLabel, n, 0) soundPrefGrid.addWidget(self.wavmanagerChooser, n, 1) n = n+1 self.writewav = QCheckBox(self.tr('Write wav file')) self.writewav.setChecked(self.tmpPref["pref"]["sound"]["writewav"]) soundPrefGrid.addWidget(self.writewav, n, 0) n = n+1 self.writeSndSeqSegments = QCheckBox(self.tr('Write sound sequence segments wavs')) self.writeSndSeqSegments.setChecked(self.tmpPref["pref"]["sound"]["writeSndSeqSegments"]) soundPrefGrid.addWidget(self.writeSndSeqSegments, n, 0) n = n+1 self.appendSilenceLabel = QLabel(self.tr('Append silence to each sound (ms):')) soundPrefGrid.addWidget(self.appendSilenceLabel, n, 0) self.appendSilenceWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["sound"]["appendSilence"])) soundPrefGrid.addWidget(self.appendSilenceWidget, n, 1) n = n+1 self.soundPrefWidget.setLayout(soundPrefGrid) self.soundPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize) # NOTIFICATION PREF notificationPrefGrid = QGridLayout() n = 0 self.playEndMessage = QCheckBox(self.tr('Play End Message')) self.playEndMessage.setChecked(self.tmpPref["pref"]["general"]["playEndMessage"]) notificationPrefGrid.addWidget(self.playEndMessage, n, 0) self.endMessageButton = QPushButton(self.tr("Choose Wav"), self) self.endMessageButton.clicked.connect(self.onClickEndMessageButton) notificationPrefGrid.addWidget(self.endMessageButton, n, 1) n = n+1 notificationPrefGrid.addItem(QSpacerItem(20,20,QSizePolicy.Expanding), n, 0) n = n+1 self.nBlocksLabel = QLabel(self.tr('blocks before end of experiment:')) notificationPrefGrid.addWidget(self.nBlocksLabel, n, 1) self.nBlocksWidget = QLineEdit(self.currLocale.toString(self.tmpPref['pref']['email']['nBlocksNotify'])) notificationPrefGrid.addWidget(self.nBlocksWidget, n, 0) n = n+1 self.emailNotify = QCheckBox(self.tr('Send Notification e-mail')) self.emailNotify.setChecked(self.tmpPref["pref"]["email"]["notifyEnd"]) notificationPrefGrid.addWidget(self.emailNotify, n, 0) n = n+1 self.nBlocksCustomCommandLabel = QLabel(self.tr('Execute custom command:')) notificationPrefGrid.addWidget(self.nBlocksCustomCommandLabel, n, 0) self.nBlocksCustomCommandWidget = QLineEdit(self.tmpPref["pref"]["general"]["nBlocksCustomCommand"]) notificationPrefGrid.addWidget(self.nBlocksCustomCommandWidget, n, 1) n = n+1 notificationPrefGrid.addItem(QSpacerItem(20,20,QSizePolicy.Expanding), n, 0) n = n+1 self.atEndLabel = QLabel(self.tr('At the end of the experiment:')) notificationPrefGrid.addWidget(self.atEndLabel, n, 0) n = n+1 self.sendData = QCheckBox(self.tr('Send data via e-mail')) self.sendData.setChecked(self.tmpPref["pref"]["email"]["sendData"]) notificationPrefGrid.addWidget(self.sendData, n, 0) n = n+1 self.atEndCustomCommandLabel = QLabel(self.tr('Execute custom command:')) notificationPrefGrid.addWidget(self.atEndCustomCommandLabel, n, 0) self.atEndCustomCommandWidget = QLineEdit(self.tmpPref["pref"]["general"]["atEndCustomCommand"]) notificationPrefGrid.addWidget(self.atEndCustomCommandWidget, n, 1) n = n+1 notificationPrefGrid.addItem(QSpacerItem(20,20,QSizePolicy.Expanding), n, 0) n = n+1 self.serverLabel = QLabel(self.tr('Outgoing server (SMTP):')) notificationPrefGrid.addWidget(self.serverLabel, n, 0) self.serverWidget = QLineEdit(self.tmpPref['pref']['email']['SMTPServer']) notificationPrefGrid.addWidget(self.serverWidget, n, 1) n = n+1 self.serverPortLabel = QLabel(self.tr('Port:')) notificationPrefGrid.addWidget(self.serverPortLabel, n, 0) self.serverPortWidget = QLineEdit(self.currLocale.toString(self.tmpPref['pref']['email']['SMTPServerPort'])) self.serverPortWidget.setValidator(QIntValidator(self)) notificationPrefGrid.addWidget(self.serverPortWidget, n, 1) n = n+1 self.serverSecurityLabel = QLabel(self.tr('Security:')) notificationPrefGrid.addWidget(self.serverSecurityLabel, n, 0) self.serverSecurityChooser = QComboBox() self.serverSecurityChooser.addItems(["TLS/SSL (a)", "TLS/SSL (b)", "none"]) self.serverSecurityChooser.setCurrentIndex(self.serverSecurityChooser.findText(self.tmpPref['pref']['email']['SMTPServerSecurity'])) notificationPrefGrid.addWidget(self.serverSecurityChooser, n, 1) n = n+1 self.serverRequiresAuthCheckBox = QCheckBox(self.tr('Server requires authentication')) self.serverRequiresAuthCheckBox.setChecked(self.tmpPref["pref"]["email"]["serverRequiresAuthentication"]) notificationPrefGrid.addWidget(self.serverRequiresAuthCheckBox, n, 0, 1, 2) n = n+1 self.usernameLabel = QLabel(self.tr('Username:'******'pref']['email']['fromUsername']) notificationPrefGrid.addWidget(self.usernameWidget, n, 1) n = n+1 self.passwordLabel = QLabel(self.tr('Password:'******'pref']['email']['fromPassword']) self.passwordWidget.setEchoMode(QLineEdit.Password) notificationPrefGrid.addWidget(self.passwordWidget, n, 1) n = n+1 self.passwordWarningLabel = QLabel(self.tr('Password is NOT stored safely (see manual), use at your own risk!')) notificationPrefGrid.addWidget(self.passwordWarningLabel, n, 0, 1, 2) n = n+1 self.testEmailButton = QPushButton(self.tr("Send test e-mail"), self) self.testEmailButton.clicked.connect(self.onClickTestEmailButton) self.testEmailButton.setToolTip(self.tr("Send a test e-mail")) notificationPrefGrid.addWidget(self.testEmailButton, n, 0, 1, 2) self.notificationPrefWidget.setLayout(notificationPrefGrid) self.notificationPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize) ##--#--#--#--#-- # EEG PREF GRID eegPrefGrid = QGridLayout() n = 0 self.ONTriggerLabel = QLabel(self.tr('ON Trigger:')) eegPrefGrid.addWidget(self.ONTriggerLabel, n, 0) self.ONTriggerWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["ONTrigger"])) eegPrefGrid.addWidget(self.ONTriggerWidget, n, 1) n = n+1 self.OFFTriggerLabel = QLabel(self.tr('OFF Trigger:')) eegPrefGrid.addWidget(self.OFFTriggerLabel, n, 0) self.OFFTriggerWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["OFFTrigger"])) eegPrefGrid.addWidget(self.OFFTriggerWidget, n, 1) n = n+1 self.triggerDurLabel = QLabel(self.tr('Trigger Duration (ms):')) eegPrefGrid.addWidget(self.triggerDurLabel, n, 0) self.triggerDurWidget = QLineEdit(self.currLocale.toString(self.tmpPref["pref"]["general"]["triggerDur"])) eegPrefGrid.addWidget(self.triggerDurWidget, n, 1) self.eegPrefWidget.setLayout(eegPrefGrid) self.eegPrefWidget.layout().setSizeConstraint(QLayout.SetFixedSize) # ........................ self.tabWidget.addTab(self.appPrefWidget, self.tr("Genera&l")) self.tabWidget.addTab(self.soundPrefWidget, self.tr("Soun&d")) self.tabWidget.addTab(self.notificationPrefWidget, self.tr("Notification&s")) self.tabWidget.addTab(self.eegPrefWidget, self.tr("EE&G")) buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Ok|QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.permanentApply) layout = QVBoxLayout() layout.addWidget(self.tabWidget) layout.addWidget(buttonBox) self.setLayout(layout) def onLanguageChooserChange(self): for i in range(self.countryChooser.count()): self.countryChooser.removeItem(0) self.countryChooser.addItems(self.parent().prm['appData']['available_countries'][self.languageChooser.currentText()]) def onResponseBoxLanguageChooserChange(self): for i in range(self.responseBoxCountryChooser.count()): self.responseBoxCountryChooser.removeItem(0) self.responseBoxCountryChooser.addItems(self.parent().prm['appData']['available_countries'][self.responseBoxLanguageChooser.currentText()]) def onPlayChooserChange(self): foo = self.playChooser.currentText() if foo != self.tr('custom'): self.playCommandLabel.hide() self.playCommandWidget.hide() self.playCommandWidget.setText(foo) self.playCommandWidget.setReadOnly(True) else: self.playCommandWidget.show() self.playCommandLabel.show() self.playCommandWidget.setReadOnly(False) if self.parent().prm["appData"]["alsaaudioAvailable"] == True: if foo == "alsaaudio": self.alsaaudioDeviceLabel.show() self.alsaaudioDeviceChooser.show() else: self.alsaaudioDeviceLabel.hide() self.alsaaudioDeviceChooser.hide() if self.parent().prm["appData"]["pyaudioAvailable"] == True: if foo == "pyaudio": self.pyaudioDeviceLabel.show() self.pyaudioDeviceChooser.show() else: self.pyaudioDeviceLabel.hide() self.pyaudioDeviceChooser.hide() if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True: if foo in ["alsaaudio", "pyaudio"]: self.bufferSizeLabel.show() self.bufferSizeWidget.show() else: self.bufferSizeLabel.hide() self.bufferSizeWidget.hide() def onClickEndMessageButton(self): dialog = wavListDialog(self) if dialog.exec_(): self.wavsList = dialog.wavsList self.wavsPref = {} self.wavsPref['endMessageFiles'] = [] self.wavsPref['endMessageFilesUse'] = [] self.wavsPref['endMessageFilesID'] = [] self.wavsPref['endMessageLevels'] = [] keys = sorted(self.wavsList.keys()) for key in keys: self.wavsPref['endMessageFiles'].append(str(self.wavsList[key]['file'])) self.wavsPref['endMessageFilesUse'].append(self.wavsList[key]['use']) self.wavsPref['endMessageLevels'].append(self.wavsList[key]['level']) self.wavsPref['endMessageFilesID'].append(key) def onClickTestEmailButton(self): self.mailer.sendTestEmail() def popMailerMessage(self, msg, msgtype): if msgtype == 'critical': QMessageBox.critical(self, self.tr("Error"), msg) elif msgtype == 'warning': QMessageBox.warning(self, self.tr("Warning"), msg) elif msgtype == 'information': QMessageBox.information(self, self.tr("Information"), msg) def tryApply(self): self.tmpPref['pref']['language'] = self.tr(self.languageChooser.currentText()) self.tmpPref['pref']['country'] = self.tr(self.countryChooser.currentText()) self.tmpPref['pref']['responseBoxLanguage'] = self.tr(self.responseBoxLanguageChooser.currentText()) self.tmpPref['pref']['responseBoxCountry'] = self.tr(self.responseBoxCountryChooser.currentText()) self.tmpPref['pref']['general']['csvSeparator'] = self.csvSeparatorWidget.text() self.tmpPref['pref']['general']['ONTrigger'] = self.currLocale.toInt(self.ONTriggerWidget.text())[0] self.tmpPref['pref']['general']['OFFTrigger'] = self.currLocale.toInt(self.OFFTriggerWidget.text())[0] self.tmpPref['pref']['general']['triggerDur'] = self.currLocale.toDouble(self.triggerDurWidget.text())[0] self.tmpPref['pref']['general']['maxRecursionDepth'] = self.currLocale.toInt(self.recursionLimitWidget.text())[0] self.tmpPref['pref']['general']['startupCommand'] = self.startupCommandWidget.text() self.tmpPref['pref']['sound']['playCommand'] = self.tr(self.playCommandWidget.text()) self.tmpPref['pref']['sound']['playCommandType'] = self.tr(self.playChooser.currentText()) if self.parent().prm["appData"]["alsaaudioAvailable"] == True: self.tmpPref['pref']['sound']['alsaaudioDevice'] = self.alsaaudioDeviceChooser.currentText() if self.parent().prm["appData"]["pyaudioAvailable"] == True: self.tmpPref['pref']['sound']['pyaudioDevice'] = self.pyaudioDeviceListIdx[self.pyaudioDeviceChooser.currentIndex()] self.tmpPref['pref']['sound']['wavmanager'] = str(self.wavmanagerChooser.currentText()) if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True: self.tmpPref['pref']['sound']['bufferSize'] = self.currLocale.toInt(self.bufferSizeWidget.text())[0] self.tmpPref['pref']['sound']['defaultSampleRate'] = self.samplerateWidget.text() self.tmpPref['pref']['sound']['defaultNBits'] = self.nbitsChooser.currentText() self.tmpPref['pref']['sound']['appendSilence'] = self.currLocale.toInt(self.appendSilenceWidget.text())[0] self.tmpPref["pref"]["email"]["nBlocksNotify"] = self.currLocale.toInt(self.nBlocksWidget.text())[0] self.tmpPref["pref"]["general"]["nBlocksCustomCommand"] = self.nBlocksCustomCommandWidget.text() self.tmpPref["pref"]["general"]["atEndCustomCommand"] = self.atEndCustomCommandWidget.text() self.tmpPref["pref"]["email"]['SMTPServer'] = self.serverWidget.text() self.tmpPref["pref"]["email"]['SMTPServerPort'] = self.currLocale.toInt(self.serverPortWidget.text())[0] self.tmpPref["pref"]["email"]['fromUsername'] = self.usernameWidget.text() self.tmpPref["pref"]["email"]['SMTPServerSecurity'] = self.serverSecurityChooser.currentText() self.tmpPref["pref"]["general"]["endMessageFiles"] = self.wavsPref['endMessageFiles'] self.tmpPref["pref"]["general"]["endMessageFilesUse"] = self.wavsPref['endMessageFilesUse'] self.tmpPref["pref"]["general"]["endMessageFilesID"] = self.wavsPref['endMessageFilesID'] self.tmpPref["pref"]["general"]["endMessageLevels"] = self.wavsPref['endMessageLevels'] self.tmpPref["pref"]["email"]['fromPassword'] = self.passwordWidget.text() if self.writewav.isChecked(): self.tmpPref['pref']['sound']['writewav'] = True else: self.tmpPref['pref']['sound']['writewav'] = False if self.writeSndSeqSegments.isChecked(): self.tmpPref['pref']['sound']['writeSndSeqSegments'] = True else: self.tmpPref['pref']['sound']['writeSndSeqSegments'] = False if self.dpCorrCheckBox.isChecked(): self.tmpPref['pref']['general']['dprimeCorrection'] = True else: self.tmpPref['pref']['general']['dprimeCorrection'] = False if self.listenerNameWarnCheckBox.isChecked(): self.tmpPref['pref']['general']['listenerNameWarn'] = True else: self.tmpPref['pref']['general']['listenerNameWarn'] = False if self.sessionLabelWarnCheckBox.isChecked(): self.tmpPref['pref']['general']['sessionLabelWarn'] = True else: self.tmpPref['pref']['general']['sessionLabelWarn'] = False if self.emailNotify.isChecked(): self.tmpPref['pref']['email']['notifyEnd'] = True else: self.tmpPref['pref']['email']['notifyEnd'] = False if self.sendData.isChecked(): self.tmpPref['pref']['email']['sendData'] = True else: self.tmpPref['pref']['email']['sendData'] = False if self.serverRequiresAuthCheckBox.isChecked(): self.tmpPref['pref']['email']['serverRequiresAuthentication'] = True else: self.tmpPref['pref']['email']['serverRequiresAuthentication'] = False if self.playEndMessage.isChecked(): self.tmpPref['pref']['general']['playEndMessage'] = True else: self.tmpPref['pref']['general']['playEndMessage'] = False if self.tmpPref['pref']['email']['notifyEnd'] == True or self.tmpPref['pref']['email']['sendData'] == True: if checkUsernameValid(self.tmpPref["pref"]["email"]['fromUsername']) == False: errMsg = self.tr("Username invalid. Disabling sending e-mails.") QMessageBox.warning(self, self.tr("Warning"), errMsg) self.emailNotify.setChecked(False) self.sendData.setChecked(False) self.tmpPref['pref']['email']['notifyEnd'] = False self.tmpPref['pref']['email']['sendData'] = False elif checkServerValid(self.tmpPref["pref"]["email"]['SMTPServer']) == False: errMsg = self.tr("SMTP server name invalid. Disabling sending e-mails.") QMessageBox.warning(self, self.tr("Warning"), errMsg) self.emailNotify.setChecked(False) self.sendData.setChecked(False) self.tmpPref['pref']['email']['notifyEnd'] = False self.tmpPref['pref']['email']['sendData'] = False def revertChanges(self): self.languageChooser.setCurrentIndex(self.languageChooser.findText(self.tmpPref['pref']['language'])) self.countryChooser.setCurrentIndex(self.countryChooser.findText(self.tmpPref['pref']['country'])) self.responseBoxLanguageChooser.setCurrentIndex(self.responseBoxLanguageChooser.findText(self.tmpPref['pref']['responseBoxLanguage'])) self.responseBoxCountryChooser.setCurrentIndex(self.responseBoxCountryChooser.findText(self.tmpPref['pref']['responseBoxCountry'])) self.csvSeparatorWidget.setText(self.tmpPref['pref']['general']['csvSeparator']) self.ONTriggerWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['ONTrigger'])) self.OFFTriggerWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['OFFTrigger'])) self.triggerDurWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['triggerDur'])) self.recursionLimitWidget.setText(self.currLocale.toString(self.tmpPref['pref']['general']['maxRecursionDepth'])) self.startupCommandWidget.setText(self.tmpPref['pref']['general']['startupCommand']) self.playChooser.setCurrentIndex(self.playChooser.findText(self.tmpPref['pref']['sound']['playCommandType'])) if self.parent().prm["appData"]["alsaaudioAvailable"] == True: self.alsaaudioDeviceChooser.setCurrentIndex(self.alsaaudioDeviceChooser.findText(self.tmpPref['pref']['sound']['alsaaudioDevice'])) if self.parent().prm["appData"]["pyaudioAvailable"] == True: self.pyaudioDeviceChooser.setCurrentIndex(self.pyaudioDeviceListIdx.index(self.tmpPref['pref']['sound']['pyaudioDevice'])) self.wavmanagerChooser.setCurrentIndex(self.wavmanagerChooser.findText(self.tmpPref['pref']['sound']['wavmanager'])) self.playCommandWidget.setText(self.tmpPref['pref']['sound']['playCommand']) if self.parent().prm["appData"]["alsaaudioAvailable"] == True or self.parent().prm["appData"]["pyaudioAvailable"] == True: self.bufferSizeWidget.setText(self.currLocale.toString(self.tmpPref['pref']['sound']['bufferSize'])) self.samplerateWidget.setText(self.tmpPref['pref']['sound']['defaultSampleRate']) self.nbitsChooser.setCurrentIndex(self.nbitsChooser.findText(self.tmpPref['pref']['sound']['defaultNBits'])) self.appendSilenceWidget.setText(self.currLocale.toString(self.tmpPref['pref']['sound']['appendSilence'])) self.nBlocksWidget.setText(self.currLocale.toString(self.tmpPref['pref']['email']['nBlocksNotify'])) self.nBlocksCustomCommandWidget.setText( self.tmpPref["pref"]["general"]["nBlocksCustomCommand"]) self.atEndCustomCommandWidget.setText( self.tmpPref["pref"]["general"]["nBlocksCustomCommand"]) self.serverWidget.setText(self.tmpPref['pref']['email']['SMTPServer']) self.serverPortWidget.setText(self.currLocale.toString(self.tmpPref['pref']['email']['SMTPServerPort'])) self.usernameWidget.setText(self.tmpPref['pref']['email']['fromUsername']) self.passwordWidget.setText(self.tmpPref['pref']['email']['fromPassword']) self.serverSecurityChooser.setCurrentIndex(self.serverSecurityChooser.findText(self.tmpPref['pref']['email']['SMTPServerSecurity'])) self.wavsPref["endMessageFiles"] = self.tmpPref["pref"]["general"]["endMessageFiles"] self.wavsPref["endMessageFilesUse"] = self.tmpPref["pref"]["general"]["endMessageFilesUse"] self.wavsPref["endMessageFilesID"] = self.tmpPref["pref"]["general"]["endMessageFilesID"] self.wavsPref["endMessageLevels"] = self.tmpPref["pref"]["general"]["endMessageLevels"] if self.playChooser.currentText() != self.tr('custom'): self.playCommandWidget.setReadOnly(True) self.writewav.setChecked(self.tmpPref["pref"]["sound"]["writewav"]) self.writeSndSeqSegments.setChecked(self.tmpPref["pref"]["sound"]["writeSndSeqSegments"]) self.dpCorrCheckBox.setChecked(self.tmpPref["pref"]["general"]["dprimeCorrection"]) self.listenerNameWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["listenerNameWarn"]) self.sessionLabelWarnCheckBox.setChecked(self.tmpPref["pref"]["general"]["sessionLabelWarn"]) self.emailNotify.setChecked(self.tmpPref["pref"]["email"]["notifyEnd"]) self.sendData.setChecked(self.tmpPref["pref"]["email"]["sendData"]) self.serverRequiresAuthCheckBox.setChecked(self.tmpPref["pref"]["email"]["serverRequiresAuthentication"]) self.playEndMessage.setChecked(self.tmpPref["pref"]["general"]["playEndMessage"]) def permanentApply(self): self.tryApply() if self.parent().prm['pref']['email']['fromPassword'] != self.tmpPref['pref']['email']['fromPassword']: passwd = bytes(self.passwordWidget.text(),'utf-8') encoded_passwd = base64.b64encode(passwd) encoded_passwd = str(encoded_passwd, "utf-8") #passwd = hashlib.sha1(passwd).hexdigest() self.tmpPref["pref"]["email"]['fromPassword'] = encoded_passwd self.passwordWidget.setText(self.tmpPref['pref']['email']['fromPassword']) self.parent().prm['pref'] = copy.deepcopy(self.tmpPref['pref']) f = open(self.parent().prm['prefFile'], 'wb') pickle.dump(self.parent().prm['pref'], f) f.close() def tabChanged(self): self.tryApply() if self.tmpPref['pref'] != self.parent().prm['pref']: reply = QMessageBox.warning(self, self.tr("Warning"), self.tr('There are unsaved changes. Apply Changes?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) if reply == QMessageBox.Yes: self.permanentApply() else: self.tmpPref['pref'] = copy.deepcopy(self.parent().prm['pref']) self.revertChanges() def listAlsaaudioPlaybackCards(self): playbackCardList = [] for card in alsaaudio.cards(): try: alsaaudio.PCM(type=alsaaudio.PCM_PLAYBACK, mode=alsaaudio.PCM_NORMAL, card=card) playbackCardList.append(card) except: pass return playbackCardList def listPyaudioPlaybackDevices(self): self.pyaudioHostApiListName = [] self.pyaudioHostApiListIdx = [] self.pyaudioDeviceListName = [] self.pyaudioDeviceListIdx = [] paManager = pyaudio.PyAudio() nDevices = paManager.get_device_count() nApi = paManager.get_host_api_count() for i in range(nApi): self.pyaudioHostApiListName.append(paManager.get_host_api_info_by_index(i)['name']) self.pyaudioHostApiListIdx.append(paManager.get_host_api_info_by_index(i)['index']) for i in range(nDevices): thisDevInfo = paManager.get_device_info_by_index(i) if thisDevInfo["maxOutputChannels"] > 0: self.pyaudioDeviceListName.append(thisDevInfo["name"] + ' - ' + self.pyaudioHostApiListName[thisDevInfo["hostApi"]]) self.pyaudioDeviceListIdx.append(thisDevInfo["index"]) return
class LinkInput(QDialog): def __init__(self, cfg, parent = None): QDialog.__init__(self) self.setParent(parent) self.setWindowFlags(Qt.Dialog) self.setWindowTitle(self.tr('manage links')) self.setModal(1) self.config = cfg self.modified = [] self.links = self.config.loadLinks() self.typeSelect = QComboBox(self) self.plugins = classdirPlugins() plugs = self.plugins.classes() self.typeSelect.addItems(['generic'] + plugs) self.nameSelect = QComboBox(self) self.nameSelect.addItems([l for l in self.links]) self.connect(self.nameSelect, SIGNAL('currentIndexChanged(int)'), self.onNameSelectChange) self.lUserName = QLabel(self.tr('userName'), self) self.lPass = QLabel(self.tr('password'), self) self.lUrl = QLabel(self.tr('Url'), self) self.lType = QLabel(self.tr('widgetType'), self) self.lWidgetName = QLabel(self.tr('widgetName'), self) self.name = QLineEdit(self) self.urlEdit = QLineEdit() self.passwd = QLineEdit(self) self.passwd.setEchoMode(QLineEdit.Password) self.connect(self.typeSelect , SIGNAL('activated(int)') , self.onChange) self.connect(self.urlEdit , SIGNAL('textEdited(QString)') , self.onChange) self.connect(self.name , SIGNAL('textEdited(QString)') , self.onChange) self.connect(self.passwd , SIGNAL('textEdited(QString)') , self.onChange) self.newButton = QPushButton(self.tr('&new'), self) self.delButton = QPushButton(self.tr('&del'), self) self.savButton = QPushButton(self.tr('&save'), self) self.finButton = QPushButton(self.tr('&finish'), self) self.defFont = QFont() self.connect(self.newButton, SIGNAL('clicked()'), self.onNewClick) self.connect(self.delButton, SIGNAL('clicked()'), self.onDelClick) self.connect(self.savButton, SIGNAL('clicked()'), self.onSavClick) self.connect(self.finButton, SIGNAL('clicked()'), self.onFinClick) self.layout = QGridLayout(self) self.layout.addWidget(self.lWidgetName , 0 , 0) self.layout.addWidget(self.lType , 2 , 0) self.layout.addWidget(self.lUrl , 3 , 0) self.layout.addWidget(self.lUserName , 4 , 0) self.layout.addWidget(self.lPass , 5 , 0) self.layout.addWidget(self.nameSelect , 0 , 1) self.layout.addWidget(self.typeSelect , 2 , 1) self.layout.addWidget(self.urlEdit , 3 , 1) self.layout.addWidget(self.name , 4 , 1) self.layout.addWidget(self.passwd , 5 , 1) self.layout.addWidget(self.newButton , 1 , 2) self.layout.addWidget(self.delButton , 2 , 2) self.layout.addWidget(self.savButton , 3 , 2) self.layout.addWidget(self.finButton , 4 , 2) self.setMinimumWidth(500) self.nameSelect.setCurrentIndex(self.nameSelect.count()-1) def onChange(self): self.savButton.setFont(QFont(self.defFont.defaultFamily(), -1, QFont.Bold)) def onSavClick(self): if self.urlEdit.text().isEmpty(): self.urlEdit.setText(self.tr("insert URL here")) self.urlEdit.selectAll() else: u = QUrl() u.setUrl(self.urlEdit.text()) if not u.scheme(): u.setScheme('http') u.setUserName(self.name.text()) u.setPassword(self.passwd.text()) self.config.saveLink(self.nameSelect.currentText(), { 'type' : self.typeSelect.currentText(), 'data' : u.toString()}) #self.links = self.config.loadLinks() self.savButton.setFont(QFont()) self.modified.append(str(self.nameSelect.currentText())) def onNewClick(self): inp = StringInput([l for l in self.links], self) if inp.exec_(): self.name.clear() self.passwd.clear() self.urlEdit.clear() self.nameSelect.addItem(inp.getVal()) self.nameSelect.setCurrentIndex(self.nameSelect.findText(inp.getVal())) def onDelClick(self): if QMessageBox( QMessageBox.Question, self.tr('del_link'), self.tr('ask_del_link %1 ?').arg(self.nameSelect.currentText()), QMessageBox.Yes | QMessageBox.No, self).exec_() == QMessageBox.Yes: if not self.config.delLink(self.nameSelect.currentText()): print(('link "%s" not deleted !' % self.nameSelect.currentText())) self.links = self.config.loadLinks() self.nameSelect.removeItem(self.nameSelect.currentIndex()) def onFinClick(self): self.accept() def onNameSelectChange(self): try: l = self.links[str(self.nameSelect.currentText())] u = QUrl(l['data']) self.name.setText(u.userName()) self.passwd.setText(u.password()) self.urlEdit.setText(u.toString(QUrl.RemoveUserInfo)) self.typeSelect.setCurrentIndex(self.typeSelect.findText(l['type'])) except Exception as e: #print e pass def modifiedWidgets(self): return set(self.modified)
class Plugin(QObject): def __init__(self, iface): QObject.__init__(self) self.__iface = iface self.__shortcuts = [] self.__current_section = QComboBox() self.__current_section.setMinimumWidth(150) self.__current_graph = QComboBox() self.__current_graph.setMinimumWidth(150) self.__toolbar = None self.__axis_layer = None self.__menu = None self.__log_strati = None def initGui(self): for keyseq, slot in ( (Qt.CTRL + Qt.ALT + Qt.Key_K, self.__create_group), (Qt.CTRL + Qt.ALT + Qt.Key_S, self.__select_next_group), (Qt.CTRL + Qt.ALT + Qt.Key_N, self.__next_section), (Qt.CTRL + Qt.ALT + Qt.Key_B, self.__previous_section) ): short = QShortcut(QKeySequence(keyseq), self.__iface.mainWindow()) short.setContext(Qt.ApplicationShortcut) short.activated.connect(slot) self.__shortcuts.append(short) self.__menu = QMenu("Albion") self.__menu.aboutToShow.connect(self.__create_menu_entries) self.__iface.mainWindow().menuBar().addMenu(self.__menu) self.__toolbar = QToolBar('Albion') self.__iface.addToolBar(self.__toolbar) self.__toolbar.addAction(icon('log_strati.svg'), 'stratigraphic log').triggered.connect(self.__log_strati_clicked) self.__toolbar.addWidget(self.__current_graph) self.__current_graph.currentIndexChanged[unicode].connect(self.__current_graph_changed) self.__toolbar.addWidget(self.__current_section) self.__current_section.currentIndexChanged[unicode].connect(self.__current_section_changed) self.__toolbar.addAction(icon('previous_line.svg'), 'previous section (Ctrl+Alt+b)').triggered.connect(self.__previous_section) self.__toolbar.addAction(icon('next_line.svg'), 'next section (Ctrl+Alt+n)').triggered.connect(self.__next_section) self.__toolbar.addAction(icon('line_from_selected.svg'), 'create temporary section').triggered.connect(self.__section_from_selection) self.__viewer3d = QDockWidget('3D') self.__viewer3d.setWidget(Viewer3d()) self.__iface.addDockWidget(Qt.LeftDockWidgetArea, self.__viewer3d) self.__iface.mainWindow().tabifyDockWidget( self.__iface.mainWindow().findChild(QDockWidget, "Layers"), self.__viewer3d) self.__viewer3d_ctrl = QToolBar('3D controls') self.__viewer3d_ctrl.addWidget(ViewerControls(self.__viewer3d.widget())) self.__iface.addToolBar(self.__viewer3d_ctrl) QgsProject.instance().readProject.connect(self.__qgis__project__loaded) self.__qgis__project__loaded() # case of reload def unload(self): for s in self.__shortcuts: s.setParent(None) self.__toolbar and self.__toolbar.setParent(None) self.__menu and self.__menu.setParent(None) self.__viewer3d and self.__viewer3d.setParent(None) self.__viewer3d_ctrl and self.__viewer3d_ctrl.setParent(None) def __add_menu_entry(self, name, callback, enabled=True, help_str=''): act = self.__menu.addAction(name) if callback is not None: act.triggered.connect(callback) act.setEnabled(enabled) act.setToolTip(help_str) else: act.setEnabled(False) act.setToolTip("NOT INMPLEMENTED "+help_str) return act def __create_menu_entries(self): self.__menu.clear() self.__add_menu_entry('New &Project', self.__new_project) self.__add_menu_entry('Import Project', self.__import_project) self.__add_menu_entry('Upgrade Project', self.__upgrade_project) self.__menu.addSeparator() self.__add_menu_entry('&Import Data', self.__import_data, self.project is not None, "Import data from directory. The data files are in ") self.__menu.addSeparator() self.__add_menu_entry('Create cells', self.__create_cells, self.project is not None and self.project.has_collar, "Create Delaunay triangulation of collar layer.") self.__add_menu_entry('Refresh all edges', self.__refresh_all_edge, self.project is not None and self.project.has_cell, "Refresh materialized view of all cell edges used by graph possible edges.") self.__menu.addSeparator() #self.__add_menu_entry(u'Create section views 0° and 90°', self.__create_section_view_0_90, # False and self.project is not None and self.project.has_hole, # "Create section views (i.e. cut directions) to work West-East and South-North for this project") #self.__add_menu_entry(u'Create section views -45° and 45°', None, # False and self.project is not None and self.project.has_hole, # "Create section views (i.e. cut directions) to work SE-NW and SW-NE for this project") # #self.__menu.addSeparator() self.__add_menu_entry('Create sections', self.__create_sections, self.project is not None and self.project.has_group_cell, "Once cell groups have been defined, create section lines.") self.__menu.addSeparator() self.__add_menu_entry('Compute &Mineralization', self.__compute_mineralization, self.project is not None and self.project.has_radiometry, "") self.__menu.addSeparator() self.__add_menu_entry('New &Graph', self.__new_graph, self.project is not None, "Create a new grap.h") self.__add_menu_entry('Delete Graph', self.__delete_graph, self.project is not None) self.__menu.addSeparator() self.__add_menu_entry('Create volumes', self.__create_volumes, self.project is not None and bool(self.__current_graph.currentText()), "Create volumes associated with current graph.") self.__menu.addSeparator() self.__add_menu_entry('Create terminations', self.__create_terminations, self.project is not None and bool(self.__current_graph.currentText()), "Create terminations associated with current graph.") self.__menu.addSeparator() self.__add_menu_entry('Toggle axis', self.__toggle_axis) self.__menu.addSeparator() self.__add_menu_entry('Export Project', self.__export_project, self.project is not None) self.__add_menu_entry('Export Sections', None, self.project is not None and self.project.has_section, "Export triangulated section in .obj or .dxf format") self.__add_menu_entry('Export Volume', self.__export_volume, self.project is not None and bool(self.__current_graph.currentText()), "Export volume of current graph in .obj or .dxf format") self.__menu.addSeparator() self.__menu.addAction('Help').triggered.connect(self.open_help) def __current_graph_changed(self, graph_id): if self.project is None: return self.__viewer3d.widget().set_graph(graph_id) def __getattr__(self, name): if name == "project": project_name = QgsProject.instance().readEntry("albion", "project_name", "")[0] return Project(project_name) if project_name else None else: raise AttributeError(name) def __refresh_all_edge(self): if self.project is None: return self.project.refresh_all_edge() def __create_terminations(self): if self.project is None: return self.project.create_terminations(self.__current_graph.currentText()) self.__viewer3d.widget().refresh_data() self.__refresh_layers('section') def __create_volumes(self): if self.project is None: return self.project.create_volumes(self.__current_graph.currentText()) self.__viewer3d.widget().refresh_data() def __next_section(self): if self.project is None: return self.project.next_section(self.__current_section.currentText()) self.__refresh_layers('section') self.__viewer3d.widget().scene.update('section') self.__viewer3d.widget().update() def __previous_section(self): if self.project is None: return self.project.previous_section(self.__current_section.currentText()) self.__refresh_layers('section') self.__viewer3d.widget().scene.update('section') self.__viewer3d.widget().update() def __refresh_layers(self, name=None): for layer in self.__iface.mapCanvas().layers(): if name is None or layer.name().find(name) != -1: layer.triggerRepaint() def __current_section_changed(self, section_id): layers = QgsMapLayerRegistry.instance().mapLayersByName(u"group_cell") if len(layers): layers[0].setSubsetString("section_id='{}'".format(section_id)) self.__refresh_layers('section') def __select_next_group(self): if self.project and self.__iface.activeLayer() and self.__iface.activeLayer().name() == u"cell": self.__iface.activeLayer().removeSelection() self.__iface.activeLayer().selectByExpression( "id in ({})".format(",".join(project.next_group_ids()))) def __create_group(self): if self.project and self.__iface.activeLayer() and self.__iface.activeLayer().name() == u"cell": if self.__iface.activeLayer().selectedFeatureCount(): section = self.__current_section.currentText() self.project.create_group(section, [f['id'] for f in self.__iface.activeLayer().selectedFeatures()]) self.__iface.activeLayer().removeSelection() self.__refresh_layers('group_cell') def __qgis__project__loaded(self): if self.project is None: return self.__current_graph.clear() self.__current_section.clear() self.__current_section.addItems(self.project.sections()) self.__current_graph.addItems(self.project.graphs()) layers = QgsMapLayerRegistry.instance().mapLayersByName('section.anchor') if len(layers): layers[0].editingStopped.connect(self.__update_section_list) self.__viewer3d.widget().resetScene(self.project) def __update_section_list(self): self.__current_section.clear() self.__current_section.addItems(self.project.sections()) def __upgrade_project(self): project_name, ok = QInputDialog.getText(self.__iface.mainWindow(), "Database name", "Database name:", QLineEdit.Normal, '') if not ok: return Project(project_name).update() def __new_project(self): # @todo open dialog to configure project name and srid fil = QFileDialog.getSaveFileName(None, u"New project name (no space, plain ascii)", QgsProject.instance().readEntry("albion", "last_dir", "")[0], "QGIS poject file (*.qgs)") if not fil: return fil = fil if len(fil)>4 and fil[-4:]=='.qgs' else fil+'.qgs' fil = fil.replace(' ','_') try: fil.decode('ascii') except UnicodeDecodeError: self.__iface.messageBar().pushError('Albion:', "project name may only contain asci character (no accent)") return srid, ok = QInputDialog.getText(self.__iface.mainWindow(), "Project SRID", "Project SRID EPSG:", QLineEdit.Normal, '32632') if not ok: return srid = int(srid) project_name = str(os.path.split(fil)[1][:-4]) if Project.exists(project_name): if QMessageBox.Yes != QMessageBox(QMessageBox.Information, "Delete existing DB", "Database {} exits, to you want to delete it ?".format(project_name), QMessageBox.Yes|QMessageBox.No).exec_(): return Project.delete(project_name) self.__iface.messageBar().pushInfo('Albion:', "creating project...") Project.create(project_name, srid) # load template open(fil, 'w').write( open(resource('template_project.qgs')).read().replace('template_project', project_name)) self.__iface.newProject() QgsProject.instance().setFileName(fil) QgsProject.instance().read() QgsProject.instance().writeEntry("albion", "project_name", project_name) QgsProject.instance().writeEntry("albion", "srid", srid) QgsProject.instance().write() self.__qgis__project__loaded() def __import_data(self): if self.project is None: return if not QgsProject.instance().readEntry("albion", "conn_info", "")[0]: return dir_ = QFileDialog.getExistingDirectory(None, u"Data directory", QgsProject.instance().readEntry("albion", "last_dir", "")[0]) if not dir_: return QgsProject.instance().writeEntry("albion", "last_dir", dir_), progressMessageBar = self.__iface.messageBar().createMessage("Loading {}...".format(dir_)) progress = QProgressBar() progress.setAlignment(Qt.AlignLeft|Qt.AlignVCenter) progressMessageBar.layout().addWidget(progress) self.__iface.messageBar().pushWidget(progressMessageBar, self.__iface.messageBar().INFO) self.project.import_data(dir_, ProgressBar(progress)) self.project.triangulate() self.project.create_section_view_0_90(4) self.__iface.messageBar().clearWidgets() collar = QgsMapLayerRegistry.instance().mapLayersByName('collar')[0] collar.reload() collar.updateExtents() self.__iface.setActiveLayer(collar) QApplication.instance().processEvents() while self.__iface.mapCanvas().isDrawing(): QApplication.instance().processEvents() self.__iface.zoomToActiveLayer() self.__iface.actionSaveProject().trigger() self.__viewer3d.widget().resetScene(self.project) self.__current_section.clear() self.__current_section.addItems(self.project.sections()) def __new_graph(self): if self.project is None: return graph, ok = QInputDialog.getText(self.__iface.mainWindow(), "Graph", "Graph name:", QLineEdit.Normal, 'test_graph') if not ok: return parent, ok = QInputDialog.getText(self.__iface.mainWindow(), "Parent Graph", "Parent Graph name:", QLineEdit.Normal, '') if not ok: return self.project.new_graph(graph, parent) self.__current_graph.addItem(graph) self.__current_graph.setCurrentIndex(self.__current_graph.findText(graph)) def __delete_graph(self): if self.project is None: return graph, ok = QInputDialog.getText(self.__iface.mainWindow(), "Graph", "Graph name:", QLineEdit.Normal, self.__current_graph.currentText()) if not ok: return self.__current_graph.removeItem(self.__current_graph.findText(graph)) def __toggle_axis(self): if self.__axis_layer: pass QgsMapLayerRegistry.instance().removeMapLayer(self.__axis_layer.id()) self.__axis_layer = None else: self.__axis_layer = AxisLayer(self.__iface.mapCanvas().mapSettings().destinationCrs()) QgsMapLayerRegistry.instance().addMapLayer(self.__axis_layer) self.__refresh_layers() def __create_cells(self): if self.project is None: return self.project.triangulate() self.__refresh_layers('cells') def __create_sections(self): if self.project is None: return self.project.create_sections() def __compute_mineralization(self): MineralizationDialog(self.project).exec_() def __export_volume(self): if self.project is None: return fil = QFileDialog.getSaveFileName(None, u"Export volume for current graph", QgsProject.instance().readEntry("albion", "last_dir", "")[0], "File formats (*.dxf *.obj)") if not fil: return QgsProject.instance().writeEntry("albion", "last_dir", os.path.dirname(fil)), if fil[-4:] == '.obj': self.project.export_obj(self.__current_graph.currentText(), fil) elif fil[-4:] == '.dxf': self.project.export_dxf(self.__current_graph.currentText(), fil) else: self.__iface.messageBar().pushWarning('Albion', 'unsupported extension for volume export') def __import_project(self): fil = QFileDialog.getOpenFileName(None, u"Import project from file", QgsProject.instance().readEntry("albion", "last_dir", "")[0], "File formats (*.zip)") if not fil: return QgsProject.instance().writeEntry("albion", "last_dir", os.path.dirname(fil)), if fil[-4:] != '.zip': self.__iface.messageBar().pushWarning('Albion', 'unsupported extension for import') project_name = os.path.split(fil)[1][:-4] dir_ = tempfile.gettempdir() with zipfile.ZipFile(fil, "r") as z: z.extractall(dir_) dump = find_in_dir(dir_, '.dump') prj = find_in_dir(dir_, '.qgs') self.__iface.messageBar().pushInfo('Albion', 'loading {} from {}'.format(project_name, dump)) if Project.exists(project_name): if QMessageBox.Yes != QMessageBox(QMessageBox.Information, "Delete existing DB", "Database {} exits, to you want to delete it ?".format(project_name), QMessageBox.Yes|QMessageBox.No).exec_(): return Project.delete(project_name) project = Project.import_(project_name, dump) QgsProject.instance().read(QFileInfo(prj)) def __export_project(self): if self.project is None: return fil = QFileDialog.getSaveFileName(None, u"Export project", QgsProject.instance().readEntry("albion", "last_dir", "")[0], "Data files(*.zip)") if not fil: return QgsProject.instance().writeEntry("albion", "last_dir", os.path.dirname(fil)), if os.path.exists(fil): os.remove(fil) with zipfile.ZipFile(fil, 'w') as project: dump = tempfile.mkstemp()[1] self.project.export(dump) project.write(dump, self.project.name+'.dump') project.write(QgsProject.instance().fileName(), os.path.split(QgsProject.instance().fileName())[1]) def __create_section_view_0_90(self): if self.project is None: return self.project.create_section_view_0_90() def __log_strati_clicked(self): #@todo switch behavior when in section view -> ortho self.__click_tool = QgsMapToolEmitPoint(self.__iface.mapCanvas()) self.__iface.mapCanvas().setMapTool(self.__click_tool) self.__click_tool.canvasClicked.connect(self.__map_log_clicked) def __map_log_clicked(self, point, button): self.__click_tool.setParent(None) self.__click_tool = None if self.project is None: self.__log_strati and self.__log_strati.setParent(None) self.__log_strati = None return if self.__log_strati is None: self.__log_strati = QDockWidget('Stratigraphic Log') self.__log_strati.setWidget(BoreHoleWindow(self.project)) self.__iface.addDockWidget(Qt.LeftDockWidgetArea, self.__log_strati) self.__iface.mainWindow().tabifyDockWidget( self.__iface.mainWindow().findChild(QDockWidget, "Layers"), self.__log_strati) res = self.project.closest_hole_id(point.x(), point.y()) if res: self.__log_strati.widget().scene.set_current_id(res) self.__log_strati.show() self.__log_strati.raise_() def __section_from_selection(self): if self.project is None: return if self.__iface.activeLayer() and self.__iface.activeLayer().name() == u"collar" \ and self.__iface.activeLayer().selectedFeatures(): collar = self.__iface.activeLayer() selection = collar.selectedFeatures() if len(selection) < 2: return def align(l): assert len(l) >= 2 res = numpy.array(l[:2]) for p in l[2:]: u, v = res[0] - res[1], p - res[1] if numpy.dot(u,v) < 0: res[1] = p elif numpy.dot(u, u) < numpy.dot(v,v): res[0] = p # align with ref direction sqrt2 = math.sqrt(2.)/2 l = l[numpy.argsort(numpy.dot(l-res[0], res[1]-res[0]))] d = numpy.array(l[-1] - l[0]) dr = numpy.array([(0,1),(sqrt2, sqrt2),(1,0), (sqrt2, -sqrt2)]) i = numpy.argmax(numpy.abs(dr.dot(d))) return l if (dr.dot(d))[i] > 0 else l[::-1] line = LineString(align(numpy.array([f.geometry().asPoint() for f in selection]))) collar.removeSelection() self.project.set_section_geom(self.__current_section.currentText(), line) self.__refresh_layers('section') self.__viewer3d.widget().scene.update('section') self.__viewer3d.widget().update() def open_help(self): QDesktopServices.openUrl(QUrl.fromLocalFile(os.path.join(os.path.dirname(__file__), 'doc', 'build', 'html', 'index.html')))
class ShowSettingsDialog(QDialog): """ Dialog class for plugin settings """ def __init__(self, iface, configTable, uriDb, schemaDb): """ Constructor :param iface: interface :param memoryPointsLayer: working memory points layer :param memoryLinesLayer: working memory lines layer :param configTable: config table selected for import """ QDialog.__init__(self) self.__iface = iface self.__configTable = configTable self.__uriDb = uriDb self.__schemaDb = schemaDb self.setWindowTitle( QCoreApplication.translate("VDLNetwork", "Settings")) self.__tables = [] self.__schemas = [] self.__dbs = DBConnector.getUsedDatabases() self.resize(450, 200) self.__layout = QGridLayout() dbLabel = QLabel( QCoreApplication.translate("VDLNetwork", "Control database : ")) dbLabel.setMinimumHeight(20) dbLabel.setMinimumWidth(50) self.__layout.addWidget(dbLabel, 0, 1) self.__dbCombo = QComboBox() self.__dbCombo.setMinimumHeight(20) self.__dbCombo.setMinimumWidth(50) self.__dbCombo.addItem("") for db in list(self.__dbs.keys()): self.__dbCombo.addItem(db) self.__layout.addWidget(self.__dbCombo, 0, 2) schemaLabel = QLabel( QCoreApplication.translate("VDLNetwork", "Control schema : ")) schemaLabel.setMinimumHeight(20) schemaLabel.setMinimumWidth(50) self.__layout.addWidget(schemaLabel, 1, 1) self.__schemaCombo = QComboBox() self.__schemaCombo.setMinimumHeight(20) self.__schemaCombo.setMinimumWidth(50) self.__schemaCombo.addItem("") self.__layout.addWidget(self.__schemaCombo, 1, 2) tableLabel = QLabel( QCoreApplication.translate("VDLNetwork", "Control table : ")) tableLabel.setMinimumHeight(20) tableLabel.setMinimumWidth(50) self.__layout.addWidget(tableLabel, 2, 1) self.__tableCombo = QComboBox() self.__tableCombo.setMinimumHeight(20) self.__tableCombo.setMinimumWidth(50) self.__tableCombo.addItem("") self.__layout.addWidget(self.__tableCombo, 2, 2) self.__okButton = QPushButton( QCoreApplication.translate("VDLNetwork", "OK")) self.__okButton.setMinimumHeight(20) self.__okButton.setMinimumWidth(100) self.__cancelButton = QPushButton( QCoreApplication.translate("VDLNetwork", "Cancel")) self.__cancelButton.setMinimumHeight(20) self.__cancelButton.setMinimumWidth(100) self.__layout.addWidget(self.__okButton, 100, 1) self.__layout.addWidget(self.__cancelButton, 100, 2) self.setLayout(self.__layout) self.__dbCombo.currentIndexChanged.connect(self.__dbComboChanged) self.__schemaCombo.currentIndexChanged.connect( self.__schemaComboChanged) self.__tableCombo.currentIndexChanged.connect(self.__tableComboChanged) if self.__uriDb is not None: if self.__uriDb.database() in list(self.__dbs.keys()): self.__dbCombo.setCurrentIndex( list(self.__dbs.keys()).index(self.__uriDb.database()) + 1) @staticmethod def __resetCombo(combo): """ To reset a combo list :param combo: concerned combo """ while combo.count() > 0: combo.removeItem(combo.count() - 1) def __setSchemaCombo(self, uriDb): """ To fill the schema combo list :param uriDb: selected database uri """ connector = DBConnector(uriDb, self.__iface) db = connector.setConnection() if db: Signal.safelyDisconnect(self.__schemaCombo.currentIndexChanged, self.__schemaComboChanged) self.__resetCombo(self.__schemaCombo) self.__schemaCombo.addItem("") self.__schemas = [] query = db.exec_( """SELECT DISTINCT table_schema FROM information_schema.tables WHERE table_schema NOT IN ('pg_catalog', 'information_schema', 'topology') AND table_type = 'BASE TABLE' AND table_name NOT IN (SELECT f_table_name FROM geometry_columns)""") if query.lastError().isValid(): self.__iface.messageBar().pushMessage( query.lastError().text(), level=QgsMessageBar.CRITICAL, duration=0) else: while next(query): self.__schemas.append(query.value(0)) db.close() for schema in self.__schemas: self.__schemaCombo.addItem(schema) self.__schemaCombo.currentIndexChanged.connect( self.__schemaComboChanged) if self.__schemaDb is not None: if self.__schemaDb in self.__schemas: self.__schemaCombo.setCurrentIndex( self.__schemas.index(self.__schemaDb) + 1) def __setTableCombo(self, uriDb, schema): """ To fill the table combo list :param uriDb: selected database uri :param schema: selected database schema """ connector = DBConnector(uriDb, self.__iface) db = connector.setConnection() if db: Signal.safelyDisconnect(self.__tableCombo.currentIndexChanged, self.__tableComboChanged) self.__resetCombo(self.__tableCombo) self.__tableCombo.addItem("") self.__tables = [] query = db.exec_( """SELECT table_name FROM information_schema.tables WHERE table_schema = '""" + schema + """' ORDER BY table_name""") if query.lastError().isValid(): self.__iface.messageBar().pushMessage( query.lastError().text(), level=QgsMessageBar.CRITICAL, duration=0) else: while next(query): self.__tables.append(query.value(0)) db.close() for table in self.__tables: if self.__tableCombo.findText(table) == -1: self.__tableCombo.addItem(table) self.__tableCombo.currentIndexChanged.connect( self.__tableComboChanged) if self.__configTable is not None: if self.__configTable in self.__tables: self.__tableCombo.setCurrentIndex( self.__tables.index(self.__configTable) + 1) def __tableComboChanged(self): """ To remove blank item when another one is selected """ if self.__tableCombo.itemText(0) == "": self.__tableCombo.removeItem(0) def __dbComboChanged(self): """ When the selection in db combo has changed """ if self.__dbCombo.itemText(0) == "": self.__dbCombo.removeItem(0) if self.uriDb() is not None: self.__setSchemaCombo(self.uriDb()) def __schemaComboChanged(self): """ When the selection in schema combo has changed """ if self.__schemaCombo.itemText(0) == "": self.__schemaCombo.removeItem(0) if self.schemaDb() is not None: self.__setTableCombo(self.uriDb(), self.schemaDb()) def okButton(self): """ To get the ok button instance :return: ok button instance """ return self.__okButton def cancelButton(self): """ To get the cancel button instance :return: cancel button instance """ return self.__cancelButton def configTable(self): """ To get the selected config table :return: selected config table, or none """ index = self.__tableCombo.currentIndex() if self.__tableCombo.itemText(index) == "": return None else: return self.__tables[index] def uriDb(self): """ To get selected import database uri :return: import database uri """ index = self.__dbCombo.currentIndex() if self.__dbCombo.itemText(index) == "": return None else: return self.__dbs[list(self.__dbs.keys())[index]] def schemaDb(self): """ To get selected import database schema :return: import database schema """ index = self.__schemaCombo.currentIndex() if self.__schemaCombo.itemText(index) == "": return None else: return self.__schemas[index]
class Plugin(BasePlugin): button_label = _("Coinapult Locks") def __init__(self, config, name): BasePlugin.__init__(self, config, name) self.balance_updater = None self.gui = None self.Locks_action = None self.Locks_currency = None self.Locks_amount = None self.btc_rate = decimal.Decimal("0.0") self.wallet = None self.tabLayout = None self.quote_button = None self.ecc_pub_key_edit = None self.ecc_priv_key_edit = None self.ca_ok_button = None self.unlock_address = None self.specify_by_currency = None @hook def init_qt(self, gui): self.gui = gui if not self.agreed_tos(): if self.settings_dialog(): self.enable() return True else: self.disable() return False else: self.gui.main_window.tabs.addTab(self.create_locks_tab(), "Locks") @hook def get_locks_balances(self, r): bals = self.config.get('Locks_balances', LOCKS_BALS) r[0] = bals @hook def load_wallet(self, wallet): self.wallet = wallet authmethod = self.config.get('coinapult_auth_method', 'REST') if authmethod == 'REST': self.client = CoinapultClient(credentials={'key': self.api_key(), 'secret': self.api_secret()}) else: ecc_pub = self.wallet.storage.get("coinapult_ecc_public", '') ecc_priv = self.wallet.storage.get("coinapult_ecc_private", '') try: self.client = CoinapultClient(ecc={'pubkey': ecc_pub, 'privkey': ecc_priv}, authmethod='ecc') except (CoinapultError, CoinapultErrorECC): self.client = None QMessageBox.warning(None, _('Coinapult Connection failed'), _('Failed to connect to Coinapult. Locks disabled for this session.'), _('OK')) self.disable() self.init_balances() def init_balances(self): if self.balance_updater is None: self.balance_updater = Balance_updater(self) self.balance_updater.start() self.gui.balance_updater = self.balance_updater elif not self.balance_updater.is_running: self.balance_updater.is_running = True self.gui.main_window.connect(self.gui.main_window, SIGNAL("refresh_locks_account()"), self.gui.main_window.update_status) self.gui.main_window.connect(self.gui.main_window, SIGNAL("refresh_locks_account()"), self.update_locks_bal_display) def api_key(self): return self.config.get("plugin_coinapult_locks_api_key") def api_secret(self): return self.config.get("plugin_coinapult_locks_api_secret") def agreed_tos(self): return self.config.get("plugin_coinapult_locks_tos", False) def fullname(self): return 'Coinapult Locks' def description(self): return _("Coinapult's Locks service lets users tie the value of their bitcoins to USD, EUR, GBP, " "gold or silver.") def update_locks_bal_display(self): lock_bals = self.config.get('Locks_balances', LOCKS_BALS) unlock_bals = self.config.get('Locks_unbalances', LOCKS_BALS) row = 1 for cur in LOCKS_CURRENCIES: if cur == 'XAU': disp_cur = 'Gold oz' elif cur == 'XAG': disp_cur = 'Silver oz' else: disp_cur = cur widg = self.balsLayout.itemAtPosition(row, 0) if unlock_bals[cur] > 0: widg.widget().setText("<font size='5'>%s [+%s unconfirmed] %s</font>" % (floor(lock_bals[cur]*1000)/1000, floor(unlock_bals[cur] * 1000) / 1000, disp_cur)) else: widg.widget().setText("<font size='5'>%s %s</font>" % (floor(lock_bals[cur]*1000)/1000, disp_cur)) row += 1 # widg = self.tabLayout.itemAtPosition(row, 1) # widg.widget().setText('%s BTC' % lock_bals['BTC']) def create_locks_tab(self): self.specify_by_currency = QComboBox() def on_change_currency(currency): if currency != self.Locks_currency: self.Locks_currency = LOCKS_CURRENCIES[currency] self.specify_by_currency.clear() otheri = 0 if self.specify_by_currency.findText('BTC') > 0 else 1 self.specify_by_currency.removeItem(otheri) self.specify_by_currency.addItem(str(LOCKS_CURRENCIES[currency])) self.specify_by_currency.addItem('BTC') self.specify_by_currency.setMaximumWidth(60) def on_btc_amount_change(amount): if amount != self.Locks_amount: self.Locks_amount = amount def on_change_action(act): action = LOCK_ACTIONS[act] if action != self.Locks_action: self.Locks_action = action def get_quote(): specifiedCurrency = self.specify_by_currency.currentText() def get_lock(): if specifiedCurrency == 'BTC': amount = float(self.Locks_amount) outAmount = 0 else: amount = 0 outAmount = float(self.Locks_amount) try: lock = self.client.lock(amount=amount, outAmount=outAmount, currency=self.Locks_currency) # print json.dumps(lock, indent=4) pending_locks = self.config.get('pending_locks', []) pending_locks.append(lock) self.config.set_key('pending_locks', pending_locks, True) return lock except (CoinapultError, CoinapultErrorECC) as ce: QMessageBox.warning(None, _('Lock Failed'), _('Lock action failed due to reason: %s') % ce, _('OK')) def get_unlock(): if specifiedCurrency == 'BTC': amount = 0 outAmount = float(self.Locks_amount) else: amount = float(self.Locks_amount) outAmount = 0 for addr in self.wallet.addresses(): u, used = self.wallet.is_used(addr) if not used and u == 0: self.unlock_address = addr break try: unlock = self.client.unlock(amount=amount, outAmount=outAmount, currency=str(self.Locks_currency), address=str(self.unlock_address)) # print json.dumps(unlock, indent=4) pending_unlocks = self.config.get('pending_unlocks', []) pending_unlocks.append(unlock) self.config.set_key('pending_unlocks', pending_unlocks, True) return unlock except (CoinapultError, CoinapultErrorECC) as ce: QMessageBox.warning(None, _('Unlock Failed'), _('Unlock action failed due to reason: %s') % ce, _('OK')) self.quote_button.setDisabled(True) if self.Locks_action == 'Lock': self.waiting_dialog = WaitingDialog(w, 'Requesting Lock Quote', get_lock, self.lock_confirm_dialog) self.waiting_dialog.start() else: self.waiting_dialog = WaitingDialog(w, 'Requesting Unlock Quote', get_unlock, self.unlock_confirm_dialog) self.waiting_dialog.start() w = QWidget() self.tabLayout = QGridLayout(w) self.tabLayout.setColumnMinimumWidth(3, 400) self.tabLayout.setColumnStretch(0, 5) self.tabLayout.setHorizontalSpacing(10) about_locks_label = QLabel(ABOUT_LOCKS) about_locks_label.setWordWrap(True) about_locks_label.setOpenExternalLinks(True) self.tabLayout.addWidget(about_locks_label, 0, 2, 2, 3, Qt.AlignTop) self.balsLayout = QGridLayout(w) self.balsLayout.setColumnMinimumWidth(35, 400) self.balsLayout.setHorizontalSpacing(10) # self.balsLayout.setFrameStyle(QFrame.VLine) row = 0 balw = QLabel(_("<font size='5' style='bold'>Current Locks Balances</font>")) # balw.setBackgroundRole(QPalette_ColorRole=QPalette_ColorRole) balw.setBackgroundRole(QPalette.Midlight) balw.setAutoFillBackground(True) balw.setMinimumWidth(250) self.balsLayout.addWidget(balw, row, 0) row += 1 for cur in LOCKS_CURRENCIES: if cur == 'XAU': disp_cur = "Gold oz" elif cur == 'XAG': disp_cur = "Silver oz" else: disp_cur = cur curw = QLabel(_("<font size='5'>- %s</font>" % disp_cur)) curw.setBackgroundRole(QPalette.Light) curw.setAutoFillBackground(True) curw.setMinimumWidth(250) self.balsLayout.addWidget(curw, row, 0) row += 1 self.tabLayout.addLayout(self.balsLayout, 0, 0, 2, 3, Qt.AlignTop) # self.tabLayout.addWidget(QLabel(_('Estimated Total BTC Value')), row, 0) # self.tabLayout.addWidget(QLabel(_('- BTC')), row, 1) # row += 1 self.tabLayout.addWidget(QLabel(_('What do you want to do?')), 2, 0, Qt.AlignBottom) # row += 1 self.tabLayout.addWidget(QLabel(_('Which Locks asset?')), 2, 1, Qt.AlignBottom) # row += 1 # row += 1 self.tabLayout.addWidget(QLabel(_('Amount')), 2, 2, 1, 2, Qt.AlignBottom) # self.tabLayout.addWidget(QLabel(_('')), row, 0) # self.tabLayout.addWidget(QLabel(_('How much of which?')), 2, 3, Qt.AlignBottom) row += 1 combo_action = QComboBox() combo_action.currentIndexChanged.connect(on_change_action) combo_action.addItems(LOCK_ACTIONS) combo_action.setMaximumWidth(100) self.tabLayout.addWidget(combo_action, 3, 0, Qt.AlignTop) combo_currency = QComboBox() combo_currency.currentIndexChanged.connect(on_change_currency) combo_currency.addItems(LOCKS_CURRENCIES) combo_currency.setMaximumWidth(60) self.tabLayout.addWidget(combo_currency, 3, 1, Qt.AlignTop) btc_amount_edit = QLineEdit('0') btc_amount_edit.textChanged.connect(on_btc_amount_change) btc_amount_edit.setMaximumWidth(100) self.tabLayout.addWidget(btc_amount_edit, 3, 2, Qt.AlignRight) # self.specify_by_currency.currentIndexChanged.connect(on_change_specify_currency) self.specify_by_currency.addItems(['']) self.specify_by_currency.setMaximumWidth(60) self.tabLayout.addWidget(self.specify_by_currency, 3, 3, Qt.AlignLeft) # row += 1 self.quote_button = QPushButton(_('Get Quote')) self.quote_button.clicked.connect(get_quote) self.quote_button.setMaximumWidth(100) self.tabLayout.addWidget(self.quote_button, 5, 0, Qt.AlignBottom) return w def enable(self): self.set_enabled(True) if self.gui: self.init_balances(self.gui) return True def disable(self): length = self.gui.main_window.tabs.count() for i in range(0, length): if self.gui.main_window.tabs.tabText(i) == "Locks": self.gui.main_window.tabs.removeTab(i) self.set_enabled(False) self.balance_updater.stop() return True def is_available(self): return True def requires_settings(self): return True def settings_widget(self, window): return EnterButton(_('Settings'), self.settings_dialog) def settings_dialog(self): def check_for_api_key(api_key): if api_key and len(api_key) > 12: self.config.set_key("plugin_coinapult_locks_api_key", str(api_key)) def check_for_api_secret(api_secret): if api_secret and len(api_secret) > 12: self.config.set_key("plugin_coinapult_locks_api_secret", str(api_secret)) def check_for_ecc_pub_key(pub_key): if pub_key and len(pub_key) > 12: self.wallet.storage.put("coinapult_ecc_public", str(pub_key)) def check_for_ecc_priv_key(priv_key): if priv_key and len(priv_key) > 12: self.wallet.storage.put("coinapult_ecc_private", str(priv_key)) def ok_clicked(): # check_for_api_key(self.api_key_edit.text()) # check_for_api_secret(self.api_secret_edit.text()) check_for_ecc_pub_key(self.ecc_pub_key_edit.toPlainText()) check_for_ecc_priv_key(self.ecc_priv_key_edit.toPlainText()) if self.agreed_tos(): d.accept() else: self.disable() return False def on_change_auth_method(method): if method == 'REST': self.config.set_key('coinapult_auth_method', 'REST', True) else: self.config.set_key('coinapult_auth_method', 'ECC', True) d = QDialog() d.setMaximumWidth(600) d.setWindowTitle("Settings") layout = QGridLayout(d) layout.setColumnMinimumWidth(1, 200) layout.setHorizontalSpacing(20) about_locks_label = QLabel(ABOUT_LOCKS) about_locks_label.setWordWrap(True) about_locks_label.setOpenExternalLinks(True) layout.addWidget(about_locks_label, 0, 1, 5, 1, Qt.AlignRight) create_account_label = QLabel(_("If you wish to use Locks, and do not already have an account, " "click here to generate your ECC keys:")) create_account_label.setWordWrap(True) create_account_label.setOpenExternalLinks(True) layout.addWidget(create_account_label, 0, 0) create_account_button = QPushButton(_('Create Account')) create_account_button.setMaximumWidth(120) create_account_button.clicked.connect(self.create_account_dialog) layout.addWidget(create_account_button, 1, 0, Qt.AlignTop) warning_label = QLabel(_("If you already have a Coinapult account, simply paste your ECC credentials below." "<br><br>" "<font color='red'>WARNING Back up the keys below somewhere safe! If you overwrite " "them here, you could lose access to your Coinapult account.</font><br><br>" "ECC public key")) warning_label.setWordWrap(True) layout.addWidget(warning_label, 3, 0, Qt.AlignBottom) self.ecc_pub_key_edit = QTextEdit(self.wallet.storage.get("coinapult_ecc_public", '')) # self.ecc_pub_key_edit.textChanged.connect(check_for_ecc_pub_key) layout.addWidget(self.ecc_pub_key_edit, 4, 0, Qt.AlignTop) # layout.setRowStretch(2, 3) layout.addWidget(QLabel(_('ECC private key')), 5, 0, Qt.AlignBottom) self.ecc_priv_key_edit = QTextEdit("hidden") # self.ecc_priv_key_edit.textChanged.connect(check_for_ecc_priv_key) layout.addWidget(self.ecc_priv_key_edit, 6, 0, Qt.AlignTop) # layout.setRowStretch(2, 3) ## Rest Layout # layout.addWidget(QLabel(_('Coinapult API key: ')), 0, 0) # self.api_key_edit = QLineEdit(self.api_key()) # self.api_key_edit.textChanged.connect(check_for_api_key) # layout.addWidget(self.api_key_edit, 0, 1, 1, 2) # # layout.addWidget(QLabel(_('Coinapult API secret: ')), 1, 0) # self.api_secret_edit = QLineEdit("hidden") # self.api_key_edit.textChanged.connect(check_for_api_secret) # layout.addWidget(self.api_secret_edit, 1, 1, 1, 2) ok_button = QPushButton(_("OK")) ok_button.setMaximumWidth(50) ok_button.clicked.connect(lambda: ok_clicked()) layout.addWidget(ok_button, 7, 0) if d.exec_(): return True else: return False def create_account_dialog(self): def coinapult_signup(): try: self.client.createAccount(createLocalKeys=True, changeAuthMethod=True, tag="electrum-gfk36") self.client.activateAccount(agree=True) except (CoinapultError, CoinapultErrorECC) as ce: QMessageBox.warning(None, _("Unable to create Coinapult account because %s" % str(ce), QString(_("OK")))) def signup_done(result): self.ca_ok_button.setDisabled(False) self.wallet.storage.put("coinapult_ecc_public", str(self.client.ecc_pub_pem)) self.ecc_pub_key_edit.setText(self.client.ecc_pub_pem) self.wallet.storage.put("coinapult_ecc_private", str(self.client.ecc['privkey'].to_pem())) self.ecc_priv_key_edit.setText(str(self.client.ecc['privkey'].to_pem())) self.config.set_key('coinapult_auth_method', 'ECC', True) ecc_pub = self.wallet.storage.get("coinapult_ecc_public", '') ecc_priv = self.wallet.storage.get("coinapult_ecc_private", '') try: self.client = CoinapultClient(ecc={'pubkey': ecc_pub, 'privkey': ecc_priv}, authmethod='ecc') except (CoinapultError, CoinapultErrorECC): self.client = None QMessageBox.warning(None, _('Coinapult Connection failed'), _('Failed to connect to Coinapult. Locks disabled for this session.'), _('OK')) d.accept() def on_change_tos(checked): if checked: self.config.set_key('plugin_coinapult_locks_tos', 'checked') else: self.config.set_key('plugin_coinapult_locks_tos', 'unchecked') def ok_clicked(): if self.agreed_tos(): self.ca_ok_button.setDisabled(True) self.waiting_dialog = WaitingDialog(d, 'Creating your Coinapult account. One moment please...', coinapult_signup, signup_done) self.waiting_dialog.start() d = QDialog() d.setWindowTitle("Create Coinapult Account") layout = QGridLayout(d) # lable = None text_edit = QPlainTextEdit() text = open(os.path.dirname(__file__) + '/lib/TERMS.txt').read() text_edit.setPlainText(text) layout.addWidget(text_edit, 0, 0) layout.setRowStretch(0, 8) layout.addWidget(QLabel(_("Do you agree to Coinapult's Terms of Service (https://coinapult.com/terms)?: ")), 3, 0) tos_checkbox = QCheckBox() tos_checkbox.setEnabled(True) tos_checkbox.setChecked(self.config.get('plugin_coinapult_locks_tos', 'unchecked') != 'unchecked') tos_checkbox.stateChanged.connect(on_change_tos) layout.addWidget(tos_checkbox, 3, 1) layout.addWidget( QLabel(_("<font color='red'>This will overwrite any Coinapult API keys in your wallet.<br>" "If you do not have backups of your API keys, this will lock you out of your " # TODO This isn't actually stored in the wallet yet... "account!</font>")), 4, 0) self.ca_ok_button = QPushButton(_("OK")) self.ca_ok_button.clicked.connect(ok_clicked) layout.addWidget(self.ca_ok_button, 5, 1) if d.exec_(): return True else: return False def lock_confirm_dialog(self, lock): def lock_clicked(): message = "Lock %s %s for cost of %s BTC" % ( lock['out']['expected'], lock['out']['currency'], lock['in']['expected']) self.gui.main_window.pay_from_URI("bitcoin:%s?amount=%s&message=%s" % (lock['address'], lock['in']['expected'], message)) self.gui.main_window.emit(SIGNAL("refresh_locks_account()")) d.accept() pass self.quote_button.setDisabled(False) d = QDialog() d.setWindowTitle("Confirm Lock") layout = QGridLayout(d) row = 0 layout.addWidget(QLabel(_('Lock %s %s for a cost of %s BTC?' % (lock['out']['expected'], lock['out']['currency'], lock['in']['expected']))), row, 0) layout.addWidget(QLabel(_('Exchange rate: %s' % lock['quote']['bid'])), row, 1) row += 1 layout.addWidget(QLabel(_("If you wish to complete this Lock, please click 'Lock', then send %s BTC to " "%s\n\nPlease note that this transaction will take 2 confirmations to complete." % (lock['in']['expected'], lock['address']))), row, 0) row += 1 lock_button = QPushButton(_("Lock")) lock_button.clicked.connect(lock_clicked) layout.addWidget(lock_button, row, 1) if d.exec_(): return True else: return False def unlock_confirm_dialog(self, unlock): def unlock_clicked(): try: self.client.unlockConfirm(transaction_id=unlock['transaction_id']) self.gui.main_window.emit(SIGNAL("refresh_locks_account()")) d.accept() except (CoinapultError, CoinapultErrorECC) as ce: QMessageBox.warning(None, _('Unlock Failed'), _('Unlock action failed due to reason: %s') % ce, _('OK')) self.quote_button.setDisabled(False) d = QDialog() d.setWindowTitle("Confirm Unlock") layout = QGridLayout(d) row = 0 layout.addWidget(QLabel(_('Unlock %s %s and reclaim %s BTC?' % (unlock['in']['expected'], unlock['in']['currency'], unlock['out']['expected']))), row, 0) layout.addWidget(QLabel(_('Exchange rate: %s' % unlock['quote']['ask'])), row, 1) row += 1 layout.addWidget(QLabel(_("If you wish to complete this Unlock, please click 'Unlock' below, " "then we will send %s BTC to " "%s" % (unlock['out']['expected'], self.unlock_address))), row, 0) row += 1 unlock_button = QPushButton(_("Unlock")) unlock_button.clicked.connect(unlock_clicked) layout.addWidget(unlock_button, row, 1) if d.exec_(): return True else: return False
class ShowSettingsDialog(QDialog): """ Dialog class for plugin settings """ def __init__(self, iface, memoryPointsLayer, memoryLinesLayer, ctllDb, configTable, uriDb, schemaDb, mntUrl, refLayers, adjLayers, levelAtt, levelVal, drawdowmLayer, pipeDiam, moreTools): """ Constructor :param iface: interface :param memoryPointsLayer: working memory points layer :param memoryLinesLayer: working memory lines layer :param configTable: config table selected for import """ QDialog.__init__(self) self.__iface = iface self.__memoryPointsLayer = memoryPointsLayer self.__memoryLinesLayer = memoryLinesLayer self.__ctlDb = ctllDb self.__configTable = configTable self.__uriDb = uriDb self.__schemaDb = schemaDb self.__mntUrl = mntUrl self.__refLayers = refLayers self.__adjLayers = adjLayers self.__levelAtt = levelAtt self.__levelVal = levelVal self.__drawdowmLayer = drawdowmLayer self.__pipeDiam = pipeDiam self.setWindowTitle(QCoreApplication.translate("VDLTools", "Settings")) self.__pointsLayers = [] self.__linesLayers = [] self.__refAvailableLayers = [] self.__drawdownLayers = [] self.__tables = [] self.__schemas = [] self.__pipeDiamFields = [] self.__levelAttFields = [] self.__dbs = DBConnector.getUsedDatabases() self.__refLabels = [] self.__refChecks = [] self.__adjChecks = [] for layer in list(QgsMapLayerRegistry.instance().mapLayers().values()): if layer is not None and layer.type() == QgsMapLayer.VectorLayer: if layer.providerType() == "memory": if layer.geometryType() == QGis.Point: self.__pointsLayers.append(layer) if layer.geometryType() == QGis.Line: self.__linesLayers.append(layer) if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.LineStringZ: self.__drawdownLayers.append(layer) if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.PointZ: self.__refAvailableLayers.append(layer) # self.resize(450, 400) self.__layout = QGridLayout() line = 0 intersectLabel = QLabel(QCoreApplication.translate("VDLTools", "Intersect ")) self.__layout.addWidget(intersectLabel, line, 0) line += 1 pointLabel = QLabel(QCoreApplication.translate("VDLTools", "Working points layer : ")) self.__layout.addWidget(pointLabel, line, 1) self.__pointCombo = QComboBox() self.__pointCombo.setMinimumHeight(20) self.__pointCombo.setMinimumWidth(50) self.__pointCombo.addItem("") for layer in self.__pointsLayers: self.__pointCombo.addItem(layer.name()) self.__layout.addWidget(self.__pointCombo, line, 2) self.__pointCombo.currentIndexChanged.connect(self.__pointComboChanged) if self.__memoryPointsLayer is not None: if self.__memoryPointsLayer in self.__pointsLayers: self.__pointCombo.setCurrentIndex(self.__pointsLayers.index(self.__memoryPointsLayer)+1) line += 1 lineLabel = QLabel(QCoreApplication.translate("VDLTools", "Working lines layer : ")) self.__layout.addWidget(lineLabel, line, 1) self.__lineCombo = QComboBox() self.__lineCombo.setMinimumHeight(20) self.__lineCombo.setMinimumWidth(50) self.__lineCombo.addItem("") for layer in self.__linesLayers: self.__lineCombo.addItem(layer.name()) self.__layout.addWidget(self.__lineCombo, line, 2) self.__lineCombo.currentIndexChanged.connect(self.__lineComboChanged) if self.__memoryLinesLayer is not None: if self.__memoryLinesLayer in self.__linesLayers: self.__lineCombo.setCurrentIndex(self.__linesLayers.index(self.__memoryLinesLayer)+1) line += 1 profilesLabel = QLabel(QCoreApplication.translate("VDLTools", "Profiles ")) self.__layout.addWidget(profilesLabel, line, 0) line += 1 mntLabel = QLabel(QCoreApplication.translate("VDLTools", "Url for MNT : ")) self.__layout.addWidget(mntLabel, line, 1) self.__mntText = QLineEdit() if self.__mntUrl is None or self.__mntUrl == "None": self.__mntText.insert('https://map.lausanne.ch/prod/wsgi/profile.json') else: self.__mntText.insert(self.__mntUrl) self.__mntText.setMinimumHeight(20) self.__mntText.setMinimumWidth(100) self.__layout.addWidget(self.__mntText, line, 2) line += 1 ddLabel = QLabel(QCoreApplication.translate("VDLTools", "Drawdown ")) self.__layout.addWidget(ddLabel, line, 0) line += 1 self.__layout.addWidget(QLabel(QCoreApplication.translate("VDLTools", "Layer")), line, 1) namesLayout = QHBoxLayout() namesWidget = QWidget() namesLayout.addWidget(QLabel(QCoreApplication.translate("VDLTools", "Reference"))) namesLayout.addWidget(QLabel(QCoreApplication.translate("VDLTools", "Adjustable"))) namesLayout.setContentsMargins(0,0,0,0) namesWidget.setLayout(namesLayout) self.__layout.addWidget(namesWidget, line, 2) line += 1 for layer in self.__refAvailableLayers: refLabel = QLabel(" - " + layer.name()) self.__refLabels.append(refLabel) self.__layout.addWidget(refLabel, line, 1) checksLayout = QHBoxLayout() checksLayout.setContentsMargins(0,0,0,0) checksWidget = QWidget() refCheck = QCheckBox() self.__refChecks.append(refCheck) refCheck.stateChanged.connect(self.__refBoxesChanged) checksLayout.addWidget(refCheck) adjCheck = QCheckBox() self.__adjChecks.append(adjCheck) checksLayout.addWidget(adjCheck) checksWidget.setLayout(checksLayout) self.__layout.addWidget(checksWidget, line, 2) line += 1 levelAttLabel = QLabel(QCoreApplication.translate("VDLTools", "Code(s) on pipe : ")) self.__layout.addWidget(levelAttLabel, line, 1) self.__levelAttCombo = QComboBox() self.__levelAttCombo.setMinimumHeight(20) self.__levelAttCombo.setMinimumWidth(50) self.__levelAttCombo.addItem("") self.__layout.addWidget(self.__levelAttCombo, line, 2) self.__levelAttCombo.currentIndexChanged.connect(self.__levelAttComboChanged) i = 0 for layer in self.__refAvailableLayers: if layer in self.__refLayers: self.__refChecks[i].setChecked(True) if layer in self.__adjLayers: self.__adjChecks[i].setChecked(True) i += 1 line += 1 levelValLabel = QLabel(QCoreApplication.translate("VDLTools", "Point code attribute : ")) self.__layout.addWidget(levelValLabel, line, 1) self.__levelValText = QLineEdit() if self.__levelVal is not None and self.__levelVal != "None": self.__levelValText.insert(self.__levelVal) self.__levelValText.setMinimumHeight(20) self.__levelValText.setMinimumWidth(100) self.__layout.addWidget(self.__levelValText, line, 2) line += 1 drawdownLabel = QLabel(QCoreApplication.translate("VDLTools", "drawdown layer : ")) self.__layout.addWidget(drawdownLabel, line, 1) self.__drawdownCombo = QComboBox() self.__drawdownCombo.setMinimumHeight(20) self.__drawdownCombo.setMinimumWidth(50) self.__drawdownCombo.addItem("") for layer in self.__drawdownLayers: self.__drawdownCombo.addItem(layer.name()) self.__layout.addWidget(self.__drawdownCombo, line, 2) line += 1 pipeDiamLabel = QLabel(QCoreApplication.translate("VDLTools", "Pipe diameter attribute [cm] : ")) self.__layout.addWidget(pipeDiamLabel, line, 1) self.__pipeDiamCombo = QComboBox() self.__pipeDiamCombo.setMinimumHeight(20) self.__pipeDiamCombo.setMinimumWidth(50) self.__pipeDiamCombo.addItem("") self.__layout.addWidget(self.__pipeDiamCombo, line, 2) self.__drawdownCombo.currentIndexChanged.connect(self.__drawdownComboChanged) self.__pipeDiamCombo.currentIndexChanged.connect(self.__pipeDiamComboChanged) if self.__drawdowmLayer is not None: if self.__drawdowmLayer in self.__drawdownLayers: self.__drawdownCombo.setCurrentIndex(self.__drawdownLayers.index(self.__drawdowmLayer)+1) if moreTools: line += 1 importLabel = QLabel(QCoreApplication.translate("VDLTools", "Import ")) self.__layout.addWidget(importLabel, line, 0) line += 1 dbLabel = QLabel(QCoreApplication.translate("VDLTools", "Import database : ")) self.__layout.addWidget(dbLabel, line, 1) self.__dbCombo = QComboBox() self.__dbCombo.setMinimumHeight(20) self.__dbCombo.setMinimumWidth(50) self.__dbCombo.addItem("") for db in list(self.__dbs.keys()): self.__dbCombo.addItem(db) self.__layout.addWidget(self.__dbCombo, line, 2) line += 1 schemaLabel = QLabel(QCoreApplication.translate("VDLTools", "Database schema : ")) self.__layout.addWidget(schemaLabel, line, 1) self.__schemaCombo = QComboBox() self.__schemaCombo.setMinimumHeight(20) self.__schemaCombo.setMinimumWidth(50) self.__schemaCombo.addItem("") self.__layout.addWidget(self.__schemaCombo, line, 2) line += 1 tableLabel = QLabel(QCoreApplication.translate("VDLTools", "Config table : ")) self.__layout.addWidget(tableLabel, line, 1) self.__tableCombo = QComboBox() self.__tableCombo.setMinimumHeight(20) self.__tableCombo.setMinimumWidth(50) self.__tableCombo.addItem("") self.__layout.addWidget(self.__tableCombo, line, 2) line += 1 controlLabel = QLabel(QCoreApplication.translate("VDLTools", "Control ")) self.__layout.addWidget(controlLabel, line, 0) line += 1 ctlLabel = QLabel(QCoreApplication.translate("VDLTools", "Control database : ")) self.__layout.addWidget(ctlLabel, line, 1) self.__ctlCombo = QComboBox() self.__ctlCombo.setMinimumHeight(20) self.__ctlCombo.setMinimumWidth(50) self.__ctlCombo.addItem("") for db in list(self.__dbs.keys()): self.__ctlCombo.addItem(db) self.__layout.addWidget(self.__ctlCombo, line, 2) self.__dbCombo.currentIndexChanged.connect(self.__dbComboChanged) self.__schemaCombo.currentIndexChanged.connect(self.__schemaComboChanged) self.__tableCombo.currentIndexChanged.connect(self.__tableComboChanged) self.__ctlCombo.currentIndexChanged.connect(self.__ctlComboChanged) if self.__uriDb is not None: if self.__uriDb.database() in list(self.__dbs.keys()): self.__dbCombo.setCurrentIndex(list(self.__dbs.keys()).index(self.__uriDb.database()) + 1) if self.__ctlDb is not None: if self.__ctlDb.database() in list(self.__dbs.keys()): self.__ctlCombo.setCurrentIndex(list(self.__dbs.keys()).index(self.__ctlDb.database()) + 1) else: self.__dbCombo = None self.__schemaCombo = None self.__tableCombo = None self.__ctlCombo = None self.__okButton = QPushButton(QCoreApplication.translate("VDLTools", "OK")) self.__okButton.setMinimumHeight(20) self.__okButton.setMinimumWidth(100) self.__cancelButton = QPushButton(QCoreApplication.translate("VDLTools", "Cancel")) self.__cancelButton.setMinimumHeight(20) self.__cancelButton.setMinimumWidth(100) self.__layout.addWidget(self.__okButton, 100, 1) self.__layout.addWidget(self.__cancelButton, 100, 2) self.setLayout(self.__layout) @staticmethod def __resetCombo(combo): """ To reset a combo list :param combo: concerned combo """ while combo.count() > 0: combo.removeItem(combo.count()-1) def __setSchemaCombo(self, uriDb): """ To fill the schema combo list :param uriDb: selected database uri """ connector = DBConnector(uriDb, self.__iface) db = connector.setConnection() if db: Signal.safelyDisconnect(self.__schemaCombo.currentIndexChanged, self.__schemaComboChanged) self.__resetCombo(self.__schemaCombo) self.__schemaCombo.addItem("") self.__schemas = [] query = db.exec_("""SELECT DISTINCT table_schema FROM information_schema.tables WHERE table_schema NOT IN ('pg_catalog', 'information_schema', 'topology') AND table_type = 'BASE TABLE' AND table_name NOT IN (SELECT f_table_name FROM geometry_columns)""") if query.lastError().isValid(): self.__iface.messageBar().pushMessage(query.lastError().text(), level=QgsMessageBar.CRITICAL, duration=0) else: while next(query): self.__schemas.append(query.value(0)) db.close() for schema in self.__schemas: self.__schemaCombo.addItem(schema) self.__schemaCombo.currentIndexChanged.connect(self.__schemaComboChanged) if self.__schemaDb is not None: if self.__schemaDb in self.__schemas: self.__schemaCombo.setCurrentIndex(self.__schemas.index(self.__schemaDb) + 1) def __setTableCombo(self, uriDb, schema): """ To fill the table combo list :param uriDb: selected database uri :param schema: selected database schema """ connector = DBConnector(uriDb, self.__iface) db = connector.setConnection() if db: Signal.safelyDisconnect(self.__tableCombo.currentIndexChanged, self.__tableComboChanged) self.__resetCombo(self.__tableCombo) self.__tableCombo.addItem("") self.__tables = [] query = db.exec_("""SELECT table_name FROM information_schema.tables WHERE table_schema = '""" + schema + """' ORDER BY table_name""") if query.lastError().isValid(): self.__iface.messageBar().pushMessage(query.lastError().text(), level=QgsMessageBar.CRITICAL, duration=0) else: while next(query): self.__tables.append(query.value(0)) db.close() for table in self.__tables: if self.__tableCombo.findText(table) == -1: self.__tableCombo.addItem(table) self.__tableCombo.currentIndexChanged.connect(self.__tableComboChanged) if self.__configTable is not None: if self.__configTable in self.__tables: self.__tableCombo.setCurrentIndex(self.__tables.index(self.__configTable) + 1) def __setPipeDiamCombo(self, drawdownLayer): """ To fill the pipe diameter combo list :param drawdownLayer: choosen drawdown layer """ Signal.safelyDisconnect(self.__pipeDiamCombo.currentIndexChanged, self.__pipeDiamComboChanged) self.__resetCombo(self.__pipeDiamCombo) self.__pipeDiamCombo.addItem("") fields = drawdownLayer.fields() self.__pipeDiamFields = [] for field in fields: self.__pipeDiamFields.append(field.name()) self.__pipeDiamCombo.addItem(field.name()) self.__pipeDiamCombo.currentIndexChanged.connect(self.__pipeDiamComboChanged) if self.__pipeDiam is not None: if self.__pipeDiam in self.__pipeDiamFields: self.__pipeDiamCombo.setCurrentIndex(self.__pipeDiamFields.index(self.__pipeDiam) + 1) def __setLevelAttCombo(self, refLayers): """ To fill the level attribute combo list :param refLayers: choosen reference layers """ Signal.safelyDisconnect(self.__levelAttCombo.currentIndexChanged, self.__levelAttComboChanged) self.__resetCombo(self.__levelAttCombo) self.__levelAttCombo.addItem("") self.__levelAttFields = [] num = 0 for layer in refLayers: fields = layer.fields() if num == 0: for field in fields: self.__levelAttFields.append(field.name()) num = 1 else: names = [] for field in fields: names.append(field.name()) news = [] for name in self.__levelAttFields: if name in names: news.append(name) self.__levelAttFields = news for name in self.__levelAttFields: self.__levelAttCombo.addItem(name) self.__levelAttCombo.currentIndexChanged.connect(self.__levelAttComboChanged) if self.__levelAtt is not None: if self.__levelAtt in self.__levelAttFields: self.__levelAttCombo.setCurrentIndex(self.__levelAttFields.index(self.__levelAtt) + 1) def __lineComboChanged(self): """ To remove blank item when another one is selected """ if self.__lineCombo.itemText(0) == "": self.__lineCombo.removeItem(0) def __pointComboChanged(self): """ To remove blank item when another one is selected """ if self.__pointCombo.itemText(0) == "": self.__pointCombo.removeItem(0) def __refBoxesChanged(self): """ To update level attribute combo when reference layers have changed """ if self.refLayers() is not None: self.__setLevelAttCombo(self.refLayers()) def __drawdownComboChanged(self): """ To remove blank item when another one is selected and update pipe diamete combo when drawdown layer has changed """ if self.__drawdownCombo.itemText(0) == "": self.__drawdownCombo.removeItem(0) if self.drawdownLayer() is not None: self.__setPipeDiamCombo(self.drawdownLayer()) def __tableComboChanged(self): """ To remove blank item when another one is selected """ if self.__tableCombo.itemText(0) == "": self.__tableCombo.removeItem(0) def __dbComboChanged(self): """ When the selection in db combo has changed """ if self.__dbCombo.itemText(0) == "": self.__dbCombo.removeItem(0) if self.uriDb() is not None: self.__setSchemaCombo(self.uriDb()) def __schemaComboChanged(self): """ When the selection in schema combo has changed """ if self.__schemaCombo.itemText(0) == "": self.__schemaCombo.removeItem(0) if self.schemaDb() is not None: self.__setTableCombo(self.uriDb(), self.schemaDb()) def __pipeDiamComboChanged(self): """ When the selection in schema combo has changed """ if self.__pipeDiamCombo.itemText(0) == "": self.__pipeDiamCombo.removeItem(0) def __levelAttComboChanged(self): """ When the selection in schema combo has changed """ if self.__levelAttCombo.itemText(0) == "": self.__levelAttCombo.removeItem(0) def __ctlComboChanged(self): """ When the selection in ctl combo has changed """ if self.__ctlCombo.itemText(0) == "": self.__ctlCombo.removeItem(0) def okButton(self): """ To get the ok button instance :return: ok button instance """ return self.__okButton def cancelButton(self): """ To get the cancel button instance :return: cancel button instance """ return self.__cancelButton def pointsLayer(self): """ To get the selected memory points layer :return: selected memory points layer, or none """ index = self.__pointCombo.currentIndex() if self.__pointCombo.itemText(index) == "": return None else: return self.__pointsLayers[index] def linesLayer(self): """ To get the selected memory lines layer :return: selected memory lines layer, or none """ index = self.__lineCombo.currentIndex() if self.__lineCombo.itemText(index) == "": return None else: return self.__linesLayers[index] def refLayers(self): """ To get the selected reference layers :return: selected reference layers, or none """ layers = [] i = 0 for check in self.__refChecks: if check.isChecked(): layers.append(self.__refAvailableLayers[i]) i += 1 return layers def adjLayers(self): """ To get the selected ajustable layers :return: selected adjustable layers, or none """ layers = [] i = 0 for check in self.__adjChecks: if check.isChecked(): layers.append(self.__refAvailableLayers[i]) i += 1 return layers def levelAtt(self): """ To get the selected level attribute :return: selected level attribute, or none """ if self.__levelAttCombo is None: return None index = self.__levelAttCombo.currentIndex() if self.__levelAttCombo.itemText(index) == "": return None else: return self.__levelAttFields[index] def levelVal(self): """ To get the filled level value :return: filled level value """ return self.__levelValText.text() def drawdownLayer(self): """ To get the selected drawdown layer :return: selected drawdown layer, or none """ index = self.__drawdownCombo.currentIndex() if self.__drawdownCombo.itemText(index) == "": return None else: return self.__drawdownLayers[index] def pipeDiam(self): """ To get the selected pipe diameter :return: selected pipe diameter, or none """ if self.__pipeDiamCombo is None: return None index = self.__pipeDiamCombo.currentIndex() if self.__pipeDiamCombo.itemText(index) == "": return None else: return self.__pipeDiamFields[index] def configTable(self): """ To get the selected config table :return: selected config table, or none """ if self.__tableCombo is None: return None index = self.__tableCombo.currentIndex() if self.__tableCombo.itemText(index) == "": return None else: return self.__tables[index] def uriDb(self): """ To get selected import database uri :return: import database uri """ if self.__dbCombo is None: return None index = self.__dbCombo.currentIndex() if self.__dbCombo.itemText(index) == "": return None else: return self.__dbs[list(self.__dbs.keys())[index]] def schemaDb(self): """ To get selected import database schema :return: import database schema """ if self.__schemaCombo is None: return None index = self.__schemaCombo.currentIndex() if self.__schemaCombo.itemText(index) == "": return None else: return self.__schemas[index] def mntUrl(self): """ To get selected MN url :return: MN url """ return self.__mntText.text() def ctlDb(self): """ To get selected control database uri :return: control database uri """ if self.__ctlCombo is None: return None index = self.__ctlCombo.currentIndex() if self.__ctlCombo.itemText(index) == "": return None else: return self.__dbs[list(self.__dbs.keys())[index]]
class SchemeSelector(QWidget): currentChanged = pyqtSignal() changed = pyqtSignal() def __init__(self, parent=None): super(SchemeSelector, self).__init__(parent) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.label = QLabel(_("Scheme:")) self.scheme = QComboBox() self.label.setBuddy(self.scheme) self.add = QPushButton(icons.get('list-add'), '') self.remove = QPushButton(icons.get('list-remove'), '') layout.addWidget(self.label) layout.addWidget(self.scheme) layout.addWidget(self.add) layout.addWidget(self.remove) self.scheme.currentIndexChanged.connect(self.slotSchemeChanged) self.add.clicked.connect(self.addClicked) self.remove.clicked.connect(self.removeClicked) app.translateUI(self) def translateUI(self): self.label.setText(_("Scheme:")) self.add.setText(_("New Scheme", "&New...")) self.remove.setText(_("&Remove")) def slotSchemeChanged(self, index): """Called when the Scheme combobox is changed by the user.""" self.remove.setEnabled(bool(index)) self.currentChanged.emit() self.changed.emit() def schemes(self): """Returns the list with internal names of currently available schemes.""" return self._schemes def currentScheme(self): """Returns the internal name of the currently selected scheme""" return self._schemes[self.scheme.currentIndex()] def removeClicked(self): index = self.scheme.currentIndex() if index == 0: return # default can not be removed self._schemesToRemove.add(self._schemes[index]) del self._schemes[index] del self._schemeNames[index] self.scheme.removeItem(index) def addClicked(self): name, ok = QInputDialog.getText(self, app.caption("Add Scheme"), _("Please enter a name for the new scheme:")) if not ok: return num, key = 1, 'user1' while key in self._schemes or key in self._schemesToRemove: num += 1 key = 'user{0}'.format(num) self._schemes.append(key) self._schemeNames.append(name) self.scheme.addItem(name) self.scheme.setCurrentIndex(self.scheme.count() - 1) def loadSettings(self, currentKey, namesGroup): # dont mark schemes for removal anymore self._schemesToRemove = set() s = QSettings() cur = s.value(currentKey, "default") # load the names for the shortcut schemes s.beginGroup(namesGroup) self._schemes = ["default"] self._schemeNames = [_("Default")] for key in s.childKeys(): self._schemes.append(key) self._schemeNames.append(s.value(key, key)) block = self.scheme.blockSignals(True) self.scheme.clear() self.scheme.addItems(self._schemeNames) # find out index index = self._schemes.index(cur) if cur in self._schemes else 0 self.remove.setEnabled(bool(index)) self.scheme.setCurrentIndex(index) self.scheme.blockSignals(block) self.currentChanged.emit() def saveSettings(self, currentKey, namesGroup, removePrefix=None): # first save new scheme names s = QSettings() s.beginGroup(namesGroup) for scheme, name in zip(self._schemes, self._schemeNames)[1:]: s.setValue(scheme, name) # then remove removed schemes for scheme in self._schemesToRemove: s.remove(scheme) s.endGroup() if removePrefix: for scheme in self._schemesToRemove: s.remove("{0}/{1}".format(removePrefix, scheme)) # then save current scheme = self.currentScheme() s.setValue(currentKey, scheme) # clean up self._schemesToRemove = set()
class ShowSettingsDialog(QDialog): """ Dialog class for plugin settings """ def __init__(self, iface, memoryPointsLayer, memoryLinesLayer, ctllDb, configTable, uriDb, schemaDb, mntUrl): """ Constructor :param iface: interface :param memoryPointsLayer: working memory points layer :param memoryLinesLayer: working memory lines layer :param configTable: config table selected for import """ QDialog.__init__(self) self.__iface = iface self.__memoryPointsLayer = memoryPointsLayer self.__memoryLinesLayer = memoryLinesLayer self.__ctlDb = ctllDb self.__configTable = configTable self.__uriDb = uriDb self.__schemaDb = schemaDb self.__mntUrl = mntUrl self.setWindowTitle(QCoreApplication.translate("VDLTools", "Settings")) self.__pointsLayers = [] self.__linesLayers = [] self.__tables = [] self.__schemas = [] self.__dbs = DBConnector.getUsedDatabases() for layer in list(QgsMapLayerRegistry.instance().mapLayers().values()): if layer is not None and layer.type( ) == QgsMapLayer.VectorLayer and layer.providerType() == "memory": if layer.geometryType() == QGis.Point: self.__pointsLayers.append(layer) if layer.geometryType() == QGis.Line: self.__linesLayers.append(layer) self.resize(450, 200) self.__layout = QGridLayout() pointLabel = QLabel( QCoreApplication.translate("VDLTools", "Working points layer : ")) pointLabel.setMinimumHeight(20) pointLabel.setMinimumWidth(50) self.__layout.addWidget(pointLabel, 0, 1) self.__pointCombo = QComboBox() self.__pointCombo.setMinimumHeight(20) self.__pointCombo.setMinimumWidth(50) self.__pointCombo.addItem("") for layer in self.__pointsLayers: self.__pointCombo.addItem(layer.name()) self.__layout.addWidget(self.__pointCombo, 0, 2) self.__pointCombo.currentIndexChanged.connect(self.__pointComboChanged) if self.__memoryPointsLayer is not None: if self.__memoryPointsLayer in self.__pointsLayers: self.__pointCombo.setCurrentIndex( self.__pointsLayers.index(self.__memoryPointsLayer) + 1) lineLabel = QLabel( QCoreApplication.translate("VDLTools", "Working lines layer : ")) lineLabel.setMinimumHeight(20) lineLabel.setMinimumWidth(50) self.__layout.addWidget(lineLabel, 1, 1) self.__lineCombo = QComboBox() self.__lineCombo.setMinimumHeight(20) self.__lineCombo.setMinimumWidth(50) self.__lineCombo.addItem("") for layer in self.__linesLayers: self.__lineCombo.addItem(layer.name()) self.__layout.addWidget(self.__lineCombo, 1, 2) self.__lineCombo.currentIndexChanged.connect(self.__lineComboChanged) if self.__memoryLinesLayer is not None: if self.__memoryLinesLayer in self.__linesLayers: self.__lineCombo.setCurrentIndex( self.__linesLayers.index(self.__memoryLinesLayer) + 1) dbLabel = QLabel( QCoreApplication.translate("VDLTools", "Import database : ")) dbLabel.setMinimumHeight(20) dbLabel.setMinimumWidth(50) self.__layout.addWidget(dbLabel, 2, 1) self.__dbCombo = QComboBox() self.__dbCombo.setMinimumHeight(20) self.__dbCombo.setMinimumWidth(50) self.__dbCombo.addItem("") for db in list(self.__dbs.keys()): self.__dbCombo.addItem(db) self.__layout.addWidget(self.__dbCombo, 2, 2) schemaLabel = QLabel( QCoreApplication.translate("VDLTools", "Database schema : ")) schemaLabel.setMinimumHeight(20) schemaLabel.setMinimumWidth(50) self.__layout.addWidget(schemaLabel, 3, 1) self.__schemaCombo = QComboBox() self.__schemaCombo.setMinimumHeight(20) self.__schemaCombo.setMinimumWidth(50) self.__schemaCombo.addItem("") self.__layout.addWidget(self.__schemaCombo, 3, 2) tableLabel = QLabel( QCoreApplication.translate("VDLTools", "Config table : ")) tableLabel.setMinimumHeight(20) tableLabel.setMinimumWidth(50) self.__layout.addWidget(tableLabel, 4, 1) self.__tableCombo = QComboBox() self.__tableCombo.setMinimumHeight(20) self.__tableCombo.setMinimumWidth(50) self.__tableCombo.addItem("") self.__layout.addWidget(self.__tableCombo, 4, 2) mntLabel = QLabel( QCoreApplication.translate("VDLTools", "Url for MNT : ")) schemaLabel.setMinimumHeight(20) schemaLabel.setMinimumWidth(50) self.__layout.addWidget(mntLabel, 5, 1) self.__mntText = QLineEdit() if self.__mntUrl is None or self.__mntUrl == "None": self.__mntText.insert( 'http://map.lausanne.ch/main/wsgi/profile.json') else: self.__mntText.insert(self.__mntUrl) self.__mntText.setMinimumHeight(20) self.__mntText.setMinimumWidth(100) self.__layout.addWidget(self.__mntText, 5, 2) ctlLabel = QLabel( QCoreApplication.translate("VDLTools", "Control database : ")) ctlLabel.setMinimumHeight(20) ctlLabel.setMinimumWidth(50) self.__layout.addWidget(ctlLabel, 6, 1) self.__ctlCombo = QComboBox() self.__ctlCombo.setMinimumHeight(20) self.__ctlCombo.setMinimumWidth(50) self.__ctlCombo.addItem("") for db in list(self.__dbs.keys()): self.__ctlCombo.addItem(db) self.__layout.addWidget(self.__ctlCombo, 6, 2) self.__okButton = QPushButton( QCoreApplication.translate("VDLTools", "OK")) self.__okButton.setMinimumHeight(20) self.__okButton.setMinimumWidth(100) self.__cancelButton = QPushButton( QCoreApplication.translate("VDLTools", "Cancel")) self.__cancelButton.setMinimumHeight(20) self.__cancelButton.setMinimumWidth(100) self.__layout.addWidget(self.__okButton, 100, 1) self.__layout.addWidget(self.__cancelButton, 100, 2) self.setLayout(self.__layout) self.__dbCombo.currentIndexChanged.connect(self.__dbComboChanged) self.__schemaCombo.currentIndexChanged.connect( self.__schemaComboChanged) self.__tableCombo.currentIndexChanged.connect(self.__tableComboChanged) self.__ctlCombo.currentIndexChanged.connect(self.__ctlComboChanged) if self.__uriDb is not None: if self.__uriDb.database() in list(self.__dbs.keys()): self.__dbCombo.setCurrentIndex( list(self.__dbs.keys()).index(self.__uriDb.database()) + 1) if self.__ctlDb is not None: if self.__ctlDb.database() in list(self.__dbs.keys()): self.__ctlCombo.setCurrentIndex( list(self.__dbs.keys()).index(self.__ctlDb.database()) + 1) @staticmethod def __resetCombo(combo): """ To reset a combo list :param combo: concerned combo """ while combo.count() > 0: combo.removeItem(combo.count() - 1) def __setSchemaCombo(self, uriDb): """ To fill the schema combo list :param uriDb: selected database uri """ connector = DBConnector(uriDb, self.__iface) db = connector.setConnection() if db: Signal.safelyDisconnect(self.__schemaCombo.currentIndexChanged, self.__schemaComboChanged) self.__resetCombo(self.__schemaCombo) self.__schemaCombo.addItem("") self.__schemas = [] query = db.exec_( """SELECT DISTINCT table_schema FROM information_schema.tables WHERE table_schema NOT IN ('pg_catalog', 'information_schema', 'topology') AND table_type = 'BASE TABLE' AND table_name NOT IN (SELECT f_table_name FROM geometry_columns)""") if query.lastError().isValid(): self.__iface.messageBar().pushMessage( query.lastError().text(), level=QgsMessageBar.CRITICAL, duration=0) else: while next(query): self.__schemas.append(query.value(0)) db.close() for schema in self.__schemas: self.__schemaCombo.addItem(schema) self.__schemaCombo.currentIndexChanged.connect( self.__schemaComboChanged) if self.__schemaDb is not None: if self.__schemaDb in self.__schemas: self.__schemaCombo.setCurrentIndex( self.__schemas.index(self.__schemaDb) + 1) def __setTableCombo(self, uriDb, schema): """ To fill the table combo list :param uriDb: selected database uri :param schema: selected database schema """ connector = DBConnector(uriDb, self.__iface) db = connector.setConnection() if db: Signal.safelyDisconnect(self.__tableCombo.currentIndexChanged, self.__tableComboChanged) self.__resetCombo(self.__tableCombo) self.__tableCombo.addItem("") self.__tables = [] query = db.exec_( """SELECT table_name FROM information_schema.tables WHERE table_schema = '""" + schema + """' ORDER BY table_name""") if query.lastError().isValid(): self.__iface.messageBar().pushMessage( query.lastError().text(), level=QgsMessageBar.CRITICAL, duration=0) else: while next(query): self.__tables.append(query.value(0)) db.close() for table in self.__tables: if self.__tableCombo.findText(table) == -1: self.__tableCombo.addItem(table) self.__tableCombo.currentIndexChanged.connect( self.__tableComboChanged) if self.__configTable is not None: if self.__configTable in self.__tables: self.__tableCombo.setCurrentIndex( self.__tables.index(self.__configTable) + 1) def __lineComboChanged(self): """ To remove blank item when another one is selected """ if self.__lineCombo.itemText(0) == "": self.__lineCombo.removeItem(0) def __pointComboChanged(self): """ To remove blank item when another one is selected """ if self.__pointCombo.itemText(0) == "": self.__pointCombo.removeItem(0) def __tableComboChanged(self): """ To remove blank item when another one is selected """ if self.__tableCombo.itemText(0) == "": self.__tableCombo.removeItem(0) def __dbComboChanged(self): """ When the selection in db combo has changed """ if self.__dbCombo.itemText(0) == "": self.__dbCombo.removeItem(0) if self.uriDb() is not None: self.__setSchemaCombo(self.uriDb()) def __schemaComboChanged(self): """ When the selection in schema combo has changed """ if self.__schemaCombo.itemText(0) == "": self.__schemaCombo.removeItem(0) if self.schemaDb() is not None: self.__setTableCombo(self.uriDb(), self.schemaDb()) def __ctlComboChanged(self): """ When the selection in ctl combo has changed """ if self.__ctlCombo.itemText(0) == "": self.__ctlCombo.removeItem(0) def okButton(self): """ To get the ok button instance :return: ok button instance """ return self.__okButton def cancelButton(self): """ To get the cancel button instance :return: cancel button instance """ return self.__cancelButton def pointsLayer(self): """ To get the selected memory points layer :return: selected memeory points layer, or none """ index = self.__pointCombo.currentIndex() if self.__pointCombo.itemText(index) == "": return None else: return self.__pointsLayers[index] def linesLayer(self): """ To get the selected memory lines layer :return: selected memory lines layer, or none """ index = self.__lineCombo.currentIndex() if self.__lineCombo.itemText(index) == "": return None else: return self.__linesLayers[index] def configTable(self): """ To get the selected config table :return: selected config table, or none """ index = self.__tableCombo.currentIndex() if self.__tableCombo.itemText(index) == "": return None else: return self.__tables[index] def uriDb(self): """ To get selected import database uri :return: import database uri """ index = self.__dbCombo.currentIndex() if self.__dbCombo.itemText(index) == "": return None else: return self.__dbs[list(self.__dbs.keys())[index]] def schemaDb(self): """ To get selected import database schema :return: import database schema """ index = self.__schemaCombo.currentIndex() if self.__schemaCombo.itemText(index) == "": return None else: return self.__schemas[index] def mntUrl(self): """ To get selected MN url :return: MN url """ return self.__mntText.text() def ctlDb(self): """ To get selected control database uri :return: control database uri """ index = self.__ctlCombo.currentIndex() if self.__ctlCombo.itemText(index) == "": return None else: return self.__dbs[list(self.__dbs.keys())[index]]
class preferencesDialog(QDialog): def __init__(self, parent): QDialog.__init__(self, parent) self.tmpPref = {} self.tmpPref['pref'] = copy.deepcopy(self.parent().prm['pref']) self.currLocale = self.parent().prm['data']['currentLocale'] self.currLocale.setNumberOptions(self.currLocale.OmitGroupSeparator | self.currLocale.RejectGroupSeparator) self.tabWidget = QTabWidget() self.tabWidget.currentChanged.connect(self.tabChanged) self.appPrefWidget = QWidget() self.plotPrefWidget = QWidget() self.signalPrefWidget = QWidget() self.soundPrefWidget = QWidget() #APP PREF appPrefGrid = QGridLayout() n = 0 self.languageChooserLabel = QLabel(self.tr('Language (requires restart):')) appPrefGrid.addWidget(self.languageChooserLabel, n, 0) self.languageChooser = QComboBox() self.languageChooser.addItems(self.parent().prm['data']['available_languages']) self.languageChooser.setCurrentIndex(self.languageChooser.findText(self.tmpPref['pref']['language'])) self.languageChooser.currentIndexChanged[int].connect(self.onLanguageChooserChange) appPrefGrid.addWidget(self.languageChooser, n, 1) n = n+1 self.countryChooserLabel = QLabel(self.tr('Country (requires restart):')) appPrefGrid.addWidget(self.countryChooserLabel, n, 0) self.countryChooser = QComboBox() self.countryChooser.addItems(self.parent().prm['data']['available_countries'][self.tmpPref['pref']['language']]) self.countryChooser.setCurrentIndex(self.countryChooser.findText(self.tmpPref['pref']['country'])) appPrefGrid.addWidget(self.countryChooser, n, 1) self.appPrefWidget.setLayout(appPrefGrid) #PLOT PREF plotPrefGrid = QGridLayout() n = 0 #LINE COLOUR self.lineColor1 = self.tmpPref['pref']['lineColor1'] self.lineColorButton = QPushButton(self.tr("Line Color"), self) self.lineColorButton.clicked.connect(self.onChangeLineColor) plotPrefGrid.addWidget(self.lineColorButton, n, 0) self.lineColorSquare = QWidget(self) self.lineColorSquare.setStyleSheet("QWidget { background-color: %s }" % self.lineColor1.name()) plotPrefGrid.addWidget(self.lineColorSquare, n, 1) n = n+1 self.backgroundColor = self.tmpPref['pref']['backgroundColor'] self.backgroundColorButton = QPushButton(self.tr("Background Color"), self) self.backgroundColorButton.clicked.connect(self.onChangeBackgroundColor) plotPrefGrid.addWidget(self.backgroundColorButton, n, 0) self.backgroundColorSquare = QWidget(self) self.backgroundColorSquare.setStyleSheet("QWidget { background-color: %s }" % self.backgroundColor.name()) plotPrefGrid.addWidget(self.backgroundColorSquare, n, 1) n = n+1 self.canvasColor = self.tmpPref['pref']['canvasColor'] self.canvasColorButton = QPushButton(self.tr("Canvas Color"), self) self.canvasColorButton.clicked.connect(self.onChangeCanvasColor) plotPrefGrid.addWidget(self.canvasColorButton, n, 0) self.canvasColorSquare = QWidget(self) self.canvasColorSquare.setStyleSheet("QWidget { background-color: %s }" % self.canvasColor.name()) plotPrefGrid.addWidget(self.canvasColorSquare, n, 1) n = n+1 self.dpiLabel = QLabel(self.tr('DPI - Resolution:')) plotPrefGrid.addWidget(self.dpiLabel, n, 0) self.dpiWidget = QLineEdit(str(self.tmpPref['pref']['dpi'])) plotPrefGrid.addWidget(self.dpiWidget, n, 1) self.dpiWidget.setValidator(QIntValidator(self)) self.dpiWidget.editingFinished.connect(self.ondpiChange) n = n+1 self.cmapChooserLabel = QLabel(self.tr('Color Map:')) plotPrefGrid.addWidget(self.cmapChooserLabel, n, 0) self.cmapChooser = QComboBox() self.cmapChooser.addItems(self.parent().prm['data']['available_colormaps']) self.cmapChooser.setCurrentIndex(self.cmapChooser.findText(self.tmpPref['pref']['colormap'])) plotPrefGrid.addWidget(self.cmapChooser, n, 1) n = n+1 self.gridOn = QCheckBox(self.tr('Grid')) self.gridOn.setChecked(self.tmpPref['pref']['grid']) plotPrefGrid.addWidget(self.gridOn, n, 1) self.plotPrefWidget.setLayout(plotPrefGrid) #SIGNAL PREF signalPrefGrid = QGridLayout() n = 0 self.windowChooser = QComboBox() self.windowChooser.addItems(self.parent().prm['data']['available_windows']) self.windowChooser.setCurrentIndex(self.windowChooser.findText(self.tmpPref['pref']['smoothingWindow'])) self.windowChooserLabel = QLabel(self.tr('Window:')) signalPrefGrid.addWidget(self.windowChooserLabel, 0, 0) signalPrefGrid.addWidget(self.windowChooser, 0, 1) n = n+1 self.signalPrefWidget.setLayout(signalPrefGrid) #SOUND PREF soundPrefGrid = QGridLayout() n = 0 self.wavmanagerLabel = QLabel(self.tr('Wav Manager (requires restart):')) self.wavmanagerChooser = QComboBox() self.wavmanagerChooser.addItems(["scipy"]) self.wavmanagerChooser.setCurrentIndex(self.wavmanagerChooser.findText(self.tmpPref['pref']['wavmanager'])) soundPrefGrid.addWidget(self.wavmanagerLabel, n, 0) soundPrefGrid.addWidget(self.wavmanagerChooser, n, 1) n = n+1 self.playChooser = QComboBox() self.playChooser.addItems(self.parent().prm['data']['available_play_commands']) self.playChooser.setCurrentIndex(self.playChooser.findText(self.tmpPref['pref']['playCommandType'])) self.playChooser.currentIndexChanged[int].connect(self.onPlayChooserChange) self.playChooserLabel = QLabel(self.tr('Play Command:')) soundPrefGrid.addWidget(self.playChooserLabel, n, 0) soundPrefGrid.addWidget(self.playChooser, n, 1) n = n+1 self.playCommandLabel = QLabel(self.tr('Command:')) soundPrefGrid.addWidget(self.playCommandLabel, n, 0) self.playCommandWidget = QLineEdit(str(self.tmpPref['pref']['playCommand'])) self.playCommandWidget.setReadOnly(True) soundPrefGrid.addWidget(self.playCommandWidget, n, 1) n = n+1 self.maxLevelLabel = QLabel(self.tr('Max Level:')) soundPrefGrid.addWidget(self.maxLevelLabel, n, 0) self.maxLevelWidget = QLineEdit(self.currLocale.toString(self.tmpPref['pref']['maxLevel'])) self.maxLevelWidget.setValidator(QDoubleValidator(self)) soundPrefGrid.addWidget(self.maxLevelWidget, n, 1) self.soundPrefWidget.setLayout(soundPrefGrid) self.tabWidget.addTab(self.appPrefWidget, self.tr("Applicatio&n")) self.tabWidget.addTab(self.plotPrefWidget, self.tr("Plot&s")) self.tabWidget.addTab(self.signalPrefWidget, self.tr("Signa&l")) self.tabWidget.addTab(self.soundPrefWidget, self.tr("Soun&d")) buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Ok|QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.permanentApply) layout = QVBoxLayout() layout.addWidget(self.tabWidget) layout.addWidget(buttonBox) self.setLayout(layout) def ondpiChange(self): try: val = int(self.dpiWidget.text()) except ValueError: QMessageBox.warning(self, self.tr('Warning'), self.tr('dpi value not valid')) self.dpiWidget.setText(str(self.tmpPref['pref']['dpi'])) val = int(self.dpiWidget.text()) if val < 10: QMessageBox.warning(self, self.tr('Warning'), self.tr('dpi value too small')) self.dpiWidget.setText(str(10)) def onChangeLineColor(self): col = QColorDialog.getColor() if col.isValid(): self.lineColor1 = col self.lineColorSquare.setStyleSheet("QWidget { background-color: %s }" % self.lineColor1.name()) def onChangeCanvasColor(self): col = QColorDialog.getColor() if col.isValid(): self.canvasColor = col self.canvasColorSquare.setStyleSheet("QWidget { background-color: %s }" % self.canvasColor.name()) def onChangeBackgroundColor(self): col = QColorDialog.getColor() if col.isValid(): self.backgroundColor = col self.backgroundColorSquare.setStyleSheet("QWidget { background-color: %s }" % self.backgroundColor.name()) def onLanguageChooserChange(self): for i in range(self.countryChooser.count()): self.countryChooser.removeItem(0) self.countryChooser.addItems(self.parent().prm['data']['available_countries'][self.languageChooser.currentText()]) def onPlayChooserChange(self): foo = self.playChooser.currentText() if foo != self.tr('custom'): self.playCommandWidget.setText(foo) self.playCommandWidget.setReadOnly(True) else: self.playCommandWidget.setReadOnly(False) def tryApply(self): self.tmpPref['pref']['colormap'] = str(self.cmapChooser.currentText()) self.tmpPref['pref']['dpi'] = int(self.dpiWidget.text()) self.tmpPref['pref']['lineColor1'] = self.lineColor1 self.tmpPref['pref']['canvasColor'] = self.canvasColor self.tmpPref['pref']['backgroundColor'] = self.backgroundColor self.tmpPref['pref']['language'] = self.languageChooser.currentText() self.tmpPref['pref']['country'] = self.countryChooser.currentText() self.tmpPref['pref']['wavmanager'] = str(self.wavmanagerChooser.currentText()) self.tmpPref['pref']['playCommand'] = self.playCommandWidget.text() self.tmpPref['pref']['playCommandType'] = self.playChooser.currentText() self.tmpPref['pref']['maxLevel'] = self.currLocale.toDouble(self.maxLevelWidget.text())[0] if self.gridOn.isChecked(): self.tmpPref['pref']['grid'] = True else: self.tmpPref['pref']['grid'] = False self.tmpPref['pref']['smoothingWindow'] = str(self.windowChooser.currentText()) def revertChanges(self): self.cmapChooser.setCurrentIndex(self.cmapChooser.findText(self.tmpPref['pref']['colormap'])) self.dpiWidget.setText(str(self.tmpPref['pref']['dpi'])) self.languageChooser.setCurrentIndex(self.languageChooser.findText(self.tmpPref['pref']['language'])) self.countryChooser.setCurrentIndex(self.countryChooser.findText(self.tmpPref['pref']['country'])) self.wavmanagerChooser.setCurrentIndex(self.wavmanagerChooser.findText(self.tmpPref['pref']['sound']['wavmanager'])) self.playChooser.setCurrentIndex(self.playChooser.findText(self.tmpPref['pref']['playCommandType'])) self.playCommandWidget.setText(self.tmpPref['pref']['playCommand']) if self.playChooser.currentText() != self.tr('custom'): self.playCommandWidget.setReadOnly(True) self.maxLevelWidget.setText(str(self.tmpPref['pref']['maxLevel'])) self.gridOn.setChecked(self.tmpPref['pref']['grid']) self.windowChooser.setCurrentIndex(self.windowChooser.findText(self.tmpPref['pref']['smoothingWindow'])) self.lineColor1 = self.tmpPref['pref']['lineColor1'] self.lineColorSquare.setStyleSheet("QWidget { background-color: %s }" % self.lineColor1.name()) self.canvasColor = self.tmpPref['pref']['canvasColor'] self.backgroundColor = self.tmpPref['pref']['backgroundColor'] self.backgroundColorSquare.setStyleSheet("QWidget { background-color: %s }" % self.backgroundColor.name()) self.canvasColorSquare.setStyleSheet("QWidget { background-color: %s }" % self.canvasColor.name()) def permanentApply(self): self.tryApply() self.parent().prm['pref'] = copy.deepcopy(self.tmpPref['pref']) f = open(self.parent().prm['prefFile'], 'wb') pickle.dump(self.parent().prm['pref'], f) f.close() def tabChanged(self): self.tryApply() if self.tmpPref['pref'] != self.parent().prm['pref']: conf = applyChanges(self) if conf.exec_(): self.permanentApply() else: self.tmpPref['pref'] = copy.deepcopy(self.parent().prm['pref']) self.revertChanges()
class SchemeSelector(QWidget): currentChanged = pyqtSignal() changed = pyqtSignal() def __init__(self, parent=None): super(SchemeSelector, self).__init__(parent) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.label = QLabel() self.scheme = QComboBox() self.menuButton = QPushButton(flat=True) menu = QMenu(self.menuButton) self.menuButton.setMenu(menu) layout.addWidget(self.label) layout.addWidget(self.scheme) layout.addWidget(self.menuButton) layout.addStretch(1) # action generator def act(slot, icon=None): a = QAction(self, triggered=slot) self.addAction(a) icon and a.setIcon(icons.get(icon)) return a # add action a = self.addAction_ = act(self.slotAdd, 'list-add') menu.addAction(a) # remove action a = self.removeAction = act(self.slotRemove, 'list-remove') menu.addAction(a) # rename action a = self.renameAction = act(self.slotRename, 'document-edit') menu.addAction(a) menu.addSeparator() # import action a = self.importAction = act(self.slotImport, 'document-open') menu.addAction(a) # export action a = self.exportAction = act(self.slotExport, 'document-save-as') menu.addAction(a) self.scheme.currentIndexChanged.connect(self.slotSchemeChanged) app.translateUI(self) def translateUI(self): self.label.setText(_("Scheme:")) self.menuButton.setText(_("&Menu")) self.addAction_.setText(_("&Add...")) self.removeAction.setText(_("&Remove")) self.renameAction.setText(_("Re&name...")) self.importAction.setText(_("&Import...")) self.exportAction.setText(_("&Export...")) def slotSchemeChanged(self, index): """Called when the Scheme combobox is changed by the user.""" self.disableDefault(self.scheme.itemData(index) == 'default') self.currentChanged.emit() self.changed.emit() def disableDefault(self, val): self.removeAction.setDisabled(val) self.renameAction.setDisabled(val) def schemes(self): """Returns the list with internal names of currently available schemes.""" return [self.scheme.itemData(i) for i in range(self.scheme.count())] def currentScheme(self): """Returns the internal name of the currently selected scheme""" return self.scheme.itemData(self.scheme.currentIndex()) def insertSchemeItem(self, name, scheme): for i in range(1, self.scheme.count()): n = self.scheme.itemText(i) if n.lower() > name.lower(): self.scheme.insertItem(i, name, scheme) break else: self.scheme.addItem(name, scheme) def addScheme(self, name): num, key = 1, 'user1' while key in self.schemes() or key in self._schemesToRemove: num += 1 key = 'user{0}'.format(num) self.insertSchemeItem(name, key) self.scheme.setCurrentIndex(self.scheme.findData(key)) return key def slotAdd(self): name, ok = QInputDialog.getText( self, app.caption(_("Add Scheme")), _("Please enter a name for the new scheme:")) if ok: self.addScheme(name) def slotRemove(self): index = self.scheme.currentIndex() scheme = self.scheme.itemData(index) if scheme == 'default': return # default can not be removed self._schemesToRemove.add(scheme) self.scheme.removeItem(index) def slotRename(self): index = self.scheme.currentIndex() name = self.scheme.itemText(index) scheme = self.scheme.itemData(index) newName, ok = QInputDialog.getText(self, _("Rename"), _("New name:"), text=name) if ok: self.scheme.blockSignals(True) self.scheme.removeItem(index) self.insertSchemeItem(newName, scheme) self.scheme.setCurrentIndex(self.scheme.findData(scheme)) self.scheme.blockSignals(False) self.changed.emit() def slotImport(self): filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files")) caption = app.caption(_("dialog title", "Import color theme")) filename = QFileDialog.getOpenFileName(self, caption, QDir.homePath(), filetypes) if filename: self.parent().import_(filename) def slotExport(self): name = self.scheme.currentText() filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files")) caption = app.caption( _("dialog title", "Export {name}").format(name=name)) path = os.path.join(QDir.homePath(), name + '.xml') filename = QFileDialog.getSaveFileName(self, caption, path, filetypes) if filename: if os.path.splitext(filename)[1] != '.xml': filename += '.xml' self.parent().export(name, filename) def loadSettings(self, currentKey, namesGroup): # don't mark schemes for removal anymore self._schemesToRemove = set() s = QSettings() cur = s.value(currentKey, "default", type("")) # load the names for the shortcut schemes s.beginGroup(namesGroup) block = self.scheme.blockSignals(True) self.scheme.clear() self.scheme.addItem(_("Default"), "default") lst = [(s.value(key, key, type("")), key) for key in s.childKeys()] for name, key in sorted(lst, key=lambda f: f[0].lower()): self.scheme.addItem(name, key) # find out index index = self.scheme.findData(cur) self.disableDefault(cur == 'default') self.scheme.setCurrentIndex(index) self.scheme.blockSignals(block) self.currentChanged.emit() def saveSettings(self, currentKey, namesGroup, removePrefix=None): # first save new scheme names s = QSettings() s.beginGroup(namesGroup) for i in range(self.scheme.count()): if self.scheme.itemData(i) != 'default': s.setValue(self.scheme.itemData(i), self.scheme.itemText(i)) for scheme in self._schemesToRemove: s.remove(scheme) s.endGroup() if removePrefix: for scheme in self._schemesToRemove: s.remove("{0}/{1}".format(removePrefix, scheme)) # then save current scheme = self.currentScheme() s.setValue(currentKey, scheme) # clean up self._schemesToRemove = set()
class SchemeSelector(QWidget): currentChanged = pyqtSignal() changed = pyqtSignal() def __init__(self, parent=None): super(SchemeSelector, self).__init__(parent) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.label = QLabel() self.scheme = QComboBox() self.menuButton = QPushButton(flat=True) menu = QMenu(self.menuButton) self.menuButton.setMenu(menu) layout.addWidget(self.label) layout.addWidget(self.scheme) layout.addWidget(self.menuButton) layout.addStretch(1) # action generator def act(slot, icon=None): a = QAction(self, triggered=slot) self.addAction(a) icon and a.setIcon(icons.get(icon)) return a # add action a = self.addAction_ = act(self.slotAdd, 'list-add') menu.addAction(a) # remove action a = self.removeAction = act(self.slotRemove, 'list-remove') menu.addAction(a) # rename action a = self.renameAction = act(self.slotRename, 'document-edit') menu.addAction(a) menu.addSeparator() # import action a = self.importAction = act(self.slotImport, 'document-open') menu.addAction(a) # export action a = self.exportAction = act(self.slotExport, 'document-save-as') menu.addAction(a) self.scheme.currentIndexChanged.connect(self.slotSchemeChanged) app.translateUI(self) def translateUI(self): self.label.setText(_("Scheme:")) self.menuButton.setText(_("&Menu")) self.addAction_.setText(_("&Add...")) self.removeAction.setText(_("&Remove")) self.renameAction.setText(_("Re&name...")) self.importAction.setText(_("&Import...")) self.exportAction.setText(_("&Export...")) def slotSchemeChanged(self, index): """Called when the Scheme combobox is changed by the user.""" self.disableDefault(self.scheme.itemData(index) == 'default') self.currentChanged.emit() self.changed.emit() def disableDefault(self, val): self.removeAction.setDisabled(val) self.renameAction.setDisabled(val) def schemes(self): """Returns the list with internal names of currently available schemes.""" return [self.scheme.itemData(i) for i in range(self.scheme.count())] def currentScheme(self): """Returns the internal name of the currently selected scheme""" return self.scheme.itemData(self.scheme.currentIndex()) def insertSchemeItem(self, name, scheme): for i in range(1, self.scheme.count()): n = self.scheme.itemText(i) if n.lower() > name.lower(): self.scheme.insertItem(i, name, scheme) break else: self.scheme.addItem(name, scheme) def addScheme(self, name): num, key = 1, 'user1' while key in self.schemes() or key in self._schemesToRemove: num += 1 key = 'user{0}'.format(num) self.insertSchemeItem(name, key) self.scheme.setCurrentIndex(self.scheme.findData(key)) return key def slotAdd(self): name, ok = QInputDialog.getText(self, app.caption(_("Add Scheme")), _("Please enter a name for the new scheme:")) if ok: self.addScheme(name) def slotRemove(self): index = self.scheme.currentIndex() scheme = self.scheme.itemData(index) if scheme == 'default': return # default can not be removed self._schemesToRemove.add(scheme) self.scheme.removeItem(index) def slotRename(self): index = self.scheme.currentIndex() name = self.scheme.itemText(index) scheme = self.scheme.itemData(index) newName, ok = QInputDialog.getText(self, _("Rename"), _("New name:"), text=name) if ok: self.scheme.blockSignals(True) self.scheme.removeItem(index) self.insertSchemeItem(newName, scheme) self.scheme.setCurrentIndex(self.scheme.findData(scheme)) self.scheme.blockSignals(False) self.changed.emit() def slotImport(self): filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files")) caption = app.caption(_("dialog title", "Import color theme")) filename = QFileDialog.getOpenFileName(self, caption, os.environ['HOME'], filetypes) if filename: self.parent().import_(filename) def slotExport(self): name = self.scheme.currentText() filetypes = "{0} (*.xml);;{1} (*)".format(_("XML Files"), _("All Files")) caption = app.caption(_("dialog title", "Export {name}").format(name=name)) path = os.path.join(os.environ['HOME'], name+'.xml') filename = QFileDialog.getSaveFileName(self, caption, path, filetypes) if filename: if os.path.splitext(filename)[1] != '.xml': filename += '.xml' self.parent().export(name, filename) def loadSettings(self, currentKey, namesGroup): # dont mark schemes for removal anymore self._schemesToRemove = set() s = QSettings() cur = s.value(currentKey, "default", type("")) # load the names for the shortcut schemes s.beginGroup(namesGroup) self.scheme.clear() self.scheme.addItem(_("Default"), "default") lst = [(s.value(key, key, type("")), key) for key in s.childKeys()] for name, key in sorted(lst, key=lambda f: f[0].lower()): self.scheme.addItem(name, key) block = self.scheme.blockSignals(True) # find out index index = self.scheme.findData(cur) self.disableDefault(cur == 'default') self.scheme.setCurrentIndex(index) self.scheme.blockSignals(block) self.currentChanged.emit() def saveSettings(self, currentKey, namesGroup, removePrefix=None): # first save new scheme names s = QSettings() s.beginGroup(namesGroup) for i in range(self.scheme.count()): if self.scheme.itemData(i) != 'default': s.setValue(self.scheme.itemData(i), self.scheme.itemText(i)) for scheme in self._schemesToRemove: s.remove(scheme) s.endGroup() if removePrefix: for scheme in self._schemesToRemove: s.remove("{0}/{1}".format(removePrefix, scheme)) # then save current scheme = self.currentScheme() s.setValue(currentKey, scheme) # clean up self._schemesToRemove = set()
class ProjectTreeColumn(QDialog): def __init__(self, parent=None): super(ProjectTreeColumn, self).__init__(parent, Qt.WindowStaysOnTopHint) vbox = QVBoxLayout(self) vbox.setSizeConstraint(QVBoxLayout.SetDefaultConstraint) vbox.setContentsMargins(0, 0, 0, 0) self._buttons = [] self._combo_project = QComboBox() self._combo_project.setMinimumHeight(30) self._combo_project.setContextMenuPolicy(Qt.CustomContextMenu) vbox.addWidget(self._combo_project) self._projects_area = QStackedLayout() logger.debug("This is the projects area") logger.debug(self._projects_area) vbox.addLayout(self._projects_area) self.projects = [] self.connect(self._combo_project, SIGNAL("currentIndexChanged(int)"), self._change_current_project) self.connect(self._combo_project, SIGNAL("customContextMenuRequested(const QPoint &)"), self.context_menu_for_root) connections = ( { 'target': 'main_container', 'signal_name': 'addToProject(QString)', 'slot': self._add_file_to_project }, { 'target': 'main_container', 'signal_name': 'showFileInExplorer(QString)', 'slot': self._show_file_in_explorer }, ) IDE.register_service('projects_explorer', self) IDE.register_signals('projects_explorer', connections) ExplorerContainer.register_tab(translations.TR_TAB_PROJECTS, self) #FIXME: Should have a ninja settings object that stores tree state #FIXME: Or bettter, application data object #TODO: check this: #self.connect(ide, SIGNAL("goingDown()"), #self.tree_projects.shutdown) #def close_project_signal(): #self.emit(SIGNAL("updateLocator()")) def install_tab(self): ide = IDE.get_service('ide') ui_tools.install_shortcuts(self, actions.PROJECTS_TREE_ACTIONS, ide) self.connect(ide, SIGNAL("goingDown()"), self.close) def load_session_projects(self, projects): for project in projects: if os.path.exists(project): self._open_project_folder(project) def open_project_folder(self, folderName=None): if settings.WORKSPACE: directory = settings.WORKSPACE else: directory = os.path.expanduser("~") if folderName is None: folderName = QFileDialog.getExistingDirectory( self, translations.TR_OPEN_PROJECT_DIRECTORY, directory) logger.debug("Choosing Foldername") if folderName: logger.debug("Opening %s" % folderName) self._open_project_folder(folderName) def _open_project_folder(self, folderName): ninjaide = IDE.get_service("ide") project = NProject(folderName) qfsm = ninjaide.filesystem.open_project(project) if qfsm: self.add_project(project) self.emit(SIGNAL("updateLocator()")) self.save_recent_projects(folderName) main_container = IDE.get_service('main_container') if main_container: main_container.show_editor_area() def _add_file_to_project(self, path): """Add the file for 'path' in the project the user choose here.""" if self._active_project: pathProject = [self._active_project.project] addToProject = add_to_project.AddToProject(pathProject, self) addToProject.exec_() if not addToProject.pathSelected: return main_container = IDE.get_service('main_container') if not main_container: return editorWidget = main_container.get_current_editor() if not editorWidget.file_path: name = QInputDialog.getText( None, translations.TR_ADD_FILE_TO_PROJECT, translations.TR_FILENAME + ": ")[0] if not name: QMessageBox.information( self, translations.TR_INVALID_FILENAME, translations.TR_INVALID_FILENAME_ENTER_A_FILENAME) return else: name = file_manager.get_basename(editorWidget.file_path) new_path = file_manager.create_path(addToProject.pathSelected, name) ide_srv = IDE.get_service("ide") old_file = ide_srv.get_or_create_nfile(path) new_file = old_file.save(editorWidget.get_text(), new_path) #FIXME: Make this file replace the original in the open tab else: pass # Message about no project def _show_file_in_explorer(self, path): '''Iterate through the list of available projects and show the current file in the explorer view for the first project that contains it (i.e. if the same file is included in multiple open projects, the path will be expanded for the first project only). Note: This slot is connected to the main container's "showFileInExplorer(QString)" signal.''' for project in self.projects: index = project.model().index(path) if index.isValid(): # Show the explorer if it is currently hidden central = IDE.get_service('central_container') if central and not central.is_lateral_panel_visible(): central.change_lateral_visibility() # This highlights the index in the tree for us project.setCurrentIndex(index) # Loop through the parents to expand the tree # all the way up to the selected index. while index.isValid(): project.expand(index) index = index.parent() break def add_project(self, project): if project not in self.projects: self._combo_project.addItem(project.name) ptree = TreeProjectsWidget(project) self._projects_area.addWidget(ptree) self.connect(ptree, SIGNAL("closeProject(PyQt_PyObject)"), self._close_project) pmodel = project.model ptree.setModel(pmodel) pindex = pmodel.index(pmodel.rootPath()) ptree.setRootIndex(pindex) self.projects.append(ptree) current_index = self._projects_area.count() self._projects_area.setCurrentIndex(current_index - 1) self._combo_project.setCurrentIndex(current_index - 1) def _close_project(self, widget): """Close the project related to the tree widget.""" index = self._projects_area.currentIndex() self.projects.remove(widget) self._projects_area.takeAt(index) self._combo_project.removeItem(index) index = self._combo_project.currentIndex() self._projects_area.setCurrentIndex(index) ninjaide = IDE.get_service('ide') ninjaide.filesystem.close_project(widget.project.path) widget.deleteLater() def _change_current_project(self, index): self._projects_area.setCurrentIndex(index) def close_opened_projects(self): for project in reversed(self.projects): self._close_project(project) def save_project(self): """Save all the opened files that belongs to the actual project.""" if self._active_project: path = self._projects_area.currentWidget().project.path main_container = IDE.get_service('main_container') if path and main_container: main_container.save_project(path) def create_new_project(self): wizard = new_project_manager.NewProjectManager(self) wizard.show() @property def current_project(self): if self._projects_area.count() > 0: return self._projects_area.currentWidget().project @property def current_tree(self): return self._projects_area.currentWidget() def save_recent_projects(self, folder): settings = IDE.data_settings() recent_project_list = settings.value('recentProjects', {}) #if already exist on the list update the date time projectProperties = json_manager.read_ninja_project(folder) name = projectProperties.get('name', '') description = projectProperties.get('description', '') if name == '': name = file_manager.get_basename(folder) if description == '': description = translations.TR_NO_DESCRIPTION if folder in recent_project_list: properties = recent_project_list[folder] properties["lastopen"] = QDateTime.currentDateTime() properties["name"] = name properties["description"] = description recent_project_list[folder] = properties else: recent_project_list[folder] = { "name": name, "description": description, "isFavorite": False, "lastopen": QDateTime.currentDateTime() } #if the length of the project list it's high that 10 then delete #the most old #TODO: add the length of available projects to setting if len(recent_project_list) > 10: del recent_project_list[self.find_most_old_open( recent_project_list)] settings.setValue('recentProjects', recent_project_list) def find_most_old_open(self, recent_project_list): listFounder = [] for recent_project_path, content in list(recent_project_list.items()): listFounder.append( (recent_project_path, int(content["lastopen"].toString("yyyyMMddHHmmzzz")))) listFounder = sorted(listFounder, key=lambda date: listFounder[1], reverse=True) # sort by date last used return listFounder[0][0] def reject(self): if self.parent() is None: self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self) def closeEvent(self, event): self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self) event.ignore() def context_menu_for_root(self): menu = QMenu(self) path = self.current_tree.project.path action_add_file = menu.addAction(QIcon(":img/new"), translations.TR_ADD_NEW_FILE) action_add_folder = menu.addAction(QIcon(":img/openProj"), translations.TR_ADD_NEW_FOLDER) action_create_init = menu.addAction(translations.TR_CREATE_INIT) self.connect(action_add_file, SIGNAL("triggered()"), lambda: self.current_tree._add_new_file(path)) self.connect(action_add_folder, SIGNAL("triggered()"), lambda: self.current_tree._add_new_folder(path)) self.connect(action_create_init, SIGNAL("triggered()"), lambda: self.current_tree._create_init(path)) menu.addSeparator() actionRunProject = menu.addAction(QIcon(":img/play"), translations.TR_RUN_PROJECT) self.connect(actionRunProject, SIGNAL("triggered()"), self.current_tree._execute_project) if self.current_tree._added_to_console: actionRemoveFromConsole = menu.addAction( translations.TR_REMOVE_PROJECT_FROM_PYTHON_CONSOLE) self.connect(actionRemoveFromConsole, SIGNAL("triggered()"), self.current_tree._remove_project_from_console) else: actionAdd2Console = menu.addAction( translations.TR_ADD_PROJECT_TO_PYTHON_CONSOLE) self.connect(actionAdd2Console, SIGNAL("triggered()"), self.current_tree._add_project_to_console) actionShowFileSizeInfo = menu.addAction(translations.TR_SHOW_FILESIZE) self.connect(actionShowFileSizeInfo, SIGNAL("triggered()"), self.current_tree.show_filesize_info) actionProperties = menu.addAction(QIcon(":img/pref"), translations.TR_PROJECT_PROPERTIES) self.connect(actionProperties, SIGNAL("triggered()"), self.current_tree.open_project_properties) menu.addSeparator() action_close = menu.addAction( self.style().standardIcon(QStyle.SP_DialogCloseButton), translations.TR_CLOSE_PROJECT) self.connect(action_close, SIGNAL("triggered()"), self.current_tree._close_project) #menu for the project for m in self.current_tree.extra_menus_by_scope['project']: if isinstance(m, QMenu): menu.addSeparator() menu.addMenu(m) #show the menu! menu.exec_(QCursor.pos())
class ShowSettingsDialog(QDialog): def __init__(self, iface, memoryPointsLayer, memoryLinesLayer, configTable): """ Constructor :param iface: interface :param memoryPointsLayer: working memory points layer :param memoryLinesLayer: working memory lines layer :param configTable: config table selected for import """ QDialog.__init__(self) self.__iface = iface self.__memoryPointsLayer = memoryPointsLayer self.__memoryLinesLayer = memoryLinesLayer self.__configTable = configTable self.setWindowTitle(QCoreApplication.translate("VDLTools", "Settings")) self.__pointsLayers = [] self.__linesLayers = [] self.__tables = [] # dataSource = QgsDataSourceURI(self.__layer.source()) # db = DBConnector.setConnection(dataSource.database(), self.__iface) # if db: # query = db.exec_("""SELECT table_name FROM information_schema.tables WHERE table_schema NOT IN # ('pg_catalog', 'information_schema', 'topology') AND table_type = 'BASE TABLE' AND table_name NOT IN # (SELECT f_table_name FROM geometry_columns)""") # while query.next(): # self.__tables.append(query.value(0)) # db.close() for layer in self.__iface.mapCanvas().layers(): if layer is not None \ and layer.type() == QgsMapLayer.VectorLayer \ and layer.providerType() == "memory": if layer.geometryType() == QGis.Point: self.__pointsLayers.append(layer) if layer.geometryType() == QGis.Line: self.__linesLayers.append(layer) self.resize(400, 200) self.__layout = QGridLayout() pointLabel = QLabel( QCoreApplication.translate("VDLTools", "Working points layer : ")) pointLabel.setMinimumHeight(20) pointLabel.setMinimumWidth(50) self.__layout.addWidget(pointLabel, 0, 1) self.__pointCombo = QComboBox() self.__pointCombo.setMinimumHeight(20) self.__pointCombo.setMinimumWidth(50) self.__pointCombo.addItem("") for layer in self.__pointsLayers: self.__pointCombo.addItem(layer.name()) self.__layout.addWidget(self.__pointCombo, 0, 2) self.__pointCombo.currentIndexChanged.connect(self.__pointComboChanged) if self.__memoryPointsLayer is not None: if self.__memoryPointsLayer in self.__pointsLayers: self.__pointCombo.setCurrentIndex( self.__pointsLayers.index(self.__memoryPointsLayer) + 1) lineLabel = QLabel( QCoreApplication.translate("VDLTools", "Working lines layer : ")) lineLabel.setMinimumHeight(20) lineLabel.setMinimumWidth(50) self.__layout.addWidget(lineLabel, 1, 1) self.__lineCombo = QComboBox() self.__lineCombo.setMinimumHeight(20) self.__lineCombo.setMinimumWidth(50) self.__lineCombo.addItem("") for layer in self.__linesLayers: self.__lineCombo.addItem(layer.name()) self.__layout.addWidget(self.__lineCombo, 1, 2) self.__lineCombo.currentIndexChanged.connect(self.__lineComboChanged) if self.__memoryLinesLayer is not None: if self.__memoryLinesLayer in self.__linesLayers: self.__lineCombo.setCurrentIndex( self.__linesLayers.index(self.__memoryLinesLayer) + 1) tableLabel = QLabel( QCoreApplication.translate("VDLTools", "Config table : ")) tableLabel.setMinimumHeight(20) tableLabel.setMinimumWidth(50) self.__layout.addWidget(tableLabel, 2, 1) self.__tableCombo = QComboBox() self.__tableCombo.setMinimumHeight(20) self.__tableCombo.setMinimumWidth(50) self.__tableCombo.addItem("") for table in self.__tables: self.__tableCombo.addItem(table) self.__layout.addWidget(self.__tableCombo, 2, 2) self.__tableCombo.currentIndexChanged.connect(self.__tableComboChanged) if self.__configTable is not None: if self.__configTable in self.__tables: self.__tableCombo.setCurrentIndex( self.__tables.index(self.__configTable) + 1) self.__okButton = QPushButton( QCoreApplication.translate("VDLTools", "OK")) self.__okButton.setMinimumHeight(20) self.__okButton.setMinimumWidth(100) self.__cancelButton = QPushButton( QCoreApplication.translate("VDLTools", "Cancel")) self.__cancelButton.setMinimumHeight(20) self.__cancelButton.setMinimumWidth(100) self.__layout.addWidget(self.__okButton, 100, 1) self.__layout.addWidget(self.__cancelButton, 100, 2) self.setLayout(self.__layout) def __lineComboChanged(self): """ To remove blank item when another one is selected """ if self.__lineCombo.itemText(0) == "": self.__lineCombo.removeItem(0) def __pointComboChanged(self): """ To remove blank item when another one is selected """ if self.__pointCombo.itemText(0) == "": self.__pointCombo.removeItem(0) def __tableComboChanged(self): """ To remove blank item when another one is selected """ if self.__tableCombo.itemText(0) == "": self.__tableCombo.removeItem(0) def okButton(self): """ To get the ok button instance :return: ok button instance """ return self.__okButton def cancelButton(self): """ To get the cancel button instance :return: cancel button instance """ return self.__cancelButton def pointsLayer(self): """ To get the selected memory points layer :return: selected memeory points layer, or none """ index = self.__pointCombo.currentIndex() if self.__pointCombo.itemText(index) == "": return None else: return self.__pointsLayers[index] def linesLayer(self): """ To get the selected memory lines layer :return: selected memory lines layer, or none """ index = self.__lineCombo.currentIndex() if self.__lineCombo.itemText(index) == "": return None else: return self.__linesLayers[index] def configTable(self): """ To get the selected config table :return: selected config table, or none """ index = self.__tableCombo.currentIndex() if self.__tableCombo.itemText(index) == "": return None else: return self.__tables[index]
class experimentersDialog(QDialog): def __init__(self, parent): QDialog.__init__(self, parent) self.prm = self.parent().prm self.tmpPref = {} self.tmpPref['experimenter'] = {} self.tmpPref['experimenter'] = copy.deepcopy(self.parent().prm['experimenter']) self.currLocale = self.parent().prm['currentLocale'] self.currLocale.setNumberOptions(self.currLocale.OmitGroupSeparator | self.currLocale.RejectGroupSeparator) self.sizer = QGridLayout() self.h1Sizer = QHBoxLayout() self.v1Sizer = QVBoxLayout() self.v2Sizer = QVBoxLayout() n = 0 self.experimenterLabel = QLabel(self.tr("Experimenter ID:"), self) self.sizer.addWidget(self.experimenterLabel, n, 0) self.experimenterChooser = QComboBox() self.experimenterChooser.addItems(self.tmpPref['experimenter']['experimenter_id']) self.sizer.addWidget(self.experimenterChooser, n, 1) self.experimenterChooser.activated[str].connect(self.onExperimenterChange) self.currIdx = self.experimenterChooser.currentIndex() n = n+1 self.experimenterNameLabel = QLabel(self.tr("Name:"), self) self.sizer.addWidget(self.experimenterNameLabel, n, 0) self.experimenterNameTF = QLineEdit("") self.experimenterNameTF.setText(self.tmpPref['experimenter']['experimenter_name'][0]) self.sizer.addWidget(self.experimenterNameTF, n, 1) n = n+1 self.experimenterSurnameLabel = QLabel(self.tr("Surname:"), self) self.sizer.addWidget(self.experimenterSurnameLabel, n, 0) self.experimenterSurnameTF = QLineEdit("") self.experimenterSurnameTF.setText(self.tmpPref['experimenter']['experimenter_surname'][0]) self.sizer.addWidget(self.experimenterSurnameTF, n, 1) n = n+1 self.experimenterEmailLabel = QLabel(self.tr("e-mail:"), self) self.sizer.addWidget(self.experimenterEmailLabel, n, 0) self.experimenterEmailTF = QLineEdit("") self.experimenterEmailTF.setText(self.tmpPref['experimenter']['experimenter_email'][0]) self.sizer.addWidget(self.experimenterEmailTF, n, 1) n = n+1 self.experimenterAddressLabel = QLabel(self.tr("Address (line 1):"), self) self.sizer.addWidget(self.experimenterAddressLabel, n, 0) self.experimenterAddressTF = QLineEdit("") self.experimenterAddressTF.setText(self.tmpPref['experimenter']['experimenter_address'][0]) self.sizer.addWidget(self.experimenterAddressTF, n, 1) n = n+1 self.experimenterAddressLabel2 = QLabel(self.tr("Address (line 2):"), self) self.sizer.addWidget(self.experimenterAddressLabel2, n, 0) self.experimenterAddressTF2 = QLineEdit("") self.experimenterAddressTF2.setText(self.tmpPref['experimenter']['experimenter_address2'][0]) self.sizer.addWidget(self.experimenterAddressTF2, n, 1) n = n+1 self.experimenterTelephoneLabel = QLabel(self.tr("Telephone:"), self) self.sizer.addWidget(self.experimenterTelephoneLabel, n, 0) self.experimenterTelephoneTF = QLineEdit("") self.experimenterTelephoneTF.setText(self.tmpPref['experimenter']['experimenter_telephone'][0]) self.sizer.addWidget(self.experimenterTelephoneTF, n, 1) n = n+1 self.experimenterMobileLabel = QLabel(self.tr("Mobile:"), self) self.sizer.addWidget(self.experimenterMobileLabel, n, 0) self.experimenterMobileTF = QLineEdit("") self.experimenterMobileTF.setText(self.tmpPref['experimenter']['experimenter_mobile'][0]) self.sizer.addWidget(self.experimenterMobileTF, n, 1) #ADD EXPERIMENTER BUTTON addExpButton = QPushButton(self.tr("Add Experimenter"), self) addExpButton.clicked.connect(self.onClickAddExpButton) self.v2Sizer.addWidget(addExpButton) #REMOVE EXPERIMENTER BUTTON removeExpButton = QPushButton(self.tr("Remove Experimenter"), self) removeExpButton.clicked.connect(self.onClickRemoveExpButton) self.v2Sizer.addWidget(removeExpButton) #CHANGE ID BUTTON changeIdButton = QPushButton(self.tr("Change Identifier"), self) changeIdButton.clicked.connect(self.onClickChangeIdButton) self.v2Sizer.addWidget(changeIdButton) #SET AS DEFAULT BUTTON setAsDefaultButton = QPushButton(self.tr("Set as default"), self) setAsDefaultButton.clicked.connect(self.onClickSetAsDefaultButton) self.v2Sizer.addWidget(setAsDefaultButton) self.v2Sizer.addStretch() buttonBox = QDialogButtonBox(QDialogButtonBox.Apply|QDialogButtonBox.Ok|QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.onClickApplyButton) self.h1Sizer.addLayout(self.v2Sizer) self.sizer.setAlignment(Qt.AlignTop) self.h1Sizer.addLayout(self.sizer) self.v1Sizer.addLayout(self.h1Sizer) self.v1Sizer.addWidget(buttonBox) self.setLayout(self.v1Sizer) def onClickApplyButton(self): self.tryApply(self.currIdx) self.permanentApply() def permanentApply(self): self.parent().prm['experimenter'] = copy.deepcopy(self.tmpPref['experimenter']) f = open(self.parent().prm['experimenterPrefFile'], 'wb') pickle.dump(self.parent().prm['experimenter'], f) f.close() for i in range(self.parent().experimenterChooser.count()): self.parent().experimenterChooser.removeItem(0) self.parent().experimenterChooser.addItems(self.parent().prm['experimenter']['experimenter_id']) def tryApply(self, idx): self.tmpPref['experimenter']['experimenter_id'][idx] = self.experimenterChooser.itemText(idx) self.tmpPref['experimenter']['experimenter_name'][idx] = self.experimenterNameTF.text() self.tmpPref['experimenter']['experimenter_surname'][idx] = self.experimenterSurnameTF.text() self.tmpPref['experimenter']['experimenter_email'][idx] = self.experimenterEmailTF.text() self.tmpPref['experimenter']['experimenter_address'][idx] = self.experimenterAddressTF.text() self.tmpPref['experimenter']['experimenter_address2'][idx] = self.experimenterAddressTF2.text() self.tmpPref['experimenter']['experimenter_telephone'][idx] = self.experimenterTelephoneTF.text() self.tmpPref['experimenter']['experimenter_mobile'][idx] = self.experimenterMobileTF.text() def revertChanges(self): if len(self.tmpPref['experimenter']['experimenter_id']) != len(self.parent().prm['experimenter']['experimenter_id']): #experimenter was added, reverting for i in range(self.experimenterChooser.count()): self.experimenterChooser.removeItem(0) self.experimenterChooser.addItems(self.parent().prm['experimenter']['experimenter_id']) self.tmpPref['experimenter'] = copy.deepcopy(self.parent().prm['experimenter']) def onExperimenterChange(self, experimenterSelected): self.prevIdx = self.currIdx self.currIdx = self.tmpPref['experimenter']['experimenter_id'].index(experimenterSelected) self.tryApply(self.prevIdx) if self.tmpPref['experimenter'] != self.parent().prm['experimenter']: conf = applyChanges(self) if conf.exec_(): self.permanentApply() else: self.revertChanges() self.experimenterNameTF.setText(self.prm['experimenter']['experimenter_name'][self.currIdx]) self.experimenterSurnameTF.setText(self.prm['experimenter']['experimenter_surname'][self.currIdx]) self.experimenterEmailTF.setText(self.prm['experimenter']['experimenter_email'][self.currIdx]) self.experimenterAddressTF.setText(self.prm['experimenter']['experimenter_address'][self.currIdx]) self.experimenterAddressTF2.setText(self.prm['experimenter']['experimenter_address2'][self.currIdx]) self.experimenterTelephoneTF.setText(self.prm['experimenter']['experimenter_telephone'][self.currIdx]) self.experimenterMobileTF.setText(self.prm['experimenter']['experimenter_mobile'][self.currIdx]) def onClickAddExpButton(self): self.tryApply(self.currIdx) if self.tmpPref['experimenter'] != self.parent().prm['experimenter']: conf = applyChanges(self) if conf.exec_(): self.permanentApply() else: self.revertChanges() msg = self.tr("Experimenter's Identifier:") name, ok = QInputDialog.getText(self, self.tr('Input Dialog'), msg) if ok: self.tmpPref['experimenter']['defaultExperimenter'].append('') self.tmpPref['experimenter']['experimenter_id'].append(name) self.tmpPref['experimenter']['experimenter_name'].append('') self.tmpPref['experimenter']['experimenter_surname'].append('') self.tmpPref['experimenter']['experimenter_email'].append('') self.tmpPref['experimenter']['experimenter_address'].append('') self.tmpPref['experimenter']['experimenter_address2'].append('') self.tmpPref['experimenter']['experimenter_telephone'].append('') self.tmpPref['experimenter']['experimenter_mobile'].append('') self.permanentApply() self.currIdx = self.experimenterChooser.count() self.experimenterNameTF.setText(self.tmpPref['experimenter']['experimenter_name'][self.currIdx]) self.experimenterSurnameTF.setText(self.tmpPref['experimenter']['experimenter_surname'][self.currIdx]) self.experimenterEmailTF.setText(self.tmpPref['experimenter']['experimenter_email'][self.currIdx]) self.experimenterAddressTF.setText(self.tmpPref['experimenter']['experimenter_address'][self.currIdx]) self.experimenterAddressTF2.setText(self.tmpPref['experimenter']['experimenter_address2'][self.currIdx]) self.experimenterTelephoneTF.setText(self.tmpPref['experimenter']['experimenter_telephone'][self.currIdx]) self.experimenterMobileTF.setText(self.tmpPref['experimenter']['experimenter_mobile'][self.currIdx]) self.experimenterChooser.addItem(name) self.experimenterChooser.setCurrentIndex(self.currIdx) def onClickRemoveExpButton(self): self.tryApply(self.currIdx) if self.tmpPref['experimenter'] != self.parent().prm['experimenter']: conf = applyChanges(self) if conf.exec_(): self.permanentApply() else: self.revertChanges() if self.experimenterChooser.count() > 1: reply = QMessageBox.warning(self, self.tr('Message'), "Remove experimenter? This action cannot be undone!", QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.Yes: self.tmpPref['experimenter']['defaultExperimenter'].pop(self.currIdx) self.tmpPref['experimenter']['experimenter_id'].pop(self.currIdx) self.tmpPref['experimenter']['experimenter_name'].pop(self.currIdx) self.tmpPref['experimenter']['experimenter_surname'].pop(self.currIdx) self.tmpPref['experimenter']['experimenter_email'].pop(self.currIdx) self.tmpPref['experimenter']['experimenter_address'].pop(self.currIdx) self.tmpPref['experimenter']['experimenter_address2'].pop(self.currIdx) self.tmpPref['experimenter']['experimenter_telephone'].pop(self.currIdx) self.tmpPref['experimenter']['experimenter_mobile'].pop(self.currIdx) self.experimenterChooser.removeItem(self.currIdx) self.currIdx = self.experimenterChooser.currentIndex() self.permanentApply() self.experimenterNameTF.setText(self.tmpPref['experimenter']['experimenter_name'][self.currIdx]) self.experimenterSurnameTF.setText(self.tmpPref['experimenter']['experimenter_surname'][self.currIdx]) self.experimenterEmailTF.setText(self.tmpPref['experimenter']['experimenter_email'][self.currIdx]) self.experimenterAddressTF.setText(self.tmpPref['experimenter']['experimenter_address'][self.currIdx]) self.experimenterAddressTF2.setText(self.tmpPref['experimenter']['experimenter_address2'][self.currIdx]) self.experimenterTelephoneTF.setText(self.tmpPref['experimenter']['experimenter_telephone'][self.currIdx]) self.experimenterMobileTF.setText(self.tmpPref['experimenter']['experimenter_mobile'][self.currIdx]) else: QMessageBox.warning(self, self.tr('Message'), self.tr("Only one experimenter left. Experimenter cannot be removed!"), QMessageBox.Ok) def onClickChangeIdButton(self): self.tryApply(self.currIdx) if self.tmpPref['experimenter'] != self.parent().prm['experimenter']: conf = applyChanges(self) if conf.exec_(): self.permanentApply() else: self.revertChanges() msg = self.tr("Experimenter's Identifier:") name, ok = QInputDialog.getText(self, self.tr('Input Dialog'), msg) if ok: self.tmpPref['experimenter']['experimenter_id'][self.currIdx] = name self.experimenterChooser.setItemText(self.currIdx, name) self.permanentApply() def onClickSetAsDefaultButton(self): idx = self.experimenterChooser.currentIndex() print(idx) self.tryApply(self.currIdx) if self.tmpPref['experimenter'] != self.parent().prm['experimenter']: conf = applyChanges(self) if conf.exec_(): self.permanentApply() else: self.revertChanges() for i in range(len(self.parent().prm['experimenter']["defaultExperimenter"])): if i == idx: self.tmpPref['experimenter']["defaultExperimenter"][i] = "\u2713" else: self.tmpPref['experimenter']["defaultExperimenter"][i] = "\u2012" print(self.tmpPref) self.permanentApply()
class ShowSettingsDialog(QDialog): """ Dialog class for plugin settings """ def __init__(self, iface, memoryPointsLayer, memoryLinesLayer, importConfigTable, importUriDb, importSchemaDb, controlConfigTable, controlUriDb, controlSchemaDb, mntUrl, refLayers, adjLayers, levelAtt, levelVal, drawdowmLayer, pipeDiam, moreTools): """ Constructor :param iface: interface :param memoryPointsLayer: working memory points layer :param memoryLinesLayer: working memory lines layer :param importConfigTable: config table selected for import :param importUriDb: database for import :param importSchemaDb: db schema for import :param controlConfigTable: config table selected for control :param controlUriDb: database for control :param controlSchemaDb: db schema for control :param mntUrl: url to get mnt :param refLayers: reference layers for drawdown :param adjLayers: adjustement layers for drawdown :param levelAtt: level attribute for drawdown :param levelVal: level value for drawdown :param drawdowmLayer: line layer for drawdown :param pipeDiam: pipe diameter for drawdown :param moreTools: if more tools or not """ QDialog.__init__(self) self.__iface = iface self.__memoryPointsLayer = memoryPointsLayer self.__memoryLinesLayer = memoryLinesLayer self.__importConfigTable = importConfigTable self.__importUriDb = importUriDb self.__importSchemaDb = importSchemaDb self.__controlConfigTable = controlConfigTable self.__controlUriDb = controlUriDb self.__controlSchemaDb = controlSchemaDb self.__mntUrl = mntUrl self.__refLayers = refLayers self.__adjLayers = adjLayers self.__levelAtt = levelAtt self.__levelVal = levelVal self.__drawdowmLayer = drawdowmLayer self.__pipeDiam = pipeDiam self.setWindowTitle(QCoreApplication.translate("VDLTools", "Settings")) self.__pointsLayers = [] self.__linesLayers = [] self.__refAvailableLayers = [] self.__drawdownLayers = [] self.__tables = [] self.__schemas = [] self.__pipeDiamFields = [] self.__levelAttFields = [] self.__dbs = DBConnector.getUsedDatabases() self.__refLabels = [] self.__refChecks = [] self.__adjChecks = [] for layer in list(QgsMapLayerRegistry.instance().mapLayers().values()): if layer is not None and layer.type() == QgsMapLayer.VectorLayer: if layer.providerType() == "memory": if layer.geometryType() == QGis.Point: self.__pointsLayers.append(layer) if layer.geometryType() == QGis.Line: self.__linesLayers.append(layer) if QGis.fromOldWkbType( layer.wkbType()) == QgsWKBTypes.LineStringZ: self.__drawdownLayers.append(layer) if QGis.fromOldWkbType(layer.wkbType()) == QgsWKBTypes.PointZ: self.__refAvailableLayers.append(layer) self.resize(600, 500) self.__layout = QGridLayout() self.__scrollLayout = QGridLayout() line = 0 intersectLabel = QLabel( QCoreApplication.translate("VDLTools", "Intersect ")) self.__scrollLayout.addWidget(intersectLabel, line, 0) line += 1 pointLabel = QLabel( QCoreApplication.translate("VDLTools", "Working points layer : ")) self.__scrollLayout.addWidget(pointLabel, line, 1) self.__pointCombo = QComboBox() self.__pointCombo.setMinimumHeight(20) self.__pointCombo.setMinimumWidth(50) self.__pointCombo.addItem("") for layer in self.__pointsLayers: self.__pointCombo.addItem(layer.name()) self.__scrollLayout.addWidget(self.__pointCombo, line, 2) self.__pointCombo.currentIndexChanged.connect(self.__pointComboChanged) if self.__memoryPointsLayer is not None: if self.__memoryPointsLayer in self.__pointsLayers: self.__pointCombo.setCurrentIndex( self.__pointsLayers.index(self.__memoryPointsLayer) + 1) line += 1 lineLabel = QLabel( QCoreApplication.translate("VDLTools", "Working lines layer : ")) self.__scrollLayout.addWidget(lineLabel, line, 1) self.__lineCombo = QComboBox() self.__lineCombo.setMinimumHeight(20) self.__lineCombo.setMinimumWidth(50) self.__lineCombo.addItem("") for layer in self.__linesLayers: self.__lineCombo.addItem(layer.name()) self.__scrollLayout.addWidget(self.__lineCombo, line, 2) self.__lineCombo.currentIndexChanged.connect(self.__lineComboChanged) if self.__memoryLinesLayer is not None: if self.__memoryLinesLayer in self.__linesLayers: self.__lineCombo.setCurrentIndex( self.__linesLayers.index(self.__memoryLinesLayer) + 1) line += 1 profilesLabel = QLabel( QCoreApplication.translate("VDLTools", "Profiles ")) self.__scrollLayout.addWidget(profilesLabel, line, 0) line += 1 mntLabel = QLabel( QCoreApplication.translate("VDLTools", "Url for MNT : ")) self.__scrollLayout.addWidget(mntLabel, line, 1) self.__mntText = QLineEdit() if self.__mntUrl is None or self.__mntUrl == "None": self.__mntText.insert( 'https://map.lausanne.ch/prod/wsgi/profile.json') else: self.__mntText.insert(self.__mntUrl) self.__mntText.setMinimumHeight(20) self.__mntText.setMinimumWidth(100) self.__scrollLayout.addWidget(self.__mntText, line, 2) line += 1 ddLabel = QLabel(QCoreApplication.translate("VDLTools", "Drawdown ")) self.__scrollLayout.addWidget(ddLabel, line, 0) line += 1 self.__scrollLayout.addWidget( QLabel(QCoreApplication.translate("VDLTools", "Layer")), line, 1) namesLayout = QHBoxLayout() namesWidget = QWidget() namesLayout.addWidget( QLabel(QCoreApplication.translate("VDLTools", "Reference"))) namesLayout.addWidget( QLabel(QCoreApplication.translate("VDLTools", "Adjustable"))) namesLayout.setContentsMargins(0, 0, 0, 0) namesWidget.setLayout(namesLayout) self.__scrollLayout.addWidget(namesWidget, line, 2) line += 1 for layer in self.__refAvailableLayers: refLabel = QLabel(" - " + layer.name()) self.__refLabels.append(refLabel) self.__scrollLayout.addWidget(refLabel, line, 1) checksLayout = QHBoxLayout() checksLayout.setContentsMargins(0, 0, 0, 0) checksWidget = QWidget() refCheck = QCheckBox() self.__refChecks.append(refCheck) refCheck.stateChanged.connect(self.__refBoxesChanged) checksLayout.addWidget(refCheck) adjCheck = QCheckBox() self.__adjChecks.append(adjCheck) checksLayout.addWidget(adjCheck) checksWidget.setLayout(checksLayout) self.__scrollLayout.addWidget(checksWidget, line, 2) line += 1 levelAttLabel = QLabel( QCoreApplication.translate("VDLTools", "Code(s) on pipe : ")) self.__scrollLayout.addWidget(levelAttLabel, line, 1) self.__levelAttCombo = QComboBox() self.__levelAttCombo.setMinimumHeight(20) self.__levelAttCombo.setMinimumWidth(50) self.__levelAttCombo.addItem("") self.__scrollLayout.addWidget(self.__levelAttCombo, line, 2) self.__levelAttCombo.currentIndexChanged.connect( self.__levelAttComboChanged) i = 0 for layer in self.__refAvailableLayers: if layer in self.__refLayers: self.__refChecks[i].setChecked(True) if layer in self.__adjLayers: self.__adjChecks[i].setChecked(True) i += 1 line += 1 levelValLabel = QLabel( QCoreApplication.translate("VDLTools", "Point code attribute : ")) self.__scrollLayout.addWidget(levelValLabel, line, 1) self.__levelValText = QLineEdit() if self.__levelVal is not None and self.__levelVal != "None": self.__levelValText.insert(self.__levelVal) self.__levelValText.setMinimumHeight(20) self.__levelValText.setMinimumWidth(100) self.__scrollLayout.addWidget(self.__levelValText, line, 2) line += 1 drawdownLabel = QLabel( QCoreApplication.translate("VDLTools", "drawdown layer : ")) self.__scrollLayout.addWidget(drawdownLabel, line, 1) self.__drawdownCombo = QComboBox() self.__drawdownCombo.setMinimumHeight(20) self.__drawdownCombo.setMinimumWidth(50) self.__drawdownCombo.addItem("") for layer in self.__drawdownLayers: self.__drawdownCombo.addItem(layer.name()) self.__scrollLayout.addWidget(self.__drawdownCombo, line, 2) line += 1 pipeDiamLabel = QLabel( QCoreApplication.translate("VDLTools", "Pipe diameter attribute [cm] : ")) self.__scrollLayout.addWidget(pipeDiamLabel, line, 1) self.__pipeDiamCombo = QComboBox() self.__pipeDiamCombo.setMinimumHeight(20) self.__pipeDiamCombo.setMinimumWidth(50) self.__pipeDiamCombo.addItem("") self.__scrollLayout.addWidget(self.__pipeDiamCombo, line, 2) self.__drawdownCombo.currentIndexChanged.connect( self.__drawdownComboChanged) self.__pipeDiamCombo.currentIndexChanged.connect( self.__pipeDiamComboChanged) if self.__drawdowmLayer is not None: if self.__drawdowmLayer in self.__drawdownLayers: self.__drawdownCombo.setCurrentIndex( self.__drawdownLayers.index(self.__drawdowmLayer) + 1) line += 1 controlLabel = QLabel( QCoreApplication.translate("VDLTools", "Control ")) self.__scrollLayout.addWidget(controlLabel, line, 0) line += 1 controlDbLabel = QLabel( QCoreApplication.translate("VDLTools", "Control database : ")) self.__scrollLayout.addWidget(controlDbLabel, line, 1) self.__controlDbCombo = QComboBox() self.__controlDbCombo.setMinimumHeight(20) self.__controlDbCombo.setMinimumWidth(50) self.__controlDbCombo.addItem("") for db in list(self.__dbs.keys()): self.__controlDbCombo.addItem(db) self.__scrollLayout.addWidget(self.__controlDbCombo, line, 2) line += 1 controlSchemaLabel = QLabel( QCoreApplication.translate("VDLTools", "Control database schema : ")) self.__scrollLayout.addWidget(controlSchemaLabel, line, 1) self.__controlSchemaCombo = QComboBox() self.__controlSchemaCombo.setMinimumHeight(20) self.__controlSchemaCombo.setMinimumWidth(50) self.__controlSchemaCombo.addItem("") self.__scrollLayout.addWidget(self.__controlSchemaCombo, line, 2) line += 1 controlTableLabel = QLabel( QCoreApplication.translate("VDLTools", "Control config table : ")) self.__scrollLayout.addWidget(controlTableLabel, line, 1) self.__controlTableCombo = QComboBox() self.__controlTableCombo.setMinimumHeight(20) self.__controlTableCombo.setMinimumWidth(50) self.__controlTableCombo.addItem("") self.__scrollLayout.addWidget(self.__controlTableCombo, line, 2) self.__controlDbCombo.currentIndexChanged.connect( self.__controlDbComboChanged) self.__controlSchemaCombo.currentIndexChanged.connect( self.__controlSchemaComboChanged) self.__controlTableCombo.currentIndexChanged.connect( self.__controlTableComboChanged) if self.__controlUriDb is not None: if self.__controlUriDb.database() in list(self.__dbs.keys()): self.__controlDbCombo.setCurrentIndex( list(self.__dbs.keys()).index( self.__controlUriDb.database()) + 1) if moreTools: line += 1 importLabel = QLabel( QCoreApplication.translate("VDLTools", "Import ")) self.__scrollLayout.addWidget(importLabel, line, 0) line += 1 importDbLabel = QLabel( QCoreApplication.translate("VDLTools", "Import database : ")) self.__scrollLayout.addWidget(importDbLabel, line, 1) self.__importDbCombo = QComboBox() self.__importDbCombo.setMinimumHeight(20) self.__importDbCombo.setMinimumWidth(50) self.__importDbCombo.addItem("") for db in list(self.__dbs.keys()): self.__importDbCombo.addItem(db) self.__scrollLayout.addWidget(self.__importDbCombo, line, 2) line += 1 importSchemaLabel = QLabel( QCoreApplication.translate("VDLTools", "Import database schema : ")) self.__scrollLayout.addWidget(importSchemaLabel, line, 1) self.__importSchemaCombo = QComboBox() self.__importSchemaCombo.setMinimumHeight(20) self.__importSchemaCombo.setMinimumWidth(50) self.__importSchemaCombo.addItem("") self.__scrollLayout.addWidget(self.__importSchemaCombo, line, 2) line += 1 importTableLabel = QLabel( QCoreApplication.translate("VDLTools", "Import config table : ")) self.__scrollLayout.addWidget(importTableLabel, line, 1) self.__importTableCombo = QComboBox() self.__importTableCombo.setMinimumHeight(20) self.__importTableCombo.setMinimumWidth(50) self.__importTableCombo.addItem("") self.__scrollLayout.addWidget(self.__importTableCombo, line, 2) self.__importDbCombo.currentIndexChanged.connect( self.__importDbComboChanged) self.__importSchemaCombo.currentIndexChanged.connect( self.__importSchemaComboChanged) self.__importTableCombo.currentIndexChanged.connect( self.__importTableComboChanged) if self.__importUriDb is not None: if self.__importUriDb.database() in list(self.__dbs.keys()): self.__importDbCombo.setCurrentIndex( list(self.__dbs.keys()).index( self.__importUriDb.database()) + 1) else: self.__importDbCombo = None self.__importSchemaCombo = None self.__importTableCombo = None widget = QWidget() widget.setLayout(self.__scrollLayout) scroll = QScrollArea() scroll.setWidgetResizable(True) scroll.setWidget(widget) self.__layout.addWidget(scroll, 1, 0, 1, 2) self.__okButton = QPushButton( QCoreApplication.translate("VDLTools", "OK")) self.__okButton.setMinimumHeight(20) self.__okButton.setMinimumWidth(100) self.__cancelButton = QPushButton( QCoreApplication.translate("VDLTools", "Cancel")) self.__cancelButton.setMinimumHeight(20) self.__cancelButton.setMinimumWidth(100) self.__layout.addWidget(self.__okButton, 100, 0) self.__layout.addWidget(self.__cancelButton, 100, 1) self.setLayout(self.__layout) @staticmethod def __resetCombo(combo): """ To reset a combo list :param combo: concerned combo """ while combo.count() > 0: combo.removeItem(combo.count() - 1) def __setSchemaCombo(self, uriDb, schemaCombo, schemaComboChanged, schemaDb): """ To fill the schema combo list :param uriDb: selected database uri :param schemaCombo: concerned schema combo :param schemaComboChanged: concerned schema combo change event :param schemaDb: selected schema db """ connector = DBConnector(uriDb, self.__iface) db = connector.setConnection() if db: Signal.safelyDisconnect(schemaCombo.currentIndexChanged, schemaComboChanged) self.__resetCombo(schemaCombo) schemaCombo.addItem("") self.__schemas = [] query = db.exec_( """SELECT DISTINCT table_schema FROM information_schema.tables WHERE table_schema NOT IN ('pg_catalog', 'information_schema', 'topology') AND table_type = 'BASE TABLE' AND table_name NOT IN (SELECT f_table_name FROM geometry_columns)""") if query.lastError().isValid(): self.__iface.messageBar().pushMessage( query.lastError().text(), level=QgsMessageBar.CRITICAL, duration=0) else: while next(query): self.__schemas.append(query.value(0)) db.close() for schema in self.__schemas: schemaCombo.addItem(schema) schemaCombo.currentIndexChanged.connect(schemaComboChanged) if schemaDb is not None: if schemaDb in self.__schemas: schemaCombo.setCurrentIndex( self.__schemas.index(schemaDb) + 1) def __setTableCombo(self, uriDb, schema, tableCombo, tableComboChanged, configTable): """ To fill the table combo list :param uriDb: selected database uri :param schema: selected database schema :param tableCombo: concerned table combo :param tableComboChanged: concerned table combo change event :param configTable: selected config table """ connector = DBConnector(uriDb, self.__iface) db = connector.setConnection() if db: Signal.safelyDisconnect(tableCombo.currentIndexChanged, tableComboChanged) self.__resetCombo(tableCombo) tableCombo.addItem("") self.__tables = [] query = db.exec_( """SELECT table_name FROM information_schema.tables WHERE table_schema = '""" + schema + """' ORDER BY table_name""") if query.lastError().isValid(): self.__iface.messageBar().pushMessage( query.lastError().text(), level=QgsMessageBar.CRITICAL, duration=0) else: while next(query): self.__tables.append(query.value(0)) db.close() for table in self.__tables: if tableCombo.findText(table) == -1: tableCombo.addItem(table) tableCombo.currentIndexChanged.connect(tableComboChanged) if configTable is not None: if configTable in self.__tables: tableCombo.setCurrentIndex( self.__tables.index(configTable) + 1) def __setPipeDiamCombo(self, drawdownLayer): """ To fill the pipe diameter combo list :param drawdownLayer: choosen drawdown layer """ Signal.safelyDisconnect(self.__pipeDiamCombo.currentIndexChanged, self.__pipeDiamComboChanged) self.__resetCombo(self.__pipeDiamCombo) self.__pipeDiamCombo.addItem("") fields = drawdownLayer.fields() self.__pipeDiamFields = [] for field in fields: self.__pipeDiamFields.append(field.name()) self.__pipeDiamCombo.addItem(field.name()) self.__pipeDiamCombo.currentIndexChanged.connect( self.__pipeDiamComboChanged) if self.__pipeDiam is not None: if self.__pipeDiam in self.__pipeDiamFields: self.__pipeDiamCombo.setCurrentIndex( self.__pipeDiamFields.index(self.__pipeDiam) + 1) def __setLevelAttCombo(self, refLayers): """ To fill the level attribute combo list :param refLayers: choosen reference layers """ Signal.safelyDisconnect(self.__levelAttCombo.currentIndexChanged, self.__levelAttComboChanged) self.__resetCombo(self.__levelAttCombo) self.__levelAttCombo.addItem("") self.__levelAttFields = [] num = 0 for layer in refLayers: fields = layer.fields() if num == 0: for field in fields: self.__levelAttFields.append(field.name()) num = 1 else: names = [] for field in fields: names.append(field.name()) news = [] for name in self.__levelAttFields: if name in names: news.append(name) self.__levelAttFields = news for name in self.__levelAttFields: self.__levelAttCombo.addItem(name) self.__levelAttCombo.currentIndexChanged.connect( self.__levelAttComboChanged) if self.__levelAtt is not None: if self.__levelAtt in self.__levelAttFields: self.__levelAttCombo.setCurrentIndex( self.__levelAttFields.index(self.__levelAtt) + 1) def __lineComboChanged(self): """ To remove blank item when another one is selected """ if self.__lineCombo.itemText(0) == "": self.__lineCombo.removeItem(0) def __pointComboChanged(self): """ To remove blank item when another one is selected """ if self.__pointCombo.itemText(0) == "": self.__pointCombo.removeItem(0) def __refBoxesChanged(self): """ To update level attribute combo when reference layers have changed """ if self.refLayers() is not None: self.__setLevelAttCombo(self.refLayers()) def __drawdownComboChanged(self): """ To remove blank item when another one is selected and update pipe diamete combo when drawdown layer has changed """ if self.__drawdownCombo.itemText(0) == "": self.__drawdownCombo.removeItem(0) if self.drawdownLayer() is not None: self.__setPipeDiamCombo(self.drawdownLayer()) def __controlTableComboChanged(self): """ To remove blank item when another one is selected """ if self.__controlTableCombo.itemText(0) == "": self.__controlTableCombo.removeItem(0) def __importTableComboChanged(self): """ To remove blank item when another one is selected """ if self.__importTableCombo.itemText(0) == "": self.__importTableCombo.removeItem(0) def __controlDbComboChanged(self): """ When the selection in db combo has changed """ if self.__controlDbCombo.itemText(0) == "": self.__controlDbCombo.removeItem(0) if self.controlUriDb() is not None: self.__setSchemaCombo(self.controlUriDb(), self.__controlSchemaCombo, self.__controlSchemaComboChanged, self.__controlSchemaDb) def __importDbComboChanged(self): """ When the selection in db combo has changed """ if self.__importDbCombo.itemText(0) == "": self.__importDbCombo.removeItem(0) if self.importUriDb() is not None: self.__setSchemaCombo(self.importUriDb(), self.__importSchemaCombo, self.__importSchemaComboChanged, self.__importSchemaDb) def __controlSchemaComboChanged(self): """ When the selection in schema combo has changed """ if self.__controlSchemaCombo.itemText(0) == "": self.__controlSchemaCombo.removeItem(0) if self.controlSchemaDb() is not None: self.__setTableCombo(self.controlUriDb(), self.controlSchemaDb(), self.__controlTableCombo, self.__controlTableComboChanged, self.__controlConfigTable) def __importSchemaComboChanged(self): """ When the selection in schema combo has changed """ if self.__importSchemaaCombo.itemText(0) == "": self.__importSchemaCombo.removeItem(0) if self.importSchemaDb() is not None: self.__setTableCombo(self.importUriDb(), self.importSchemaDb(), self.__importTableCombo, self.__importTableComboChanged, self.__importConfigTable) def __pipeDiamComboChanged(self): """ When the selection in schema combo has changed """ if self.__pipeDiamCombo.itemText(0) == "": self.__pipeDiamCombo.removeItem(0) def __levelAttComboChanged(self): """ When the selection in schema combo has changed """ if self.__levelAttCombo.itemText(0) == "": self.__levelAttCombo.removeItem(0) def okButton(self): """ To get the ok button instance :return: ok button instance """ return self.__okButton def cancelButton(self): """ To get the cancel button instance :return: cancel button instance """ return self.__cancelButton def pointsLayer(self): """ To get the selected memory points layer :return: selected memory points layer, or none """ index = self.__pointCombo.currentIndex() if self.__pointCombo.itemText(index) == "": return None else: return self.__pointsLayers[index] def linesLayer(self): """ To get the selected memory lines layer :return: selected memory lines layer, or none """ index = self.__lineCombo.currentIndex() if self.__lineCombo.itemText(index) == "": return None else: return self.__linesLayers[index] def refLayers(self): """ To get the selected reference layers :return: selected reference layers, or none """ layers = [] i = 0 for check in self.__refChecks: if check.isChecked(): layers.append(self.__refAvailableLayers[i]) i += 1 return layers def adjLayers(self): """ To get the selected ajustable layers :return: selected adjustable layers, or none """ layers = [] i = 0 for check in self.__adjChecks: if check.isChecked(): layers.append(self.__refAvailableLayers[i]) i += 1 return layers def levelAtt(self): """ To get the selected level attribute :return: selected level attribute, or none """ if self.__levelAttCombo is None: return None index = self.__levelAttCombo.currentIndex() if self.__levelAttCombo.itemText(index) == "": return None else: return self.__levelAttFields[index] def levelVal(self): """ To get the filled level value :return: filled level value """ return self.__levelValText.text() def drawdownLayer(self): """ To get the selected drawdown layer :return: selected drawdown layer, or none """ index = self.__drawdownCombo.currentIndex() if self.__drawdownCombo.itemText(index) == "": return None else: return self.__drawdownLayers[index] def pipeDiam(self): """ To get the selected pipe diameter :return: selected pipe diameter, or none """ if self.__pipeDiamCombo is None: return None index = self.__pipeDiamCombo.currentIndex() if self.__pipeDiamCombo.itemText(index) == "": return None else: return self.__pipeDiamFields[index] def controlConfigTable(self): """ To get the selected config table :return: selected config table, or none """ if self.__controlTableCombo is None: return None index = self.__controlTableCombo.currentIndex() if self.__controlTableCombo.itemText(index) == "": return None else: return self.__tables[index] def importConfigTable(self): """ To get the selected config table :return: selected config table, or none """ if self.__importTableCombo is None: return None index = self.__importTableCombo.currentIndex() if self.__importTableCombo.itemText(index) == "": return None else: return self.__tables[index] def controlUriDb(self): """ To get selected import database uri :return: import database uri """ if self.__controlDbCombo is None: return None index = self.__controlDbCombo.currentIndex() if self.__controlDbCombo.itemText(index) == "": return None else: return self.__dbs[list(self.__dbs.keys())[index]] def importUriDb(self): """ To get selected import database uri :return: import database uri """ if self.__importDbCombo is None: return None index = self.__importDbCombo.currentIndex() if self.__importDbCombo.itemText(index) == "": return None else: return self.__dbs[list(self.__dbs.keys())[index]] def controlSchemaDb(self): """ To get selected import database schema :return: import database schema """ if self.__controlSchemaCombo is None: return None index = self.__controlSchemaCombo.currentIndex() if self.__controlSchemaCombo.itemText(index) == "": return None else: return self.__schemas[index] def importSchemaDb(self): """ To get selected import database schema :return: import database schema """ if self.__importSchemaCombo is None: return None index = self.__importSchemaCombo.currentIndex() if self.__importSchemaCombo.itemText(index) == "": return None else: return self.__schemas[index] def mntUrl(self): """ To get selected MN url :return: MN url """ return self.__mntText.text()
class DownloaderWindow(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.DownloadPath = os.path.expanduser("~") # get home dir self.pool = QThreadPool() self.pool.setMaxThreadCount(1) self.initVariables() self.resize(700, 400) self.initUI() self.line_downpath.setText(self.down_control.getDownloadPath()) def initVariables(self): self.down_control = DownloadController(self.addInfo) self.down_control.setDownloadPath(self.DownloadPath) self.chapters = None self.chapters_filtered = None self.ch_from = None self.ch_to = None def initUI(self): cw = QWidget() self.setCentralWidget(cw) layout_main = QVBoxLayout() layout_main.setSpacing(5) ## Info self.info = QTextEdit() self.info.setReadOnly(True) self.info.setLineWrapMode(QTextEdit.NoWrap) layout_main.addWidget(self.info, 1) ## Line edit layout_url = QHBoxLayout() layout_url.setSpacing(5) self.line_url = QLineEdit() layout_url.addWidget(QLabel('<b>Series URL:</b>')) layout_url.addWidget(self.line_url, 1) layout_main.addLayout(layout_url) ## Comboboxes layout_combo = QHBoxLayout() layout_combo.setSpacing(5) self.combo_from = QComboBox() self.combo_from.setEnabled(False) self.combo_to = QComboBox() self.combo_to.setEnabled(False) layout_combo.addWidget(QLabel('<b>Download chapters: </b>')) layout_combo.addWidget(QLabel(' From:')) layout_combo.addWidget(self.combo_from, 1) layout_combo.addWidget(QLabel('To:')) layout_combo.addWidget(self.combo_to, 1) layout_main.addLayout(layout_combo) ## Download path layout_downpath = QHBoxLayout() layout_downpath.setSpacing(5) self.line_downpath = QLineEdit() self.line_downpath.setEnabled(False) self.btn_downpath = QPushButton('Change') self.btn_downpath.pressed.connect(self.selectDownloadPath) layout_downpath.addWidget(QLabel('<b>Download path:</b>')) layout_downpath.addWidget(self.line_downpath, 1) layout_downpath.addWidget(self.btn_downpath) layout_main.addLayout(layout_downpath) ## Buttons layout_btn = QHBoxLayout() layout_btn.setSpacing(5) self.btn_getlist = QPushButton('Get List of Chapters') self.btn_getlist.pressed.connect(self.getChaptersList) self.btn_download = QPushButton('Download chapters') self.btn_download.pressed.connect(self.downloadChapters) self.btn_download.setEnabled(False) self.btn_exit = QPushButton('Exit') self.btn_exit.pressed.connect(self.close) layout_btn.addStretch() layout_btn.addWidget(self.btn_getlist) layout_btn.addWidget(self.btn_download) layout_btn.addWidget(self.btn_exit) layout_btn.addStretch() layout_main.addLayout(layout_btn) # status bar self.statusBar().showMessage('Ready') # add layout to main window cw.setLayout(layout_main) self.setWindowTitle('OMAD - Online MAnga Downloader') self.show() def closeEvent(self, event): """ Runs when user tryes to close main window. sys.exit(0) - to fix wierd bug, where process is not terminated. """ sys.exit(0) def addInfo(self, s='Testing printing...', exception=False, downloadProgress=False, trace=[]): logger.info(s+', '+str(exception)+', '+str(downloadProgress)+', '+str(trace)) if type(s)!=type("") and type(s)!=type(b"") and type(s) != type(QtCore.QString('')): s = str(s) if exception: s = "!!! Exception: "+s if downloadProgress: s = "Downloading progress: "+s self.setStatusBarText(s) self.info.append(s) if exception: for t in trace: self.info.append(str(t)) sb = self.info.verticalScrollBar() sb.setValue(sb.maximum()) QtCore.QCoreApplication.processEvents() def setStatusBarText(self, s='Testing...'): """ Changes status bar text """ self.statusBar().showMessage(s) QtCore.QCoreApplication.processEvents() def getChaptersList(self): self.addInfo('Getting list of chapters...') # reinit clean variables self.initVariables() # get series url url = str(self.line_url.text()).strip() if not self.down_control.setSeriesUrl(url): return # bad url self.chapters = self.down_control.getChaptersList() logger.debug('Setting up comboBoxes...') for i in range(0, self.combo_from.count()): self.combo_from.removeItem(0) for i in range(0, self.combo_to.count()): self.combo_to.removeItem(0) for c in self.chapters: self.combo_from.addItem(c[0]) self.combo_to.addItem(c[0]) self.combo_from.setCurrentIndex(0) self.combo_to.setCurrentIndex(len(self.chapters)-1) self.addInfo('Chapter list loaded') self.combo_from.setEnabled(True) self.combo_to.setEnabled(True) self.btn_download.setEnabled(True) def downloadChapters(self): self.addInfo('Checking chapter range') self.ch_from = self.combo_from.currentIndex() self.ch_to = self.combo_to.currentIndex() if self.ch_from>self.ch_to: self.addInfo('Bad range. Cant download backwards!') return else: self.addInfo('Range OK, starting download of '+str((self.ch_to-self.ch_from)+1)+' chapters...') self.gui_disable(True) worker = DownloadWorker(self.down_control, self.ch_from, self.ch_to) worker.signals.update.connect(self.addInfo) worker.signals.finished.connect(self.downloadChapters_finished) self.pool.start(worker) def downloadChapters_finished(self): self.gui_disable(False) self.setStatusBarText('Ready - Download Finished!!') # Finished self.addInfo('Download Finished!!') # Print failed downloads failed_chs = [] for i, r in enumerate(self.down_control.results): if r is False: failed_chs.append(self.chapters[i+self.ch_from]) if len(failed_chs)==0: self.addInfo('\nNo failed downloads') else: self.addInfo('\nChapters with failed downloads:') for c in failed_chs: self.addInfo(c[0]) self.addInfo('') def selectDownloadPath(self): downdir = self._get_dir(directory=self.DownloadPath) self.down_control.setDownloadPath(downdir) self.DownloadPath = self.down_control.getDownloadPath() self.line_downpath.setText(self.DownloadPath) def _get_dir(self, directory=''): """ Draw a dialog for directory selection. """ downdir = QFileDialog.getExistingDirectory( caption='Select Folder', options=QFileDialog.ShowDirsOnly, directory=directory ) if len(downdir) > 0: downdir = "%s" % (downdir) else: downdir = directory return downdir def gui_disable(self, downloading=True): self.line_url.setEnabled(not downloading) self.combo_from.setEnabled(not downloading) self.combo_to.setEnabled(not downloading) self.btn_getlist.setEnabled(not downloading) self.btn_download.setEnabled(not downloading) self.btn_downpath.setEnabled(not downloading)
class OWFile(OWWidget): settingsList = ["selected_file", "recent_files", "show_advanced", "create_new_on"] contextHandlers = {"": FileNameContextHandler()} def __init__(self, parent=None, signalManager=None, title="CSV File Import"): OWWidget.__init__(self, parent, signalManager, title, wantMainArea=False, noReport=True) self.symbol_DC = "" self.symbol_DK = "" #: List of recent opened files. self.recent_files = [] #: Current selected file name self.selected_file = None #: Variable reuse flag self.create_new_on = 2 #: Display advanced var reuse options self.show_advanced = False self.loadSettings() self.recent_files = filter(os.path.exists, self.recent_files) self._loader = None self._invalidated = False self._datareport = None layout = QHBoxLayout() OWGUI.widgetBox(self.controlArea, "File", orientation=layout) icons = standard_icons(self) self.recent_combo = QComboBox( self, objectName="recent_combo", toolTip="Recent files.", activated=self.activate_recent ) cb_append_file_list(self.recent_combo, self.recent_files) self.recent_combo.insertSeparator(self.recent_combo.count()) self.recent_combo.addItem(u"Browse documentation data sets…") self.browse_button = QPushButton( u"…", icon=icons.dir_open_icon, toolTip="Browse filesystem", clicked=self.browse ) self.reload_button = QPushButton( "Reload", icon=icons.reload_icon, toolTip="Reload the selected file", clicked=self.reload, default=True ) layout.addWidget(self.recent_combo, 2) layout.addWidget(self.browse_button) layout.addWidget(self.reload_button) ########### # Info text ########### box = OWGUI.widgetBox(self.controlArea, "Info", addSpace=True) self.infoa = OWGUI.widgetLabel(box, "No data loaded.") self.infob = OWGUI.widgetLabel(box, " ") self.warnings = OWGUI.widgetLabel(box, " ") # Set word wrap so long warnings won't expand the widget self.warnings.setWordWrap(True) self.warnings.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.MinimumExpanding) advanced = QGroupBox( "Advanced Settings", checkable=True, checked=self.show_advanced ) advanced.setLayout(QVBoxLayout()) def set_group_visible(groupbox, state): layout = groupbox.layout() for i in range(layout.count()): item = layout.itemAt(i) widget = item.widget() if widget is not None: widget.setVisible(state) groupbox.setFlat(not state) def toogle_advanced(state): self.show_advanced = state set_group_visible(advanced, state) self.layout().activate() QApplication.instance().processEvents() QTimer.singleShot(0, self.adjustSize) advanced.toggled.connect(toogle_advanced) self.taboptions = QWidget() self.taboptions.setLayout(QVBoxLayout()) box = QGroupBox("Missing Value Symbols", flat=True) form = QFormLayout(fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow) form.addRow( "Don't care:", OWGUI.lineEdit(None, self, "symbol_DC", tooltip="Default values: '~' or '*'")) form.addRow( "Don't know:", OWGUI.lineEdit(None, self, "symbol_DK", tooltip="Default values: empty fields (space), " "'?' or 'NA'")) box.setLayout(form) advanced.layout().addWidget(box) rb = OWGUI.radioButtonsInBox( advanced, self, "create_new_on", box="New Attributes", callback=self._invalidate, label=u"Create a new attribute when existing attribute(s) …", btnLabels=[u"Have mismatching order of values", u"Have no common values with the new (recommended)", u"Miss some values of the new attribute", u"… Always create a new attribute"] ) rb.setFlat(True) self.controlArea.layout().addWidget(advanced) button_box = QDialogButtonBox(orientation=Qt.Horizontal) self.import_options_button = QPushButton( u"Import Options…", enabled=False ) self.import_options_button.pressed.connect(self._activate_import_dialog) button_box.addButton( self.import_options_button, QDialogButtonBox.ActionRole ) button_box.addButton( QPushButton("&Report", pressed=self.reportAndFinish), QDialogButtonBox.ActionRole ) self.controlArea.layout().addWidget(button_box) OWGUI.rubber(self.controlArea) set_group_visible(advanced, self.show_advanced) if self.recent_files and self.recent_files[0] == self.selected_file: QTimer.singleShot( 0, lambda: self.activate_recent(0) ) else: self.selected_file = None self.recent_combo.setCurrentIndex(-1) @Slot(int) def activate_recent(self, index): """Activate an item from the recent list.""" if 0 <= index < len(self.recent_files): recent = self.recent_files[index] self.set_selected_file(recent) elif index == len(self.recent_files) + 1: status = self.browse(Orange.utils.environ.dataset_install_dir) if status == QDialog.Rejected: self.recent_combo.setCurrentIndex( min(0, len(self.recent_files) - 1) ) else: self.recent_combo.setCurrentIndex(-1) @Slot() def browse(self, startdir=None): """ Open a file dialog and select a user specified file. """ if startdir is None: if self.selected_file: startdir = os.path.dirname(self.selected_file) else: startdir = unicode( QDesktopServices.storageLocation( QDesktopServices.DocumentsLocation) ) def format_spec(format): ext_pattern = ", ".join(map("*{}".format, format.extensions)) return "{} ({})".format(format.name, ext_pattern) formats = [format_spec(format) for format in FILEFORMATS] filters = ";;".join(formats + ["All files (*.*)"]) path, selected_filter = QFileDialog.getOpenFileNameAndFilter( self, "Open Data File", startdir, filters ) if path: path = unicode(path) if selected_filter in formats: filter_idx = formats.index(str(selected_filter)) fformat = FILEFORMATS[filter_idx] loader = DEFAULT_ACTIONS[filter_idx] if fformat.extensions in ([".csv"], [".tsv"]): loader = loader._replace( params=loader_for_path(path).params) else: loader = None self.set_selected_file(path, loader=loader) return QDialog.Accepted else: return QDialog.Rejected @Slot() def reload(self): """Reload the current selected file.""" if self.selected_file: self.send_data() def _activate_import_dialog(self): assert self.selected_file is not None dlg = CSVImportDialog( self, windowTitle="Import Options", ) dlg.setAttribute(Qt.WA_DeleteOnClose) dlg.setWindowFlags(Qt.Sheet) loader = self._loader dlg.set_options(loader.params) dlg.set_path(self.selected_file) def update(): self._loader = loader._replace(params=dlg.options()) self._invalidate() dlg.accepted.connect(update) dlg.open() def set_selected_file(self, filename, loader=None): """Set the current filename path to be loaded.""" self.closeContext("") self.selected_file = filename self._loader = None self._add_recent(filename) self.warning(1) self.openContext("", filename) if loader is not None and self._loader is not None and \ self._loader.format == loader.format: loader = self._loader if loader is None: loader = self._loader if loader is None: loader = loader_for_path(filename) self.set_loader(loader) def _add_recent(self, filename): """Add filename to the list of recent files.""" index_to_remove = None if filename in self.recent_files: index_to_remove = self.recent_files.index(filename) elif len(self.recent_files) >= 20: # keep maximum of 20 files in the list. index_to_remove = len(self.recent_files) - 1 cb_insert_file_list(self.recent_combo, 0, [filename]) self.recent_files.insert(0, filename) if index_to_remove is not None: self.recent_combo.removeItem(index_to_remove + 1) self.recent_files.pop(index_to_remove + 1) self.recent_combo.setCurrentIndex(0) def set_loader(self, loader): if loader is None: loader = DEFAULT_ACTIONS[0] self._loader = loader self.import_options_button.setEnabled( isinstance(loader.params, CSV) ) self._invalidate() def _invalidate(self): if not self._invalidated: self._invalidated = True QApplication.postEvent(self, QEvent(QEvent.User)) def customEvent(self, event): if self._invalidated: self._invalidated = False self.send_data() def send_data(self): self.error(0) loader = self._loader if "DK" in loader.params._fields and self.symbol_DK: loader = loader._replace( params=loader.params._replace( DK=str(self.symbol_DK), DC=str(self.symbol_DC)) ) try: data = load_table(self.selected_file, loader, create_new_on=3 - self.create_new_on) except Exception as err: self.error(str(err)) self.infoa.setText('Data was not loaded due to an error.') self.infob.setText('Error:') self.warnings.setText(str(err)) data = None else: self._update_status_messages(data) if data is not None: add_origin(data, self.selected_file) basename = os.path.basename(self.selected_file) data.name, _ = os.path.splitext(basename) self._datareport = self.prepareDataReport(data) else: self._datareport = None self.send("Data", data) def _update_status_messages(self, data): if data is None: self.infoa.setText("No data loaded.") self.infob.setText("") self.warnings.setText("") return def pluralize(seq): return "s" if len(seq) != 1 else "" summary = ("{n_instances} data instance{plural_1}, " "{n_features} feature{plural_2}, " "{n_meta} meta{plural_3}").format( n_instances=len(data), plural_1=pluralize(data), n_features=len(data.domain.attributes), plural_2=pluralize(data.domain.attributes), n_meta=len(data.domain.getmetas()), plural_3=pluralize(data.domain.getmetas())) self.infoa.setText(summary) cl = data.domain.class_var if cl is not None: if isinstance(cl, Orange.feature.Continuous): self.infob.setText('Regression; Numerical class.') elif isinstance(cl, Orange.feature.Discrete): self.infob.setText( 'Classification; Discrete class with %d value%s.' % (len(cl.values), 's' if len(cl.values) > 1 else '') ) else: self.infob.setText("Class is neither discrete nor continuous.") elif data.domain.class_vars: self.infob.setText("Multiple class variables") else: self.infob.setText("Data has no dependent variable.") self.warnings.setText( feature_load_status_report(data, self.create_new_on)) def sendReport(self): if self._datareport: formatname = self._loader.format self.reportSettings( "File", [("File name", self.selected_file), ("Format", formatname)]) self.reportData(self._datareport) def settingsFromWidgetCallback(self, handler, context): context.filename = self.selected_file or "" context.loader = self._loader context.symbolDC, context.symbolDK = self.symbol_DC, self.symbol_DK def settingsToWidgetCallback(self, handler, context): self.symbol_DC, self.symbol_DK = context.symbolDC, context.symbolDK self._loader = getattr(context, "loader", None) def setSettings(self, settings): if settings.get(_SETTINGS_VERSION_KEY, None) is None: # import old File widget's settings mapping = [ ("recentFiles", "recent_files"), ("createNewOn", "create_new_on"), ("showAdvanced", "show_advanced") ] if all(old in settings for old, _ in mapping) and \ not any(new in settings for _, new in mapping): settings = settings.copy() for old, new in mapping: settings[new] = settings[old] del settings[old] # settings[_SETTINGS_VERSION_KEY] = self.settingsDataVersion if len(settings["recent_files"]): settings["selected_file"] = settings["recent_files"][0] super(OWFile, self).setSettings(settings)
class LayerSelectionPage(QFrame): #TODO. Filtering, (visible) row selection, multi selection colparams = ((0,65,'Name'), (1,235,'Title'), (2,350,'Keywords')) XFER_BW = 40 def __init__(self, parent=None): super(LayerSelectionPage, self).__init__(parent) self.parent = parent #convenience link self.confconn_link = self.parent.parent.confconn #flag top prevent read read action on keyword delete. New logic makes this redundant #self.keywordbypass = False QToolTip.setFont(QFont('SansSerif', 10)) #label filterlabel = QLabel('Filter') availablelabel = QLabel('Available Layers') selectionlabel = QLabel('Layer Selections') keywordlabel = QLabel('Keyword') explainlabel = QLabel("Edit Group assignments using this dialog or to simply initialise the Layer-Config just click 'Finish'") #selection buttons chooseallbutton = QPushButton('>>') chooseallbutton.setFixedWidth(self.XFER_BW) chooseallbutton.clicked.connect(self.doChooseAllClickAction) choosebutton = QPushButton('>') choosebutton.setFixedWidth(self.XFER_BW) choosebutton.clicked.connect(self.doChooseClickAction) rejectbutton = QPushButton('<') rejectbutton.setFixedWidth(self.XFER_BW) rejectbutton.clicked.connect(self.doRejectClickAction) rejectallbutton = QPushButton('<<') rejectallbutton.setFixedWidth(self.XFER_BW) rejectallbutton.clicked.connect(self.doRejectAllClickAction) #operation buttons finishbutton = QPushButton('Finish') finishbutton.setToolTip('Finish and Close layer selection dialog') finishbutton.clicked.connect(self.parent.close) resetbutton = QPushButton('Reset') resetbutton.font() resetbutton.setToolTip('Read Layer from LDS GetCapabilities request. Overwrites current Layer Config') resetbutton.clicked.connect(self.doResetClickAction) self.available_sfpm = LDSSFPAvailableModel(self) self.selection_sfpm = LDSSFPSelectionModel(self) self.available_sfpm.setSourceModel(self.parent.available_model) self.selection_sfpm.setSourceModel(self.parent.selection_model) #textedits filteredit = QLineEdit('') filteredit.setToolTip('Filter Available-Layers pane (filter operates across Name and Title fields and accepts Regex expressions)') filteredit.textChanged.connect(self.available_sfpm.setActiveFilter) self.keywordcombo = QComboBox() self.keywordcombo.setToolTip('Select or Add a unique identifier to be saved in layer config (keyword)') self.keywordcombo.addItems(list(self.confconn_link.assigned)) self.keywordcombo.setEditable(True) self.keywordcombo.activated.connect(self.doKeyComboChangeAction) lgindex = self.confconn_link.getLayerGroupIndex(self.confconn_link.lgval,col=1) lgentry = self.confconn_link.lglist[lgindex] if LU.assessNone(lgindex) else None #keywordedit = self.keywordcombo.lineEdit().text().toUtf8().data().decode('utf8')# for writing #if no entry or layer indicated then blank self.keywordcombo.lineEdit().setText('' if lgentry is None or lgentry[0]==LORG.LAYER else lgentry[1])#self.confconn_link.lgval)#TODO. group only #header headmodel = QStandardItemModel() headmodel.setHorizontalHeaderLabels([i[2] for i in self.colparams][:self.parent.available_model.columnCount()]) headview1 = QHeaderView(Qt.Horizontal) headview1.setModel(headmodel) headview1.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) headview2 = QHeaderView(Qt.Horizontal) headview2.setModel(headmodel) headview2.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) #table self.available = QTableView() self.available.setSelectionBehavior(QAbstractItemView.SelectRows) self.available.setSelectionMode(QAbstractItemView.MultiSelection) self.selection = QTableView() self.selection.setSelectionBehavior(QAbstractItemView.SelectRows) self.selection.setSelectionMode(QAbstractItemView.MultiSelection) #interesting, must set model after selection attributes but before headers else row selections/headers don't work properly self.available.setModel(self.available_sfpm) self.selection.setModel(self.selection_sfpm) self.available.setSortingEnabled(True) self.available.setHorizontalHeader(headview1) self.selection.setSortingEnabled(True) self.selection.setHorizontalHeader(headview2) for cp in self.colparams: self.available.setColumnWidth(cp[0],cp[1]) self.selection.setColumnWidth(cp[0],cp[1]) self.available.verticalHeader().setVisible(False) self.available.horizontalHeader().setVisible(True) self.selection.verticalHeader().setVisible(False) self.selection.horizontalHeader().setVisible(True) #layout vbox00 = QVBoxLayout() vbox00.addWidget(availablelabel) vbox00.addWidget(self.available) vbox01 = QVBoxLayout() vbox01.addWidget(chooseallbutton) vbox01.addWidget(choosebutton) vbox01.addWidget(rejectbutton) vbox01.addWidget(rejectallbutton) vbox02 = QVBoxLayout() vbox02.addWidget(selectionlabel) vbox02.addWidget(self.selection) vbox10 = QVBoxLayout() vbox10.addWidget(filterlabel) vbox10.addWidget(filteredit) hbox12 = QHBoxLayout() hbox12.addWidget(keywordlabel) hbox12.addStretch(1) #hbox12.addWidget(inspbutton) #hbox12.addWidget(addbutton) #hbox12.addWidget(delbutton) vbox12 = QVBoxLayout() vbox12.addLayout(hbox12) vbox12.addWidget(self.keywordcombo) #00|01|02 #10|11|12 grid0 = QGridLayout() grid0.addLayout(vbox00,1,0) grid0.addLayout(vbox01,1,1) grid0.addLayout(vbox02,1,2) grid0.addLayout(vbox10,0,0) grid0.addLayout(vbox12,0,2) hbox2 = QHBoxLayout() hbox2.addWidget(resetbutton) hbox2.addStretch(1) hbox2.addWidget(explainlabel) hbox2.addWidget(finishbutton) #gbox1.setLayout(hbox2) vbox3 = QVBoxLayout() vbox3.addLayout(grid0) #vbox3.addLayout(hbox3) #vbox3.addWidget(line0) vbox3.addLayout(hbox2) self.setLayout(vbox3) def doChooseAllClickAction(self): '''Moves the lot to Selected''' #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text())) if not self.checkKeyword(ktext): return #------------------------------ self.parent.signalModels(self.parent.STEP.PRE) #self.parent.selection_model.mdata += self.parent.available_model.mdata self.parent.selection_model.initData(self.confconn_link.complete) self.parent.available_model.initData([]) self.parent.signalModels(self.parent.STEP.POST) #------------------------------ self.parent.writeKeysToLayerConfig(ktext) #self.confconn_link.setupAssignedLayerList() if self.keywordcombo.findText(ktext) == -1: self.keywordcombo.addItem(ktext) def doChooseClickAction(self): '''Takes available selected and moves to selection''' #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text())) #ktext = str(self.keywordcombo.lineEdit().text()) if not self.checkKeyword(ktext): return #------------------------------ select = self.available.selectionModel() if select.hasSelection(): self.transferSelectedRows(select.selectedRows(),self.available_sfpm,self.selection_sfpm) #------------------------------ self.parent.writeKeysToLayerConfig(ktext) #self.confconn_link.assigned = self.confconn_link.setupAssignedLayerList() # -1 to indicate no index since 0,1,... are valid if self.keywordcombo.findText(ktext) == -1: self.keywordcombo.addItem(ktext) else: ldslog.warn('L2R > Transfer action without selection') #TRACE# #pdb.set_trace() self.available.clearSelection() def transferSelectedRows(self,indices,from_model,to_model): tlist = [] for proxymodelindex in indices: transfer = from_model.getData(proxymodelindex) tlist.append((proxymodelindex,transfer),) to_model.addData([t[1] for t in tlist]) from_model.delData([t[0] for t in tlist]) return tlist def doRejectClickAction(self): '''Takes available selected and moves to selection''' #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text())) if not self.checkKeyword(ktext): return #------------------------------ select = self.selection.selectionModel() if select.hasSelection(): tlist = self.transferSelectedRows(select.selectedRows(),self.selection_sfpm,self.available_sfpm) #------------------------------ kindex = self.keywordcombo.findText(ktext) remainder = self.parent.deleteKeysFromLayerConfig([ll[1][0] for ll in tlist],ktext) if remainder > 0 and kindex == -1: #items+newkey -> add self.parent.writeKeysToLayerConfig(ktext) self.keywordcombo.addItem(ktext) elif remainder == 0 and kindex > -1: #empty+oldkey -> del self.keywordcombo.removeItem(kindex) self.keywordcombo.clearEditText() else: ldslog.warn('R2L < Transfer action without selection') #TRACE# #pdb.set_trace() self.selection.clearSelection() def doRejectAllClickAction(self): #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text())) if not self.checkKeyword(ktext): return #------------------------------ self.parent.deleteKeysFromLayerConfig([ll[0] for ll in self.parent.selection_model.mdata],ktext) #------------------------------ self.parent.signalModels(self.parent.STEP.PRE) #self.parent.available_model.mdata += self.parent.selection_model.mdata self.parent.available_model.initData(self.confconn_link.complete) self.parent.selection_model.initData([]) self.parent.signalModels(self.parent.STEP.POST) #------------------------------ #self.confconn_link.setupAssignedLayerList() #self.keywordbypass = True self.keywordcombo.removeItem(self.keywordcombo.findText(ktext)) self.keywordcombo.clearEditText() def doKeyComboChangeAction(self): '''Reset the available pane and if there is anything in the keyword box use this to init the selection pane''' #HACK #if self.keywordbypass: # self.keywordbypass = False # return #------------------------------ #ktext = LU.recode(self.keywordcombo.lineEdit().text().toUtf8().data()) ktext = LU.recode(LQ.readWidgetText(self.keywordcombo.lineEdit().text())) #------------------------------ av_sl = self.parent.splitData(ktext,self.confconn_link.complete) #av_sl = self.parent.splitData(ktext,self.confconn_link.complete) self.parent.signalModels(self.parent.STEP.PRE) self.parent.available_model.initData(av_sl[0]) self.parent.selection_model.initData(av_sl[1]) self.parent.signalModels(self.parent.STEP.POST) def doResetClickAction(self): '''Dumps the LC and rebuilds from a fresh read of the caps doc''' #int warning (QWidget parent, QString title, QString text, QString button0Text, QString button1Text = QString(), QString button2Text = QString(), int defaultButtonNumber = 0, int escapeButtonNumber = -1) ans = QMessageBox.warning(self, "Reset","This action will overwrite your Layer Configuration using the current LDS settings (potentially adding new or removing layers). Continue?","Continue","Cancel") if ans: #Cancel ldslog.warn('Cancelling Reset operation') return #Continue ldslog.warn('Reset Layer Config') self.parent.resetLayers() self.keywordcombo.clear() def checkKeyword(self,ktext): '''Checks keyword isn't null and isn't part of the LDS supplied keywords''' if LU.assessNone(ktext) is None: QMessageBox.about(self, "Keyword Required","Please enter a Keyword to assign Layer(s) to") return False if ktext in self.confconn_link.reserved: QMessageBox.about(self, "Reserved Keyword","'{}' is a reserved keyword, please select again".format(ktext)) return False return True
class ActionBar(QFrame): """ SIGNALS: @changeCurrent(PyQt_PyObject) @runFile(QString) @reopenTab(QString) @recentTabsModified() """ def __init__(self, main_combo=False): super(ActionBar, self).__init__() self.setObjectName("actionbar") hbox = QHBoxLayout(self) hbox.setContentsMargins(1, 1, 1, 1) hbox.setSpacing(1) self.lbl_checks = QLabel('') self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.lbl_checks.setFixedWidth(48) self.lbl_checks.setVisible(False) hbox.addWidget(self.lbl_checks) self.combo = QComboBox() #model = QStandardItemModel() #self.combo.setModel(model) #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove) self.combo.setMaximumWidth(300) self.combo.setObjectName("combotab") self.connect(self.combo, SIGNAL("currentIndexChanged(int)"), self.current_changed) self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP) self.combo.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.combo, SIGNAL("customContextMenuRequested(const QPoint &)"), self._context_menu_requested) hbox.addWidget(self.combo) self.symbols_combo = QComboBox() self.symbols_combo.setObjectName("combo_symbols") self.connect(self.symbols_combo, SIGNAL("activated(int)"), self.current_symbol_changed) hbox.addWidget(self.symbols_combo) self.code_navigator = CodeNavigator() hbox.addWidget(self.code_navigator) self._pos_text = "Line: %d, Col: %d" self.lbl_position = QLabel(self._pos_text % (0, 0)) self.lbl_position.setObjectName("position") self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.lbl_position) self.btn_close = QPushButton( self.style().standardIcon(QStyle.SP_DialogCloseButton), '') if main_combo: self.btn_close.setObjectName('navigation_button') self.btn_close.setToolTip(translations.TR_CLOSE_FILE) self.connect(self.btn_close, SIGNAL("clicked()"), self.about_to_close_file) else: self.btn_close.setObjectName('close_split') self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT) self.connect(self.btn_close, SIGNAL("clicked()"), self.close_split) self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.btn_close) def resizeEvent(self, event): super(ActionBar, self).resizeEvent(event) if event.size().width() < 350: self.symbols_combo.hide() self.code_navigator.hide() self.lbl_position.hide() else: self.symbols_combo.show() self.code_navigator.show() self.lbl_position.show() def add_item(self, text, neditable): """Add a new item to the combo and add the neditable data.""" self.combo.addItem(text, neditable) self.combo.setCurrentIndex(self.combo.count() - 1) def get_editables(self): editables = [] for index in range(self.combo.count()): neditable = self.combo.itemData(index) editables.append(neditable) return editables def add_symbols(self, symbols): """Add the symbols to the symbols's combo.""" self.symbols_combo.clear() for symbol in symbols: data = symbol[1] if data[1] == 'f': icon = QIcon(":img/function") else: icon = QIcon(":img/class") self.symbols_combo.addItem(icon, data[0]) def set_current_symbol(self, index): self.symbols_combo.setCurrentIndex(index) def update_item_icon(self, neditable, icon): index = self.combo.findData(neditable) self.combo.setItemIcon(index, icon) def update_item_text(self, neditable, text): index = self.combo.findData(neditable) self.combo.setItemText(index, text) def current_changed(self, index): """Change the current item in the combo.""" neditable = self.combo.itemData(index) self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable, index) def current_symbol_changed(self, index): """Change the current symbol in the combo.""" self.emit(SIGNAL("goToSymbol(int)"), index) def update_line_col(self, line, col): """Update the line and column position.""" self.lbl_position.setText(self._pos_text % (line, col)) def _context_menu_requested(self, point): """Display context menu for the combo file.""" if self.combo.count() == 0: # If there is not an Editor opened, don't show the menu return menu = QMenu() actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT) actionRun = menu.addAction(translations.TR_RUN_FILE) menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX) self._create_menu_syntax(menuSyntax) menu.addSeparator() actionClose = menu.addAction(translations.TR_CLOSE_FILE) actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES) actionCloseAllNotThis = menu.addAction( translations.TR_CLOSE_OTHER_FILES) menu.addSeparator() actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY) actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY) menu.addSeparator() actionCopyPath = menu.addAction( translations.TR_COPY_FILE_PATH_TO_CLIPBOARD) actionReopen = menu.addAction(translations.TR_REOPEN_FILE) actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR) if len(settings.LAST_OPENED_FILES) == 0: actionReopen.setEnabled(False) #Connect actions self.connect(actionSplitH, SIGNAL("triggered()"), lambda: self._split(False)) self.connect(actionSplitV, SIGNAL("triggered()"), lambda: self._split(True)) self.connect(actionRun, SIGNAL("triggered()"), self._run_this_file) self.connect(actionAdd, SIGNAL("triggered()"), self._add_to_project) self.connect(actionClose, SIGNAL("triggered()"), self.about_to_close_file) self.connect(actionCloseAllNotThis, SIGNAL("triggered()"), self._close_all_files_except_this) self.connect(actionCloseAll, SIGNAL("triggered()"), self._close_all_files) self.connect(actionCopyPath, SIGNAL("triggered()"), self._copy_file_location) self.connect(actionReopen, SIGNAL("triggered()"), self._reopen_last_tab) self.connect(actionUndock, SIGNAL("triggered()"), self._undock_editor) menu.exec_(QCursor.pos()) def _create_menu_syntax(self, menuSyntax): """Create Menu with the list of syntax supported.""" syntax = list(settings.SYNTAX.keys()) syntax.sort() for syn in syntax: menuSyntax.addAction(syn) self.connect(menuSyntax, SIGNAL("triggered(QAction*)"), self._reapply_syntax) def _reapply_syntax(self, syntaxAction): #TODO if [self.currentIndex(), syntaxAction] != self._resyntax: self._resyntax = [self.currentIndex(), syntaxAction] self.emit(SIGNAL("syntaxChanged(QWidget, QString)"), self.currentWidget(), syntaxAction.text()) def set_current_file(self, neditable): index = self.combo.findData(neditable) self.combo.setCurrentIndex(index) def set_current_by_index(self, index): self.combo.setCurrentIndex(index) def about_to_close_file(self, index=None): """Close the NFile object.""" if index is None: index = self.combo.currentIndex() neditable = self.combo.itemData(index) if neditable: neditable.nfile.close() def close_split(self): self.emit(SIGNAL("closeSplit()")) def close_file(self, neditable): """Receive the confirmation to close the file.""" index = self.combo.findData(neditable) self.combo.removeItem(index) return index def _run_this_file(self): """Execute the current file.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("runFile(QString)"), neditable.file_path) def _add_to_project(self): """Emit a signal to let someone handle the inclusion of the file inside a project.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("addToProject(QString)"), neditable.file_path) def _reopen_last_tab(self): self.emit(SIGNAL("reopenTab(QString)"), settings.LAST_OPENED_FILES.pop()) self.emit(SIGNAL("recentTabsModified()")) def _undock_editor(self): self.emit(SIGNAL("undockEditor()")) def _split(self, orientation): self.emit(SIGNAL("splitEditor(bool)"), orientation) def _copy_file_location(self): """Copy the path of the current opened file to the clipboard.""" neditable = self.combo.itemData(self.combo.currentIndex()) QApplication.clipboard().setText(neditable.file_path, QClipboard.Clipboard) def _close_all_files(self): """Close all the files opened.""" for i in range(self.combo.count()): self.about_to_close_file(0) def _close_all_files_except_this(self): """Close all the files except the current one.""" neditable = self.combo.itemData(self.combo.currentIndex()) for i in reversed(list(range(self.combo.count()))): ne = self.combo.itemData(i) if ne is not neditable: self.about_to_close_file(i)
class OWFile(OWWidget): settingsList = [ "selected_file", "recent_files", "show_advanced", "create_new_on" ] contextHandlers = {"": FileNameContextHandler()} def __init__(self, parent=None, signalManager=None, title="CSV File Import"): OWWidget.__init__(self, parent, signalManager, title, wantMainArea=False, noReport=True) self.symbol_DC = "" self.symbol_DK = "" #: List of recent opened files. self.recent_files = [] #: Current selected file name self.selected_file = None #: Variable reuse flag self.create_new_on = 2 #: Display advanced var reuse options self.show_advanced = False self.loadSettings() self.recent_files = filter(os.path.exists, self.recent_files) self._loader = None self._invalidated = False self._datareport = None layout = QHBoxLayout() OWGUI.widgetBox(self.controlArea, "File", orientation=layout) icons = standard_icons(self) self.recent_combo = QComboBox(self, objectName="recent_combo", toolTip="Recent files.", activated=self.activate_recent) cb_append_file_list(self.recent_combo, self.recent_files) self.recent_combo.insertSeparator(self.recent_combo.count()) self.recent_combo.addItem(u"Browse documentation data sets…") self.browse_button = QPushButton(u"…", icon=icons.dir_open_icon, toolTip="Browse filesystem", clicked=self.browse) self.reload_button = QPushButton("Reload", icon=icons.reload_icon, toolTip="Reload the selected file", clicked=self.reload, default=True) layout.addWidget(self.recent_combo, 2) layout.addWidget(self.browse_button) layout.addWidget(self.reload_button) ########### # Info text ########### box = OWGUI.widgetBox(self.controlArea, "Info", addSpace=True) self.infoa = OWGUI.widgetLabel(box, "No data loaded.") self.infob = OWGUI.widgetLabel(box, " ") self.warnings = OWGUI.widgetLabel(box, " ") # Set word wrap so long warnings won't expand the widget self.warnings.setWordWrap(True) self.warnings.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.MinimumExpanding) advanced = QGroupBox("Advanced Settings", checkable=True, checked=self.show_advanced) advanced.setLayout(QVBoxLayout()) def set_group_visible(groupbox, state): layout = groupbox.layout() for i in range(layout.count()): item = layout.itemAt(i) widget = item.widget() if widget is not None: widget.setVisible(state) groupbox.setFlat(not state) def toogle_advanced(state): self.show_advanced = state set_group_visible(advanced, state) self.layout().activate() QApplication.instance().processEvents() QTimer.singleShot(0, self.adjustSize) advanced.toggled.connect(toogle_advanced) self.taboptions = QWidget() self.taboptions.setLayout(QVBoxLayout()) box = QGroupBox("Missing Value Symbols", flat=True) form = QFormLayout(fieldGrowthPolicy=QFormLayout.AllNonFixedFieldsGrow) form.addRow( "Don't care:", OWGUI.lineEdit(None, self, "symbol_DC", tooltip="Default values: '~' or '*'")) form.addRow( "Don't know:", OWGUI.lineEdit(None, self, "symbol_DK", tooltip="Default values: empty fields (space), " "'?' or 'NA'")) box.setLayout(form) advanced.layout().addWidget(box) rb = OWGUI.radioButtonsInBox( advanced, self, "create_new_on", box="New Attributes", callback=self._invalidate, label=u"Create a new attribute when existing attribute(s) …", btnLabels=[ u"Have mismatching order of values", u"Have no common values with the new (recommended)", u"Miss some values of the new attribute", u"… Always create a new attribute" ]) rb.setFlat(True) self.controlArea.layout().addWidget(advanced) button_box = QDialogButtonBox(orientation=Qt.Horizontal) self.import_options_button = QPushButton(u"Import Options…", enabled=False) self.import_options_button.pressed.connect( self._activate_import_dialog) button_box.addButton(self.import_options_button, QDialogButtonBox.ActionRole) button_box.addButton( QPushButton("&Report", pressed=self.reportAndFinish), QDialogButtonBox.ActionRole) self.controlArea.layout().addWidget(button_box) OWGUI.rubber(self.controlArea) set_group_visible(advanced, self.show_advanced) if self.recent_files and self.recent_files[0] == self.selected_file: QTimer.singleShot(0, lambda: self.activate_recent(0)) else: self.selected_file = None self.recent_combo.setCurrentIndex(-1) @Slot(int) def activate_recent(self, index): """Activate an item from the recent list.""" if 0 <= index < len(self.recent_files): recent = self.recent_files[index] self.set_selected_file(recent) elif index == len(self.recent_files) + 1: status = self.browse(Orange.utils.environ.dataset_install_dir) if status == QDialog.Rejected: self.recent_combo.setCurrentIndex( min(0, len(self.recent_files) - 1)) else: self.recent_combo.setCurrentIndex(-1) @Slot() def browse(self, startdir=None): """ Open a file dialog and select a user specified file. """ if startdir is None: if self.selected_file: startdir = os.path.dirname(self.selected_file) else: startdir = unicode( QDesktopServices.storageLocation( QDesktopServices.DocumentsLocation)) def format_spec(format): ext_pattern = ", ".join(map("*{}".format, format.extensions)) return "{} ({})".format(format.name, ext_pattern) formats = [format_spec(format) for format in FILEFORMATS] filters = ";;".join(formats + ["All files (*.*)"]) path, selected_filter = QFileDialog.getOpenFileNameAndFilter( self, "Open Data File", startdir, filters) if path: path = unicode(path) if selected_filter in formats: filter_idx = formats.index(str(selected_filter)) fformat = FILEFORMATS[filter_idx] loader = DEFAULT_ACTIONS[filter_idx] if fformat.extensions in ([".csv"], [".tsv"]): loader = loader._replace( params=loader_for_path(path).params) else: loader = None self.set_selected_file(path, loader=loader) return QDialog.Accepted else: return QDialog.Rejected @Slot() def reload(self): """Reload the current selected file.""" if self.selected_file: self.send_data() def _activate_import_dialog(self): assert self.selected_file is not None dlg = CSVImportDialog( self, windowTitle="Import Options", ) dlg.setAttribute(Qt.WA_DeleteOnClose) dlg.setWindowFlags(Qt.Sheet) loader = self._loader dlg.set_options(loader.params) dlg.set_path(self.selected_file) def update(): self._loader = loader._replace(params=dlg.options()) self._invalidate() dlg.accepted.connect(update) dlg.open() def set_selected_file(self, filename, loader=None): """Set the current filename path to be loaded.""" self.closeContext("") self.selected_file = filename self._loader = None self._add_recent(filename) self.warning(1) self.openContext("", filename) if loader is not None and self._loader is not None and \ self._loader.format == loader.format: loader = self._loader if loader is None: loader = self._loader if loader is None: loader = loader_for_path(filename) self.set_loader(loader) def _add_recent(self, filename): """Add filename to the list of recent files.""" index_to_remove = None if filename in self.recent_files: index_to_remove = self.recent_files.index(filename) elif len(self.recent_files) >= 20: # keep maximum of 20 files in the list. index_to_remove = len(self.recent_files) - 1 cb_insert_file_list(self.recent_combo, 0, [filename]) self.recent_files.insert(0, filename) if index_to_remove is not None: self.recent_combo.removeItem(index_to_remove + 1) self.recent_files.pop(index_to_remove + 1) self.recent_combo.setCurrentIndex(0) def set_loader(self, loader): if loader is None: loader = DEFAULT_ACTIONS[0] self._loader = loader self.import_options_button.setEnabled(isinstance(loader.params, CSV)) self._invalidate() def _invalidate(self): if not self._invalidated: self._invalidated = True QApplication.postEvent(self, QEvent(QEvent.User)) def customEvent(self, event): if self._invalidated: self._invalidated = False self.send_data() def send_data(self): self.error(0) loader = self._loader if "DK" in loader.params._fields and self.symbol_DK: loader = loader._replace(params=loader.params._replace( DK=str(self.symbol_DK), DC=str(self.symbol_DC))) try: data = load_table(self.selected_file, loader, create_new_on=3 - self.create_new_on) except Exception as err: self.error(str(err)) self.infoa.setText('Data was not loaded due to an error.') self.infob.setText('Error:') self.warnings.setText(str(err)) data = None else: self._update_status_messages(data) if data is not None: add_origin(data, self.selected_file) basename = os.path.basename(self.selected_file) data.name, _ = os.path.splitext(basename) self._datareport = self.prepareDataReport(data) else: self._datareport = None self.send("Data", data) def _update_status_messages(self, data): if data is None: self.infoa.setText("No data loaded.") self.infob.setText("") self.warnings.setText("") return def pluralize(seq): return "s" if len(seq) != 1 else "" summary = ("{n_instances} data instance{plural_1}, " "{n_features} feature{plural_2}, " "{n_meta} meta{plural_3}").format( n_instances=len(data), plural_1=pluralize(data), n_features=len(data.domain.attributes), plural_2=pluralize(data.domain.attributes), n_meta=len(data.domain.getmetas()), plural_3=pluralize(data.domain.getmetas())) self.infoa.setText(summary) cl = data.domain.class_var if cl is not None: if isinstance(cl, Orange.feature.Continuous): self.infob.setText('Regression; Numerical class.') elif isinstance(cl, Orange.feature.Discrete): self.infob.setText( 'Classification; Discrete class with %d value%s.' % (len(cl.values), 's' if len(cl.values) > 1 else '')) else: self.infob.setText("Class is neither discrete nor continuous.") elif data.domain.class_vars: self.infob.setText("Multiple class variables") else: self.infob.setText("Data has no dependent variable.") self.warnings.setText( feature_load_status_report(data, self.create_new_on)) def sendReport(self): if self._datareport: formatname = self._loader.format self.reportSettings("File", [("File name", self.selected_file), ("Format", formatname)]) self.reportData(self._datareport) def settingsFromWidgetCallback(self, handler, context): context.filename = self.selected_file or "" context.loader = self._loader context.symbolDC, context.symbolDK = self.symbol_DC, self.symbol_DK def settingsToWidgetCallback(self, handler, context): self.symbol_DC, self.symbol_DK = context.symbolDC, context.symbolDK self._loader = getattr(context, "loader", None) def setSettings(self, settings): if settings.get(_SETTINGS_VERSION_KEY, None) is None: # import old File widget's settings mapping = [("recentFiles", "recent_files"), ("createNewOn", "create_new_on"), ("showAdvanced", "show_advanced")] if all(old in settings for old, _ in mapping) and \ not any(new in settings for _, new in mapping): settings = settings.copy() for old, new in mapping: settings[new] = settings[old] del settings[old] # settings[_SETTINGS_VERSION_KEY] = self.settingsDataVersion if len(settings["recent_files"]): settings["selected_file"] = settings["recent_files"][0] super(OWFile, self).setSettings(settings)
class Window(QMainWindow): def __init__(self,parent = None): QMainWindow.__init__(self,parent) self.resize(1024,768) self.setWindowTitle("Sabel") self.setWindowIcon(Icons.sabel) self.centralwidget = QWidget(self) self.horizontalLayout = QHBoxLayout(self.centralwidget) self.horizontalLayout.setMargin(0) self.cmdList = config.cmds() self.paramList = config.params() '''A.Editor TabWidget''' '''This parent is for findbar and vertical layout''' self.editorLayoutWidget = QWidget(self) self.editorLayoutWidget.setMinimumWidth(800) self.tabWidget = EditorTab(self) self.editorLayout = QVBoxLayout(self.editorLayoutWidget) self.editorLayout.setMargin(0) self.editorLayout.addWidget(self.tabWidget) "0.Style Layout" self.styleLayoutWidget = QFrame() self.styleLayoutWidget.setFrameShape(QFrame.StyledPanel) self.styleLayout = QHBoxLayout(self.styleLayoutWidget) self.styleTest = QPushButton(self.styleLayoutWidget) self.styleTest.setText("Change Styles") self.styleTest.clicked.connect(self.changeStyleSheet) self.popWidget = Popup(self.styleLayoutWidget) self.styleLayout.addWidget(self.styleTest) self.styleLayout.addWidget(self.popWidget) self.styleLayout.setMargin(0) self.editorLayout.addWidget(self.styleLayoutWidget) self.styleLayoutWidget.hide() "1.Find Layout" self.findLayoutWidget = QFrame() self.findLayoutWidget.setFrameShape(QFrame.StyledPanel) self.findLayout = QHBoxLayout(self.findLayoutWidget) self.lineEdit = QLineEdit(self.findLayoutWidget) self.lineEdit_2 = QLineEdit(self.findLayoutWidget) self.findClose = QPushButton(self.findLayoutWidget) self.findClose.setIcon(Icons.close_view) self.findClose.setFlat(True) self.findClose.clicked.connect(self.findBarShow) self.find = QPushButton(self.findLayoutWidget) self.find.setText("Find") self.find.clicked.connect(self.findCurrentText) self.replacefind = QPushButton(self.findLayoutWidget) self.replacefind.setText("Replace/Find") self.replacefind.clicked.connect(self.replaceFindText) self.replace = QPushButton(self.findLayoutWidget) self.replace.setText("Replace") self.replace.clicked.connect(self.replaceCurrentText) self.replaceAll = QPushButton(self.findLayoutWidget) self.replaceAll.setText("Replace All") self.replaceAll.clicked.connect(self.replaceAllText) self.caseSensitive = QToolButton(self.findLayoutWidget) self.caseSensitive.setIcon(Icons.font) self.caseSensitive.setCheckable(True) self.wholeWord = QToolButton(self.findLayoutWidget) self.wholeWord.setText("ww") self.wholeWord.setCheckable(True) self.regex = QToolButton(self.findLayoutWidget) self.regex.setText("re") self.regex.setCheckable(True) self.backward = QToolButton(self.findLayoutWidget) self.backward.setText("bk") self.backward.setCheckable(True) self.backward.setDisabled(True) self.findLayout.addWidget(self.findClose) self.findLayout.addWidget(self.find) self.findLayout.addWidget(self.lineEdit) self.findLayout.addWidget(self.lineEdit_2) self.findLayout.addWidget(self.caseSensitive) self.findLayout.addWidget(self.wholeWord) self.findLayout.addWidget(self.regex) self.findLayout.addWidget(self.backward) self.findLayout.addWidget(self.replacefind) self.findLayout.addWidget(self.replace) self.findLayout.addWidget(self.replaceAll) self.findLayout.setMargin(0) self.findLayoutWidget.setMaximumHeight(25) self.editorLayout.addWidget(self.findLayoutWidget) self.findLayoutWidget.hide() '''B.Designer''' '''This parent is for widgetsbar and design layout''' self.designerLayoutWidget = QWidget(self) self.designerLayoutWidget.setMinimumWidth(800) self.designerWidget = Screen(self) self.designerLayoutWidget.hide() self.designerLayout = QVBoxLayout(self.designerLayoutWidget) self.designerLayout.setMargin(0) self.designerLayout.addWidget(self.designerWidget) '''C.Level Editor''' '''This parent is for spritesheets and level layout''' self.levelLayoutWidget = QWidget(self) self.levelLayoutWidget.setMinimumWidth(800) self.levelWidget = Level(self) self.levelLayoutWidget.hide() self.levelLayout = QVBoxLayout(self.levelLayoutWidget) self.levelLayout.setMargin(0) self.levelLayout.addWidget(self.levelWidget) '''D.Explorer TabWidget''' self.explorerTabWidget = TreeTab(self) #self.explorerTabWidget.setMaximumWidth(200) '''1.Project Tree''' self.tab_5 = QWidget() #self.tab_5.setMaximumWidth(200) self.VerticalLayout_2 = QVBoxLayout(self.tab_5)#QHBoxLayout(self.tab_5) self.VerticalLayout_2.setMargin(0) self.treeWidget = ProjectTree(self.tab_5) #self.treeWidget.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) #self.treeWidget.horizontalScrollBar().show() self.VerticalLayout_2.addWidget(self.treeWidget) '''2.Outline Tree''' self.tab_2 = QWidget() #self.tab_2.setMaximumWidth(200) self.VerticalLayout_3 = QVBoxLayout(self.tab_2) self.VerticalLayout_3.setMargin(0) self.outlineWidget = OutlineTree(self.tab_2) self.outlineWidget.itemDoubleClicked.connect(self.gotoLine) self.VerticalLayout_3.addWidget(self.outlineWidget) '''E.Output TabWidget''' self.outputTabWidget = OutputTab(self) self.tabWidget.currentChanged.connect(self.fileChanged) self.explorerTabWidget.currentChanged.connect(self.closeExplorer) self.outputTabWidget.currentChanged.connect(self.closeConsole) self.tabWidget.setTabsClosable(True) self.tabWidget.setTabShape(0) '''1.Output layout''' #must check self.tab_6 = QWidget() self.horizontalLayout_2 = QVBoxLayout(self.tab_6) self.horizontalLayout_2.setMargin(0) self.textEdit = QTextEdit() self.inputLayout = QHBoxLayout() self.inputLayout.setMargin(0) self.fileButton = QPushButton() self.fileButton.setText("File") self.fileButton.clicked.connect(self.getFile) self.runButton = QPushButton() self.runButton.setFlat(True) self.runButton.setIcon(Icons.go) self.combo = QComboBox() self.combo.setFixedWidth(100) self.comboAdd = QPushButton() self.comboAdd.setIcon(Icons.add) self.comboAdd.setFlat(True) self.comboAdd.clicked.connect(self.addCmd) self.comboDel = QPushButton() self.comboDel.setIcon(Icons.close_view) self.comboDel.setFlat(True) self.comboDel.clicked.connect(self.delCmd) self.combo2 = QComboBox() self.combo2.setFixedWidth(500) self.combo2Add = QPushButton() self.combo2Add.setIcon(Icons.add) self.combo2Add.setFlat(True) self.combo2Add.clicked.connect(self.addParam) self.combo2Del = QPushButton() self.combo2Del.setIcon(Icons.close_view) self.combo2Del.setFlat(True) self.combo2Del.clicked.connect(self.delParam) if(self.checkHasValue(self.cmdList)): for cmd in self.cmdList: self.combo.addItem(cmd) else: self.cmdList = [] if(self.checkHasValue(self.paramList)): for param in self.paramList: self.combo2.addItem(param) else: self.paramList = [] self.horizontalLayout_2.addWidget(self.textEdit) self.inputLayout.addWidget(QLabel("<b>Command:</b>")) self.inputLayout.addWidget(self.combo) self.inputLayout.addWidget(self.comboAdd) self.inputLayout.addWidget(self.comboDel) self.inputLayout.addWidget(QLabel("<b>Parameters:</b>")) self.inputLayout.addWidget(self.combo2) self.inputLayout.addWidget(self.combo2Add) self.inputLayout.addWidget(self.combo2Del) self.inputLayout.addWidget(self.fileButton) self.inputLayout.addWidget(self.runButton) self.horizontalLayout_2.addLayout(self.inputLayout) '''2.Error Layout''' self.tab_7 = QWidget() self.horizontalLayout_4 = QHBoxLayout(self.tab_7) self.horizontalLayout_4.setMargin(0) self.errorTree = ErrorTree(self.tab_7) self.errorTree.itemDoubleClicked.connect(self.errorLine) self.horizontalLayout_4.addWidget(self.errorTree) '''TabWidgets tabs''' #self.designerWidget.addTab(QWidget(self),"") #self.designerWidget.setTabIcon(0,Icons.close_view) #self.levelWidget.addTab(QWidget(self),"") #self.levelWidget.setTabIcon(0,Icons.close_view) self.explorerTabWidget.addTab(self.tab_5,"Projects") self.explorerTabWidget.addTab(self.tab_2,"Outline") self.explorerTabWidget.addTab(QWidget(self),"") self.explorerTabWidget.setTabIcon(0,Icons.cprj) self.explorerTabWidget.setTabIcon(1,Icons.envvar) self.explorerTabWidget.setTabIcon(2,Icons.close_view) self.outputTabWidget.addTab(self.tab_7,"Error") self.outputTabWidget.addTab(self.tab_6,"Output") self.outputTabWidget.addTab(QWidget(self),"") self.outputTabWidget.setTabIcon(0,Icons.error) self.outputTabWidget.setTabIcon(1,Icons.console_view) self.outputTabWidget.setTabIcon(2,Icons.close_view) '''Splitters''' self.split1 = QSplitter(Qt.Horizontal) self.split1.addWidget(self.explorerTabWidget) self.split1.addWidget(self.editorLayoutWidget) self.split1.addWidget(self.designerLayoutWidget) self.split1.addWidget(self.levelLayoutWidget) #self.split1.addWidget(self.tab_5) self.split2 = QSplitter(Qt.Vertical) self.split2.addWidget(self.split1) self.split2.addWidget(self.outputTabWidget) self.horizontalLayout.addWidget(self.split2) '''Status Bar''' self.statusbar = QStatusBar(self) self.aboutButton = QPushButton(self) self.aboutButton.setFlat(True) self.aboutButton.setIcon(Icons.anchor) self.aboutButton.clicked.connect(self.about) self.expButton = QPushButton(self) self.expButton.setFlat(True) self.expButton.setIcon(Icons.prj) self.expButton.clicked.connect(self.exp) self.cmdButton = QPushButton(self) self.cmdButton.setFlat(True) self.cmdButton.setIcon(Icons.console_view) self.cmdButton.clicked.connect(self.cmd) self.cmdButton.setShortcut('Ctrl+D') self.imgButton = QPushButton(self) self.imgButton.setFlat(True) self.imgButton.setIcon(Icons.color_palette) self.imgButton.clicked.connect(self.design) self.imgButton.setShortcut('Ctrl+I') self.findButton = QPushButton(self) self.findButton.setFlat(True) self.findButton.setIcon(Icons.find) self.findButton.setShortcut("Ctrl+F") self.findButton.clicked.connect(self.findBarShow) ''' self.zoominButton = QPushButton(self) self.zoominButton.setFlat(True) self.zoominButton.setIcon(Icons.zoomplus) self.zoominButton.clicked.connect(self.zoomin) self.zoomoutButton = QPushButton(self) self.zoomoutButton.setFlat(True) self.zoomoutButton.setIcon(Icons.zoomminus) self.zoomoutButton.clicked.connect(self.zoomout) ''' '''Status Text,Line Text, Progress Bar and Stop Button''' self.statusText = QLabel("Writable") #self.statusText.setAlignment(Qt.AlignCenter) self.statusText.setFixedWidth(200) self.lineText = QLabel("") self.lineText.setFixedWidth(50) self.progressbar = QProgressBar() self.progressbar.setMinimum(0) self.progressbar.setMaximum(100) self.stopButton = QPushButton(self) self.stopButton.setFlat(True) self.stopButton.setIcon(Icons.stop) self.stopButton.clicked.connect(self.forceStop) self.progressbar.hide() self.stopButton.hide() self.temp = False self.progress = False self.counter = 0 '''Adding all widgets to Status Bar''' self.statusbar.addWidget(self.aboutButton) self.statusbar.addWidget(self.expButton) self.statusbar.addWidget(self.cmdButton) self.statusbar.addWidget(self.imgButton) self.statusbar.addWidget(self.findButton) #self.statusbar.addWidget(QWidget(self)) #self.statusbar.addWidget(self.zoominButton) #self.statusbar.addWidget(self.zoomoutButton) self.statusbar.addWidget(self.statusText) self.statusbar.addWidget(self.lineText) self.statusbar.addWidget(self.progressbar) self.statusbar.addWidget(self.stopButton) #self.statusbar.setFixedHeight(18) ''''Initializing Coloring Style''' self.initEditorStyle() self.initStyleSheet() '''Adding Cental Widget and Status Bar''' self.setCentralWidget(self.centralwidget) self.setStatusBar(self.statusbar) self.textEdit.setReadOnly(True) def initStyleSheet(self): import stylesheet self.setStyleSheet(stylesheet.mainstyl) self.tabWidget.tabBar().setStyleSheet(stylesheet.stletabb) self.explorerTabWidget.tabBar().setStyleSheet(stylesheet.stletabb) self.outputTabWidget.tabBar().setStyleSheet(stylesheet.stletabb) self.popWidget.setStyleSheet(stylesheet.popbg) self.popWidget.hide() ''' This is for changing the palette/window colors to Theme ''' def initEditorStyle(self): pass #editStyle = config.readStyle() #print editStyle #pal = QPalette(self.explorerTabWidget.palette()) #print pal.color(QPalette.Base).name() #print pal.color(QPalette.Window).name() #pal.setColor(QPalette.Base,self.colorStyle.paper) #pal.setColor(QPalette.Text,self.colorStyle.color) #self.explorerTabWidget.setPalette(pal) #self.outputTabWidget.setPalette(pal) ''' This is only for testing dont know if it works for builds ''' def changeStyleSheet(self): ''' Dynamically load the changed stylesheet.py and load the modules and change the style at runtime saves countless deploys ''' import imp foo = imp.load_source('stletabb', workDir+"/stylesheet.py") #print foo.stletabb #self.setStyleSheet(stylesheet.mainstyl) self.tabWidget.tabBar().setStyleSheet(foo.stletabb) self.popWidget.setStyleSheet(foo.popbg) if(self.popWidget.isHidden()): self.popWidget.showPopup() def build_project(self): #current_file = self.files[self.tabWidget.currentIndex()] prj = self.treeWidget.getProject() if(prj != None): self.treeWidget.build(prj) def run_project(self): #current_file = self.files[self.tabWidget.currentIndex()] prj = self.treeWidget.getProject()#current_file) if(prj != None): self.treeWidget.run(prj) def forceStop(self): self.ant.kill() self.progressStop() def kill(self): self.deleteLater() #-----------------------------------------------------------------------------------# # Menu Actions Functions # #-----------------------------------------------------------------------------------# def run(self): if(config.mode() == 0): self.sq.run() elif(config.mode() == 1): self.adb.run() elif(config.mode() == 2): self.ios.run() elif(config.mode() == 3): self.c.run() def setMode(self, action): if(action.text() == "Squ"): config.setMode(0) self.toolBar.action_Build.setEnabled(False) self.toolBar.action_Run.setEnabled(False) elif(action.text() == "Emo"): config.setMode(1) self.toolBar.action_Build.setEnabled(True) self.toolBar.action_Run.setEnabled(True) elif(action.text() == "Android"): config.setMode(2) self.toolBar.action_Build.setEnabled(True) self.toolBar.action_Run.setEnabled(True) elif(action.text() == "ios"): config.setMode(3) self.toolBar.action_Build.setEnabled(False) self.toolBar.action_Run.setEnabled(False) def openCommand(self): text, ok = QInputDialog.getText(self, 'Run Command', 'Command:') cmd = str(text) if ok and cmd != "": import subprocess subprocess.Popen(cmd) def about(self): form = DialogAbout(self) def todo(self): form = DialogTodo(self) form.show() def help(self): QMessageBox.about(self,"Help","This is about all The Help that i can Give you now") def full(self): if not self.isFull: self.setWindowState(Qt.WindowFullScreen) self.isFull = True else: self.setWindowState(Qt.WindowMaximized) self.isFull = False def android(self): form = DialogAndroid(self) form.show() def antt(self): form = DialogAnt(self) form.show() def squirrel(self): form = DialogSquirrel(self) form.show() def findBarShow(self): if(self.findLayoutWidget.isHidden()): self.findLayoutWidget.show() else: self.findLayoutWidget.hide() def exp(self): if(self.explorerTabWidget.isHidden()): self.explorerTabWidget.show() else: self.explorerTabWidget.hide() def cmd(self): if(self.outputTabWidget.isHidden()): self.outputTabWidget.show() else: self.outputTabWidget.hide() def editor(self): if(self.editorLayoutWidget.isHidden()): self.editorLayoutWidget.show() self.levelLayoutWidget.hide() self.designerLayoutWidget.hide() def design(self): if(self.designerLayoutWidget.isHidden()): self.designerLayoutWidget.show() self.editorLayoutWidget.hide() self.levelLayoutWidget.hide() else: self.designerLayoutWidget.hide() self.editorLayoutWidget.show() def level(self): if(self.levelLayoutWidget.isHidden()): self.levelLayoutWidget.show() self.editorLayoutWidget.hide() self.designerLayoutWidget.hide() else: self.levelLayoutWidget.hide() self.editorLayoutWidget.show() def closeDesigner(self,no): pass ''' if(no == self.tiler.closeIndex()): if(self.tiler.isHidden()): self.tiler.show() else: self.tiler.setCurrentIndex(1) self.tiler.hide() ''' '''The current Changed idx of outputTabWidget is passed to this a param''' def closeConsole(self,no = 2): if(no == 2): if(self.outputTabWidget.isHidden()): self.outputTabWidget.show() else: self.outputTabWidget.setCurrentIndex(1) self.outputTabWidget.hide() def popOutput(self): if(self.outputTabWidget.isHidden()): self.outputTabWidget.show() self.outputTabWidget.setCurrentIndex(1) def popError(self): if(self.outputTabWidget.isHidden()): self.outputTabWidget.show() self.outputTabWidget.setCurrentIndex(0) '''The current Changed idx of explorerTabWidget is passed to this a param''' def closeExplorer(self,no = 2): if(no == 2): if(self.explorerTabWidget.isHidden()): self.explorerTabWidget.show() else: self.explorerTabWidget.setCurrentIndex(0) self.explorerTabWidget.hide() elif(no == 1): self.fileChanged(no) ''' This is to refresh the outline widget''' def fileChanged(self,no): if(self.explorerTabWidget.currentIndex() == 1): edt = self.tabWidget.widget(self.tabWidget.currentIndex()) source = edt.text() self.outlineWidget.parseText(source) def statusSaving(self): self.statusText.setText("Saving") def statusParsing(self): self.statusText.setText("Parsing") def statusWriting(self): self.statusText.setText("Writable") def statusRunning(self): self.statusText.setText("Running") def statusStopping(self): self.statusText.setText("Stopping") def statusCommand(self): self.statusText.setText("Command") def statusBuilding(self): self.statusText.setText("Building") def statusInstalling(self): self.statusText.setText("Installing") def statusCleaning(self): self.statusText.setText("Cleaning") def statusCreating(self): self.statusText.setText("Creating") def progressStart(self): self.progress == True self.temp == True if(self.progressbar.isHidden()): self.progressbar.show() if(self.stopButton.isHidden()): self.stopButton.show() self.progressbar.setValue(1) def progressStop(self): self.progress == False self.temp == False self.progressbar.setValue(100) if not(self.progressbar.isHidden()): self.progressbar.hide() if not(self.stopButton.isHidden()): self.stopButton.hide() def progressUpdate(self): if(self.progress): if(self.temp): self.counter += 1 self.progressbar.setValue(self.counter) if(self.counter == 100): self.temp = False else: self.counter -= 1 self.progressbar.setValue(self.counter) if(self.counter == 0): self.temp = True #-----------------------------------------------------------------------------------# # Editor Functions # #-----------------------------------------------------------------------------------# '''Search and Replace Functions''' def findCurrentText(self): edt = self.tabWidget.widget(self.tabWidget.currentIndex()) edt.findText(self.lineEdit.text(),self.regex.isChecked(),self.caseSensitive.isChecked(),self.wholeWord.isChecked(),self.backward.isChecked()) def replaceCurrentText(self): edt = self.tabWidget.widget(self.tabWidget.currentIndex()) edt.replaceText(self.lineEdit_2.text()) def replaceFindText(self): edt = self.tabWidget.widget(self.tabWidget.currentIndex()) edt.replaceText(self.lineEdit_2.text()) self.findCurrentText() def replaceAllText(self): edt = self.tabWidget.widget(self.tabWidget.currentIndex()) while(edt.findText(self.lineEdit.text(),self.regex.isChecked(),self.caseSensitive.isChecked(),self.wholeWord.isChecked(),self.backward.isChecked())): edt.replaceText(self.lineEdit_2.text()) def errorLine(self,error): index = self.tabWidget.currentIndex() edt = self.tabWidget.widget(index) '''To prevent File item double clicking''' if(error.isFile() == False): edt.setLine(error.line) '''Font Functions''' def zoomin(self): pass #for i in range(len(self.files)): # self.tabWidget.widget(i).zoomin() def zoomout(self): pass #for i in range(len(self.files)): # self.tabWidget.widget(i).zoomout() ''' Must implement Lexer ''' def setLexer(self, action): pass #print action.text() def setApi(self, action): #print action.text() for i in range(len(self.files)): #not QString self.tabWidget.widget(i).setApi(str(action.text())) def setFont(self,font): config.setFontName(str(font.family())) for i in range(len(self.files)): self.tabWidget.widget(i).setNewFont(font) def setFontSize(self,idx): fontSize = idx+1 config.setFontSize(fontSize) for i in range(len(self.files)): self.tabWidget.widget(i).setFontSize() def gotoLine(self,item): edt = self.tabWidget.widget(self.tabWidget.currentIndex()) edt.setLine(item.line) def updateLine(self,no,col): self.lineText.setText(str(no)+" : "+str(col)) def setMargin(self): mar = config.margin() if(mar == 0): config.setMargin(1) for i in range(len(self.files)): self.tabWidget.widget(i).setMargin(1) else: config.setMargin(0) for i in range(len(self.files)): self.tabWidget.widget(i).setMargin(0) ''' Toggle ''' def setIndent(self): indent = config.indent() if(indent == 0): config.setIndent(1) for i in range(len(self.files)): self.tabWidget.widget(i).setIndent(1) else: config.setIndent(0) for i in range(len(self.files)): self.tabWidget.widget(i).setIndent(0) ''' Toggle ''' def setWhiteSpace(self): white = config.whiteSpace() if(white == 0): config.setWhiteSpace(1) for i in range(len(self.files)): self.tabWidget.widget(i).setWhitespaceVisibility(True) else: config.setWhiteSpace(0) for i in range(len(self.files)): self.tabWidget.widget(i).setWhitespaceVisibility(False) ''' Toggle ''' def setEndLine(self): for i in range(len(self.files)): edt = self.tabWidget.widget(i) edt.setEolVisibility(not edt.eolVisibility()) def setEncoding(self, action): if(action.text() == "Ascii"): config.setAscii() for i in range(len(self.files)): self.tabWidget.widget(i).setUtf8(False) elif(action.text() == "Unicode"): config.setUnicode() for i in range(len(self.files)): self.tabWidget.widget(i).setUtf8(True) def setThreshold(self,val): config.setThresh(val) for i in range(len(self.files)): #print i self.tabWidget.widget(i).setThreshold(val) def setTabWidth(self,val): config.setTabWidth(val) for i in range(len(self.files)): #print i self.tabWidget.widget(i).setTabWidth(val) '''style Functions''' #-----------------------------------------------------------------------------------# # Command Functions # #-----------------------------------------------------------------------------------# def getFile(self): self.browsedialog = DialogBrowse(self) self.browsedialog.tree.itemDoubleClicked.connect(self.getName) self.browsedialog.show() def getName(self,item): if(item.isFile()): self.browsedialog.accept() fname = item.getPath() if not (fname == ""): index = self.combo2.currentIndex() text = str(self.combo2.itemText(index))+" "+fname self.combo2.setItemText(index,text) self.paramList.pop(index) self.paramList.insert(index,text) config.setParam(self.paramList) def addCmd(self,index): text, ok = QInputDialog.getText(self, 'Add Command', 'Command:') if(ok): if(str(text) != ''): cmd = str(text).upper() self.cmdList.append(cmd) #print self.cmdList self.combo.addItem(cmd) config.setCmd(self.cmdList) config.setParam(self.paramList) def delCmd(self): index = self.combo.currentIndex() self.combo.removeItem(index) self.cmdList.pop(index) #print self.cmdList config.setCmd(self.cmdList) def addParam(self,index): text, ok = QInputDialog.getText(self, 'Add Parameters', 'Params:') if(ok): if(str(text) != ''): param = str(text) self.paramList.append(param) self.combo2.addItem(param) config.setParam(self.paramList) def delParam(self): index = self.combo2.currentIndex() self.combo2.removeItem(index) self.paramList.pop(index) config.setParam(self.paramList) def checkHasValue(self,list): if(list != None and len(list) != 0): return True else: return False
class ActionBar(QFrame): """ SIGNALS: @changeCurrent(PyQt_PyObject) @runFile(QString) @reopenTab(QString) @recentTabsModified() """ def __init__(self, main_combo=False): super(ActionBar, self).__init__() self.setObjectName("actionbar") hbox = QHBoxLayout(self) hbox.setContentsMargins(1, 1, 1, 1) hbox.setSpacing(1) self.lbl_checks = QLabel('') self.lbl_checks.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.lbl_checks.setFixedWidth(48) self.lbl_checks.setVisible(False) hbox.addWidget(self.lbl_checks) self.combo = QComboBox() self.combo.setIconSize(QSize(16, 16)) #model = QStandardItemModel() #self.combo.setModel(model) #self.combo.view().setDragDropMode(QAbstractItemView.InternalMove) self.combo.setMaximumWidth(300) self.combo.setObjectName("combotab") self.connect(self.combo, SIGNAL("currentIndexChanged(int)"), self.current_changed) self.combo.setToolTip(translations.TR_COMBO_FILE_TOOLTIP) self.combo.setContextMenuPolicy(Qt.CustomContextMenu) self.connect(self.combo, SIGNAL( "customContextMenuRequested(const QPoint &)"), self._context_menu_requested) hbox.addWidget(self.combo) self.symbols_combo = QComboBox() self.symbols_combo.setIconSize(QSize(16, 16)) self.symbols_combo.setObjectName("combo_symbols") self.connect(self.symbols_combo, SIGNAL("activated(int)"), self.current_symbol_changed) hbox.addWidget(self.symbols_combo) self.code_navigator = CodeNavigator() hbox.addWidget(self.code_navigator) self._pos_text = "Line: %d, Col: %d" self.lbl_position = QLabel(self._pos_text % (0, 0)) self.lbl_position.setObjectName("position") self.lbl_position.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.lbl_position) self.btn_close = QPushButton( self.style().standardIcon(QStyle.SP_DialogCloseButton), '') self.btn_close.setIconSize(QSize(16, 16)) if main_combo: self.btn_close.setObjectName('navigation_button') self.btn_close.setToolTip(translations.TR_CLOSE_FILE) self.connect(self.btn_close, SIGNAL("clicked()"), self.about_to_close_file) else: self.btn_close.setObjectName('close_split') self.btn_close.setToolTip(translations.TR_CLOSE_SPLIT) self.connect(self.btn_close, SIGNAL("clicked()"), self.close_split) self.btn_close.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) hbox.addWidget(self.btn_close) def resizeEvent(self, event): super(ActionBar, self).resizeEvent(event) if event.size().width() < 350: self.symbols_combo.hide() self.code_navigator.hide() self.lbl_position.hide() else: self.symbols_combo.show() self.code_navigator.show() self.lbl_position.show() def add_item(self, text, neditable): """Add a new item to the combo and add the neditable data.""" self.combo.addItem(text, neditable) self.combo.setCurrentIndex(self.combo.count() - 1) def get_editables(self): editables = [] for index in range(self.combo.count()): neditable = self.combo.itemData(index) editables.append(neditable) return editables def add_symbols(self, symbols): """Add the symbols to the symbols's combo.""" self.symbols_combo.clear() for symbol in symbols: data = symbol[1] if data[1] == 'f': icon = QIcon(":img/function") else: icon = QIcon(":img/class") self.symbols_combo.addItem(icon, data[0]) def set_current_symbol(self, index): self.symbols_combo.setCurrentIndex(index) def update_item_icon(self, neditable, icon): index = self.combo.findData(neditable) self.combo.setItemIcon(index, icon) def update_item_text(self, neditable, text): index = self.combo.findData(neditable) self.combo.setItemText(index, text) def current_changed(self, index): """Change the current item in the combo.""" neditable = self.combo.itemData(index) self.emit(SIGNAL("changeCurrent(PyQt_PyObject, int)"), neditable, index) def current_symbol_changed(self, index): """Change the current symbol in the combo.""" self.emit(SIGNAL("goToSymbol(int)"), index) def update_line_col(self, line, col): """Update the line and column position.""" self.lbl_position.setText(self._pos_text % (line, col)) def _context_menu_requested(self, point): """Display context menu for the combo file.""" if self.combo.count() == 0: # If there is not an Editor opened, don't show the menu return menu = QMenu() actionAdd = menu.addAction(translations.TR_ADD_TO_PROJECT) actionRun = menu.addAction(translations.TR_RUN_FILE) menuSyntax = menu.addMenu(translations.TR_CHANGE_SYNTAX) self._create_menu_syntax(menuSyntax) menu.addSeparator() actionClose = menu.addAction(translations.TR_CLOSE_FILE) actionCloseAll = menu.addAction(translations.TR_CLOSE_ALL_FILES) actionCloseAllNotThis = menu.addAction( translations.TR_CLOSE_OTHER_FILES) menu.addSeparator() actionSplitH = menu.addAction(translations.TR_SPLIT_VERTICALLY) actionSplitV = menu.addAction(translations.TR_SPLIT_HORIZONTALLY) menu.addSeparator() actionCopyPath = menu.addAction( translations.TR_COPY_FILE_PATH_TO_CLIPBOARD) actionReopen = menu.addAction(translations.TR_REOPEN_FILE) actionUndock = menu.addAction(translations.TR_UNDOCK_EDITOR) if len(settings.LAST_OPENED_FILES) == 0: actionReopen.setEnabled(False) #Connect actions self.connect(actionSplitH, SIGNAL("triggered()"), lambda: self._split(False)) self.connect(actionSplitV, SIGNAL("triggered()"), lambda: self._split(True)) self.connect(actionRun, SIGNAL("triggered()"), self._run_this_file) self.connect(actionAdd, SIGNAL("triggered()"), self._add_to_project) self.connect(actionClose, SIGNAL("triggered()"), self.about_to_close_file) self.connect(actionCloseAllNotThis, SIGNAL("triggered()"), self._close_all_files_except_this) self.connect(actionCloseAll, SIGNAL("triggered()"), self._close_all_files) self.connect(actionCopyPath, SIGNAL("triggered()"), self._copy_file_location) self.connect(actionReopen, SIGNAL("triggered()"), self._reopen_last_tab) self.connect(actionUndock, SIGNAL("triggered()"), self._undock_editor) menu.exec_(QCursor.pos()) def _create_menu_syntax(self, menuSyntax): """Create Menu with the list of syntax supported.""" syntax = list(settings.SYNTAX.keys()) syntax.sort() for syn in syntax: menuSyntax.addAction(syn) self.connect(menuSyntax, SIGNAL("triggered(QAction*)"), self._reapply_syntax) def _reapply_syntax(self, syntaxAction): #TODO if [self.currentIndex(), syntaxAction] != self._resyntax: self._resyntax = [self.currentIndex(), syntaxAction] self.emit(SIGNAL("syntaxChanged(QWidget, QString)"), self.currentWidget(), syntaxAction.text()) def set_current_file(self, neditable): index = self.combo.findData(neditable) self.combo.setCurrentIndex(index) def set_current_by_index(self, index): self.combo.setCurrentIndex(index) def about_to_close_file(self, index=None): """Close the NFile object.""" if index is None: index = self.combo.currentIndex() neditable = self.combo.itemData(index) if neditable: neditable.nfile.close() def close_split(self): self.emit(SIGNAL("closeSplit()")) def close_file(self, neditable): """Receive the confirmation to close the file.""" index = self.combo.findData(neditable) self.combo.removeItem(index) return index def _run_this_file(self): """Execute the current file.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("runFile(QString)"), neditable.file_path) def _add_to_project(self): """Emit a signal to let someone handle the inclusion of the file inside a project.""" neditable = self.combo.itemData(self.combo.currentIndex()) self.emit(SIGNAL("addToProject(QString)"), neditable.file_path) def _reopen_last_tab(self): self.emit(SIGNAL("reopenTab(QString)"), settings.LAST_OPENED_FILES.pop()) self.emit(SIGNAL("recentTabsModified()")) def _undock_editor(self): self.emit(SIGNAL("undockEditor()")) def _split(self, orientation): self.emit(SIGNAL("splitEditor(bool)"), orientation) def _copy_file_location(self): """Copy the path of the current opened file to the clipboard.""" neditable = self.combo.itemData(self.combo.currentIndex()) QApplication.clipboard().setText(neditable.file_path, QClipboard.Clipboard) def _close_all_files(self): """Close all the files opened.""" for i in range(self.combo.count()): self.about_to_close_file(0) def _close_all_files_except_this(self): """Close all the files except the current one.""" neditable = self.combo.itemData(self.combo.currentIndex()) for i in reversed(list(range(self.combo.count()))): ne = self.combo.itemData(i) if ne is not neditable: self.about_to_close_file(i)