def set_completer(self, tablename, widget, field_search, color='black'): """ Set autocomplete of widget @table_object + "_id" getting id's from selected @table_object """ if not widget: return # Set SQL sql = ("SELECT DISTINCT(" + field_search + ")" " FROM " + self.schema_name + "." + tablename + "" " ORDER BY " + field_search + "") row = self.controller.get_rows(sql) for i in range(0, len(row)): aux = row[i] row[i] = str(aux[0]) # Set completer and model: add autocomplete in the widget self.completer = QCompleter() self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setCompletionMode(0) self.completer.popup().setStyleSheet("color: " + color + ";") widget.setCompleter(self.completer) model = QStringListModel() model.setStringList(row) self.completer.setModel(model)
def create_QNewStrategy(self): self.__q_new_strategy = QNewStrategy() completer = QCompleter() if self.get_got_list_instrument_info(): model = QStringListModel() model.setStringList(self.get_list_instrument_id()) completer.setModel(model) else: print(">>> CTPManager.create_QNewStrategy() 查询合约信息失败") self.__q_new_strategy.lineEdit_a_instrument.setCompleter(completer) self.__q_new_strategy.lineEdit_b_instrument.setCompleter(completer) self.__q_new_strategy.set_ClientMain( self.__client_main) # CTPManager设置为新建策略窗口属性 self.__q_new_strategy.set_CTPManager(self) # CTPManager设置为新建策略窗口属性 self.__q_new_strategy.set_SocketManager( self.__socket_manager) # SocketManager设置为新建策略窗口属性 self.__q_new_strategy.set_trader_id(self.__trader_id) # 设置trade_id属性 self.set_QNewStrategy(self.__q_new_strategy) # 新建策略窗口设置为CTPManager属性 self.__client_main.set_QNewStrategy( self.__q_new_strategy) # 新建策略窗口设置为ClientMain属性 self.signal_hide_QNewStrategy.connect( self.get_QNewStrategy().hide) # 绑定信号槽,新创建策略成功后隐藏“新建策略弹窗” # 绑定信号槽:新建策略窗新建策略指令 -> SocketManager.slot_send_msg self.__q_new_strategy.signal_send_msg.connect( self.__socket_manager.slot_send_msg)
def set_completers(self): """ Set autocompleters of the form """ # Adding auto-completion to a QLineEdit - visit_id self.completer = QCompleter() self.dlg.visit_id.setCompleter(self.completer) model = QStringListModel() sql = "SELECT DISTINCT(id) FROM " + self.schema_name + ".om_visit" rows = self.controller.get_rows(sql, commit=self.autocommit) values = [] if rows: for row in rows: values.append(str(row[0])) model.setStringList(values) self.completer.setModel(model) # Adding auto-completion to a QLineEdit - document_id self.completer = QCompleter() self.dlg.doc_id.setCompleter(self.completer) model = QStringListModel() sql = "SELECT DISTINCT(id) FROM " + self.schema_name + ".v_ui_document" rows = self.controller.get_rows(sql, commit=self.autocommit) values = [] if rows: for row in rows: values.append(str(row[0])) model.setStringList(values) self.completer.setModel(model)
def set_completer_object(self, dialog, table_object): """ Set autocomplete of widget @table_object + "_id" getting id's from selected @table_object """ widget = utils_giswater.getWidget(dialog, table_object + "_id") if not widget: return # Set SQL field_object_id = "id" if table_object == "element": field_object_id = table_object + "_id" sql = ("SELECT DISTINCT(" + field_object_id + ")" " FROM " + self.schema_name + "." + table_object) row = self.controller.get_rows(sql, commit=self.autocommit) for i in range(0, len(row)): aux = row[i] row[i] = str(aux[0]) # Set completer and model: add autocomplete in the widget self.completer = QCompleter() self.completer.setCaseSensitivity(Qt.CaseInsensitive) widget.setCompleter(self.completer) model = QStringListModel() model.setStringList(row) self.completer.setModel(model)
class AppletNoticeWindow(QWidget): def __init__(self, controller): QWidget.__init__(self) self.__controller = controller self.__pkglist = [] # setup widgets self.__vbox_up = QVBoxLayout() self.__critical_label = QLabel() self.__critical_label.setWordWrap(True) self.__list_model = QStringListModel() self.__list_view = QListView() self.__list_view.setModel(self.__list_model) self.__vbox_up.addWidget(self.__critical_label) self.__vbox_up.addWidget(self.__list_view) # bottom buttons self.__vbox = QVBoxLayout() self.__vbox.addLayout(self.__vbox_up) self.__button_hbox = QHBoxLayout() self.__close_button = QPushButton(_("Close")) self.__launch_pm_button = QPushButton(_("Launch Application Browser")) self.__button_hbox.addWidget(self.__launch_pm_button) self.__button_hbox.addWidget(self.__close_button) self.__vbox.addLayout(self.__button_hbox) self.setLayout(self.__vbox) # set window settings self.resize(400, 200) self.setWindowTitle(_("Application updates")) self.connect(self.__close_button, SIGNAL("clicked()"), self.on_close) self.connect(self.__launch_pm_button, SIGNAL("clicked()"), self.on_pm) def closeEvent(self, event): """ We don't want to kill the window, since the whole app will close otherwise. """ event.ignore() self.on_close() def on_pm(self): self.__controller.launch_package_manager() def on_close(self): self.__controller.trigger_notice_window() def populate(self, pkg_data, critical_txt): self.__list_model.setStringList(pkg_data) self.__critical_label.setText(critical_txt) self.__list_view.update()
def __init__(self,parent=None): super(QtGui.QLineEdit, self).__init__(parent) model = QStringListModel() completer = QCompleter() completer.setModel(model) model.setStringList(cmd.cmdset) self.setCompleter(completer)
def set_completer(self): """ Set autocompleters of the form """ # Adding auto-completion to a QLineEdit - visit_id self.completer = QCompleter() self.dlg_work.arc_id.setCompleter(self.completer) model = QStringListModel() model.setStringList(self.selected_list) self.completer.setModel(model)
def mg_mincut_management(self): """ Button 27: Mincut management """ self.action = "mg_mincut_management" # Create the dialog and signals self.dlg_min_edit = Mincut_edit() utils_giswater.setDialog(self.dlg_min_edit) self.tbl_mincut_edit = self.dlg_min_edit.findChild( QTableView, "tbl_mincut_edit") self.txt_mincut_id = self.dlg_min_edit.findChild( QLineEdit, "txt_mincut_id") self.tbl_mincut_edit.setSelectionBehavior(QAbstractItemView.SelectRows) # Adding auto-completion to a QLineEdit self.completer = QCompleter() self.txt_mincut_id.setCompleter(self.completer) model = QStringListModel() sql = "SELECT DISTINCT(id) FROM " + self.schema_name + ".anl_mincut_result_cat " rows = self.controller.get_rows(sql) values = [] for row in rows: values.append(str(row[0])) model.setStringList(values) self.completer.setModel(model) self.txt_mincut_id.textChanged.connect( partial(self.filter_by_id, self.tbl_mincut_edit, self.txt_mincut_id, "anl_mincut_result_cat")) self.dlg_min_edit.btn_accept.pressed.connect(self.open_mincut) self.dlg_min_edit.btn_cancel.pressed.connect(self.dlg_min_edit.close) self.dlg_min_edit.btn_delete.clicked.connect( partial(self.delete_mincut_management, self.tbl_mincut_edit, "anl_mincut_result_cat", "id")) # Fill ComboBox state sql = ("SELECT id" " FROM " + self.schema_name + ".anl_mincut_cat_state" " ORDER BY id") rows = self.controller.get_rows(sql) utils_giswater.fillComboBox("state_edit", rows) self.dlg_min_edit.state_edit.activated.connect( partial(self.filter_by_state, self.tbl_mincut_edit, self.dlg_min_edit.state_edit, "anl_mincut_result_cat")) # Set a model with selected filter. Attach that model to selected table self.fill_table_mincut_management( self.tbl_mincut_edit, self.schema_name + ".anl_mincut_result_cat") self.mincut.set_table_columns(self.tbl_mincut_edit, "anl_mincut_result_cat") self.dlg_min_edit.show()
def __init__(self,expdat): super(DBAnnotateSave, self).__init__() print("DBAnnotateSave") uic.loadUi(os.path.join(hs.heatsequerdir,'ui/manualdata.py'), self) self.bplus.clicked.connect(self.plus) self.bminus.clicked.connect(self.minus) self.bontoinput.returnPressed.connect(self.plus) self.bstudyinfo.clicked.connect(self.studyinfo) self.bisa.toggled.connect(self.radiotoggle) self.bdiffpres.toggled.connect(self.radiotoggle) self.bisatype.currentIndexChanged.connect(self.isatypechanged) self.bhistory.clicked.connect(self.history) self.cexp=expdat self.lnumbact.setText(str(len(expdat.selectedseqs))) completer = QCompleter() self.bontoinput.setCompleter(completer) scdb=hs.scdb self.scdb=scdb self.dataid=hs.supercooldb.finddataid(scdb,datamd5=self.cexp.datamd5,mapmd5=self.cexp.mapmd5) model = QStringListModel() completer.setModel(model) # completer.setCompletionMode(QCompleter.InlineCompletion) completer.maxVisibleItems=10 completer.setCaseSensitivity(Qt.CaseInsensitive) # make the completer selection also erase the text edit completer.activated.connect(self.cleartext,type=Qt.QueuedConnection) # in qt5 should work with middle complete as well... # completer.setFilterMode(Qt.MatchContains) if not hs.scdb.ontologyfromid: hs.scdb=hs.supercooldb.loaddbonto(hs.scdb) self.ontology=hs.scdb.ontology self.ontologyfromid=hs.scdb.ontologyfromid nlist=list(self.ontology.keys()) # nlist=sorted(nlist) nlist=sorted(nlist, key=lambda s: s.lower()) print("sorted ontology") model.setStringList(nlist) self.setWindowTitle(self.cexp.studyname) try: tt=hs.lastdatamd5 except: hs.lastdatamd5='' if self.cexp.datamd5==hs.lastdatamd5: self.fillfromcuration(hs.lastcurations[-1],onlyall=True) self.prefillinfo() self.bontoinput.setFocus()
def __init__(self, parent=None, settings={}, commands={}): super(CommandWindow, self).__init__(parent) self.settings = settings self.commands = commands self.push_button_run = QtGui.QPushButton(self) self.push_button_run.setText("Run") self.push_button_run.clicked.connect(self.on_push_button_run_clicked) self.push_button_run.setAutoDefault(True) self.line_edit_command = QtGui.QLineEdit(self) self.line_edit_command.returnPressed.connect( self.push_button_run.click) completer = QCompleter() self.line_edit_command.setCompleter(completer) self.line_edit_command.setFocus() model = QStringListModel() completer.setModel(model) model.setStringList(self.commands.keys()) self.message_label = QtGui.QLabel() self.message_label.setText("<i>please enter command</i>") self.message_label.setStyleSheet("color: #333333") self.error_label = QtGui.QLabel() self.error_label.setStyleSheet("color: red") self.error_label.hide() self.output_label = QtGui.QLabel() self.output_label.setStyleSheet( "font-family: monospace; background-color: #eeeeee; color: green") self.output_label.hide() self.layoutHorizontal = QtGui.QHBoxLayout() self.layoutHorizontal.addWidget(self.line_edit_command) self.layoutHorizontal.addWidget(self.push_button_run) self.layout_vertical = QtGui.QVBoxLayout(self) self.layout_vertical.addWidget(self.message_label) self.layout_vertical.addLayout(self.layoutHorizontal) self.layout_vertical.addWidget(self.error_label) self.layout_vertical.addWidget(self.output_label) self.installEventFilter(self) # self.resize(640, 480) self.center()
def edit_add_element(self): """ Button 33: Add element """ # Create the dialog and signals self.dlg = AddElement() utils_giswater.setDialog(self.dlg) self.set_icon(self.dlg.add_geom, "129") self.dlg.btn_accept.pressed.connect(self.ed_add_element_accept) self.dlg.btn_cancel.pressed.connect(self.close_dialog) # Manage i18n of the form self.controller.translate_form(self.dlg, 'element') # Check if we have at least one feature selected if not self.edit_check(): return # Fill combo boxes self.populate_combo("elementcat_id", "cat_element") self.populate_combo("state", "value_state") self.populate_combo("location_type", "man_type_location") self.populate_combo("workcat_id", "cat_work") self.populate_combo("buildercat_id", "cat_builder") self.populate_combo("ownercat_id", "cat_owner") self.populate_combo("verified", "value_verified") self.populate_combo("workcat_id_end", "cat_work") # Adding auto-completion to a QLineEdit self.edit = self.dlg.findChild(QLineEdit, "element_id") self.completer = QCompleter() self.edit.setCompleter(self.completer) model = QStringListModel() sql = "SELECT DISTINCT(element_id) FROM " + self.schema_name + ".element " row = self.dao.get_rows(sql) for i in range(0, len(row)): aux = row[i] row[i] = str(aux[0]) model.setStringList(row) self.completer.setModel(model) # Set signal to reach selected value from QCompleter self.completer.activated.connect(self.ed_add_el_autocomplete) self.dlg.add_geom.pressed.connect(self.add_point) # Open the dialog self.dlg.setWindowFlags(Qt.WindowStaysOnTopHint) self.dlg.open()
def set_model_by_list(string_list, widget, proxy_model): """ Set the model according to the list """ model = QStringListModel() model.setStringList(string_list) proxy_model.setSourceModel(model) proxy_model.setFilterKeyColumn(0) proxy_model_aux = QSortFilterProxyModel() proxy_model_aux.setSourceModel(model) proxy_model_aux.setFilterKeyColumn(0) widget.setModel(proxy_model_aux) widget.setModelColumn(0) completer = QCompleter() completer.setModel(proxy_model) completer.setCompletionColumn(0) completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) widget.setCompleter(completer)
def set_model_by_list(self, string_list, widget): model = QStringListModel() model.setStringList(string_list) self.proxy_model = QSortFilterProxyModel() self.proxy_model.setSourceModel(model) self.proxy_model.setFilterKeyColumn(0) proxy_model_aux = QSortFilterProxyModel() proxy_model_aux.setSourceModel(model) proxy_model_aux.setFilterKeyColumn(0) widget.setModel(proxy_model_aux) widget.setModelColumn(0) completer = QCompleter() completer.setModel(self.proxy_model) completer.setCompletionColumn(0) completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion) widget.setCompleter(completer)
def set_completers(self, widget, table_name): """ Set autocompleters of the form """ # Adding auto-completion to a QLineEdit - visit_id self.completer = QCompleter() widget.setCompleter(self.completer) model = QStringListModel() sql = "SELECT DISTINCT(id) FROM " + self.schema_name + "." +str(table_name) rows = self.controller.get_rows(sql, commit=self.autocommit) values = [] if rows: for row in rows: values.append(str(row[0])) model.setStringList(values) self.completer.setModel(model)
class IntroPage(WizardPage): UI_CLASS = Ui_Intro TITLE = "Starting a bisection" SUBTITLE = "Please choose an application and a type of bisection." FIELDS = {'application': 'app_combo', 'bisect_type': 'bisect_combo', 'find_fix': 'find_fix'} ID = 0 def __init__(self): WizardPage.__init__(self) self.fetch_config = None self.app_model = QStringListModel(REGISTRY.names()) self.ui.app_combo.setModel(self.app_model) self.bisect_model = QStringListModel() self.ui.bisect_combo.setModel(self.bisect_model) self.ui.app_combo.currentIndexChanged.connect(self._set_fetch_config) self._set_fetch_config(0) def _set_fetch_config(self, index): # limit bisection type given the application old_bisect_index = self.ui.bisect_combo.currentIndex() self.fetch_config = create_config( str(self.ui.app_combo.itemText(index)), mozinfo.os, mozinfo.bits) bisect_types = ['nightlies'] if self.fetch_config.is_inbound(): bisect_types.append('inbound') self.bisect_model.setStringList(bisect_types) bisect_index = 0 if old_bisect_index == 1 and len(bisect_types) == 2: bisect_index = 1 self.ui.bisect_combo.setCurrentIndex(bisect_index) def validatePage(self): app_name = self.fetch_config.app_name launcher_class = LAUNCHER_REGISTRY.get(app_name) try: launcher_class.check_is_runnable() return True except LauncherNotRunnable, exc: QMessageBox.critical( self, "%s is not runnable" % app_name, str(exc) ) return False
def ed_add_element(self): ''' Button 33. Add element ''' # Create the dialog and signals self.dlg = Add_element() utils_giswater.setDialog(self.dlg) self.dlg.btn_accept.pressed.connect(self.ed_add_element_accept) self.dlg.btn_cancel.pressed.connect(self.close_dialog) # Manage i18n of the form self.controller.translate_form(self.dlg, 'element') # Check if we have at least one feature selected if not self.ed_check(): return # Fill combo boxes self.populate_combo("elementcat_id", "cat_element") self.populate_combo("state", "value_state") self.populate_combo("location_type", "man_type_location") self.populate_combo("workcat_id", "cat_work") self.populate_combo("buildercat_id", "cat_builder") self.populate_combo("elementcat_id", "cat_element") self.populate_combo("ownercat_id", "cat_owner") self.populate_combo("verified", "value_verified") # Adding auto-completion to a QLineEdit self.edit = self.dlg.findChild(QLineEdit, "element_id") self.completer = QCompleter() self.edit.setCompleter(self.completer) model = QStringListModel() sql = "SELECT DISTINCT(element_id) FROM "+self.schema_name+".element " row = self.dao.get_rows(sql) for i in range(0,len(row)): aux = row[i] row[i] = str(aux[0]) model.setStringList(row) self.completer.setModel(model) # Set signal to reach selected value from QCompleter self.completer.activated.connect(self.ed_add_el_autocomplete) # Open the dialog self.dlg.exec_()
def edit_add_file(self): """ Button 34: Add document """ # Create the dialog and signals self.dlg = AddDoc() utils_giswater.setDialog(self.dlg) self.dlg.btn_accept.pressed.connect(self.edit_add_file_accept) self.dlg.btn_cancel.pressed.connect(self.close_dialog) # Get widgets self.dlg.path_url.clicked.connect(partial(self.open_web_browser, "path")) self.dlg.path_doc.clicked.connect(partial(self.get_file_dialog, "path")) # Manage i18n of the form self.controller.translate_form(self.dlg, 'file') # Check if we have at least one feature selected if not self.edit_check(): return # Fill combo boxes self.populate_combo("doc_type", "doc_type") # Adding auto-completion to a QLineEdit self.completer = QCompleter() self.dlg.doc_id.setCompleter(self.completer) model = QStringListModel() sql = "SELECT DISTINCT(id) FROM " + self.schema_name + ".doc " row = self.dao.get_rows(sql) for i in range(0, len(row)): aux = row[i] row[i] = str(aux[0]) model.setStringList(row) self.completer.setModel(model) # Set signal to reach selected value from QCompleter self.completer.activated.connect(self.edit_add_file_autocomplete) # Open the dialog self.dlg.exec_()
def create_QNewStrategy(self): self.__q_new_strategy = QNewStrategy() completer = QCompleter() if self.get_got_list_instrument_info(): model = QStringListModel() model.setStringList(self.get_list_instrument_id()) completer.setModel(model) else: print(">>> CTPManager.create_QNewStrategy() 查询合约信息失败") self.__q_new_strategy.lineEdit_a_instrument.setCompleter(completer) self.__q_new_strategy.lineEdit_b_instrument.setCompleter(completer) self.__q_new_strategy.set_ClientMain(self.__client_main) # CTPManager设置为新建策略窗口属性 self.__q_new_strategy.set_CTPManager(self) # CTPManager设置为新建策略窗口属性 self.__q_new_strategy.set_SocketManager(self.__socket_manager) # SocketManager设置为新建策略窗口属性 self.__q_new_strategy.set_trader_id(self.__trader_id) # 设置trade_id属性 self.set_QNewStrategy(self.__q_new_strategy) # 新建策略窗口设置为CTPManager属性 self.__client_main.set_QNewStrategy(self.__q_new_strategy) # 新建策略窗口设置为ClientMain属性 self.signal_hide_QNewStrategy.connect(self.get_QNewStrategy().hide) # 绑定信号槽,新创建策略成功后隐藏“新建策略弹窗” # 绑定信号槽:新建策略窗新建策略指令 -> SocketManager.slot_send_msg self.__q_new_strategy.signal_send_msg.connect(self.__socket_manager.slot_send_msg)
def __init__(self, items): QSpinBox.__init__(self) self.setMinimumWidth(75) self.__string_converter = str self.__items = items list = [] for item in self.__items: assert isinstance(item, CTime) date = item.date() list.append(self.convertToString(date)) model = QStringListModel() model.setStringList(list) self.setRange(0, len(items) - 1) self.setValue(len(items) - 1) line_edit = QLineEdit() self.setLineEdit(line_edit)
def set_completer_feature_id(self, widget, geom_type, viewname): """ Set autocomplete of widget 'feature_id' getting id's from selected @viewname """ # Adding auto-completion to a QLineEdit self.completer = QCompleter() self.completer.setCaseSensitivity(Qt.CaseInsensitive) widget.setCompleter(self.completer) model = QStringListModel() sql = ("SELECT " + geom_type + "_id" " FROM " + self.schema_name + "." + viewname) row = self.controller.get_rows(sql, commit=self.autocommit) if row: for i in range(0, len(row)): aux = row[i] row[i] = str(aux[0]) model.setStringList(row) self.completer.setModel(model)
def ed_add_file(self): ''' Button 34. Add file ''' # Create the dialog and signals self.dlg = Add_file() utils_giswater.setDialog(self.dlg) self.dlg.btn_accept.pressed.connect(self.ed_add_file_accept) self.dlg.btn_cancel.pressed.connect(self.close_dialog) # Manage i18n of the form self.controller.translate_form(self.dlg, 'file') # Check if we have at least one feature selected if not self.ed_check(): return # Fill combo boxes self.populate_combo("doc_type", "doc_type") self.populate_combo("tagcat_id", "cat_tag") # Adding auto-completion to a QLineEdit self.edit = self.dlg.findChild(QLineEdit, "doc_id") self.completer = QCompleter() self.edit.setCompleter(self.completer) model = QStringListModel() sql = "SELECT DISTINCT(id) FROM "+self.schema_name+".doc " row = self.dao.get_rows(sql) for i in range(0,len(row)): aux = row[i] row[i] = str(aux[0]) model.setStringList(row) self.completer.setModel(model) # Set signal to reach selected value from QCompleter self.completer.activated.connect(self.ed_add_file_autocomplete) # Open the dialog self.dlg.exec_()
class ExplainView(QListView): """show a list explaining all score computations""" def __init__(self, game, parent=None): QListView.__init__(self, parent) self.game = None self.setWindowTitle(m18n('Explain Scores').replace('&', '') + ' - Kajongg') self.setGeometry(0, 0, 300, 400) self.model = QStringListModel() self.setModel(self.model) StateSaver(self) self.refresh(game) def refresh(self, game): """refresh for new values""" self.game = game lines = [] if self.game is None: lines.append(m18n('There is no active game')) else: i18nName = m18n(self.game.ruleset.name) lines.append(m18n('Ruleset: %1', i18nName)) lines.append('') for player in self.game.players: pLines = [] if player.hand and player.hand.tileNames: total = player.hand.total() if total: pLines = ['%s: %s' % (player.localName, total)] for line in player.hand.explain(): pLines.append('- ' + line) elif player.handTotal: pLines.append(m18n('Manual score for %1: %2 points', player.localName, player.handTotal)) if pLines: pLines.append('') lines.extend(pLines) if 'xxx'.join(lines) != 'xxx'.join(unicode(x) for x in self.model.stringList()): # QStringListModel does not optimize identical lists away, so we do self.model.setStringList(lines)
class AddNewWord(QLineEdit): def __init__(self): super(AddNewWord, self).__init__(None) self.setWindowTitle("AddNewWord") completer = QCompleter(self) self.string_list_model = QStringListModel(self) completer.setCaseSensitivity(Qt.CaseInsensitive) completer.setModel(self.string_list_model) self.setCompleter(completer) self.connect(self, SIGNAL("editingFinished()"), self.editComplete) self.word_list = QStringList() def editComplete(self): text = self.text() if QString.compare(text, QString("")) != 0: is_contains = self.word_list.contains(text, Qt.CaseInsensitive) if not is_contains: self.word_list << text self.string_list_model.setStringList(self.word_list)
class LineEdit(QLineEdit): """Cursom QLineEdit with tab completion""" def __init__(self, parent=None): QLineEdit.__init__(self, parent) self.completer = QCompleter() self.setCompleter(self.completer) self.model = QStringListModel() self.completer.setModel(self.model) #get_data(model) self.completions = None self.parent = parent def keyPressEvent(self, event): """Handle keypress event""" text = self.text() if event.key() == Qt.Key_Tab: current_text = self.text() if current_text != '': for item in self.completions: if item.startswith(current_text): self.setText(item) break event.accept() elif event.key() == Qt.Key_Return: if text != '': self.window().process_command(text) self.setText('') event.accept() else: QLineEdit.keyPressEvent(self, event) def set_completions(self, completions): """Set completions""" self.completions = completions self.model.setStringList(completions)
class ControlPanelWindow(QMainWindow, Ui_ControlPanelWindow): def __init__(self): QMainWindow.__init__(self) self.setupUi(self) self.__nodesList = [] self.__nodesModel = QStringListModel(self) self.nodesView.setModel(self.__nodesModel) OTPApplication.instance().lastWindowClosed.connect(self._quit) BootstrapServer.nodeDown.connect(self._nodeDown) BootstrapServer.nodeUp.connect(self._nodeUp) BootstrapServer.ready.connect(lambda: self.actionBootstrap.setEnabled(True)) BootstrapServer.notReady.connect(lambda: self.actionBootstrap.setEnabled(False)) QTimer.singleShot(0, self._startup) @pyqtSlot(name="on_actionBootstrap_triggered") def _bootstrap(self): self.actionNew.setEnabled(False) self.actionBootstrap.setEnabled(False) BootstrapServer.bootstrap(self._bootstrapDone, *self.__bootstrapArgs) def _bootstrapDone(self, reply): if reply == "ok": self.statusBar().showMessage("System bootstrapped successfully", 5000) self.actionShutdown.setEnabled(True) else: self.statusBar().showMessage("Bootstrap failed", 5000) QMessageBox.critical(self, "Error", "An error occurred during bootstrap:\n\n %s" % reply) self.actionNew.setEnabled(True) self.actionBootstrap.setEnabled(True) @pyqtSlot(name="on_actionNew_triggered") def _newSimulation(self): dialog = ConfigDialog(self) if dialog.exec_() == ConfigDialog.Accepted: self.__bootstrapArgs = dialog.bootstrapArgs() def _nodeDown(self, node): try: self.__nodesList.remove(str(node)) self.__nodesModel.setStringList(self.__nodesList) except ValueError: pass def _nodeUp(self, node): self.__nodesList.append(str(node)) self.__nodesModel.setStringList(self.__nodesList) def _quit(self): BootstrapServer.shutdown(lambda _: OTPApplication.quit(), Atom("true")) def _setGuiNode(self): BootstrapServer.setGuiNode(self._setGuiNodeDone, OTPApplication.nodeName()) def _setGuiNodeDone(self, reply): if reply == "ok": QTimer.singleShot(0, self.actionNew.trigger) else: QTimer.singleShot(500, self._setGuiNode) @pyqtSlot(name="on_actionShutdown_triggered") def _shutdown(self): self.actionShutdown.setEnabled(False) BootstrapServer.shutdown(self._shutdownDone, Atom("false")) def _shutdownDone(self, reply): if reply == "ok": self.statusBar().showMessage("System shutdown complete", 5000) self.actionNew.setEnabled(True) else: self.statusBar().showMessage("Shutdown failed", 5000) QMessageBox.critical(self, "Error", "An error occurred during shutdown:\n\n %s" % reply) self.actionShutdown.setEnabled(True) def _startup(self): if BootstrapServer.start(): self._setGuiNode() else: QMessageBox.critical(self, "Fatal error", "Failed to start an instance of bootstrap_server.") OTPApplication.quit()
class IntroPage(WizardPage): UI_CLASS = Ui_Intro TITLE = "Bisection start" SUBTITLE = ("Please choose an application, a type of bisection" " and the number of bits for the application.") FIELDS = {'application': 'app_combo', 'bisect_type': 'bisect_combo', 'find_fix': 'find_fix', 'bits': 'bits_combo'} ID = 0 def __init__(self): WizardPage.__init__(self) self.fetch_config = None self.app_model = QStringListModel(REGISTRY.names()) self.ui.app_combo.setModel(self.app_model) self.bisect_model = QStringListModel() self.ui.bisect_combo.setModel(self.bisect_model) if mozinfo.bits == 64: self.bits_model = QStringListModel(['32', '64']) bits_index = 1 elif mozinfo.bits == 32: self.bits_model = QStringListModel(['32']) bits_index = 0 self.ui.bits_combo.setModel(self.bits_model) self.ui.bits_combo.setCurrentIndex(bits_index) self.ui.app_combo.currentIndexChanged.connect(self._set_fetch_config) self.ui.bits_combo.currentIndexChanged.connect(self._set_fetch_config) self.ui.app_combo.setCurrentIndex( self.ui.app_combo.findText("firefox")) def _set_fetch_config(self, index): # limit bisection type given the application bits = int(self.ui.bits_combo.currentText()) old_bisect_index = self.ui.bisect_combo.currentIndex() self.fetch_config = create_config( str(self.ui.app_combo.itemText(index)), mozinfo.os, bits) bisect_types = ['nightlies'] if self.fetch_config.is_inbound(): bisect_types.append('inbound') self.bisect_model.setStringList(bisect_types) bisect_index = 0 if old_bisect_index == 1 and len(bisect_types) == 2: bisect_index = 1 self.ui.bisect_combo.setCurrentIndex(bisect_index) available_bits = self.fetch_config.available_bits() if not available_bits: self.ui.bits_combo.hide() self.ui.label_4.hide() else: self.ui.bits_combo.show() self.ui.label_4.show() def validatePage(self): app_name = self.fetch_config.app_name launcher_class = LAUNCHER_REGISTRY.get(app_name) try: launcher_class.check_is_runnable() return True except LauncherNotRunnable, exc: QMessageBox.critical( self, "%s is not runnable" % app_name, str(exc) ) return False
class PylouWidget(QGraphicsWidget): """Main Widget for Pylou.""" def __init__(self, parent): """Init class.""" QGraphicsWidget.__init__(self) self.applet = parent def init(self): """Start Pylou Widget.""" self.layou = QGraphicsLinearLayout(self) self.stringlist = QStringList() self.model = QStringListModel(self.applet) self.model.setStringList(self.stringlist) self.treeview = MyTreeView(self) self.treeview.setModel(self.model) self.lineEdit, self.label = MyLineEdit(self), Plasma.Label(self) self.label.setText("Search") self.layou.setOrientation(0x2) # Qt.Vertical self.layou.addItem(self.treeview) self.layou.addItem(self.label) self.layou.addItem(self.lineEdit) self.setLayout(self.layou) self.lineEdit.returnPressed.connect(self.addItem) self.setMinimumSize(200, 99) self.setMaximumSize(666, 666) # custom user choosed fonts user_font_family = QVariant(self.applet.configurations.readEntry( "TextFont", QVariant(QFont()))) self.treeview.nativeWidget().setFont(QFont(user_font_family)) # custom user choosed styles user_style_sheet = "color:{};alternate-background-color:{}".format( self.applet.configurations.readEntry("TextColor"), self.applet.configurations.readEntry("AlternateBColor")) self.treeview.nativeWidget().setStyleSheet(user_style_sheet) # Qt connecting people Applet.connect( self.lineEdit, SIGNAL("keyUPPressed"), self.prevHistoryItem) Applet.connect( self.lineEdit, SIGNAL("keyDownPressed"), self.nextHistoryItem) Applet.connect(self.treeview, SIGNAL("DblClick"), self.openFile) Applet.connect(self.treeview, SIGNAL("Click"), self.openDirectory) self.applet.appletDestroyed.connect(self.saveHistory) # History file self.histfile = HISTORY_FILE_PATH with open(self.histfile, 'r') as history_file: self.history = history_file.readlines() self.historyCurrentItem = 0 self.treeview.nativeWidget().hide() self.resize(self.minimumSize()) def saveHistory(self): """Write History to History file.""" with open(self.histfile, 'w') as history_file: history_file.writelines(self.history) def prevHistoryItem(self): """Navigate the History 1 Item Backwards.""" if self.historyCurrentItem < len(self.history): self.historyCurrentItem = self.historyCurrentItem + 1 try: self.lineEdit.setText(str(self.history[-self.historyCurrentItem])) except IndexError as error: print(error) self.label.setText("ERROR: History Empty.") def nextHistoryItem(self): """Navigate the History 1 Item Forwards.""" if self.historyCurrentItem > 1: self.historyCurrentItem = self.historyCurrentItem - 1 try: self.lineEdit.setText(str(self.history[-self.historyCurrentItem])) except IndexError as error: print(error) self.label.setText("ERROR: History Empty.") def addItem(self): """Add Items from Locate command.""" start_time = datetime.now().second self.stringlist.clear() lineText = self.lineEdit.text() if len(lineText) and str(lineText).strip() not in self.history: self.history.append(lineText + "\n") self.historyCurrentItem = 1 self.saveHistory() self.historyCurrentItem = self.historyCurrentItem - 1 command = "ionice --ignore --class 3 chrt --idle 0 " # Nice CPU / IO command += "locate --ignore-case --existing --quiet --limit 9999 {}" condition = str(self.applet.configurations.readEntry("Home")) == "true" if len(str(lineText).strip()) and condition: command_to_run = command.format( # Only Search inside Home folders path.join(path.expanduser("~"), "*{}*".format(lineText))) else: command_to_run = command.format(lineText) locate_output = Popen(command_to_run, shell=True, stdout=PIPE).stdout results = tuple(locate_output.readlines()) banned = self.applet.configurations.readEntry("Banned") banned_regex_pattern = str(banned).strip().lower().replace(" ", "|") for item in results: if not search(banned_regex_pattern, str(item)): # banned words self.stringlist.append(item[:-1]) purge() # Purge RegEX Cache self.model.setStringList(self.stringlist) self.treeview.nativeWidget().resizeColumnToContents(0) number_of_results = len(results) if number_of_results: # if tems found Focus on item list self.lineEdit.nativeWidget().clear() self.label.setText("Found {} results on {} seconds !".format( number_of_results, abs(datetime.now().second - start_time))) self.resize(500, 12 * number_of_results) self.treeview.nativeWidget().show() self.treeview.nativeWidget().setFocus() else: # if no items found Focus on LineEdit self.label.setText("Search") self.resize(self.minimumSize()) self.treeview.nativeWidget().hide() self.lineEdit.nativeWidget().selectAll() self.lineEdit.nativeWidget().setFocus() def openDirectory(self, index): """Take a model index and find the folder name then open the folder.""" item_to_open = path.dirname(str(self.model.data(index, 0).toString())) Popen("xdg-open '{}'".format(item_to_open), shell=True) def openFile(self, index): """Take a model index and find the filename then open the file.""" item_to_open = self.model.data(index, 0).toString() Popen("xdg-open '{}'".format(item_to_open), shell=True)
class DicomBrowser(QtGui.QMainWindow, Ui_DicomBrowserWin): ''' This is the window class for the app which implements the UI functionality and the directory loading thread. It inherits from the type loaded from the .ui file in the resources. ''' statusSignal = QtCore.pyqtSignal( str, int, int) # signal for updating the status bar asynchronously updateSignal = QtCore.pyqtSignal( ) # signal for updating the source list and series table def __init__(self, args, parent=None): QtGui.QMainWindow.__init__(self, parent) self.srclist = [] # list of source directories self.imageIndex = 0 # index of selected image self.seriesMap = OrderedDict( ) # maps series table row tuples to DicomSeries object it was generated from self.seriesColumns = list(seriesListColumns) # keywords for columns self.selectedRow = -1 # selected series row self.lastDir = '.' # last loaded directory root self.filterRegex = '' # regular expression to filter tags by # create the directory queue and loading thread objects self.dirQueue = Queue() # queue of directories to load self.loadDirThread = threading.Thread(target=self._loadDirsThread) self.loadDirThread.daemon = True # clean shutdown possible with daemon threads self.loadDirThread.start( ) # start the thread now, it will wait until something is put on self.dirQueue # setup ui self.setupUi(self) # create UI elements based on the loaded .ui file self.setWindowTitle('DicomBrowser v%s (FOR RESEARCH ONLY)' % (__version__)) self.setStatus('') # connect signals self.importButton.clicked.connect(self._openDirDialog) self.statusSignal.connect(self.setStatus) self.updateSignal.connect(self._updateSeriesTable) self.filterLine.textChanged.connect(self._setFilterString) self.imageSlider.valueChanged.connect(self.setSeriesImage) self.seriesView.clicked.connect(self._seriesTableClicked) # setup the list and table models self.srcmodel = QStringListModel() self.seriesmodel = SeriesTableModel(self.seriesColumns) self.seriesmodel.layoutChanged.connect(self._seriesTableResize) self.tagmodel = QtGui.QStandardItemModel() # assign models to views self.sourceListView.setModel(self.srcmodel) self.seriesView.setModel(self.seriesmodel) self.tagView.setModel(self.tagmodel) # create the pyqtgraph object for viewing images self.imageview = pg.ImageView() layout = QtGui.QGridLayout(self.view2DGroup) layout.addWidget(self.imageview) # load the empty image placeholder into a ndarray qimg = QtGui.QImage(':/icons/noimage.png') bytedata = qimg.constBits().asstring(qimg.width() * qimg.height()) self.noimg = np.ndarray((qimg.width(), qimg.height()), dtype=np.ubyte, buffer=bytedata) # add the directories passed as arguments to the directory queue to start loading for i in args: if os.path.isdir(i): self.addSourceDir(i) def keyPressEvent(self, e): '''Close the window if escape is pressed, otherwise do as inherited.''' if e.key() == Qt.Key_Escape: self.close() else: QtGui.QMainWindow.keyPressEvent(self, e) def show(self): '''Calls the inherited show() method then sets the splitter positions.''' QtGui.QMainWindow.show(self) self.listSplit.moveSplitter(200, 1) self.seriesSplit.moveSplitter(100, 1) self.viewMetaSplitter.moveSplitter(800, 1) def _loadDirsThread(self): ''' This method is run in a daemon thread and continually checks self.dirQueue for a queued directory to scan for Dicom files. It calls loadDicomDir() for a given directory and adds the results the self.srclist member. ''' while True: try: rootdir = self.dirQueue.get(True, 0.5) series = loadDicomDir(rootdir, self.statusSignal.emit) if series and all(len(s.filenames) > 0 for s in series): for s in series: s.filenames, s.dcms = zip(*sorted( zip(s.filenames, s.dcms))) # sort series contents by filename self.srclist.append((rootdir, series)) self.updateSignal.emit() except Empty: pass def _openDirDialog(self): '''Opens the open file dialog to choose a directory to scan for Dicoms.''' rootdir = str( QtGui.QFileDialog.getExistingDirectory(self, 'Choose Source Directory', self.lastDir)) if rootdir: self.addSourceDir(rootdir) def _updateSeriesTable(self): ''' Updates the self.seriesMap object from self.srclist, and refills the self.srcmodel object. This will refresh the list of source directories and the table of available series. ''' self.seriesMap.clear() for _, series in self.srclist: # add each series in each source into self.seriesMap for s in series: entry = s.getTagValues(self.seriesColumns) self.seriesMap[entry] = s self.srcmodel.setStringList([s[0] for s in self.srclist]) self.seriesmodel.updateSeriesTable(self.seriesMap.keys()) self.seriesmodel.layoutChanged.emit() def _seriesTableClicked(self, item): '''Called when a series is clicked on, set the viewed image to be from the clicked series.''' self.selectedRow = item.row() self.setSeriesImage(self.imageSlider.value(), True) def _seriesTableResize(self): '''Resizes self.seriesView columns to contents, setting the last section to stretch.''' self.seriesView.horizontalHeader().setStretchLastSection(False) self.seriesView.resizeColumnsToContents() self.seriesView.horizontalHeader().setStretchLastSection(True) def _setFilterString(self, regex): '''Set the filtering regex to be `regex'.''' self.filterRegex = regex self._fillTagView() def _fillTagView(self): '''Refill the Dicom tag view, this will rejig the columns and (unfortunately) reset column sorting.''' series = self.getSelectedSeries() vpos = self.tagView.verticalScrollBar().value() self.tagmodel.clear() self.tagmodel.setHorizontalHeaderLabels(tagTreeColumns) fillTagModel(self.tagmodel, series.getTagObject(self.imageIndex), self.filterRegex) self.tagView.expandAll() self.tagView.resizeColumnToContents(0) self.tagView.verticalScrollBar().setValue(vpos) def getSelectedSeries(self): '''Returns the DicomSeries object for the selected series, None if no series is selected.''' if 0 <= self.selectedRow < len(self.seriesMap): return self.seriesMap[self.seriesmodel.getRow(self.selectedRow)] def setSeriesImage(self, i, autoRange=False): ''' Set the view image to be that at index `i' of the selected series. The `autoRange' boolean value sets whether the data value range is reset or not when this is done. The tag table is also set to that of image `i'. ''' series = self.getSelectedSeries() if series: maxindex = len(series.filenames) - 1 self.imageIndex = np.clip(i, 0, maxindex) img = series.getPixelData(self.imageIndex) # image matrix interval = 1 # tick interval on the slider # choose a more sensible tick interval if there's a lot of images if maxindex >= 5000: interval = 100 elif maxindex >= 500: interval = 10 if img is None: # if the image is None use the default "no image" object img = self.noimg #elif len(img.shape)==3: # multi-channel or multi-dimensional image, use average of dimensions # img=np.mean(img,axis=2) self.imageview.setImage( img.T, autoRange=autoRange, autoLevels=self.autoLevelsCheck.isChecked()) self._fillTagView() self.imageSlider.setTickInterval(interval) self.imageSlider.setMaximum(maxindex) self.numLabel.setText(str(self.imageIndex)) self.view2DGroup.setTitle('2D View - ' + series.filenames[self.imageIndex]) def setStatus(self, msg, progress=0, progressmax=0): ''' Set the status bar with message `msg' with progress set to `progress' out of `progressmax', or hide the status elements if `msg' is empty or None. ''' if not msg: progress = 0 progressmax = 0 self.statusText.setText(msg) self.statusText.setVisible(bool(msg)) self.importButton.setVisible(not bool(msg)) self.statusProgressBar.setVisible(progressmax > 0) self.statusProgressBar.setRange(0, progressmax) self.statusProgressBar.setValue(progress) def removeSourceDir(self, index): '''Remove the source directory at the given index.''' self.srclist.pop(index) self.updateSignal.emit() def addSourceDir(self, rootdir): '''Add the given directory to the queue of directories to load and set the self.lastDir value to its parent.''' self.dirQueue.put(rootdir) self.lastDir = os.path.dirname(rootdir)
class MainForm(QtGui.QWidget, Ui_Form2): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.setupUi(self) global creds,address r=req.get(address+"/send/all",auth=creds,verify=False) ls=r.json() self.userBox.addItems(ls) self.model = QStringListModel() r=req.get(address+"/receive/get/all",auth=creds,verify=False) self.files=r.json() self.model.setStringList(self.files) self.listView.setModel(self.model) self.pushButton.clicked.connect(self.openButton) self.sendButton.clicked.connect(self.sButton) self.getFile.clicked.connect(self.getfile) self.exiter.clicked.connect(self.end) self.pushButton_2.clicked.connect(self.change) self.delete_button.clicked.connect(self.del_file) def del_file(self): items=self.listView.selectedIndexes() r=req.get(address+"/receive/delete/"+str(items[0].row()+1),auth=creds,verify=False) r=req.get(address+"/receive/get/all",auth=creds,verify=False) self.files=r.json() self.model.setStringList(self.files) self.listView.setModel(self.model) def change(self): oldp=str(self.oldpassword.text()) newp1=str(self.newpassword1.text()) newp2=self.newpassword2.text() if not newp1==newp2: QMessageBox.about(self,"Error","Passwords don't match") else: ch=req.get(address+"/change/"+oldp+"/"+newp1,auth=creds,verify=False) if "changed" in ch.text: decrypt_file(hashlib.sha256(oldp).digest(),creds[0]+"key.enc") os.remove(creds[0]+"key.enc") encrypt_file(hashlib.sha256(newp1).digest(),creds[0]+"key") os.remove(creds[0]+"key") QMessageBox.about(self,"Info","Passwords successfully changed") else: QMessageBox.about(self,"Info","Password could not be changed") def end(self): QtCore.QCoreApplication.instance().quit() def openButton(self): self.filen=QFileDialog.getOpenFileName() self.Filename.setText(self.filen) def sButton(self): if self.filen: usern=self.userBox.currentText() r=req.get(address+"/send/"+usern,auth=creds,verify=False) key=RsaPublicKey.Read(r.json()["key"]) data=open(self.filen,"r").read() aesk=AesKey.Generate() symencdata=aesk.Encrypt(data) decrypt_file(hashlib.sha256(str(creds[1])).digest(),creds[0]+"key.enc") privatekey=RsaPrivateKey.Read(open(str(creds[0])+"key").read()) os.remove(creds[0]+"key") akey=key.Encrypt(str(aesk)) filename =str(self.filen).split("/")[-1] finaldata=akey+symencdata files = {'file': finaldata} signed=privatekey.Sign(finaldata) signhex=binascii.hexlify(signed) send=req.post(address+"/send/"+usern+"/"+filename+"/"+signhex,files=files,auth=creds,verify=False) if send.status_code==200: QMessageBox.about(self,"Info","File sent successfully") else: QMessageBox.about(self,"Info","File not send") def getfile(self): items=self.listView.selectedIndexes() r=req.get(address+"/receive/get/"+str(items[0].row()+1),auth=creds,verify=False) filename=self.files[items[0].row()] ver=req.get(address+"/receive/verify/"+str(items[0].row()+1),auth=creds,verify=False) signature=binascii.unhexlify(ver.json()["sign"]) keycall=req.get(address+"/send/"+ver.json()["user"],auth=creds,verify=False) key=RsaPublicKey.Read(keycall.json()["key"]) if key.Verify(r.content,signature): QMessageBox.about(self,"Info","File verified to be from "+ver.json()["user"]) else: QMessageBox.about(self,"Info","Verification failed") decrypt_file(hashlib.sha256(str(creds[1])).digest(),creds[0]+"key.enc") open(filename,"w").write(decrypt(r.content,creds[0]+"key")) QMessageBox.about(self,"Info","File written to "+filename) os.remove(creds[0]+"key") os.system("gnome-open "+filename)
class WithCompletion(QPlainTextEdit): """\ Mixin to add base completion funtionallity to QPlainTextEdit It will propose completion with words from current file When the word you are writting is bigger than two, it will request for possible completions but with no default selection. If you press Ctrl-Space, the proposal will choose the first one as default Specific mixings will have to implement the get_text_completion_list method """ def get_text_completion_list(self): return [] def __init__(self, *args): self.model_completer = QStringListModel() self.completer = QCompleter(self) self.completer.popup().setFont(QFont("Monospace", 11)) # self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setWrapAround(False) self.completer.setWidget(self) self.completer.setCompletionMode(QCompleter.PopupCompletion) self.completer.setCaseSensitivity(Qt.CaseInsensitive) self.completer.setModel(self.model_completer) self.completer.activated.connect(self.insert_completion) def keyPressEvent(self, event): event_key = event.key() if self.completer.popup().isVisible(): # The following keys are forwarded by the completer to the widget if event_key in [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab, Qt.Key_Backtab]: if self.completer.popup().currentIndex().row() >= 0: event.ignore() return # let the completer do default behavior else: self.completer.popup().hide() super(WithCompletion, self).keyPressEvent(event) if (event.modifiers() | event.key()) == QKeySequence("Ctrl+Space"): self.show_completer(True) elif event_key in [Qt.Key_Enter, Qt.Key_Return, Qt.Key_Escape, Qt.Key_Tab, Qt.Key_Backtab]: pass else: pressed_key_as_string = QKeySequence(event.key()).toString() word_till_cursor = unicode(self.word_till_cursor()) if (len(word_till_cursor) > 2 or (self.completer.popup().isVisible() and len(word_till_cursor) > 0)) and ( (event.text() != "" and regex.match("^[A-Za-z0-9_-]*$", unicode(pressed_key_as_string[0]))) or self.completer.popup().isVisible() ): self.show_completer(self.completer.popup().currentIndex().row() >= 0) else: self.completer.popup().setCurrentIndex(self.completer.completionModel().index(-1, 0)) self.completer.popup().hide() def show_completer(self, select_first): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) completion_words = self.get_text_completion_list() QApplication.restoreOverrideCursor() if not completion_words or len(completion_words) < 1: self.completer.popup().hide() return self.model_completer.setStringList(completion_words) cr = self.cursorRect() width = ( self.completer.popup().sizeHintForColumn(0) + self.completer.popup().verticalScrollBar().sizeHint().width() ) cr.setWidth(width if width < 300 else 300) self.completer.complete(cr) if select_first: self.completer.popup().setCurrentIndex(self.completer.completionModel().index(0, 0)) def word_under_cursor(self): result = "" for i in range(self.current_pos_init_of_word(), self.current_pos_end_of_word()): result = result + unichr(self.document().characterAt(i).unicode()) return QString(result) def word_till_cursor(self): result = "" for i in range(self.current_pos_init_of_word(), self.textCursor().position()): result = result + unichr(self.document().characterAt(i).unicode()) return QString(result) def current_pos_init_of_word(self): pos = self.textCursor().position() - 1 while True: char = unichr(self.document().characterAt(pos).unicode()) if not char in WORD_SYMBOLS or pos < 0: # if char=='\n' or re.match("^[A-Za-z0-9_-ñÑ]*$", unicode(char)) == None or pos==0: break pos = pos - 1 return pos + 1 def current_pos_end_of_word(self): pos = self.textCursor().position() while True: char = unichr(self.document().characterAt(pos).unicode()) if not char in WORD_SYMBOLS or pos == self.document().characterCount(): # if char.isSpace() or re.match("^[A-Za-z0-9_-ñÑ]*$", unicode(char)) == None: break pos = pos + 1 return pos def insert_completion(self, completion_text): if self.completer.widget() != self: return tc = self.textCursor() till_pos = tc.position() tc.movePosition( QTextCursor.Left, QTextCursor.MoveAnchor, self.textCursor().position() - self.current_pos_init_of_word() ) # tc.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, self.current_pos_end_of_word()-self.current_pos_init_of_word()) tc.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, till_pos - self.current_pos_init_of_word()) tc.removeSelectedText() tc.insertText(completion_text) self.setTextCursor(tc)
class PosiviewProperties(QgsOptionsDialogBase, Ui_PosiviewPropertiesBase): ''' GUI class classdocs for the Configuration dialog ''' applyChanges = pyqtSignal(dict) def __init__(self, project, parent=None): ''' Setup dialog widgets with the project properties ''' super(PosiviewProperties, self).__init__("PosiViewProperties", parent) self.setupUi(self) self.groupBox_6.hide() self.initOptionsBase(False) self.restoreOptionsBaseUi() self.comboBoxParser.addItems(PARSERS) self.comboBoxProviderType.addItems(DEVICE_TYPES) self.project = project self.projectProperties = project.properties() self.mToolButtonLoad.setDefaultAction(self.actionLoadConfiguration) self.mToolButtonSave.setDefaultAction(self.actionSaveConfiguration) self.mobileModel = QStringListModel() self.mobileListModel = QStringListModel() self.mMobileListView.setModel(self.mobileListModel) self.mobileProviderModel = QStandardItemModel() self.mobileProviderModel.setHorizontalHeaderLabels(('Provider', 'Filter')) self.mMobileProviderTableView.setModel(self.mobileProviderModel) self.providerListModel = QStringListModel() self.mDataProviderListView.setModel(self.providerListModel) self.comboBoxProviders.setModel(self.providerListModel) self.setupModelData(self.projectProperties) self.setupGeneralData(self.projectProperties) def setupModelData(self, properties): self.mobileListModel.setStringList(sorted(properties['Mobiles'].keys())) self.providerListModel.setStringList(sorted(properties['Provider'].keys())) def setupGeneralData(self, properties): self.lineEditCruise.setText(properties['Mission']['cruise']) self.lineEditDive.setText(properties['Mission']['dive']) self.lineEditStation.setText(properties['Mission']['station']) self.lineEditRecorderPath.setText(properties['RecorderPath']) self.checkBoxAutoRecording.setChecked(properties['AutoRecord']) self.spinBoxNotifyDuration.setValue(properties['NotifyDuration']) self.checkBoxUtcClock.setChecked((properties['ShowUtcClock'])) def updateGeneralData(self): self.projectProperties['Mission']['cruise'] = self.lineEditCruise.text() self.projectProperties['Mission']['dive'] = self.lineEditDive.text() self.projectProperties['Mission']['station'] = self.lineEditStation.text() self.projectProperties['RecorderPath'] = self.lineEditRecorderPath.text() self.projectProperties['AutoRecord'] = self.checkBoxAutoRecording.isChecked() self.projectProperties['NotifyDuration'] = self.spinBoxNotifyDuration.value() self.projectProperties['ShowUtcClock'] = self.checkBoxUtcClock.isChecked() def getColor(self, value): try: return QColor.fromRgba(int(value)) except ValueError: return QColor(value) @pyqtSlot(QAbstractButton, name='on_buttonBox_clicked') def onButtonBoxClicked(self, button): role = self.buttonBox.buttonRole(button) if role == QDialogButtonBox.ApplyRole or role == QDialogButtonBox.AcceptRole: self.updateGeneralData() self.applyChanges.emit(self.projectProperties) @pyqtSlot(name='on_actionSaveConfiguration_triggered') def onActionSaveConfigurationTriggered(self): ''' Save the current configuration ''' fn = QFileDialog.getSaveFileName(None, 'Save PosiView configuration', '', 'Configuration (*.ini *.conf)') self.project.store(fn) @pyqtSlot(name='on_actionLoadConfiguration_triggered') def onActionLoadConfigurationTriggered(self): ''' Load configuration from file ''' fn = QFileDialog.getOpenFileName(None, 'Save PosiView configuration', '', 'Configuration (*.ini *.conf)') self.projectProperties = self.project.read(fn) self.setupModelData(self.projectProperties) self.setupGeneralData(self.projectProperties) @pyqtSlot(QModelIndex, name='on_mMobileListView_clicked') def editMobile(self, index): ''' Populate the widgets with the selected mobiles properties ''' if index.isValid(): self.populateMobileWidgets(index) @pyqtSlot(str, name='on_comboBoxMobileType_currentIndexChanged') def mobileTypeChanged(self, mType): if mType == 'SHAPE': # self.lineEditMobileShape.setText(str(mobile['shape'])) self.lineEditMobileShape.setEnabled(True) else: self.lineEditMobileShape.setEnabled(False) @pyqtSlot(QModelIndex, name='on_mMobileListView_activated') def activated(self, index): pass @pyqtSlot(name='on_toolButtonAddMobile_clicked') def addMobile(self): self.mobileListModel.insertRow(self.mobileListModel.rowCount()) index = self.mobileListModel.index(self.mobileListModel.rowCount() - 1) self.lineEditMobileName.setText('NewMobile') self.mobileListModel.setData(index, 'NewMobile', Qt.DisplayRole) self.mMobileListView.setCurrentIndex(index) self.applyMobile() @pyqtSlot(name='on_pushButtonApplyMobile_clicked') def applyMobile(self): index = self.mMobileListView.currentIndex() if index.isValid() and not self.lineEditMobileName.text() == '': mobile = dict() mobile['Name'] = self.lineEditMobileName.text() mobile['type'] = self.comboBoxMobileType.currentText() try: t = eval(self.lineEditMobileShape.text()) if t.__class__ is tuple or t.__class__ is dict: mobile['shape'] = t except SyntaxError: mobile['shape'] = ((0.0, -0.5), (0.3, 0.5), (0.0, 0.2), (-0.5, 0.5)) mobile['length'] = self.doubleSpinBoxMobileLength.value() mobile['width'] = self.doubleSpinBoxMobileWidth.value() mobile['zValue'] = self.spinBoxZValue.value() mobile['color'] = self.mColorButtonMobileColor.color().rgba() mobile['fillColor'] = self.mColorButtonMobileFillColor.color().rgba() mobile['timeout'] = self.spinBoxMobileTimeout.value() * 1000 mobile['nofixNotify'] = self.spinBoxMobileNotification.value() mobile['trackLength'] = self.spinBoxTrackLength.value() mobile['trackColor'] = self.mColorButtonMobileTrackColor.color().rgba() provs = dict() for r in range(self.mobileProviderModel.rowCount()): try: fil = int(self.mobileProviderModel.item(r, 1).data(Qt.DisplayRole)) except: fil = self.mobileProviderModel.item(r, 1).data(Qt.DisplayRole) if not fil: fil = None provs[self.mobileProviderModel.item(r, 0).data(Qt.DisplayRole)] = fil mobile['provider'] = provs currName = self.mobileListModel.data(index, Qt.DisplayRole) if not currName == mobile['Name']: del self.projectProperties['Mobiles'][currName] self.mobileListModel.setData(index, mobile['Name'], Qt.DisplayRole) self.projectProperties['Mobiles'][mobile['Name']] = mobile def populateMobileWidgets(self, index): mobile = self.projectProperties['Mobiles'][self.mobileListModel.data(index, Qt.DisplayRole)] self.lineEditMobileName.setText(mobile.get('Name')) self.comboBoxMobileType.setCurrentIndex(self.comboBoxMobileType.findText(mobile.setdefault('type', 'BOX').upper())) if mobile['type'] == 'SHAPE': self.lineEditMobileShape.setText(str(mobile['shape'])) self.lineEditMobileShape.setEnabled(True) else: self.lineEditMobileShape.setEnabled(False) self.lineEditMobileShape.clear() self.doubleSpinBoxMobileLength.setValue(mobile.get('length', 20.0)) self.doubleSpinBoxMobileWidth.setValue(mobile.get('width', 5.0)) self.spinBoxZValue.setValue(mobile.get('zValue', 100)) self.mColorButtonMobileColor.setColor(self.getColor(mobile.get('color', 'black'))) self.mColorButtonMobileFillColor.setColor(self.getColor(mobile.get('fillColor', 'green'))) self.spinBoxMobileTimeout.setValue(mobile.get('timeout', 3000) / 1000) self.spinBoxMobileNotification.setValue(mobile.get('nofixNotify', 0)) self.spinBoxTrackLength.setValue(mobile.get('trackLength', 100)) self.mColorButtonMobileTrackColor.setColor(self.getColor(mobile.get('trackColor', 'green'))) r = 0 self.mobileProviderModel.removeRows(0, self.mobileProviderModel.rowCount()) if 'provider' in mobile: for k, v in mobile['provider'].items(): prov = QStandardItem(k) val = QStandardItem(str(v)) self.mobileProviderModel.setItem(r, 0, prov) self.mobileProviderModel.setItem(r, 1, val) r += 1 @pyqtSlot(name='on_toolButtonRemoveMobile_clicked') def removeMobile(self): idx = self.mMobileListView.currentIndex() if idx.isValid(): self.projectProperties['Mobiles'].pop(self.mobileListModel.data(idx, Qt.DisplayRole)) self.mobileListModel.removeRows(idx.row(), 1) idx = self.mMobileListView.currentIndex() if idx.isValid(): self.populateMobileWidgets(idx) @pyqtSlot(name='on_toolButtonRefreshMobileProvider_clicked') def refreshMobileProvider(self): prov = self.comboBoxProviders.currentText() if prov == '': return fil = None if self.lineEditProviderFilter.text() != '': fil = self.lineEditProviderFilter.text() items = self.mobileProviderModel.findItems(prov, Qt.MatchExactly, 0) if items: for item in items: self.mobileProviderModel.setItem(item.row(), 1, QStandardItem(fil)) else: self.mobileProviderModel.appendRow([QStandardItem(prov), QStandardItem(fil)]) @pyqtSlot(name='on_toolButtonRemoveMobileProvider_clicked') def removeMobileProvider(self): idx = self.mMobileProviderTableView.currentIndex() if idx.isValid(): self.mobileProviderModel.removeRow(idx.row()) @pyqtSlot(name='on_pushButtonApplyDataProvider_clicked') def applyDataProvider(self): index = self.mDataProviderListView.currentIndex() if index.isValid() and not self.lineEditProviderName.text() == '': provider = dict() provider['Name'] = self.lineEditProviderName.text() provider['DataDeviceType'] = self.comboBoxProviderType.currentText() if provider['DataDeviceType'] in NETWORK_TYPES: provider['Host'] = self.lineEditProviderHostName.text() provider['Port'] = self.spinBoxProviderPort.value() provider['Parser'] = self.comboBoxParser.currentText() currName = self.providerListModel.data(index, Qt.DisplayRole) if not currName == provider['Name']: del self.projectProperties['Provider'][currName] self.providerListModel.setData(index, provider['Name'], Qt.DisplayRole) self.projectProperties['Provider'][provider['Name']] = provider @pyqtSlot(QModelIndex, name='on_mDataProviderListView_clicked') def editDataProvider(self, index): ''' ''' if index.isValid(): self.populateDataProviderWidgets(index) def populateDataProviderWidgets(self, index): provider = self.projectProperties['Provider'][self.providerListModel.data(index, Qt.DisplayRole)] self.lineEditProviderName.setText(provider.get('Name')) self.comboBoxProviderType.setCurrentIndex(self.comboBoxProviderType.findText(provider.setdefault('DataDeviceType', 'UDP').upper())) if provider['DataDeviceType'] in NETWORK_TYPES: self.stackedWidgetDataDevice.setCurrentIndex(0) self.lineEditProviderHostName.setText(provider.setdefault('Host', '0.0.0.0')) self.spinBoxProviderPort.setValue(int(provider.setdefault('Port', 2000))) self.comboBoxParser.setCurrentIndex(self.comboBoxParser.findText(provider.setdefault('Parser', 'NONE').upper())) @pyqtSlot(name='on_toolButtonAddDataProvider_clicked') def addDataProvider(self): self.providerListModel.insertRow(self.providerListModel.rowCount()) index = self.providerListModel.index(self.providerListModel.rowCount() - 1) self.lineEditProviderName.setText('NewDataProvider') self.providerListModel.setData(index, 'NewDataProvider', Qt.DisplayRole) self.mDataProviderListView.setCurrentIndex(index) self.applyDataProvider() @pyqtSlot(name='on_toolButtonRemoveDataProvider_clicked') def removeDataProvider(self): idx = self.mDataProviderListView.currentIndex() if idx.isValid(): self.projectProperties['Provider'].pop(self.providerListModel.data(idx, Qt.DisplayRole)) self.providerListModel.removeRows(idx.row(), 1) idx = self.mDataProviderListView.currentIndex() if idx.isValid(): self.populateDataProviderWidgets(idx) @pyqtSlot(name='on_toolButtonSelectLogPath_clicked') def selectRecorderPath(self): path = QFileDialog.getExistingDirectory(self, self.tr('Select Recorder Path'), self.lineEditRecorderPath.text(), QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks) if path != '': self.lineEditRecorderPath.setText(path) @pyqtSlot(QPoint, name='on_lineEditMobileShape_customContextMenuRequested') def mobileShapeContextMenu(self, pos): menu = QMenu(self.lineEditMobileShape) vesselAction = menu.addAction(self.tr('Vessel')) rovAction = menu.addAction(self.tr('ROV')) auvAction = menu.addAction(self.tr('AUV')) arrowAction = menu.addAction(self.tr('Arrow')) selectedAction = menu.exec_(self.lineEditMobileShape.mapToGlobal(pos)) if selectedAction == vesselAction: self.lineEditMobileShape.setText(u'((0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3))') elif selectedAction == rovAction: self.lineEditMobileShape.setText(u'((0.3, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3), (-0.3, -0.5))') elif selectedAction == auvAction: self.lineEditMobileShape.setText(u'((0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3))') elif selectedAction == arrowAction: self.lineEditMobileShape.setText(u'((0, -0.5), (0.5, 0.5), (0, 0), (-0.5, 0.5))') @pyqtSlot(name='on_buttonBox_helpRequested') def showHelp(self): """Display application help to the user.""" help_file = os.path.join(os.path.split(os.path.dirname(__file__))[0], 'help', 'index.html') QDesktopServices.openUrl(QUrl.fromLocalFile(help_file))
class MainWindow(QMainWindow, Ui_mythen_gui): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) self.add_scans.clicked.connect(self.addScanFiles) self.delete_selection.clicked.connect(self.deleteFiles) self.add_scan_numbers.clicked.connect(self.addScanNumbers) self.process.clicked.connect(self.processScans) self.scans = [] self.scans_model = QStringListModel(self.scans, self.scans_view) self.scans_view.setModel(self.scans_model) self.scans_view.setAcceptDrops(True) # add years to combo from time import localtime tm = localtime() for i in range(tm.tm_year, 2006, -1): self.year_combo.addItem(str(i)) # range dialog self.range_dialog = QDialog() self.range_ui = Ui_range_dialog() self.range_ui.setupUi(self.range_dialog) def addScanFiles(self): base = self.getBaseDirectory(False) files, _selectedfilter = getopenfilenames(caption="Select scan files", filters="Data files(*.dat)", basedir=base, options=QFileDialog.ReadOnly) files = [f for f in files if f not in self.scans] self.scans.extend(files) self.scans_model.setStringList(self.scans) def deleteFiles(self): rows = sorted([i.row() for i in self.scans_view.selectedIndexes()]) for r in reversed(rows): del self.scans[r] self.scans_model.setStringList(self.scans) def getYearAndVisit(self): year = None if self.year_combo.currentIndex( ) == 0 else self.year_combo.currentText() vtext = self.visit_edit.toPlainText() visit = vtext if vtext else None return year, visit def getBaseDirectory(self, processing=False, scans=None): base = None if scans: base = path.dirname(scans[0]) if processing: base = path.join(base, 'processing') if not path.exists(base): base = None if base is None: year, visit = self.getYearAndVisit() base = mythen.DEFAULT_BL_DIR if year is not None: base = path.join(base, year) if visit is not None: if processing: base = path.join(base, visit, 'processing') else: base = path.join(base, visit) return base def addScanNumbers(self): result = self.range_dialog.exec_() if result == QDialog.Accepted: text = self.range_ui.range_edit.text() if text: not_found = [] numbers = mythen.parse_range_list(text) year, visit = self.getYearAndVisit() progress = QProgressDialog( "Locating scan files from numbers...", "Stop", 0, len(numbers), self) progress.setWindowModality(Qt.WindowModal) progress.forceShow() progress.setValue(0) for n in numbers: progress.setValue(progress.value() + 1) if progress.wasCanceled(): break files = mythen.find_mythen_files( n, visit=visit, year=year) # FIXME needs to be in separate thread(!) if files: files = [f for f in files if f not in self.scans] self.scans.extend(files) self.scans_model.setStringList(self.scans) else: not_found.append(n) progress.setValue(progress.maximum()) if not_found: error = QErrorMessage(self) msg = "The following numbers were not found: " for n in not_found: msg = msg + str(n) + ", " error.showMessage(msg[:-2]) def processScans(self): base = self.getBaseDirectory(True, self.scans) out_file, _selectedfilter = getsavefilename( caption= "Choose file for summary output - the directory is also used for rebinned and/or summed scans", basedir=path.join(base, 'summary.txt')) if not out_file: return progress = QProgressDialog("Process scans...", "Stop", 0, 2 * len(self.scans), self) progress.setWindowModality(Qt.WindowModal) progress.forceShow() progress.setValue(0) from mythen import load_all, process_and_save, report_processing data, files = load_all(self.scans, None, None, progress=progress) summed = True rebinned = True if self.rebin_rb.isChecked(): summed = False elif self.sum_rb.isChecked(): rebinned = False process_and_save(data, self.angle_spinbox.value(), self.delta_spinbox.value(), rebinned, summed, files, out_file, progress=progress, weights=self.weight_cb.isChecked(), ext='.xye') report_processing(files, out_file, self.angle_spinbox.value(), [self.delta_spinbox.value()]) progress.setValue(progress.maximum()) def keyPressEvent(self, event): k = event.key() if k == Qt.Key_Delete or k == Qt.Key_Backspace: self.deleteFiles()
class Person(QObject): """Base class of all people in Manitae. All subclasses are required to provide the following class variables: * :const:`TYPE`: The type of person, in plain text (not CamelCase). * :const:`level`: The level of the person. * :const:`level_up_types`: Types that the type being defined can upgrade to. (if applicable) * :const:`upgrade_exp_reqs`: A dictionary representing the experience requirements to upgrade to this type. Define your class to inherit from the classed it can be upgraded from.""" TYPE = "Person" level = -1 id_inc = 1 level_up_types = [] name_changed_sig = pyqtSignal() send_notice = pyqtSignal(str) send_warning = pyqtSignal(str) upgraded = pyqtSignal() def __init__(self): super(Person, self).__init__() self._employer = None self.id = Person.id_inc Person.id_inc += 1 self._total_expenses = 0.0 self._net_worth = 0.0 self._name = '' self.experience = {} self.shelter = None self.level_up_type_model = QStringListModel(self.level_up_types) self.exp_type_model = QStringListModel(self.exp_types) self.ui = Ui_Person() self.widget = QWidget() self.ui.setupUi(self.widget) self.ui.upgradeComboBox.setModel(self.level_up_type_model) self.ui.upgradePushButton.clicked.connect(self.upgrade) self.ui.expComboBox.setModel(self.exp_type_model) self.ui.expComboBox.activated[str].connect(self.update_experience_widget) self.ui.nameLineEdit.textEdited.connect(self.name_changed) self.ui.typeLineEdit.setText(self.TYPE) self.ui.levelLineEdit.setText(str(self.level)) self.ui.employerLineEdit.setText("Unemployed") self.ui.netWorthLineEdit.setText(self.display_money(self._net_worth)) self.ui.salaryLineEdit.setText(self.display_money(self.salary)) self.ui.totalIncomeLineEdit.setText(self.display_money(self.total_income)) self.ui.taxesLineEdit.setText(self.display_money(self.income_tax)) self.ui.netLineEdit.setText(self.display_money(self.net)) def __str__(self): if not(self.name): return "{0} (Level {1}): id {2}".format(self.TYPE, self.level, str(self.id)) else: return self.name def key(self): return self.level @pyqtProperty(Unit) def employer(self): return self._employer @employer.setter def employer(self, unit): self._employer = unit self.ui.employerLineEdit.setText(str(self._employer) if self._employer else "Unemployed") self.ui.salaryLineEdit.setText(self.display_money(self.salary)) self.ui.totalIncomeLineEdit.setText(self.display_money(self.total_income)) self.ui.taxesLineEdit.setText(self.display_money(self.income_tax)) self.ui.netLineEdit.setText(self.display_money(self.net)) @pyqtProperty(list) def exp_types(self): return self.experience.keys() @pyqtProperty(str) def name(self): return self._name @name.setter def name(self, value): self._name = value self.name_changed_sig.emit() @pyqtProperty(float) def net_worth(self): return self._net_worth @net_worth.setter def net_worth(self, value): self._net_worth = value self.ui.netWorthLineEdit.setText(self.display_money(self._net_worth)) @pyqtProperty(float) def income_tax(self): if self.shelter: pass else: return self.salary * 0.05 @pyqtProperty(float) def salary(self): try: return self._employer.emp_to_salary[self] except (AttributeError, KeyError): return 0.0 @pyqtProperty(float) def net(self): return self.total_income - self.total_expenses @pyqtProperty(float) def total_expenses(self): return self.income_tax @pyqtProperty(float) def total_income(self): return self.salary def employer_production_switched(self): self.ui.salaryLineEdit.setText(self.display_money(self.salary)) self.ui.totalIncomeLineEdit.setText(self.display_money(self.total_income)) self.ui.taxesLineEdit.setText(self.display_money(self.income_tax)) self.ui.netLineEdit.setText(self.display_money(self.net)) def name_changed(self, new_name): self.name = str(new_name) def on_turn_end(self): self.net_worth += self.net self.ui.salaryLineEdit.setText(self.display_money(self.salary)) self.ui.totalIncomeLineEdit.setText(self.display_money(self.total_income)) self.ui.taxesLineEdit.setText(self.display_money(self.income_tax)) self.ui.netLineEdit.setText(self.display_money(self.net)) def gain_experience(self, exp_type, amount): try: self.experience[exp_type] += amount except KeyError: self.experience[exp_type] = amount self.exp_type_model.setStringList(self.exp_types) finally: self.update_experience_widget_after_turn(exp_type) def upgrade(self): person_type = self.ui.upgradeComboBox.currentText() if not(person_type): return person_type_clean = person_type.replace(' ', '') upgrade_check, error = eval("manitae.people.{0}.{0}.upgrade_to(self)".format(person_type_clean)) if not(upgrade_check): self.send_warning.emit("Could not upgrade person {0}: {1}".format(str(self), error)) else: self.name_changed_sig.emit() self.upgraded.emit() self.employer.employee_upgraded(self) def update_experience_widget(self, exp_type): exp_amount = self.experience[str(exp_type)] self.ui.expLineEdit.setText(str(exp_amount)) def update_experience_widget_after_turn(self, exp_changed): exp_type = self.ui.expComboBox.currentText() if str(exp_type) == str(exp_changed): exp_amount = self.experience[str(exp_type)] self.ui.expLineEdit.setText(str(exp_amount)) def display_money(self, amount): return "{:.2f}".format(amount)
class OWDatabasesUpdate(OWWidget): name = "Databases update" description = "Update local system biology databases." icon = "../widgets/icons/Databases.svg" priority = 10 inputs = [] outputs = [] want_main_area = False def __init__(self, parent=None, signalManager=None, name="Databases update", domains=None): OWWidget.__init__(self, parent, signalManager, name, wantMainArea=False) self.searchString = "" self.accessCode = "" self.domains = domains or DOMAINS self.serverFiles = serverfiles.ServerFiles() self.__in_progress_update = False fbox = gui.widgetBox(self.controlArea, "Filter") # The completer model token strings self.completertokens = [] # A 'dynamic' completer item model will be updated with # 'prefix {token}' where prefix is current 'active' filter list # (the QCompleter only completes on one item in the model) self.completermodel = QStringListModel(self) self.completer = QCompleter( self.completermodel, self, caseSensitivity=Qt.CaseInsensitive ) self.lineEditFilter = QLineEdit(textChanged=self.SearchUpdate) self.lineEditFilter.setCompleter(self.completer) fbox.layout().addWidget(self.lineEditFilter) box = gui.widgetBox(self.controlArea, "Files") self.filesView = QTreeWidget(self) self.filesView.setHeaderLabels( ["", "Data Source", "Update", "Last Updated", "Size"]) self.filesView.setRootIsDecorated(False) self.filesView.setUniformRowHeights(True) self.filesView.setSelectionMode(QAbstractItemView.NoSelection) self.filesView.setSortingEnabled(True) self.filesView.sortItems(1, Qt.AscendingOrder) self.filesView.setItemDelegateForColumn( 0, UpdateOptionsItemDelegate(self.filesView)) self.filesView.model().layoutChanged.connect(self.SearchUpdate) box.layout().addWidget(self.filesView) box = gui.widgetBox(self.controlArea, orientation="horizontal") self.updateButton = gui.button( box, self, "Update all", callback=self.UpdateAll, tooltip="Update all updatable files", ) self.downloadButton = gui.button( box, self, "Download all", callback=self.DownloadFiltered, tooltip="Download all filtered files shown" ) self.cancelButton = gui.button( box, self, "Cancel", callback=self.Cancel, tooltip="Cancel scheduled downloads/updates." ) gui.rubber(box) gui.lineEdit(box, self, "accessCode", "Access Code", orientation="horizontal", callback=self.RetrieveFilesList) self.retryButton = gui.button( box, self, "Retry", callback=self.RetrieveFilesList ) self.retryButton.hide() box = gui.widgetBox(self.controlArea, orientation="horizontal") gui.rubber(box) self.infoLabel = QLabel() self.infoLabel.setAlignment(Qt.AlignCenter) self.controlArea.layout().addWidget(self.infoLabel) self.infoLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.updateItems = [] self.resize(800, 600) self.progress = ProgressState(self, maximum=3) self.progress.valueChanged.connect(self._updateProgress) self.progress.rangeChanged.connect(self._updateProgress) self.executor = ThreadExecutor( threadPool=QThreadPool(maxThreadCount=2) ) task = Task(self, function=self.RetrieveFilesList) task.exceptionReady.connect(self.HandleError) task.start() self._tasks = [] self._haveProgress = False def RetrieveFilesList(self): self.progress.setRange(0, 3) self.serverFiles = serverfiles.ServerFiles(access_code=self.accessCode) task = Task(function=partial(retrieveFilesList, self.serverFiles, self.domains, methodinvoke(self.progress, "advance"))) task.resultReady.connect(self.SetFilesList) task.exceptionReady.connect(self.HandleError) self.executor.submit(task) self.setEnabled(False) def SetFilesList(self, serverInfo): """ Set the files to show. """ self.setEnabled(True) domains = serverInfo.keys() if not domains: if self.domains: domains = self.domains else: domains = serverfiles.listdomains() localInfo = dict([(dom, serverfiles.allinfo(dom)) for dom in domains]) all_tags = set() self.filesView.clear() self.updateItems = [] for item in join_info_dict(localInfo, serverInfo): tree_item = UpdateTreeWidgetItem(item) options_widget = UpdateOptionsWidget(item.state) options_widget.item = item options_widget.installClicked.connect( partial(self.SubmitDownloadTask, item.domain, item.filename) ) options_widget.removeClicked.connect( partial(self.SubmitRemoveTask, item.domain, item.filename) ) self.updateItems.append((item, tree_item, options_widget)) all_tags.update(item.tags) self.filesView.addTopLevelItems( [tree_item for _, tree_item, _ in self.updateItems] ) for item, tree_item, options_widget in self.updateItems: self.filesView.setItemWidget(tree_item, 0, options_widget) # Add an update button if the file is updateable if item.state == OUTDATED: button = QToolButton( None, text="Update", maximumWidth=120, maximumHeight=30 ) if sys.platform == "darwin": button.setAttribute(Qt.WA_MacSmallSize) button.clicked.connect( partial(self.SubmitDownloadTask, item.domain, item.filename) ) self.filesView.setItemWidget(tree_item, 2, button) self.progress.advance() self.filesView.setColumnWidth(0, self.filesView.sizeHintForColumn(0)) for column in range(1, 4): contents_hint = self.filesView.sizeHintForColumn(column) header_hint = self.filesView.header().sectionSizeHint(column) width = max(min(contents_hint, 400), header_hint) self.filesView.setColumnWidth(column, width) hints = [hint for hint in sorted(all_tags) if not hint.startswith("#")] self.completertokens = hints self.completermodel.setStringList(hints) self.SearchUpdate() self.UpdateInfoLabel() self.toggleButtons() self.cancelButton.setEnabled(False) self.progress.setRange(0, 0) def buttonCheck(self, selected_items, state, button): for item in selected_items: if item.state != state: button.setEnabled(False) else: button.setEnabled(True) break def toggleButtons(self): selected_items = [item for item, tree_item, _ in self.updateItems if not tree_item.isHidden()] self.buttonCheck(selected_items, OUTDATED, self.updateButton) self.buttonCheck(selected_items, AVAILABLE, self.downloadButton) def HandleError(self, exception): if isinstance(exception, IOError): self.error(0, "Could not connect to server! Press the Retry " "button to try again.") self.SetFilesList({}) else: sys.excepthook(type(exception), exception.args, None) self.progress.setRange(0, 0) self.setEnabled(True) def UpdateInfoLabel(self): local = [item for item, tree_item, _ in self.updateItems if item.state != AVAILABLE and not tree_item.isHidden()] size = sum(float(item.size) for item in local) onServer = [item for item, tree_item, _ in self.updateItems if not tree_item.isHidden()] sizeOnServer = sum(float(item.size) for item in onServer) text = ("%i items, %s (on server: %i items, %s)" % (len(local), sizeof_fmt(size), len(onServer), sizeof_fmt(sizeOnServer))) self.infoLabel.setText(text) def UpdateAll(self): for item, tree_item, _ in self.updateItems: if item.state == OUTDATED and not tree_item.isHidden(): self.SubmitDownloadTask(item.domain, item.filename) def DownloadFiltered(self): # TODO: submit items in the order shown. for item, tree_item, _ in self.updateItems: if not tree_item.isHidden() and item.state in \ [AVAILABLE, OUTDATED]: self.SubmitDownloadTask(item.domain, item.filename) def _updateCompleterPrefix(self, prefix, seperator=" "): prefix = str(self.completer.completionPrefix()) tokens = self.completertokens model = self.completer.model() if not prefix.endswith(seperator) and seperator in prefix: prefix, _ = prefix.rsplit(seperator, 1) items = [prefix + seperator + item for item in tokens] else: items = tokens old = set(str(item) for item in model.stringList()) if old != set(items): model.setStringList(items) def SearchUpdate(self, searchString=None): self._updateCompleterPrefix(searchString) strings = str(self.lineEditFilter.text()).split() for item, tree_item, _ in self.updateItems: hide = not all(UpdateItem_match(item, string) for string in strings) tree_item.setHidden(hide) self.UpdateInfoLabel() self.toggleButtons() def SubmitDownloadTask(self, domain, filename): """ Submit the (domain, filename) to be downloaded/updated. """ self.cancelButton.setEnabled(True) index = self.updateItemIndex(domain, filename) _, tree_item, opt_widget = self.updateItems[index] if self.accessCode: sf = serverfiles.ServerFiles(access_code=self.accessCode) else: sf = serverfiles.ServerFiles() task = DownloadTask(domain, filename, sf) self.executor.submit(task) self.progress.adjustRange(0, 100) pb = ItemProgressBar(self.filesView) pb.setRange(0, 100) pb.setTextVisible(False) task.advanced.connect(pb.advance) task.advanced.connect(self.progress.advance) task.finished.connect(pb.hide) task.finished.connect(self.onDownloadFinished, Qt.QueuedConnection) task.exception.connect(self.onDownloadError, Qt.QueuedConnection) self.filesView.setItemWidget(tree_item, 2, pb) # Clear the text so it does not show behind the progress bar. tree_item.setData(2, Qt.DisplayRole, "") pb.show() # Disable the options widget opt_widget.setEnabled(False) self._tasks.append(task) def EndDownloadTask(self, task): future = task.future() index = self.updateItemIndex(task.domain, task.filename) item, tree_item, opt_widget = self.updateItems[index] self.filesView.removeItemWidget(tree_item, 2) opt_widget.setEnabled(True) if future.cancelled(): # Restore the previous state tree_item.setUpdateItem(item) opt_widget.setState(item.state) elif future.exception(): tree_item.setUpdateItem(item) opt_widget.setState(item.state) # Show the exception string in the size column. tree_item.setData( 2, Qt.DisplayRole, "Error occurred while downloading:" + str(future.exception()) ) else: # get the new updated info dict and replace the the old item info = serverfiles.info(item.domain, item.filename) new_item = update_item_from_info(item.domain, item.filename, info, info) self.updateItems[index] = (new_item, tree_item, opt_widget) tree_item.setUpdateItem(new_item) opt_widget.setState(new_item.state) self.UpdateInfoLabel() def SubmitRemoveTask(self, domain, filename): serverfiles.remove(domain, filename) index = self.updateItemIndex(domain, filename) item, tree_item, opt_widget = self.updateItems[index] if item.info_server: new_item = item._replace(state=AVAILABLE, local=None, info_local=None) else: new_item = item._replace(local=None, info_local=None) # Disable the options widget. No more actions can be performed # for the item. opt_widget.setEnabled(False) tree_item.setUpdateItem(new_item) opt_widget.setState(new_item.state) self.updateItems[index] = (new_item, tree_item, opt_widget) self.UpdateInfoLabel() def Cancel(self): """ Cancel all pending update/download tasks (that have not yet started). """ for task in self._tasks: task.future().cancel() def onDeleteWidget(self): self.Cancel() self.executor.shutdown(wait=False) OWWidget.onDeleteWidget(self) def onDownloadFinished(self): # on download completed/canceled/error assert QThread.currentThread() is self.thread() for task in list(self._tasks): future = task.future() if future.done(): self.EndDownloadTask(task) self._tasks.remove(task) if not self._tasks: # Clear/reset the overall progress self.progress.setRange(0, 0) self.cancelButton.setEnabled(False) def onDownloadError(self, exc_info): sys.excepthook(*exc_info) def updateItemIndex(self, domain, filename): for i, (item, _, _) in enumerate(self.updateItems): if item.domain == domain and item.filename == filename: return i raise ValueError("%r, %r not in update list" % (domain, filename)) def _updateProgress(self, *args): rmin, rmax = self.progress.range() if rmin != rmax: if not self._haveProgress: self._haveProgress = True self.progressBarInit() self.progressBarSet(self.progress.ratioCompleted() * 100) # self.progressBarSet(self.progress.ratioCompleted() * 100, # processEventsFlags=None) if rmin == rmax: self._haveProgress = False self.progressBarFinished() def progressBarSet(self, value): if not self.__in_progress_update: self.__in_progress_update = True try: OWWidget.progressBarSet(self, value) finally: self.__in_progress_update = False
class NeutraXkbConfig(QMainWindow): reloadLayouts = pyqtSignal() def __init__(self, parent=None): QMainWindow.__init__(self, parent) self.ui = Ui_MainWindow() self.ui.setupUi(self) QApplication.setQuitOnLastWindowClosed(False) self.mod = False self.langList = [] self.flagInfo = str() self.flagIcon = str() self.currentLayout = str() self.cfgInfo = NXkbCfgParser() # Lang Model self.model = QStringListModel(self.ui.langView) self.langFilter = QSortFilterProxyModel() # Flag Model self.fmodel = QStandardItemModel(self.ui.flagView) self.flagFilter = QSortFilterProxyModel() # Fill Views self.fillViews() # Init Lang Model self.model.setStringList(self.langList) self.langFilter.setSourceModel(self.model) self.ui.langView.setModel(self.langFilter) # Init Flag Model self.flagFilter.setSourceModel(self.fmodel) self.ui.flagView.setModel(self.flagFilter) # Set both filters to case insensitive self.langFilter.setFilterCaseSensitivity(Qt.CaseInsensitive) self.flagFilter.setFilterCaseSensitivity(Qt.CaseInsensitive) # Connections self.ui.lineEdit.textChanged[str].connect(self.langFilter.setFilterFixedString) self.ui.lineEdit_2.textChanged[str].connect(self.flagFilter.setFilterFixedString) self.ui.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(self.closeRequest) self.ui.flagView.clicked.connect(self.changeFlag) self.ui.langView.clicked.connect(self.updateIconDisplay) self.ui.addButton.clicked.connect(self.addLayout) self.ui.moveUpButton.clicked.connect(self.moveLangUp) self.ui.moveDownButton.clicked.connect(self.moveLangDown) self.ui.removeButton.clicked.connect(self.removeLang) self.ui.buttonBox.button(QDialogButtonBox.Apply).clicked.connect(lambda: self.reloadRequested(self.mod)) self.ui.buttonBox.button(QDialogButtonBox.Ok).clicked.connect(self.okRequest) self.ui.browseButton.clicked.connect(self.addCustomIcon) # Actions self.ui.actionSave.triggered.connect(lambda: self.reloadRequested(self.mod)) self.ui.actionQuit.triggered.connect(self.closeRequest) ############################################################################### @pyqtSlot() def addLayout(self): if self.currentLayout == "": self.statusBar().showMessage("No layout selected.", 6000) return if self.flagInfo is "": self.flagIcon = self.cfgInfo.defaultIconDir() + "zz.png" self.flagInfo = "zz" listInfo = next(key for key, val in self.dataDict.items() if val == self.currentLayout) + " [{}]".format(self.currentLayout) if self.ui.resView.findItems(listInfo, Qt.MatchExactly): # Do not add if item is already in resView. return self.ui.resView.insertItem(self.ui.resView.count(), QListWidgetItem(QIcon(self.flagIcon), listInfo + " |{}|".format(self.flagInfo))) self.mod = True ###################################################################### @pyqtSlot() def okRequest(self): if self.mod: self.reloadRequested(True) self.closeRequest() else: self.closeRequest() ############################################################################### @pyqtSlot(QModelIndex) def updateIconDisplay(self, item1): self.currentLayout = self.dataDict[item1.data()].lower() if "/" in self.currentLayout: self.currentLayout = self.currentLayout.split("/")[1] self.ui.customFlagLabel.setText("Set Custom Icon for {}".format(item1.data())) self.flagIcon = os.path.abspath(self.cfgInfo.defaultIconDir() + self.currentLayout + ".png") if not os.path.exists(self.flagIcon): self.flagIcon = self.cfgInfo.defaultIconDir() + "zz.png" if os.path.isfile(self.flagIcon): self.ui.flagLabel.setPixmap(QPixmap(self.flagIcon)) self.flagInfo = self.flagIcon.split("/")[-1].split(".")[0] self.statusBar().showMessage("{}".format(self.dataDict[item1.data()]), 6000) return ############################################################################### @pyqtSlot(QModelIndex) def changeFlag(self, flag): self.flagInfo = flag.data() self.flagIcon = os.path.abspath(self.cfgInfo.defaultIconDir() + flag.data().lower() + ".png") self.ui.flagLabel.setPixmap(QPixmap(self.flagIcon)) self.flagInfo = flag.data().lower() ############################################################################### def fillViews(self): flagList = glob(os.path.abspath(self.cfgInfo.defaultIconDir() + "*.png")) flagList.sort() XkbLayouts = self.getXkbLayouts() for x in XkbLayouts: # fill layout listView for k in x.keys(): self.langList.append(k) self.dataDict = {} for dict in XkbLayouts: # fill internal data dict for dName, isocode in dict.items(): dispName = dName self.dataDict.update({dispName: isocode}) self.langList.sort() for f in flagList: # fill the flag listView i = QStandardItem(f.split("/")[-1].split(".")[0].upper()) i.setIcon(QIcon(f)) self.fmodel.appendRow(i) self.ui.flagLabel.setPixmap(QPixmap(flagList[0])) self.fillResView() del flagList del XkbLayouts ############################################################################### def fillResView(self): self.ui.resView.clear() for langDict in self.cfgInfo.languages(): # fill added/available languages/layouts listwidget entryIcon1 = langDict["icon"] entryName = langDict["name"] entryLayout = langDict["layout"] i = QListWidgetItem(QIcon(entryIcon1), "{} [{}] |{}|".format(entryName, entryLayout, entryIcon1.split("/")[-1].split(".")[0])) self.ui.resView.addItem(i) ############################################################################### def getXkbLayouts(self): x = [] try: with open("/usr/share/X11/xkb/rules/base.lst") as layouts: r = False for line in layouts: if line == "\n": continue if line.startswith("! layout"): r = True if re.search(r"^! [^ layout]", line) is not None: r = False if r == True: l = re.split(r"^\s|\s{2,15}", line.strip()) if l[0] == "! layout": continue l.sort() x.append({l[0]: l[1]}) except IOError as e: print("File not found.") return x ############################################################################### @pyqtSlot() def addCustomIcon(self): m_dir = os.path.expanduser("~/") customIcon = QFileDialog.getOpenFileName(self, "Select Custom Icon", m_dir, "Image Files (*.png *.jpg *.gif)") if customIcon is "": return else: icon1 = QPixmap(customIcon) if icon1.width() > 128 or icon1.height() > 128: QMessageBox.warning(self, "Large Icon File", "The custom icon is too large.\nPlease select an Icon around the size of 24x24 pixels.") return else: self.flagInfo = customIcon self.ui.flagLabel.setPixmap(icon1) self.flagIcon = icon1 ############################################################################### @pyqtSlot() def moveLangUp(self): currentSelection = self.ui.resView.currentRow() currentLang = self.ui.resView.takeItem(currentSelection) self.ui.resView.insertItem(currentSelection - 1, currentLang) self.ui.resView.setCurrentItem(currentLang) layoutName = re.split(r" \[(.{2,8})\] ", currentLang.text())[1] self.cfgInfo.upgradeLang(layoutName) sectName = currentLang.text().split(" ")[0] sectName = sectName + "_" + layoutName self.cfgInfo.upgradeSection(sectName.lower()) self.mod = True ############################################################################### @pyqtSlot() def removeLang(self): lang = self.ui.resView.item(self.ui.resView.currentRow()).text() entry = re.split(r"([A-Za-z]{2,50})\s\(?.*\[(.{2,8})\]\s.*", lang) entry = list(filter(("").__ne__, entry)) entry = "_".join(entry).lower() self.cfgInfo.removeLanguage(entry) self.ui.resView.takeItem(self.ui.resView.currentRow()) self.mod = True ############################################################################### @pyqtSlot() def moveLangDown(self): currentSelection = self.ui.resView.currentRow() currentLang = self.ui.resView.takeItem(currentSelection) self.ui.resView.insertItem(currentSelection + 1, currentLang) self.ui.resView.setCurrentItem(currentLang) layoutName = re.split(r" \[(.{2,8})\] ", currentLang.text())[1] self.cfgInfo.downgradeLang(layoutName) sectName = currentLang.text().split(" ")[0] sectName = sectName + "_" + layoutName self.cfgInfo.downgradeSection(sectName.lower()) self.mod = True ############################################################################### @pyqtSlot() def reloadRequested(self, sendSig=bool()): if sendSig == False: return for x in self.ui.resView.findItems("*", Qt.MatchWildcard): langInfo = x.text() langInfo = re.split(r"\s\[(.{2,8})\]", langInfo) cfgLabel = re.sub("([A-Za-z]{3,60})\s.*", r"\1", langInfo[0]) cfgLabel = cfgLabel + "_{}".format(langInfo[1]) self.flagInfo = langInfo[2].replace(" ", "").replace("|", "") if not self.flagInfo.startswith("/"): self.flagInfo = self.cfgInfo.defaultIconDir() + self.flagInfo + ".png" dTup = (cfgLabel, '{{"name": "{}", \n"label": "{}", \n"layout": "{}", \n"icon": "{}"}}\n'.format(langInfo[0], cfgLabel.split("_")[0], langInfo[1], self.flagInfo)) self.cfgInfo.addLanguage(dTup) appendLayout = self.cfgInfo.get("deflayout", "currentLayout") if not langInfo[1] in appendLayout: appendLayout = appendLayout + ",{}".format(langInfo[1]) self.cfgInfo.set("deflayout", "currentLayout", appendLayout) subprocess.call(["setxkbmap -layout {}".format(appendLayout)], shell=True) self.cfgInfo.writeCFG() self.cfgInfo.__init__() self.statusBar().showMessage("Added {}. Current layout: {}".format(langInfo[0], appendLayout), 6000) self.reloadLayouts.emit() self.mod = False ############################################################################### @pyqtSlot() def closeRequest(self): self.ui.resView.clear() self.close() self.fillResView()
class LevelOnePrimitiveProducer(PrimitiveProducer): """A :class:`~units.base.PrimitiveProducer.PrimitiveProducer` at :attr:`~core.basetypes.Unit.Unit.level` 1 Level 1 Primitive Producers include (in the base package): * :class:`~units.Gatherer.Gatherer` * :class:`~units.Hunter.Hunter` * :class:`~units.StoneGatherer.StoneGatherer` * :class:`~units.WoodGatherer.WoodGatherer` """ level = 1 employee_types = ['Citizen'] """Types of :class:`people <core.basetypes.Person.Person>` that may be employed by this unit.""" employee_efficiency = {'Citizen': 2} """Production rate per type of employee.""" employee_salary = {'Citizen': 7.50} """Salary per type of employee.""" employee_max = 1 """Maximum number of people that can be employed at one time.""" def __init__(self): super(LevelOnePrimitiveProducer, self).__init__() self.employees = [] self._production_on = False self.employee_model = QStringListModel() self.hirable_model = QStringListModel() self.widget = QWidget() uic.loadUi('./manitae/units/ui/PrimitiveProducer.ui', self.widget) self.widget.typeLineEdit.setText(self.UNIT) self.widget.levelLineEdit.setText(str(self.level)) self.widget.nameLineEdit.textEdited.connect(self.name_changed) self.widget.fireComboBox.setModel(self.employee_model) self.widget.fireButton.clicked.connect(self.fire_employee) self.widget.hireComboBox.setModel(self.hirable_model) self.widget.hireButton.clicked.connect(self.hire_employee) self.widget.prodOnCheckBox.toggled.connect(self.production_on_checked) self.widget.employeeLineEdit.setText(str(self.employee_count)) self.widget.prodOnCheckBox.setChecked(self.production_on) self.widget.destroyButton.clicked.connect(self.destroy) self.widget.employeeListView.setModel(self.employee_model) def ready_for_allocation(self): self.needs_employee.emit(self, 1) if self.employee_count == 0: raise NoMoreWorkersError(self.UNIT) self.employee_model.setStringList(self.employee_string_list) self.widget.employeeLineEdit.setText(str(self.employee_count)) self.widget.prodLevelLineEdit.setText(str(self.production_rate)) self.widget.salaryLineEdit.setText(self.display_money(self.salary)) self.production_on = True #Properties and UI updaters @pyqtProperty(list) def employee_string_list(self): string_list = [] for x in self.employees: string_list.append(str(x)) return string_list @pyqtProperty(int) def production_rate(self): try: if self.production_on: return self.employee_efficiency[self.employees[0].TYPE] else: return 0 except (IndexError, KeyError): return 0 @pyqtProperty(float) def salary(self): try: if self.production_on: return self.employee_salary[self.employees[0].TYPE] else: return 0.0 except (IndexError, KeyError): return 0.0 @pyqtProperty(dict) def emp_to_salary(self): try: if self.production_on: return {self.employees[0]: self.employee_salary[self.employees[0].TYPE]} else: return {self.employees[0]: 0.0} except IndexError: return {} @pyqtProperty(int) def employee_count(self): return len(self.employees) @pyqtProperty(bool) def production_on(self): return self._production_on @production_on.setter def production_on(self, value): self._production_on = value self.widget.prodOnCheckBox.setChecked(self._production_on) try: self.salary_changed.emit(self.salary) self.widget.salaryLineEdit.setText(self.display_money(self.salary)) self.widget.prodLevelLineEdit.setText(str(self.production_rate)) for emp in self.employees: emp.employer_production_switched() self.production_switched.emit() except IndexError: pass @pyqtSlot(bool) def production_on_checked(self, checked): self.production_on = checked def destroy(self): self.production_on = False self.to_be_destroyed.emit() def fire_employee(self): if self.employee_count == 0: self.send_warning.emit("Unable to fire employee from unit {0}: this unit has no employees.".format(str(self))) return emp_str = self.widget.fireComboBox.currentText() self.employee_fired.emit(emp_str) self.widget.employeeLineEdit.setText(str(self.employee_count)) self.employee_model.setStringList(self.employee_string_list) self.widget.salaryLineEdit.setText(self.display_money(self.salary)) self.widget.prodLevelLineEdit.setText(str(self.production_rate)) def hire_employee(self): if self.employee_count == self.employee_max: self.send_warning.emit("Unable to hire employee for unit {0}: this unit has the maximum number of employees.".format(str(self))) return emp_str = self.widget.hireComboBox.currentText() self.employee_hired.emit(emp_str) self.widget.employeeLineEdit.setText(str(self.employee_count)) self.employee_model.setStringList(self.employee_string_list) self.widget.salaryLineEdit.setText(self.display_money(self.salary)) self.widget.prodLevelLineEdit.setText(str(self.production_rate)) def employee_upgraded(self, emp): if (emp.TYPE not in self.employee_types): emp_str = str(emp) self.employee_fired.emit(emp_str) self.widget.employeeLineEdit.setText(str(self.employee_count)) self.employee_model.setStringList(self.employee_string_list) self.widget.salaryLineEdit.setText(self.display_money(self.salary)) self.widget.prodLevelLineEdit.setText(str(self.production_rate)) else: self.widget.salaryLineEdit.setText(self.display_money(self.salary)) self.widget.prodLevelLineEdit.setText(str(self.production_rate)) self.salary_changed.emit(self.salary) def name_changed(self, new_name): self.name = str(new_name) self.employees[0].ui.employerLineEdit.setText(str(self))
class PosiviewProperties(QgsOptionsDialogBase, Ui_PosiviewPropertiesBase): ''' GUI class classdocs for the Configuration dialog ''' applyChanges = pyqtSignal(dict) def __init__(self, project, parent=None): ''' Setup dialog widgets with the project properties ''' super(PosiviewProperties, self).__init__("PosiViewProperties", parent) self.setupUi(self) self.groupBox_6.hide() self.initOptionsBase(False) self.restoreOptionsBaseUi() self.comboBoxParser.addItems(PARSERS) self.comboBoxProviderType.addItems(DEVICE_TYPES) self.project = project self.projectProperties = project.properties() self.mToolButtonLoad.setDefaultAction(self.actionLoadConfiguration) self.mToolButtonSave.setDefaultAction(self.actionSaveConfiguration) self.mobileModel = QStringListModel() self.mobileListModel = QStringListModel() self.mMobileListView.setModel(self.mobileListModel) self.mobileProviderModel = QStandardItemModel() self.mobileProviderModel.setHorizontalHeaderLabels( ('Provider', 'Filter')) self.mMobileProviderTableView.setModel(self.mobileProviderModel) self.providerListModel = QStringListModel() self.mDataProviderListView.setModel(self.providerListModel) self.comboBoxProviders.setModel(self.providerListModel) self.setupModelData(self.projectProperties) self.setupGeneralData(self.projectProperties) def setupModelData(self, properties): self.mobileListModel.setStringList(sorted( properties['Mobiles'].keys())) self.providerListModel.setStringList( sorted(properties['Provider'].keys())) def setupGeneralData(self, properties): self.lineEditCruise.setText(properties['Mission']['cruise']) self.lineEditDive.setText(properties['Mission']['dive']) self.lineEditStation.setText(properties['Mission']['station']) self.lineEditRecorderPath.setText(properties['RecorderPath']) self.checkBoxAutoRecording.setChecked(properties['AutoRecord']) self.spinBoxNotifyDuration.setValue(properties['NotifyDuration']) self.checkBoxUtcClock.setChecked((properties['ShowUtcClock'])) def updateGeneralData(self): self.projectProperties['Mission']['cruise'] = self.lineEditCruise.text( ) self.projectProperties['Mission']['dive'] = self.lineEditDive.text() self.projectProperties['Mission'][ 'station'] = self.lineEditStation.text() self.projectProperties[ 'RecorderPath'] = self.lineEditRecorderPath.text() self.projectProperties[ 'AutoRecord'] = self.checkBoxAutoRecording.isChecked() self.projectProperties[ 'NotifyDuration'] = self.spinBoxNotifyDuration.value() self.projectProperties[ 'ShowUtcClock'] = self.checkBoxUtcClock.isChecked() def getColor(self, value): try: return QColor.fromRgba(int(value)) except ValueError: return QColor(value) @pyqtSlot(QAbstractButton, name='on_buttonBox_clicked') def onButtonBoxClicked(self, button): role = self.buttonBox.buttonRole(button) if role == QDialogButtonBox.ApplyRole or role == QDialogButtonBox.AcceptRole: self.updateGeneralData() self.applyChanges.emit(self.projectProperties) @pyqtSlot(name='on_actionSaveConfiguration_triggered') def onActionSaveConfigurationTriggered(self): ''' Save the current configuration ''' fn = QFileDialog.getSaveFileName(None, 'Save PosiView configuration', '', 'Configuration (*.ini *.conf)') self.project.store(fn) @pyqtSlot(name='on_actionLoadConfiguration_triggered') def onActionLoadConfigurationTriggered(self): ''' Load configuration from file ''' fn = QFileDialog.getOpenFileName(None, 'Save PosiView configuration', '', 'Configuration (*.ini *.conf)') self.projectProperties = self.project.read(fn) self.setupModelData(self.projectProperties) self.setupGeneralData(self.projectProperties) @pyqtSlot(QModelIndex, name='on_mMobileListView_clicked') def editMobile(self, index): ''' Populate the widgets with the selected mobiles properties ''' if index.isValid(): self.populateMobileWidgets(index) @pyqtSlot(str, name='on_comboBoxMobileType_currentIndexChanged') def mobileTypeChanged(self, mType): if mType == 'SHAPE': self.lineEditMobileShape.setEnabled(True) else: self.lineEditMobileShape.setEnabled(False) @pyqtSlot(QModelIndex, name='on_mMobileListView_activated') def activated(self, index): pass @pyqtSlot(name='on_toolButtonAddMobile_clicked') def addMobile(self): self.mobileListModel.insertRow(self.mobileListModel.rowCount()) index = self.mobileListModel.index(self.mobileListModel.rowCount() - 1) self.lineEditMobileName.setText('NewMobile') self.mobileListModel.setData(index, 'NewMobile', Qt.DisplayRole) self.mMobileListView.setCurrentIndex(index) self.applyMobile() @pyqtSlot(name='on_pushButtonApplyMobile_clicked') def applyMobile(self): index = self.mMobileListView.currentIndex() if index.isValid() and not self.lineEditMobileName.text() == '': mobile = dict() mobile['Name'] = self.lineEditMobileName.text() mobile['type'] = self.comboBoxMobileType.currentText() try: t = eval(self.lineEditMobileShape.text()) if t.__class__ is tuple or t.__class__ is dict: mobile['shape'] = t except SyntaxError: mobile['shape'] = ((0.0, -0.5), (0.3, 0.5), (0.0, 0.2), (-0.5, 0.5)) mobile['length'] = self.doubleSpinBoxMobileLength.value() mobile['width'] = self.doubleSpinBoxMobileWidth.value() mobile['offsetX'] = self.doubleSpinBoxXOffset.value() mobile['offsetY'] = self.doubleSpinBoxYOffset.value() mobile['zValue'] = self.spinBoxZValue.value() mobile['color'] = self.mColorButtonMobileColor.color().rgba() mobile['fillColor'] = self.mColorButtonMobileFillColor.color( ).rgba() mobile['timeout'] = self.spinBoxMobileTimeout.value() * 1000 mobile['nofixNotify'] = self.spinBoxMobileNotification.value() mobile['trackLength'] = self.spinBoxTrackLength.value() mobile['trackColor'] = self.mColorButtonMobileTrackColor.color( ).rgba() mobile['showLabel'] = self.checkBoxShowLabel.isChecked() provs = dict() for r in range(self.mobileProviderModel.rowCount()): try: fil = int( self.mobileProviderModel.item(r, 1).data(Qt.DisplayRole)) except: fil = self.mobileProviderModel.item(r, 1).data(Qt.DisplayRole) if not fil: fil = None provs[self.mobileProviderModel.item(r, 0).data( Qt.DisplayRole)] = fil mobile['provider'] = provs currName = self.mobileListModel.data(index, Qt.DisplayRole) if not currName == mobile['Name']: del self.projectProperties['Mobiles'][currName] self.mobileListModel.setData(index, mobile['Name'], Qt.DisplayRole) self.projectProperties['Mobiles'][mobile['Name']] = mobile def populateMobileWidgets(self, index): mobile = self.projectProperties['Mobiles'][self.mobileListModel.data( index, Qt.DisplayRole)] self.lineEditMobileName.setText(mobile.get('Name')) self.comboBoxMobileType.setCurrentIndex( self.comboBoxMobileType.findText( mobile.setdefault('type', 'BOX').upper())) if mobile['type'] == 'SHAPE': self.lineEditMobileShape.setText(str(mobile['shape'])) self.lineEditMobileShape.setEnabled(True) self.doubleSpinBoxXOffset.setEnabled(True) self.doubleSpinBoxYOffset.setEnabled(True) else: self.lineEditMobileShape.setEnabled(False) self.doubleSpinBoxXOffset.setEnabled(False) self.doubleSpinBoxYOffset.setEnabled(False) self.lineEditMobileShape.clear() self.doubleSpinBoxMobileLength.setValue(mobile.get('length', 20.0)) self.doubleSpinBoxMobileWidth.setValue(mobile.get('width', 5.0)) self.doubleSpinBoxXOffset.setValue(mobile.get('offsetX', 0.0)) self.doubleSpinBoxYOffset.setValue(mobile.get('offsetY', 0.0)) self.spinBoxZValue.setValue(mobile.get('zValue', 100)) self.mColorButtonMobileColor.setColor( self.getColor(mobile.get('color', 'black'))) self.mColorButtonMobileFillColor.setColor( self.getColor(mobile.get('fillColor', 'green'))) self.spinBoxMobileTimeout.setValue(mobile.get('timeout', 3000) / 1000) self.spinBoxMobileNotification.setValue(mobile.get('nofixNotify', 0)) self.spinBoxTrackLength.setValue(mobile.get('trackLength', 100)) self.mColorButtonMobileTrackColor.setColor( self.getColor(mobile.get('trackColor', 'green'))) self.checkBoxShowLabel.setChecked(mobile.get('showLabel', False)) r = 0 self.mobileProviderModel.removeRows( 0, self.mobileProviderModel.rowCount()) if 'provider' in mobile: for k, v in mobile['provider'].items(): prov = QStandardItem(k) val = QStandardItem(str(v)) self.mobileProviderModel.setItem(r, 0, prov) self.mobileProviderModel.setItem(r, 1, val) r += 1 @pyqtSlot(name='on_toolButtonRemoveMobile_clicked') def removeMobile(self): idx = self.mMobileListView.currentIndex() if idx.isValid(): self.projectProperties['Mobiles'].pop( self.mobileListModel.data(idx, Qt.DisplayRole)) self.mobileListModel.removeRows(idx.row(), 1) idx = self.mMobileListView.currentIndex() if idx.isValid(): self.populateMobileWidgets(idx) @pyqtSlot(name='on_toolButtonRefreshMobileProvider_clicked') def refreshMobileProvider(self): prov = self.comboBoxProviders.currentText() if prov == '': return fil = None if self.lineEditProviderFilter.text() != '': fil = self.lineEditProviderFilter.text() items = self.mobileProviderModel.findItems(prov, Qt.MatchExactly, 0) if items: for item in items: self.mobileProviderModel.setItem(item.row(), 1, QStandardItem(fil)) else: self.mobileProviderModel.appendRow( [QStandardItem(prov), QStandardItem(fil)]) @pyqtSlot(name='on_toolButtonRemoveMobileProvider_clicked') def removeMobileProvider(self): idx = self.mMobileProviderTableView.currentIndex() if idx.isValid(): self.mobileProviderModel.removeRow(idx.row()) @pyqtSlot(name='on_pushButtonApplyDataProvider_clicked') def applyDataProvider(self): index = self.mDataProviderListView.currentIndex() if index.isValid() and not self.lineEditProviderName.text() == '': provider = dict() provider['Name'] = self.lineEditProviderName.text() provider['DataDeviceType'] = self.comboBoxProviderType.currentText( ) if provider['DataDeviceType'] in NETWORK_TYPES: provider['Host'] = self.lineEditProviderHostName.text() provider['Port'] = self.spinBoxProviderPort.value() provider['Parser'] = self.comboBoxParser.currentText() currName = self.providerListModel.data(index, Qt.DisplayRole) if not currName == provider['Name']: del self.projectProperties['Provider'][currName] self.providerListModel.setData(index, provider['Name'], Qt.DisplayRole) self.projectProperties['Provider'][provider['Name']] = provider @pyqtSlot(QModelIndex, name='on_mDataProviderListView_clicked') def editDataProvider(self, index): ''' ''' if index.isValid(): self.populateDataProviderWidgets(index) def populateDataProviderWidgets(self, index): provider = self.projectProperties['Provider'][ self.providerListModel.data(index, Qt.DisplayRole)] self.lineEditProviderName.setText(provider.get('Name')) self.comboBoxProviderType.setCurrentIndex( self.comboBoxProviderType.findText( provider.setdefault('DataDeviceType', 'UDP').upper())) if provider['DataDeviceType'] in NETWORK_TYPES: self.stackedWidgetDataDevice.setCurrentIndex(0) self.lineEditProviderHostName.setText( provider.setdefault('Host', '0.0.0.0')) self.spinBoxProviderPort.setValue( int(provider.setdefault('Port', 2000))) self.comboBoxParser.setCurrentIndex( self.comboBoxParser.findText( provider.setdefault('Parser', 'NONE').upper())) @pyqtSlot(name='on_toolButtonAddDataProvider_clicked') def addDataProvider(self): self.providerListModel.insertRow(self.providerListModel.rowCount()) index = self.providerListModel.index( self.providerListModel.rowCount() - 1) self.lineEditProviderName.setText('NewDataProvider') self.providerListModel.setData(index, 'NewDataProvider', Qt.DisplayRole) self.mDataProviderListView.setCurrentIndex(index) self.applyDataProvider() @pyqtSlot(name='on_toolButtonRemoveDataProvider_clicked') def removeDataProvider(self): idx = self.mDataProviderListView.currentIndex() if idx.isValid(): self.projectProperties['Provider'].pop( self.providerListModel.data(idx, Qt.DisplayRole)) self.providerListModel.removeRows(idx.row(), 1) idx = self.mDataProviderListView.currentIndex() if idx.isValid(): self.populateDataProviderWidgets(idx) @pyqtSlot(name='on_toolButtonSelectLogPath_clicked') def selectRecorderPath(self): path = QFileDialog.getExistingDirectory( self, self.tr('Select Recorder Path'), self.lineEditRecorderPath.text(), QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks) if path != '': self.lineEditRecorderPath.setText(path) @pyqtSlot(QPoint, name='on_lineEditMobileShape_customContextMenuRequested') def mobileShapeContextMenu(self, pos): menu = QMenu(self.lineEditMobileShape) vesselAction = menu.addAction(self.tr('Vessel')) rovAction = menu.addAction(self.tr('ROV')) auvAction = menu.addAction(self.tr('AUV')) arrowAction = menu.addAction(self.tr('Arrow')) selectedAction = menu.exec_(self.lineEditMobileShape.mapToGlobal(pos)) if selectedAction == vesselAction: self.lineEditMobileShape.setText( u'((0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3))' ) elif selectedAction == rovAction: self.lineEditMobileShape.setText( u'((0.3, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3), (-0.3, -0.5))' ) elif selectedAction == auvAction: self.lineEditMobileShape.setText( u'((0, -0.5), (0.5, -0.3), (0.5, 0.5), (-0.5, 0.5), (-0.5, -0.3))' ) elif selectedAction == arrowAction: self.lineEditMobileShape.setText( u'((0, -0.5), (0.5, 0.5), (0, 0), (-0.5, 0.5))') @pyqtSlot(name='on_buttonBox_helpRequested') def showHelp(self): """Display application help to the user.""" help_file = os.path.join( os.path.split(os.path.dirname(__file__))[0], 'help', 'index.html') QDesktopServices.openUrl(QUrl.fromLocalFile(help_file))
class CompleteLineEdit(QLineEdit): def __init__(self, words): super(CompleteLineEdit, self).__init__(None) self.words = words # QStringList 整个完成列表的单词 self.listView = QListView(self) self.model = QStringListModel(self) self.listView.setWindowFlags(Qt.ToolTip) self.connect(self, SIGNAL("textChanged(const QString &)"), self, SLOT("setCompleter(const QString &)")) self.connect(self.listView, SIGNAL("clicked(const QModelIndex &)"), self, SLOT("completeText(const QModelIndex &)")) def focusOutEvent(self, focus_event): # self.listView.hide() pass @pyqtSlot("QKeyEvent") def keyPressEvent(self, e): if not self.listView.isHidden(): key = e.key() count = self.listView.model().rowCount() currentIndex = self.listView.currentIndex() if Qt.Key_Down == key: # 按向下方向键时,移动光标选中下一个完成列表中的项 row = currentIndex.row() + 1 if (row >= count): row = 0 index = self.listView.model().index(row, 0) self.listView.setCurrentIndex(index) elif Qt.Key_Up == key: # 按向下方向键时,移动光标选中上一个完成列表中的项 row = currentIndex.row() - 1 if (row < 0): row = count - 1 index = self.listView.model().index(row, 0) self.listView.setCurrentIndex(index) elif Qt.Key_Escape == key: # 按下Esc键时,隐藏完成列表 self.listView.hide() elif Qt.Key_Enter == key or Qt.Key_Return == key: # 按下回车键时,使用完成列表中选中的项,并隐藏完成列表 if (currentIndex.isValid()): text = self.listView.currentIndex().data().toString() self.setText(text) self.listView.hide() else: # 其他情况,隐藏完成列表,并使用QLineEdit的键盘按下事件 self.listView.hide() QLineEdit.keyPressEvent(self,e) else: QLineEdit.keyPressEvent(self,e) # 动态的显示完成列表 @pyqtSlot("QString") def setCompleter(self, text): if (text.isEmpty()): self.listView.hide() return if text.length() > 1 and not self.listView.isHidden(): return # 如果完整的完成列表中的某个单词包含输入的文本,则加入要显示的完成列表串中 sl = QStringList() for i in range(self.words.count()): if self.words[i].contains(text): sl << self.words[i] self.model.setStringList(sl) self.listView.setModel(self.model) if (self.model.rowCount() == 0): return # Position the text edit self.listView.setMinimumWidth(self.width()) self.listView.setMaximumWidth(self.width()) p = QPoint(0, self.height()) x = self.mapToGlobal(p).x() y = self.mapToGlobal(p).y() + 1 self.listView.move(x, y) self.listView.show() # 点击完成列表中的项,使用此项自动完成输入的单词 @pyqtSlot("QModelIndex") def completeText(self, index): text = index.data().toString() self.setText(text) self.listView.hide()
class OWDatabasesUpdate(OWWidget): name = "Databases Update" description = "Update local systems biology databases." icon = "../widgets/icons/Databases.svg" priority = 10 inputs = [] outputs = [] want_main_area = False def __init__(self, parent=None, signalManager=None, name="Databases update", domains=None): OWWidget.__init__(self, parent, signalManager, name, wantMainArea=False) self.searchString = "" self.accessCode = "" self.domains = domains or DOMAINS self.serverFiles = serverfiles.ServerFiles() fbox = gui.widgetBox(self.controlArea, "Filter") # The completer model token strings self.completertokens = [] # A 'dynamic' completer item model will be updated with # 'prefix {token}' where prefix is current 'active' filter list # (the QCompleter only completes on one item in the model) self.completermodel = QStringListModel(self) self.completer = QCompleter(self.completermodel, self, caseSensitivity=Qt.CaseInsensitive) self.lineEditFilter = QLineEdit(textChanged=self.SearchUpdate) self.lineEditFilter.setCompleter(self.completer) fbox.layout().addWidget(self.lineEditFilter) box = gui.widgetBox(self.controlArea, "Files") self.filesView = QTreeWidget(self) self.filesView.setHeaderLabels( ["", "Data Source", "Update", "Last Updated", "Size"]) self.filesView.setRootIsDecorated(False) self.filesView.setUniformRowHeights(True) self.filesView.setSelectionMode(QAbstractItemView.NoSelection) self.filesView.setSortingEnabled(True) self.filesView.sortItems(1, Qt.AscendingOrder) self.filesView.setItemDelegateForColumn( 0, UpdateOptionsItemDelegate(self.filesView)) self.filesView.model().layoutChanged.connect(self.SearchUpdate) box.layout().addWidget(self.filesView) box = gui.widgetBox(self.controlArea, orientation="horizontal") self.updateButton = gui.button( box, self, "Update all", callback=self.UpdateAll, tooltip="Update all updatable files", ) self.downloadButton = gui.button( box, self, "Download all", callback=self.DownloadFiltered, tooltip="Download all filtered files shown") self.cancelButton = gui.button( box, self, "Cancel", callback=self.Cancel, tooltip="Cancel scheduled downloads/updates.") self.retryButton = gui.button(box, self, "Reconnect", callback=self.RetrieveFilesList) self.retryButton.hide() gui.rubber(box) gui.lineEdit(box, self, "accessCode", "Access Code", orientation="horizontal", callback=self.RetrieveFilesList) self.warning(0) box = gui.widgetBox(self.controlArea, orientation="horizontal") gui.rubber(box) self.infoLabel = QLabel() self.infoLabel.setAlignment(Qt.AlignCenter) self.controlArea.layout().addWidget(self.infoLabel) self.infoLabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.updateItems = [] self.resize(800, 600) self.progress = ProgressState(self, maximum=3) self.progress.valueChanged.connect(self._updateProgress) self.progress.rangeChanged.connect(self._updateProgress) self.executor = ThreadExecutor(threadPool=QThreadPool( maxThreadCount=2)) task = Task(self, function=self.RetrieveFilesList) task.exceptionReady.connect(self.HandleError) task.start() self._tasks = [] self._haveProgress = False def RetrieveFilesList(self): self.retryButton.hide() self.warning(0) self.progress.setRange(0, 3) self.serverFiles = serverfiles.ServerFiles(access_code=self.accessCode) task = Task( function=partial(retrieveFilesList, self.serverFiles, self.domains, methodinvoke(self.progress, "advance"))) task.resultReady.connect(self.SetFilesList) task.exceptionReady.connect(self.HandleError) self.executor.submit(task) self.setEnabled(False) def SetFilesList(self, serverInfo): """ Set the files to show. """ self.setEnabled(True) domains = serverInfo.keys() if not domains: if self.domains: domains = self.domains else: domains = serverfiles.listdomains() localInfo = dict([(dom, serverfiles.allinfo(dom)) for dom in domains]) all_tags = set() self.filesView.clear() self.updateItems = [] for item in join_info_dict(localInfo, serverInfo): tree_item = UpdateTreeWidgetItem(item) options_widget = UpdateOptionsWidget(item.state) options_widget.item = item options_widget.installClicked.connect( partial(self.SubmitDownloadTask, item.domain, item.filename)) options_widget.removeClicked.connect( partial(self.SubmitRemoveTask, item.domain, item.filename)) self.updateItems.append((item, tree_item, options_widget)) all_tags.update(item.tags) self.filesView.addTopLevelItems( [tree_item for _, tree_item, _ in self.updateItems]) for item, tree_item, options_widget in self.updateItems: self.filesView.setItemWidget(tree_item, 0, options_widget) # Add an update button if the file is updateable if item.state == OUTDATED: button = QToolButton(None, text="Update", maximumWidth=120, minimumHeight=20, maximumHeight=20) if sys.platform == "darwin": button.setAttribute(Qt.WA_MacSmallSize) button.clicked.connect( partial(self.SubmitDownloadTask, item.domain, item.filename)) self.filesView.setItemWidget(tree_item, 2, button) self.progress.advance() self.filesView.setColumnWidth(0, self.filesView.sizeHintForColumn(0)) for column in range(1, 4): contents_hint = self.filesView.sizeHintForColumn(column) header_hint = self.filesView.header().sectionSizeHint(column) width = max(min(contents_hint, 400), header_hint) self.filesView.setColumnWidth(column, width) hints = [hint for hint in sorted(all_tags) if not hint.startswith("#")] self.completertokens = hints self.completermodel.setStringList(hints) self.SearchUpdate() self.UpdateInfoLabel() self.toggleButtons() self.cancelButton.setEnabled(False) self.progress.setRange(0, 0) def buttonCheck(self, selected_items, state, button): for item in selected_items: if item.state != state: button.setEnabled(False) else: button.setEnabled(True) break def toggleButtons(self): selected_items = [ item for item, tree_item, _ in self.updateItems if not tree_item.isHidden() ] self.buttonCheck(selected_items, OUTDATED, self.updateButton) self.buttonCheck(selected_items, AVAILABLE, self.downloadButton) def HandleError(self, exception): if isinstance(exception, ConnectionError): self.warning( 0, "Could not connect to server! Check your connection " "and try to reconnect.") self.SetFilesList({}) self.retryButton.show() else: sys.excepthook(type(exception), exception.args, None) self.progress.setRange(0, 0) self.setEnabled(True) def UpdateInfoLabel(self): local = [ item for item, tree_item, _ in self.updateItems if item.state != AVAILABLE and not tree_item.isHidden() ] size = sum(float(item.size) for item in local) onServer = [ item for item, tree_item, _ in self.updateItems if not tree_item.isHidden() ] sizeOnServer = sum(float(item.size) for item in onServer) text = ("%i items, %s (on server: %i items, %s)" % (len(local), sizeof_fmt(size), len(onServer), sizeof_fmt(sizeOnServer))) self.infoLabel.setText(text) def UpdateAll(self): self.warning(0) for item, tree_item, _ in self.updateItems: if item.state == OUTDATED and not tree_item.isHidden(): self.SubmitDownloadTask(item.domain, item.filename) def DownloadFiltered(self): # TODO: submit items in the order shown. for item, tree_item, _ in self.updateItems: if not tree_item.isHidden() and item.state in \ [AVAILABLE, OUTDATED]: self.SubmitDownloadTask(item.domain, item.filename) def _updateCompleterPrefix(self, prefix, seperator=" "): prefix = str(self.completer.completionPrefix()) tokens = self.completertokens model = self.completer.model() if not prefix.endswith(seperator) and seperator in prefix: prefix, _ = prefix.rsplit(seperator, 1) items = [prefix + seperator + item for item in tokens] else: items = tokens old = set(str(item) for item in model.stringList()) if old != set(items): model.setStringList(items) def SearchUpdate(self, searchString=None): self._updateCompleterPrefix(searchString) strings = str(self.lineEditFilter.text()).split() for item, tree_item, _ in self.updateItems: hide = not all( UpdateItem_match(item, string) for string in strings) tree_item.setHidden(hide) self.UpdateInfoLabel() self.toggleButtons() def SubmitDownloadTask(self, domain, filename): """ Submit the (domain, filename) to be downloaded/updated. """ self.cancelButton.setEnabled(True) index = self.updateItemIndex(domain, filename) _, tree_item, opt_widget = self.updateItems[index] if self.accessCode: sf = serverfiles.ServerFiles(access_code=self.accessCode) else: sf = serverfiles.ServerFiles() task = DownloadTask(domain, filename, sf) self.progress.adjustRange(0, 100) pb = ItemProgressBar(self.filesView) pb.setRange(0, 100) pb.setTextVisible(False) task.advanced.connect(pb.advance) task.advanced.connect(self.progress.advance) task.finished.connect(pb.hide) task.finished.connect(self.onDownloadFinished, Qt.QueuedConnection) task.exception.connect(self.onDownloadError, Qt.QueuedConnection) self.filesView.setItemWidget(tree_item, 2, pb) # Clear the text so it does not show behind the progress bar. tree_item.setData(2, Qt.DisplayRole, "") pb.show() # Disable the options widget opt_widget.setEnabled(False) self._tasks.append(task) self.executor.submit(task) def EndDownloadTask(self, task): future = task.future() index = self.updateItemIndex(task.domain, task.filename) item, tree_item, opt_widget = self.updateItems[index] self.filesView.removeItemWidget(tree_item, 2) opt_widget.setEnabled(True) if future.cancelled(): # Restore the previous state tree_item.setUpdateItem(item) opt_widget.setState(item.state) elif future.exception(): tree_item.setUpdateItem(item) opt_widget.setState(item.state) # Show the exception string in the size column. self.warning( 0, "Error while downloading. Check your connection " "and retry.") # recreate button for download button = QToolButton(None, text="Retry", maximumWidth=120, minimumHeight=20, maximumHeight=20) if sys.platform == "darwin": button.setAttribute(Qt.WA_MacSmallSize) button.clicked.connect( partial(self.SubmitDownloadTask, item.domain, item.filename)) self.filesView.setItemWidget(tree_item, 2, button) else: # get the new updated info dict and replace the the old item self.warning(0) info = serverfiles.info(item.domain, item.filename) new_item = update_item_from_info(item.domain, item.filename, info, info) self.updateItems[index] = (new_item, tree_item, opt_widget) tree_item.setUpdateItem(new_item) opt_widget.setState(new_item.state) self.UpdateInfoLabel() def SubmitRemoveTask(self, domain, filename): serverfiles.remove(domain, filename) index = self.updateItemIndex(domain, filename) item, tree_item, opt_widget = self.updateItems[index] if item.info_server: new_item = item._replace(state=AVAILABLE, local=None, info_local=None) else: new_item = item._replace(local=None, info_local=None) # Disable the options widget. No more actions can be performed # for the item. opt_widget.setEnabled(False) tree_item.setUpdateItem(new_item) opt_widget.setState(new_item.state) self.updateItems[index] = (new_item, tree_item, opt_widget) self.UpdateInfoLabel() def Cancel(self): """ Cancel all pending update/download tasks (that have not yet started). """ for task in self._tasks: task.future().cancel() def onDeleteWidget(self): self.Cancel() self.executor.shutdown(wait=False) OWWidget.onDeleteWidget(self) def onDownloadFinished(self): # on download completed/canceled/error assert QThread.currentThread() is self.thread() for task in list(self._tasks): future = task.future() if future.done(): self.EndDownloadTask(task) self._tasks.remove(task) if not self._tasks: # Clear/reset the overall progress self.progress.setRange(0, 0) self.cancelButton.setEnabled(False) def onDownloadError(self, exc_info): sys.excepthook(*exc_info) self.warning( 0, "Error while downloading. Check your connection and " "retry.") def updateItemIndex(self, domain, filename): for i, (item, _, _) in enumerate(self.updateItems): if item.domain == domain and item.filename == filename: return i raise ValueError("%r, %r not in update list" % (domain, filename)) def _updateProgress(self, *args): rmin, rmax = self.progress.range() if rmin != rmax: if not self._haveProgress: self._haveProgress = True self.progressBarInit() self.progressBarSet(self.progress.ratioCompleted() * 100, processEvents=None) if rmin == rmax: self._haveProgress = False self.progressBarFinished()
class IntroPage(WizardPage): UI_CLASS = Ui_Intro TITLE = "Starting a bisection" SUBTITLE = ("Please choose an application, a type of bisection" "and the number of bits for the application.") FIELDS = { 'application': 'app_combo', 'bisect_type': 'bisect_combo', 'find_fix': 'find_fix', 'bits': 'bits_combo' } ID = 0 def __init__(self): WizardPage.__init__(self) self.fetch_config = None self.app_model = QStringListModel(REGISTRY.names()) self.ui.app_combo.setModel(self.app_model) self.bisect_model = QStringListModel() self.ui.bisect_combo.setModel(self.bisect_model) if mozinfo.bits == 64: self.bits_model = QStringListModel(['32', '64']) bits_index = 1 elif mozinfo.bits == 32: self.bits_model = QStringListModel(['32']) bits_index = 0 self.ui.bits_combo.setModel(self.bits_model) self.ui.bits_combo.setCurrentIndex(bits_index) self.ui.app_combo.currentIndexChanged.connect(self._set_fetch_config) self.ui.bits_combo.currentIndexChanged.connect(self._set_fetch_config) self.ui.app_combo.setCurrentIndex( self.ui.app_combo.findText("firefox")) def _set_fetch_config(self, index): # limit bisection type given the application bits = int(self.ui.bits_combo.currentText()) old_bisect_index = self.ui.bisect_combo.currentIndex() self.fetch_config = create_config( str(self.ui.app_combo.itemText(index)), mozinfo.os, bits) bisect_types = ['nightlies'] if self.fetch_config.is_inbound(): bisect_types.append('inbound') self.bisect_model.setStringList(bisect_types) bisect_index = 0 if old_bisect_index == 1 and len(bisect_types) == 2: bisect_index = 1 self.ui.bisect_combo.setCurrentIndex(bisect_index) available_bits = self.fetch_config.available_bits() if not available_bits: self.ui.bits_combo.hide() self.ui.label_4.hide() else: self.ui.bits_combo.show() self.ui.label_4.show() def validatePage(self): app_name = self.fetch_config.app_name launcher_class = LAUNCHER_REGISTRY.get(app_name) try: launcher_class.check_is_runnable() return True except LauncherNotRunnable, exc: QMessageBox.critical(self, "%s is not runnable" % app_name, str(exc)) return False
class RatingWidget(QWidget): """ Last panel. Gives point cost of idea set and lists any penalty flags. """ def __init__(self, parent=None): super().__init__(parent=parent) # cost display self.cost = QGroupBox("National ideas") costLayout = QFormLayout() self.costRating = QLineEdit() self.costRating.setReadOnly(True) costLayout.addRow(QLabel("Rating:"), self.costRating) self.costDisplay = QLineEdit() self.costDisplay.setReadOnly(True) costLayout.addRow(QLabel("Cost:"), self.costDisplay) possibleRatings = QGroupBox("Possible ratings") possibleRatingsLayout = QFormLayout() for cost, rating in ideaRatings: if cost is not None: possibleRatingsLayout.addRow(QLabel("Up to %0.1f:" % (cost),), QLabel(rating)) else: possibleRatingsLayout.addRow(QLabel("Above:"), QLabel(rating)) possibleRatings.setLayout(possibleRatingsLayout) costLayout.addRow(possibleRatings) breakdown = QGroupBox("Breakdown") breakdownLayout = QFormLayout() self.breakdownLabels = [] self.breakdownCosts = [] for i in range(9): breakdownLabel = QLabel() self.breakdownLabels.append(breakdownLabel) breakdownCost = QLineEdit() breakdownCost.setReadOnly(True) self.breakdownCosts.append(breakdownCost) breakdownLayout.addRow(breakdownLabel, breakdownCost) breakdown.setLayout(breakdownLayout) costLayout.addRow(breakdown) self.cost.setLayout(costLayout) self.cost.setToolTip(costToolTipText) # penalty display self.penalties = QGroupBox("Penalties") penaltiesLayout = QFormLayout() # self.penaltiesRating = QLineEdit() # self.penaltiesRating.setReadOnly(True) # penaltiesLayout.addRow(QLabel("Rating:"), self.penaltiesRating) self.yellowCardCount = QLineEdit() self.yellowCardCount.setReadOnly(True) penaltiesLayout.addRow(QLabel("Yellow cards:"), self.yellowCardCount) self.yellowCardDisplay = QListView() self.yellowCardDisplay.setSelectionMode(QAbstractItemView.NoSelection) self.yellowCards = QStringListModel() self.yellowCardDisplay.setModel(self.yellowCards) penaltiesLayout.addRow(self.yellowCardDisplay) self.redCardCount = QLineEdit() self.redCardCount.setReadOnly(True) penaltiesLayout.addRow(QLabel("Red cards:"), self.redCardCount) self.redCardDisplay = QListView() self.redCardDisplay.setSelectionMode(QAbstractItemView.NoSelection) self.redCards = QStringListModel() self.redCardDisplay.setModel(self.redCards) penaltiesLayout.addRow(self.redCardDisplay) self.penalties.setLayout(penaltiesLayout) self.penalties.setToolTip(penaltiesToolTipText) layout = QHBoxLayout() layout.addWidget(self.cost) layout.addWidget(self.penalties) self.setLayout(layout) def handleCostChanged(self, costs): totalCost = sum(costs) self.costDisplay.setText("%0.2f" % (totalCost,)) self.costRating.setText(getIdeaRating(totalCost)) for i, cost in enumerate(costs): self.breakdownCosts[i].setText("%0.2f" % cost) def handleIdeaNamesChanged(self, names): for i, name in enumerate(names): self.breakdownLabels[i].setText(name) def handlePenaltiesChanged(self, yellow, red): self.yellowCardCount.setText("%d" % (len(yellow),)) self.yellowCards.setStringList(yellow) self.redCardCount.setText("%d" % (len(red),)) self.redCards.setStringList(red)