def keyPressEvent(self, event): text, key = event.text(), event.key() alt = event.modifiers() & Qt.AltModifier shift = event.modifiers() & Qt.ShiftModifier ctrl = event.modifiers() & Qt.ControlModifier modifier = shift or ctrl or alt if (key in (Qt.Key_Return, Qt.Key_Enter) and self.enter_select) \ or key == Qt.Key_Tab: self.item_selected() elif key in (Qt.Key_Return, Qt.Key_Enter, Qt.Key_Left, Qt.Key_Right) or text in ('.', ':'): self.hide() self.textedit.keyPressEvent(event) elif key in (Qt.Key_Up, Qt.Key_Down, Qt.Key_PageUp, Qt.Key_PageDown, Qt.Key_Home, Qt.Key_End, Qt.Key_CapsLock) and not modifier: QListWidget.keyPressEvent(self, event) elif len(text) or key == Qt.Key_Backspace: self.textedit.keyPressEvent(event) self.update_current() elif modifier: self.textedit.keyPressEvent(event) else: self.hide() QListWidget.keyPressEvent(self, event)
def __init__(self, parent, ancestor): QListWidget.__init__(self, ancestor) self.setWindowFlags(Qt.SubWindow | Qt.FramelessWindowHint) self.textedit = parent self.completion_list = None self.case_sensitive = False self.enter_select = None self.hide() self.connect(self, SIGNAL("itemActivated(QListWidgetItem*)"), self.item_selected)
def __init__(self, parent=None): QDialog.__init__(self, parent) self.main = parent # Widgets self.pages_widget = QStackedWidget() self.contents_widget = QListWidget() self.button_reset = QPushButton(_('Reset to defaults')) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) # Widgets setup # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowTitle(_('Preferences')) self.setWindowIcon(ima.icon('configure')) self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) self.contents_widget.setCurrentRow(0) # Layout hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) btnlayout = QHBoxLayout() btnlayout.addWidget(self.button_reset) btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) # Signals and slots self.button_reset.clicked.connect(self.main.reset_spyder) self.pages_widget.currentChanged.connect(self.current_page_changed) self.contents_widget.currentRowChanged.connect( self.pages_widget.setCurrentIndex) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) bbox.clicked.connect(self.button_clicked) # Ensures that the config is present on spyder first run CONF.set('main', 'interface_language', load_lang_conf())
def __init__(self, parent=None, pathlist=None, ro_pathlist=None, sync=True): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) assert isinstance(pathlist, list) self.pathlist = pathlist if ro_pathlist is None: ro_pathlist = [] self.ro_pathlist = ro_pathlist self.last_path = getcwd() self.setWindowTitle(_("PYTHONPATH manager")) self.setWindowIcon(ima.icon('pythonpath')) self.resize(500, 300) self.selection_widgets = [] layout = QVBoxLayout() self.setLayout(layout) top_layout = QHBoxLayout() layout.addLayout(top_layout) self.toolbar_widgets1 = self.setup_top_toolbar(top_layout) self.listwidget = QListWidget(self) self.listwidget.currentRowChanged.connect(self.refresh) layout.addWidget(self.listwidget) bottom_layout = QHBoxLayout() layout.addLayout(bottom_layout) self.sync_button = None self.toolbar_widgets2 = self.setup_bottom_toolbar(bottom_layout, sync) # Buttons configuration bbox = QDialogButtonBox(QDialogButtonBox.Close) bbox.rejected.connect(self.reject) bottom_layout.addWidget(bbox) self.update_list() self.refresh()
def __init__(self, parent=None): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.contents_widget = QListWidget() self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()")) self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()")) self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"), self.button_clicked) self.pages_widget = QStackedWidget() self.connect(self.pages_widget, SIGNAL("currentChanged(int)"), self.current_page_changed) self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"), self.pages_widget.setCurrentIndex) self.contents_widget.setCurrentRow(0) hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) btnlayout = QHBoxLayout() btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) self.setWindowTitle(_("Preferences")) self.setWindowIcon(get_icon("configure.png"))
def __init__(self, parent=None, pathlist=None, ro_pathlist=None, sync=True): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) assert isinstance(pathlist, list) self.pathlist = pathlist if ro_pathlist is None: ro_pathlist = [] self.ro_pathlist = ro_pathlist self.last_path = getcwd() self.setWindowTitle(_("PYTHONPATH manager")) self.setWindowIcon(get_icon('pythonpath.png')) self.resize(500, 300) self.selection_widgets = [] layout = QVBoxLayout() self.setLayout(layout) top_layout = QHBoxLayout() layout.addLayout(top_layout) self.toolbar_widgets1 = self.setup_top_toolbar(top_layout) self.listwidget = QListWidget(self) self.connect(self.listwidget, SIGNAL("currentRowChanged(int)"), self.refresh) layout.addWidget(self.listwidget) bottom_layout = QHBoxLayout() layout.addLayout(bottom_layout) self.sync_button = None self.toolbar_widgets2 = self.setup_bottom_toolbar(bottom_layout, sync) # Buttons configuration bbox = QDialogButtonBox(QDialogButtonBox.Close) self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()")) bottom_layout.addWidget(bbox) self.update_list() self.refresh()
def __init__(self, parent=None): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.contents_widget = QListWidget() self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) bbox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Apply |QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()")) self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()")) self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"), self.button_clicked) self.pages_widget = QStackedWidget() self.connect(self.pages_widget, SIGNAL("currentChanged(int)"), self.current_page_changed) self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"), self.pages_widget.setCurrentIndex) self.contents_widget.setCurrentRow(0) hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) btnlayout = QHBoxLayout() btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) self.setWindowTitle(_("Preferences")) self.setWindowIcon(get_icon("configure.png"))
def hide(self): QListWidget.hide(self) self.textedit.setFocus()
class ConfigDialog(QDialog): """Spyder configuration ('Preferences') dialog box""" # Signals check_settings = Signal() size_change = Signal(QSize) def __init__(self, parent=None): QDialog.__init__(self, parent) self.main = parent # Widgets self.pages_widget = QStackedWidget() self.contents_widget = QListWidget() self.button_reset = QPushButton(_('Reset to defaults')) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) # Widgets setup # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowTitle(_('Preferences')) self.setWindowIcon(ima.icon('configure')) self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) self.contents_widget.setCurrentRow(0) # Layout hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) btnlayout = QHBoxLayout() btnlayout.addWidget(self.button_reset) btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) # Signals and slots self.button_reset.clicked.connect(self.main.reset_spyder) self.pages_widget.currentChanged.connect(self.current_page_changed) self.contents_widget.currentRowChanged.connect( self.pages_widget.setCurrentIndex) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) bbox.clicked.connect(self.button_clicked) # Ensures that the config is present on spyder first run CONF.set('main', 'interface_language', load_lang_conf()) def get_current_index(self): """Return current page index""" return self.contents_widget.currentRow() def set_current_index(self, index): """Set current page index""" self.contents_widget.setCurrentRow(index) def get_page(self, index=None): """Return page widget""" if index is None: widget = self.pages_widget.currentWidget() else: widget = self.pages_widget.widget(index) return widget.widget() @Slot() def accept(self): """Reimplement Qt method""" for index in range(self.pages_widget.count()): configpage = self.get_page(index) if not configpage.is_valid(): return configpage.apply_changes() QDialog.accept(self) def button_clicked(self, button): if button is self.apply_btn: # Apply button was clicked configpage = self.get_page() if not configpage.is_valid(): return configpage.apply_changes() def current_page_changed(self, index): widget = self.get_page(index) self.apply_btn.setVisible(widget.apply_callback is not None) self.apply_btn.setEnabled(widget.is_modified) def add_page(self, widget): self.check_settings.connect(widget.check_settings) widget.show_this_page.connect(lambda row=self.contents_widget.count(): self.contents_widget.setCurrentRow(row)) widget.apply_button_enabled.connect(self.apply_btn.setEnabled) scrollarea = QScrollArea(self) scrollarea.setWidgetResizable(True) scrollarea.setWidget(widget) self.pages_widget.addWidget(scrollarea) item = QListWidgetItem(self.contents_widget) item.setIcon(widget.get_icon()) item.setText(widget.get_name()) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) item.setSizeHint(QSize(0, 25)) def check_all_settings(self): """This method is called to check all configuration page settings after configuration dialog has been shown""" self.check_settings.emit() def resizeEvent(self, event): """ Reimplement Qt method to be able to save the widget's size from the main application """ QDialog.resizeEvent(self, event) self.size_change.emit(self.size())
def __init__(self, parent, tabs, data): QDialog.__init__(self, parent) # Variables self.tabs = tabs # Editor stack tabs self.data = data # Editor data self.mode = self.FILE_MODE # By default start in this mode self.initial_cursors = None # {fullpath: QCursor} self.initial_path = None # Fullpath of initial active editor self.initial_editor = None # Initial active editor self.line_number = None # Selected line number in filer help_text = _("Press <b>Enter</b> to switch files or <b>Esc</b> to " "cancel.<br><br>Type to filter filenames.<br><br>" "Use <b>:number</b> to go to a line, e.g. " "<b><code>main:42</code></b><br>" "Use <b>@symbol_text</b> to go to a symbol, e.g. " "<b><code>@init</code></b>" "<br><br> Press <b>Ctrl+W</b> to close current tab.<br>") # Either allow searching for a line number or a symbol but not both regex = QRegExp("([A-Za-z0-9_]{0,100}@[A-Za-z0-9_]{0,100})|" + "([A-Za-z]{0,100}:{0,1}[0-9]{0,100})") # Widgets self.edit = QLineEdit(self) self.help = HelperToolButton() self.list = QListWidget(self) self.filter = KeyPressFilter() regex_validator = QRegExpValidator(regex, self.edit) # Widgets setup self.setWindowFlags(Qt.Popup | Qt.FramelessWindowHint) self.setWindowOpacity(0.95) self.edit.installEventFilter(self.filter) self.edit.setValidator(regex_validator) self.help.setToolTip(help_text) self.list.setItemDelegate(HTMLDelegate(self)) # Layout edit_layout = QHBoxLayout() edit_layout.addWidget(self.edit) edit_layout.addWidget(self.help) layout = QVBoxLayout() layout.addLayout(edit_layout) layout.addWidget(self.list) self.setLayout(layout) # Signals self.rejected.connect(self.restore_initial_state) self.filter.sig_up_key_pressed.connect(self.previous_row) self.filter.sig_down_key_pressed.connect(self.next_row) self.edit.returnPressed.connect(self.accept) self.edit.textChanged.connect(self.setup) self.list.itemSelectionChanged.connect(self.item_selection_changed) self.list.clicked.connect(self.edit.setFocus) # Setup self.save_initial_state() self.set_dialog_position() self.setup()
class FileSwitcher(QDialog): """A Sublime-like file switcher.""" sig_goto_file = Signal(int) sig_close_file = Signal(int) # Constants that define the mode in which the list widget is working # FILE_MODE is for a list of files, SYMBOL_MODE if for a list of symbols # in a given file when using the '@' symbol. FILE_MODE, SYMBOL_MODE = [1, 2] def __init__(self, parent, tabs, data): QDialog.__init__(self, parent) # Variables self.tabs = tabs # Editor stack tabs self.data = data # Editor data self.mode = self.FILE_MODE # By default start in this mode self.initial_cursors = None # {fullpath: QCursor} self.initial_path = None # Fullpath of initial active editor self.initial_editor = None # Initial active editor self.line_number = None # Selected line number in filer help_text = _("Press <b>Enter</b> to switch files or <b>Esc</b> to " "cancel.<br><br>Type to filter filenames.<br><br>" "Use <b>:number</b> to go to a line, e.g. " "<b><code>main:42</code></b><br>" "Use <b>@symbol_text</b> to go to a symbol, e.g. " "<b><code>@init</code></b>" "<br><br> Press <b>Ctrl+W</b> to close current tab.<br>") # Either allow searching for a line number or a symbol but not both regex = QRegExp("([A-Za-z0-9_]{0,100}@[A-Za-z0-9_]{0,100})|" + "([A-Za-z]{0,100}:{0,1}[0-9]{0,100})") # Widgets self.edit = QLineEdit(self) self.help = HelperToolButton() self.list = QListWidget(self) self.filter = KeyPressFilter() regex_validator = QRegExpValidator(regex, self.edit) # Widgets setup self.setWindowFlags(Qt.Popup | Qt.FramelessWindowHint) self.setWindowOpacity(0.95) self.edit.installEventFilter(self.filter) self.edit.setValidator(regex_validator) self.help.setToolTip(help_text) self.list.setItemDelegate(HTMLDelegate(self)) # Layout edit_layout = QHBoxLayout() edit_layout.addWidget(self.edit) edit_layout.addWidget(self.help) layout = QVBoxLayout() layout.addLayout(edit_layout) layout.addWidget(self.list) self.setLayout(layout) # Signals self.rejected.connect(self.restore_initial_state) self.filter.sig_up_key_pressed.connect(self.previous_row) self.filter.sig_down_key_pressed.connect(self.next_row) self.edit.returnPressed.connect(self.accept) self.edit.textChanged.connect(self.setup) self.list.itemSelectionChanged.connect(self.item_selection_changed) self.list.clicked.connect(self.edit.setFocus) # Setup self.save_initial_state() self.set_dialog_position() self.setup() # --- Properties @property def editors(self): return [self.tabs.widget(index) for index in range(self.tabs.count())] @property def line_count(self): return [editor.get_line_count() for editor in self.editors] @property def save_status(self): return [getattr(td, 'newly_created', False) for td in self.data] @property def paths(self): return [getattr(td, 'filename', None) for td in self.data] @property def filenames(self): return [self.tabs.tabText(index) for index in range(self.tabs.count())] @property def current_path(self): return self.paths_by_editor[self.get_editor()] @property def paths_by_editor(self): return dict(zip(self.editors, self.paths)) @property def editors_by_path(self): return dict(zip(self.paths, self.editors)) @property def filter_text(self): """Get the normalized (lowecase) content of the filter text.""" return to_text_string(self.edit.text()).lower() def save_initial_state(self): """Saves initial cursors and initial active editor.""" paths = self.paths self.initial_editor = self.get_editor() self.initial_cursors = {} for i, editor in enumerate(self.editors): if editor is self.initial_editor: self.initial_path = paths[i] self.initial_cursors[paths[i]] = editor.textCursor() def accept(self): QDialog.accept(self) self.list.clear() def restore_initial_state(self): """Restores initial cursors and initial active editor.""" self.list.clear() editors = self.editors_by_path for path in self.initial_cursors: cursor = self.initial_cursors[path] if path in editors: self.set_editor_cursor(editors[path], cursor) if self.initial_editor in self.paths_by_editor: index = self.paths.index(self.initial_path) self.sig_goto_file.emit(index) def set_dialog_position(self): """Positions the file switcher dialog in the center of the editor.""" parent = self.parent() geo = parent.geometry() width = self.list.width() # This has been set in setup left = parent.geometry().width() / 2 - width / 2 top = 0 while parent: geo = parent.geometry() top += geo.top() left += geo.left() parent = parent.parent() # Note: the +1 pixel on the top makes it look better self.move(left, top + self.tabs.tabBar().geometry().height() + 1) def fix_size(self, content, extra=50): """Adjusts the width of the file switcher, based on the content.""" # Update size of dialog based on longest shortened path strings = [] if content: for rich_text in content: label = QLabel(rich_text) label.setTextFormat(Qt.PlainText) strings.append(label.text()) fm = label.fontMetrics() max_width = max([fm.width(s) * 1.3 for s in strings]) self.list.setMinimumWidth(max_width + extra) self.set_dialog_position() # --- Helper methods: List widget def count(self): """Gets the item count in the list widget.""" return self.list.count() def current_row(self): """Returns the current selected row in the list widget.""" return self.list.currentRow() def set_current_row(self, row): """Sets the current selected row in the list widget.""" return self.list.setCurrentRow(row) def select_row(self, steps): """Select row in list widget based on a number of steps with direction. Steps can be positive (next rows) or negative (previous rows). """ row = self.current_row() + steps if 0 <= row < self.count(): self.set_current_row(row) def previous_row(self): """Select previous row in list widget.""" self.select_row(-1) def next_row(self): """Select next row in list widget.""" self.select_row(+1) # --- Helper methods: Editor def get_editor(self, index=None, path=None): """Get editor by index or path. If no path or index specified the current active editor is returned """ if index: return self.tabs.widget(index) elif path: return self.tabs.widget(index) else: return self.parent().get_current_editor() def set_editor_cursor(self, editor, cursor): """Set the cursor of an editor.""" pos = cursor.position() anchor = cursor.anchor() new_cursor = QTextCursor() if pos == anchor: new_cursor.movePosition(pos) else: new_cursor.movePosition(anchor) new_cursor.movePosition(pos, QTextCursor.KeepAnchor) editor.setTextCursor(cursor) def goto_line(self, line_number): """Go to specified line number in current active editor.""" if line_number: line_number = int(line_number) editor = self.get_editor() editor.go_to_line(min(line_number, editor.get_line_count())) # --- Helper methods: Outline explorer def get_symbol_list(self): """Get the object explorer data.""" return self.get_editor().highlighter.get_outlineexplorer_data() # --- Handlers def item_selection_changed(self): """List widget item selection change handler.""" row = self.current_row() if self.count() and row >= 0: if self.mode == self.FILE_MODE: try: stack_index = self.paths.index(self.filtered_path[row]) self.sig_goto_file.emit(stack_index) self.goto_line(self.line_number) self.edit.setFocus() except ValueError: pass else: line_number = self.filtered_symbol_lines[row] self.goto_line(line_number) def setup_file_list(self, filter_text, current_path): """Setup list widget content for file list display.""" short_paths = shorten_paths(self.paths, self.save_status) paths = self.paths results = [] trying_for_line_number = ':' in filter_text # Get optional line number if trying_for_line_number: filter_text, line_number = filter_text.split(':') else: line_number = None # Get all available filenames and get the scores for "fuzzy" matching scores = get_search_scores(filter_text, self.filenames, template="<b>{0}</b>") # Build the text that will appear on the list widget for index, score in enumerate(scores): text, rich_text, score_value = score if score_value != -1: text_item = '<big>' + rich_text + '</big>' if trying_for_line_number: text_item += " [{0:} {1:}]".format(self.line_count[index], _("lines")) text_item += "<br><i>{0:}</i>".format(short_paths[index]) results.append((score_value, index, text_item)) # Sort the obtained scores and populate the list widget self.filtered_path = [] for result in sorted(results): index = result[1] text = result[-1] path = paths[index] item = QListWidgetItem(self.tabs.tabIcon(index), text) item.setToolTip(path) item.setSizeHint(QSize(0, 25)) self.list.addItem(item) self.filtered_path.append(path) # Move selected item in list accordingly and update list size if current_path in self.filtered_path: self.set_current_row(self.filtered_path.index(current_path)) elif self.filtered_path: self.set_current_row(0) self.fix_size(short_paths) # If a line number is searched look for it self.line_number = line_number self.goto_line(line_number) def setup_symbol_list(self, filter_text, current_path): """Setup list widget content for symbol list display.""" # Get optional symbol name filter_text, symbol_text = filter_text.split('@') # Fetch the Outline explorer data, get the icons and values oedata = self.get_symbol_list() icons = get_python_symbol_icons(oedata) symbol_list = process_python_symbol_data(oedata) line_fold_token = [(item[0], item[2], item[3]) for item in symbol_list] choices = [item[1] for item in symbol_list] scores = get_search_scores(symbol_text, choices, template="<b>{0}</b>") # Build the text that will appear on the list widget results = [] lines = [] self.filtered_symbol_lines = [] for index, score in enumerate(scores): text, rich_text, score_value = score line, fold_level, token = line_fold_token[index] lines.append(text) if score_value != -1: results.append((score_value, line, text, rich_text, fold_level, icons[index], token)) template_1 = '<code>{0}<big>{1} {2}</big></code>' template_2 = '<br><code>{0}</code><i>[Line {1}]</i>' for (score, line, text, rich_text, fold_level, icon, token) in sorted(results): fold_space = ' ' * (fold_level) line_number = line + 1 self.filtered_symbol_lines.append(line_number) textline = template_1.format(fold_space, token, rich_text) textline += template_2.format(fold_space, line_number) item = QListWidgetItem(icon, textline) item.setSizeHint(QSize(0, 16)) self.list.addItem(item) # Move selected item in list accordingly # NOTE: Doing this is causing two problems: # 1. It makes the cursor to auto-jump to the last selected # symbol after opening or closing a different file # 2. It moves the cursor to the first symbol by default, # which is very distracting. # That's why this line is commented! # self.set_current_row(0) # Update list size self.fix_size(lines, extra=125) def setup(self): """Setup list widget content.""" if not self.tabs.count(): self.close() return self.list.clear() current_path = self.current_path filter_text = self.filter_text # Get optional line or symbol to define mode and method handler trying_for_symbol = ('@' in self.filter_text) if trying_for_symbol: self.mode = self.SYMBOL_MODE self.setup_symbol_list(filter_text, current_path) else: self.mode = self.FILE_MODE self.setup_file_list(filter_text, current_path)
class FileSwitcher(QDialog): """A Sublime-like file switcher.""" sig_goto_file = Signal(int) sig_close_file = Signal(int) # Constants that define the mode in which the list widget is working # FILE_MODE is for a list of files, SYMBOL_MODE if for a list of symbols # in a given file when using the '@' symbol. FILE_MODE, SYMBOL_MODE = [1, 2] def __init__(self, parent, tabs, data): QDialog.__init__(self, parent) # Variables self.tabs = tabs # Editor stack tabs self.data = data # Editor data self.mode = self.FILE_MODE # By default start in this mode self.initial_cursors = None # {fullpath: QCursor} self.initial_path = None # Fullpath of initial active editor self.initial_editor = None # Initial active editor self.line_number = None # Selected line number in filer help_text = _("Press <b>Enter</b> to switch files or <b>Esc</b> to " "cancel.<br><br>Type to filter filenames.<br><br>" "Use <b>:number</b> to go to a line, e.g. " "<b><code>main:42</code></b><br>" "Use <b>@symbol_text</b> to go to a symbol, e.g. " "<b><code>@init</code></b>" "<br><br> Press <b>Ctrl+W</b> to close current tab.<br>") # Either allow searching for a line number or a symbol but not both regex = QRegExp("([A-Za-z0-9_]{0,100}@[A-Za-z0-9_]{0,100})|" + "([A-Za-z]{0,100}:{0,1}[0-9]{0,100})") # Widgets self.edit = QLineEdit(self) self.help = HelperToolButton() self.list = QListWidget(self) self.filter = KeyPressFilter() regex_validator = QRegExpValidator(regex, self.edit) # Widgets setup self.setWindowFlags(Qt.Popup | Qt.FramelessWindowHint) self.setWindowOpacity(0.95) self.edit.installEventFilter(self.filter) self.edit.setValidator(regex_validator) self.help.setToolTip(help_text) self.list.setItemDelegate(HTMLDelegate(self)) # Layout edit_layout = QHBoxLayout() edit_layout.addWidget(self.edit) edit_layout.addWidget(self.help) layout = QVBoxLayout() layout.addLayout(edit_layout) layout.addWidget(self.list) self.setLayout(layout) # Signals self.rejected.connect(self.restore_initial_state) self.filter.sig_up_key_pressed.connect(self.previous_row) self.filter.sig_down_key_pressed.connect(self.next_row) self.edit.returnPressed.connect(self.accept) self.edit.textChanged.connect(self.setup) self.list.itemSelectionChanged.connect(self.item_selection_changed) self.list.clicked.connect(self.edit.setFocus) # Setup self.save_initial_state() self.set_dialog_position() self.setup() # --- Properties @property def editors(self): return [self.tabs.widget(index) for index in range(self.tabs.count())] @property def line_count(self): return [editor.get_line_count() for editor in self.editors] @property def save_status(self): return [getattr(td, 'newly_created', False) for td in self.data] @property def paths(self): return [getattr(td, 'filename', None) for td in self.data] @property def filenames(self): return [self.tabs.tabText(index) for index in range(self.tabs.count())] @property def current_path(self): return self.paths_by_editor[self.get_editor()] @property def paths_by_editor(self): return dict(zip(self.editors, self.paths)) @property def editors_by_path(self): return dict(zip(self.paths, self.editors)) @property def filter_text(self): """Get the normalized (lowecase) content of the filter text.""" return to_text_string(self.edit.text()).lower() def save_initial_state(self): """Saves initial cursors and initial active editor.""" paths = self.paths self.initial_editor = self.get_editor() self.initial_cursors = {} for i, editor in enumerate(self.editors): if editor is self.initial_editor: self.initial_path = paths[i] self.initial_cursors[paths[i]] = editor.textCursor() def restore_initial_state(self): """Restores initial cursors and initial active editor.""" editors = self.editors_by_path for path in self.initial_cursors: cursor = self.initial_cursors[path] if path in editors: self.set_editor_cursor(editors[path], cursor) if self.initial_editor in self.paths_by_editor: index = self.paths.index(self.initial_path) self.sig_goto_file.emit(index) def set_dialog_position(self): """Positions the file switcher dialog in the center of the editor.""" parent = self.parent() geo = parent.geometry() width = self.list.width() # This has been set in setup left = parent.geometry().width()/2 - width/2 top = 0 while parent: geo = parent.geometry() top += geo.top() left += geo.left() parent = parent.parent() # Note: the +1 pixel on the top makes it look better self.move(left, top + self.tabs.tabBar().geometry().height() + 1) def fix_size(self, content, extra=50): """Adjusts the width of the file switcher, based on the content.""" # Update size of dialog based on longest shortened path strings = [] if content: for rich_text in content: label = QLabel(rich_text) label.setTextFormat(Qt.PlainText) strings.append(label.text()) fm = label.fontMetrics() max_width = max([fm.width(s)*1.3 for s in strings]) self.list.setMinimumWidth(max_width + extra) self.set_dialog_position() # --- Helper methods: List widget def count(self): """Gets the item count in the list widget.""" return self.list.count() def current_row(self): """Returns the current selected row in the list widget.""" return self.list.currentRow() def set_current_row(self, row): """Sets the current selected row in the list widget.""" return self.list.setCurrentRow(row) def select_row(self, steps): """Select row in list widget based on a number of steps with direction. Steps can be positive (next rows) or negative (previous rows). """ row = self.current_row() + steps if 0 <= row < self.count(): self.set_current_row(row) def previous_row(self): """Select previous row in list widget.""" self.select_row(-1) def next_row(self): """Select next row in list widget.""" self.select_row(+1) # --- Helper methods: Editor def get_editor(self, index=None, path=None): """Get editor by index or path. If no path or index specified the current active editor is returned """ if index: return self.tabs.widget(index) elif path: return self.tabs.widget(index) else: return self.parent().get_current_editor() def set_editor_cursor(self, editor, cursor): """Set the cursor of an editor.""" pos = cursor.position() anchor = cursor.anchor() new_cursor = QTextCursor() if pos == anchor: new_cursor.movePosition(pos) else: new_cursor.movePosition(anchor) new_cursor.movePosition(pos, QTextCursor.KeepAnchor) editor.setTextCursor(cursor) def goto_line(self, line_number): """Go to specified line number in current active editor.""" if line_number: line_number = int(line_number) editor = self.get_editor() editor.go_to_line(min(line_number, editor.get_line_count())) # --- Helper methods: Outline explorer def get_symbol_list(self): """Get the object explorer data.""" return self.get_editor().highlighter.get_outlineexplorer_data() # --- Handlers def item_selection_changed(self): """List widget item selection change handler.""" row = self.current_row() if self.count() and row >= 0: if self.mode == self.FILE_MODE: try: stack_index = self.paths.index(self.filtered_path[row]) self.sig_goto_file.emit(stack_index) self.goto_line(self.line_number) self.edit.setFocus() except ValueError: pass else: line_number = self.filtered_symbol_lines[row] self.goto_line(line_number) def setup_file_list(self, filter_text, current_path): """Setup list widget content for file list display.""" short_paths = shorten_paths(self.paths, self.save_status) paths = self.paths results = [] trying_for_line_number = ':' in filter_text # Get optional line number if trying_for_line_number: filter_text, line_number = filter_text.split(':') else: line_number = None # Get all available filenames and get the scores for "fuzzy" matching scores = get_search_scores(filter_text, self.filenames, template="<b>{0}</b>") # Build the text that will appear on the list widget for index, score in enumerate(scores): text, rich_text, score_value = score if score_value != -1: text_item = '<big>' + rich_text + '</big>' if trying_for_line_number: text_item += " [{0:} {1:}]".format(self.line_count[index], _("lines")) text_item += "<br><i>{0:}</i>".format( short_paths[index]) results.append((score_value, index, text_item)) # Sort the obtained scores and populate the list widget self.filtered_path = [] for result in sorted(results): index = result[1] text = result[-1] path = paths[index] item = QListWidgetItem(self.tabs.tabIcon(index), text) item.setToolTip(path) item.setSizeHint(QSize(0, 25)) self.list.addItem(item) self.filtered_path.append(path) # Move selected item in list accordingly and update list size if current_path in self.filtered_path: self.set_current_row(self.filtered_path.index(current_path)) elif self.filtered_path: self.set_current_row(0) self.fix_size(short_paths) # If a line number is searched look for it self.line_number = line_number self.goto_line(line_number) def setup_symbol_list(self, filter_text, current_path): """Setup list widget content for symbol list display.""" # Get optional symbol name filter_text, symbol_text = filter_text.split('@') # Fetch the Outline explorer data, get the icons and values oedata = self.get_symbol_list() icons = get_python_symbol_icons(oedata) symbol_list = process_python_symbol_data(oedata) line_fold_token = [(item[0], item[2], item[3]) for item in symbol_list] choices = [item[1] for item in symbol_list] scores = get_search_scores(symbol_text, choices, template="<b>{0}</b>") # Build the text that will appear on the list widget results = [] lines = [] self.filtered_symbol_lines = [] for index, score in enumerate(scores): text, rich_text, score_value = score line, fold_level, token = line_fold_token[index] lines.append(text) if score_value != -1: results.append((score_value, line, text, rich_text, fold_level, icons[index], token)) template_1 = '<code>{0}<big>{1} {2}</big></code>' template_2 = '<br><code>{0}</code><i>[Line {1}]</i>' for (score, line, text, rich_text, fold_level, icon, token) in sorted(results): fold_space = ' '*(fold_level) line_number = line + 1 self.filtered_symbol_lines.append(line_number) textline = template_1.format(fold_space, token, rich_text) textline += template_2.format(fold_space, line_number) item = QListWidgetItem(icon, textline) item.setSizeHint(QSize(0, 16)) self.list.addItem(item) # Move selected item in list accordingly and update list size self.set_current_row(0) self.fix_size(lines, extra=125) def setup(self): """Setup list widget content.""" if not self.tabs.count(): self.close() return self.list.clear() current_path = self.current_path filter_text = self.filter_text # Get optional line or symbol to define mode and method handler trying_for_symbol = ('@' in self.filter_text) if trying_for_symbol: self.mode = self.SYMBOL_MODE self.setup_symbol_list(filter_text, current_path) else: self.mode = self.FILE_MODE self.setup_file_list(filter_text, current_path)
class PathManager(QDialog): redirect_stdio = Signal(bool) def __init__(self, parent=None, pathlist=None, ro_pathlist=None, sync=True): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) assert isinstance(pathlist, list) self.pathlist = pathlist if ro_pathlist is None: ro_pathlist = [] self.ro_pathlist = ro_pathlist self.last_path = getcwd() self.setWindowTitle(_("PYTHONPATH manager")) self.setWindowIcon(get_icon('pythonpath.png')) self.resize(500, 300) self.selection_widgets = [] layout = QVBoxLayout() self.setLayout(layout) top_layout = QHBoxLayout() layout.addLayout(top_layout) self.toolbar_widgets1 = self.setup_top_toolbar(top_layout) self.listwidget = QListWidget(self) self.listwidget.currentRowChanged.connect(self.refresh) layout.addWidget(self.listwidget) bottom_layout = QHBoxLayout() layout.addLayout(bottom_layout) self.sync_button = None self.toolbar_widgets2 = self.setup_bottom_toolbar(bottom_layout, sync) # Buttons configuration bbox = QDialogButtonBox(QDialogButtonBox.Close) bbox.rejected.connect(self.reject) bottom_layout.addWidget(bbox) self.update_list() self.refresh() def _add_widgets_to_layout(self, layout, widgets): layout.setAlignment(Qt.AlignLeft) for widget in widgets: layout.addWidget(widget) def setup_top_toolbar(self, layout): toolbar = [] movetop_button = create_toolbutton(self, text=_("Move to top"), icon=get_icon('2uparrow.png'), triggered=lambda: self.move_to(absolute=0), text_beside_icon=True) toolbar.append(movetop_button) moveup_button = create_toolbutton(self, text=_("Move up"), icon=get_icon('1uparrow.png'), triggered=lambda: self.move_to(relative=-1), text_beside_icon=True) toolbar.append(moveup_button) movedown_button = create_toolbutton(self, text=_("Move down"), icon=get_icon('1downarrow.png'), triggered=lambda: self.move_to(relative=1), text_beside_icon=True) toolbar.append(movedown_button) movebottom_button = create_toolbutton(self, text=_("Move to bottom"), icon=get_icon('2downarrow.png'), triggered=lambda: self.move_to(absolute=1), text_beside_icon=True) toolbar.append(movebottom_button) self.selection_widgets.extend(toolbar) self._add_widgets_to_layout(layout, toolbar) return toolbar def setup_bottom_toolbar(self, layout, sync=True): toolbar = [] add_button = create_toolbutton(self, text=_("Add path"), icon=get_icon('edit_add.png'), triggered=self.add_path, text_beside_icon=True) toolbar.append(add_button) remove_button = create_toolbutton(self, text=_("Remove path"), icon=get_icon('edit_remove.png'), triggered=self.remove_path, text_beside_icon=True) toolbar.append(remove_button) self.selection_widgets.append(remove_button) self._add_widgets_to_layout(layout, toolbar) layout.addStretch(1) if os.name == 'nt' and sync: self.sync_button = create_toolbutton(self, text=_("Synchronize..."), icon=get_icon('synchronize.png'), triggered=self.synchronize, tip=_("Synchronize Spyder's path list with PYTHONPATH " "environment variable"), text_beside_icon=True) layout.addWidget(self.sync_button) return toolbar @Slot() def synchronize(self): """ Synchronize Spyder's path list with PYTHONPATH environment variable Only apply to: current user, on Windows platforms """ answer = QMessageBox.question(self, _("Synchronize"), _("This will synchronize Spyder's path list with " "<b>PYTHONPATH</b> environment variable for current user, " "allowing you to run your Python modules outside Spyder " "without having to configure sys.path. " "<br>Do you want to clear contents of PYTHONPATH before " "adding Spyder's path list?"), QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) if answer == QMessageBox.Cancel: return elif answer == QMessageBox.Yes: remove = True else: remove = False from spyderlib.utils.environ import (get_user_env, set_user_env, listdict2envdict) env = get_user_env() if remove: ppath = self.pathlist+self.ro_pathlist else: ppath = env.get('PYTHONPATH', []) if not isinstance(ppath, list): ppath = [ppath] ppath = [path for path in ppath if path not in (self.pathlist+self.ro_pathlist)] ppath.extend(self.pathlist+self.ro_pathlist) env['PYTHONPATH'] = ppath set_user_env( listdict2envdict(env), parent=self ) def get_path_list(self): """Return path list (does not include the read-only path list)""" return self.pathlist def update_list(self): """Update path list""" self.listwidget.clear() for name in self.pathlist+self.ro_pathlist: item = QListWidgetItem(name) item.setIcon(get_std_icon('DirClosedIcon')) if name in self.ro_pathlist: item.setFlags(Qt.NoItemFlags) self.listwidget.addItem(item) self.refresh() def refresh(self, row=None): """Refresh widget""" for widget in self.selection_widgets: widget.setEnabled(self.listwidget.currentItem() is not None) not_empty = self.listwidget.count() > 0 if self.sync_button is not None: self.sync_button.setEnabled(not_empty) def move_to(self, absolute=None, relative=None): index = self.listwidget.currentRow() if absolute is not None: if absolute: new_index = len(self.pathlist)-1 else: new_index = 0 else: new_index = index + relative new_index = max(0, min(len(self.pathlist)-1, new_index)) path = self.pathlist.pop(index) self.pathlist.insert(new_index, path) self.update_list() self.listwidget.setCurrentRow(new_index) @Slot() def remove_path(self): answer = QMessageBox.warning(self, _("Remove path"), _("Do you really want to remove selected path?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: self.pathlist.pop(self.listwidget.currentRow()) self.update_list() @Slot() def add_path(self): self.redirect_stdio.emit(False) directory = getexistingdirectory(self, _("Select directory"), self.last_path) self.redirect_stdio.emit(True) if directory: directory = osp.abspath(directory) self.last_path = directory if directory in self.pathlist: answer = QMessageBox.question(self, _("Add path"), _("This directory is already included in Spyder path " "list.<br>Do you want to move it to the top of " "the list?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: self.pathlist.remove(directory) else: return self.pathlist.insert(0, directory) self.update_list()
def __init__(self, parent, max_entries=100): """ Creates a very basic window with some text """ """ RATE_LAW_MESSAGE = \ "The Plugins for Spyder consists out of three main classes: \n\n" \ "1. HelloWorld\n\n" \ "\tThe HelloWorld class inherits all its methods from\n" \ "\tSpyderPluginMixin and the HelloWorldWidget and performs all\n" \ "\tthe processing required by the GU. \n\n" \ "2. HelloWorldConfigPage\n\n" \ "\tThe HelloWorldConfig class inherits all its methods from\n" \ "\tPluginConfigPage to create a configuration page that can be\n" \ "\tfound under Tools -> Preferences\n\n" \ "3. HelloWorldWidget\n\n" \ "\tThe HelloWorldWidget class inherits all its methods from\n" \ "\tQWidget to create the actual plugin GUI interface that \n" \ "\tdisplays this message on screen\n\n" """ #Testing access editor on plugin initialization RATE_LAW_MESSAGE = "" displaynamelist = [] #displaylist = [] infixlist = [] desclist = [] parameterstringlist = [] xmldoc = minidom.parse('\\.spyder2\\ratelaw2_0_3.xml') #xmldoc = minidom.parse('%\\Downloads\\ratelaw2_0_3.xml') lawlistxml = xmldoc.getElementsByTagName('law') #i is the number of laws currently in the xml file i = 0 """ Parsing xml: Acquiring rate law name, description, and list of parameter information """ for s in lawlistxml: #RATE_LAW_MESSAGE += s.getAttribute('displayName') + "\n" RATE_LAW_MESSAGE += s.getAttribute('display') + "\n" #displaynamelist[i] = s.getAttribute('displayName') #displaylist[i] = s.getAttribute('display') displaynamelist.append(s.getAttribute('displayName')) #displaylist.append(s.getAttribute('display')) infixlist.append(s.getAttribute('infixExpression')) desclist.append(s.getAttribute('description')) parameterlist = s.getElementsByTagName('listOfParameters')[0] #for p in parameterlist parameters = parameterlist.getElementsByTagName('parameter') parameterstring = "" for param in parameters: parametername = param.attributes['name'].value parameterdesc = param.attributes['description'].value parameterstring = parameterstring + '\t' + parametername + ":" + '\t' + " " + parameterdesc + "\n" """Creates "description" string""" #print('\t' + parametername + ":" + '\t' + parameterdesc) parameterstringlist.append(parameterstring) i = i + 1 QWidget.__init__(self, parent) self.setWindowTitle("Rate Law Library") self.output = None self.error_output = None self._last_wdir = None self._last_args = None self._last_pythonpath = None self.textlabel = QLabel(RATE_LAW_MESSAGE) self.lawlist = QListWidget() self.lawpage = QStackedWidget() #Adding displayName items to lawlist for j in range(i): item = QListWidgetItem(displaynamelist[j]) """Creates list entry for each rate law""" self.lawlist.addItem(item) """Adds rate law to list""" self.lawdetailpage = QWidget() """Creates page for each rate law""" # Page layout will become its own function setup_group = QGroupBox(displaynamelist[j]) """Creates box with rate law name as title""" infixmod = infixlist[j].replace("___"," ") setup_label = QLabel(infixmod) setup_label.setWordWrap(True) """types rate law expression, removing underscores""" desc_group = QGroupBox("Description") """creates box for description""" desc_label = QLabel(desclist[j]) desc_label.setWordWrap(True) param_label = QLabel(parameterstringlist[j]) param_label.setWordWrap(True) # Warning: do not try to regroup the following QLabel contents with # widgets above -- this string was isolated here in a single QLabel # on purpose: to fix Issue 863 setup_layout = QVBoxLayout() setup_layout.addWidget(setup_label) setup_group.setLayout(setup_layout) desc_layout = QVBoxLayout() desc_layout.addWidget(desc_label) desc_layout.addWidget(param_label) desc_group.setLayout(desc_layout) vlayout = QVBoxLayout() vlayout.addWidget(setup_group) vlayout.addWidget(desc_group) vlayout.addStretch(1) self.lawdetailpage.setLayout(vlayout) self.lawpage.addWidget(self.lawdetailpage) """Formats the page shown when a rate law is selected""" #self.connect(self.lawlist, SIGNAL(self.lawlist.currentRowChanged(int)),self.lawpage,SLOT(self.lawpage.setCurrentIndex(int))) self.lawlist.currentRowChanged.connect(self.lawpage.setCurrentIndex) """When a rate law in the list is clicked, its corresponding page is shown""" ''' self.lawpage = QWidget() ''' self.lawlist.setCurrentRow(0) hsplitter = QSplitter() hsplitter.addWidget(self.lawlist) "Adds list to left side of window" hlayout1 = QHBoxLayout() hlayout1.addWidget(self.textlabel) hlayout1.addStretch() self.lawpage.setLayout(hlayout1) hsplitter.addWidget(self.lawpage) """Adds law page to left side of window""" layout = QVBoxLayout() layout.addWidget(hsplitter) self.setLayout(layout)
class PathManager(QDialog): def __init__(self, parent=None, pathlist=None, ro_pathlist=None, sync=True): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) assert isinstance(pathlist, list) self.pathlist = pathlist if ro_pathlist is None: ro_pathlist = [] self.ro_pathlist = ro_pathlist self.last_path = getcwd() self.setWindowTitle(_("PYTHONPATH manager")) self.setWindowIcon(get_icon('pythonpath.png')) self.resize(500, 300) self.selection_widgets = [] layout = QVBoxLayout() self.setLayout(layout) top_layout = QHBoxLayout() layout.addLayout(top_layout) self.toolbar_widgets1 = self.setup_top_toolbar(top_layout) self.listwidget = QListWidget(self) self.connect(self.listwidget, SIGNAL("currentRowChanged(int)"), self.refresh) layout.addWidget(self.listwidget) bottom_layout = QHBoxLayout() layout.addLayout(bottom_layout) self.sync_button = None self.toolbar_widgets2 = self.setup_bottom_toolbar(bottom_layout, sync) # Buttons configuration bbox = QDialogButtonBox(QDialogButtonBox.Close) self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()")) bottom_layout.addWidget(bbox) self.update_list() self.refresh() def _add_widgets_to_layout(self, layout, widgets): layout.setAlignment(Qt.AlignLeft) for widget in widgets: layout.addWidget(widget) def setup_top_toolbar(self, layout): toolbar = [] movetop_button = create_toolbutton(self, text=_("Move to top"), icon=get_icon('2uparrow.png'), triggered=lambda: self.move_to(absolute=0), text_beside_icon=True) toolbar.append(movetop_button) moveup_button = create_toolbutton(self, text=_("Move up"), icon=get_icon('1uparrow.png'), triggered=lambda: self.move_to(relative=-1), text_beside_icon=True) toolbar.append(moveup_button) movedown_button = create_toolbutton(self, text=_("Move down"), icon=get_icon('1downarrow.png'), triggered=lambda: self.move_to(relative=1), text_beside_icon=True) toolbar.append(movedown_button) movebottom_button = create_toolbutton(self, text=_("Move to bottom"), icon=get_icon('2downarrow.png'), triggered=lambda: self.move_to(absolute=1), text_beside_icon=True) toolbar.append(movebottom_button) self.selection_widgets.extend(toolbar) self._add_widgets_to_layout(layout, toolbar) return toolbar def setup_bottom_toolbar(self, layout, sync=True): toolbar = [] add_button = create_toolbutton(self, text=_("Add path"), icon=get_icon('edit_add.png'), triggered=self.add_path, text_beside_icon=True) toolbar.append(add_button) remove_button = create_toolbutton(self, text=_("Remove path"), icon=get_icon('edit_remove.png'), triggered=self.remove_path, text_beside_icon=True) toolbar.append(remove_button) self.selection_widgets.append(remove_button) self._add_widgets_to_layout(layout, toolbar) layout.addStretch(1) if os.name == 'nt' and sync: self.sync_button = create_toolbutton(self, text=_("Synchronize..."), icon=get_icon('synchronize.png'), triggered=self.synchronize, tip=_("Synchronize Spyder's path list with PYTHONPATH " "environment variable"), text_beside_icon=True) layout.addWidget(self.sync_button) return toolbar def synchronize(self): """ Synchronize Spyder's path list with PYTHONPATH environment variable Only apply to: current user, on Windows platforms """ answer = QMessageBox.question(self, _("Synchronize"), _("This will synchronize Spyder's path list with " "<b>PYTHONPATH</b> environment variable for current user, " "allowing you to run your Python modules outside Spyder " "without having to configure sys.path. " "<br>Do you want to clear contents of PYTHONPATH before " "adding Spyder's path list?"), QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) if answer == QMessageBox.Cancel: return elif answer == QMessageBox.Yes: remove = True else: remove = False from spyderlib.utils.environ import (get_user_env, set_user_env, listdict2envdict) env = get_user_env() if remove: ppath = self.pathlist+self.ro_pathlist else: ppath = env.get('PYTHONPATH', []) if not isinstance(ppath, list): ppath = [ppath] ppath = [path for path in ppath if path not in (self.pathlist+self.ro_pathlist)] ppath.extend(self.pathlist+self.ro_pathlist) env['PYTHONPATH'] = ppath set_user_env( listdict2envdict(env), parent=self ) def get_path_list(self): """Return path list (does not include the read-only path list)""" return self.pathlist def update_list(self): """Update path list""" self.listwidget.clear() for name in self.pathlist+self.ro_pathlist: item = QListWidgetItem(name) item.setIcon(get_std_icon('DirClosedIcon')) if name in self.ro_pathlist: item.setFlags(Qt.NoItemFlags) self.listwidget.addItem(item) self.refresh() def refresh(self, row=None): """Refresh widget""" for widget in self.selection_widgets: widget.setEnabled(self.listwidget.currentItem() is not None) not_empty = self.listwidget.count() > 0 if self.sync_button is not None: self.sync_button.setEnabled(not_empty) def move_to(self, absolute=None, relative=None): index = self.listwidget.currentRow() if absolute is not None: if absolute: new_index = len(self.pathlist)-1 else: new_index = 0 else: new_index = index + relative new_index = max(0, min(len(self.pathlist)-1, new_index)) path = self.pathlist.pop(index) self.pathlist.insert(new_index, path) self.update_list() self.listwidget.setCurrentRow(new_index) def remove_path(self): answer = QMessageBox.warning(self, _("Remove path"), _("Do you really want to remove selected path?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: self.pathlist.pop(self.listwidget.currentRow()) self.update_list() def add_path(self): self.emit(SIGNAL('redirect_stdio(bool)'), False) directory = getexistingdirectory(self, _("Select directory"), self.last_path) self.emit(SIGNAL('redirect_stdio(bool)'), True) if directory: directory = osp.abspath(directory) self.last_path = directory if directory in self.pathlist: answer = QMessageBox.question(self, _("Add path"), _("This directory is already included in Spyder path " "list.<br>Do you want to move it to the top of " "the list?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.Yes: self.pathlist.remove(directory) else: return self.pathlist.insert(0, directory) self.update_list()
def __init__(self, parent, max_entries=100): "Initialize Various list objects before assignment" displaylist = [] displaynamelist = [] infixmod = [] infixlist = [] desclist = [] parameternamelist = [] parameterdesclist = [] parameterstringlist = [] paramcountlist = [] buttonlist = [] xmldoc = minidom.parse('C:\\Users\\Jayit\\.spyder2\\ratelaw2_0_3.xml') #xmldoc = minidom.parse('%\\Downloads\\ratelaw2_0_3.xml') lawlistxml = xmldoc.getElementsByTagName('law') o = 0 for s in lawlistxml: o = o + 1 parameternamelistlist = [0 for x in range(o)] parameterdesclistlist = [0 for x in range(o)] """i is the number of laws currently in the xml file""" i = 0 """ Parsing xml: Acquiring rate law name, description, and list of parameter information """ for s in lawlistxml: #RATE_LAW_MESSAGE += s.getAttribute('displayName') + "\n" """Gets Latec Expression""" displaylist.append(s.getAttribute('display')) """Gets Rate-Law Name""" displaynamelist.append(s.getAttribute('displayName')) """"Gets Raw Rate-Law expression""" infixlist.append(s.getAttribute('infixExpression')) """Gets description statement""" desclist.append(s.getAttribute('description')) """Gets listOfParameters Object""" parameterlist = s.getElementsByTagName('listOfParameters')[0] """Gets a list of parameters within ListOfParameters object""" parameters = parameterlist.getElementsByTagName('parameter') for param in parameters: parameternamelist.append(param.attributes['name'].value) #print(param.attributes['name'].value) parameterdesclist.append(param.attributes['description'].value) parameternamelistlist[i] = parameternamelist #print("break") parameterdesclistlist[i] = parameterdesclist parameternamelist = [] parameterdesclist = [] i = i + 1 SLElistlist = [0 for x in range(i)] PLElistlist = [0 for x in range(i)] ILElistlist = [0 for x in range(i)] paramLElistlist = [0 for x in range(i)] numlistlist = [0 for x in range(i)] QWidget.__init__(self, parent) self.setWindowTitle("Rate Law Library") self.output = None self.error_output = None self._last_wdir = None self._last_args = None self._last_pythonpath = None #self.textlabel = QLabel(RATE_LAW_MESSAGE) self.lawlist = QListWidget() self.lawpage = QStackedWidget() index = 0 for j in range(i): item = QListWidgetItem(displaynamelist[j]) self.lawlist.addItem(item) self.lawdetailpage = QWidget() setup_group = QGroupBox(displaynamelist[j]) infixmod.append(infixlist[j].replace("___", " ")) setup_label = QLabel(infixmod[j]) setup_label.setWordWrap(True) desc_group = QGroupBox("Description") desc_label = QLabel(desclist[j]) desc_label.setWordWrap(True) param_label = QGridLayout() nm = QLabel("Name:") des = QLabel("Description:") repl = QLabel("Replace with:") param_label.addWidget(nm, 0, 0) param_label.addWidget(des, 0, 1) param_label.addWidget(repl, 0, 2) """g is the total number of alterable values""" g = 0 """t is the total number of alterable non-parameters""" t = 1 snum = 0 pnum = 0 inum = 0 """range of N is the max number of possible substrates OR products""" N = 5 for n in range(N): nl = n + 1 if (infixmod[j].find('S%s' % nl) > -1): z = QLabel('S%s is present' % nl) param_label.addWidget(z, t, 0) snum = snum + 1 t = t + 1 for n in range(N): nl = n + 1 if (infixmod[j].find('P%s' % nl) > -1): z = QLabel('P%s is present' % nl) param_label.addWidget(z, t, 0) pnum = pnum + 1 t = t + 1 for n in range(N): nl = n + 1 if (infixmod[j].find('I%s' % nl) > -1): z = QLabel('I%s is present' % nl) param_label.addWidget(z, t, 0) inum = inum + 1 t = t + 1 """Initialize lists of list of parameter lineedit""" length = len(parameternamelistlist[j]) for b in range(length): p = QLabel("%s :" % parameternamelistlist[j][b]) param_label.addWidget(p, b + t, 0) d = QLabel("'%s'" % parameterdesclistlist[j][b]) param_label.addWidget(d, b + t, 1) g = t + length Slineeditlist = [0 for x in range(snum)] Plineeditlist = [0 for x in range(pnum)] Ilineeditlist = [0 for x in range(inum)] paramlineeditlist = [0 for x in range(length)] editcount = 1 """Place lineedit widgets for parameters""" for s in range(snum): Slineeditlist[s] = QLineEdit() param_label.addWidget(Slineeditlist[s], editcount, 2) editcount = editcount + 1 SLElistlist[j] = Slineeditlist for s in range(pnum): Plineeditlist[s] = QLineEdit() param_label.addWidget(Plineeditlist[s], editcount, 2) editcount = editcount + 1 PLElistlist[j] = Plineeditlist for s in range(inum): Ilineeditlist[s] = QLineEdit() param_label.addWidget(Ilineeditlist[s], editcount, 2) editcount = editcount + 1 ILElistlist[j] = Ilineeditlist for s in range(length): paramlineeditlist[s] = QLineEdit() param_label.addWidget(paramlineeditlist[s], editcount, 2) editcount = editcount + 1 paramLElistlist[j] = paramlineeditlist """Necessary lists for editable parameters. Housekeeping essentially.""" stuff = paramlineeditlist[0].text() numlistlist[j] = [snum, pnum, inum, length] charlist = ["S", "P", "I"] buttonlist.append(QPushButton(self)) buttonlist[j].setText("Insert Rate Law: %s" % displaynamelist[j]) # Warning: do not try to regroup the following QLabel contents with # widgets above -- this string was isolated here in a single QLabel # on purpose: to fix Issue 863 """Page formatting""" setup_layout = QVBoxLayout() setup_layout.addWidget(setup_label) setup_group.setLayout(setup_layout) desc_group.setLayout(param_label) vlayout = QVBoxLayout() vlayout.addWidget(setup_group) vlayout.addWidget(desc_group) vlayout.addWidget(buttonlist[j]) vlayout.addStretch(1) self.lawdetailpage.setLayout(vlayout) self.lawpage.addWidget(self.lawdetailpage) """Set up button functionality""" for k in range(47): buttonlist[k].clicked.connect( pressbutton(self, infixmod[k], SLElistlist[k], PLElistlist[k], ILElistlist[k], paramLElistlist[k], parameternamelistlist[k], numlistlist[k], charlist, k)) self.lawlist.currentRowChanged.connect(self.lawpage.setCurrentIndex) self.lawlist.setCurrentRow(0) """Set up high-level widget formatting.""" hsplitter = QSplitter() hsplitter.addWidget(self.lawlist) hsplitter.addWidget(self.lawpage) layout = QVBoxLayout() layout.addWidget(hsplitter) self.setLayout(layout)
class ConfigDialog(QDialog): """Spyder configuration ('Preferences') dialog box""" def __init__(self, parent=None): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.contents_widget = QListWidget() self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()")) self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()")) self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"), self.button_clicked) self.pages_widget = QStackedWidget() self.connect(self.pages_widget, SIGNAL("currentChanged(int)"), self.current_page_changed) self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"), self.pages_widget.setCurrentIndex) self.contents_widget.setCurrentRow(0) hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) btnlayout = QHBoxLayout() btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) self.setWindowTitle(_("Preferences")) self.setWindowIcon(get_icon("configure.png")) def get_current_index(self): """Return current page index""" return self.contents_widget.currentRow() def set_current_index(self, index): """Set current page index""" self.contents_widget.setCurrentRow(index) def get_page(self, index=None): """Return page widget""" if index is None: widget = self.pages_widget.currentWidget() else: widget = self.pages_widget.widget(index) return widget.widget() def accept(self): """Reimplement Qt method""" for index in range(self.pages_widget.count()): configpage = self.get_page(index) if not configpage.is_valid(): return configpage.apply_changes() QDialog.accept(self) def button_clicked(self, button): if button is self.apply_btn: # Apply button was clicked configpage = self.get_page() if not configpage.is_valid(): return configpage.apply_changes() def current_page_changed(self, index): widget = self.get_page(index) self.apply_btn.setVisible(widget.apply_callback is not None) self.apply_btn.setEnabled(widget.is_modified) def add_page(self, widget): self.connect(self, SIGNAL('check_settings()'), widget.check_settings) self.connect(widget, SIGNAL('show_this_page()'), lambda row=self.contents_widget.count(): self. contents_widget.setCurrentRow(row)) self.connect(widget, SIGNAL("apply_button_enabled(bool)"), self.apply_btn.setEnabled) scrollarea = QScrollArea(self) scrollarea.setWidgetResizable(True) scrollarea.setWidget(widget) self.pages_widget.addWidget(scrollarea) item = QListWidgetItem(self.contents_widget) item.setIcon(widget.get_icon()) item.setText(widget.get_name()) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) item.setSizeHint(QSize(0, 25)) def check_all_settings(self): """This method is called to check all configuration page settings after configuration dialog has been shown""" self.emit(SIGNAL('check_settings()')) def resizeEvent(self, event): """ Reimplement Qt method to be able to save the widget's size from the main application """ QDialog.resizeEvent(self, event) self.emit(SIGNAL("size_change(QSize)"), self.size())
class ConfigDialog(QDialog): """Spyder configuration ('Preferences') dialog box""" def __init__(self, parent=None): QDialog.__init__(self, parent) # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.contents_widget = QListWidget() self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) bbox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Apply |QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()")) self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()")) self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"), self.button_clicked) self.pages_widget = QStackedWidget() self.connect(self.pages_widget, SIGNAL("currentChanged(int)"), self.current_page_changed) self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"), self.pages_widget.setCurrentIndex) self.contents_widget.setCurrentRow(0) hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) btnlayout = QHBoxLayout() btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) self.setWindowTitle(_("Preferences")) self.setWindowIcon(get_icon("configure.png")) def get_current_index(self): """Return current page index""" return self.contents_widget.currentRow() def set_current_index(self, index): """Set current page index""" self.contents_widget.setCurrentRow(index) def get_page(self, index=None): """Return page widget""" if index is None: widget = self.pages_widget.currentWidget() else: widget = self.pages_widget.widget(index) return widget.widget() def accept(self): """Reimplement Qt method""" for index in range(self.pages_widget.count()): configpage = self.get_page(index) if not configpage.is_valid(): return configpage.apply_changes() QDialog.accept(self) def button_clicked(self, button): if button is self.apply_btn: # Apply button was clicked configpage = self.get_page() if not configpage.is_valid(): return configpage.apply_changes() def current_page_changed(self, index): widget = self.get_page(index) self.apply_btn.setVisible(widget.apply_callback is not None) self.apply_btn.setEnabled(widget.is_modified) def add_page(self, widget): self.connect(self, SIGNAL('check_settings()'), widget.check_settings) self.connect(widget, SIGNAL('show_this_page()'), lambda row=self.contents_widget.count(): self.contents_widget.setCurrentRow(row)) self.connect(widget, SIGNAL("apply_button_enabled(bool)"), self.apply_btn.setEnabled) scrollarea = QScrollArea(self) scrollarea.setWidgetResizable(True) scrollarea.setWidget(widget) self.pages_widget.addWidget(scrollarea) item = QListWidgetItem(self.contents_widget) item.setIcon(widget.get_icon()) item.setText(widget.get_name()) item.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled) item.setSizeHint(QSize(0, 25)) def check_all_settings(self): """This method is called to check all configuration page settings after configuration dialog has been shown""" self.emit(SIGNAL('check_settings()')) def resizeEvent(self, event): """ Reimplement Qt method to be able to save the widget's size from the main application """ QDialog.resizeEvent(self, event) self.emit(SIGNAL("size_change(QSize)"), self.size())
def __init__(self, parent, max_entries=100): """ Creates a very basic window with some text """ """ RATE_LAW_MESSAGE = \ "The Plugins for Spyder consists out of three main classes: \n\n" \ "1. HelloWorld\n\n" \ "\tThe HelloWorld class inherits all its methods from\n" \ "\tSpyderPluginMixin and the HelloWorldWidget and performs all\n" \ "\tthe processing required by the GU. \n\n" \ "2. HelloWorldConfigPage\n\n" \ "\tThe HelloWorldConfig class inherits all its methods from\n" \ "\tPluginConfigPage to create a configuration page that can be\n" \ "\tfound under Tools -> Preferences\n\n" \ "3. HelloWorldWidget\n\n" \ "\tThe HelloWorldWidget class inherits all its methods from\n" \ "\tQWidget to create the actual plugin GUI interface that \n" \ "\tdisplays this message on screen\n\n" """ #Testing access editor on plugin initialization RATE_LAW_MESSAGE = "" displaynamelist = [] #displaylist = [] infixlist = [] desclist = [] parameterstringlist = [] xmldoc = minidom.parse('\\.spyder2\\ratelaw2_0_3.xml') #xmldoc = minidom.parse('%\\Downloads\\ratelaw2_0_3.xml') lawlistxml = xmldoc.getElementsByTagName('law') #i is the number of laws currently in the xml file i = 0 for s in lawlistxml: #RATE_LAW_MESSAGE += s.getAttribute('displayName') + "\n" RATE_LAW_MESSAGE += s.getAttribute('display') + "\n" #displaynamelist[i] = s.getAttribute('displayName') #displaylist[i] = s.getAttribute('display') displaynamelist.append(s.getAttribute('displayName')) #displaylist.append(s.getAttribute('display')) infixlist.append(s.getAttribute('infixExpression')) desclist.append(s.getAttribute('description')) parameterlist = s.getElementsByTagName('listOfParameters')[0] #for p in parameterlist parameters = parameterlist.getElementsByTagName('parameter') parameterstring = "" for param in parameters: parametername = param.attributes['name'].value parameterdesc = param.attributes['description'].value parameterstring = parameterstring + '\t' + parametername + ":" + '\t' + " " + parameterdesc + "\n" #print('\t' + parametername + ":" + '\t' + parameterdesc) parameterstringlist.append(parameterstring) i = i + 1 QWidget.__init__(self, parent) self.setWindowTitle("Rate Law Library") self.output = None self.error_output = None self._last_wdir = None self._last_args = None self._last_pythonpath = None self.textlabel = QLabel(RATE_LAW_MESSAGE) self.lawlist = QListWidget() self.lawpage = QStackedWidget() #Adding displayName items to lawlist for j in range(i): item = QListWidgetItem(displaynamelist[j]) self.lawlist.addItem(item) self.lawdetailpage = QWidget() # Page layout will become its own function setup_group = QGroupBox(displaynamelist[j]) infixmod = infixlist[j].replace("___"," ") setup_label = QLabel(infixmod) setup_label.setWordWrap(True) desc_group = QGroupBox("Description") desc_label = QLabel(desclist[j]) desc_label.setWordWrap(True) param_label = QLabel(parameterstringlist[j]) param_label.setWordWrap(True) # Warning: do not try to regroup the following QLabel contents with # widgets above -- this string was isolated here in a single QLabel # on purpose: to fix Issue 863 setup_layout = QVBoxLayout() setup_layout.addWidget(setup_label) setup_group.setLayout(setup_layout) desc_layout = QVBoxLayout() desc_layout.addWidget(desc_label) desc_layout.addWidget(param_label) desc_group.setLayout(desc_layout) vlayout = QVBoxLayout() vlayout.addWidget(setup_group) vlayout.addWidget(desc_group) vlayout.addStretch(1) self.lawdetailpage.setLayout(vlayout) self.lawpage.addWidget(self.lawdetailpage) #self.connect(self.lawlist, SIGNAL(self.lawlist.currentRowChanged(int)),self.lawpage,SLOT(self.lawpage.setCurrentIndex(int))) self.lawlist.currentRowChanged.connect(self.lawpage.setCurrentIndex) ''' self.lawpage = QWidget() ''' self.lawlist.setCurrentRow(0) hsplitter = QSplitter() hsplitter.addWidget(self.lawlist) hlayout1 = QHBoxLayout() hlayout1.addWidget(self.textlabel) hlayout1.addStretch() self.lawpage.setLayout(hlayout1) hsplitter.addWidget(self.lawpage) layout = QVBoxLayout() layout.addWidget(hsplitter) self.setLayout(layout)
class ConfigDialog(QDialog): """Spyder configuration ('Preferences') dialog box""" # Signals check_settings = Signal() size_change = Signal(QSize) def __init__(self, parent=None): QDialog.__init__(self, parent) self.main = parent # Widgets self.pages_widget = QStackedWidget() self.contents_widget = QListWidget() self.button_reset = QPushButton(_('Reset to defaults')) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) # Widgets setup # Destroying the C++ object right after closing the dialog box, # otherwise it may be garbage-collected in another QThread # (e.g. the editor's analysis thread in Spyder), thus leading to # a segmentation fault on UNIX or an application crash on Windows self.setAttribute(Qt.WA_DeleteOnClose) self.setWindowTitle(_('Preferences')) self.setWindowIcon(ima.icon('configure')) self.contents_widget.setMovement(QListView.Static) self.contents_widget.setSpacing(1) self.contents_widget.setCurrentRow(0) # Layout hsplitter = QSplitter() hsplitter.addWidget(self.contents_widget) hsplitter.addWidget(self.pages_widget) btnlayout = QHBoxLayout() btnlayout.addWidget(self.button_reset) btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addWidget(hsplitter) vlayout.addLayout(btnlayout) self.setLayout(vlayout) # Signals and slots self.button_reset.clicked.connect(self.main.reset_spyder) self.pages_widget.currentChanged.connect(self.current_page_changed) self.contents_widget.currentRowChanged.connect( self.pages_widget.setCurrentIndex) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) bbox.clicked.connect(self.button_clicked) # Ensures that the config is present on spyder first run CONF.set('main', 'interface_language', load_lang_conf()) def get_current_index(self): """Return current page index""" return self.contents_widget.currentRow() def set_current_index(self, index): """Set current page index""" self.contents_widget.setCurrentRow(index) def get_page(self, index=None): """Return page widget""" if index is None: widget = self.pages_widget.currentWidget() else: widget = self.pages_widget.widget(index) return widget.widget() @Slot() def accept(self): """Reimplement Qt method""" for index in range(self.pages_widget.count()): configpage = self.get_page(index) if not configpage.is_valid(): return configpage.apply_changes() QDialog.accept(self) def button_clicked(self, button): if button is self.apply_btn: # Apply button was clicked configpage = self.get_page() if not configpage.is_valid(): return configpage.apply_changes() def current_page_changed(self, index): widget = self.get_page(index) self.apply_btn.setVisible(widget.apply_callback is not None) self.apply_btn.setEnabled(widget.is_modified) def add_page(self, widget): self.check_settings.connect(widget.check_settings) widget.show_this_page.connect(lambda row=self.contents_widget.count(): self.contents_widget.setCurrentRow(row)) widget.apply_button_enabled.connect(self.apply_btn.setEnabled) scrollarea = QScrollArea(self) scrollarea.setWidgetResizable(True) scrollarea.setWidget(widget) self.pages_widget.addWidget(scrollarea) item = QListWidgetItem(self.contents_widget) item.setIcon(widget.get_icon()) item.setText(widget.get_name()) item.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled) item.setSizeHint(QSize(0, 25)) def check_all_settings(self): """This method is called to check all configuration page settings after configuration dialog has been shown""" self.check_settings.emit() def resizeEvent(self, event): """ Reimplement Qt method to be able to save the widget's size from the main application """ QDialog.resizeEvent(self, event) self.size_change.emit(self.size())
def __init__(self, parent, max_entries=100): "Initialize Various list objects before assignment" displaylist = [] displaynamelist = [] infixmod = [] infixlist = [] desclist = [] parameternamelist = [] parameterdesclist = [] parameterstringlist = [] paramcountlist = [] buttonlist = [] xmldoc = minidom.parse('C:\\Users\\Jayit\\.spyder2\\ratelaw2_0_3.xml') #xmldoc = minidom.parse('%\\Downloads\\ratelaw2_0_3.xml') lawlistxml = xmldoc.getElementsByTagName('law') o = 0 for s in lawlistxml: o = o + 1 parameternamelistlist = [0 for x in range(o)] parameterdesclistlist = [0 for x in range(o)] """i is the number of laws currently in the xml file""" i = 0 """ Parsing xml: Acquiring rate law name, description, and list of parameter information """ for s in lawlistxml: #RATE_LAW_MESSAGE += s.getAttribute('displayName') + "\n" """Gets Latec Expression""" displaylist.append(s.getAttribute('display')) """Gets Rate-Law Name""" displaynamelist.append(s.getAttribute('displayName')) """"Gets Raw Rate-Law expression""" infixlist.append(s.getAttribute('infixExpression')) """Gets description statement""" desclist.append(s.getAttribute('description')) """Gets listOfParameters Object""" parameterlist = s.getElementsByTagName('listOfParameters')[0] """Gets a list of parameters within ListOfParameters object""" parameters = parameterlist.getElementsByTagName('parameter') for param in parameters: parameternamelist.append(param.attributes['name'].value) #print(param.attributes['name'].value) parameterdesclist.append(param.attributes['description'].value) parameternamelistlist[i] = parameternamelist #print("break") parameterdesclistlist[i] = parameterdesclist parameternamelist = [] parameterdesclist = [] i = i + 1 SLElistlist = [ 0 for x in range(i)] PLElistlist = [ 0 for x in range(i)] ILElistlist = [ 0 for x in range(i)] paramLElistlist = [ 0 for x in range(i)] numlistlist = [ 0 for x in range(i)] QWidget.__init__(self, parent) self.setWindowTitle("Rate Law Library") self.output = None self.error_output = None self._last_wdir = None self._last_args = None self._last_pythonpath = None #self.textlabel = QLabel(RATE_LAW_MESSAGE) self.lawlist = QListWidget() self.lawpage = QStackedWidget() index = 0 for j in range(i): item = QListWidgetItem(displaynamelist[j]) self.lawlist.addItem(item) self.lawdetailpage = QWidget() setup_group = QGroupBox(displaynamelist[j]) infixmod.append(infixlist[j].replace("___"," ")) setup_label = QLabel(infixmod[j]) setup_label.setWordWrap(True) desc_group = QGroupBox("Description") desc_label = QLabel(desclist[j]) desc_label.setWordWrap(True) param_label = QGridLayout() nm = QLabel("Name:") des = QLabel("Description:") repl = QLabel("Replace with:") param_label.addWidget(nm,0,0) param_label.addWidget(des,0,1) param_label.addWidget(repl,0,2) """g is the total number of alterable values""" g = 0 """t is the total number of alterable non-parameters""" t = 1 snum = 0 pnum = 0 inum = 0 """range of N is the max number of possible substrates OR products""" N = 5 for n in range(N): nl = n+1 if (infixmod[j].find('S%s' % nl) > -1): z = QLabel('S%s is present' % nl) param_label.addWidget(z,t,0) snum = snum + 1 t = t + 1 for n in range(N): nl = n+1 if (infixmod[j].find('P%s' % nl) > -1): z = QLabel('P%s is present' % nl) param_label.addWidget(z,t,0) pnum = pnum + 1 t = t + 1 for n in range(N): nl = n+1 if (infixmod[j].find('I%s' % nl) > -1): z = QLabel('I%s is present' % nl) param_label.addWidget(z,t,0) inum = inum + 1 t = t + 1 """Initialize lists of list of parameter lineedit""" length = len(parameternamelistlist[j]) for b in range(length): p = QLabel("%s :" % parameternamelistlist[j][b]) param_label.addWidget(p,b+t,0) d = QLabel("'%s'" % parameterdesclistlist[j][b]) param_label.addWidget(d,b+t,1) g = t + length Slineeditlist = [0 for x in range(snum)] Plineeditlist = [0 for x in range(pnum)] Ilineeditlist = [0 for x in range(inum)] paramlineeditlist = [0 for x in range(length)] editcount = 1 """Place lineedit widgets for parameters""" for s in range(snum): Slineeditlist[s] = QLineEdit() param_label.addWidget(Slineeditlist[s],editcount,2) editcount = editcount + 1 SLElistlist[j] = Slineeditlist for s in range(pnum): Plineeditlist[s] = QLineEdit() param_label.addWidget(Plineeditlist[s],editcount,2) editcount = editcount + 1 PLElistlist[j] = Plineeditlist for s in range(inum): Ilineeditlist[s] = QLineEdit() param_label.addWidget(Ilineeditlist[s],editcount,2) editcount = editcount + 1 ILElistlist[j] = Ilineeditlist for s in range(length): paramlineeditlist[s] = QLineEdit() param_label.addWidget(paramlineeditlist[s],editcount,2) editcount = editcount + 1 paramLElistlist[j] = paramlineeditlist """Necessary lists for editable parameters. Housekeeping essentially.""" stuff = paramlineeditlist[0].text() numlistlist[j] = [snum, pnum, inum, length] charlist = ["S","P","I"] buttonlist.append(QPushButton(self)) buttonlist[j].setText("Insert Rate Law: %s" % displaynamelist[j]) # Warning: do not try to regroup the following QLabel contents with # widgets above -- this string was isolated here in a single QLabel # on purpose: to fix Issue 863 """Page formatting""" setup_layout = QVBoxLayout() setup_layout.addWidget(setup_label) setup_group.setLayout(setup_layout) desc_group.setLayout(param_label) vlayout = QVBoxLayout() vlayout.addWidget(setup_group) vlayout.addWidget(desc_group) vlayout.addWidget(buttonlist[j]) vlayout.addStretch(1) self.lawdetailpage.setLayout(vlayout) self.lawpage.addWidget(self.lawdetailpage) """Set up button functionality""" for k in range(47): buttonlist[k].clicked.connect(pressbutton(self, infixmod[k], SLElistlist[k], PLElistlist[k],ILElistlist[k], paramLElistlist[k], parameternamelistlist[k], numlistlist[k], charlist,k)) self.lawlist.currentRowChanged.connect(self.lawpage.setCurrentIndex) self.lawlist.setCurrentRow(0) """Set up high-level widget formatting.""" hsplitter = QSplitter() hsplitter.addWidget(self.lawlist) hsplitter.addWidget(self.lawpage) layout = QVBoxLayout() layout.addWidget(hsplitter) self.setLayout(layout)