def __init__(self, model): super().__init__() self._model = model layout = QGridLayout() splitter = QSplitter() self._bot_table = _BotTable() self._responses_tab = _ResponsesTab() self._execute_tab = _ExecuteTab(self._responses_tab, model) self._tab_widget = QTabWidget() self._tab_widget.addTab(self._execute_tab, "Execute") self._tab_widget.addTab(self._responses_tab, "Responses") splitter.setOrientation(Qt.Vertical) splitter.addWidget(self._bot_table) splitter.addWidget(self._tab_widget) splitter.setSizes([50, 100]) layout.addWidget(splitter) self.setLayout(layout) self._register_listeners()
def init_workspace(self): splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.sizePolicy().setVerticalPolicy(QSizePolicy.Maximum) query_edit = self.init_query_text_edit() self.on_disconnected() splitter.addWidget(query_edit) results_widget = self.init_results_widget() splitter.addWidget(results_widget) splitter.setSizes([100, 900]) return splitter
def init_workspace(self): # Create a splitter consisting of query edit and table view splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.sizePolicy().setVerticalPolicy(QSizePolicy.Maximum) # Initialize query edit file query_edit = self.init_query_text_edit() # Disable query control buttons by default self.on_disconnected() splitter.addWidget(query_edit) # Initialize result desiplaying widgets results_widget = self.init_results_widget() splitter.addWidget(results_widget) splitter.setSizes([100, 900]) return splitter
def setup_layout(self): # group the editor with the console vertical_splitter = QSplitter(self) vertical_splitter.setOrientation(Qt.Vertical) vertical_splitter.addWidget(self.editor_pane) vertical_splitter.addWidget(self.console) vertical_splitter.setStretchFactor(0, 3) vertical_splitter.setStretchFactor(1, 1) # group horizontal_splitter = QSplitter(self) horizontal_splitter.addWidget(self.explorer_tab) horizontal_splitter.addWidget(vertical_splitter) horizontal_splitter.addWidget(self.info_bar) horizontal_splitter.setStretchFactor(0, 1) horizontal_splitter.setStretchFactor(1, 4) horizontal_splitter.setStretchFactor(2, 1) self.setCentralWidget(horizontal_splitter)
class Snipdom(QMainWindow): def __init__(self): QMainWindow.__init__(self) self.hsplit = QSplitter() self.setCentralWidget(self.hsplit) kernel_manager = QtInProcessKernelManager() kernel_manager.start_kernel() self.kernel = kernel_manager.kernel self.kernel.gui = 'qt' self.control = RichIPythonWidget(gui_completion="droplist") self.kernel.shell.push({'snipdom': self}) kernel_client = kernel_manager.client() kernel_client.start_channels() self.control.kernel_manager = kernel_manager self.control.kernel_client = kernel_client self.vsplit = QSplitter() self.vsplit.setOrientation(Qt.Vertical) self.vsplit.addWidget(self.control) self.hsplit.addWidget(self.vsplit) self.sendButton = QPushButton("send") #self.sendButton.clicked.connect(self.sendcode) self.vsplit.addWidget(self.sendButton) self.bridge = Js2Py() self.bridge.sent.connect(self.codeFromJs) #lab = QtGui.QLabel(kernel.shell.history_manager.get_range(start=-1).next()[2]) def codeFromJs(self, code): self.control.input_buffer = code
def __init__(self, path, panel, parent): """ Create widget. Arguments: obj (Command, Parameter): Command or Parameter being edited. parent (Optional[QWidget]): Parent widget. """ super(ParameterTableWindow, self).__init__(path, panel, parent) view = ParameterTableView(panel, item_path=path, parent_item=None, parent=self) self._actions = {} self._setView(view) self._search.setVisible(False) self._plot = None if re.match("^.*[.]VALE$", path.path()) or \ re.match("^.*[.](ABSCISSE|ORDONNEE)$", path.path()): self._plot = PlotWidget(view, self) self._plot.hide() splitter = QSplitter(self) splitter.setOrientation(Qt.Vertical) splitter.addWidget(view) splitter.addWidget(self._plot) self._scroll.setWidget(splitter) else: self._scroll.setWidget(view) view.selectionChanged.connect(self._updateState) tbar = QToolBar(self) tbar.setToolButtonStyle(Qt.ToolButtonIconOnly) tbar.addAction(\ self._createAction(ParameterTableWindow.AppendRow, load_icon("as_pic_add_row.png"), translate("ParameterPanel", "Append row"), translate("ParameterPanel", "Append row to the end of table"), view.appendRow)) tbar.addAction(\ self._createAction(ParameterTableWindow.InsertRow, load_icon("as_pic_insert_row.png"), translate("ParameterPanel", "Insert row"), translate("ParameterPanel", "Insert row at current position"), view.insertRow)) tbar.addAction(\ self._createAction(ParameterTableWindow.RemoveRow, load_icon("as_pic_remove_row.png"), translate("ParameterPanel", "Remove rows"), translate("ParameterPanel", "Remove selected rows"), view.removeRows)) tbar.addSeparator() tbar.addAction(\ self._createAction(ParameterTableWindow.MoveRowUp, load_icon("as_pic_move_up.png"), translate("ParameterPanel", "Move up"), translate("ParameterPanel", "Move selected rows up"), view.moveRowsUp)) tbar.addAction(\ self._createAction(ParameterTableWindow.MoveRowDown, load_icon("as_pic_move_down.png"), translate("ParameterPanel", "Move down"), translate("ParameterPanel", "Move selected rows down"), view.moveRowsDown)) tbar.addSeparator() if self._plot is not None: tbar.addAction(\ self._createAction(ParameterTableWindow.FunctionPlot, load_icon("as_pic_show_plot.png"), translate("ParameterPanel", "Plot function"), translate("ParameterPanel", "Show/hide plot view"), self._plot.setVisible, True)) tbar.addSeparator() tbar.addAction(\ self._createAction(ParameterTableWindow.Import, load_icon("as_pic_import_table.png"), translate("ParameterPanel", "Import table"), translate("ParameterPanel", "Import function data from file"), view.importFile)) self.addControlWidget(tbar) self._updateState()
class MainWidget(QWidget): """Main window class that provides logic of the program. Allows to search concept and to show information about concepts and relations """ def __init__(self, parent=None, application=None): super().__init__(parent) self.parent = parent self.application = application self.db = self.openDatabase() self.initUI() def initActions(self): """initalization of actions for main windows""" self.help_action = QAction("&Help", self) self.help_action.setShortcut("F1") self.help_action.setStatusTip('Help') self.help_action.triggered.connect(lambda: HelpDialog(self)) self.about_action = QAction("&About", self) self.about_action.setStatusTip('About') self.about_action.triggered.connect(self.showAboutMessage) self.new_db_action = QAction("New DB", self) self.new_db_action.setShortcut("Ctrl+N") self.new_db_action.triggered.connect(self.openNewDB) self.delete_сoncept_action = QAction("&Delete", self) self.delete_сoncept_action.setShortcut("DEL") self.delete_сoncept_action.setStatusTip("Delete") self.delete_сoncept_action.triggered.connect(lambda: self.delete(Concept)) self.delete_subcategory_action = QAction("&Delete subcategory", self) self.delete_subcategory_action.triggered.connect(lambda: self.delete(Subcategory)) self.edit_concept_action = QAction("&Edit", self) self.edit_concept_action.setShortcut("F2") self.edit_concept_action.triggered.connect(self.editConcept) self.edit_relation_action = QAction("&Edit", self) self.edit_relation_action.setShortcut("Ctrl+F2") self.edit_relation_action.triggered.connect(self.editRelation) self.exit_action = QAction("&Exit", self) self.exit_action.setShortcut("ESC") self.exit_action.triggered.connect(self.close) self.select_relation_action = QAction("&Select relation", self) self.select_relation_action.triggered.connect(self.setRelationDescription) self.delete_relation_action = QAction("&Delete", self) self.delete_relation_action.setShortcut("Ctrl+DEL") self.delete_relation_action.triggered.connect(lambda: self.delete(Relation)) def showAboutMessage(self): try: with open("about.txt") as f: text = f.read() QMessageBox.about(self.parent, "About application", text) except: pass def openNewDB(self): """This method deletes setting.py file and closes current application session. This uses for creating a new instance of Main Window. """ if os.path.exists("setting.py"): os.remove("setting.py") self.parent.close() self.application.exit(1) def initUI(self): self.initActions() self.add_data_button = QPushButton("Add data", self) self.export_button = QPushButton("Export references", self) self.search_box = QGroupBox() self.concept_list = QListWidget(self) self.relation_list = QListWidget(self) self.result_table = QTextEdit(self) self.concept_list.selectionModel().selectionChanged.connect(self.searchRelations) self.concept_list.setSelectionMode(QAbstractItemView.ContiguousSelection) self.concept_list.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.concept_list.setContextMenuPolicy(Qt.CustomContextMenu) self.concept_list.customContextMenuRequested.connect(self.showConceptContextMenu) self.relation_list.setContextMenuPolicy(Qt.CustomContextMenu) self.relation_list.customContextMenuRequested.connect(self.showRelationContextMenu) self.relation_list.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.relation_list.selectionModel().selectionChanged.connect(self.setRelationDescription) self.initSearchFrame(self.search_box) self.grid = QGridLayout() self.result_table.setReadOnly(True) self.search() self.configWidgets() self.bindWidgets() self.show() def showConceptContextMenu(self, pos): if not len(self.concept_list.selectedItems()) == 1: return global_position = self.concept_list.mapToGlobal(pos) my_menu = QMenu() my_menu.addAction(self.edit_concept_action) my_menu.addAction(self.delete_сoncept_action) my_menu.addAction(self.delete_subcategory_action) my_menu.addSeparator() my_menu.addAction(self.help_action) my_menu.addAction(self.exit_action) my_menu.exec(global_position) def initSearchFrame(self, frame): self.search_line = QLineEdit(frame) checkboxes = QGroupBox() checkboxes.setStyleSheet("border:0;") self.concept_checkbox = QCheckBox("Concept", checkboxes) self.description_checkbox = QCheckBox("Description", checkboxes) self.study_checkbox = QCheckBox("Study", checkboxes) self.reference_checkbox = QCheckBox("Reference", checkboxes) self.in_selected_checkbox = QCheckBox("Search in selected concepts", checkboxes) self.search_button = QPushButton("Search", checkboxes) checkboxes_layout = QGridLayout(checkboxes) checkboxes_layout.addWidget(self.concept_checkbox, 0, 0) checkboxes_layout.addWidget(self.description_checkbox, 0, 1) checkboxes_layout.addWidget(self.study_checkbox, 0, 2) checkboxes_layout.addWidget(self.reference_checkbox, 0, 3) checkboxes_layout.addWidget(self.in_selected_checkbox, 0, 4) checkboxes_layout.setContentsMargins(0, 0, 0, 0) self.concept_checkbox.setChecked(True) self.in_selected_checkbox.setChecked(True) grid = QGridLayout(frame) grid.addWidget(self.search_line, 1, 0) grid.addWidget(self.search_button, 1, 1) grid.addWidget(checkboxes, 2, 0, Qt.AlignLeft) frame.setLayout(grid) def getSearchData(self): """This method reads parameters of search line and checkboxes, and returns "Subcategory" class. None and [] uses for showing checkboxes that have been checked. """ concept = self.search_line.text() if self.concept_checkbox.isChecked() else None if self.reference_checkbox.isChecked(): reference = [ #RelationReference(text=self.search_line.text()), ConceptReference(text=self.search_line.text()) ] else: reference = [] if self.description_checkbox.isChecked(): description = [Description(text=self.search_line.text(), reference=reference)] else: description = [Description(reference=reference)] study = self.search_line.text() if self.study_checkbox.isChecked() else None if self.in_selected_checkbox.isChecked and len(self.concept_list.selectedItems()) > 1: selected_items_raw = self.concept_list.selectedItems() selected_items = [item.data(Qt.UserRole)[1] for item in selected_items_raw] else: selected_items = [] return Subcategory(subcategory=concept, description=description, study=study), selected_items # todo: doesn't work, becouse need html + bib --> rendered bib def searchRelations(self): """This method triggers when the user clicked on the concept. This method selected ID of a subcategory from selected item in conceptions list and then searches and setting all information about this selected concept. """ if not self.concept_list.selectedItems(): self.setConceptDescription() self.setResult([], self.relation_list) return subcategory_id = self.concept_list.selectedItems()[0].data(Qt.UserRole)[1].id self.setConceptDescription() result = self.db.search_relation(subcategory_id) self.setResult(result, self.relation_list) def showRelationContextMenu(self, pos): global_position = self.relation_list.mapToGlobal(pos) my_menu = QMenu() my_menu.addAction(self.edit_relation_action) my_menu.addAction(self.delete_relation_action) my_menu.addSeparator() my_menu.exec(global_position) def editRelation(self): """This method opens dialog for editing Relation""" if hasSlelectedItems(self.relation_list): relation = self.relation_list.selectedItems()[0].data(Qt.UserRole)[2] dlg = EditRelationDialog(self, relation) if dlg.exec_(): relation = dlg.getValue() self.db.update_relation(relation) self.select_relation_action.trigger() def editConcept(self): """This method opens dialog for editing Concept""" if hasSlelectedItems(self.concept_list): concept = self.concept_list.selectedItems()[0].data(Qt.UserRole)[0] subcategory = self.concept_list.selectedItems()[0].data(Qt.UserRole)[1] dlg = EditConceptDialog(self, concept, subcategory) if dlg.exec_(): concept, subcategory = dlg.getValue() self.db.update_concept(concept) self.db.update_subcategory(subcategory) self.search() def delete(self, something): """This universal method for deleting something from the list and database. "something" parameter needs to be any of this types: Concept, Subcategory, Relation """ if something == Concept: number = 0 target_list = self.concept_list elif something == Subcategory: number = 1 target_list = self.concept_list elif something == Relation: number = 2 target_list = self.relation_list if hasSlelectedItems(target_list): something = target_list.selectedItems()[0].data(Qt.UserRole)[number] self.db.delete(something) self.search() # need refactoring def setRelationDescription(self): """This method retrieves information about relation, formats and sets it in description field. """ if hasSlelectedItems(self.relation_list): relation = self.relation_list.selectedItems()[0].data(Qt.UserRole)[2] concept1 = "{}{}".format(relation.node1.concept.name, ", {}".format(relation.node1.subcategory) if relation.node1.subcategory else "") concept2 = "{}{}".format(relation.node2.concept.name, ", {}".format(relation.node2.subcategory) if relation.node2.subcategory else "") description = relation.description study = relation.study references = relation.reference # HTML is used for a better information formating text = "<b>Relation between </b> \"{}\" <b>and</b> \"{}\"<p>".format(concept1, concept2) text += r"<b>Description:</b>" + "<br> {} <p>".format(description) text += r"<b>Study:</b> {} <p>".format(study) text += r"<b>References:</b><ol>" for ref in references: text += " <li> {} </li>".format(getBibRenderFromHTML(ref.text)) text += "</ol><br>" self.result_table.setHtml(text) else: self.result_table.clear() # need refactoring def setConceptDescription(self): """This method retrieves information about concept, formats and sets it in description field. """ if not self.concept_list.selectedItems(): self.result_table.setHtml("") return concept = self.concept_list.selectedItems()[0].data(Qt.UserRole)[0] subcategory = self.concept_list.selectedItems()[0].data(Qt.UserRole)[1] description = subcategory.description # HTML is used for a better information formating text = "<b>Concept:</b> {}<p>".format(concept.name) text += "<b>Subcategory:</b> {}<p>".format(subcategory.subcategory) text += "<b>Synonyms:</b> {}<p>".format(concept.synonyms) text += "<ol>" for des in description: text += "<li> {}".format("<b>Description:</b> <br>") text += " {} <p>".format(des.text) text += "<ol>" text += "<b>References: </b>" for ref in des.reference: text += "<li>" text += "{}".format(getBibRenderFromHTML(ref.text)) text += "</li>" text += "</ol>" text += "</li>" text += "</ol>" self.result_table.setHtml(text) def setResult(self, result, list): """This is a universal method for showing information in a relation field or in a concept field. """ list.clear() for concept, subcategory, *other in result: item = QListWidgetItem() item.setData(Qt.UserRole, (concept, subcategory, *other)) item.setText("{}{} {}".format(concept.name, "" if subcategory.subcategory == "" else ", ", subcategory.subcategory)) list.insertItem(0, item) def search(self): subcategory, selected_items = self.getSearchData() result = self.db.search_nodes(subcategory, selected_items) self.setResult([], self.relation_list) self.setResult(result, self.concept_list) self.setResult([], self.relation_list) self.setRelationDescription() def configWidgets(self): self.grid.setAlignment(Qt.AlignTop) self.grid.setSpacing(5) self.menu_bar = QMenuBar(self) self.database_menu = self.menu_bar.addMenu("Database") self.database_menu.addAction(self.new_db_action) self.database_menu.addSeparator() self.database_menu.addAction(self.exit_action) self.concept_menu = self.menu_bar.addMenu("Concept") self.concept_menu.addAction(self.edit_concept_action) self.concept_menu.addAction(self.delete_сoncept_action) self.concept_menu.addAction(self.delete_subcategory_action) self.relation_menu = self.menu_bar.addMenu("Relation") self.relation_menu.addAction(self.edit_relation_action) self.relation_menu.addAction(self.delete_relation_action) self.help_menu = self.menu_bar.addMenu("Help") self.help_menu.addAction(self.help_action) self.help_menu.addAction(self.about_action) self.grid.setMenuBar(self.menu_bar) self.concept_box = QGroupBox("Concepts") self.concept_grid = QGridLayout() self.concept_grid.setContentsMargins(0, 10, 0, 0) self.concept_grid.addWidget(self.concept_list) self.concept_box.setLayout(self.concept_grid) self.relation_box = QGroupBox("Relations") self.relation_grid = QGridLayout() self.relation_grid.setContentsMargins(0, 10, 0, 0) self.relation_grid.addWidget(self.relation_list) self.relation_box.setLayout(self.relation_grid) self.description_box = QGroupBox("Description") self.description_grid = QGridLayout() self.description_grid.setContentsMargins(0, 10, 0, 0) self.description_grid.addWidget(self.result_table) self.description_box.setLayout(self.description_grid) self.concept_splitter = QSplitter(self) self.concept_splitter.addWidget(self.concept_box) self.concept_splitter.addWidget(self.relation_box) self.description_splitter = QSplitter(self) self.description_splitter.setOrientation(Qt.Vertical) self.description_splitter.addWidget(self.concept_splitter) self.description_splitter.addWidget(self.description_box) self.grid.addWidget(self.add_data_button, 1, 0, Qt.AlignLeft) self.grid.addWidget(self.export_button, 1, 1, Qt.AlignRight) self.grid.addWidget(self.search_box, 2, 0, 1, 2) self.grid.addWidget(self.description_splitter, 5, 0, 1, 2) self.setLayout(self.grid) def bindWidgets(self): self.add_data_button.clicked.connect(self.addData) self.search_button.clicked.connect(self.search) self.export_button.clicked.connect(self.exportReferences) self.search_line.returnPressed.connect(self.search) def exportReferences(self): references = self.db.get_all_references() references = [getPlainText(ref.text) for ref in references] references = list(set(references)) references = [prepareBibStr(ref) for ref in references] final_text = ",\n\n".join(references) dlg = QFileDialog() file_path = dlg.getSaveFileName(self, "Save bibtex file")[0] if not (file_path == ""): # todo: check readBibsFromFile try: with open(file_path, 'w') as f: f.write(final_text) except Exception as error: showError(error) def addData(self): dlg = NewDataDialog(self.db) dlg.exec_() self.search() def getPath(self): dialog = NewDBDialog() if dialog.exec_(): path = dialog.path with open("setting.py", "w") as f: f.write("{{ 'last': r'{0}' }}".format(path)) return path else: self.close() def openDatabase(self): if os.path.exists("setting.py"): with open("setting.py") as f: setting = eval(f.read()) if "last" in setting: if os.path.exists(setting["last"]): path = setting["last"] else: path = self.getPath() else: path = self.getPath() else: path = self.getPath() if path is None: self.close() exit(0) else: return Graph(path) def closeEvent(self, event): event.ignore()
class MainWindow(QWidget): """Main window class that provides logic of the program. Allows to search concept and to show information about concepts and relations """ def __init__(self, application): super().__init__() self.application = application self.db = self.openDatabase() self._initUI() def initActions(self): """initalization of actions for main windows""" self.help_action = QAction("&Help", self) self.help_action.setShortcut("F1") self.help_action.setStatusTip('Help') self.help_action.triggered.connect(lambda: HelpDialog(self)) self.new_db_action = QAction("New DB", self) self.new_db_action.setShortcut("Ctrl+N") self.new_db_action.triggered.connect(self.openNewDB) self.delete_сoncept_action = QAction("&Delete", self) self.delete_сoncept_action.setShortcut("DEL") self.delete_сoncept_action.setStatusTip("Delete") self.delete_сoncept_action.triggered.connect(lambda: self.delete(Concept)) self.delete_subcategory_action = QAction("&Delete subcategory", self) self.delete_subcategory_action.triggered.connect(lambda: self.delete(Subcategory)) self.edit_concept_action = QAction("&Edit", self) self.edit_concept_action.setShortcut("F2") self.edit_concept_action.triggered.connect(self.editConcept) self.edit_relation_action = QAction("&Edit", self) self.edit_relation_action.setShortcut("Ctrl+F2") self.edit_relation_action.triggered.connect(self.editRelation) self.exit_action = QAction("&Exit", self) self.exit_action.setShortcut("ESC") self.exit_action.triggered.connect(self.close) self.select_relation_action = QAction("&Select relation", self) self.select_relation_action.triggered.connect(self.setRelationDescription) self.delete_relation_action = QAction("&Delete", self) self.delete_relation_action.setShortcut("Ctrl+DEL") self.delete_relation_action.triggered.connect(lambda: self.delete(Relation)) def openNewDB(self): """This method deletes setting.py file and closes current application session. This uses for creating a new instance of Main Window. """ if os.path.exists("setting.py"): os.remove("setting.py") self.application.exit(1) def _initUI(self): self.setWindowIcon(QIcon("logo.png")) self.setWindowTitle('GraphNotes') self.resize(1000, 700) self.initActions() self.add_data_button = QPushButton("Add data", self) self.search_box = QGroupBox() self._initSearchFrame(self.search_box) self.concept_list = QListWidget(self) self.relation_list = QListWidget(self) self.result_table = QTextEdit(self) self.concept_list.itemClicked.connect(self.searchRelations) self.concept_list.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.concept_list.setContextMenuPolicy(Qt.CustomContextMenu) self.concept_list.customContextMenuRequested.connect(self._showConceptContextMenu) self.relation_list.setContextMenuPolicy(Qt.CustomContextMenu) self.relation_list.customContextMenuRequested.connect(self._showRelationContextMenu) self.relation_list.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.relation_list.itemClicked.connect(self.setRelationDescription) self.grid = QGridLayout() self.result_table.setReadOnly(True) self.search() self._configWidgets() self._bindWidgets() self.show() def _showConceptContextMenu(self, pos): global_position = self.concept_list.mapToGlobal(pos) my_menu = QMenu() my_menu.addAction(self.edit_concept_action) my_menu.addAction(self.delete_сoncept_action) my_menu.addAction(self.delete_subcategory_action) my_menu.addSeparator() my_menu.addAction(self.help_action) my_menu.addAction(self.exit_action) my_menu.exec(global_position) def _initSearchFrame(self, frame): self.search_line = QLineEdit(frame) checkboxes = QGroupBox() checkboxes.setStyleSheet("border:0;") self.concept_checkbox = QCheckBox("Concept", checkboxes) self.description_checkbox = QCheckBox("Description", checkboxes) self.study_checkbox = QCheckBox("Study", checkboxes) self.search_button = QPushButton("Search", checkboxes) checkboxes_layout = QGridLayout(checkboxes) checkboxes_layout.addWidget(self.concept_checkbox, 0, 0) checkboxes_layout.addWidget(self.description_checkbox, 0, 1) checkboxes_layout.addWidget(self.study_checkbox, 0, 2) checkboxes_layout.setContentsMargins(0, 0, 0, 0) self.concept_checkbox.setChecked(True) grid = QGridLayout(frame) grid.addWidget(self.search_line, 1, 0) grid.addWidget(self.search_button, 1, 1) grid.addWidget(checkboxes, 2, 0, Qt.AlignLeft) frame.setLayout(grid) def getSearchData(self): """This method reads parameters of search line and checkboxes, and returns "Subcategory" class. None and [] uses for showing checkboxes that have been checked. """ concept = self.search_line.text() if self.concept_checkbox.isChecked() else None description = [Description(text=self.search_line.text())] if self.description_checkbox.isChecked() else [] study = self.search_line.text() if self.study_checkbox.isChecked() else None return Subcategory(subcategory=concept, description=description, study=study) def searchRelations(self): """This method triggers when the user clicked on the concept. This method selected ID of a subcategory from selected item in conceptions list and then searches and setting all information about this selected concept. """ subcategory_id = self.concept_list.selectedItems()[0].data(Qt.UserRole)[1].id self.setConceptDescription() result = self.db.search_relation(subcategory_id) self.setResult(result, self.relation_list) def _showRelationContextMenu(self, pos): global_position = self.relation_list.mapToGlobal(pos) my_menu = QMenu() my_menu.addAction(self.edit_relation_action) my_menu.addAction(self.delete_relation_action) my_menu.addSeparator() my_menu.exec(global_position) def editRelation(self): """This method opens dialog for editing Relation""" if self.relation_list.currentIndex().isValid(): relation = self.relation_list.selectedItems()[0].data(Qt.UserRole)[2] dlg = EditRelationDialog(self, relation) if dlg.exec_(): relation = dlg.getValue() self.db.update_relation(relation) self.select_relation_action.trigger() def editConcept(self): """This method opens dialog for editing Concept""" if self.concept_list.currentIndex().isValid(): concept = self.concept_list.selectedItems()[0].data(Qt.UserRole)[0] subcategory = self.concept_list.selectedItems()[0].data(Qt.UserRole)[1] dlg = EditConceptDialog(self, concept, subcategory) if dlg.exec_(): concept, subcategory = dlg.getValue() self.db.update_concept(concept) self.db.update_subcategory(subcategory) self.search() def delete(self, something): """This universal method for deleting something from the list and database. "something" parameter needs to be any of this types: Concept, Subcategory, Relation """ if something == Concept: number = 0 target_list = self.concept_list elif something == Subcategory: number = 1 target_list = self.concept_list elif something == Relation: number = 2 target_list = self.relation_list if target_list.currentIndex().isValid(): something = target_list.selectedItems()[0].data(Qt.UserRole)[number] self.db.delete(something) self.search() def setRelationDescription(self): """This method retrieves information about relation, formats and sets it in description field. """ if self.relation_list.currentIndex().isValid(): relation = self.relation_list.selectedItems()[0].data(Qt.UserRole)[2] concept1 = "{}{}".format(relation.node1.concept.name, ", {}".format(relation.node1.subcategory) if relation.node1.subcategory else "") concept2 = "{}{}".format(relation.node2.concept.name, ", {}".format(relation.node2.subcategory) if relation.node2.subcategory else "") description = relation.description study = relation.study references = relation.reference # HTML is used for a better information formating text = "<b>Relation between </b> \"{}\" <b>and</b> \"{}\"<p>".format(concept1, concept2) text += r"<b>Description:</b>" + "<br> {} <p>".format(description) text += r"<b>Study:</b> {} <p>".format(study) text += r"<b>References:</b><ol>" for ref in references: text += " <li> {} </li>".format(ref.text) text += "</ol><br>" self.result_table.setText(text) else: self.result_table.clear() def setConceptDescription(self): """This method retrieves information about concept, formats and sets it in description field. """ concept = self.concept_list.selectedItems()[0].data(Qt.UserRole)[0] subcategory = self.concept_list.selectedItems()[0].data(Qt.UserRole)[1] description = subcategory.description # HTML is used for a better information formating text = "<b>Concept:</b> {}<p>".format(concept.name) text += "<b>Subcategory:</b> {}<p>".format(subcategory.subcategory) text += "<b>Synonyms:</b> {}<p>".format(concept.synonyms) text += "<ol>" for des in description: text += "<li> {}".format("<b>Description:</b> <br>") text += " {} <p>".format(des.text) text += "<ol>" text += "<b>References: </b>" for ref in des.reference: text += "<li>" text += "{}".format(ref.text) text += "</li>" text += "</ol>" text += "</li>" text += "</ol>" self.result_table.setText(text) def setResult(self, result, list): """This is a universal method for showing information in a relation field or in a concept field. """ list.clear() for concept, subcategory, *other in result: item = QListWidgetItem() item.setData(Qt.UserRole, (concept, subcategory, *other)) item.setText("{}{} {}".format(concept.name, "" if subcategory.subcategory == "" else ", ", subcategory.subcategory)) list.insertItem(0, item) def search(self): parameters = self.getSearchData() result = self.db.search_nodes(parameters) self.setResult([], self.relation_list) self.setResult(result, self.concept_list) self.setResult([], self.relation_list) self.setRelationDescription() def _configWidgets(self): self.grid.setAlignment(Qt.AlignTop) self.grid.setSpacing(5) self.menu_bar = QMenuBar(self) self.database_menu = self.menu_bar.addMenu("Database") self.database_menu.addAction(self.new_db_action) self.database_menu.addSeparator() self.database_menu.addAction(self.exit_action) self.concept_menu = self.menu_bar.addMenu("Concept") self.concept_menu.addAction(self.edit_concept_action) self.concept_menu.addAction(self.delete_сoncept_action) self.concept_menu.addAction(self.delete_subcategory_action) self.relation_menu = self.menu_bar.addMenu("Relation") self.relation_menu.addAction(self.edit_relation_action) self.relation_menu.addAction(self.delete_relation_action) self.help_menu = self.menu_bar.addMenu("Help") self.help_menu.addAction(self.help_action) self.grid.setMenuBar(self.menu_bar) self.concept_box = QGroupBox("Concepts") self.concept_grid = QGridLayout() self.concept_grid.setContentsMargins(0, 10, 0, 0) self.concept_grid.addWidget(self.concept_list) self.concept_box.setLayout(self.concept_grid) self.relation_box = QGroupBox("Relations") self.relation_grid = QGridLayout() self.relation_grid.setContentsMargins(0, 10, 0, 0) self.relation_grid.addWidget(self.relation_list) self.relation_box.setLayout(self.relation_grid) self.description_box = QGroupBox("Description") self.description_grid = QGridLayout() self.description_grid.setContentsMargins(0, 10, 0, 0) self.description_grid.addWidget(self.result_table) self.description_box.setLayout(self.description_grid) self.concept_splitter = QSplitter(self) self.concept_splitter.addWidget(self.concept_box) self.concept_splitter.addWidget(self.relation_box) self.description_splitter = QSplitter(self) self.description_splitter.setOrientation(Qt.Vertical) self.description_splitter.addWidget(self.concept_splitter) self.description_splitter.addWidget(self.description_box) self.grid.addWidget(self.add_data_button, 1, 0, Qt.AlignLeft) self.grid.addWidget(self.search_box, 2, 0, 1, 2) self.grid.addWidget(self.description_splitter, 5, 0, 1, 2) self.setLayout(self.grid) def _bindWidgets(self): self.add_data_button.clicked.connect(self.addData) self.search_button.clicked.connect(self.search) self.search_line.returnPressed.connect(self.search) def addData(self): dlg = NewDataDialog(self.db) dlg.exec_() self.search() def getPath(self): dialog = NewDBDialog() if dialog.exec_(): print("EXEc") path = dialog.path with open("setting.py", "w") as f: f.write("{{ 'last': r'{0}' }}".format(path)) return path else: self.close() def openDatabase(self): if os.path.exists("setting.py"): with open("setting.py") as f: setting = eval(f.read()) if "last" in setting: if os.path.exists(setting["last"]): path = setting["last"] else: path = self.getPath() else: path = self.getPath() else: path = self.getPath() if path is None: self.close() exit(0) else: return Graph(path)
class MainWin(QMainWindow): def __init__(self, fileName=None, logName=None, parent=None): super(MainWin, self).__init__(parent) #self.setWindowIcon(QIcon(':/images/logo.png')) self.setToolButtonStyle(Qt.ToolButtonFollowStyle) self.setupFileActions() self.setupEditActions() self.setupTextActions() self.setupRunActions() self.initializeSettings() self.populateRunSettings() # FIXME put in initializeSettings()? settingsMenu = QMenu('Settings', self) self.menuBar().addMenu(settingsMenu) settingsMenu.addAction('Configure...', self.configure) helpMenu = QMenu("Help", self) self.menuBar().addMenu(helpMenu) helpMenu.addAction("About", self.about) helpMenu.addAction("About &Qt", QApplication.instance().aboutQt) self.splitter = QSplitter(self) self.splitter.setOrientation(Qt.Vertical) self.textPane = TextPane() self.logPane = LogPane() self.logBox = QGroupBox() self.logBox.setFlat(True) vbox = QVBoxLayout() vbox.addWidget(self.logPane) self.logBox.setLayout(vbox) self.splitter.addWidget(self.textPane) self.splitter.addWidget(QLabel()) # spacer self.splitter.addWidget(self.logBox) self.setCentralWidget(self.splitter) self.loadSrc(fileName) self.loadLog(logName) #if logName and (-1 == self.comboLogFile.findText(logName)): #self.comboLogFile.addItem(logName) self.logPane.setFocus() self.fontChanged(self.textPane.font()) self.textPane.document().modificationChanged.connect(self.actionSave.setEnabled) self.textPane.document().modificationChanged.connect(self.setWindowModified) self.textPane.document().undoAvailable.connect(self.actionUndo.setEnabled) self.textPane.document().redoAvailable.connect( self.actionRedo.setEnabled) self.setWindowModified(self.textPane.document().isModified()) self.actionSave.setEnabled(self.textPane.document().isModified()) self.actionUndo.setEnabled(self.textPane.document().isUndoAvailable()) self.actionRedo.setEnabled(self.textPane.document().isRedoAvailable()) self.actionUndo.triggered.connect(self.textPane.undo) self.actionRedo.triggered.connect(self.textPane.redo) self.actionCut.setEnabled(False) self.actionCopy.setEnabled(False) self.actionCut.triggered.connect(self.textPane.cut) self.actionCopy.triggered.connect(self.textPane.copy) self.actionPaste.triggered.connect(self.textPane.paste) self.textPane.copyAvailable.connect(self.actionCut.setEnabled) self.textPane.copyAvailable.connect(self.actionCopy.setEnabled) QApplication.clipboard().dataChanged.connect(self.clipboardDataChanged) self.actionRun.triggered.connect(self.scannoCheck) self.logPane.lineMatchChanged.connect(self.logLineMatchChanged) def closeEvent(self, e): if self.maybeSave(): e.accept() else: e.ignore() def setupFileActions(self): tb = QToolBar(self) tb.setWindowTitle("File Actions") self.addToolBar(tb) menu = QMenu("&File", self) self.menuBar().addMenu(menu) self.actionNew = QAction("&New", self, priority=QAction.LowPriority, shortcut=QKeySequence.New, triggered=self.fileNew) tb.addAction(self.actionNew) menu.addAction(self.actionNew) self.actionOpen = QAction("&Open...", self, shortcut=QKeySequence.Open, triggered=self.fileOpen) tb.addAction(self.actionOpen) menu.addAction(self.actionOpen) menu.addSeparator() self.actionSave = QAction("&Save", self, shortcut=QKeySequence.Save, triggered=self.fileSave, enabled=False) tb.addAction(self.actionSave) menu.addAction(self.actionSave) self.actionSaveAs = QAction("Save &As...", self, priority=QAction.LowPriority, shortcut=Qt.CTRL + Qt.SHIFT + Qt.Key_S, triggered=self.fileSaveAs) menu.addAction(self.actionSaveAs) menu.addSeparator() self.actionQuit = QAction("&Quit", self, shortcut=QKeySequence.Quit, triggered=self.close) menu.addAction(self.actionQuit) def setupEditActions(self): tb = QToolBar(self) tb.setWindowTitle("Edit Actions") self.addToolBar(tb) menu = QMenu("&Edit", self) self.menuBar().addMenu(menu) self.actionUndo = QAction("&Undo", self, shortcut=QKeySequence.Undo) tb.addAction(self.actionUndo) menu.addAction(self.actionUndo) self.actionRedo = QAction("&Redo", self, priority=QAction.LowPriority, shortcut=QKeySequence.Redo) tb.addAction(self.actionRedo) menu.addAction(self.actionRedo) menu.addSeparator() self.actionCut = QAction("Cu&t", self, priority=QAction.LowPriority, shortcut=QKeySequence.Cut) tb.addAction(self.actionCut) menu.addAction(self.actionCut) self.actionCopy = QAction("&Copy", self, priority=QAction.LowPriority, shortcut=QKeySequence.Copy) tb.addAction(self.actionCopy) menu.addAction(self.actionCopy) self.actionPaste = QAction("&Paste", self, priority=QAction.LowPriority, shortcut=QKeySequence.Paste, enabled=(len(QApplication.clipboard().text()) != 0)) tb.addAction(self.actionPaste) menu.addAction(self.actionPaste) def setupTextActions(self): tb = QToolBar(self) tb.setWindowTitle("Format Actions") self.addToolBar(tb) tb = QToolBar(self) tb.setAllowedAreas(Qt.TopToolBarArea | Qt.BottomToolBarArea) tb.setWindowTitle("Format Actions") self.addToolBarBreak(Qt.TopToolBarArea) self.addToolBar(tb) self.comboFont = QFontComboBox(tb) tb.addWidget(self.comboFont) self.comboFont.activated[str].connect(self.textFamily) self.comboSize = QComboBox(tb) self.comboSize.setObjectName("comboSize") tb.addWidget(self.comboSize) self.comboSize.setEditable(True) db = QFontDatabase() for size in db.standardSizes(): self.comboSize.addItem('{}'.format(size)) self.comboSize.activated[str].connect(self.textSize) self.comboSize.setCurrentIndex(self.comboSize.findText('{}'.format(QApplication.font().pointSize()))) def setupRunActions(self): tb = QToolBar(self) tb.setWindowTitle("Run Actions") self.addToolBar(tb) menu = QMenu("Run", self) self.menuBar().addMenu(menu) self.actionRun = QAction( "&Run", self, shortcut=Qt.CTRL + Qt.Key_R) tb.addAction(self.actionRun) menu.addAction(self.actionRun) self.comboScannoFile = QComboBox(tb) self.comboScannoFile.setObjectName("comboScannoFile") tb.addWidget(self.comboScannoFile) self.comboScannoFile.setEditable(True) self.comboLogFile= QComboBox(tb) self.comboLogFile.setObjectName("comboLogFile") self.comboLogFile.setEditable(True) tb.addWidget(self.comboLogFile) def populateRunSettings(self): for f in self.scannoFiles(): self.comboScannoFile.addItem(f) if self.defaultScannoFile: idx = self.comboScannoFile.findText(self.defaultScannoFile) self.comboScannoFile.setCurrentIndex(idx) self.comboLogFile.addItem('plog.txt') def loadSrc(self, src): if src: if not self.textPane.load(src): return False self.setCurrentFileName(src) return True def loadLog(self, log): if log: if not self.logPane.load(log): return False self.comboLogFile.clear() self.comboLogFile.addItem(log) else: self.logPane.clear() self.logPane.setEnabled(False) self.logBox.setTitle(self.tr('No log file loaded.')) return True def maybeSave(self): if not self.textPane.document().isModified(): return True ret = QMessageBox.warning(self, 'GuiScannos', 'The document has been modified.\n' 'Do you want to save your changes?', QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) if ret == QMessageBox.Save: return self.fileSave() if ret == QMessageBox.Cancel: return False return True def setCurrentFileName(self, fileName=''): self.fileName = fileName self.textPane.document().setModified(False) if not fileName: shownName = 'untitled.txt' self.actionRun.setEnabled(False) else: shownName = QFileInfo(fileName).fileName() self.actionRun.setEnabled(True) self.setWindowTitle(self.tr('{}[*] - {}'.format(shownName, 'GUI Scannos'))) self.setWindowModified(False) def fileNew(self): if self.maybeSave(): self.textPane.clear() self.loadLog(None) # clears logPane, logBox title, etc self.setCurrentFileName() def fileOpen(self): fn, _ = QFileDialog.getOpenFileName(self, 'Open File...', None, 'Text Files (*.txt);;All Files (*)') if fn: self.loadSrc(fn) self.loadLog(None) # clears logPane, logBox title, etc def fileSave(self): if not self.fileName: return self.fileSaveAs() return self.textpane.save(self.fileName) def fileSaveAs(self): fn, _ = QFileDialog.getSaveFileName(self, "Save as...", None, "text files (*.txt);;All Files (*)") if not fn: return False self.setCurrentFileName(fn) return self.fileSave() def logLineMatchChanged(self): linenum = self.logPane.srcLineNum() col = self.logPane.srcColNum() s = self.logPane.srcScanno() self.textPane.setSelection(linenum, col, len(s)) def textFamily(self, family): """Set font family for text and log panes.""" self.textPane.setFontFamily(family) self.logPane.setFontFamily(family) def textSize(self, pointSize): """Set font size for text and log panes.""" self.textPane.setFontPointSize(pointSize) self.logPane.setFontPointSize(pointSize) def clipboardDataChanged(self): self.actionPaste.setEnabled(len(QApplication.clipboard().text()) != 0) def about(self): QMessageBox.about(self, 'About', 'GUI for ppscannos.') def fontChanged(self, font): self.comboFont.setCurrentIndex(self.comboFont.findText(QFontInfo(font).family())) self.comboSize.setCurrentIndex(self.comboSize.findText('{}'.format(font.pointSize()))) def scannoCheck(self): """Run ppscannos.""" scannodir = os.path.dirname(self.ppscannos) cmd = sys.executable assert(cmd) scannoFile = self.comboScannoFile.currentText() if not scannoFile: scannoFile = self.defaultScannoFile scannoFile = scannodir + '/' + scannoFile src = self.fileName log = self.comboLogFile.currentText() if not log: log = './plog.txt' subprocess.call([cmd, self.ppscannos, '-s' + scannoFile, '-o' + log, '-i' + src]) self.loadLog(log) self.logPane.setEnabled(True) def configure(self): """Configure application settings by way of a dialog.""" dlg = ConfigDialog() if dlg.exec(): self.setPPScannos(dlg.lineEditPPScannos.text()) self.setDefaultScannoFile(dlg.comboScannoFiles.currentText()) settings = QSettings(QApplication.organizationName(), QApplication.applicationName()) settings.setValue('ppscannos', self.ppscannos) settings.setValue('defaultScannoFile', self.defaultScannoFile) def setPPScannos(self, s): self.ppscannos = s self.actionRun.setEnabled(self.ppscannos and os.path.exists(self.ppscannos)) def scannoFiles(self): """Return list of .rc filenames (without path) that are in ppscannos directory.""" if not self.ppscannos: return [] return getRCFilesForDir(os.path.dirname(self.ppscannos)) def setDefaultScannoFile(self, s): self.defaultScannoFile = s valid = False if self.defaultScannoFile and self.ppscannos and os.path.exists(self.ppscannos): if os.path.exists(os.path.dirname(self.ppscannos) + '/' + self.defaultScannoFile): valid = True self.actionRun.setEnabled(valid) def initializeSettings(self): """Load persistent config settings.""" settings = QSettings() s = settings.value('ppscannos', type=str) if not s: # try the default s = os.path.expanduser('~') + '/ppscannos1/ppscannos1.py' #s = os.environ['HOME'] + '/ppscannos1/ppscannos1.py' self.setPPScannos(s) s = settings.value('defaultScannoFile', type=str) if (not s) and self.ppscannos: # try the default lst = getRCFilesForDir(os.path.dirname(self.ppscannos)) if len(lst): # prefer 'regex.rc'; otherwise use the first one s = lst[0] for f in lst: if f == 'regex.rc': s = f break self.setDefaultScannoFile(s)