def createEditor(self, parent, _QStyleOptionViewItem, index): combo = QComboBox(parent) attr = index.model()[index.row()][0] combo.setModel(self._combo_continuous_model if attr.is_continuous else self._combo_discrete_model if attr.is_discrete else self._combo_string_model) return combo
def createEditor( self, parent, option, index ): if index.column() == DESCRIPCION: combo = QComboBox( parent ) combo.setEditable( True ) value = index.data().toString() self.filtrados.append( value ) self.proxymodel.setFilterRegExp( self.filter() ) combo.setModel( self.proxymodel ) combo.setModelColumn( 1 ) combo.setCompleter( self.completer ) return combo elif index.column() == BANCO: combo = QComboBox( parent ) #combo.setEditable(True) combo.setModel( self.bancosmodel ) combo.setModelColumn( 1 ) #combo.setCompleter(self.completer) return combo elif index.column() == MONTO: doublespinbox = QDoubleSpinBox( parent ) doublespinbox.setMinimum( -1000000 ) doublespinbox.setMaximum( 1000000 ) doublespinbox.setDecimals( 4 ) doublespinbox.setAlignment( Qt.AlignHCenter ) return doublespinbox elif index.column() == REFERENCIA: textbox = QStyledItemDelegate.createEditor( self, parent, option, index ) textbox.setAlignment( Qt.AlignHCenter ) return textbox
class Widget(QWidget): def __init__(self, tool): super(Widget, self).__init__(tool) layout = QVBoxLayout() self.setLayout(layout) layout.setContentsMargins(0, 0, 0, 0) self.blockCombo = QComboBox() self.charmap = CharMapWidget() layout.addWidget(self.blockCombo) layout.addWidget(self.charmap) # size policy of combo p = self.blockCombo.sizePolicy() p.setHorizontalPolicy(QSizePolicy.Ignored) self.blockCombo.setSizePolicy(p) # size policy of combo popup p = self.blockCombo.view().sizePolicy() p.setHorizontalPolicy(QSizePolicy.MinimumExpanding) self.blockCombo.view().setSizePolicy(p) model = listmodel.ListModel(_blocks, display = lambda b: b.name) self.blockCombo.setModel(model) # load block setting name = QSettings().value("charmaptool/last_block", "", type("")) if name: for i, b in enumerate(_blocks): if b.name == name: self.blockCombo.setCurrentIndex(i) break self.blockCombo.activated[int].connect(self.updateBlock) self.updateBlock() self.loadSettings() app.settingsChanged.connect(self.loadSettings) def loadSettings(self): s = QSettings() s.beginGroup("charmaptool") font = self.font() family = s.value("fontfamily", "", type("")) if family: font.setFamily(family) self.charmap.charmap.setDisplayFont(font) size = s.value("fontsize", font.pointSizeF(), float) self.charmap.charmap.setDisplayFontSizeF(size) def updateBlock(self): i = self.blockCombo.currentIndex() if 0 <= i < len(_blocks): first, last, name = _blocks[i] self.charmap.charmap.setRange(first, last) QSettings().setValue("charmaptool/last_block", name)
def createComboBoxWithStrings(self, array): dbList = QComboBox() dbsListModel = QStandardItemModel(dbList) for f in array: item = QStandardItem(f) dbsListModel.appendRow(item) dbList.setModel(dbsListModel) return dbList
def createEditor(self, parent, _QStyleOptionViewItem, index): combo = QComboBox(parent) attr = index.model()[index.row()][0] combo.setModel( self._combo_continuous_model if attr. is_continuous else self._combo_discrete_model if attr. is_discrete else self._combo_string_model) return combo
def createEditor(self, parent, option, index): if index.column() in [0, 1]: editor = QComboBox(parent) editor.setSizeAdjustPolicy(QComboBox.AdjustToContents) editor.setModel(self.model) else: editor = QLineEdit(parent) return editor
class StaffGroup(_base.Container): @staticmethod def title(_=_base.translate): return _("Staff Group") def accepts(self): return (StaffGroup, _base.Part) def createWidgets(self, layout): self.systemStartLabel = QLabel() self.systemStart = QComboBox() self.systemStartLabel.setBuddy(self.systemStart) self.systemStart.setModel( listmodel.ListModel( ( # L10N: Brace like a piano staff (lambda: _("Brace"), 'system_start_brace'), # L10N: Bracket like a choir staff (lambda: _("Bracket"), 'system_start_bracket'), # L10N: Square bracket like a sub-group (lambda: _("Square"), 'system_start_square'), ), self.systemStart, display=listmodel.translate_index(0), icon=lambda item: symbols.icon(item[1]))) self.systemStart.setIconSize(QSize(64, 64)) self.connectBarLines = QCheckBox(checked=True) box = QHBoxLayout() box.addWidget(self.systemStartLabel) box.addWidget(self.systemStart) layout.addLayout(box) layout.addWidget(self.connectBarLines) def translateWidgets(self): self.systemStartLabel.setText(_("Type:")) self.connectBarLines.setText(_("Connect Barlines")) self.connectBarLines.setToolTip( _("If checked, barlines are connected between the staves.")) self.systemStart.model().update() def build(self, data, builder): s = self.systemStart.currentIndex() b = self.connectBarLines.isChecked() if s == 0: node = ly.dom.GrandStaff() if not b: ly.dom.Line("\\remove Span_bar_engraver", node.getWith()) else: node = ly.dom.StaffGroup() if b else ly.dom.ChoirStaff() if s == 2: node.getWith()['systemStartDelimiter'] = ly.dom.Scheme( "'SystemStartSquare") data.nodes.append(node) data.music = ly.dom.Simr(node)
def __init__(self,parent,attached=False): info="Los productos con caracteristicas similares se agrupan familias y estas a su vez pertenecen a un departamento." logo=":/actions/images/actions/color_18/card_spades.png" deps=QComboBox(parent) deps.setModel(parent.departamento.getModelo()) deps.setModelColumn(1) Admin1.__init__(self,parent,'familias',[['id','Id','str',None,False],['nombre','Nombre','str',None,True] ,['departamento','Departamento','combo',deps,True]],info,logo,cond=" ORDER BY nombre ") self.ui=parent self.ui.connect(self.ui.verFamilias, QtCore.SIGNAL("triggered()"), self.iniciar) self.ui.connect(self.ui.tFamilias, QtCore.SIGNAL("clicked()"), self.iniciar) #self.ui.tbrProductos.addAction(self.ui.verFamilias) self.anclar(attached)
class StaffGroup(_base.Container): @staticmethod def title(_=_base.translate): return _("Staff Group") def accepts(self): return (StaffGroup, _base.Part) def createWidgets(self, layout): self.systemStartLabel = QLabel() self.systemStart = QComboBox() self.systemStartLabel.setBuddy(self.systemStart) self.systemStart.setModel(listmodel.ListModel(( # L10N: Brace like a piano staff (lambda: _("Brace"), 'system_start_brace'), # L10N: Bracket like a choir staff (lambda: _("Bracket"), 'system_start_bracket'), # L10N: Square bracket like a sub-group (lambda: _("Square"), 'system_start_square'), ), self.systemStart, display=listmodel.translate_index(0), icon=lambda item: symbols.icon(item[1]))) self.systemStart.setIconSize(QSize(64, 64)) self.connectBarLines = QCheckBox(checked=True) box = QHBoxLayout() box.addWidget(self.systemStartLabel) box.addWidget(self.systemStart) layout.addLayout(box) layout.addWidget(self.connectBarLines) def translateWidgets(self): self.systemStartLabel.setText(_("Type:")) self.connectBarLines.setText(_("Connect Barlines")) self.connectBarLines.setToolTip(_("If checked, barlines are connected between the staves.")) self.systemStart.model().update() def build(self, data, builder): s = self.systemStart.currentIndex() b = self.connectBarLines.isChecked() if s == 0: node = ly.dom.GrandStaff() if not b: ly.dom.Line("\\remove Span_bar_engraver", node.getWith()) else: node = ly.dom.StaffGroup() if b else ly.dom.ChoirStaff() if s == 2: node.getWith()['systemStartDelimiter'] = ly.dom.Scheme("'SystemStartSquare") data.nodes.append(node) data.music = ly.dom.Simr(node)
class VariableComboBox(QWidget): def __init__(self, id, text="Input data", default=[], model=None): QWidget.__init__(self) self.setToolTip("<p>Select input dataset</p>") self.id = id if model is None: self.model = TreeModel() else: self.model = model self.comboBox = QComboBox() self.treeView = QListView(self.comboBox) self.connect(self.comboBox, SIGNAL("currentIndexChanged(int)"), self.changeSelectedText) self.proxyModel = SortFilterProxyModel() self.proxyModel.setDynamicSortFilter(True) self.proxyModel.setFilterKeyColumn(1) self.proxyModel.setSourceModel(self.model) regexp = QRegExp("|".join([r"%s" % i for i in default])) self.proxyModel.setFilterRegExp(regexp) # self.treeView.header().hide() self.currentText = QString() self.treeView.setModel(self.proxyModel) self.comboBox.setModel(self.proxyModel) self.comboBox.setView(self.treeView) # self.treeView.hideColumn(1) # self.treeView.hideColumn(2) # self.treeView.hideColumn(3) self.treeView.viewport().installEventFilter(self.comboBox) label = QLabel(text) hbox = HBoxLayout() hbox.addWidget(label) hbox.addWidget(self.comboBox) self.setLayout(hbox) self.changeSelectedText(None) def changeSelectedText(self, index): item = self.treeView.currentIndex() if not item.isValid(): item = self.proxyModel.index(0,0, QModelIndex()) tree = self.treeView.model().parentTree(item) self.currentText = tree def parameterValues(self): return {self.id:self.currentText}
def __init__(self): QWidget.__init__(self) layout = QVBoxLayout() self.model = DataTypeKeysListModel() self.filter_model = DataTypeProxyModel(self.model) self.search_box = SearchBox() self.search_box.filterChanged.connect(self.setSearchString) layout.addWidget(self.search_box) data_type_model = QStandardItemModel(0, 1) item = QStandardItem("Select data types...") data_type_model.appendRow(item) self.__summary_item = QStandardItem("Summary") self.__summary_item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) self.__summary_item.setData(Qt.Checked, Qt.CheckStateRole) data_type_model.appendRow(self.__summary_item) self.__block_item = QStandardItem("Block") self.__block_item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled) self.__block_item.setData(Qt.Checked, Qt.CheckStateRole) data_type_model.appendRow(self.__block_item) data_type_model.itemChanged.connect(self.onItemChanged) combo = QComboBox() combo.setModel(data_type_model) layout.addWidget(combo) self.data_type_keys_widget = QListView() self.data_type_keys_widget.setModel(self.filter_model) self.data_type_keys_widget.selectionModel().selectionChanged.connect(self.itemSelected) layout.addSpacing(15) layout.addWidget(self.data_type_keys_widget, 2) layout.addWidget(Legend("Default types", DataTypeKeysListModel.DEFAULT_DATA_TYPE)) layout.addWidget(Legend("Observations available", DataTypeKeysListModel.HAS_OBSERVATIONS)) self.setLayout(layout)
class LoadResultsPanel(QWidget): def __init__(self): QWidget.__init__(self) self.setMinimumWidth(500) self.setMinimumHeight(200) self.__dynamic = False self.setWindowTitle("Load results manually") self.activateWindow() layout = QFormLayout() current_case = CaseSelectorModel().getCurrentChoice() self.__case_model = AllCasesModel() self.__case_combo = QComboBox() self.__case_combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self.__case_combo.setMinimumContentsLength(20) self.__case_combo.setModel(self.__case_model) self.__case_combo.setCurrentIndex(self.__case_model.indexOf(current_case)) layout.addRow("Select case:",self.__case_combo) self.__active_realizations_model = LoadResultsRealizationsModel(EnsembleSizeModel().getValue()) self.__active_realizations_field = StringBox(self.__active_realizations_model, "Realizations to load", "load_results_manually/Realizations") self.__active_realizations_field.setValidator(RangeStringArgument()) layout.addRow(self.__active_realizations_field.getLabel(), self.__active_realizations_field) self.__iterations_count = LoadResultsModel().getIterationCount() self._iterations_model = LoadResultsIterationsModel(self.__iterations_count) self._iterations_field = StringBox(self._iterations_model, "Iteration to load", "load_results_manually/iterations") self._iterations_field.setValidator(RangeStringArgument()) layout.addRow(self._iterations_field.getLabel(), self._iterations_field) self.setLayout(layout) def load(self): all_cases = self.__case_model.getAllItems() selected_case = all_cases[self.__case_combo.currentIndex()] realizations = self.__active_realizations_model.getActiveRealizationsMask() iterations = self._iterations_model.getActiveRealizationsMask() LoadResultsModel().loadResults(selected_case, realizations, iterations)
def addCaseSelector(self, disabled=False, current_case=None): if len(self.__case_selectors_order) == 5: return widget = QWidget() layout = QHBoxLayout() layout.setMargin(0) widget.setLayout(layout) combo = QComboBox() combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon) combo.setMinimumContentsLength(20) combo.setModel(self.__model) if current_case is not None: index = 0 for item in self.__model: if item == current_case: combo.setCurrentIndex(index) break index += 1 combo.currentIndexChanged.connect(self.caseSelectionChanged.emit) layout.addWidget(combo, 1) button = QToolButton() button.setAutoRaise(True) button.setDisabled(disabled) button.setIcon(util.resourceIcon("ide/small/delete")) button.clicked.connect(self.__signal_mapper.map) layout.addWidget(button) self.__case_selectors[widget] = combo self.__case_selectors_order.append(widget) self.__signal_mapper.setMapping(button, widget) self.__case_layout.addWidget(widget) self.caseSelectionChanged.emit()
def addCaseSelector(self, disabled=False, current_case=None): widget = QWidget() layout = QHBoxLayout() layout.setMargin(0) widget.setLayout(layout) combo = QComboBox() combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLengthWithIcon) combo.setMinimumContentsLength(20) combo.setModel(self.__model) if current_case is not None: index = 0 for item in self.__model: if item == current_case: combo.setCurrentIndex(index) break index += 1 combo.currentIndexChanged.connect(self.caseSelectionChanged.emit) layout.addWidget(combo, 1) button = QToolButton() button.setAutoRaise(True) button.setDisabled(disabled) button.setIcon(util.resourceIcon("ide/small/delete")) button.clicked.connect(self.__signal_mapper.map) layout.addWidget(button) self.__case_selectors[widget] = combo self.__case_selectors_order.append(widget) self.__signal_mapper.setMapping(button, widget) self.__case_layout.addWidget(widget) self.checkCaseCount() self.caseSelectionChanged.emit()
class ChordNames(object): def createWidgets(self, layout): self.chordStyleLabel = QLabel() self.chordStyle = QComboBox() self.chordStyleLabel.setBuddy(self.chordStyle) self.chordStyle.setModel(listmodel.ListModel(chordNameStyles, self.chordStyle, display=listmodel.translate)) self.guitarFrets = QCheckBox() box = QHBoxLayout() box.addWidget(self.chordStyleLabel) box.addWidget(self.chordStyle) layout.addLayout(box) layout.addWidget(self.guitarFrets) def translateWidgets(self): self.chordStyleLabel.setText(_("Chord style:")) self.guitarFrets.setText(_("Guitar fret diagrams")) self.guitarFrets.setToolTip(_( "Show predefined guitar fret diagrams below the chord names " "(LilyPond 2.12 and above).")) self.chordStyle.model().update() def build(self, data, builder): p = ly.dom.ChordNames() a = data.assign('chordNames') ly.dom.Identifier(a.name, p) s = ly.dom.ChordMode(a) ly.dom.Identifier(data.globalName, s).after = 1 i = self.chordStyle.currentIndex() if i > 0: ly.dom.Line('\\{0}Chords'.format( ('german', 'semiGerman', 'italian', 'french')[i-1]), s) ly.dom.LineComment(_("Chords follow here."), s) ly.dom.BlankLine(s) data.nodes.append(p) if self.guitarFrets.isChecked(): f = ly.dom.FretBoards() ly.dom.Identifier(a.name, f) data.nodes.append(f) data.includes.append("predefined-guitar-fretboards.ly")
def setModel(self, model): """ Override setModel to include connections and disconnections for the reset-based signals. The model's reset-based signals are used to determine what the current index is, and to set it back to that after the model has been reset. """ if self.model(): try: self.model().modelAboutToBeReset.disconnect(self.beforeReset) except: pass try: self.model().modelReset.disconnect(self.afterReset) except: pass QComboBox.setModel(self, model) self.model().modelAboutToBeReset.connect(self.beforeReset) self.model().modelReset.connect(self.afterReset)
class LoadResultsPanel(QWidget): def __init__(self): QWidget.__init__(self) self.setMinimumWidth(500) self.setMinimumHeight(200) self._dynamic = False self.setWindowTitle("Load results manually") self.activateWindow() layout = QFormLayout() current_case = getCurrentCaseName() run_path_text = QTextEdit() run_path_text.setText(self.readCurrentRunPath()) run_path_text.setDisabled(True) run_path_text.setFixedHeight(80) layout.addRow("Load data from current run path: ",run_path_text) self._case_model = AllCasesModel() self._case_combo = QComboBox() self._case_combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self._case_combo.setMinimumContentsLength(20) self._case_combo.setModel(self._case_model) self._case_combo.setCurrentIndex(self._case_model.indexOf(current_case)) layout.addRow("Load into case:", self._case_combo) self._active_realizations_model = ActiveRealizationsModel() self._active_realizations_field = StringBox(self._active_realizations_model, "load_results_manually/Realizations") self._active_realizations_field.setValidator(RangeStringArgument()) layout.addRow("Realizations to load:", self._active_realizations_field) iterations_count = LoadResultsModel.getIterationCount() self._iterations_model = ValueModel(iterations_count) self._iterations_field = StringBox(self._iterations_model, "load_results_manually/iterations") self._iterations_field.setValidator(IntegerArgument()) layout.addRow("Iteration to load:", self._iterations_field) self.setLayout(layout) def readCurrentRunPath(self): current_case = getCurrentCaseName() run_path = LoadResultsModel.getCurrentRunPath() run_path = run_path.replace("<ERTCASE>",current_case) run_path = run_path.replace("<ERT-CASE>",current_case) return run_path def load(self): all_cases = self._case_model.getAllItems() selected_case = all_cases[self._case_combo.currentIndex()] realizations = self._active_realizations_model.getActiveRealizationsMask() iteration = self._iterations_model.getValue() try: if iteration is None: iteration = '' iteration = int(iteration) except ValueError as e: print('Expected a (whole) number in iteration field, got "%s". Error message: %s.' % (iteration, e)) return False loaded = LoadResultsModel.loadResults(selected_case, realizations, iteration) if loaded > 0: print('Successfully loaded %d realisations.' % loaded) else: print('No realisations loaded.') return loaded def setCurrectCase(self): current_case = getCurrentCaseName() self._case_combo.setCurrentIndex(self._case_model.indexOf(current_case))
class BugReportsWidget(QWidget): PREFERRED_WIDTH = 400 PREFERRED_HEIGHT = 150 def __init__(self, parent, mt): super(BugReportsWidget, self).__init__(parent) self.mt = mt layout = QVBoxLayout(self) # layout.setContentsMargins(0, 0, 0, 0) self.entry = QTextEdit(self) self.issues = {} self.issuesComboModel = IssuesComboModel() self.dropdown_reports = QComboBox(self) self.dropdown_reports.setModel(self.issuesComboModel) self.display_report() self.details_btn = QPushButton("Details", self) self.details_btn.setEnabled(False) self.refresh_btn = QPushButton("Refresh", self) create_report_btn = QPushButton("New", self) topLayout = QHBoxLayout() topLayout.addWidget(self.dropdown_reports, 1) topLayout.addWidget(self.details_btn) topLayout.addWidget(self.refresh_btn) topLayout.addSpacing(20) topLayout.addWidget(create_report_btn) layout.addLayout(topLayout) layout.addWidget(QLabel("Description:", self)) self.entry.setLineWrapMode(QTextEdit.WidgetWidth) self.entry.setReadOnly(True) layout.addWidget(self.entry) self.dropdown_reports.currentIndexChanged.connect(self.display_report) self.details_btn.clicked.connect(self.displayReportDetails) self.refresh_btn.clicked.connect(self.update_reports) create_report_btn.clicked.connect(self.createBugReport) self.update_reports() def repoChanged(self): self.update_reports() def displayReportDetails(self): selectedIssue = self.selectedIssue() if selectedIssue == None: return url = selectedIssue.issueUrl if url != None: webbrowser.open(url, new=2) def isRepoSpecified(self): repoUser = self.mt.options[u"repo_user"] repoName = self.mt.options[u"repo_name"] if repoUser and repoName: return True return False @pyqtSlot(QThread, unicode) def downloadedIssues(self, thread, _): self.refresh_btn.setEnabled(self.isRepoSpecified()) j = json.loads(thread.getResult()) newKeys = set() for i, issueDict in enumerate(j): issue = Issue(issueDict) newKeys.add(issue.id) self.issues[issue.id] = issue if not self.issuesComboModel.hasKey(issue.id): self.issuesComboModel.externalRowInserted(issue.id, issue, i) else: self.issuesComboModel.externalRowUpdated(issue.id, issue) oldKeys = set(self.issuesComboModel.keys) for removedKey in oldKeys - newKeys: self.issuesComboModel.externalRowRemoved(removedKey) self.details_btn.setEnabled(self.issuesComboModel.rowCount() > 0) @pyqtSlot(QThread, unicode) def errorDownloadingIssues(self, _thread, _url): self.refresh_btn.setEnabled(self.isRepoSpecified()) log_error("Error fetching issues from github.") def update_reports(self): self.refresh_btn.setEnabled(False) repoUser = self.mt.options[u"repo_user"] repoName = self.mt.options[u"repo_name"] if repoUser and repoName: log_debug("Fetching issues from repository %s/%s" % (repoUser, repoName)) thread = DownloadThread(self, "https://api.github.com/repos/%s/%s/issues?state=open" % (repoUser, repoName)) thread.finished.connect(thread.deleteLater) thread.error.connect(self.errorDownloadingIssues) thread.success.connect(self.downloadedIssues) thread.start() else: log_warning("No Lunchinator GitHub repository specified.") def createBugReport(self): repoUser = self.mt.options[u"repo_user"] repoName = self.mt.options[u"repo_name"] if repoUser and repoName: url = "https://github.com/%s/%s/issues/new" % (repoUser, repoName) if url != None: webbrowser.open(url, new=2) else: log_warning("No Lunchinator GitHub repository specified.") QMessageBox.critical(self, "No Repository", "No Lunchinator GitHub repository specified.", buttons=QMessageBox.Ok, defaultButton=QMessageBox.Ok) def selectedIssue(self): issueID = self.dropdown_reports.itemData(self.dropdown_reports.currentIndex(), IssuesComboModel.KEY_ROLE).toInt()[0] if not issueID in self.issues: log_error("ID of selected issue is not in issues dictionary") return None return self.issues[issueID] def display_report(self): if self.dropdown_reports.currentIndex()>=0: self.entry.setText(self.selectedIssue().description) def sizeHint(self): return QSize(self.PREFERRED_WIDTH, self.PREFERRED_HEIGHT)
class SharedSqlQueries: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale UNUSED # locale = QSettings().value('locale/userLocale')[0:2] # locale_path = os.path.join( # self.plugin_dir, # 'i18n', # 'SharedSqlQueries_{}.qm'.format(locale)) # # if os.path.exists(locale_path): # self.translator = QTranslator() # self.translator.load(locale_path) # # if qVersion() > '4.3.3': # QCoreApplication.installTranslator(self.translator) # Declare instance attributes self.actions = [] self.menu = self.tr(u'&Shared SQL Queries') self.toolbar = self.iface.addToolBar(u'SharedSqlQueries') self.toolbar.setObjectName(u'SharedSqlQueries') #print "** INITIALIZING SharedSqlQueries" #self.dockwidget = None #combo of queries files self.comboxQueries = None self.config = None self.queriesFolder = None self.dbrequest = None self.selectedQueryPath = None self.pluginIsActive = False # init related to config file. Return False if no config.json has been found def init_config(self): #just once if self.config is not None: return True #config file (in plugin directory) : configpath = os.path.dirname(__file__) + '/config.json' try: self.config = JsonFile(configpath) except IOError: # copy default config json if it does not exist self.errorMessage(self.tr( u"No config.json file found ! A default one is created but you have to edit it (in your plugin directory)")) configpath_default = os.path.dirname(__file__) + '/config_default.json' copyfile(configpath_default, configpath) return False self.queriesFolder = self.config.value("queries_folder") #database self.dbrequest = Connection(self.config.value("bdpostgis")) return True # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass #return QCoreApplication.translate('SharedSqlQueries', message) return translate.tr(message) #simplier def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu( self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/SharedSqlQueries/icon.png' self.add_action( icon_path, text=self.tr(u'Shared SQL Queries'), callback=self.run, parent=self.iface.mainWindow()) #combo of queries files self.comboxQueries = QComboBox() self.comboxQueries.setMinimumHeight(27) self.comboxQueries.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) # its model : self.queriesModel = QStandardItemModel() self.comboxQueries.setModel(self.queriesModel) # and its view (treeview) : self.queriesView = QTreeView() self.queriesView.setHeaderHidden(True) self.queriesView.setMinimumHeight(300) setWidgetWidth(self.comboxQueries, 0, 0) #no visible self.comboxQueries.setView(self.queriesView) # capture last clicked query self.queriesView.activated.connect(self.querySelected) self.queriesView.pressed.connect(self.querySelected) self.toolbar.addWidget(self.comboxQueries) #Run query button self.buttonRunQuery = QPushButton(self.tr("Open")) setWidgetWidth(self.buttonRunQuery, 0, 0) #no visible self.buttonRunQuery.clicked.connect(self.runQuery) self.toolbar.addWidget(self.buttonRunQuery) #-------------------------------------------------------------------------- def onClosePlugin(self): """Cleanup necessary items here when plugin dockwidget is closed""" #print "** CLOSING SharedSqlQueries" # disconnects #self.dockwidget.closingPlugin.disconnect(self.onClosePlugin) self.pluginIsActive = False def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" #print "** UNLOAD SharedSqlQueries" for action in self.actions: self.iface.removePluginMenu( self.tr(u'Shared SQL Queries'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar #-------------------------------------------------------------------------- def run(self): """Run method that loads and starts the plugin""" # look for config file (required at the first run) if not self.init_config(): # invalid config file return if not self.pluginIsActive: self.pluginIsActive = True #first init #print "** STARTING SharedSqlQueries" # dockwidget may not exist if: # first run of plugin # removed on close (see self.onClosePlugin method) #if self.dockwidget == None: # Create the dockwidget (after translation) and keep reference # self.dockwidget = SharedSqlQueriesDockWidget() # connect to provide cleanup on closing of dockwidget #self.dockwidget.closingPlugin.connect(self.onClosePlugin) # show the dockwidget #self.iface.addDockWidget(Qt.TopDockWidgetArea, self.dockwidget) #self.dockwidget.show() #Togle visibility of toolbar options (set width coz visible is not usable in toolbar) show_options = (self.comboxQueries.minimumWidth() == 0) if show_options: self.updateComboQueries() setWidgetWidth(self.comboxQueries, 300, 300) setWidgetWidth(self.buttonRunQuery, 0, 120) else: setWidgetWidth(self.comboxQueries, 0, 0) setWidgetWidth(self.buttonRunQuery, 0, 0) #display an error def errorMessage(self, message): self.iface.messageBar().pushMessage(self.tr(u"Error"), message, level=QgsMessageBar.CRITICAL) #read file in query folder and show them in combo tree view def updateComboQueries(self): self.queriesModel.clear() self.queriesModel.setHorizontalHeaderLabels(['Files']) item = QStandardItem(self.tr(u"Query File")) item.setSelectable(False) self.queriesModel.appendRow(item) # read directories with sql files for path, dirs, files in os.walk(self.queriesFolder): for rep in dirs: item = QStandardItem(rep) item.setData(rep, Qt.UserRole) item.setSelectable(False) self.queriesModel.appendRow(item) # in each directory, look for sql files for nomfich in glob.glob(self.queriesFolder + "/" + rep + "/*.sql"): fileName, fileExtension = os.path.splitext(os.path.basename(nomfich)) # one item found subitem = QStandardItem(fileName) subitem.setData(nomfich, Qt.UserRole) item.appendRow(subitem) #last selected query def querySelected(self, index): item = self.queriesModel.itemFromIndex(index) self.selectedQueryPath = item.data(Qt.UserRole) #run selected query def runQuery(self): #print self.comboxQueries.currentText() #print self.selectedQueryPath try: query = CustomSqlQuery(self.selectedQueryPath) except UnicodeDecodeError: self.errorMessage(self.tr(u"Query File is not UTF8 encoded ! Please convert it to UTF8 !")) return except SyntaxError as e: self.errorMessage(e.text) return except Exception as e: self.errorMessage(str(e)) return # open param dialog dialog = QueryParamDialog(self.iface, self.dbrequest, query, self.toolbar) if dialog.exec_() == QDialog.Accepted: if dialog.errorMessage != "": self.errorMessage(dialog.errorMessage) return # format query as a Qgis readable sql source sql = query.updateFinalSql() QgsMessageLog.logMessage(sql, "SharedSql", QgsMessageLog.INFO) # add the corresponding layer try: # save query in a memory layer if query.headerValue("layer storage") == "memory": layer = self.dbrequest.sqlAddMemoryLayer(sql, query.headerValue("layer name"), query.headerValue("gid"), query.headerValue("geom")) # save query directly as a sql layer elif query.headerValue("layer storage") == "source": layer = self.dbrequest.sqlAddLayer(sql, query.headerValue("layer name"), query.headerValue("gid"), query.headerValue("geom")) # save query in a file layer else: type = query.headerValue("layer storage").lower() driver = None if type == "geojson": driver = "GeoJSON" if type == "shp": driver = "ESRI Shapefile" if driver is None: self.errorMessage(self.tr(u"Unknown file type : ") + str(type)) return directory = query.headerValue("layer directory") if directory is None: self.errorMessage(self.tr(u"No layer directory parameter found in query !")) return name = query.headerValue("layer name") # new layer name and file name if file already exists filepath = directory + "/" + name + "." + type filecount = 1 new_name = name while os.path.exists(filepath): # file already exists filecount += 1 new_name = name + "_" + str(filecount) filepath = directory + "/" + new_name + "." + type name = new_name #wait cursor QApplication.setOverrideCursor(Qt.WaitCursor) # add new layer layer = self.dbrequest.sqlAddFileLayer(sql, driver, filepath, name, query.headerValue("gid"), query.headerValue("geom")) QApplication.setOverrideCursor(Qt.ArrowCursor) except SyntaxError as e: QApplication.setOverrideCursor(Qt.ArrowCursor) # sql is correct but does not fit QGIS requirement (like '%' char) self.errorMessage(self.tr(e.text)) return if layer is None: self.errorMessage(self.tr(u"Unable to add a layer corresponding to this query !") + sql) # sql which is used in layer query print makeSqlValidForLayer(sql) return # if there's a qml style file corresponding to the query, apply it to the newly added layer if os.path.exists(query.styleFilePath()): layer.loadNamedStyle(query.styleFilePath())
class TablaturePart(_base.Part): """Base class for tablature instrument part types.""" octave = 0 clef = None transposition = None tunings = () # may contain a list of tunings. tabFormat = '' # can contain a tablatureFormat value. def createWidgets(self, layout): self.staffTypeLabel = QLabel() self.staffType = QComboBox() self.staffTypeLabel.setBuddy(self.staffType) self.staffType.setModel( listmodel.ListModel(tablatureStaffTypes, self.staffType, display=listmodel.translate)) box = QHBoxLayout() layout.addLayout(box) box.addWidget(self.staffTypeLabel) box.addWidget(self.staffType) if self.tunings: self.createTuningWidgets(layout) self.staffType.activated.connect(self.slotTabEnable) self.slotTabEnable(0) def createTuningWidgets(self, layout): self.tuningLabel = QLabel() self.tuning = QComboBox() self.tuningLabel.setBuddy(self.tuning) tunings = [('', lambda: _("Default"))] tunings.extend(self.tunings) tunings.append(('', lambda: _("Custom tuning"))) self.tuning.setModel( listmodel.ListModel(tunings, self.tuning, display=listmodel.translate_index(1))) self.tuning.setCurrentIndex(1) self.customTuning = QLineEdit(enabled=False) completionmodel.complete( self.customTuning, "scorewiz/completion/plucked_strings/custom_tuning") self.tuning.currentIndexChanged.connect(self.slotCustomTuningEnable) box = QHBoxLayout() layout.addLayout(box) box.addWidget(self.tuningLabel) box.addWidget(self.tuning) layout.addWidget(self.customTuning) def translateWidgets(self): self.staffTypeLabel.setText(_("Staff type:")) self.staffType.model().update() if self.tunings: self.translateTuningWidgets() def translateTuningWidgets(self): self.tuningLabel.setText(_("Tuning:")) self.customTuning.setToolTip('<qt>' + _( "Select custom tuning in the combobox and " "enter a custom tuning here, e.g. <code>e, a d g b e'</code>. " "Use absolute note names in the same language as you want to use " "in your document (by default: \"nederlands\").")) try: self.customTuning.setPlaceholderText(_("Custom tuning...")) except AttributeError: pass # only in Qt 4.7+ self.tuning.model().update() def slotTabEnable(self, enable): """Called when the user changes the staff type. Non-zero if the user wants a TabStaff. """ self.tuning.setEnabled(bool(enable)) if enable: self.slotCustomTuningEnable(self.tuning.currentIndex()) else: self.customTuning.setEnabled(False) def slotCustomTuningEnable(self, index): self.customTuning.setEnabled(index > len(self.tunings)) def voiceCount(self): """Returns the number of voices. Inherit to make this user-settable. """ return 1 def build(self, data, builder): # First make assignments for the voices we want to create numVoices = self.voiceCount() if numVoices == 1: voices = (ly.util.mkid(data.name()), ) elif numVoices == 2: order = 1, 2 voices = 'upper', 'lower' elif numVoices == 3: order = 1, 3, 2 voices = 'upper', 'middle', 'lower' else: order = 1, 2, 3, 4 voices = [ ly.util.mkid(data.name(), "voice") + ly.util.int2text(i) for i in order ] assignments = [ data.assignMusic(name, self.octave, self.transposition) for name in voices ] staffType = self.staffType.currentIndex() if staffType in (0, 2): # create a normal staff staff = ly.dom.Staff() seq = ly.dom.Seqr(staff) if self.clef: ly.dom.Clef(self.clef, seq) mus = ly.dom.Simr(seq) for a in assignments[:-1]: ly.dom.Identifier(a.name, mus) ly.dom.VoiceSeparator(mus) ly.dom.Identifier(assignments[-1].name, mus) builder.setMidiInstrument(staff, self.midiInstrument) if staffType in (1, 2): # create a tab staff tabstaff = ly.dom.TabStaff() if self.tabFormat: tabstaff.getWith()['tablatureFormat'] = ly.dom.Scheme( self.tabFormat) self.setTunings(tabstaff) sim = ly.dom.Simr(tabstaff) if numVoices == 1: ly.dom.Identifier(assignments[0].name, sim) else: for num, a in zip(order, assignments): s = ly.dom.Seq(ly.dom.TabVoice(parent=sim)) ly.dom.Text('\\voice' + ly.util.int2text(num), s) ly.dom.Identifier(a.name, s) if staffType == 0: # only a normal staff p = staff elif staffType == 1: # only a TabStaff builder.setMidiInstrument(tabstaff, self.midiInstrument) p = tabstaff else: # both TabStaff and normal staff p = ly.dom.StaffGroup() s = ly.dom.Sim(p) s.append(staff) s.append(tabstaff) builder.setInstrumentNamesFromPart(p, self, data) data.nodes.append(p) def setTunings(self, tab): if self.tunings: i = self.tuning.currentIndex() if i == 0: return elif i > len(self.tunings): value = ly.dom.Text("\\stringTuning <{0}>".format( self.customTuning.text())) else: tuning = self.tunings[self.tuning.currentIndex() - 1][0] value = ly.dom.Scheme(tuning) tab.getWith()['stringTunings'] = value
class ExportPanel(QWidget): updateExportButton = pyqtSignal(str, bool) runExport = pyqtSignal(dict) def __init__(self, parent=None): QWidget.__init__(self, parent) self.setMinimumWidth(500) self.setMinimumHeight(200) self._dynamic = False self.setWindowTitle("Export data") self.activateWindow() layout = QFormLayout() current_case = getCurrentCaseName() self._case_model = AllCasesModel() self._case_combo = QComboBox() self._case_combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self._case_combo.setMinimumContentsLength(20) self._case_combo.setModel(self._case_model) self._case_combo.setCurrentIndex(self._case_model.indexOf(current_case)) layout.addRow("Select case:", self._case_combo) self._export_keyword_model = ExportKeywordModel() self._kw_model = self._export_keyword_model.getKeyWords() self._keywords = QComboBox() self._keywords.addItems(self._kw_model) layout.addRow("Select keyword:", self._keywords) self._active_realizations_model = ActiveRealizationsModel() self._active_realizations_field = StringBox(self._active_realizations_model, "config/simulation/active_realizations") self._active_realizations_field.setValidator(RangeStringArgument()) self._active_realizations_field.getValidationSupport().validationChanged.connect(self.validateExportDialog) layout.addRow("Active realizations:", self._active_realizations_field) file_name_button = QToolButton() file_name_button.setText("Browse") file_name_button.clicked.connect(self.selectFileDirectory) self._defaultPath = QDir.currentPath() + "/export" self._file_name = QLineEdit() self._file_name.setEnabled(False) self._file_name.setText(self._defaultPath) self._file_name.textChanged.connect(self.validateExportDialog) self._file_name.setMinimumWidth(250) file_name_layout = QHBoxLayout() file_name_layout.addWidget(self._file_name) file_name_layout.addWidget(file_name_button) layout.addRow("Select directory to save files to:", file_name_layout) self._gen_kw_file_types = ["Parameter list", "Template based"] self._field_kw_file_types = ["Eclipse GRDECL", "RMS roff"] self._gen_data_file_types = ["Gen data"] self._file_type_model = self._field_kw_file_types self._file_type_combo = QComboBox() self._file_type_combo.setSizeAdjustPolicy(QComboBox.AdjustToContents) self._file_type_combo.addItems(self._file_type_model) layout.addRow("Select file format:", self._file_type_combo) self._report_step = QLineEdit() layout.addRow("Report step:", self._report_step) self._gen_data_report_step_model = [] self._gen_data_report_step = QComboBox() layout.addRow("Report step:", self._gen_data_report_step) self.setLayout(layout) self._keywords.currentIndexChanged.connect(self.keywordSelected) self.keywordSelected() def selectFileDirectory(self): directory = QFileDialog().getExistingDirectory(self, "Directory", self._file_name.text(), QFileDialog.ShowDirsOnly) if str(directory).__len__() > 0: self._file_name.setText(str(directory)) def updateFileExportType(self, keyword): self._file_type_combo.clear() if self._export_keyword_model.isGenKw(keyword): self._file_type_model = self._gen_kw_file_types elif self._export_keyword_model.isGenParamKw(keyword): self._file_type_model = self._gen_data_file_types elif self._export_keyword_model.isGenDataKw(keyword): self._file_type_model = self._gen_data_file_types else: self._file_type_model = self._field_kw_file_types self._file_type_combo.addItems(self._file_type_model) def export(self): keyword = self._kw_model[self._keywords.currentIndex()] report_step = self.getReportStep(keyword) all_cases = self._case_model.getAllItems() selected_case = all_cases[self._case_combo.currentIndex()] path = self._file_name.text() iactive = self._active_realizations_model.getActiveRealizationsMask() file_type_key = self._file_type_model[self._file_type_combo.currentIndex()] values = {"keyword": keyword, "report_step": report_step, "iactive": iactive, "file_type_key": file_type_key, "path": path, "selected_case": selected_case} self.runExport.emit(values) def getReportStep(self, key): report_step = 0 if self._dynamic: report_step = self._report_step.text() if self._export_keyword_model.isGenParamKw(key): return report_step if self._export_keyword_model.isGenDataKw(key): lst = self._gen_data_report_step_model idx = self._gen_data_report_step.currentIndex() if lst and len(lst) > idx: report_step = lst[idx] else: raise IndexError('No such model step: %d. Valid range: [0, %d)' % (idx, len(lst))) return report_step def keywordSelected(self): key = self._kw_model[self._keywords.currentIndex()] self.updateFileExportType(key) self._dynamic = False if self._export_keyword_model.isFieldKw(key): self._dynamic = self._export_keyword_model.isDynamicField(key) self._report_step.setVisible(self._dynamic) self.layout().labelForField(self._report_step).setVisible(self._dynamic) self._gen_data_report_step.setVisible(self._export_keyword_model.isGenDataKw(key)) self.layout().labelForField(self._gen_data_report_step).setVisible(self._export_keyword_model.isGenDataKw(key)) if self._export_keyword_model.isGenDataKw(key): data = self._export_keyword_model.getGenDataReportSteps(key) self._gen_data_report_step_model = data self._gen_data_report_step.clear() self._gen_data_report_step.addItems(self._gen_data_report_step_model) def setSelectedCase(self, selected_case): self._case_combo.setCurrentIndex(self._case_model.indexOf(selected_case)) def validateExportDialog(self): validRealizations = False if self._active_realizations_field.isValid(): validRealizations = True path = str(self._file_name.text()) validPath = len(path) > 0 if validRealizations and validPath: self.updateExportButton.emit("export", True) else: self.updateExportButton.emit("export", False)
class TablaturePart(_base.Part): """Base class for tablature instrument part types.""" octave = 0 clef = None transposition = None tunings = () # may contain a list of tunings. tabFormat = "" # can contain a tablatureFormat value. def createWidgets(self, layout): self.staffTypeLabel = QLabel() self.staffType = QComboBox() self.staffTypeLabel.setBuddy(self.staffType) self.staffType.setModel(listmodel.ListModel(tablatureStaffTypes, self.staffType, display=listmodel.translate)) box = QHBoxLayout() layout.addLayout(box) box.addWidget(self.staffTypeLabel) box.addWidget(self.staffType) if self.tunings: self.createTuningWidgets(layout) self.staffType.activated.connect(self.slotTabEnable) self.slotTabEnable(0) def createTuningWidgets(self, layout): self.tuningLabel = QLabel() self.tuning = QComboBox() self.tuningLabel.setBuddy(self.tuning) tunings = [("", lambda: _("Default"))] tunings.extend(self.tunings) self.tuning.setModel(listmodel.ListModel(tunings, self.tuning, display=listmodel.translate_index(1))) self.tuning.setCurrentIndex(1) box = QHBoxLayout() layout.addLayout(box) box.addWidget(self.tuningLabel) box.addWidget(self.tuning) def translateWidgets(self): self.staffTypeLabel.setText(_("Staff type:")) self.staffType.model().update() if self.tunings: self.translateTuningWidgets() def translateTuningWidgets(self): self.tuningLabel.setText(_("Tuning:")) self.tuning.model().update() def slotTabEnable(self, enable): """Called when the user changes the staff type. Non-zero if the user wants a TabStaff. """ self.tuning.setEnabled(bool(enable)) def voiceCount(self): """Returns the number of voices. Inherit to make this user-settable. """ return 1 def build(self, data, builder): # First make assignments for the voices we want to create numVoices = self.voiceCount() if numVoices == 1: voices = (ly.util.mkid(data.name()),) elif numVoices == 2: order = 1, 2 voices = "upper", "lower" elif numVoices == 3: order = 1, 3, 2 voices = "upper", "middle", "lower" else: order = 1, 2, 3, 4 voices = [ly.util.mkid(data.name(), "voice") + ly.util.int2text(i) for i in order] assignments = [data.assignMusic(name, self.octave, self.transposition) for name in voices] staffType = self.staffType.currentIndex() if staffType in (0, 2): # create a normal staff staff = ly.dom.Staff() seq = ly.dom.Seqr(staff) if self.clef: ly.dom.Clef(self.clef, seq) mus = ly.dom.Simr(seq) for a in assignments[:-1]: ly.dom.Identifier(a.name, mus) ly.dom.VoiceSeparator(mus) ly.dom.Identifier(assignments[-1].name, mus) builder.setMidiInstrument(staff, self.midiInstrument) if staffType in (1, 2): # create a tab staff tabstaff = ly.dom.TabStaff() if self.tabFormat: tabstaff.getWith()["tablatureFormat"] = ly.dom.Scheme(self.tabFormat) self.setTunings(tabstaff) sim = ly.dom.Simr(tabstaff) if numVoices == 1: ly.dom.Identifier(assignments[0].name, sim) else: for num, a in zip(order, assignments): s = ly.dom.Seq(ly.dom.TabVoice(parent=sim)) ly.dom.Text("\\voice" + ly.util.int2text(num), s) ly.dom.Identifier(a.name, s) if staffType == 0: # only a normal staff p = staff elif staffType == 1: # only a TabStaff builder.setMidiInstrument(tabstaff, self.midiInstrument) p = tabstaff else: # both TabStaff and normal staff p = ly.dom.StaffGroup() s = ly.dom.Sim(p) s.append(staff) s.append(tabstaff) builder.setInstrumentNamesFromPart(p, self, data) data.nodes.append(p) def setTunings(self, tab): if self.tunings and self.tuning.currentIndex() > 0: tuning = self.tunings[self.tuning.currentIndex() - 1][0] tab.getWith()["stringTunings"] = ly.dom.Scheme(tuning)
def createEditor(self, parent, _QStyleOptionViewItem, index): combo = QComboBox(parent) combo.setModel(self._combo_model) return combo
class Dialog(QDialog): def __init__(self, mainwindow): super(Dialog, self).__init__(mainwindow) self._document = None layout = QGridLayout() self.setLayout(layout) self.versionLabel = QLabel() self.lilyChooser = lilychooser.LilyChooser() self.outputLabel = QLabel() self.outputCombo = QComboBox() self.resolutionLabel = QLabel() self.resolutionCombo = QComboBox(editable=True) self.antialiasLabel = QLabel() self.antialiasSpin = QSpinBox(minimum=1, maximum=128, value=1) self.modeLabel = QLabel() self.modeCombo = QComboBox() self.englishCheck = QCheckBox() self.deleteCheck = QCheckBox() self.commandLineLabel = QLabel() self.commandLine = QTextEdit(acceptRichText=False) self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttons.button(QDialogButtonBox.Ok).setIcon( icons.get("lilypond-run")) userguide.addButton(self.buttons, "engrave_custom") self.resolutionCombo.addItems(['100', '200', '300', '600', '1200']) self.resolutionCombo.setCurrentIndex(2) self.modeCombo.addItems(['preview', 'publish', 'debug']) layout.addWidget(self.versionLabel, 0, 0) layout.addWidget(self.lilyChooser, 0, 1, 1, 3) layout.addWidget(self.outputLabel, 1, 0) layout.addWidget(self.outputCombo, 1, 1, 1, 3) layout.addWidget(self.resolutionLabel, 2, 0) layout.addWidget(self.resolutionCombo, 2, 1) layout.addWidget(self.antialiasLabel, 2, 2, Qt.AlignRight) layout.addWidget(self.antialiasSpin, 2, 3) layout.addWidget(self.modeLabel, 3, 0) layout.addWidget(self.modeCombo, 3, 1, 1, 3) layout.addWidget(self.englishCheck, 4, 0, 1, 4) layout.addWidget(self.deleteCheck, 5, 0, 1, 4) layout.addWidget(self.commandLineLabel, 6, 0, 1, 4) layout.addWidget(self.commandLine, 7, 0, 1, 4) layout.addWidget(widgets.Separator(), 8, 0, 1, 4) layout.addWidget(self.buttons, 9, 0, 1, 4) app.translateUI(self) qutil.saveDialogSize(self, "engrave/custom/dialog/size", QSize(480, 260)) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) model = listmodel.ListModel(formats, display=lambda f: f.title(), icon=lambda f: icons.file_type(f.type)) self.outputCombo.setModel(model) s = QSettings() s.beginGroup("lilypond_settings") self.englishCheck.setChecked(s.value("no_translation", False, bool)) self.deleteCheck.setChecked( s.value("delete_intermediate_files", True, bool)) if s.value("default_output_target", "pdf", type("")) == "svg": self.outputCombo.setCurrentIndex(3) app.jobFinished.connect(self.slotJobFinished) self.outputCombo.currentIndexChanged.connect(self.makeCommandLine) self.modeCombo.currentIndexChanged.connect(self.makeCommandLine) self.deleteCheck.toggled.connect(self.makeCommandLine) self.resolutionCombo.editTextChanged.connect(self.makeCommandLine) self.antialiasSpin.valueChanged.connect(self.makeCommandLine) self.makeCommandLine() panelmanager.manager( mainwindow).layoutcontrol.widget().optionsChanged.connect( self.makeCommandLine) def translateUI(self): self.setWindowTitle(app.caption(_("Engrave custom"))) self.versionLabel.setText(_("LilyPond Version:")) self.outputLabel.setText(_("Output Format:")) self.resolutionLabel.setText(_("Resolution:")) self.antialiasLabel.setText(_("Antialias Factor:")) self.modeLabel.setText(_("Engraving mode:")) self.modeCombo.setItemText(0, _("Preview")) self.modeCombo.setItemText(1, _("Publish")) self.modeCombo.setItemText(2, _("Layout Control")) self.englishCheck.setText(_("Run LilyPond with English messages")) self.deleteCheck.setText(_("Delete intermediate output files")) self.commandLineLabel.setText(_("Command line:")) self.buttons.button(QDialogButtonBox.Ok).setText(_("Run LilyPond")) self.outputCombo.update() def slotJobFinished(self, doc): if doc == self._document: self.buttons.button(QDialogButtonBox.Ok).setEnabled(True) self._document = None def setDocument(self, doc): self.lilyChooser.setLilyPondInfo(command.info(doc)) if jobmanager.isRunning(doc): self._document = doc self.buttons.button(QDialogButtonBox.Ok).setEnabled(False) def makeCommandLine(self): """Reads the widgets and builds a command line.""" f = formats[self.outputCombo.currentIndex()] self.resolutionCombo.setEnabled('resolution' in f.widgets) self.antialiasSpin.setEnabled('antialias' in f.widgets) cmd = ["$lilypond"] if self.modeCombo.currentIndex() == 0: # preview mode cmd.append('-dpoint-and-click') elif self.modeCombo.currentIndex() == 1: # publish mode cmd.append('-dno-point-and-click') else: # debug mode args = panelmanager.manager( self.parent()).layoutcontrol.widget().preview_options() cmd.extend(args) if self.deleteCheck.isChecked(): cmd.append('-ddelete-intermediate-files') else: cmd.append('-dno-delete-intermediate-files') d = { 'version': self.lilyChooser.lilyPondInfo().version, 'resolution': self.resolutionCombo.currentText(), 'antialias': self.antialiasSpin.value(), } cmd.append("$include") cmd.extend(f.options(d)) cmd.append("$filename") self.commandLine.setText(' '.join(cmd)) def getJob(self, document): """Returns a Job to start.""" filename, includepath = documentinfo.info(document).jobinfo(True) i = self.lilyChooser.lilyPondInfo() cmd = [] for t in self.commandLine.toPlainText().split(): if t == '$lilypond': cmd.append(i.abscommand() or i.command) elif t == '$filename': cmd.append(filename) elif t == '$include': cmd.extend('-I' + path for path in includepath) else: cmd.append(t) j = job.Job() j.directory = os.path.dirname(filename) j.command = cmd if self.englishCheck.isChecked(): j.environment['LANG'] = 'C' j.setTitle("{0} {1} [{2}]".format(os.path.basename(i.command), i.versionString(), document.documentName())) return j
class CaseInitializationConfigurationPanel(RowPanel): @may_take_a_long_time def __init__(self): RowPanel.__init__(self, "Case Management") self.setMinimumWidth(600) self.addCreateNewCaseTab() self.addInitializeFromScratchTab() self.addInitializeFromExistingTab() self.addShowCaseInfo() self.endTabs() def newValidatedKeywordPopup(self, existing_keywords): dialog = ValidatedDialog("New case", "Enter name of new case:", existing_keywords) return dialog.showAndTell() def addCreateNewCaseTab(self): self.startTabs("Create new case") case_list = KeywordList(CaseList(), "Available cases", "init/case_list") case_list.setMaximumWidth(250) case_list.newKeywordPopup = self.newValidatedKeywordPopup case_list.setSelectable(False) self.addRow(case_list) def addInitializeFromScratchTab(self): self.addTab("Initialize from scratch") case_model = CaseSelectorModel() case_selector = ComboChoice(case_model, "Target case", "init/current_case_selection") self.addRow(case_selector) row_group = RowGroup() parameter_model = InitializationParametersModel() parameter_check_list = CheckList(parameter_model, "Parameters", "init/select_parameters") parameter_check_list.setMaximumWidth(300) row_group.addWidget(parameter_check_list) member_model = InitializationMembersModel() member_check_list = CheckList(member_model, "Members", "init/select_members") member_check_list.setMaximumWidth(150) row_group.addWidget(member_check_list) self.addRow(row_group) self.addSpace(10) initialize_from_scratch = InitializeFromScratchModel() self.addRow(Button(initialize_from_scratch, help_link="init/initialize_from_scratch")) self.addSpace(10) def addInitializeFromExistingTab(self): self.addTab("Initialize from existing") case_model = CaseSelectorModel() target_case_selector = ComboChoice(case_model, "Target case", "init/current_case_selection") self.addRow(target_case_selector) initialized_cases = ComboChoice(InitializedCaseSelectorModel(), "Source case", "init/source_case") self.addRow(initialized_cases) #self.addRow("State", "Analyzed/Forecast") timestep_group = RowGroup("Timestep") history_length = HistoryLengthModel() history_length_spinner = IntegerSpinner(history_length, "Timestep", "config/init/history_length") timestep_group.addWidget(history_length_spinner) initial = QToolButton() initial.setText("Initial") initial.clicked.connect(history_length.setToMin) timestep_group.addWidget(initial) end_of_time = QToolButton() end_of_time.setText("End of time") end_of_time.clicked.connect(history_length.setToMax) timestep_group.addWidget(end_of_time) timestep_group.addGroupStretch() self.addRow(timestep_group) self.addSpace(10) row_group = RowGroup() parameter_model = InitializationParametersModel() parameter_check_list = CheckList(parameter_model, "Parameters", "init/select_parameters") parameter_check_list.setMaximumWidth(300) row_group.addWidget(parameter_check_list) member_model = InitializationMembersModel() member_check_list = CheckList(member_model, "Members", "init/select_members") member_check_list.setMaximumWidth(150) row_group.addWidget(member_check_list) self.addRow(row_group) self.addSpace(10) initialize_from_existing = InitializeFromExistingCaseModel() self.addRow(Button(initialize_from_existing, help_link="init/initialize_from_existing")) self.addSpace(10) def addShowCaseInfo(self): self.addTab("Case Info") case_widget = HelpedWidget("Select case", "init/select_case_for_info") model = AllCasesModel() self.combo = QComboBox() self.combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self.combo.setMinimumContentsLength(20) self.combo.setModel(model) self.combo.currentIndexChanged.connect(self.showInfoForCase) case_widget.addWidget(self.combo) case_widget.addStretch() self.addRow(case_widget) area_widget = HelpedWidget("Case info", "init/selected_case_info") self.text_area = QTextEdit() self.text_area.setReadOnly(True) self.text_area.setMinimumHeight(300) area_widget.addWidget(self.text_area) area_widget.addStretch() self.addRow(area_widget) choice = CaseSelectorModel().getCurrentChoice() self.combo.setCurrentIndex(model.indexOf(choice)) def showInfoForCase(self): case = self.combo.currentText() states = CaseList().getCaseRealizationStates(str(case)) html = "<table>" for index in range(len(states)): html += "<tr><td width=30>%d.</td><td>%s</td></tr>" % (index, str(states[index])) html += "</table>" self.text_area.setHtml(html)
class DlgAnular( QDialog ): def __init__( self , numero, parent = None ): super( DlgAnular, self ).__init__( parent ) self.cboConceptos = QComboBox( self ) self.cboConceptos.setObjectName( "cboConceptos" ) self.txtObservaciones = QPlainTextEdit( self ) self.txtObservaciones.setObjectName( "txtObservaciones" ) self.setupUi() #QtCore.QMetaObject.connectSlotsByName(self) self.conceptosmodel = QSqlQueryModel() self.conceptosmodel.setQuery( """ SELECT idconcepto,descripcion FROM conceptos c WHERE idtipodoc = %d ; """ % constantes.IDANULACION ) self.cboConceptos.setModel( self.conceptosmodel ) self.cboConceptos.setCurrentIndex( -1 ) self.cboConceptos.setModelColumn( 1 ) self.numero = numero self.lblnfactura2.setText( str( self.numero ) ) def setupUi( self ): self.setObjectName( "frmAnulaciones" ) self.setWindowTitle( "Seleccione la factura a anular" ) self.resize( 485, 300 ) gridLayout = QGridLayout( self ) gridLayout.setObjectName( "gridLayout" ) lblnfactura = QLabel( self ) lblnfactura.setObjectName( "lblnfactura" ) lblnfactura.setText( "# Factura" ) gridLayout.addWidget( lblnfactura, 0, 0, 1, 1 ) self.lblnfactura2 = QLabel( self ) self.lblnfactura2.setFrameShape( QFrame.Box ) self.lblnfactura2.setText( "" ) self.lblnfactura2.setObjectName( "lblnfactura2" ) gridLayout.addWidget( self.lblnfactura2, 0, 1, 1, 1 ) lblconcepto = QLabel( self ) lblconcepto.setObjectName( "lblconcepto" ) lblconcepto.setText( "Concepto" ) gridLayout.addWidget( lblconcepto, 1, 0, 1, 1 ) gridLayout.addWidget( self.cboConceptos, 1, 1, 1, 1 ) lblobservaciones = QLabel( self ) lblobservaciones.setObjectName( "lblobservaciones" ) lblobservaciones.setText( "Observaciones" ) gridLayout.addWidget( lblobservaciones, 2, 0, 1, 1 ) gridLayout.addWidget( self.txtObservaciones, 3, 1, 1, 1 ) buttonBox = QDialogButtonBox( self ) buttonBox.setOrientation( Qt.Horizontal ) buttonBox.setStandardButtons( QDialogButtonBox.Cancel | QDialogButtonBox.Ok ) buttonBox.setObjectName( "buttonBox" ) gridLayout.addWidget( buttonBox, 4, 0, 1, 2 ) buttonBox.accepted.connect( self.accept ) buttonBox.rejected.connect( self.reject )
class LoadResultsPanel(QWidget): def __init__(self): QWidget.__init__(self) self.setMinimumWidth(500) self.setMinimumHeight(200) self._dynamic = False self.setWindowTitle("Load results manually") self.activateWindow() layout = QFormLayout() current_case = getCurrentCaseName() run_path_text = QTextEdit() run_path_text.setText(self.readCurrentRunPath()) run_path_text.setDisabled(True) run_path_text.setFixedHeight(80) layout.addRow("Load data from current run path: ", run_path_text) self._case_model = AllCasesModel() self._case_combo = QComboBox() self._case_combo.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLength) self._case_combo.setMinimumContentsLength(20) self._case_combo.setModel(self._case_model) self._case_combo.setCurrentIndex( self._case_model.indexOf(current_case)) layout.addRow("Load into case:", self._case_combo) self._active_realizations_model = ActiveRealizationsModel() self._active_realizations_field = StringBox( self._active_realizations_model, "load_results_manually/Realizations") self._active_realizations_field.setValidator(RangeStringArgument()) layout.addRow("Realizations to load:", self._active_realizations_field) iterations_count = LoadResultsModel.getIterationCount() self._iterations_model = ValueModel(iterations_count) self._iterations_field = StringBox(self._iterations_model, "load_results_manually/iterations") self._iterations_field.setValidator(IntegerArgument()) layout.addRow("Iteration to load:", self._iterations_field) self.setLayout(layout) def readCurrentRunPath(self): current_case = getCurrentCaseName() run_path = LoadResultsModel.getCurrentRunPath() run_path = run_path.replace("<ERTCASE>", current_case) run_path = run_path.replace("<ERT-CASE>", current_case) return run_path def load(self): all_cases = self._case_model.getAllItems() selected_case = all_cases[self._case_combo.currentIndex()] realizations = self._active_realizations_model.getActiveRealizationsMask( ) iteration = self._iterations_model.getValue() try: if iteration is None: iteration = '' iteration = int(iteration) except ValueError as e: print( 'Expected a (whole) number in iteration field, got "%s". Error message: %s.' % (iteration, e)) return False loaded = LoadResultsModel.loadResults(selected_case, realizations, iteration) if loaded > 0: print('Successfully loaded %d realisations.' % loaded) else: print('No realisations loaded.') return loaded def setCurrectCase(self): current_case = getCurrentCaseName() self._case_combo.setCurrentIndex( self._case_model.indexOf(current_case))
def createEditor(self, parent, option, index): cb = QComboBox(parent) cb.setModel(self.sortingModel) cb.showPopup() return cb
class Widget(QWidget): def __init__(self, dockwidget): super(Widget, self).__init__(dockwidget) self._document = None self._fileSelector = QComboBox(editable=True, insertPolicy=QComboBox.NoInsert) widgets.drag.ComboDrag(self._fileSelector).role = Qt.UserRole self._fileSelector.lineEdit().setReadOnly(True) self._fileSelector.lineEdit().setFocusPolicy(Qt.NoFocus) self._stopButton = QToolButton() self._playButton = QToolButton() self._timeSlider = QSlider(Qt.Horizontal, tracking=False, singleStep=500, pageStep=5000, invertedControls=True) self._display = Display() self._tempoFactor = QSlider(Qt.Vertical, minimum=-50, maximum=50, singleStep=1, pageStep=5) grid = QGridLayout(spacing=0) self.setLayout(grid) grid.addWidget(self._fileSelector, 0, 0, 1, 3) grid.addWidget(self._stopButton, 1, 0) grid.addWidget(self._playButton, 1, 1) grid.addWidget(self._timeSlider, 1, 2) grid.addWidget(self._display, 2, 0, 1, 3) grid.addWidget(self._tempoFactor, 0, 3, 3, 1) # size policy of combo p = self._fileSelector.sizePolicy() p.setHorizontalPolicy(QSizePolicy.Ignored) self._fileSelector.setSizePolicy(p) # size policy of combo popup p = self._fileSelector.view().sizePolicy() p.setHorizontalPolicy(QSizePolicy.MinimumExpanding) self._fileSelector.view().setSizePolicy(p) self._player = player.Player() self._outputCloseTimer = QTimer(interval=60000, singleShot=True, timeout=self.closeOutput) self._timeSliderTicker = QTimer(interval=200, timeout=self.updateTimeSlider) self._fileSelector.activated[int].connect(self.slotFileSelected) self._tempoFactor.valueChanged.connect(self.slotTempoChanged) self._timeSlider.valueChanged.connect(self.slotTimeSliderChanged) self._timeSlider.sliderMoved.connect(self.slotTimeSliderMoved) self._player.beat.connect(self.updateDisplayBeat) self._player.time.connect(self.updateDisplayTime) self._player.stateChanged.connect(self.slotPlayerStateChanged) self.slotPlayerStateChanged(False) dockwidget.mainwindow().currentDocumentChanged.connect( self.loadResults) app.documentLoaded.connect(self.slotUpdatedFiles) app.jobFinished.connect(self.slotUpdatedFiles) app.aboutToQuit.connect(self.stop) midihub.aboutToRestart.connect(self.slotAboutToRestart) midihub.settingsChanged.connect(self.clearMidiSettings, -100) midihub.settingsChanged.connect(self.readMidiSettings) app.documentClosed.connect(self.slotDocumentClosed) app.translateUI(self) self.readMidiSettings() d = dockwidget.mainwindow().currentDocument() if d: self.loadResults(d) def translateUI(self): self._tempoFactor.setToolTip(_("Tempo")) def slotAboutToRestart(self): self.stop() self._player.set_output(None) def clearMidiSettings(self): """Called first when settings are changed.""" self.stop() self._outputCloseTimer.stop() self._player.set_output(None) def readMidiSettings(self): """Called after clearMidiSettings(), and on first init.""" pass def openOutput(self): """Called when playing starts. Ensures an output port is opened.""" self._outputCloseTimer.stop() if not self._player.output(): p = QSettings().value("midi/player/output_port", midihub.default_output(), type("")) o = midihub.output_by_name(p) if o: self._player.set_output(output.Output(o)) def closeOutput(self): """Called when the output close timer fires. Closes the output.""" self._player.set_output(None) def slotPlayerStateChanged(self, playing): ac = self.parentWidget().actionCollection # setDefaultAction also adds the action for b in self._stopButton, self._playButton: while b.actions(): b.removeAction(b.actions()[0]) if playing: self._timeSliderTicker.start() self._stopButton.setDefaultAction(ac.midi_stop) self._playButton.setDefaultAction(ac.midi_pause) else: self._timeSliderTicker.stop() self.updateTimeSlider() self._stopButton.setDefaultAction(ac.midi_restart) self._playButton.setDefaultAction(ac.midi_play) # close the output if the preference is set if QSettings().value("midi/close_outputs", False, bool): self._outputCloseTimer.start() def play(self): """Starts the MIDI player, opening an output if necessary.""" if not self._player.is_playing() and not self._player.has_events(): self.restart() self.openOutput() if not self._player.output(): self._display.statusMessage(_("No output found!")) self._player.start() def stop(self): """Stops the MIDI player.""" self._player.stop() def restart(self): """Restarts the MIDI player. If another file is in the file selector, or the file was updated, the new file is loaded. """ self._player.seek(0) self.updateTimeSlider() self._display.reset() if self._document: files = midifiles.MidiFiles.instance(self._document) index = self._fileSelector.currentIndex() if files and (files.song(index) is not self._player.song()): self.loadSong(index) def slotTempoChanged(self, value): """Called when the user drags the tempo.""" # convert -50 to 50 to 0.5 to 2.0 factor = 2**(value / 50.0) self._player.set_tempo_factor(factor) self._display.setTempo("{0}%".format(int(factor * 100))) def slotTimeSliderChanged(self, value): self._player.seek(value) self._display.setTime(value) if self._player.song(): self._display.setBeat(*self._player.song().beat(value)[1:]) def slotTimeSliderMoved(self, value): self._display.setTime(value) if self._player.song(): self._display.setBeat(*self._player.song().beat(value)[1:]) def updateTimeSlider(self): if not self._timeSlider.isSliderDown(): with qutil.signalsBlocked(self._timeSlider): self._timeSlider.setMaximum(self._player.total_time()) self._timeSlider.setValue(self._player.current_time()) def updateDisplayBeat(self, measnum, beat, num, den): if not self._timeSlider.isSliderDown(): self._display.setBeat(measnum, beat, num, den) def updateDisplayTime(self, time): if not self._timeSlider.isSliderDown(): self._display.setTime(time) def slotUpdatedFiles(self, document): """Called when there are new MIDI files.""" if document == self.parentWidget().mainwindow().currentDocument(): self.loadResults(document) def loadResults(self, document): self._document = document files = midifiles.MidiFiles.instance(document) self._fileSelector.setModel(files.model()) if files: self._fileSelector.setCurrentIndex(files.current) if not self._player.is_playing(): self.loadSong(files.current) def loadSong(self, index): files = midifiles.MidiFiles.instance(self._document) self._player.set_song(files.song(index)) m, s = divmod(self._player.total_time() // 1000, 60) name = self._fileSelector.currentText() self.updateTimeSlider() self._display.reset() self._display.statusMessage(_("midi lcd screen", "LOADED"), name, _("midi lcd screen", "TOTAL"), "{0}:{1:02}".format(m, s)) def slotFileSelected(self, index): if self._document: self._player.stop() files = midifiles.MidiFiles.instance(self._document) if files: files.current = index self.restart() def slotDocumentClosed(self, document): if document == self._document: self._document = None self._fileSelector.clear() self._player.stop() self._player.clear() self.updateTimeSlider() self._display.reset()
class Dialog(QDialog): def __init__(self, mainwindow): super(Dialog, self).__init__(mainwindow) self._document = None layout = QGridLayout() self.setLayout(layout) self.versionLabel = QLabel() self.lilyChooser = lilychooser.LilyChooser() self.outputLabel = QLabel() self.outputCombo = QComboBox() self.resolutionLabel = QLabel() self.resolutionCombo = QComboBox(editable=True) self.antialiasLabel = QLabel() self.antialiasSpin = QSpinBox(minimum=1, maximum=128, value=1) self.modeLabel = QLabel() self.modeCombo = QComboBox() self.englishCheck = QCheckBox() self.deleteCheck = QCheckBox() self.commandLineLabel = QLabel() self.commandLine = QTextEdit(acceptRichText=False) self.buttons = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttons.button(QDialogButtonBox.Ok).setIcon(icons.get("lilypond-run")) userguide.addButton(self.buttons, "engrave_custom") self.resolutionCombo.addItems(['100', '200', '300', '600', '1200']) self.resolutionCombo.setCurrentIndex(2) self.modeCombo.addItems(['preview', 'publish', 'debug']) layout.addWidget(self.versionLabel, 0, 0) layout.addWidget(self.lilyChooser, 0, 1, 1, 3) layout.addWidget(self.outputLabel, 1, 0) layout.addWidget(self.outputCombo, 1, 1, 1, 3) layout.addWidget(self.resolutionLabel, 2, 0) layout.addWidget(self.resolutionCombo, 2, 1) layout.addWidget(self.antialiasLabel, 2, 2, Qt.AlignRight) layout.addWidget(self.antialiasSpin, 2, 3) layout.addWidget(self.modeLabel, 3, 0) layout.addWidget(self.modeCombo, 3, 1, 1, 3) layout.addWidget(self.englishCheck, 4, 0, 1, 4) layout.addWidget(self.deleteCheck, 5, 0, 1, 4) layout.addWidget(self.commandLineLabel, 6, 0, 1, 4) layout.addWidget(self.commandLine, 7, 0, 1, 4) layout.addWidget(widgets.Separator(), 8, 0, 1, 4) layout.addWidget(self.buttons, 9, 0, 1, 4) app.translateUI(self) qutil.saveDialogSize(self, "engrave/custom/dialog/size", QSize(480, 260)) self.buttons.accepted.connect(self.accept) self.buttons.rejected.connect(self.reject) model = listmodel.ListModel(formats, display=lambda f: f.title(), icon=lambda f: icons.file_type(f.type)) self.outputCombo.setModel(model) s = QSettings() s.beginGroup("lilypond_settings") self.englishCheck.setChecked( s.value("no_translation", False, bool)) self.deleteCheck.setChecked( s.value("delete_intermediate_files", True, bool)) if s.value("default_output_target", "pdf", type("")) == "svg": self.outputCombo.setCurrentIndex(3) app.jobFinished.connect(self.slotJobFinished) self.outputCombo.currentIndexChanged.connect(self.makeCommandLine) self.modeCombo.currentIndexChanged.connect(self.makeCommandLine) self.deleteCheck.toggled.connect(self.makeCommandLine) self.resolutionCombo.editTextChanged.connect(self.makeCommandLine) self.antialiasSpin.valueChanged.connect(self.makeCommandLine) self.makeCommandLine() panelmanager.manager(mainwindow).layoutcontrol.widget().optionsChanged.connect(self.makeCommandLine) def translateUI(self): self.setWindowTitle(app.caption(_("Engrave custom"))) self.versionLabel.setText(_("LilyPond Version:")) self.outputLabel.setText(_("Output Format:")) self.resolutionLabel.setText(_("Resolution:")) self.antialiasLabel.setText(_("Antialias Factor:")) self.modeLabel.setText(_("Engraving mode:")) self.modeCombo.setItemText(0, _("Preview")) self.modeCombo.setItemText(1, _("Publish")) self.modeCombo.setItemText(2, _("Layout Control")) self.englishCheck.setText(_("Run LilyPond with English messages")) self.deleteCheck.setText(_("Delete intermediate output files")) self.commandLineLabel.setText(_("Command line:")) self.buttons.button(QDialogButtonBox.Ok).setText(_("Run LilyPond")) self.outputCombo.update() def slotJobFinished(self, doc): if doc == self._document: self.buttons.button(QDialogButtonBox.Ok).setEnabled(True) self._document = None def setDocument(self, doc): self.lilyChooser.setLilyPondInfo(command.info(doc)) job = jobmanager.job(doc) if job and job.isRunning() and not jobattributes.get(job).hidden: self._document = doc self.buttons.button(QDialogButtonBox.Ok).setEnabled(False) def makeCommandLine(self): """Reads the widgets and builds a command line.""" f = formats[self.outputCombo.currentIndex()] self.resolutionCombo.setEnabled('resolution' in f.widgets) self.antialiasSpin.setEnabled('antialias' in f.widgets) cmd = ["$lilypond"] if self.modeCombo.currentIndex() == 0: # preview mode cmd.append('-dpoint-and-click') elif self.modeCombo.currentIndex() == 1: # publish mode cmd.append('-dno-point-and-click') else: # debug mode args = panelmanager.manager(self.parent()).layoutcontrol.widget().preview_options() cmd.extend(args) if self.deleteCheck.isChecked(): cmd.append('-ddelete-intermediate-files') else: cmd.append('-dno-delete-intermediate-files') d = { 'version': self.lilyChooser.lilyPondInfo().version, 'resolution': self.resolutionCombo.currentText(), 'antialias': self.antialiasSpin.value(), } cmd.append("$include") cmd.extend(f.options(d)) cmd.append("$filename") self.commandLine.setText(' '.join(cmd)) def getJob(self, document): """Returns a Job to start.""" filename, includepath = documentinfo.info(document).jobinfo(True) i = self.lilyChooser.lilyPondInfo() cmd = [] for t in self.commandLine.toPlainText().split(): if t == '$lilypond': cmd.append(i.abscommand() or i.command) elif t == '$filename': cmd.append(filename) elif t == '$include': cmd.extend('-I' + path for path in includepath) else: cmd.append(t) j = job.Job() j.directory = os.path.dirname(filename) j.command = cmd if self.englishCheck.isChecked(): j.environment['LANG'] = 'C' j.setTitle("{0} {1} [{2}]".format( os.path.basename(i.command), i.versionString(), document.documentName())) return j
class Drums(_base.Part): @staticmethod def title(_=_base.translate): return _("Drums") @staticmethod def short(_=_base.translate): return _("abbreviation for Drums", "Dr.") def createWidgets(self, layout): self.voicesLabel = QLabel() self.voices = QSpinBox(minimum=1, maximum=4, value=1) self.drumStyleLabel = QLabel() self.drumStyle = QComboBox() self.drumStyle.setModel( listmodel.ListModel(drumStyles, self.drumStyle, display=listmodel.translate)) self.drumStems = QCheckBox() box = QHBoxLayout() box.addWidget(self.voicesLabel) box.addWidget(self.voices) layout.addLayout(box) box = QHBoxLayout() box.addWidget(self.drumStyleLabel) box.addWidget(self.drumStyle) layout.addLayout(box) layout.addWidget(self.drumStems) def translateWidgets(self): self.voicesLabel.setText(_("Voices:")) self.drumStyleLabel.setText(_("Style:")) self.drumStems.setText(_("Remove stems")) self.drumStems.setToolTip(_("Remove the stems from the drum notes.")) self.drumStyle.model().update() def assignDrums(self, data, name=None): """Creates an empty name = \drummode assignment. Returns the assignment. """ a = data.assign(name) s = ly.dom.DrumMode(a) ly.dom.Identifier(data.globalName, s) ly.dom.LineComment(_("Drums follow here."), s) ly.dom.BlankLine(s) return a def build(self, data, builder): p = ly.dom.DrumStaff() s = ly.dom.Simr(p) if self.voices.value() > 1: for i in range(1, self.voices.value() + 1): q = ly.dom.Seq(ly.dom.DrumVoice(parent=s)) ly.dom.Text('\\voice' + ly.util.int2text(i), q) a = self.assignDrums(data, 'drum' + ly.util.int2text(i)) ly.dom.Identifier(a.name, q) else: a = self.assignDrums(data, 'drum') ly.dom.Identifier(a.name, s) builder.setInstrumentNamesFromPart(p, self, data) i = self.drumStyle.currentIndex() if i > 0: v = ('drums', 'timbales', 'congas', 'bongos', 'percussion')[i] p.getWith()['drumStyleTable'] = ly.dom.Scheme(v + '-style') v = (5, 2, 2, 2, 1)[i] ly.dom.Line("\\override StaffSymbol #'line-count = #{0}".format(v), p.getWith()) if self.drumStems.isChecked(): ly.dom.Line("\\override Stem #'stencil = ##f", p.getWith()) ly.dom.Line( "\\override Stem #'length = #3 % " + _("keep some distance."), p.getWith()) data.nodes.append(p)
class LoadResultsPanel(QWidget): def __init__(self): QWidget.__init__(self) self.setMinimumWidth(500) self.setMinimumHeight(200) self.__dynamic = False self.setWindowTitle("Load results manually") self.activateWindow() layout = QFormLayout() current_case = CaseSelectorModel().getCurrentChoice() run_path_text = QTextEdit() run_path_text.setText(self.readCurrentRunPath()) run_path_text.setDisabled(True) run_path_text.setFixedHeight(80) layout.addRow("Load data from current run path: ",run_path_text) self.__case_model = AllCasesModel() self.__case_combo = QComboBox() self.__case_combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self.__case_combo.setMinimumContentsLength(20) self.__case_combo.setModel(self.__case_model) self.__case_combo.setCurrentIndex(self.__case_model.indexOf(current_case)) layout.addRow("Load into case:",self.__case_combo) self.__active_realizations_model = LoadResultsRealizationsModel(EnsembleSizeModel().getValue()) self.__active_realizations_field = StringBox(self.__active_realizations_model, "Realizations to load", "load_results_manually/Realizations") self.__active_realizations_field.setValidator(RangeStringArgument()) layout.addRow(self.__active_realizations_field.getLabel(), self.__active_realizations_field) self.__iterations_count = LoadResultsModel().getIterationCount() self._iterations_model = LoadResultsIterationsModel(self.__iterations_count) self._iterations_field = StringBox(self._iterations_model, "Iteration to load", "load_results_manually/iterations") self._iterations_field.setValidator(IntegerArgument()) layout.addRow(self._iterations_field.getLabel(), self._iterations_field) self.setLayout(layout) def readCurrentRunPath(self): current_case = CaseSelectorModel().getCurrentChoice() run_path = LoadResultsModel().getCurrentRunPath() run_path = run_path.replace("<ERTCASE>",current_case) run_path = run_path.replace("<ERT-CASE>",current_case) return run_path def load(self): all_cases = self.__case_model.getAllItems() selected_case = all_cases[self.__case_combo.currentIndex()] realizations = self.__active_realizations_model.getActiveRealizationsMask() iteration = self._iterations_model.getActiveIteration() LoadResultsModel().loadResults(selected_case, realizations, iteration) def setCurrectCase(self): current_case = CaseSelectorModel().getCurrentChoice() self.__case_combo.setCurrentIndex(self.__case_model.indexOf(current_case))
class CaseInitializationConfigurationPanel(RowPanel): @may_take_a_long_time def __init__(self): RowPanel.__init__(self, "Case Management") self.setMinimumWidth(600) self.addCreateNewCaseTab() self.addInitializeFromScratchTab() self.addInitializeFromExistingTab() self.addShowCaseInfo() self.endTabs() def newValidatedKeywordPopup(self, existing_keywords): dialog = ValidatedDialog("New case", "Enter name of new case:", existing_keywords) return dialog.showAndTell() def addCreateNewCaseTab(self): self.startTabs("Create new case") case_list = KeywordList(CaseList(), "Available cases", "init/case_list") case_list.setMaximumWidth(250) case_list.newKeywordPopup = self.newValidatedKeywordPopup case_list.setSelectable(False) self.addRow(case_list) def addInitializeFromScratchTab(self): self.addTab("Initialize from scratch") case_model = CaseSelectorModel() case_selector = ComboChoice(case_model, "Target case", "init/current_case_selection") self.addRow(case_selector) row_group = RowGroup() parameter_model = InitializationParametersModel() parameter_check_list = CheckList(parameter_model, "Parameters", "init/select_parameters") parameter_check_list.setMaximumWidth(300) row_group.addWidget(parameter_check_list) member_model = InitializationMembersModel() member_check_list = CheckList(member_model, "Members", "init/select_members") member_check_list.setMaximumWidth(150) row_group.addWidget(member_check_list) self.addRow(row_group) self.addSpace(10) initialize_from_scratch = InitializeFromScratchModel() self.addRow( Button(initialize_from_scratch, help_link="init/initialize_from_scratch")) self.addSpace(10) def addInitializeFromExistingTab(self): self.addTab("Initialize from existing") case_model = CaseSelectorModel() target_case_selector = ComboChoice(case_model, "Target case", "init/current_case_selection") self.addRow(target_case_selector) initialized_cases = ComboChoice(InitializedCaseSelectorModel(), "Source case", "init/source_case") self.addRow(initialized_cases) #self.addRow("State", "Analyzed/Forecast") timestep_group = RowGroup("Timestep") history_length = HistoryLengthModel() history_length_spinner = IntegerSpinner(history_length, "Timestep", "config/init/history_length") timestep_group.addWidget(history_length_spinner) initial = QToolButton() initial.setText("Initial") initial.clicked.connect(history_length.setToMin) timestep_group.addWidget(initial) end_of_time = QToolButton() end_of_time.setText("End of time") end_of_time.clicked.connect(history_length.setToMax) timestep_group.addWidget(end_of_time) timestep_group.addGroupStretch() self.addRow(timestep_group) self.addSpace(10) row_group = RowGroup() parameter_model = InitializationParametersModel() parameter_check_list = CheckList(parameter_model, "Parameters", "init/select_parameters") parameter_check_list.setMaximumWidth(300) row_group.addWidget(parameter_check_list) member_model = InitializationMembersModel() member_check_list = CheckList(member_model, "Members", "init/select_members") member_check_list.setMaximumWidth(150) row_group.addWidget(member_check_list) self.addRow(row_group) self.addSpace(10) initialize_from_existing = InitializeFromExistingCaseModel() self.addRow( Button(initialize_from_existing, help_link="init/initialize_from_existing")) self.addSpace(10) def addShowCaseInfo(self): self.addTab("Case Info") case_widget = HelpedWidget("Select case", "init/select_case_for_info") model = AllCasesModel() self.combo = QComboBox() self.combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self.combo.setMinimumContentsLength(20) self.combo.setModel(model) self.combo.currentIndexChanged.connect(self.showInfoForCase) case_widget.addWidget(self.combo) case_widget.addStretch() self.addRow(case_widget) area_widget = HelpedWidget("Case info", "init/selected_case_info") self.text_area = QTextEdit() self.text_area.setReadOnly(True) self.text_area.setMinimumHeight(300) area_widget.addWidget(self.text_area) area_widget.addStretch() self.addRow(area_widget) choice = CaseSelectorModel().getCurrentChoice() self.combo.setCurrentIndex(model.indexOf(choice)) def showInfoForCase(self): case = self.combo.currentText() states = CaseList().getCaseRealizationStates(str(case)) html = "<table>" for index in range(len(states)): html += "<tr><td width=30>%d.</td><td>%s</td></tr>" % ( index, str(states[index])) html += "</table>" self.text_area.setHtml(html)
from PyQt4.QtCore import Qt from PyQt4.QtGui import QApplication, QListWidget, QComboBox, QListView, QStringListModel import sys if __name__ == '__main__': app = QApplication(sys.argv) app.setStyle('cleanlooks') data = ['one', 'two', 'three', 'four'] listView = QListView() listView.show() model = QStringListModel(data) listView.setModel(model) # listWidget = QListWidget() # listWidget.show() # listWidget.addItems(data) # count = listWidget.count() # for i in range(count): # item = listWidget.item(i) # item.setFlags(item.flags() | Qt.ItemIsEditable) comboBox = QComboBox() comboBox.setModel(model) comboBox.show() sys.exit(app.exec_())
class LoadResultsPanel(QWidget): def __init__(self): QWidget.__init__(self) self.setMinimumWidth(500) self.setMinimumHeight(200) self._dynamic = False self.setWindowTitle("Load results manually") self.activateWindow() layout = QFormLayout() current_case = getCurrentCaseName() run_path_text = QTextEdit() run_path_text.setText(self.readCurrentRunPath()) run_path_text.setDisabled(True) run_path_text.setFixedHeight(80) layout.addRow("Load data from current run path: ", run_path_text) self._case_model = AllCasesModel() self._case_combo = QComboBox() self._case_combo.setSizeAdjustPolicy( QComboBox.AdjustToMinimumContentsLength) self._case_combo.setMinimumContentsLength(20) self._case_combo.setModel(self._case_model) self._case_combo.setCurrentIndex( self._case_model.indexOf(current_case)) layout.addRow("Load into case:", self._case_combo) self._active_realizations_model = ActiveRealizationsModel() self._active_realizations_field = StringBox( self._active_realizations_model, "load_results_manually/Realizations") self._active_realizations_field.setValidator(RangeStringArgument()) layout.addRow("Realizations to load:", self._active_realizations_field) iterations_count = LoadResultsModel.getIterationCount() self._iterations_model = ValueModel(iterations_count) self._iterations_field = StringBox(self._iterations_model, "load_results_manually/iterations") self._iterations_field.setValidator(IntegerArgument(from_value=1)) layout.addRow("Iteration to load:", self._iterations_field) self.setLayout(layout) def readCurrentRunPath(self): current_case = getCurrentCaseName() run_path = LoadResultsModel.getCurrentRunPath() run_path = run_path.replace("<ERTCASE>", current_case) run_path = run_path.replace("<ERT-CASE>", current_case) return run_path def load(self): all_cases = self._case_model.getAllItems() selected_case = all_cases[self._case_combo.currentIndex()] realizations = self._active_realizations_model.getActiveRealizationsMask( ) iteration = self._iterations_model.getActiveIteration() LoadResultsModel.loadResults(selected_case, realizations, iteration) def setCurrectCase(self): current_case = getCurrentCaseName() self._case_combo.setCurrentIndex( self._case_model.indexOf(current_case))
class InstrumentNames(QGroupBox): def __init__(self, parent): super(InstrumentNames, self).__init__(parent, checkable=True, checked=True) grid = QGridLayout() self.setLayout(grid) self.firstSystemLabel = QLabel() self.firstSystem = QComboBox() self.firstSystemLabel.setBuddy(self.firstSystem) self.otherSystemsLabel = QLabel() self.otherSystems = QComboBox() self.otherSystemsLabel.setBuddy(self.otherSystems) self.languageLabel = QLabel() self.language = QComboBox() self.languageLabel.setBuddy(self.language) self.firstSystem.setModel( listmodel.ListModel((lambda: _("Long"), lambda: _("Short")), self.firstSystem, display=listmodel.translate)) self.otherSystems.setModel( listmodel.ListModel( (lambda: _("Long"), lambda: _("Short"), lambda: _("None")), self.otherSystems, display=listmodel.translate)) self._langs = l = ['', 'C'] l.extend(sorted(po.available())) def display(lang): if lang == 'C': return _("English (untranslated)") elif not lang: return _("Default") return language_names.languageName(lang, po.setup.current()) self.language.setModel( listmodel.ListModel(l, self.language, display=display)) grid.addWidget(self.firstSystemLabel, 0, 0) grid.addWidget(self.firstSystem, 0, 1) grid.addWidget(self.otherSystemsLabel, 1, 0) grid.addWidget(self.otherSystems, 1, 1) grid.addWidget(self.languageLabel, 2, 0) grid.addWidget(self.language, 2, 1) app.translateUI(self) self.loadSettings() self.window().finished.connect(self.saveSettings) def translateUI(self): self.setTitle(_("Instrument names")) self.firstSystemLabel.setText(_("First system:")) self.otherSystemsLabel.setText(_("Other systems:")) self.languageLabel.setText(_("Language:")) self.firstSystem.setToolTip( _("Use long or short instrument names before the first system.")) self.otherSystems.setToolTip( _("Use short, long or no instrument names before the next systems." )) self.language.setToolTip( _("Which language to use for the instrument names.")) self.firstSystem.model().update() self.otherSystems.model().update() self.language.model().update() def getLanguage(self): """Returns the language the user has set. '' means: default (use same translation as system) 'C' means: English (untranslated) or a language code that is available in Frescobaldi's translation. """ return self._langs[self.language.currentIndex()] def loadSettings(self): s = QSettings() s.beginGroup('scorewiz/instrumentnames') self.setChecked(s.value('enabled', True, bool)) allow = ['long', 'short'] first = s.value('first', '', type("")) self.firstSystem.setCurrentIndex( allow.index(first) if first in allow else 0) allow = ['long', 'short', 'none'] other = s.value('other', '', type("")) self.otherSystems.setCurrentIndex( allow.index(other) if other in allow else 2) language = s.value('language', '', type("")) self.language.setCurrentIndex( self._langs.index(language) if language in self._langs else 0) def saveSettings(self): s = QSettings() s.beginGroup('scorewiz/instrumentnames') s.setValue('enable', self.isChecked()) s.setValue('first', ('long', 'short')[self.firstSystem.currentIndex()]) s.setValue('other', ('long', 'short', 'none')[self.otherSystems.currentIndex()]) s.setValue('language', self._langs[self.language.currentIndex()])
def createEditor(self, parent, option, index): cb = QComboBox(parent) cb.setModel(self.sortingModel) cb.showPopup() return cb
class ScoreProperties(object): """This is only the base class, it should be mixed in with a widget or a different way.""" def createWidgets(self): """Creates all widgets.""" self.createKeySignatureWidget() self.createTimeSignatureWidget() self.createPickupWidget() self.createMetronomeWidget() self.createTempoWidget() def layoutWidgets(self, layout): """Adds all widgets to a vertical layout.""" self.layoutKeySignatureWidget(layout) self.layoutTimeSignatureWidget(layout) self.layoutPickupWidget(layout) self.layoutMetronomeWidget(layout) self.layoutTempoWidget(layout) def translateWidgets(self): self.translateKeySignatureWidget() self.translateTimeSignatureWidget() self.translatePickupWidget() self.tranlateMetronomeWidget() self.translateTempoWidget() def ly(self, node, builder): """Adds appropriate LilyPond command nodes to the parent node. Settings from the builder are used where that makes sense. All widgets must be present. """ self.lyKeySignature(node, builder) self.lyTimeSignature(node, builder) self.lyPickup(node, builder) self.lyTempo(node, builder) def globalSection(self, builder): """Returns a sequential expression between { } containing the output of ly().""" seq = ly.dom.Seq() self.ly(seq, builder) return seq # Key signature def createKeySignatureWidget(self): self.keySignatureLabel = QLabel() self.keyNote = QComboBox() self.keyNote.setModel(listmodel.ListModel(keyNames['nederlands'], self.keyNote)) self.keyMode = QComboBox() self.keyMode.setModel(listmodel.ListModel(modes, self.keyMode, display=listmodel.translate_index(1))) self.keySignatureLabel.setBuddy(self.keyNote) def translateKeySignatureWidget(self): self.keySignatureLabel.setText(_("Key signature:")) self.keyMode.model().update() def layoutKeySignatureWidget(self, layout): """Adds our widgets to a layout, assuming it is a QVBoxLayout.""" box = QHBoxLayout() box.addWidget(self.keySignatureLabel) box.addWidget(self.keyNote) box.addWidget(self.keyMode) layout.addLayout(box) def setPitchLanguage(self, language='nederlands'): self.keyNote.model()._data = keyNames[language or 'nederlands'] self.keyNote.model().update() def lyKeySignature(self, node, builder): """Adds the key signature to the ly.dom node parent.""" note, alter = keys[self.keyNote.currentIndex()] alter = fractions.Fraction(alter, 2) mode = modes[self.keyMode.currentIndex()][0] ly.dom.KeySignature(note, alter, mode, node).after = 1 # Time signature def createTimeSignatureWidget(self): self.timeSignatureLabel = QLabel() self.timeSignature = QComboBox(editable=True) icons = { '(4/4)': symbols.icon('time_c44'), '(2/2)': symbols.icon('time_c22'), } self.timeSignature.setModel(listmodel.ListModel(timeSignaturePresets, self.timeSignature, icon=icons.get)) self.timeSignature.setCompleter(None) self.timeSignatureLabel.setBuddy(self.timeSignature) def translateTimeSignatureWidget(self): self.timeSignatureLabel.setText(_("Time signature:")) def layoutTimeSignatureWidget(self, layout): """Adds our widgets to a layout, assuming it is a QVBoxLayout.""" box = QHBoxLayout() box.addWidget(self.timeSignatureLabel) box.addWidget(self.timeSignature) layout.addLayout(box) def lyTimeSignature(self, node, builder): """Adds the time signature to the ly.dom node parent.""" sig = self.timeSignature.currentText().strip() if '+' in sig: pass # TODO: implement support for \compoundMeter else: if sig == '(2/2)': ly.dom.TimeSignature(2, 2, node).after = 1 elif sig == '(4/4)': ly.dom.TimeSignature(4, 4, node).after = 1 else: match = re.search(r'(\d+).*?(\d+)', sig) if match: if builder.lyVersion >= (2, 11, 44): ly.dom.Line(r"\numericTimeSignature", node) else: ly.dom.Line(r"\override Staff.TimeSignature #'style = #'()", node) num, beat = map(int, match.group(1, 2)) ly.dom.TimeSignature(num, beat, node).after = 1 # Pickup bar def createPickupWidget(self): self.pickupLabel = QLabel() self.pickup = QComboBox() pickups = [''] pickups.extend(durations) self.pickup.setModel(listmodel.ListModel(pickups, self.pickup, display = lambda item: item or _("None"), icon = lambda item: symbols.icon('note_{0}'.format(item.replace('.', 'd'))) if item else None)) self.pickup.view().setIconSize(QSize(22, 22)) self.pickupLabel.setBuddy(self.pickup) def translatePickupWidget(self): self.pickupLabel.setText(_("Pickup measure:")) self.pickup.model().update() def layoutPickupWidget(self, layout): box = QHBoxLayout() box.addWidget(self.pickupLabel) box.addWidget(self.pickup) layout.addLayout(box) def lyPickup(self, node, builder): if self.pickup.currentIndex() > 0: dur, dots = partialDurations[self.pickup.currentIndex() - 1] ly.dom.Partial(dur, dots, parent=node) # Metronome value def createMetronomeWidget(self): self.metronomeLabel = QLabel() self.metronomeNote = QComboBox() self.metronomeNote.setModel(listmodel.ListModel(durations, display=None, icon = lambda item: symbols.icon('note_{0}'.format(item.replace('.', 'd'))))) self.metronomeNote.setCurrentIndex(durations.index('4')) self.metronomeNote.view().setIconSize(QSize(22, 22)) self.metronomeEqualSign = QLabel('=') self.metronomeEqualSign.setFixedWidth(self.metronomeEqualSign.minimumSizeHint().width()) self.metronomeValue = QComboBox(editable=True) self.metronomeValue.setModel(listmodel.ListModel(metronomeValues, self.metronomeValue, display=format)) self.metronomeValue.setCompleter(None) self.metronomeValue.setValidator(QIntValidator(0, 999, self.metronomeValue)) self.metronomeValue.setCurrentIndex(metronomeValues.index(100)) self.metronomeTempo = widgets.tempobutton.TempoButton() self.metronomeTempo.tempo.connect(self.setMetronomeValue) self.metronomeLabel.setBuddy(self.metronomeNote) def layoutMetronomeWidget(self, layout): box = QHBoxLayout(spacing=0) box.addWidget(self.metronomeLabel) box.addWidget(self.metronomeNote) box.addWidget(self.metronomeEqualSign) box.addWidget(self.metronomeValue) box.addWidget(self.metronomeTempo) layout.addLayout(box) def tranlateMetronomeWidget(self): self.metronomeLabel.setText(_("Metronome mark:")) def setMetronomeValue(self, bpm): """ Tap the tempo tap button """ l = [abs(t - bpm) for t in metronomeValues] m = min(l) if m < 6: self.metronomeValue.setCurrentIndex(l.index(m)) # Tempo indication def createTempoWidget(self): self.tempoLabel = QLabel() self.tempo = widgets.lineedit.LineEdit() completionmodel.complete(self.tempo, "scorewiz/completion/scoreproperties/tempo") self.tempo.completer().setCaseSensitivity(Qt.CaseInsensitive) self.tempoLabel.setBuddy(self.tempo) def layoutTempoWidget(self, layout): box = QHBoxLayout() box.addWidget(self.tempoLabel) box.addWidget(self.tempo) layout.addLayout(box) def translateTempoWidget(self): self.tempoLabel.setText(_("Tempo indication:")) def lyTempo(self, node, builder): """Returns an appropriate tempo indication.""" text = self.tempo.text().strip() if builder.showMetronomeMark: dur = durations[self.metronomeNote.currentIndex()] val = self.metronomeValue.currentText() elif text: dur = None val = None else: return tempo = ly.dom.Tempo(dur, val, node) if text: ly.dom.QuotedString(text, tempo) def lyMidiTempo(self, node): """Sets the configured tempo in the tempoWholesPerMinute variable.""" node['tempoWholesPerMinute'] = ly.dom.Scheme(self.schemeMidiTempo()) def schemeMidiTempo(self): """Returns a string with the tempo like '(ly:make-moment 100 4)' from the settings.""" base, mul = midiDurations[self.metronomeNote.currentIndex()] val = int(self.metronomeValue.currentText()) * mul return "(ly:make-moment {0} {1})".format(val, base) def lySimpleMidiTempo(self, node): """Return a simple \tempo x=y node for the currently set tempo.""" dur = durations[self.metronomeNote.currentIndex()] val = self.metronomeValue.currentText() return ly.dom.Tempo(dur, val, node)
def setModel(self, model): QComboBox.setModel(self, model) self.pFilterModel.setSourceModel(model)
def setModel(self, model): QComboBox.setModel(self, model) self.pFilterModel.setSourceModel(model)
class ScoreProperties(object): """This is only the base class, it should be mixed in with a widget or a different way.""" def createWidgets(self): """Creates all widgets.""" self.createKeySignatureWidget() self.createTimeSignatureWidget() self.createPickupWidget() self.createMetronomeWidget() self.createTempoWidget() def layoutWidgets(self, layout): """Adds all widgets to a vertical layout.""" self.layoutKeySignatureWidget(layout) self.layoutTimeSignatureWidget(layout) self.layoutPickupWidget(layout) self.layoutMetronomeWidget(layout) self.layoutTempoWidget(layout) def translateWidgets(self): self.translateKeySignatureWidget() self.translateTimeSignatureWidget() self.translatePickupWidget() self.tranlateMetronomeWidget() self.translateTempoWidget() def ly(self, node, builder): """Adds appropriate LilyPond command nodes to the parent node. Settings from the builder are used where that makes sense. All widgets must be present. """ self.lyKeySignature(node, builder) self.lyTimeSignature(node, builder) self.lyPickup(node, builder) self.lyTempo(node, builder) def globalSection(self, builder): """Returns a sequential expression between { } containing the output of ly().""" seq = ly.dom.Seq() self.ly(seq, builder) return seq # Key signature def createKeySignatureWidget(self): self.keySignatureLabel = QLabel() self.keyNote = QComboBox() self.keyNote.setModel( listmodel.ListModel(keyNames['nederlands'], self.keyNote)) self.keyMode = QComboBox() self.keyMode.setModel( listmodel.ListModel(modes, self.keyMode, display=listmodel.translate_index(1))) self.keySignatureLabel.setBuddy(self.keyNote) def translateKeySignatureWidget(self): self.keySignatureLabel.setText(_("Key signature:")) self.keyMode.model().update() def layoutKeySignatureWidget(self, layout): """Adds our widgets to a layout, assuming it is a QVBoxLayout.""" box = QHBoxLayout() box.addWidget(self.keySignatureLabel) box.addWidget(self.keyNote) box.addWidget(self.keyMode) layout.addLayout(box) def setPitchLanguage(self, language='nederlands'): self.keyNote.model()._data = keyNames[language or 'nederlands'] self.keyNote.model().update() def lyKeySignature(self, node, builder): """Adds the key signature to the ly.dom node parent.""" note, alter = keys[self.keyNote.currentIndex()] alter = fractions.Fraction(alter, 2) mode = modes[self.keyMode.currentIndex()][0] ly.dom.KeySignature(note, alter, mode, node).after = 1 # Time signature def createTimeSignatureWidget(self): self.timeSignatureLabel = QLabel() self.timeSignature = QComboBox(editable=True) icons = { '(4/4)': symbols.icon('time_c44'), '(2/2)': symbols.icon('time_c22'), } self.timeSignature.setModel( listmodel.ListModel(timeSignaturePresets, self.timeSignature, icon=icons.get)) self.timeSignature.setCompleter(None) self.timeSignatureLabel.setBuddy(self.timeSignature) def translateTimeSignatureWidget(self): self.timeSignatureLabel.setText(_("Time signature:")) def layoutTimeSignatureWidget(self, layout): """Adds our widgets to a layout, assuming it is a QVBoxLayout.""" box = QHBoxLayout() box.addWidget(self.timeSignatureLabel) box.addWidget(self.timeSignature) layout.addLayout(box) def lyTimeSignature(self, node, builder): """Adds the time signature to the ly.dom node parent.""" sig = self.timeSignature.currentText().strip() if '+' in sig: pass # TODO: implement support for \compoundMeter else: if sig == '(2/2)': ly.dom.TimeSignature(2, 2, node).after = 1 elif sig == '(4/4)': ly.dom.TimeSignature(4, 4, node).after = 1 else: match = re.search(r'(\d+).*?(\d+)', sig) if match: if builder.lyVersion >= (2, 11, 44): ly.dom.Line(r"\numericTimeSignature", node) else: ly.dom.Line( r"\override Staff.TimeSignature #'style = #'()", node) num, beat = map(int, match.group(1, 2)) ly.dom.TimeSignature(num, beat, node).after = 1 # Pickup bar def createPickupWidget(self): self.pickupLabel = QLabel() self.pickup = QComboBox() pickups = [''] pickups.extend(durations) self.pickup.setModel( listmodel.ListModel(pickups, self.pickup, display=lambda item: item or _("None"), icon=lambda item: symbols.icon( 'note_{0}'.format(item.replace('.', 'd'))) if item else None)) self.pickup.view().setIconSize(QSize(22, 22)) self.pickupLabel.setBuddy(self.pickup) def translatePickupWidget(self): self.pickupLabel.setText(_("Pickup measure:")) self.pickup.model().update() def layoutPickupWidget(self, layout): box = QHBoxLayout() box.addWidget(self.pickupLabel) box.addWidget(self.pickup) layout.addLayout(box) def lyPickup(self, node, builder): if self.pickup.currentIndex() > 0: dur, dots = partialDurations[self.pickup.currentIndex() - 1] ly.dom.Partial(dur, dots, parent=node) # Metronome value def createMetronomeWidget(self): self.metronomeLabel = QLabel() self.metronomeNote = QComboBox() self.metronomeNote.setModel( listmodel.ListModel( durations, display=None, icon=lambda item: symbols.icon('note_{0}'.format( item.replace('.', 'd'))))) self.metronomeNote.setCurrentIndex(durations.index('4')) self.metronomeNote.view().setIconSize(QSize(22, 22)) self.metronomeEqualSign = QLabel('=') self.metronomeEqualSign.setFixedWidth( self.metronomeEqualSign.minimumSizeHint().width()) self.metronomeValue = QComboBox(editable=True) self.metronomeValue.setModel( listmodel.ListModel(metronomeValues, self.metronomeValue, display=format)) self.metronomeValue.setCompleter(None) self.metronomeValue.setValidator( QIntValidator(0, 999, self.metronomeValue)) self.metronomeValue.setCurrentIndex(metronomeValues.index(100)) self.metronomeTempo = widgets.tempobutton.TempoButton() self.metronomeTempo.tempo.connect(self.setMetronomeValue) self.metronomeLabel.setBuddy(self.metronomeNote) self.metronomeRound = QCheckBox() def layoutMetronomeWidget(self, layout): grid = QGridLayout() grid.addWidget(self.metronomeLabel, 0, 0) box = QHBoxLayout(spacing=0) box.addWidget(self.metronomeNote) box.addWidget(self.metronomeEqualSign) box.addWidget(self.metronomeValue) box.addWidget(self.metronomeTempo) grid.addLayout(box, 0, 1) grid.addWidget(self.metronomeRound, 1, 1) layout.addLayout(grid) def tranlateMetronomeWidget(self): self.metronomeLabel.setText(_("Metronome mark:")) self.metronomeRound.setText(_("Round tap tempo value")) self.metronomeRound.setToolTip( _("Round the entered tap tempo to a common value.")) def setMetronomeValue(self, bpm): """ Tap the tempo tap button """ if self.metronomeRound.isChecked(): l = [abs(t - bpm) for t in metronomeValues] m = min(l) if m < 6: self.metronomeValue.setCurrentIndex(l.index(m)) else: self.metronomeValue.setEditText(str(bpm)) # Tempo indication def createTempoWidget(self): self.tempoLabel = QLabel() self.tempo = widgets.lineedit.LineEdit() completionmodel.complete(self.tempo, "scorewiz/completion/scoreproperties/tempo") self.tempo.completer().setCaseSensitivity(Qt.CaseInsensitive) self.tempoLabel.setBuddy(self.tempo) def layoutTempoWidget(self, layout): box = QHBoxLayout() box.addWidget(self.tempoLabel) box.addWidget(self.tempo) layout.addLayout(box) def translateTempoWidget(self): self.tempoLabel.setText(_("Tempo indication:")) def lyTempo(self, node, builder): """Returns an appropriate tempo indication.""" text = self.tempo.text().strip() if builder.showMetronomeMark: dur = durations[self.metronomeNote.currentIndex()] val = self.metronomeValue.currentText() or '60' elif text: dur = None val = None else: return tempo = ly.dom.Tempo(dur, val, node) if text: ly.dom.QuotedString(text, tempo) def lyMidiTempo(self, node): """Sets the configured tempo in the tempoWholesPerMinute variable.""" node['tempoWholesPerMinute'] = ly.dom.Scheme(self.schemeMidiTempo()) def schemeMidiTempo(self): """Returns a string with the tempo like '(ly:make-moment 100 4)' from the settings.""" base, mul = midiDurations[self.metronomeNote.currentIndex()] val = int(self.metronomeValue.currentText() or '60') * mul return "(ly:make-moment {0} {1})".format(val, base) def lySimpleMidiTempo(self, node): r"""Return a simple \tempo x=y node for the currently set tempo.""" dur = durations[self.metronomeNote.currentIndex()] val = self.metronomeValue.currentText() or '60' return ly.dom.Tempo(dur, val, node)
class ExportPanel(QWidget): updateExportButton = pyqtSignal(str, bool) runExport = pyqtSignal(dict) def __init__(self, parent=None): QWidget.__init__(self, parent) self.setMinimumWidth(500) self.setMinimumHeight(200) self._dynamic = False self.setWindowTitle("Export data") self.activateWindow() layout = QFormLayout() current_case = getCurrentCaseName() self._case_model = AllCasesModel() self._case_combo = QComboBox() self._case_combo.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength) self._case_combo.setMinimumContentsLength(20) self._case_combo.setModel(self._case_model) self._case_combo.setCurrentIndex(self._case_model.indexOf(current_case)) layout.addRow("Select case:", self._case_combo) self._export_keyword_model = ExportKeywordModel() self._kw_model = self._export_keyword_model.getKeyWords() self._keywords = QComboBox() self._keywords.addItems(self._kw_model) layout.addRow("Select keyword:", self._keywords) self._active_realizations_model = ActiveRealizationsModel() self._active_realizations_field = StringBox(self._active_realizations_model, "config/simulation/active_realizations") self._active_realizations_field.setValidator(RangeStringArgument()) self._active_realizations_field.getValidationSupport().validationChanged.connect(self.validateExportDialog) layout.addRow("Active realizations:", self._active_realizations_field) file_name_button = QToolButton() file_name_button.setText("Browse") file_name_button.clicked.connect(self.selectFileDirectory) self._defaultPath = QDir.currentPath() + "/export" self._file_name = QLineEdit() self._file_name.setEnabled(False) self._file_name.setText(self._defaultPath) self._file_name.textChanged.connect(self.validateExportDialog) self._file_name.setMinimumWidth(250) file_name_layout = QHBoxLayout() file_name_layout.addWidget(self._file_name) file_name_layout.addWidget(file_name_button) layout.addRow("Select directory to save files to:", file_name_layout) self._gen_kw_file_types = ["Parameter list", "Template based"] self._field_kw_file_types = ["Eclipse GRDECL", "RMS roff"] self._gen_data_file_types = ["Gen data"] self._file_type_model = self._field_kw_file_types self._file_type_combo = QComboBox() self._file_type_combo.setSizeAdjustPolicy(QComboBox.AdjustToContents) self._file_type_combo.addItems(self._file_type_model) layout.addRow("Select file format:", self._file_type_combo) self._report_step = QLineEdit() layout.addRow("Report step:", self._report_step) self._gen_data_report_step_model = [] self._gen_data_report_step = QComboBox() layout.addRow("Report step:", self._gen_data_report_step) self.setLayout(layout) self._keywords.currentIndexChanged.connect(self.keywordSelected) self.keywordSelected() def selectFileDirectory(self): directory = QFileDialog().getExistingDirectory(self, "Directory", self._file_name.text(), QFileDialog.ShowDirsOnly) if str(directory).__len__() > 0: self._file_name.setText(str(directory)) def updateFileExportType(self, keyword): self._file_type_combo.clear() if self._export_keyword_model.isGenKw(keyword): self._file_type_model = self._gen_kw_file_types elif self._export_keyword_model.isGenParamKw(keyword): self._file_type_model = self._gen_data_file_types elif self._export_keyword_model.isGenDataKw(keyword): self._file_type_model = self._gen_data_file_types else: self._file_type_model = self._field_kw_file_types self._file_type_combo.addItems(self._file_type_model) def export(self): keyword = self._kw_model[self._keywords.currentIndex()] try: report_step = self.getReportStep(keyword) except IndexError as e: QMessageBox.question(self, 'Error', e.args[0], QMessageBox.NoButton) return all_cases = self._case_model.getAllItems() selected_case = all_cases[self._case_combo.currentIndex()] path = self._file_name.text() iactive = self._active_realizations_model.getActiveRealizationsMask() file_type_key = self._file_type_model[self._file_type_combo.currentIndex()] values = {"keyword": keyword, "report_step": report_step, "iactive": iactive, "file_type_key": file_type_key, "path": path, "selected_case": selected_case} self.runExport.emit(values) def getReportStep(self, key): report_step = 0 if self._dynamic: report_step = self._report_step.text() if self._export_keyword_model.isGenParamKw(key): return report_step if self._export_keyword_model.isGenDataKw(key): lst = self._gen_data_report_step_model idx = self._gen_data_report_step.currentIndex() if lst and len(lst) > idx: report_step = lst[idx] else: raise IndexError('No such model step: %d. Valid range: [0, %d)' % (idx, len(lst))) return report_step def keywordSelected(self): key = self._kw_model[self._keywords.currentIndex()] self.updateFileExportType(key) self._dynamic = False if self._export_keyword_model.isFieldKw(key): self._dynamic = self._export_keyword_model.isDynamicField(key) self._report_step.setVisible(self._dynamic) self.layout().labelForField(self._report_step).setVisible(self._dynamic) self._gen_data_report_step.setVisible(self._export_keyword_model.isGenDataKw(key)) self.layout().labelForField(self._gen_data_report_step).setVisible(self._export_keyword_model.isGenDataKw(key)) if self._export_keyword_model.isGenDataKw(key): data = self._export_keyword_model.getGenDataReportSteps(key) self._gen_data_report_step_model = data self._gen_data_report_step.clear() self._gen_data_report_step.addItems(self._gen_data_report_step_model) def setSelectedCase(self, selected_case): self._case_combo.setCurrentIndex(self._case_model.indexOf(selected_case)) def validateExportDialog(self): validRealizations = False if self._active_realizations_field.isValid(): validRealizations = True path = str(self._file_name.text()) validPath = len(path) > 0 if validRealizations and validPath: self.updateExportButton.emit("export", True) else: self.updateExportButton.emit("export", False)
class Choir(VocalPart): @staticmethod def title(_=_base.translate): return _("Choir") def createWidgets(self, layout): self.label = QLabel(wordWrap=True) self.voicingLabel = QLabel() self.voicing = QComboBox(editable=True) self.voicingLabel.setBuddy(self.voicing) self.voicing.setCompleter(None) self.voicing.setValidator(QRegExpValidator( QRegExp("[SATB]+(-[SATB]+)*", Qt.CaseInsensitive), self.voicing)) self.voicing.addItems(( 'SA-TB', 'S-A-T-B', 'SA', 'S-A', 'SS-A', 'S-S-A', 'TB', 'T-B', 'TT-B', 'T-T-B', 'SS-A-T-B', 'S-A-TT-B', 'SS-A-TT-B', 'S-S-A-T-T-B', 'S-S-A-A-T-T-B-B', )) self.lyricsLabel = QLabel() self.lyrics = QComboBox() self.lyricsLabel.setBuddy(self.lyrics) self.lyrics.setModel(listmodel.ListModel(lyricStyles, self.lyrics, display=listmodel.translate_index(0), tooltip=listmodel.translate_index(1))) self.lyrics.setCurrentIndex(0) self.pianoReduction = QCheckBox() self.rehearsalMidi = QCheckBox() layout.addWidget(self.label) box = QHBoxLayout() layout.addLayout(box) box.addWidget(self.voicingLabel) box.addWidget(self.voicing) self.createStanzaWidget(layout) box = QHBoxLayout() layout.addLayout(box) box.addWidget(self.lyricsLabel) box.addWidget(self.lyrics) self.createAmbitusWidget(layout) layout.addWidget(self.pianoReduction) layout.addWidget(self.rehearsalMidi) def translateWidgets(self): self.translateStanzaWidget() self.translateAmbitusWidget() self.lyrics.model().update() self.label.setText('<p>{0} <i>({1})</i></p>'.format( _("Please select the voices for the choir. " "Use the letters S, A, T, or B. A hyphen denotes a new staff."), _("Hint: For a double choir you can use two choir parts."))) self.voicingLabel.setText(_("Voicing:")) self.lyricsLabel.setText(_("Lyrics:")) self.pianoReduction.setText(_("Piano reduction")) self.pianoReduction.setToolTip(_( "Adds an automatically generated piano reduction.")) self.rehearsalMidi.setText(_("Rehearsal MIDI files")) self.rehearsalMidi.setToolTip(_( "Creates a rehearsal MIDI file for every voice, " "even if no MIDI output is generated for the main score.")) def build(self, data, builder): # normalize voicing staves = self.voicing.currentText().upper() # remove unwanted characters staves = re.sub(r'[^SATB-]+', '', staves) # remove double hyphens, and from begin and end staves = re.sub('-+', '-', staves).strip('-') if not staves: return splitStaves = staves.split('-') numStaves = len(splitStaves) staffCIDs = collections.defaultdict(int) # number same-name staff Context-IDs voiceCounter = collections.defaultdict(int) # dict to number same voice types maxNumVoices = max(map(len, splitStaves)) # largest number of voices numStanzas = self.stanzas.value() lyrics = collections.defaultdict(list) # lyrics grouped by stanza number pianoReduction = collections.defaultdict(list) rehearsalMidis = [] p = ly.dom.ChoirStaff() choir = ly.dom.Sim(p) data.nodes.append(p) # print main instrumentName if there are more choirs, and we # have more than one staff. if numStaves > 1 and data.num: builder.setInstrumentNames(p, builder.instrumentName(lambda _: _("Choir"), data.num), builder.instrumentName(lambda _: _("abbreviation for Choir", "Ch."), data.num)) # get the preferred way of adding lyrics lyrAllSame, lyrEachSame, lyrEachDiff, lyrSpread = ( self.lyrics.currentIndex() == i for i in range(4)) lyrEach = lyrEachSame or lyrEachDiff # stanzas to print (0 = don't print stanza number): if numStanzas == 1: allStanzas = [0] else: allStanzas = list(range(1, numStanzas + 1)) # Which stanzas to print where: if lyrSpread and numStanzas > 1 and numStaves > 2: spaces = numStaves - 1 count, rest = divmod(max(numStanzas, spaces), spaces) stanzaSource = itertools.cycle(allStanzas) stanzaGroups = (itertools.islice(stanzaSource, num) for num in itertools.chain( itertools.repeat(count + 1, rest), itertools.repeat(count, numStaves - rest))) else: stanzaGroups = itertools.repeat(allStanzas, numStaves) # a function to set staff affinity (in LilyPond 2.13.4 and above): if builder.lyVersion >= (2, 13, 4): def setStaffAffinity(context, affinity): ly.dom.Line("\\override VerticalAxisGroup " "#'staff-affinity = #" + affinity, context.getWith()) else: def setStaffAffinity(lyricsContext, affinity): pass # a function to make a column markup: if builder.lyVersion >= (2, 11, 57): columnCommand = 'center-column' else: columnCommand = 'center-align' def makeColumnMarkup(names): node = ly.dom.Markup() column = ly.dom.MarkupEnclosed(columnCommand, node) for name in names: ly.dom.QuotedString(name, column) return node stavesLeft = numStaves for staff, stanzas in zip(splitStaves, stanzaGroups): # are we in the last staff? stavesLeft -= 1 # the number of voices in this staff numVoices = len(staff) # sort the letters in order SATB staff = ''.join(i * staff.count(i) for i in 'SATB') # Create the staff for the voices s = ly.dom.Staff(parent=choir) builder.setMidiInstrument(s, self.midiInstrument) # Build a list of the voices in this staff. # Each entry is a tuple(name, num). # name is one of 'S', 'A', 'T', or 'B' # num is an integer: 0 when a voice occurs only once, or >= 1 when # there are more voices of the same type (e.g. Soprano I and II) voices = [] for voice in staff: if staves.count(voice) > 1: voiceCounter[voice] += 1 voices.append((voice, voiceCounter[voice])) # Add the instrument names to the staff: if numVoices == 1: voice, num = voices[0] longName = builder.instrumentName(voice2Voice[voice].title, num) shortName = builder.instrumentName(voice2Voice[voice].short, num) builder.setInstrumentNames(s, longName, shortName) else: # stack instrument names (long and short) in a markup column. # long names longNames = makeColumnMarkup( builder.instrumentName(voice2Voice[voice].title, num) for voice, num in voices) shortNames = makeColumnMarkup( builder.instrumentName(voice2Voice[voice].short, num) for voice, num in voices) builder.setInstrumentNames(s, longNames, shortNames) # Make the { } or << >> holder for this staff's children. # If *all* staves have only one voice, addlyrics is used. # In that case, don't remove the braces. staffMusic = (ly.dom.Seq if lyrEach and maxNumVoices == 1 else ly.dom.Seqr if numVoices == 1 else ly.dom.Simr)(s) # Set the clef for this staff: if 'B' in staff: ly.dom.Clef('bass', staffMusic) elif 'T' in staff: ly.dom.Clef('treble_8', staffMusic) # Determine voice order (\voiceOne, \voiceTwo etc.) if numVoices == 1: order = (0,) elif numVoices == 2: order = 1, 2 elif staff in ('SSA', 'TTB'): order = 1, 3, 2 elif staff in ('SAA', 'TBB'): order = 1, 2, 4 elif staff in ('SSAA', 'TTBB'): order = 1, 3, 2, 4 else: order = range(1, numVoices + 1) # What name would the staff get if we need to refer to it? # If a name (like 's' or 'sa') is already in use in this part, # just add a number ('ss2' or 'sa2', etc.) staffCIDs[staff] += 1 cid = ly.dom.Reference(staff.lower() + str(staffCIDs[staff] if staffCIDs[staff] > 1 else "")) # Create voices and their lyrics: for (voice, num), voiceNum in zip(voices, order): name = voice2id[voice] if num: name += ly.util.int2text(num) a = data.assignMusic(name, voice2Voice[voice].octave) lyrName = name + 'Verse' if lyrEachDiff else 'verse' # Use \addlyrics if all staves have exactly one voice. if lyrEach and maxNumVoices == 1: for verse in stanzas: lyrics[verse].append((ly.dom.AddLyrics(s), lyrName)) ly.dom.Identifier(a.name, staffMusic) else: voiceName = voice2id[voice] + str(num or '') v = ly.dom.Voice(voiceName, parent=staffMusic) voiceMusic = ly.dom.Seqr(v) if voiceNum: ly.dom.Text('\\voice' + ly.util.int2text(voiceNum), voiceMusic) ly.dom.Identifier(a.name, voiceMusic) if stanzas and (lyrEach or (voiceNum <= 1 and (stavesLeft or numStaves == 1))): # Create the lyrics. If they should be above the staff, # give the staff a suitable name, and use alignAbove- # Context to align the Lyrics above the staff. above = voiceNum & 1 if lyrEach else False if above and s.cid is None: s.cid = cid for verse in stanzas: l = ly.dom.Lyrics(parent=choir) if above: l.getWith()['alignAboveContext'] = cid setStaffAffinity(l, "DOWN") elif not lyrEach and stavesLeft: setStaffAffinity(l, "CENTER") lyrics[verse].append((ly.dom.LyricsTo(voiceName, l), lyrName)) # Add ambitus: if self.ambitus.isChecked(): ambitusContext = (s if numVoices == 1 else v).getWith() ly.dom.Line('\\consists "Ambitus_engraver"', ambitusContext) if voiceNum > 1: ly.dom.Line("\\override Ambitus #'X-offset = #{0}".format( (voiceNum - 1) * 2.0), ambitusContext) pianoReduction[voice].append(a.name) rehearsalMidis.append((voice, num, a.name, lyrName)) # Assign the lyrics, so their definitions come after the note defs. # (These refs are used again below in the midi rehearsal routine.) refs = {} for verse in allStanzas: for node, name in lyrics[verse]: if (name, verse) not in refs: refs[(name, verse)] = self.assignLyrics(data, name, verse).name ly.dom.Identifier(refs[(name, verse)], node) # Create the piano reduction if desired if self.pianoReduction.isChecked(): a = data.assign('pianoReduction') data.nodes.append(ly.dom.Identifier(a.name)) piano = ly.dom.PianoStaff(parent=a) sim = ly.dom.Sim(piano) rightStaff = ly.dom.Staff(parent=sim) leftStaff = ly.dom.Staff(parent=sim) right = ly.dom.Seq(rightStaff) left = ly.dom.Seq(leftStaff) # Determine the ordering of voices in the staves upper = pianoReduction['S'] + pianoReduction['A'] lower = pianoReduction['T'] + pianoReduction['B'] preferUpper = 1 if not upper: # Male choir upper = pianoReduction['T'] lower = pianoReduction['B'] ly.dom.Clef("treble_8", right) ly.dom.Clef("bass", left) preferUpper = 0 elif not lower: # Female choir upper = pianoReduction['S'] lower = pianoReduction['A'] else: ly.dom.Clef("bass", left) # Otherwise accidentals can be confusing ly.dom.Line("#(set-accidental-style 'piano)", right) ly.dom.Line("#(set-accidental-style 'piano)", left) # Move voices if unevenly spread if abs(len(upper) - len(lower)) > 1: voices = upper + lower half = (len(voices) + preferUpper) // 2 upper = voices[:half] lower = voices[half:] for staff, voices in (ly.dom.Simr(right), upper), (ly.dom.Simr(left), lower): if voices: for v in voices[:-1]: ly.dom.Identifier(v, staff) ly.dom.VoiceSeparator(staff).after = 1 ly.dom.Identifier(voices[-1], staff) # Make the piano part somewhat smaller ly.dom.Line("fontSize = #-1", piano.getWith()) ly.dom.Line("\\override StaffSymbol #'staff-space = #(magstep -1)", piano.getWith()) # Nice to add Mark engravers ly.dom.Line('\\consists "Mark_engraver"', rightStaff.getWith()) ly.dom.Line('\\consists "Metronome_mark_engraver"', rightStaff.getWith()) # Keep piano reduction out of the MIDI output if builder.midi: ly.dom.Line('\\remove "Staff_performer"', rightStaff.getWith()) ly.dom.Line('\\remove "Staff_performer"', leftStaff.getWith()) # Create MIDI files if desired if self.rehearsalMidi.isChecked(): a = data.assign('rehearsalMidi') rehearsalMidi = a.name func = ly.dom.SchemeList(a) func.pre = '#\n(' # hack ly.dom.Text('define-music-function', func) ly.dom.Line('(parser location name midiInstrument lyrics) ' '(string? string? ly:music?)', func) choir = ly.dom.Sim(ly.dom.Command('unfoldRepeats', ly.dom.SchemeLily(func))) data.afterblocks.append(ly.dom.Comment(_("Rehearsal MIDI files:"))) for voice, num, ref, lyrName in rehearsalMidis: # Append voice to the rehearsalMidi function name = voice2id[voice] + str(num or '') seq = ly.dom.Seq(ly.dom.Voice(name, parent=ly.dom.Staff(name, parent=choir))) if builder.lyVersion < (2, 18, 0): ly.dom.Text('<>\\f', seq) # add one dynamic ly.dom.Identifier(ref, seq) # add the reference to the voice book = ly.dom.Book() # Append score to the aftermath (stuff put below the main score) suffix = "choir{0}-{1}".format(data.num, name) if data.num else name if builder.lyVersion < (2, 12, 0): data.afterblocks.append( ly.dom.Line('#(define output-suffix "{0}")'.format(suffix))) else: ly.dom.Line('\\bookOutputSuffix "{0}"'.format(suffix), book) data.afterblocks.append(book) data.afterblocks.append(ly.dom.BlankLine()) score = ly.dom.Score(book) # TODO: make configurable midiInstrument = voice2Midi[voice] cmd = ly.dom.Command(rehearsalMidi, score) ly.dom.QuotedString(name, cmd) ly.dom.QuotedString(midiInstrument, cmd) ly.dom.Identifier(refs[(lyrName, allStanzas[0])], cmd) ly.dom.Midi(score) ly.dom.Text("\\context Staff = $name", choir) seq = ly.dom.Seq(choir) ly.dom.Line("\\set Score.midiMinimumVolume = #0.5", seq) ly.dom.Line("\\set Score.midiMaximumVolume = #0.5", seq) ly.dom.Line("\\set Score.tempoWholesPerMinute = #" + data.scoreProperties.schemeMidiTempo(), seq) ly.dom.Line("\\set Staff.midiMinimumVolume = #0.8", seq) ly.dom.Line("\\set Staff.midiMaximumVolume = #1.0", seq) ly.dom.Line("\\set Staff.midiInstrument = $midiInstrument", seq) lyr = ly.dom.Lyrics(parent=choir) lyr.getWith()['alignBelowContext'] = ly.dom.Text('$name') ly.dom.Text("\\lyricsto $name $lyrics", lyr)
def __init__(self): super().__init__() # Diagram update is in progress self._updating = False # Input update is in progress self._inputUpdate = False # All input tables have the same domain. self.samedomain = True # Input datasets in the order they were 'connected'. self.data = OrderedDict() # Extracted input item sets in the order they were 'connected' self.itemsets = OrderedDict() # GUI box = gui.widgetBox(self.controlArea, "Info") self.info = gui.widgetLabel(box, "No data on input\n") self.identifiersBox = gui.radioButtonsInBox( self.controlArea, self, "useidentifiers", [], box="Data Instance Identifiers", callback=self._on_useidentifiersChanged ) self.useequalityButton = gui.appendRadioButton( self.identifiersBox, "Use instance equality" ) rb = gui.appendRadioButton( self.identifiersBox, "Use identifiers" ) self.inputsBox = gui.indentedBox( self.identifiersBox, sep=gui.checkButtonOffsetHint(rb) ) self.inputsBox.setEnabled(bool(self.useidentifiers)) for i in range(5): box = gui.widgetBox(self.inputsBox, "Data set #%i" % (i + 1), addSpace=False) box.setFlat(True) model = itemmodels.VariableListModel(parent=self) cb = QComboBox( minimumContentsLength=12, sizeAdjustPolicy=QComboBox.AdjustToMinimumContentsLengthWithIcon) cb.setModel(model) cb.activated[int].connect(self._on_inputAttrActivated) box.setEnabled(False) # Store the combo in the box for later use. box.combo_box = cb box.layout().addWidget(cb) gui.rubber(self.controlArea) gui.auto_commit(self.controlArea, self, "autocommit", "Commit", "Auto commit") # Main area view self.scene = QGraphicsScene() self.view = QGraphicsView(self.scene) self.view.setRenderHint(QPainter.Antialiasing) self.view.setBackgroundRole(QPalette.Window) self.view.setFrameStyle(QGraphicsView.StyledPanel) self.mainArea.layout().addWidget(self.view) self.vennwidget = VennDiagram() self.vennwidget.resize(400, 400) self.vennwidget.itemTextEdited.connect(self._on_itemTextEdited) self.scene.selectionChanged.connect(self._on_selectionChanged) self.scene.addItem(self.vennwidget) self.resize(self.controlArea.sizeHint().width() + 550, max(self.controlArea.sizeHint().height(), 550)) self._queue = [] self.graphButton.clicked.connect(self.save_graph)
class MembersWidget(QWidget): def __init__(self, parent, logger): super(MembersWidget, self).__init__(parent) self.logger = logger layout = QVBoxLayout(self) layout.setSpacing(0) self.dropdown_members_dict = {} self.dropdown_members_model = DropdownModel(get_peers(), self.logger) self.dropdown_members = QComboBox(self) self.dropdown_members.setModel(self.dropdown_members_model) topLayout = QHBoxLayout() topLayout.setSpacing(10) topLayout.addWidget(self.dropdown_members, 1) self.requestLogsButton = QPushButton("Request Logfiles", self) topLayout.addWidget(self.requestLogsButton) layout.addLayout(topLayout) layout.addWidget(QLabel("Member Information:", self)) self.memberInformationTable = QTreeWidget(self) self.memberInformationTable.setMaximumHeight(65) self.memberInformationTable.setSelectionMode(QTreeWidget.NoSelection) layout.addWidget(self.memberInformationTable, 0) layout.addWidget(QLabel("Send Message:", self)) sendMessageLayout = QHBoxLayout() sendMessageLayout.setSpacing(10) messageInput = HistoryLineEdit(self, "Enter a message") self.sendMessageButton = QPushButton("Send", self) sendMessageLayout.addWidget(messageInput, 1) sendMessageLayout.addWidget(self.sendMessageButton) layout.addLayout(sendMessageLayout) layout.addWidget(QLabel("Log files:", self)) logSplitter = QSplitter(Qt.Horizontal, self) logListWidget = QWidget(self) logListLayout = QVBoxLayout(logListWidget) logListLayout.setContentsMargins(0, 0, 0, 0) self.log_tree_view = QTreeWidget(logSplitter) self.log_tree_view.setAlternatingRowColors(True) self.log_tree_view.setColumnCount(1) self.log_tree_view.setHeaderHidden(True) self.log_tree_view.setItemsExpandable(False) self.log_tree_view.setIndentation(0) logListLayout.addWidget(self.log_tree_view, 1) logListBottomLayout = QHBoxLayout() self.logSizeLabel = QLabel(logListWidget) logListBottomLayout.addWidget(self.logSizeLabel, 1) self.clearLogsButton = QPushButton("Clear", logListWidget) self.clearLogsButton.setEnabled(False) self.clearLogsButton.clicked.connect(self.clearLogs) logListBottomLayout.addWidget(self.clearLogsButton, 0) logListLayout.addLayout(logListBottomLayout) logSplitter.addWidget(logListWidget) self.log_area = QTextEdit(logListWidget) self.log_area.setLineWrapMode(QTextEdit.WidgetWidth) self.log_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.log_area.setReadOnly(True) logSplitter.addWidget(self.log_area) logSplitter.setStretchFactor(0, 0) logSplitter.setStretchFactor(1, 1) layout.addWidget(logSplitter, 1) self.memberSelectionChanged() self.log_tree_view.selectionModel().selectionChanged.connect(self.displaySelectedLogfile) self.dropdown_members.currentIndexChanged.connect(self.memberSelectionChanged) self.requestLogsButton.clicked.connect(self.requestLogClicked) self.sendMessageButton.clicked.connect(partial(self.sendMessageToMember, messageInput)) messageInput.returnPressed.connect(partial(self.sendMessageToMember, messageInput)) get_notification_center().connectPeerAppended(self.dropdown_members_model.externalRowAppended) get_notification_center().connectPeerUpdated(self.dropdown_members_model.externalRowUpdated) get_notification_center().connectPeerRemoved(self.dropdown_members_model.externalRowRemoved) get_notification_center().connectPeerUpdated(self.updateMemberInformation) def destroy_widget(self): get_notification_center().disconnectPeerAppended(self.dropdown_members_model.externalRowAppended) get_notification_center().disconnectPeerUpdated(self.dropdown_members_model.externalRowUpdated) get_notification_center().disconnectPeerRemoved(self.dropdown_members_model.externalRowRemoved) get_notification_center().disconnectPeerUpdated(self.updateMemberInformation) def listLogfiles(self, basePath, sort=None): if sort is None: sort = lambda aFile: -self.getLogNumber(aFile) logList = [ os.path.join(basePath, aFile) for aFile in os.listdir(basePath) if aFile.endswith(".log") and not os.path.isdir(os.path.join(basePath, aFile)) ] return sorted(logList, key=sort) def getNumLogsToKeep(self, oldLogFiles, newLogFiles, logOffset): oldestNew = None for aLogFile in newLogFiles: oldestNew, _ = self.getLogDates(aLogFile) if oldestNew != None: break if oldestNew == None: # new new log file contains timestamps (they are probably all empty) return len(oldLogFiles) numToKeep = 0 while numToKeep < len(oldLogFiles) - logOffset: curTime, _ = self.getLogDates(oldLogFiles[numToKeep]) if curTime == None or curTime < oldestNew: # keep empty log files numToKeep = numToKeep + 1 else: break return numToKeep def getLogDates(self, aLogFile): with codecs.open(aLogFile, "rb", "utf-8") as logContent: logLines = logContent.readlines() firstDate = None for aLine in logLines: firstDate = getLogLineTime(aLine) if firstDate != None: break lastDate = None for aLine in reversed(logLines): lastDate = getLogLineTime(aLine) if lastDate != None: break return firstDate, lastDate def getLogNumber(self, aLogFile): aLogFile = os.path.basename(aLogFile) try: return int(aLogFile[: aLogFile.rfind(".")]) except: return -1 def shiftLogFiles(self, oldLogFiles, numToKeep, shift, logOffset): renamedLogfiles = [] for index, aFile in enumerate(oldLogFiles): logNum = self.getLogNumber(aFile) if logNum < logOffset: # don't touch up-to-date logs break if index < numToKeep: newName = os.path.join(os.path.dirname(aFile), "%d.log" % (logNum + shift)) renamedLogfiles.append((len(oldLogFiles) - index - 1, aFile, newName)) os.rename(aFile, newName) else: os.remove(aFile) return renamedLogfiles def handleNewLogFiles(self, basePath, tmpPath, logOffset=0): oldLogFiles = self.listLogfiles(basePath) newLogFiles = self.listLogfiles(tmpPath) # check how many log files are actually new numToKeep = self.getNumLogsToKeep(oldLogFiles, newLogFiles, logOffset) # rename / remove old log files to make room for the new ones numNew = len(newLogFiles) - (len(oldLogFiles) - logOffset - numToKeep) renamedLogfiles = self.shiftLogFiles(oldLogFiles, numToKeep, numNew, logOffset) # move new log files addedLogfiles = [] for index, aLogFile in enumerate(reversed(newLogFiles)): shutil.move(aLogFile, basePath) if index < numNew: addedLogfiles.append((index + logOffset, os.path.join(basePath, os.path.basename(aLogFile)))) shutil.rmtree(tmpPath, True) return numNew, addedLogfiles, renamedLogfiles def requestFinished(self): self.requestLogsButton.setEnabled(True) self.dropdown_members.setEnabled(True) @loggingSlot(QThread, object) def cb_log_transfer_success(self, thread, path): path = convert_string(path) basePath = os.path.dirname(path) tmpPath = os.path.join(basePath, "tmp") if not os.path.exists(tmpPath): os.makedirs(tmpPath) logsAdded = [] if path.endswith(".tgz"): # extract received log files with contextlib.closing(tarfile.open(path, "r:gz")) as tarContent: tarContent.extractall(tmpPath) _, logsAdded, logsRenamed = self.handleNewLogFiles(basePath, tmpPath) self.requestFinished() else: # log comes from old version logNum = 0 if thread.sender in self.logRequests: logNum, requestTime = self.logRequests[thread.sender] now = datetime.now() td = now - requestTime tdSeconds = (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10 ** 6) / 10 ** 6 if tdSeconds > self.LOG_REQUEST_TIMEOUT: # request timed out or was finished already logNum = 0 shutil.move(path, os.path.join(tmpPath, "%d.log" % logNum)) numNew, logsAdded, logsRenamed = self.handleNewLogFiles(basePath, tmpPath, logNum) if numNew > 0 and logNum < 9: # there might be more new ones self.logRequests[thread.sender] = (logNum + 1, datetime.now()) self.logger.debug("log seems to be new, another!!!") logsAdded.append((logNum + 1, None)) self.request_log(thread.sender, logNum + 1) elif thread.sender in self.logRequests: # request finished del self.logRequests[thread.sender] self.requestFinished() else: self.requestFinished() if len(logsAdded) > 0 or len(logsRenamed) > 0: self.updateLogList(logsAdded, logsRenamed) @loggingSlot(QThread, object) def cb_log_transfer_error(self, _thread, message): if not self.isVisible(): return False self.log_area.setText("Error while getting log (%s)" % message) self.requestFinished() def get_selected_log_member(self): member = convert_string(self.dropdown_members.currentText()) if not member: return None if "(" in member: # member contains name, extract ID member = member[member.rfind("(") + 1 : member.rfind(")")] return member def request_log(self, member=None, logNum=0): if member == None: member = self.get_selected_log_member() if member != None: self.logger.debug("Requesting log %d from %s", logNum, member) get_server().call( "HELO_REQUEST_LOGFILE %s %d" % (DataReceiverThread.getOpenPort(category="log%s" % member), logNum), set([member]), ) else: self.log_area.setText("No Member selected!") @loggingSlot() def requestLogClicked(self): self.requestLogsButton.setEnabled(False) self.dropdown_members.setEnabled(False) self.updateLogList([(0, None)]) self.request_log() def listLogFilesForMember(self, member): if member is None: return [] logDir = os.path.join(get_settings().get_main_config_dir(), "logs", member) if not os.path.exists(logDir): return [] return self.listLogfiles(logDir) def numLogFilesForMember(self, member): return len(self.listLogFilesForMember(member)) def requestTimedOut(self, item): if not sip.isdeleted(item) and item != None and item.data(0, Qt.UserRole) == None: self.log_tree_view.takeTopLevelItem(self.log_tree_view.indexFromItem(item).row()) self.requestFinished() def formatFileSize(self, num): for x in ["Bytes", "KB", "MB", "GB", "TB"]: if num < 1024.0: return "%3.1f %s" % (num, x) num /= 1024.0 def initializeLogItem(self, item, logFile): firstDate, lastDate = self.getLogDates(logFile) text = None tooltip = None if firstDate != None: text = firstDate.strftime("%Y-%m-%d %H:%M:%S") tooltip = u"File: %s\nFirst entry: %s\nLast entry: %s" % ( logFile, firstDate.strftime("%Y-%m-%d %H:%M:%S"), lastDate.strftime("%Y-%m-%d %H:%M:%S"), ) else: timestamp = datetime.fromtimestamp(os.path.getmtime(logFile)).strftime("%Y-%m-%d %H:%M:%S") text = u"%s" % os.path.basename(logFile) tooltip = u"File:%s\nModification Date: %s" % (logFile, timestamp) text = text + "\n%s" % self.formatFileSize(os.path.getsize(logFile)) if tooltip != None: item.setData(0, Qt.ToolTipRole, QVariant(tooltip)) item.setData(0, Qt.UserRole, logFile) item.setData(0, Qt.DisplayRole, QVariant(text)) @loggingSlot() def clearLogs(self): for aLogFile in self.listLogFilesForMember(self.get_selected_log_member()): os.remove(aLogFile) self.updateLogList() def updateLogList(self, logsAdded=None, logsRenamed=None): selectedMember = self.get_selected_log_member() if logsAdded == None: self.log_tree_view.clear() logsAdded = [] for index, logFile in enumerate(reversed(self.listLogFilesForMember(selectedMember))): logsAdded.append((index, logFile)) if len(logsAdded) == 0: self.log_tree_view.clear() self.log_tree_view.addTopLevelItem( QTreeWidgetItem(self.log_tree_view, QStringList("No logs available.")) ) self.log_tree_view.setSelectionMode(QTreeWidget.NoSelection) self.logSizeLabel.setText("No logs") self.clearLogsButton.setEnabled(False) return if logsRenamed != None: for index, oldName, newName in logsRenamed: # index + 1 because of the "requesting" item item = self.log_tree_view.topLevelItem(index + 1) if item != None: itemLogFile = convert_string(item.data(0, Qt.UserRole).toString()) if itemLogFile != oldName: self.logger.warning( "index does not correspond to item in list:\n\t%s\n\t%s", itemLogFile, oldName ) self.initializeLogItem(item, newName) if len(logsAdded) == 0: self.log_tree_view.takeTopLevelItem(0) else: for index, logFile in logsAdded: oldItem = self.log_tree_view.topLevelItem(index) item = None if oldItem != None and oldItem.data(0, Qt.UserRole) == None: # requested item has been received item = oldItem else: item = QTreeWidgetItem() oldItem = None if logFile == None: item.setData(0, Qt.DisplayRole, QVariant("Requesting...")) QTimer.singleShot(6000, partial(self.requestTimedOut, item)) else: self.initializeLogItem(item, logFile) if oldItem == None: # else, the old item is being modified self.log_tree_view.insertTopLevelItem(index, item) self.log_tree_view.setSelectionMode(QTreeWidget.SingleSelection) totalSize = 0 for aLogFile in self.listLogFilesForMember(selectedMember): totalSize += os.path.getsize(aLogFile) self.logSizeLabel.setText("%s consumed" % self.formatFileSize(totalSize)) self.clearLogsButton.setEnabled(True) # self.displaySelectedLogfile() def getSelectedLogContent(self): member = self.get_selected_log_member() if member == None: return "No Log selected." selection = self.log_tree_view.selectedIndexes() if len(selection) is 0: return "No Log selected." logPath = convert_string(selection[0].data(Qt.UserRole).toString()) if logPath == None: return "ERROR: path is None" if not os.path.exists(logPath): return "File not found: " + logPath fcontent = "" try: with codecs.open(logPath, "r", "utf8") as fhandler: fcontent = fhandler.read() except Exception as e: self.logger.exception("Error reading file") fcontent = "Error reading file: %s" % str(e) return fcontent @loggingSlot(QItemSelection, QItemSelection) def displaySelectedLogfile(self, _new, _old): self.log_area.setText(self.getSelectedLogContent()) @loggingSlot(int) def memberSelectionChanged(self, _new=None): self.updateLogList() isMemberSelected = self.get_selected_log_member() != None self.sendMessageButton.setEnabled(isMemberSelected) self.requestLogsButton.setEnabled(isMemberSelected) self.updateMemberInformation() @loggingSlot(object) def sendMessageToMember(self, lineEdit): selectedMember = self.get_selected_log_member() if selectedMember != None: get_server().call(convert_string(lineEdit.text()), set([selectedMember])) lineEdit.clear() @loggingSlot(object, object) def updateMemberInformation(self, peerID=None, peerInfo=None): if peerID != None and peerID != self.get_selected_log_member(): # only update if selected member updated return self.memberInformationTable.clear() if self.get_selected_log_member() == None: self.memberInformationTable.setColumnCount(0) self.memberInformationTable.setHeaderLabel("No member selected.") return if peerInfo == None: peerInfo = get_peers().getPeerInfo(pID=self.get_selected_log_member()) if peerInfo == None: self.memberInformationTable.setColumnCount(0) self.memberInformationTable.setHeaderLabel("No member information available.") return self.memberInformationTable.setColumnCount(len(peerInfo)) headers = sorted(peerInfo.keys(), key=lambda s: s.lower()) self.memberInformationTable.setHeaderLabels(QStringList(headers)) item = QTreeWidgetItem(self.memberInformationTable) for col, header in enumerate(headers): item.setData(col, Qt.DisplayRole, QVariant(peerInfo[header])) for col in range(self.memberInformationTable.columnCount()): self.memberInformationTable.resizeColumnToContents(col)
def __init__(self, parent=None): super().__init__(parent) # Output changed flag self._changed = False # Diagram update is in progress self._updating = False # Input update is in progress self._inputUpdate = False # All input tables have the same domain. self.samedomain = True # Input datasets in the order they were 'connected'. self.data = OrderedDict() # Extracted input item sets in the order they were 'connected' self.itemsets = OrderedDict() # GUI box = gui.widgetBox(self.controlArea, "Info") self.info = gui.widgetLabel(box, "No data on input\n") self.identifiersBox = gui.radioButtonsInBox( self.controlArea, self, "useidentifiers", [], box="Data Instance Identifiers", callback=self._on_useidentifiersChanged) self.useequalityButton = gui.appendRadioButton( self.identifiersBox, "Use instance equality") rb = gui.appendRadioButton(self.identifiersBox, "Use identifiers") self.inputsBox = gui.indentedBox(self.identifiersBox, sep=gui.checkButtonOffsetHint(rb)) self.inputsBox.setEnabled(bool(self.useidentifiers)) for i in range(5): box = gui.widgetBox(self.inputsBox, "Data set #%i" % (i + 1), addSpace=False) box.setFlat(True) model = itemmodels.VariableListModel(parent=self) cb = QComboBox() cb.setModel(model) cb.activated[int].connect(self._on_inputAttrActivated) box.setEnabled(False) # Store the combo in the box for later use. box.combo_box = cb box.layout().addWidget(cb) gui.rubber(self.controlArea) box = gui.widgetBox(self.controlArea, "Output") cb = gui.checkBox(box, self, "autocommit", "Commit on any change") b = gui.button(box, self, "Commit", callback=self.commit, default=True) gui.setStopper(self, b, cb, "_changed", callback=self.commit) # Main area view self.scene = QGraphicsScene() self.view = QGraphicsView(self.scene) self.view.setRenderHint(QPainter.Antialiasing) self.view.setBackgroundRole(QPalette.Window) self.view.setFrameStyle(QGraphicsView.StyledPanel) self.mainArea.layout().addWidget(self.view) self.vennwidget = VennDiagram() self.vennwidget.resize(400, 400) self.vennwidget.itemTextEdited.connect(self._on_itemTextEdited) self.scene.selectionChanged.connect(self._on_selectionChanged) self.scene.addItem(self.vennwidget) self.resize(self.controlArea.sizeHint().width() + 550, max(self.controlArea.sizeHint().height(), 550)) self._queue = []
class InstrumentNames(QGroupBox): def __init__(self, parent): super(InstrumentNames, self).__init__(parent, checkable=True, checked=True) grid = QGridLayout() self.setLayout(grid) self.firstSystemLabel = QLabel() self.firstSystem = QComboBox() self.firstSystemLabel.setBuddy(self.firstSystem) self.otherSystemsLabel = QLabel() self.otherSystems = QComboBox() self.otherSystemsLabel.setBuddy(self.otherSystems) self.languageLabel = QLabel() self.language = QComboBox() self.languageLabel.setBuddy(self.language) self.firstSystem.setModel(listmodel.ListModel( (lambda: _("Long"), lambda: _("Short")), self.firstSystem, display = listmodel.translate)) self.otherSystems.setModel(listmodel.ListModel( (lambda: _("Long"), lambda: _("Short"), lambda: _("None")), self.otherSystems, display = listmodel.translate)) self._langs = l = ['','C'] l.extend(sorted(po.available())) def display(lang): if lang == 'C': return _("English (untranslated)") elif not lang: return _("Default") return language_names.languageName(lang, po.setup.current()) self.language.setModel(listmodel.ListModel(l, self.language, display=display)) grid.addWidget(self.firstSystemLabel, 0, 0) grid.addWidget(self.firstSystem, 0, 1) grid.addWidget(self.otherSystemsLabel, 1, 0) grid.addWidget(self.otherSystems, 1, 1) grid.addWidget(self.languageLabel, 2, 0) grid.addWidget(self.language, 2, 1) app.translateUI(self) self.loadSettings() self.window().finished.connect(self.saveSettings) def translateUI(self): self.setTitle(_("Instrument names")) self.firstSystemLabel.setText(_("First system:")) self.otherSystemsLabel.setText(_("Other systems:")) self.languageLabel.setText(_("Language:")) self.firstSystem.setToolTip(_( "Use long or short instrument names before the first system.")) self.otherSystems.setToolTip(_( "Use short, long or no instrument names before the next systems.")) self.language.setToolTip(_( "Which language to use for the instrument names.")) self.firstSystem.model().update() self.otherSystems.model().update() self.language.model().update() def getLanguage(self): """Returns the language the user has set. '' means: default (use same translation as system) 'C' means: English (untranslated) or a language code that is available in Frescobaldi's translation. """ return self._langs[self.language.currentIndex()] def loadSettings(self): s = QSettings() s.beginGroup('scorewiz/instrumentnames') self.setChecked(s.value('enabled', True, bool)) allow = ['long', 'short'] first = s.value('first', '', type("")) self.firstSystem.setCurrentIndex(allow.index(first) if first in allow else 0) allow = ['long', 'short', 'none'] other = s.value('other', '', type("")) self.otherSystems.setCurrentIndex(allow.index(other) if other in allow else 2) language = s.value('language', '', type("")) self.language.setCurrentIndex(self._langs.index(language) if language in self._langs else 0) def saveSettings(self): s = QSettings() s.beginGroup('scorewiz/instrumentnames') s.setValue('enable', self.isChecked()) s.setValue('first', ('long', 'short')[self.firstSystem.currentIndex()]) s.setValue('other', ('long', 'short', 'none')[self.otherSystems.currentIndex()]) s.setValue('language', self._langs[self.language.currentIndex()])
class MidiPorts(preferences.Group): def __init__(self, page): super(MidiPorts, self).__init__(page) self._portsMessage = QLabel(wordWrap=True) self._playerLabel = QLabel() self._playerPort = QComboBox(editable=True, editTextChanged=self.changed, insertPolicy=QComboBox.NoInsert) self._inputLabel = QLabel() self._inputPort = QComboBox(editable=True, editTextChanged=self.changed, insertPolicy=QComboBox.NoInsert) self._reloadMidi = QPushButton(icon=icons.get('view-refresh')) self._reloadMidi.clicked.connect(self.refreshMidiPorts) grid = QGridLayout() self.setLayout(grid) grid.addWidget(self._portsMessage, 0, 0, 1, 3) grid.addWidget(self._playerLabel, 1, 0) grid.addWidget(self._playerPort, 1, 1, 1, 2) grid.addWidget(self._inputLabel, 2, 0) grid.addWidget(self._inputPort, 2, 1, 1, 2) grid.addWidget(self._reloadMidi, 3, 2) app.translateUI(self) self.loadMidiPorts() def translateUI(self): self.setTitle(_("MIDI Ports")) self._portsMessage.setText( _("Note: There are no MIDI output ports available on your system. " "To use MIDI, please check if PortMIDI is installed on your system " "and that a MIDI synthesizer is available or connected.")) self._playerLabel.setText(_("Player output:")) self._playerPort.setToolTip( _("The MIDI port to play music to. " "See \"What's This\" for more information.")) self._playerPort.setWhatsThis( _("<p>" "This dropdown menu lists the available MIDI output ports on your system. " "You can select one, or just type part of a name. " "In that case, the first available port name that starts with the " "specified characters is used." "</p>\n<p>" "Click the button to refresh the list, e.g. when you connect a " "MIDI device or start a software synthesizer." "</p>")) self._inputLabel.setText(_("Input port:")) self._inputPort.setToolTip( _("The MIDI port to get input from to write notes " "See \"What's This\" for more information.")) self._inputPort.setWhatsThis( _("<p>" "This dropdown menu lists the available MIDI input ports on your system. " "You can select one, or just type part of a name. " "In that case, the first available port name that starts with the " "specified characters is used." "</p>\n<p>" "Click the button to refresh the list, e.g. when you connect a " "MIDI device or start a software synthesizer." "</p>")) self._reloadMidi.setText(_("Refresh MIDI ports")) def loadMidiPorts(self): output_ports = midihub.output_ports() self._playerPort.setModel(listmodel.ListModel(output_ports)) input_ports = midihub.input_ports() self._inputPort.setModel(listmodel.ListModel(input_ports)) self._portsMessage.setVisible((not output_ports) and (not input_ports)) def refreshMidiPorts(self): midihub.refresh_ports() with qutil.signalsBlocked(self): self.loadMidiPorts() self.loadSettings() def loadSettings(self): output_port = midihub.default_output() input_port = midihub.default_input() s = QSettings() s.beginGroup("midi") self._playerPort.setEditText( s.value("player/output_port", output_port, type(""))) self._inputPort.setEditText( s.value("midi/input_port", input_port, type(""))) def saveSettings(self): s = QSettings() s.beginGroup("midi") s.setValue("player/output_port", self._playerPort.currentText()) s.setValue("midi/input_port", self._inputPort.currentText())
class MainWindow(mainwindow_widget, mainwindow_base): """ Main application window """ def __init__(self, settings): super(MainWindow, self).__init__() self.setupUi(self) self.settings = settings roam.featureform.settings = settings.settings self.canvaslayers = [] self.layerbuttons = [] self.project = None self.selectionbands = defaultdict(partial(QgsRubberBand, self.canvas)) self.canvas.setCanvasColor(Qt.white) self.canvas.enableAntiAliasing(True) self.canvas.setWheelAction(QgsMapCanvas.WheelZoomToMouseCursor) self.bar = roam.messagebaritems.MessageBar(self) self.actionMap.setVisible(False) pal = QgsPalLabeling() self.canvas.mapRenderer().setLabelingEngine(pal) self.canvas.setFrameStyle(QFrame.NoFrame) self.menuGroup = QActionGroup(self) self.menuGroup.setExclusive(True) self.menuGroup.addAction(self.actionMap) self.menuGroup.addAction(self.actionDataEntry) self.menuGroup.addAction(self.actionProject) self.menuGroup.addAction(self.actionSync) self.menuGroup.addAction(self.actionSettings) self.menuGroup.triggered.connect(self.updatePage) self.editgroup = QActionGroup(self) self.editgroup.setExclusive(True) self.editgroup.addAction(self.actionPan) self.editgroup.addAction(self.actionZoom_In) self.editgroup.addAction(self.actionZoom_Out) self.editgroup.addAction(self.actionInfo) #TODO Extract GPS out into a service and remove UI stuff self.actionGPS = GPSAction(":/icons/gps", self.canvas, self.settings, self) self.projecttoolbar.addAction(self.actionGPS) self.projectwidget = ProjectsWidget(self) self.projectwidget.requestOpenProject.connect(self.loadProject) QgsProject.instance().readProject.connect(self._readProject) self.project_page.layout().addWidget(self.projectwidget) self.syncwidget = SyncWidget() self.syncpage.layout().addWidget(self.syncwidget) self.settingswidget = SettingsWidget(settings, self) self.settings_page.layout().addWidget(self.settingswidget) self.actionSettings.toggled.connect(self.settingswidget.populateControls) self.actionSettings.toggled.connect(self.settingswidget.readSettings) self.settingswidget.settingsupdated.connect(self.settingsupdated) self.dataentrywidget = DataEntryWidget(self.canvas, self.bar) self.widgetpage.layout().addWidget(self.dataentrywidget) self.dataentrywidget.rejected.connect(self.formrejected) self.dataentrywidget.featuresaved.connect(self.featureSaved) self.dataentrywidget.featuredeleted.connect(self.featuredeleted) self.dataentrywidget.failedsave.connect(self.failSave) self.dataentrywidget.helprequest.connect(self.showhelp) self.dataentrywidget.openimage.connect(self.openimage) def createSpacer(width=0, height=0): widget = QWidget() widget.setMinimumWidth(width) widget.setMinimumHeight(height) return widget gpsspacewidget = createSpacer(30) sidespacewidget = createSpacer(30) sidespacewidget2 = createSpacer(height=20) sidespacewidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) sidespacewidget2.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) gpsspacewidget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.topspaceraction = self.projecttoolbar.insertWidget(self.actionGPS, gpsspacewidget) def createlabel(text): style = """ QLabel { color: #706565; font: 14px "Calibri" ; }""" label = QLabel(text) label.setStyleSheet(style) return label self.projectlabel = createlabel("Project: {project}") self.userlabel = createlabel("User: {user}".format(user=getpass.getuser())) self.positionlabel = createlabel('') self.statusbar.addWidget(self.projectlabel) self.statusbar.addWidget(self.userlabel) spacer = createSpacer() spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.statusbar.addWidget(spacer) self.statusbar.addWidget(self.positionlabel) self.menutoolbar.insertWidget(self.actionQuit, sidespacewidget2) self.menutoolbar.insertWidget(self.actionProject, sidespacewidget) self.stackedWidget.currentChanged.connect(self.updateUIState) self.panels = [] self.connectButtons() self.band = QgsRubberBand(self.canvas) self.band.setIconSize(20) self.band.setWidth(10) self.band.setColor(QColor(186, 93, 212, 76)) self.canvas_page.layout().insertWidget(0, self.projecttoolbar) self.dataentrymodel = QStandardItemModel(self) self.dataentrycombo = QComboBox(self.projecttoolbar) self.dataentrycombo.setIconSize(QSize(48,48)) self.dataentrycombo.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) self.dataentrycombo.setSizeAdjustPolicy(QComboBox.AdjustToContents) self.dataentrycombo.setModel(self.dataentrymodel) self.dataentrycomboaction = self.projecttoolbar.insertWidget(self.topspaceraction, self.dataentrycombo) self.dataentrycombo.showPopup = self.selectdataentry self.biglist = BigList(self.canvas) self.biglist.setlabel("Select data entry form") self.biglist.setmodel(self.dataentrymodel) self.biglist.itemselected.connect(self.dataentrychanged) self.biglist.hide() self.centralwidget.layout().addWidget(self.statusbar) self.actionGPSFeature.setProperty('dataentry', True) self.infodock = InfoDock(self.canvas) self.infodock.requestopenform.connect(self.openForm) self.infodock.featureupdated.connect(self.highlightfeature) self.infodock.resultscleared.connect(self.clearselection) self.infodock.openurl.connect(self.viewurl) self.infodock.hide() self.hidedataentry() self.canvas.extentsChanged.connect(self.updatestatuslabel) self.projecttoolbar.toolButtonStyleChanged.connect(self.updatecombo) def selectdataentry(self, ): if self.dataentrycombo.count() == 0: return self.biglist.show() def viewurl(self, url): """ Open a URL in Roam :param url: :return: """ key = url.toString().lstrip('file://') try: # Hack. Eww fix me. data, imagetype = roam.htmlviewer.images[os.path.basename(key)] except KeyError: # It's not a image so lets just pass it of as a normal # URL QDesktopServices.openUrl(url) return pix = QPixmap() if imagetype == 'base64': pix.loadFromData(data) else: pix.load(data) self.openimage(pix) def openimage(self, pixmap): viewer = ImageViewer(self.stackedWidget) viewer.resize(self.stackedWidget.size()) viewer.openimage(pixmap) def updatecombo(self, *args): self.dataentrycombo.setMinimumHeight(0) def settingsupdated(self, settings): settings.save() self.show() self.actionGPS.updateGPSPort() # eww! roam.featureform.settings = settings.settings def updatestatuslabel(self): extent = self.canvas.extent() self.positionlabel.setText("Map Center: {}".format(extent.center().toString())) def highlightselection(self, results): for layer, features in results.iteritems(): band = self.selectionbands[layer] band.setColor(QColor(255, 0, 0, 150)) band.setIconSize(20) band.setWidth(2) band.setBrushStyle(Qt.NoBrush) band.reset(layer.geometryType()) for feature in features: band.addGeometry(feature.geometry(), layer) def clearselection(self): # Clear the main selection rubber band self.band.reset() # Clear the rest for band in self.selectionbands.itervalues(): band.reset() def highlightfeature(self, layer, feature, features): self.clearselection() self.highlightselection({layer: features}) self.band.setToGeometry(feature.geometry(), layer) def showmap(self): self.actionMap.setVisible(True) self.actionMap.trigger() def hidedataentry(self): self.actionDataEntry.setVisible(False) def showdataentry(self): self.actionDataEntry.setVisible(True) self.actionDataEntry.trigger() def dataentrychanged(self, index): wasactive = self.clearCapatureTools() if not index.isValid(): return modelindex = index # modelindex = self.dataentrymodel.index(index, 0) form = modelindex.data(Qt.UserRole + 1) self.dataentrycombo.setCurrentIndex(index.row()) self.createCaptureButtons(form, wasactive) def raiseerror(self, *exinfo): info = traceback.format_exception(*exinfo) item = self.bar.pushError('Seems something has gone wrong. Press for more details', info) def setMapTool(self, tool, *args): self.canvas.setMapTool(tool) def homeview(self): """ Zoom the mapview canvas to the extents the project was opened at i.e. the default extent. """ self.canvas.setExtent(self.defaultextent) self.canvas.refresh() def connectButtons(self): def connectAction(action, tool): action.toggled.connect(partial(self.setMapTool, tool)) def cursor(name): pix = QPixmap(name) pix = pix.scaled(QSize(24,24)) return QCursor(pix) self.zoomInTool = QgsMapToolZoom(self.canvas, False) self.zoomOutTool = QgsMapToolZoom(self.canvas, True) self.panTool = TouchMapTool(self.canvas) self.moveTool = MoveTool(self.canvas, []) self.infoTool = InfoTool(self.canvas) connectAction(self.actionZoom_In, self.zoomInTool) connectAction(self.actionZoom_Out, self.zoomOutTool) connectAction(self.actionPan, self.panTool) connectAction(self.actionMove, self.moveTool) connectAction(self.actionInfo, self.infoTool) self.zoomInTool.setCursor(cursor(':/icons/in')) self.zoomOutTool.setCursor(cursor(':/icons/out')) self.infoTool.setCursor(cursor(':/icons/info')) self.actionRaster.triggered.connect(self.toggleRasterLayers) self.infoTool.infoResults.connect(self.showInfoResults) # The edit toolbutton is currently not being used but leaving it for feature. self.moveTool.layersupdated.connect(self.actionMove.setEnabled) self.moveTool.layersupdated.connect(self.actionEdit_Tools.setEnabled) self.actionGPSFeature.triggered.connect(self.addFeatureAtGPS) self.actionGPSFeature.setEnabled(self.actionGPS.isConnected) self.actionGPS.gpsfixed.connect(self.actionGPSFeature.setEnabled) self.actionHome.triggered.connect(self.homeview) self.actionQuit.triggered.connect(self.exit) def showToolError(self, label, message): self.bar.pushMessage(label, message, QgsMessageBar.WARNING) def clearCapatureTools(self): captureselected = False for action in self.projecttoolbar.actions(): if action.objectName() == "capture" and action.isChecked(): captureselected = True if action.property('dataentry'): self.projecttoolbar.removeAction(action) return captureselected def createCaptureButtons(self, form, wasselected): tool = form.getMaptool()(self.canvas) for action in tool.actions: # Create the action here. if action.ismaptool: action.toggled.connect(partial(self.setMapTool, tool)) # Set the action as a data entry button so we can remove it later. action.setProperty("dataentry", True) self.editgroup.addAction(action) self.layerbuttons.append(action) self.projecttoolbar.insertAction(self.topspaceraction, action) if action.isdefault: action.setChecked(wasselected) if hasattr(tool, 'geometryComplete'): add = partial(self.addNewFeature, form) tool.geometryComplete.connect(add) else: tool.finished.connect(self.openForm) tool.error.connect(partial(self.showToolError, form.label)) self.projecttoolbar.insertAction(self.topspaceraction, self.actionGPSFeature) self.actionGPSFeature.setVisible(not tool.isEditTool()) def createFormButtons(self, forms): """ Create buttons for each form that is defined """ self.dataentrymodel.clear() self.clearCapatureTools() def captureFeature(form): item = QStandardItem(QIcon(form.icon), form.icontext) item.setData(form, Qt.UserRole + 1) item.setSizeHint(QSize(item.sizeHint().width(), self.projecttoolbar.height())) self.dataentrymodel.appendRow(item) capabilitityhandlers = {"capture": captureFeature} failedforms = [] for form in forms: valid, reasons = form.valid if not valid: roam.utils.log("Form is invalid for data entry because {}".format(reasons)) failedforms.append((form, reasons)) continue for capability in form.capabilities: try: capabilitityhandlers[capability](form) except KeyError: # Just ignore capabilities we don't support yet. continue if failedforms: for form, reasons in failedforms: html = "<h3>{}</h3><br>{}".format(form.label, "<br>".join(reasons)) self.bar.pushMessage("Form errors", "Looks like some forms couldn't be loaded", level=QgsMessageBar.WARNING, extrainfo=html) visible = self.dataentrymodel.rowCount() > 0 self.dataentrycomboaction.setVisible(visible) self.dataentrycombo.setMinimumHeight(self.projecttoolbar.height()) index = self.dataentrymodel.index(0, 0) self.dataentrychanged(index) def addFeatureAtGPS(self): """ Add a record at the current GPS location. """ index = self.dataentrycombo.currentIndex() modelindex = self.dataentrymodel.index(index, 0) form = modelindex.data(Qt.UserRole + 1) point = self.actionGPS.position point = QgsGeometry.fromPoint(point) self.addNewFeature(form=form, geometry=point) def clearToolRubberBand(self): """ Clear the rubber band of the active tool if it has one """ tool = self.canvas.mapTool() try: tool.clearBand() except AttributeError: # No clearBand method found, but that's cool. pass def showhelp(self, url): help = HelpPage(self.stackedWidget) help.setHelpPage(url) help.show() def dataentryfinished(self): self.hidedataentry() self.showmap() self.cleartempobjects() self.infodock.refreshcurrent() def featuredeleted(self): self.dataentryfinished() self.bar.pushMessage("Deleted", "Feature Deleted", QgsMessageBar.INFO, 1) self.canvas.refresh() def featureSaved(self): self.dataentryfinished() self.canvas.refresh() def failSave(self, messages): self.bar.pushError("Error when saving changes.", messages) def cleartempobjects(self): self.band.reset() self.clearToolRubberBand() def formrejected(self, message, level): self.dataentryfinished() if message: self.bar.pushMessage("Form Message", message, level, duration=2) self.cleartempobjects() def openForm(self, form, feature): """ Open the form that is assigned to the layer """ self.band.setToGeometry(feature.geometry(), form.QGISLayer) self.showdataentry() self.dataentrywidget.openform(feature=feature, form=form, project=self.project) def addNewFeature(self, form, geometry): """ Add a new new feature to the given layer """ layer = form.QGISLayer fields = layer.pendingFields() feature = QgsFeature(fields) feature.setGeometry(geometry) for index in xrange(fields.count()): pkindexes = layer.dataProvider().pkAttributeIndexes() if index in pkindexes and layer.dataProvider().name() == 'spatialite': continue value = layer.dataProvider().defaultValue(index) feature[index] = value self.openForm(form, feature) def exit(self): """ Exit the application. """ QApplication.exit(0) def showInfoResults(self, results): self.infodock.clearResults() forms = {} for layer in results.keys(): layername = layer.name() if not layername in forms: forms[layername] = list(self.project.formsforlayer(layername)) self.infodock.setResults(results, forms) self.infodock.show() def toggleRasterLayers(self): """ Toggle all raster layers on or off. """ if not self.canvaslayers: return #Freeze the canvas to save on UI refresh self.canvas.freeze() for layer in self.canvaslayers: if layer.layer().type() == QgsMapLayer.RasterLayer: layer.setVisible(not layer.isVisible()) # Really!? We have to reload the whole layer set every time? # WAT? self.canvas.setLayerSet(self.canvaslayers) self.canvas.freeze(False) self.canvas.refresh() def missingLayers(self, layers): """ Called when layers have failed to load from the current project """ roam.utils.warning("Missing layers") map(roam.utils.warning, layers) missinglayers = roam.messagebaritems.MissingLayerItem(layers, parent=self.bar) self.bar.pushItem(missinglayers) def loadprojects(self, projects): """ Load the given projects into the project list """ projects = list(projects) self.projectwidget.loadProjectList(projects) self.syncwidget.loadprojects(projects) def updatePage(self, action): """ Update the current stack page based on the current selected action """ page = action.property("page") self.stackedWidget.setCurrentIndex(page) def show(self): """ Override show method. Handles showing the app in fullscreen mode or just maximized """ fullscreen = self.settings.settings.get("fullscreen", False) if fullscreen: self.showFullScreen() else: self.showMaximized() def viewprojects(self): self.stackedWidget.setCurrentIndex(1) def updateUIState(self, page): """ Update the UI state to reflect the currently selected page in the stacked widget """ pass @roam.utils.timeit def _readProject(self, doc): """ readProject is called by QgsProject once the map layer has been populated with all the layers """ parser = ProjectParser(doc) canvasnode = parser.canvasnode self.canvas.freeze() self.canvas.mapRenderer().readXML(canvasnode) self.canvaslayers = parser.canvaslayers() self.canvas.setLayerSet(self.canvaslayers) self.canvas.updateScale() self.projectOpened() self.canvas.freeze(False) self.canvas.refresh() self.showmap() @roam.utils.timeit def projectOpened(self): """ Called when a new project is opened in QGIS. """ projectpath = QgsProject.instance().fileName() self.project = Project.from_folder(os.path.dirname(projectpath)) self.projectlabel.setText("Project: {}".format(self.project.name)) self.createFormButtons(forms=self.project.forms) # Enable the raster layers button only if the project contains a raster layer. layers = QgsMapLayerRegistry.instance().mapLayers().values() hasrasters = any(layer.type() == QgsMapLayer.RasterLayer for layer in layers) self.actionRaster.setEnabled(hasrasters) self.defaultextent = self.canvas.extent() roam.utils.info("Extent: {}".format(self.defaultextent.toString())) # Show panels for panel in self.project.getPanels(): self.mainwindow.addDockWidget(Qt.BottomDockWidgetArea, panel) self.panels.append(panel) # TODO Abstract this out if not self.project.selectlayers: selectionlayers = QgsMapLayerRegistry.instance().mapLayers().values() else: selectionlayers = [] for layername in self.project.selectlayers: try: layer = QgsMapLayerRegistry.instance().mapLayersByName(layername)[0] except IndexError: roam.utils.warning("Can't find QGIS layer for select layer {}".format(layername)) continue selectionlayers.append(layer) self.infoTool.selectionlayers = selectionlayers self.actionPan.trigger() #noinspection PyArgumentList @roam.utils.timeit def loadProject(self, project): """ Load a project into the application . """ roam.utils.log(project) roam.utils.log(project.name) roam.utils.log(project.projectfile) roam.utils.log(project.valid) (passed, message) = project.onProjectLoad() if not passed: self.bar.pushMessage("Project load rejected", "Sorry this project couldn't" "be loaded. Click for me details.", QgsMessageBar.WARNING, extrainfo=message) return self.actionMap.trigger() self.closeProject() self.canvas.refresh() self.canvas.repaint() self.infodock.clearResults() # No idea why we have to set this each time. Maybe QGIS deletes it for # some reason. self.badLayerHandler = BadLayerHandler(callback=self.missingLayers) QgsProject.instance().setBadLayerHandler(self.badLayerHandler) self.stackedWidget.setCurrentIndex(3) self.projectloading_label.setText("Project {} Loading".format(project.name)) pixmap = QPixmap(project.splash) w = self.projectimage.width() h = self.projectimage.height() self.projectimage.setPixmap(pixmap.scaled(w,h, Qt.KeepAspectRatio)) QApplication.processEvents() QDir.setCurrent(os.path.dirname(project.projectfile)) fileinfo = QFileInfo(project.projectfile) QgsProject.instance().read(fileinfo) def closeProject(self): """ Close the current open project """ self.canvas.freeze() QgsMapLayerRegistry.instance().removeAllMapLayers() self.canvas.clear() self.canvas.freeze(False) for panel in self.panels: self.removeDockWidget(panel) del panel # Remove all the old buttons for action in self.layerbuttons: self.editgroup.removeAction(action) self.dataentrymodel.clear() self.panels = [] self.project = None self.dataentrywidget.clear() self.hidedataentry() self.infodock.close()