class DictWidget(QWidget, NodeWidget): data_type = "Dict" two_rows = True data_class = StructuredNode def __init__(self, name, data, scheme, parent=None): QWidget.__init__(self, parent) NodeWidget.__init__(self, name, data, scheme) self.layout = QVBoxLayout(self) self.layout.setMargin(0) self.layout.setContentsMargins(0,0,0,0) self._listwidget = QTreeWidget(self) self._listwidget.setColumnCount(2) self._listwidget.setHeaderLabels(("Key","Value")) self.layout.addWidget(self._listwidget) hlayout = QHBoxLayout() self.layout.addLayout(hlayout) self._plus_minus_widget = PlusMinusWidget(self.create_item, self.delete_item, self) hlayout.addWidget(self._plus_minus_widget) self.new_data = None hlayout.addStretch(1) self.add_widget = WidgetSelector(self) hlayout.addWidget(self.add_widget) def delete_item(self): current_item = self._listwidget.currentItem() if current_item: key = current_item.data(1) new_data = self.data.get() del new_data[key] self.data.set(new_data) def create_item(self): new_data = self.data.get() new_item = self.add_widget.get_item() new_data[new_item["key"]] = Node.create_node(new_item["value"].get()) self.data.set(new_data) def __createItem(self, itemname, itemvalue): item = QTreeWidgetItem(self._listwidget, [unicode(itemname), unicode(itemvalue)]) # item.setFlags (Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled ) def dump(self): pass def load(self): self._listwidget.clear() for key, value in self.data.iteritems(): self.__createItem(key, value) @classmethod def _get_default_data(cls, scheme, data): return StructuredNode({})
class AccountWidget(QWidget): def __init__(self, parent=None): super(AccountWidget, self).__init__(parent) # codeCompletionBlock start from PyQt4.QtGui import QTreeWidget, QStackedWidget self.dateTree = QTreeWidget() self.monthStack = QStackedWidget() # codeCompletionBlock end uic.loadUi(getUiFile('AccountWidget'), self) self.dateTree.currentItemChanged.connect(self.syncronizeStack) self.addTopLevelPeriod('CurrentTotal') def addNewSubaccount(self): data = self.inquireSubaccountData() print self def inquireSubaccountData(self): pass def addNextMonth(self): # treewidget get toplevel items # find last item # add new toplevvelitem if toplevel item has 12 subitems # add new sublevel item last = self.getLastItem() month = last.monthwidget self.dateTree.addMonth(month) def addSecondLevelPeriod(self, text): # TODO: find previous item item = self.dateTree.currentItem() if item: item.addChildren([QTreeWidgetItem([text])]) self.monthStack.addWidget(MonthWidget()) print self.getLastItem() def getLastItem(self): return MonthItem(1, MonthWidget()) def addTopLevelPeriod(self, text): self.monthStack.addWidget(MonthWidget()) item = QTreeWidgetItem([text]) self.dateTree.addTopLevelItem(item) self.dateTree.setCurrentItem(item) def syncronizeStack(self, item): print item
class NotebookExtSettingsDialog(QDialog): def __init__(self, parent=None, cfg_list=[]): super(NotebookExtSettingsDialog, self).__init__(parent) self.extCfgEdit = QTreeWidget() self.extCfgEdit.setHeaderLabels(['Property', 'Value']) self.addRow = QPushButton('+') self.removeRow = QPushButton('-') self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) layout = QGridLayout(self) layout.addWidget(self.extCfgEdit,0,0,1,2) layout.addWidget(self.addRow,1,0,1,1) layout.addWidget(self.removeRow,1,1,1,1) layout.addWidget(self.buttonBox,2,0,1,2) self.initCfgPanel(cfg_list) self.addRow.clicked.connect(self.actionAdd) self.removeRow.clicked.connect(self.actionRemove) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) def initCfgPanel(self, cfg_list): for item in cfg_list: self.actionAdd(prop_name=item[0], prop_val=item[1]) def actionRemove(self): item = self.extCfgEdit.currentItem() row = self.extCfgEdit.indexOfTopLevelItem(item) self.extCfgEdit.takeTopLevelItem(row) def actionAdd(self, checked=False, prop_name='', prop_val=''): item = QTreeWidgetItem(self.extCfgEdit, [prop_name, prop_val]) item.setFlags(item.flags()|Qt.ItemIsEditable) #self.extCfgEdit.addTopLevelItem(item) def configToList(self): items = [] for i in range(self.extCfgEdit.topLevelItemCount()): witem = self.extCfgEdit.topLevelItem(i) items.append((witem.text(0), witem.text(1))) return items
class NotebookExtSettingsDialog(QDialog): def __init__(self, parent=None, cfg_list=[]): super(NotebookExtSettingsDialog, self).__init__(parent) self.extCfgEdit = QTreeWidget() self.extCfgEdit.setHeaderLabels(['Property', 'Value']) self.addRow = QPushButton('+') self.removeRow = QPushButton('-') self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) layout = QGridLayout(self) layout.addWidget(self.extCfgEdit, 0, 0, 1, 2) layout.addWidget(self.addRow, 1, 0, 1, 1) layout.addWidget(self.removeRow, 1, 1, 1, 1) layout.addWidget(self.buttonBox, 2, 0, 1, 2) self.initCfgPanel(cfg_list) self.addRow.clicked.connect(self.actionAdd) self.removeRow.clicked.connect(self.actionRemove) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) def initCfgPanel(self, cfg_list): for item in cfg_list: self.actionAdd(prop_name=item[0], prop_val=item[1]) def actionRemove(self): item = self.extCfgEdit.currentItem() row = self.extCfgEdit.indexOfTopLevelItem(item) self.extCfgEdit.takeTopLevelItem(row) def actionAdd(self, checked=False, prop_name='', prop_val=''): item = QTreeWidgetItem(self.extCfgEdit, [prop_name, prop_val]) item.setFlags(item.flags() | Qt.ItemIsEditable) #self.extCfgEdit.addTopLevelItem(item) def configToList(self): items = [] for i in range(self.extCfgEdit.topLevelItemCount()): witem = self.extCfgEdit.topLevelItem(i) items.append((witem.text(0), witem.text(1))) return items
class PluginWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.pluginMetadata = {} # Main layout self.mainLayout = QVBoxLayout() self.setLayout(self.mainLayout) # Define size used for the underlines self.underlineSize = QSize() self.underlineSize.setHeight(1) # Define font used for headers self.font = QFont() self.font.setPointSize(11) self.font.setBold(True) self.font.setUnderline(True) # Plugins Description self.pluginDescription = QLabel() self.pluginDescription.setText("Click a plugin to see more information." + " Plugins can be configured from the Recording tab. \n") self.pluginDescription.setWordWrap(True) # Plugins GroupBox self.pluginLayout = QVBoxLayout() self.pluginGroupBox = QGroupBox("Plugins extend the functionality of Freeseer") self.pluginGroupBox.setLayout(self.pluginLayout) self.pluginLayout.insertWidget(0, self.pluginDescription) self.mainLayout.insertWidget(0, self.pluginGroupBox) # Plugins list self.list = QTreeWidget() self.list.setHeaderHidden(True) self.list.headerItem().setText(0, "1") self.pluginLayout.insertWidget(1, self.list) # Details self.detailPane = QGroupBox() self.detailLayout = QVBoxLayout() self.detailPane.setLayout(self.detailLayout) self.detailPaneDesc = QLabel() self.detailPaneDesc.setWordWrap(True) self.detailLayout.addWidget(self.detailPaneDesc) self.pluginLayout.insertWidget(2, self.detailPane) self.list.itemSelectionChanged.connect(self.treeViewSelect) def treeViewSelect(self): item = self.list.currentItem() key = str(item.text(0)) if key in self.pluginMetadata.keys(): self.showDetails(key) else: self.hideDetails() def showDetails(self, key): self.detailPane.setTitle(key) self.detailPaneDesc.setText(self.pluginMetadata[key]) self.detailPane.show() def hideDetails(self): self.detailPane.hide() def getWidgetPlugin(self, plugin, plugin_category, plugman): plugin_name = plugin.plugin_object.get_name() item = QTreeWidgetItem() # Display Plugin's meta data in a tooltip pluginDetails = """ <table> <tr> <td>Name: </td> <td><b>%(name)s</b></td> </tr> <tr> <td>Version: </td> <td><b>%(version)s</b></td> <tr> <td>Author: </td> <td><b>%(author)s</b></td> </tr> <tr> <td>Website: </td> <td><b>%(website)s</b></td> </tr> <tr> <td>Description: </td> <td><b>%(description)s</b></td> </tr> </table> """ % {"name": plugin.name, "version": plugin.version, "author": plugin.author, "website": plugin.website, "description": plugin.description} # put the details in the hash table self.pluginMetadata[plugin_name] = pluginDetails item.setText(0, plugin_name) return item
class AddToProject(QDialog): def __init__(self, pathProjects, parent=None): #pathProjects must be a list QDialog.__init__(self, parent) self.setWindowTitle(self.tr("Add File to Project")) self.pathSelected = '' vbox = QVBoxLayout(self) self._tree = QTreeWidget() self._tree.header().setHidden(True) self._tree.setSelectionMode(QTreeWidget.SingleSelection) self._tree.setAnimated(True) vbox.addWidget(self._tree) hbox = QHBoxLayout() btnAdd = QPushButton(self.tr("Add here!")) btnCancel = QPushButton(self.tr("Cancel")) hbox.addWidget(btnCancel) hbox.addWidget(btnAdd) vbox.addLayout(hbox) #load folders self._root = None for pathProject in pathProjects: folderStructure = file_manager.open_project(pathProject) self._load_project(folderStructure, pathProject) self.connect(btnCancel, SIGNAL("clicked()"), self.close) self.connect(btnAdd, SIGNAL("clicked()"), self._select_path) def _select_path(self): item = self._tree.currentItem() if item: self.pathSelected = unicode(item.toolTip(0)) self.close() def _load_project(self, folderStructure, folder): if not folder: return name = file_manager.get_basename(folder) item = QTreeWidgetItem(self._tree) item.setText(0, name) item.setToolTip(0, folder) item.setIcon(0, QIcon(resources.IMAGES['tree-folder'])) if folderStructure[folder][1] is not None: folderStructure[folder][1].sort() self._load_folder(folderStructure, folder, item) item.setExpanded(True) self._root = item def _load_folder(self, folderStructure, folder, parentItem): items = folderStructure[folder] if items[1] is not None: items[1].sort() for _file in items[1]: if _file.startswith('.'): continue subfolder = QTreeWidgetItem(parentItem) subfolder.setText(0, _file) subfolder.setToolTip(0, os.path.join(folder, _file)) subfolder.setIcon(0, QIcon(resources.IMAGES['tree-folder'])) self._load_folder(folderStructure, os.path.join(folder, _file), subfolder)
class Shortcuts(preferences.Page): def __init__(self, dialog): super(Shortcuts, self).__init__(dialog) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.scheme = SchemeSelector(self) layout.addWidget(self.scheme) self.tree = QTreeWidget(self) self.tree.setHeaderLabels([_("Command"), _("Shortcut")]) self.tree.setRootIsDecorated(False) self.tree.setColumnCount(2) self.tree.setAllColumnsShowFocus(True) self.tree.setAnimated(True) layout.addWidget(self.tree) self.edit = QPushButton(icons.get("preferences-desktop-keyboard-shortcuts"), '') layout.addWidget(self.edit) # signals self.scheme.currentChanged.connect(self.slotSchemeChanged) self.scheme.changed.connect(self.changed) self.tree.currentItemChanged.connect(self.slotCurrentItemChanged) self.tree.itemDoubleClicked.connect(self.editCurrentItem) self.edit.clicked.connect(self.editCurrentItem) # make a dict of all actions with the actions as key and the names as # value, with the collection prepended (for loading/saving) win = dialog.parent() allactions = {} for collection in actioncollectionmanager.manager(win).actionCollections(): for name, action in collection.actions().items(): allactions[action] = (collection, name) # keep a list of actions not in the menu structure left = allactions.keys() def add_actions(menuitem, actions): """Add actions to a QTreeWidgetItem.""" for a in actions: if a.menu(): item = build_menu_item(a) if item.childCount(): menuitem.addChild(item) elif a in left: left.remove(a) menuitem.addChild(ShortcutItem(a, *allactions[a])) menuitem.setFlags(Qt.ItemIsEnabled) # disable selection def build_menu_item(action): """Return a QTreeWidgetItem with children for all the actions in the submenu.""" menuitem = QTreeWidgetItem() text = qutil.removeAccelelator(action.text()) menuitem.setText(0, _("Menu {name}").format(name=text)) add_actions(menuitem, action.menu().actions()) return menuitem # present the actions nicely ordered as in the menus for a in win.menuBar().actions(): menuitem = build_menu_item(a) if menuitem.childCount(): self.tree.addTopLevelItem(menuitem) # sort leftover actions left.sort(key=lambda i: i.text()) # show actions that are left, grouped by collection titlegroups = {} for a in left[:]: # copy collection, name = allactions[a] if collection.title(): titlegroups.setdefault(collection.title(), []).append(a) left.remove(a) for title in sorted(titlegroups): item = QTreeWidgetItem(["{0}:".format(title)]) for a in titlegroups[title]: item.addChild(ShortcutItem(a, *allactions[a])) self.tree.addTopLevelItem(item) item.setFlags(Qt.ItemIsEnabled) # disable selection # show other actions that were not in the menus item = QTreeWidgetItem([_("Other commands:")]) for a in left: if a.text() and not a.menu(): item.addChild(ShortcutItem(a, *allactions[a])) if item.childCount(): self.tree.addTopLevelItem(item) item.setFlags(Qt.ItemIsEnabled) # disable selection self.tree.expandAll() item = self.tree.topLevelItem(0).child(0) if _lastaction: # find the previously selected item for i in self.items(): if i.name == _lastaction: item = i break self.tree.setCurrentItem(item) self.tree.resizeColumnToContents(0) def items(self): """Yield all the items in the actions tree.""" def children(item): for i in range(item.childCount()): c = item.child(i) if c.childCount(): for c1 in children(c): yield c1 else: yield c for c in children(self.tree.invisibleRootItem()): yield c def saveSettings(self): self.scheme.saveSettings("shortcut_scheme", "shortcut_schemes", "shortcuts") for item in self.items(): for scheme in self.scheme.schemes(): item.save(scheme) item.clearSettings() item.switchScheme(self.scheme.currentScheme()) def loadSettings(self): self.scheme.loadSettings("shortcut_scheme", "shortcut_schemes") # clear the settings in all the items for item in self.items(): item.clearSettings() item.switchScheme(self.scheme.currentScheme()) def slotSchemeChanged(self): """Called when the Scheme combobox is changed by the user.""" for item in self.items(): item.switchScheme(self.scheme.currentScheme()) def slotCurrentItemChanged(self, item): if isinstance(item, ShortcutItem): self.edit.setText( _("&Edit Shortcut for \"{name}\"").format(name=item.text(0))) self.edit.setEnabled(True) global _lastaction _lastaction = item.name else: self.edit.setText(_("(no shortcut)")) self.edit.setEnabled(False) def editCurrentItem(self): item = self.tree.currentItem() if not isinstance(item, ShortcutItem): return try: dlg = self._editdialog except AttributeError: dlg = self._editdialog = ShortcutEditDialog(self) scheme = self.scheme.currentScheme() action = item.action(scheme) default = item.defaultShortcuts() if dlg.editAction(action, default): shortcuts = action.shortcuts() # check for conflicts conflicting = [] for i in self.items(): if i is not item: for s1, s2 in itertools.product(i.shortcuts(scheme), shortcuts): if s1.matches(s2) or s2.matches(s1): conflicting.append(i) if conflicting: # show a question dialog msg = [_("This shortcut conflicts with the following command:", "This shortcut conflicts with the following commands:", len(conflicting))] msg.append('<br/>'.join(i.text(0) for i in conflicting)) msg.append(_("Remove the shortcut from that command?", "Remove the shortcut from those commands?", len(conflicting))) msg = '<p>{0}</p>'.format('</p><p>'.join(msg)) res = QMessageBox.warning(self, _("Shortcut Conflict"), msg, QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel) if res == QMessageBox.Yes: # remove from conflicting for i in conflicting: l = i.shortcuts(scheme) for s1 in list(l): # copy for s2 in shortcuts: if s1.matches(s2) or s2.matches(s1): l.remove(s1) i.setShortcuts(l, scheme) elif res == QMessageBox.No: # remove from ourselves for i in conflicting: for s1 in list(shortcuts): # copy for s2 in i.shortcuts(scheme): if s1.matches(s2) or s2.matches(s1): shortcuts.remove(s1) else: return # cancelled # store the shortcut item.setShortcuts(shortcuts, scheme) self.changed.emit()
class Suggest(QObject): def __init__(self, parent): QObject.__init__(self, parent) self.editor = parent editor = self.editor self.popup = QTreeWidget() popup = self.popup popup.setWindowFlags(Qt.Popup) popup.setFocusPolicy(Qt.NoFocus) popup.setFocusProxy(parent) popup.setMouseTracking(True) popup.setColumnCount(1) popup.setUniformRowHeights(True) popup.setRootIsDecorated(False) popup.setEditTriggers(QTreeWidget.NoEditTriggers) popup.setSelectionBehavior(QTreeWidget.SelectRows) popup.setFrameStyle(QFrame.Box | QFrame.Plain) popup.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) popup.header().hide() popup.installEventFilter(self) popup.itemClicked.connect(self.done) self.timer = QTimer(self) timer = self.timer timer.setSingleShot(True) # TODO: make interval optional timer.setInterval(500) timer.timeout.connect(self.suggest) editor.textEdited.connect(timer.start) self.engine = Engine(iciba.Engine()) self.engine.query_finished.connect(self.handle_query_finished) def eventFilter(self, o, e): if not o is self.popup: return False if e.type() == QEvent.MouseButtonPress: self.popup.hide() self.editor.setFocus() return True if e.type() == QEvent.KeyPress: consumed = False key = e.key() if key in (Qt.Key_Enter, Qt.Key_Return): self.done() consumed = True elif key in (Qt.Key_Escape, ): self.editor.setFocus() self.popup.hide() consumed = True elif key in ( Qt.Key_Up, Qt.Key_Down, Qt.Key_Home, Qt.Key_End, Qt.Key_PageUp, Qt.Key_PageDown ): pass else: self.editor.setFocus() self.editor.event(e) self.popup.hide() return consumed return False def complete(self, choices): if not choices: return self.popup.setUpdatesEnabled(False) self.popup.clear() for i in range(len(choices)): item = QTreeWidgetItem(self.popup) item.setText(0, choices[i]) self.popup.setCurrentItem(self.popup.topLevelItem(0)) self.popup.resizeColumnToContents(0) self.popup.resizeColumnToContents(1) self.popup.adjustSize() self.popup.setUpdatesEnabled(True) h = self.popup.sizeHintForRow(0) * min(7, len(choices)) + 3 self.popup.resize(self.editor.width(), h) self.popup.move(self.editor.mapToGlobal(QPoint(0, self.editor.height()))) self.popup.setFocus() self.popup.show() @pyqtSlot() def done(self): self.timer.stop() self.popup.hide() self.editor.setFocus() item = self.popup.currentItem() if item: self.editor.setText(item.text(0)) QMetaObject.invokeMethod(self.editor, "returnPressed") @pyqtSlot() def suggest(self): key = self.editor.text() self.engine.query(key) @pyqtSlot() def stop(self): self.timer.stop() @pyqtSlot(object) def handle_query_finished(self, result): self.complete(result)
class AddToProject(QDialog): def __init__(self, pathProjects, parent=None): #pathProjects must be a list QDialog.__init__(self, parent) self.setWindowTitle(self.tr("Add File to Project")) self.pathSelected = '' vbox = QVBoxLayout(self) self._tree = QTreeWidget() self._tree.header().setHidden(True) self._tree.setSelectionMode(QTreeWidget.SingleSelection) self._tree.setAnimated(True) vbox.addWidget(self._tree) hbox = QHBoxLayout() btnAdd = QPushButton(self.tr("Add here!")) btnCancel = QPushButton(self.tr("Cancel")) hbox.addWidget(btnCancel) hbox.addWidget(btnAdd) vbox.addLayout(hbox) #load folders self._root = None self._loading_items = {} self.loading_projects(pathProjects) self._thread_execution = ThreadExecution(self._thread_load_projects, args=[pathProjects]) self.connect(self._thread_execution, SIGNAL("finished()"), self._callback_load_project) self._thread_execution.start() self.connect(btnCancel, SIGNAL("clicked()"), self.close) self.connect(btnAdd, SIGNAL("clicked()"), self._select_path) def loading_projects(self, projects): for project in projects: loadingItem = LoadingItem() item = loadingItem.add_item_to_tree(project, self._tree, parent=self) self._loading_items[project] = item def _thread_load_projects(self, projects): structures = [] for pathProject in projects: folderStructure = file_manager.open_project(pathProject) structures.append((folderStructure, pathProject)) self._thread_execution.storage_values = structures def _callback_load_project(self): structures = self._thread_execution.storage_values for structure, path in structures: item = self._loading_items.pop(path, None) if item is not None: index = self._tree.indexOfTopLevelItem(item) self._tree.takeTopLevelItem(index) self._load_project(structure, path) def _select_path(self): item = self._tree.currentItem() if item: self.pathSelected = item.toolTip(0) self.close() def _load_project(self, folderStructure, folder): if not folder: return name = file_manager.get_basename(folder) item = QTreeWidgetItem(self._tree) item.setText(0, name) item.setToolTip(0, folder) item.setIcon(0, QIcon(resources.IMAGES['tree-folder'])) if folderStructure[folder][1] is not None: folderStructure[folder][1].sort() self._load_folder(folderStructure, folder, item) item.setExpanded(True) self._root = item def _load_folder(self, folderStructure, folder, parentItem): items = folderStructure[folder] if items[1] is not None: items[1].sort() for _file in items[1]: if _file.startswith('.'): continue subfolder = QTreeWidgetItem(parentItem) subfolder.setText(0, _file) subfolder.setToolTip(0, os.path.join(folder, _file)) subfolder.setIcon(0, QIcon(resources.IMAGES['tree-folder'])) self._load_folder(folderStructure, os.path.join(folder, _file), subfolder)
class AddToProject(QDialog): def __init__(self, pathProjects, parent=None): #pathProjects must be a list QDialog.__init__(self, parent) self.setWindowTitle(self.tr("Add File to Project")) self.pathSelected = '' vbox = QVBoxLayout(self) self._tree = QTreeWidget() self._tree.header().setHidden(True) self._tree.setSelectionMode(QTreeWidget.SingleSelection) self._tree.setAnimated(True) vbox.addWidget(self._tree) hbox = QHBoxLayout() btnAdd = QPushButton(self.tr("Add here!")) btnCancel = QPushButton(self.tr("Cancel")) hbox.addWidget(btnCancel) hbox.addWidget(btnAdd) vbox.addLayout(hbox) #load folders self._root = None self._loading_items = {} self.loading_projects(pathProjects) self._thread_execution = ThreadExecution( self._thread_load_projects, args=[pathProjects]) self.connect(self._thread_execution, SIGNAL("finished()"), self._callback_load_project) self._thread_execution.start() self.connect(btnCancel, SIGNAL("clicked()"), self.close) self.connect(btnAdd, SIGNAL("clicked()"), self._select_path) def loading_projects(self, projects): for project in projects: loadingItem = LoadingItem() item = loadingItem.add_item_to_tree(project, self._tree, parent=self) self._loading_items[project] = item def _thread_load_projects(self, projects): structures = [] for pathProject in projects: folderStructure = file_manager.open_project(pathProject) structures.append((folderStructure, pathProject)) self._thread_execution.storage_values = structures def _callback_load_project(self): structures = self._thread_execution.storage_values if structures: for structure, path in structures: item = self._loading_items.pop(path, None) if item is not None: index = self._tree.indexOfTopLevelItem(item) self._tree.takeTopLevelItem(index) self._load_project(structure, path) def _select_path(self): item = self._tree.currentItem() if item: self.pathSelected = item.toolTip(0) self.close() def _load_project(self, folderStructure, folder): if not folder: return name = file_manager.get_basename(folder) item = QTreeWidgetItem(self._tree) item.setText(0, name) item.setToolTip(0, folder) item.setIcon(0, QIcon(resources.IMAGES['tree-folder'])) if folderStructure[folder][1] is not None: folderStructure[folder][1].sort() self._load_folder(folderStructure, folder, item) item.setExpanded(True) self._root = item def _load_folder(self, folderStructure, folder, parentItem): items = folderStructure[folder] if items[1] is not None: items[1].sort() for _file in items[1]: if _file.startswith('.'): continue subfolder = QTreeWidgetItem(parentItem) subfolder.setText(0, _file) subfolder.setToolTip(0, os.path.join(folder, _file)) subfolder.setIcon(0, QIcon(resources.IMAGES['tree-folder'])) self._load_folder(folderStructure, os.path.join(folder, _file), subfolder)
class DBServersWidget(QWidget): """Displays a list of servers""" def __init__(self, parent=None): QWidget.__init__(self, parent) self.debug = False self.connections = {} self.setWindowTitle("Servers") #s#elf.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) self.mainLayout = QVBoxLayout() self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.setSpacing(0) self.setLayout(self.mainLayout) #============================================= ## Top Toolbar topBar = QToolBar() topBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.mainLayout.addWidget(topBar) ## Add the action buttons topBar.addAction(Ico.icon(Ico.ServerAdd), "Add", self.on_server_add) self.actionServerEdit = topBar.addAction(Ico.icon(Ico.ServerEdit), "Edit", self.on_server_edit) self.actionServerDelete = topBar.addAction(Ico.icon(Ico.ServerDelete), "Delete", self.on_server_delete) #============================================= ## Tree self.tree = QTreeWidget() self.mainLayout.addWidget(self.tree) self.tree.setUniformRowHeights(True) self.tree.setRootIsDecorated(True) self.tree.setHeaderLabels(["Server", "Butt"]) # set header, but hide anyway self.tree.header().hide() self.tree.header().setResizeMode(C.node, QHeaderView.Stretch) self.tree.setColumnWidth(C.butt, 20) self.connect( self.tree, SIGNAL( 'itemSelectionChanged()' ), self.on_tree_selection_changed ) self.connect( self.tree, SIGNAL( 'itemDoubleClicked (QTreeWidgetItem *,int)' ), self.on_tree_double_clicked ) self.buttGroup = QButtonGroup(self) self.connect(self.buttGroup, SIGNAL("buttonClicked(QAbstractButton*)"), self.on_open_server) self.on_tree_selection_changed() self.load_servers() #======================================= ##== Tree Events def on_tree_selection_changed(self): disabled = self.tree.selectionModel().hasSelection() == False self.actionServerEdit.setDisabled(disabled) self.actionServerDelete.setDisabled(disabled) def on_tree_double_clicked(self): self.actionServerEdit.trigger() #======================================= ## Server Actions def on_server_add(self): self.show_server_dialog(None) def on_server_edit(self): item = self.tree.currentItem() if item == None: return server = str(item.text(C.server)) self.show_server_dialog(server) def show_server_dialog(self, server=None): d = DBServerDialog.DBServerDialog(self, server) if d.exec_(): self.load_servers() def load_servers(self): """Load servers from :py:meth:`pyqtdb.XSettings.XSettings.get_servers` """ self.tree.clear() for butt in self.buttGroup.buttons(): self.buttGroup.removeButton(butt) for srv in G.settings.get_servers_list(): item = QTreeWidgetItem() item.setText(C.node, srv['server']) #item.setText(C.user, srv['user']) self.tree.addTopLevelItem(item) butt = QToolButton() butt.setIcon(Ico.icon(Ico.Connect)) butt.setProperty("server", srv['server']) self.tree.setItemWidget(item, C.butt, butt) self.buttGroup.addButton(butt) def on_server_delete(self): item = self.tree.currentItem() if item == None: return srv = str(item.text(C.server)) G.settings.delete_server(srv) self.load_servers() def on_open_server(self, butt): # self.emit(SIGNAL("open_server"), butt.property("server").toString()) srv_ki = str(butt.property("server").toString()) server = G.settings.get_server(srv_ki) db = QSqlDatabase.addDatabase("QMYSQL", srv_ki) db.setHostName(server['server']) db.setUserName(server['user']) db.setPassword(server['passwd']) ok = db.open() if ok: #self.connections[srv_ki] = self.load_databases(srv_ki) print "open", ok def load_databases(self, srv_ki): """Load databases into tree node for server; executes 'show databases;' or aslike """ sql = "show databases;" query = QSqlQuery(QSqlDatabase.database(srv_ki)) ok = query.exec_(sql) print ok, sql, query.result() # Get the parent node, ie the server node pItem = self.tree.findItems(srv_ki, Qt.MatchExactly, C.node)[0] ## Assumed value(0) is the table.. we need the defs (ie mysql case) while query.next(): table_name = query.value(0).toString() nuItem = QTreeWidgetItem(pItem) nuItem.setText(C.node, table_name) #print table_name self.tree.setItemExpanded(pItem, True)
class DBBrowser(QMainWindow): def __init__(self, parent, server): QMainWindow.__init__(self, parent) self.debug = False self.server = server self.db = None self.setWindowTitle("Database Browser") #s#elf.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) topBar = QToolBar() self.addToolBar(Qt.TopToolBarArea, topBar) self.cenWid = QWidget() self.setCentralWidget(self.cenWid) self.mainLayout = QHBoxLayout() self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.setSpacing(0) self.cenWid.setLayout(self.mainLayout) self.treeTables = QTreeWidget() self.mainLayout.addWidget(self.treeTables, 1) self.treeTables.setHeaderLabels(["Table"]) self.treeTables.setSelectionBehavior(QAbstractItemView.SelectRows) self.treeTables.setSelectionMode(QTreeView.SingleSelection) self.connect(self.treeTables, SIGNAL('itemSelectionChanged()'), self.on_table) self.treeColumns = QTreeWidget() self.mainLayout.addWidget(self.treeColumns, 4) self.treeColumns.setHeaderLabels(["Column", "Type", "Nullable"]) self.db_connect() #self.fetch() def on_table(self): item = self.treeTables.currentItem() if item == None: return self.fetch(table=str(item.text(0))) def db_connect(self): #print "db_connect", self.server self.db = QSqlDatabase.addDatabase("QMYSQL") self.db.setHostName(self.server['server']) self.db.setUserName(self.server['user']) self.db.setPassword(self.server['passwd']) ok = self.db.open() print "open", ok #self.db.setHostName(self.server['server']) def load_data(self, data): if "tables" in data: self.treeTables.clear() for t in data['tables']: item = QTreeWidgetItem() item.setText(0, t['table']) self.treeTables.addTopLevelItem(item) else: self.treeColumns.clear() for t in data['columns']: item = QTreeWidgetItem() item.setText(0, t['column']) item.setText(1, t['type']) item.setText(2, "Yes" if t['nullable'] else "-") self.treeColumns.addTopLevelItem(item)
class RunDialog(QDialog): """ Run parameters dialog implementation """ # See utils.run for runParameters def __init__(self, path, runParameters, termType, profilerParams, debuggerParams, action="", parent=None): QDialog.__init__(self, parent) # Used as a return value self.termType = termType self.profilerParams = copy.deepcopy(profilerParams) self.debuggerParams = copy.deepcopy(debuggerParams) self.__action = action.lower() # Avoid pylint complains self.__argsEdit = None self.__scriptWDRButton = None self.__dirRButton = None self.__dirEdit = None self.__dirSelectButton = None self.__inheritParentRButton = None self.__inheritParentPlusRButton = None self.__inhPlusEnvTable = None self.__addInhButton = None self.__delInhButton = None self.__editInhButton = None self.__specificRButton = None self.__specEnvTable = None self.__addSpecButton = None self.__delSpecButton = None self.__editSpecButton = None self.__runButton = None self.__nodeLimitEdit = None self.__edgeLimitEdit = None self.__createLayout(action) self.setWindowTitle(action + " parameters for " + path) # Restore the values self.runParams = copy.deepcopy(runParameters) self.__argsEdit.setText(self.runParams.arguments) # Working dir if self.runParams.useScriptLocation: self.__scriptWDRButton.setChecked(True) self.__dirEdit.setEnabled(False) self.__dirSelectButton.setEnabled(False) else: self.__dirRButton.setChecked(True) self.__dirEdit.setEnabled(True) self.__dirSelectButton.setEnabled(True) self.__dirEdit.setText(self.runParams.specificDir) # Environment self.__populateTable(self.__inhPlusEnvTable, self.runParams.additionToParentEnv) self.__populateTable(self.__specEnvTable, self.runParams.specificEnv) if self.runParams.envType == RunParameters.InheritParentEnv: self.__inheritParentRButton.setChecked(True) self.__setEnabledInheritedPlusEnv(False) self.__setEnabledSpecificEnv(False) elif self.runParams.envType == RunParameters.InheritParentEnvPlus: self.__inheritParentPlusRButton.setChecked(True) self.__setEnabledSpecificEnv(False) else: self.__specificRButton.setChecked(True) self.__setEnabledInheritedPlusEnv(False) # Terminal if self.termType == TERM_REDIRECT: self.__redirectRButton.setChecked(True) elif self.termType == TERM_AUTO: self.__autoRButton.setChecked(True) elif self.termType == TERM_KONSOLE: self.__konsoleRButton.setChecked(True) elif self.termType == TERM_GNOME: self.__gnomeRButton.setChecked(True) else: self.__xtermRButton.setChecked(True) # Close checkbox self.__closeCheckBox.setChecked(self.runParams.closeTerminal) if self.termType == TERM_REDIRECT: self.__closeCheckBox.setEnabled(False) # Profile limits if so if self.__action == "profile": if self.profilerParams.nodeLimit < 0.0 or \ self.profilerParams.nodeLimit > 100.0: self.profilerParams.nodeLimit = 1.0 self.__nodeLimitEdit.setText(str(self.profilerParams.nodeLimit)) if self.profilerParams.edgeLimit < 0.0 or \ self.profilerParams.edgeLimit > 100.0: self.profilerParams.edgeLimit = 1.0 self.__edgeLimitEdit.setText(str(self.profilerParams.edgeLimit)) elif self.__action == "debug": self.__reportExceptionCheckBox.setChecked( self.debuggerParams.reportExceptions) self.__traceInterpreterCheckBox.setChecked( self.debuggerParams.traceInterpreter) self.__stopAtFirstCheckBox.setChecked( self.debuggerParams.stopAtFirstLine) self.__autoforkCheckBox.setChecked(self.debuggerParams.autofork) self.__debugChildCheckBox.setChecked( self.debuggerParams.followChild) self.__debugChildCheckBox.setEnabled(self.debuggerParams.autofork) self.__setRunButtonProps() return @staticmethod def __populateTable(table, dictionary): " Populates the given table " for key, value in dictionary.iteritems(): item = QTreeWidgetItem([key, value]) table.addTopLevelItem(item) if dictionary: table.setCurrentItem(table.topLevelItem(0)) return def __setEnabledInheritedPlusEnv(self, value): " Disables/enables 'inherited and add' section controls " self.__inhPlusEnvTable.setEnabled(value) self.__addInhButton.setEnabled(value) self.__delInhButton.setEnabled(value) self.__editInhButton.setEnabled(value) return def __setEnabledSpecificEnv(self, value): " Disables/enables 'specific env' section controls " self.__specEnvTable.setEnabled(value) self.__addSpecButton.setEnabled(value) self.__delSpecButton.setEnabled(value) self.__editSpecButton.setEnabled(value) return def __createLayout(self, action): """ Creates the dialog layout """ self.resize(650, 300) self.setSizeGripEnabled(True) # Top level layout layout = QVBoxLayout(self) # Cmd line arguments argsLabel = QLabel("Command line arguments") self.__argsEdit = QLineEdit() self.__argsEdit.textChanged.connect(self.__argsChanged) argsLayout = QHBoxLayout() argsLayout.addWidget(argsLabel) argsLayout.addWidget(self.__argsEdit) layout.addLayout(argsLayout) # Working directory workDirGroupbox = QGroupBox(self) workDirGroupbox.setTitle("Working directory") sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( \ workDirGroupbox.sizePolicy().hasHeightForWidth() ) workDirGroupbox.setSizePolicy(sizePolicy) gridLayoutWD = QGridLayout(workDirGroupbox) self.__scriptWDRButton = QRadioButton(workDirGroupbox) self.__scriptWDRButton.setText("&Use script location") gridLayoutWD.addWidget(self.__scriptWDRButton, 0, 0) self.__scriptWDRButton.clicked.connect(self.__scriptWDirClicked) self.__dirRButton = QRadioButton(workDirGroupbox) self.__dirRButton.setText("Select &directory") gridLayoutWD.addWidget(self.__dirRButton, 1, 0) self.__dirRButton.clicked.connect(self.__dirClicked) self.__dirEdit = QLineEdit(workDirGroupbox) gridLayoutWD.addWidget(self.__dirEdit, 1, 1) self.__dirEdit.textChanged.connect(self.__workingDirChanged) self.__dirSelectButton = QPushButton(workDirGroupbox) self.__dirSelectButton.setText("...") gridLayoutWD.addWidget(self.__dirSelectButton, 1, 2) self.__dirSelectButton.clicked.connect(self.__selectDirClicked) layout.addWidget(workDirGroupbox) # Environment envGroupbox = QGroupBox(self) envGroupbox.setTitle("Environment") sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( \ envGroupbox.sizePolicy().hasHeightForWidth() ) envGroupbox.setSizePolicy(sizePolicy) layoutEnv = QVBoxLayout(envGroupbox) self.__inheritParentRButton = QRadioButton(envGroupbox) self.__inheritParentRButton.setText("Inherit &parent") self.__inheritParentRButton.clicked.connect(self.__inhClicked) layoutEnv.addWidget(self.__inheritParentRButton) self.__inheritParentPlusRButton = QRadioButton(envGroupbox) self.__inheritParentPlusRButton.setText( "Inherit parent and add/&modify") self.__inheritParentPlusRButton.clicked.connect(self.__inhPlusClicked) layoutEnv.addWidget(self.__inheritParentPlusRButton) hInhPlusLayout = QHBoxLayout() self.__inhPlusEnvTable = QTreeWidget() self.__inhPlusEnvTable.itemActivated.connect( self.__inhPlusItemActivated) self.__tuneTable(self.__inhPlusEnvTable) hInhPlusLayout.addWidget(self.__inhPlusEnvTable) vInhPlusLayout = QVBoxLayout() self.__addInhButton = QPushButton() self.__addInhButton.clicked.connect(self.__addInhClicked) self.__addInhButton.setText('Add') vInhPlusLayout.addWidget(self.__addInhButton) self.__delInhButton = QPushButton() self.__delInhButton.clicked.connect(self.__delInhClicked) self.__delInhButton.setText('Delete') vInhPlusLayout.addWidget(self.__delInhButton) self.__editInhButton = QPushButton() self.__editInhButton.clicked.connect(self.__editInhClicked) self.__editInhButton.setText("Edit") vInhPlusLayout.addWidget(self.__editInhButton) hInhPlusLayout.addLayout(vInhPlusLayout) layoutEnv.addLayout(hInhPlusLayout) self.__specificRButton = QRadioButton(envGroupbox) self.__specificRButton.setText("&Specific") self.__specificRButton.clicked.connect(self.__specClicked) layoutEnv.addWidget(self.__specificRButton) hSpecLayout = QHBoxLayout() self.__specEnvTable = QTreeWidget() self.__specEnvTable.itemActivated.connect(self.__specItemActivated) self.__tuneTable(self.__specEnvTable) hSpecLayout.addWidget(self.__specEnvTable) vSpecLayout = QVBoxLayout() self.__addSpecButton = QPushButton() self.__addSpecButton.clicked.connect(self.__addSpecClicked) self.__addSpecButton.setText('Add') vSpecLayout.addWidget(self.__addSpecButton) self.__delSpecButton = QPushButton() self.__delSpecButton.clicked.connect(self.__delSpecClicked) self.__delSpecButton.setText('Delete') vSpecLayout.addWidget(self.__delSpecButton) self.__editSpecButton = QPushButton() self.__editSpecButton.clicked.connect(self.__editSpecClicked) self.__editSpecButton.setText("Edit") vSpecLayout.addWidget(self.__editSpecButton) hSpecLayout.addLayout(vSpecLayout) layoutEnv.addLayout(hSpecLayout) layout.addWidget(envGroupbox) # Terminal and profile limits if self.__action in ["profile", "debug"]: layout.addWidget(self.__getIDEWideGroupbox()) else: termGroupbox = self.__getTermGroupbox() termGroupbox.setTitle("Terminal to run in (IDE wide setting)") layout.addWidget(termGroupbox) # Close checkbox self.__closeCheckBox = QCheckBox("&Close terminal upon " "successful completion") self.__closeCheckBox.stateChanged.connect(self.__onCloseChanged) layout.addWidget(self.__closeCheckBox) # Buttons at the bottom buttonBox = QDialogButtonBox(self) buttonBox.setOrientation(Qt.Horizontal) buttonBox.setStandardButtons(QDialogButtonBox.Cancel) self.__runButton = buttonBox.addButton(action, QDialogButtonBox.AcceptRole) self.__runButton.setDefault(True) self.__runButton.clicked.connect(self.onAccept) layout.addWidget(buttonBox) buttonBox.rejected.connect(self.close) return def __getTermGroupbox(self): " Creates the term groupbox " termGroupbox = QGroupBox(self) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( termGroupbox.sizePolicy().hasHeightForWidth()) termGroupbox.setSizePolicy(sizePolicy) layoutTerm = QVBoxLayout(termGroupbox) self.__redirectRButton = QRadioButton(termGroupbox) self.__redirectRButton.setText("&Redirect to IDE") self.__redirectRButton.toggled.connect(self.__redirectedChanged) layoutTerm.addWidget(self.__redirectRButton) self.__autoRButton = QRadioButton(termGroupbox) self.__autoRButton.setText("Aut&o detection") layoutTerm.addWidget(self.__autoRButton) self.__konsoleRButton = QRadioButton(termGroupbox) self.__konsoleRButton.setText("Default &KDE konsole") layoutTerm.addWidget(self.__konsoleRButton) self.__gnomeRButton = QRadioButton(termGroupbox) self.__gnomeRButton.setText("gnome-&terminal") layoutTerm.addWidget(self.__gnomeRButton) self.__xtermRButton = QRadioButton(termGroupbox) self.__xtermRButton.setText("&xterm") layoutTerm.addWidget(self.__xtermRButton) return termGroupbox def __redirectedChanged(self, checked): " Triggered when the redirected radio button changes its state " self.__closeCheckBox.setEnabled(not checked) return def __getIDEWideGroupbox(self): " Creates the IDE wide groupbox " ideGroupbox = QGroupBox(self) ideGroupbox.setTitle("IDE Wide Settings") sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( ideGroupbox.sizePolicy().hasHeightForWidth()) ideGroupbox.setSizePolicy(sizePolicy) layoutIDE = QHBoxLayout(ideGroupbox) termGroupbox = self.__getTermGroupbox() termGroupbox.setTitle("Terminal to run in") layoutIDE.addWidget(termGroupbox) if self.__action == "profile": # Profile version of the dialog limitsGroupbox = self.__getProfileLimitsGroupbox() layoutIDE.addWidget(limitsGroupbox) else: # Debug version of the dialog dbgGroupbox = self.__getDebugGroupbox() layoutIDE.addWidget(dbgGroupbox) return ideGroupbox def __getProfileLimitsGroupbox(self): " Creates the profile limits groupbox " limitsGroupbox = QGroupBox(self) limitsGroupbox.setTitle("Profiler diagram limits") sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( limitsGroupbox.sizePolicy().hasHeightForWidth()) limitsGroupbox.setSizePolicy(sizePolicy) layoutLimits = QGridLayout(limitsGroupbox) self.__nodeLimitEdit = QLineEdit() self.__nodeLimitEdit.textEdited.connect(self.__setRunButtonProps) self.__nodeLimitValidator = QDoubleValidator(0.0, 100.0, 2, self) self.__nodeLimitValidator.setNotation( QDoubleValidator.StandardNotation) self.__nodeLimitEdit.setValidator(self.__nodeLimitValidator) nodeLimitLabel = QLabel("Hide nodes below") self.__edgeLimitEdit = QLineEdit() self.__edgeLimitEdit.textEdited.connect(self.__setRunButtonProps) self.__edgeLimitValidator = QDoubleValidator(0.0, 100.0, 2, self) self.__edgeLimitValidator.setNotation( QDoubleValidator.StandardNotation) self.__edgeLimitEdit.setValidator(self.__edgeLimitValidator) edgeLimitLabel = QLabel("Hide edges below") layoutLimits.addWidget(nodeLimitLabel, 0, 0) layoutLimits.addWidget(self.__nodeLimitEdit, 0, 1) layoutLimits.addWidget(QLabel("%"), 0, 2) layoutLimits.addWidget(edgeLimitLabel, 1, 0) layoutLimits.addWidget(self.__edgeLimitEdit, 1, 1) layoutLimits.addWidget(QLabel("%"), 1, 2) return limitsGroupbox def __getDebugGroupbox(self): " Creates the debug settings groupbox " dbgGroupbox = QGroupBox(self) dbgGroupbox.setTitle("Debugger") sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( dbgGroupbox.sizePolicy().hasHeightForWidth()) dbgGroupbox.setSizePolicy(sizePolicy) dbgLayout = QVBoxLayout(dbgGroupbox) self.__reportExceptionCheckBox = QCheckBox("Report &exceptions") self.__reportExceptionCheckBox.stateChanged.connect( self.__onReportExceptionChanged) self.__traceInterpreterCheckBox = QCheckBox("T&race interpreter libs") self.__traceInterpreterCheckBox.stateChanged.connect( self.__onTraceInterpreterChanged) self.__stopAtFirstCheckBox = QCheckBox("Stop at first &line") self.__stopAtFirstCheckBox.stateChanged.connect( self.__onStopAtFirstChanged) self.__autoforkCheckBox = QCheckBox("&Fork without asking") self.__autoforkCheckBox.stateChanged.connect(self.__onAutoforkChanged) self.__debugChildCheckBox = QCheckBox("Debu&g child process") self.__debugChildCheckBox.stateChanged.connect(self.__onDebugChild) dbgLayout.addWidget(self.__reportExceptionCheckBox) dbgLayout.addWidget(self.__traceInterpreterCheckBox) dbgLayout.addWidget(self.__stopAtFirstCheckBox) dbgLayout.addWidget(self.__autoforkCheckBox) dbgLayout.addWidget(self.__debugChildCheckBox) return dbgGroupbox @staticmethod def __tuneTable(table): " Sets the common settings for a table " table.setAlternatingRowColors(True) table.setRootIsDecorated(False) table.setItemsExpandable(False) table.setUniformRowHeights(True) table.setSelectionMode(QAbstractItemView.SingleSelection) table.setSelectionBehavior(QAbstractItemView.SelectRows) table.setItemDelegate(NoOutlineHeightDelegate(4)) table.setHeaderLabels(["Variable", "Value"]) header = table.header() header.setSortIndicator(0, Qt.AscendingOrder) header.setSortIndicatorShown(True) header.setClickable(True) table.setSortingEnabled(True) return def __scriptWDirClicked(self): " The script working dir button is clicked " self.__dirEdit.setEnabled(False) self.__dirSelectButton.setEnabled(False) self.runParams.useScriptLocation = True self.__setRunButtonProps() return def __dirClicked(self): " The script specific working dir button is clicked " self.__dirEdit.setEnabled(True) self.__dirSelectButton.setEnabled(True) self.runParams.useScriptLocation = False self.__setRunButtonProps() return def __argsChanged(self, value): " Triggered when cmd line args are changed " value = str(value).strip() self.runParams.arguments = value self.__setRunButtonProps() return def __workingDirChanged(self, value): " Triggered when a working dir value is changed " value = str(value) self.runParams.specificDir = value self.__setRunButtonProps() return def __onCloseChanged(self, state): " Triggered when the close terminal check box changed " self.runParams.closeTerminal = state != 0 return def __onReportExceptionChanged(self, state): " Triggered when exception report check box changed " self.debuggerParams.reportExceptions = state != 0 return def __onTraceInterpreterChanged(self, state): " Triggered when trace interpreter changed " self.debuggerParams.traceInterpreter = state != 0 return def __onStopAtFirstChanged(self, state): " Triggered when stop at first changed " self.debuggerParams.stopAtFirstLine = state != 0 return def __onAutoforkChanged(self, state): " Triggered when autofork changed " self.debuggerParams.autofork = state != 0 self.__debugChildCheckBox.setEnabled(self.debuggerParams.autofork) return def __onDebugChild(self, state): " Triggered when debug child changed " self.debuggerParams.followChild = state != 0 return def __argumentsOK(self): " Returns True if the arguments are OK " try: parseCommandLineArguments(self.runParams.arguments) return True except: return False def __dirOK(self): " Returns True if the working dir is OK " if self.__scriptWDRButton.isChecked(): return True return os.path.isdir(self.__dirEdit.text()) def __setRunButtonProps(self, newText=None): " Enable/disable run button and set its tooltip " if not self.__argumentsOK(): self.__runButton.setEnabled(False) self.__runButton.setToolTip("No closing quotation in arguments") return if not self.__dirOK(): self.__runButton.setEnabled(False) self.__runButton.setToolTip("The given working " "dir is not found") return if self.__nodeLimitEdit is not None: txt = self.__nodeLimitEdit.text().strip() try: value = float(txt) if value < 0.0 or value > 100.0: raise Exception("Out of range") except: self.__runButton.setEnabled(False) self.__runButton.setToolTip("The given node limit " "is out of range") return if self.__edgeLimitEdit is not None: txt = self.__edgeLimitEdit.text().strip() try: value = float(txt) if value < 0.0 or value > 100.0: raise Exception("Out of range") except: self.__runButton.setEnabled(False) self.__runButton.setToolTip("The given edge limit " "is out of range") return self.__runButton.setEnabled(True) self.__runButton.setToolTip("Save parameters and " + self.__action + " script") return def __selectDirClicked(self): " Selects the script working dir " dirName = QFileDialog.getExistingDirectory( self, "Select the script working directory", self.__dirEdit.text(), QFileDialog.Options(QFileDialog.ShowDirsOnly)) if dirName: self.__dirEdit.setText(os.path.normpath(dirName)) return def __inhClicked(self): " Inerit parent env radio button clicked " self.__setEnabledInheritedPlusEnv(False) self.__setEnabledSpecificEnv(False) self.runParams.envType = RunParameters.InheritParentEnv return def __inhPlusClicked(self): " Inherit parent and add radio button clicked " self.__setEnabledInheritedPlusEnv(True) self.__setEnabledSpecificEnv(False) self.runParams.envType = RunParameters.InheritParentEnvPlus if self.__inhPlusEnvTable.selectedIndexes(): self.__delInhButton.setEnabled(True) self.__editInhButton.setEnabled(True) else: self.__delInhButton.setEnabled(False) self.__editInhButton.setEnabled(False) return def __specClicked(self): " Specific env radio button clicked " self.__setEnabledInheritedPlusEnv(False) self.__setEnabledSpecificEnv(True) self.runParams.envType = RunParameters.SpecificEnvironment if self.__specEnvTable.selectedIndexes(): self.__delSpecButton.setEnabled(True) self.__editSpecButton.setEnabled(True) else: self.__delSpecButton.setEnabled(False) self.__editSpecButton.setEnabled(False) return @staticmethod def __delAndInsert(table, name, value): " Deletes an item by name if so; insert new; highlight it " for index in xrange(table.topLevelItemCount()): item = table.topLevelItem(index) if str(item.text(0)) == name: table.takeTopLevelItem(index) break item = QTreeWidgetItem([name, value]) table.addTopLevelItem(item) table.setCurrentItem(item) return item def __addInhClicked(self): " Add env var button clicked " dlg = EnvVarDialog() if dlg.exec_() == QDialog.Accepted: name = str(dlg.name) value = str(dlg.value) self.__delAndInsert(self.__inhPlusEnvTable, name, value) self.runParams.additionToParentEnv[name] = value self.__delInhButton.setEnabled(True) self.__editInhButton.setEnabled(True) return def __addSpecClicked(self): " Add env var button clicked " dlg = EnvVarDialog() if dlg.exec_() == QDialog.Accepted: name = str(dlg.name) value = str(dlg.value) self.__delAndInsert(self.__specEnvTable, name, value) self.runParams.specificEnv[name] = value self.__delSpecButton.setEnabled(True) self.__editSpecButton.setEnabled(True) return def __delInhClicked(self): " Delete the highlighted variable " if self.__inhPlusEnvTable.topLevelItemCount() == 0: return name = self.__inhPlusEnvTable.currentItem().text(0) for index in xrange(self.__inhPlusEnvTable.topLevelItemCount()): item = self.__inhPlusEnvTable.topLevelItem(index) if name == item.text(0): self.__inhPlusEnvTable.takeTopLevelItem(index) break del self.runParams.additionToParentEnv[str(name)] if self.__inhPlusEnvTable.topLevelItemCount() == 0: self.__delInhButton.setEnabled(False) self.__editInhButton.setEnabled(False) else: self.__inhPlusEnvTable.setCurrentItem( \ self.__inhPlusEnvTable.topLevelItem( 0 ) ) return def __delSpecClicked(self): " Delete the highlighted variable " if self.__specEnvTable.topLevelItemCount() == 0: return name = self.__specEnvTable.currentItem().text(0) for index in xrange(self.__specEnvTable.topLevelItemCount()): item = self.__specEnvTable.topLevelItem(index) if name == item.text(0): self.__specEnvTable.takeTopLevelItem(index) break del self.runParams.specificEnv[str(name)] if self.__specEnvTable.topLevelItemCount() == 0: self.__delSpecButton.setEnabled(False) self.__editSpecButton.setEnabled(False) else: self.__specEnvTable.setCurrentItem( \ self.__specEnvTable.topLevelItem( 0 ) ) return def __editInhClicked(self): " Edits the highlighted variable " if self.__inhPlusEnvTable.topLevelItemCount() == 0: return item = self.__inhPlusEnvTable.currentItem() dlg = EnvVarDialog(str(item.text(0)), str(item.text(1)), self) if dlg.exec_() == QDialog.Accepted: name = str(dlg.name) value = str(dlg.value) self.__delAndInsert(self.__inhPlusEnvTable, name, value) self.runParams.additionToParentEnv[name] = value return def __inhPlusItemActivated(self, item, column): " Triggered when a table item is activated " self.__editInhClicked() return def __editSpecClicked(self): " Edits the highlighted variable " if self.__specEnvTable.topLevelItemCount() == 0: return item = self.__specEnvTable.currentItem() dlg = EnvVarDialog(str(item.text(0)), str(item.text(1)), self) if dlg.exec_() == QDialog.Accepted: name = str(dlg.name) value = str(dlg.value) self.__delAndInsert(self.__specEnvTable, name, value) self.runParams.specificEnv[name] = value return def __specItemActivated(self, item, column): " Triggered when a table item is activated " self.__editSpecClicked() return def onAccept(self): " Saves the selected terminal and profiling values " if self.__redirectRButton.isChecked(): self.termType = TERM_REDIRECT elif self.__autoRButton.isChecked(): self.termType = TERM_AUTO elif self.__konsoleRButton.isChecked(): self.termType = TERM_KONSOLE elif self.__gnomeRButton.isChecked(): self.termType = TERM_GNOME else: self.termType = TERM_XTERM if self.__action == "profile": self.profilerParams.nodeLimit = float(self.__nodeLimitEdit.text()) self.profilerParams.edgeLimit = float(self.__edgeLimitEdit.text()) self.accept() return
class DBDatabasesWidget(QWidget): """Displays a list of Databases""" def __init__(self, parent=None): QWidget.__init__(self, parent) self.debug = False self.db = None self.setWindowTitle("Databases") #s#elf.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) self.mainLayout = QVBoxLayout() self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.setSpacing(0) self.setLayout(self.mainLayout) #============================================= ## Top Toolbar topBar = QToolBar() topBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.mainLayout.addWidget(topBar) ## Add the action buttons topBar.addAction(Ico.icon(Ico.ServerAdd), "Add", self.on_server_add) self.actionServerEdit = topBar.addAction(Ico.icon(Ico.ServerEdit), "Edit", self.on_server_edit) self.actionServerDelete = topBar.addAction(Ico.icon(Ico.ServerDelete), "Delete", self.on_server_delete) #============================================= ## Tree self.tree = QTreeWidget() self.mainLayout.addWidget(self.tree) self.tree.setHeaderLabels(["Server", "User", ""]) self.tree.setUniformRowHeights(True) self.tree.setRootIsDecorated(False) self.tree.setColumnWidth(C.widget, 20) self.connect( self.tree, SIGNAL( 'itemSelectionChanged()' ), self.on_tree_selection_changed ) self.connect( self.tree, SIGNAL( 'itemDoubleClicked (QTreeWidgetItem *,int)' ), self.on_tree_double_clicked ) self.buttGroup = QButtonGroup(self) self.connect(self.buttGroup, SIGNAL("buttonClicked(QAbstractButton*)"), self.on_open_server) self.on_tree_selection_changed() self.load_servers() #======================================= ##== Tree Events def on_tree_selection_changed(self): disabled = self.tree.selectionModel().hasSelection() == False self.actionServerEdit.setDisabled(disabled) self.actionServerDelete.setDisabled(disabled) def on_tree_double_clicked(self): self.actionServerEdit.trigger() #======================================= ## Server Actions def on_server_add(self): self.show_server_dialog(None) def on_server_edit(self): item = self.tree.currentItem() if item == None: return server = str(item.text(C.server)) self.show_server_dialog(server) def show_server_dialog(self, server=None): d = DBServerDialog.DBServerDialog(self, server) if d.exec_(): self.load_servers() def on_open_server(self, butt): self.emit(SIGNAL("open_server"), butt.property("server").toString()) def load_servers(self): """Load servers from :py:meth:`pyqtdb.XSettings.XSettings.get_servers` """ self.tree.clear() for butt in self.buttGroup.buttons(): self.buttGroup.removeButton(butt) for srv in G.settings.get_servers_list(): item = QTreeWidgetItem() item.setText(C.server, srv['server']) item.setText(C.user, srv['user']) self.tree.addTopLevelItem(item) butt = QToolButton() butt.setIcon(Ico.icon(Ico.Connect)) butt.setProperty("server", srv['server']) self.tree.setItemWidget(item, C.widget, butt) self.buttGroup.addButton(butt) def on_server_delete(self): item = self.tree.currentItem() if item == None: return srv = str(item.text(C.server)) G.settings.delete_server(srv) self.load_servers()
class OWdictyExpress(OWWidget): name = "dictyExpress" description = "Time-course gene expression data" icon = "../widgets/icons/logo_dE.png" want_main_area = True priority = 37 inputs = [] outputs = [("Data", Table)] username = settings.Setting('*****@*****.**') password = settings.Setting('') setTimeVariable = settings.Setting(False) def __init__(self): super().__init__() self.res = None self.server = 'https://dictyexpress.research.bcm.edu' self.headerLabels = [x[1] for x in Labels] self.searchString = "" self.items = [] self.lastSelected = None # store last selected customTreeItem # Login Section box = gui.widgetBox(self.controlArea, 'Login') self.namefield = gui.lineEdit(box, self, "username", "Username:"******"password", "Password:"******"setTimeVariable", "Set Time variable") self.time_var_checkBox.setToolTip('Create new column where each row represents one time point') self.controlArea.layout().addWidget(h_line()) self.commit_button = gui.button(self.controlArea, self, "Commit", callback=self.commit) self.handle_commit_button(False) self.refresh_button = gui.button(self.controlArea, self, "Refresh", callback=self.refresh) self.handle_cache_button(True) gui.rubber(self.controlArea) # Experiment Section label = QLabel("Available projects:") my_font = QFont() my_font.setBold(True) label.setFont(my_font) self.mainArea.layout().addWidget(label) self.mainArea.layout().addWidget(h_line()) self.filter = gui.lineEdit(self.mainArea, self, "searchString", "Filter:", callbackOnType=True, callback=self.search_update) self.experimentsWidget = QTreeWidget(alternatingRowColors=True, rootIsDecorated=False, uniformRowHeights=True, sortingEnabled=True) self.experimentsWidget.setItemDelegateForColumn( 0, gui.IndicatorItemDelegate(self, role=Qt.DisplayRole)) self.experimentsWidget.selectionModel().selectionChanged.connect( self.onSelectionChanged) self.experimentsWidget.setHeaderLabels(self.headerLabels) self.mainArea.layout().addWidget(self.experimentsWidget) if self.username and self.password: self.connect() def auth_set(self): self.passfield.setDisabled(not self.username) def auth_changed(self): self.auth_set() self.connect() def refresh(self): self.reset() self.load_experiments() def reset(self): self.experimentsWidget.clear() # clear QTreeWidget self.items = [] self.lastSelected = None self.searchString = "" self.handle_commit_button(False) def search_update(self): parts = self.searchString.split() for item in self.items: item.setHidden(not all(s in item for s in parts)) def connect(self): self.res = None self.error(1) self.reset() self.handle_commit_button(False) self.handle_cache_button(False) if self.username and self.password: try: self.res = resolwe.connect(self.username, self.password, self.server, 'genesis') except resolwe.ResolweAuthException as e: self.error(1, e.args[0]) else: self.load_experiments() self.handle_cache_button(True) def load_experiments(self): with self.progressBar(100) as progress: if self.res: try: experiments = self.res.fetch_etc_objects(progress.advance) # returns a list of experiments except ConnectionError as e: self.error(1, e.args[0]) else: self.load_tree_items(experiments) def load_tree_items(self, list_of_exp): self.items = [CustomTreeItem(self.experimentsWidget, item) for item in list_of_exp] for i in range(len(self.headerLabels)): self.experimentsWidget.resizeColumnToContents(i) def onSelectionChanged(self): self.handle_commit_button(True) def handle_commit_button(self, handle): self.commit_button.setEnabled(handle) def handle_cache_button(self, handle): self.refresh_button.setEnabled(handle) def commit(self): self.error(1) with self.progressBar(100) as progress: selected_item = self.experimentsWidget.currentItem() # get selected TreeItem if self.lastSelected: self.lastSelected.setData(0, Qt.DisplayRole, "") self.lastSelected = selected_item selected_item.setData(0, Qt.DisplayRole, " ") try: etc_json = self.res.download_etc_data(selected_item.gen_data_id, progress.advance) except (HTTPError, ConnectionError, ValueError) as e: self.error(1, e.args[0]) else: data = self.res.etc_to_table(etc_json, self.setTimeVariable, progress.advance) self.send("Data", data)
class EditorConfiguration(QWidget): """EditorConfiguration widget class""" def __init__(self, parent): super(EditorConfiguration, self).__init__() self._preferences, vbox = parent, QVBoxLayout(self) # groups group1 = QGroupBox(translations.TR_PREFERENCES_EDITOR_CONFIG_INDENT) group2 = QGroupBox(translations.TR_PREFERENCES_EDITOR_CONFIG_MARGIN) group3 = QGroupBox(translations.TR_LINT_DIRTY_TEXT) group4 = QGroupBox(translations.TR_PEP8_DIRTY_TEXT) group5 = QGroupBox(translations.TR_HIGHLIGHTER_EXTRAS) group6 = QGroupBox(translations.TR_TYPING_ASSISTANCE) group7 = QGroupBox(translations.TR_DISPLAY) # groups container container_widget_with_all_preferences = QWidget() formFeatures = QGridLayout(container_widget_with_all_preferences) # Indentation hboxg1 = QHBoxLayout(group1) hboxg1.setContentsMargins(5, 15, 5, 5) self._spin, self._checkUseTabs = QSpinBox(), QComboBox() self._spin.setRange(1, 10) self._spin.setValue(settings.INDENT) hboxg1.addWidget(self._spin) self._checkUseTabs.addItems([ translations.TR_PREFERENCES_EDITOR_CONFIG_SPACES.capitalize(), translations.TR_PREFERENCES_EDITOR_CONFIG_TABS.capitalize()]) self._checkUseTabs.setCurrentIndex(int(settings.USE_TABS)) hboxg1.addWidget(self._checkUseTabs) formFeatures.addWidget(group1, 0, 0) # Margin Line hboxg2 = QHBoxLayout(group2) hboxg2.setContentsMargins(5, 15, 5, 5) self._checkShowMargin = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_MARGIN_LINE) self._checkShowMargin.setChecked(settings.SHOW_MARGIN_LINE) hboxg2.addWidget(self._checkShowMargin) self._spinMargin = QSpinBox() self._spinMargin.setRange(50, 100) self._spinMargin.setSingleStep(2) self._spinMargin.setValue(settings.MARGIN_LINE) hboxg2.addWidget(self._spinMargin) hboxg2.addWidget(QLabel(translations.TR_CHARACTERS)) formFeatures.addWidget(group2, 0, 1) # Display Errors vboxDisplay = QVBoxLayout(group7) vboxDisplay.setContentsMargins(5, 15, 5, 5) self._checkHighlightLine = QComboBox() self._checkHighlightLine.addItems([ translations.TR_PREFERENCES_EDITOR_CONFIG_ERROR_USE_BACKGROUND, translations.TR_PREFERENCES_EDITOR_CONFIG_ERROR_USE_UNDERLINE]) self._checkHighlightLine.setCurrentIndex( int(settings.UNDERLINE_NOT_BACKGROUND)) hboxDisplay1 = QHBoxLayout() hboxDisplay1.addWidget(QLabel(translations.TR_DISPLAY_ERRORS)) hboxDisplay1.addWidget(self._checkHighlightLine) hboxDisplay2 = QHBoxLayout() self._checkDisplayLineNumbers = QCheckBox( translations.TR_DISPLAY_LINE_NUMBERS) self._checkDisplayLineNumbers.setChecked(settings.SHOW_LINE_NUMBERS) hboxDisplay2.addWidget(self._checkDisplayLineNumbers) vboxDisplay.addLayout(hboxDisplay1) vboxDisplay.addLayout(hboxDisplay2) formFeatures.addWidget(group7, 1, 0, 1, 0) # Find Lint Errors (highlighter) vboxg3 = QVBoxLayout(group3) self._checkErrors = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_FIND_ERRORS) self._checkErrors.setChecked(settings.FIND_ERRORS) self.connect(self._checkErrors, SIGNAL("stateChanged(int)"), self._disable_show_errors) self._showErrorsOnLine = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_TOOLTIP_ERRORS) self._showErrorsOnLine.setChecked(settings.ERRORS_HIGHLIGHT_LINE) self.connect(self._showErrorsOnLine, SIGNAL("stateChanged(int)"), self._enable_errors_inline) vboxg3.addWidget(self._checkErrors) vboxg3.addWidget(self._showErrorsOnLine) vboxg3.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding)) formFeatures.addWidget(group3, 2, 0) # Find PEP8 Errors (highlighter) vboxg4 = QHBoxLayout(group4) vboxg4.setContentsMargins(5, 15, 5, 5) vvbox = QVBoxLayout() self._checkStyle = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_PEP8) self._checkStyle.setChecked(settings.CHECK_STYLE) self.connect(self._checkStyle, SIGNAL("stateChanged(int)"), self._disable_check_style) vvbox.addWidget(self._checkStyle) self._checkStyleOnLine = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_TOOLTIP_PEP8) self._checkStyleOnLine.setChecked(settings.CHECK_HIGHLIGHT_LINE) self.connect(self._checkStyleOnLine, SIGNAL("stateChanged(int)"), self._enable_check_inline) vvbox.addWidget(self._checkStyleOnLine) vvbox.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) vboxg4.addLayout(vvbox) # Container for tree widget and buttons widget = QWidget() hhbox = QHBoxLayout(widget) hhbox.setContentsMargins(0, 0, 0, 0) # Tree Widget with custom item delegate # always adds uppercase text self._listIgnoreViolations = QTreeWidget() self._listIgnoreViolations.setObjectName("ignore_pep8") self._listIgnoreViolations.setItemDelegate(ui_tools.CustomDelegate()) self._listIgnoreViolations.setMaximumHeight(80) self._listIgnoreViolations.setHeaderLabel( translations.TR_PREFERENCES_EDITOR_CONFIG_IGNORE_PEP8) for ic in settings.IGNORE_PEP8_LIST: self._listIgnoreViolations.addTopLevelItem(QTreeWidgetItem([ic])) hhbox.addWidget(self._listIgnoreViolations) box = QVBoxLayout() box.setContentsMargins(0, 0, 0, 0) btn_add = QPushButton(QIcon(":img/add_small"), '') btn_add.setMaximumSize(26, 24) btn_add.clicked.connect(self._add_code_pep8) box.addWidget(btn_add) btn_remove = QPushButton(QIcon(":img/delete_small"), '') btn_remove.setMaximumSize(26, 24) btn_remove.clicked.connect(self._remove_code_pep8) box.addWidget(btn_remove) box.addItem(QSpacerItem(0, 0, QSizePolicy.Fixed, QSizePolicy.Expanding)) hhbox.addLayout(box) vboxg4.addWidget(widget) formFeatures.addWidget(group4) # Show Python3 Migration, DocStrings and Spaces (highlighter) vboxg5 = QVBoxLayout(group5) vboxg5.setContentsMargins(5, 15, 5, 5) self._showMigrationTips = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_MIGRATION) self._showMigrationTips.setChecked(settings.SHOW_MIGRATION_TIPS) vboxg5.addWidget(self._showMigrationTips) self._checkForDocstrings = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_CHECK_FOR_DOCSTRINGS) self._checkForDocstrings.setChecked(settings.CHECK_FOR_DOCSTRINGS) vboxg5.addWidget(self._checkForDocstrings) self._checkShowSpaces = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_TABS_AND_SPACES) self._checkShowSpaces.setChecked(settings.SHOW_TABS_AND_SPACES) vboxg5.addWidget(self._checkShowSpaces) self._checkIndentationGuide = QCheckBox( translations.TR_SHOW_INDENTATION_GUIDE) self._checkIndentationGuide.setChecked(settings.SHOW_INDENTATION_GUIDE) vboxg5.addWidget(self._checkIndentationGuide) formFeatures.addWidget(group5, 3, 0) # End of line, Stop Scrolling At Last Line, Trailing space, Word wrap vboxg6 = QVBoxLayout(group6) vboxg6.setContentsMargins(5, 15, 5, 5) self._checkEndOfLine = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_END_OF_LINE) self._checkEndOfLine.setChecked(settings.USE_PLATFORM_END_OF_LINE) vboxg6.addWidget(self._checkEndOfLine) self._checkEndAtLastLine = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_END_AT_LAST_LINE) self._checkEndAtLastLine.setChecked(settings.END_AT_LAST_LINE) vboxg6.addWidget(self._checkEndAtLastLine) self._checkTrailing = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_REMOVE_TRAILING) self._checkTrailing.setChecked(settings.REMOVE_TRAILING_SPACES) vboxg6.addWidget(self._checkTrailing) self._allowWordWrap = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_WORD_WRAP) self._allowWordWrap.setChecked(settings.ALLOW_WORD_WRAP) vboxg6.addWidget(self._allowWordWrap) formFeatures.addWidget(group6, 3, 1) # pack all the groups vbox.addWidget(container_widget_with_all_preferences) vbox.addItem(QSpacerItem(0, 10, QSizePolicy.Expanding, QSizePolicy.Expanding)) self.connect(self._preferences, SIGNAL("savePreferences()"), self.save) def _add_code_pep8(self): item = QTreeWidgetItem() item.setFlags(item.flags() | Qt.ItemIsEditable) self._listIgnoreViolations.addTopLevelItem(item) self._listIgnoreViolations.setCurrentItem(item) self._listIgnoreViolations.editItem(item, 0) def _remove_code_pep8(self): index = self._listIgnoreViolations.indexOfTopLevelItem( self._listIgnoreViolations.currentItem()) self._listIgnoreViolations.takeTopLevelItem(index) def _enable_check_inline(self, val): """Method that takes a value to enable the inline style checking""" if val == Qt.Checked: self._checkStyle.setChecked(True) def _enable_errors_inline(self, val): """Method that takes a value to enable the inline errors checking""" if val == Qt.Checked: self._checkErrors.setChecked(True) def _disable_check_style(self, val): """Method that takes a value to disable the inline style checking""" if val == Qt.Unchecked: self._checkStyleOnLine.setChecked(False) def _disable_show_errors(self, val): """Method that takes a value to disable the inline errors checking""" if val == Qt.Unchecked: self._showErrorsOnLine.setChecked(False) def save(self): """Method to save settings""" qsettings = IDE.ninja_settings() settings.USE_TABS = bool(self._checkUseTabs.currentIndex()) qsettings.setValue('preferences/editor/useTabs', settings.USE_TABS) margin_line = self._spinMargin.value() settings.MARGIN_LINE = margin_line settings.pycodestylemod_update_margin_line_length(margin_line) qsettings.setValue('preferences/editor/marginLine', margin_line) settings.SHOW_MARGIN_LINE = self._checkShowMargin.isChecked() qsettings.setValue('preferences/editor/showMarginLine', settings.SHOW_MARGIN_LINE) settings.INDENT = self._spin.value() qsettings.setValue('preferences/editor/indent', settings.INDENT) endOfLine = self._checkEndOfLine.isChecked() settings.USE_PLATFORM_END_OF_LINE = endOfLine qsettings.setValue('preferences/editor/platformEndOfLine', endOfLine) settings.UNDERLINE_NOT_BACKGROUND = \ bool(self._checkHighlightLine.currentIndex()) qsettings.setValue('preferences/editor/errorsUnderlineBackground', settings.UNDERLINE_NOT_BACKGROUND) settings.FIND_ERRORS = self._checkErrors.isChecked() qsettings.setValue('preferences/editor/errors', settings.FIND_ERRORS) settings.ERRORS_HIGHLIGHT_LINE = self._showErrorsOnLine.isChecked() qsettings.setValue('preferences/editor/errorsInLine', settings.ERRORS_HIGHLIGHT_LINE) settings.CHECK_STYLE = self._checkStyle.isChecked() qsettings.setValue('preferences/editor/checkStyle', settings.CHECK_STYLE) settings.SHOW_MIGRATION_TIPS = self._showMigrationTips.isChecked() qsettings.setValue('preferences/editor/showMigrationTips', settings.SHOW_MIGRATION_TIPS) settings.CHECK_HIGHLIGHT_LINE = self._checkStyleOnLine.isChecked() qsettings.setValue('preferences/editor/checkStyleInline', settings.CHECK_HIGHLIGHT_LINE) settings.END_AT_LAST_LINE = self._checkEndAtLastLine.isChecked() qsettings.setValue('preferences/editor/endAtLastLine', settings.END_AT_LAST_LINE) settings.REMOVE_TRAILING_SPACES = self._checkTrailing.isChecked() qsettings.setValue('preferences/editor/removeTrailingSpaces', settings.REMOVE_TRAILING_SPACES) settings.ALLOW_WORD_WRAP = self._allowWordWrap.isChecked() qsettings.setValue('preferences/editor/allowWordWrap', settings.ALLOW_WORD_WRAP) settings.SHOW_TABS_AND_SPACES = self._checkShowSpaces.isChecked() qsettings.setValue('preferences/editor/showTabsAndSpaces', settings.SHOW_TABS_AND_SPACES) settings.SHOW_INDENTATION_GUIDE = ( self._checkIndentationGuide.isChecked()) qsettings.setValue('preferences/editor/showIndentationGuide', settings.SHOW_INDENTATION_GUIDE) settings.CHECK_FOR_DOCSTRINGS = self._checkForDocstrings.isChecked() qsettings.setValue('preferences/editor/checkForDocstrings', settings.CHECK_FOR_DOCSTRINGS) settings.SHOW_LINE_NUMBERS = self._checkDisplayLineNumbers.isChecked() qsettings.setValue('preferences/editor/showLineNumbers', settings.SHOW_LINE_NUMBERS) current_ignores = set(settings.IGNORE_PEP8_LIST) new_ignore_codes = [] # Get pep8 from tree widget for index in range(self._listIgnoreViolations.topLevelItemCount()): ignore_code = self._listIgnoreViolations.topLevelItem( index).text(0) if ignore_code: new_ignore_codes.append(ignore_code.strip()) # pep8 list that will be removed to_remove = [x for x in current_ignores if x not in new_ignore_codes] # Update list settings.IGNORE_PEP8_LIST = new_ignore_codes qsettings.setValue('preferences/editor/defaultIgnorePep8', settings.IGNORE_PEP8_LIST) # Add for ignore_code in settings.IGNORE_PEP8_LIST: settings.pycodestylemod_add_ignore(ignore_code) # Remove for ignore_code in to_remove: settings.pycodestylemod_remove_ignore(ignore_code) if settings.USE_TABS: settings.pycodestylemod_add_ignore("W191") else: settings.pycodestylemod_remove_ignore("W191")
class FontsColors(preferences.Page): def __init__(self, dialog): super(FontsColors, self).__init__(dialog) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.scheme = SchemeSelector(self) layout.addWidget(self.scheme) self.printScheme = QCheckBox() layout.addWidget(self.printScheme) hbox = QHBoxLayout() self.tree = QTreeWidget(self) self.tree.setHeaderHidden(True) self.tree.setAnimated(True) self.stack = QStackedWidget(self) hbox.addWidget(self.tree) hbox.addWidget(self.stack) layout.addLayout(hbox) hbox = QHBoxLayout() self.fontLabel = QLabel() self.fontChooser = QFontComboBox() self.fontSize = QDoubleSpinBox() self.fontSize.setRange(6.0, 32.0) self.fontSize.setSingleStep(0.5) self.fontSize.setDecimals(1) hbox.addWidget(self.fontLabel) hbox.addWidget(self.fontChooser, 1) hbox.addWidget(self.fontSize) layout.addLayout(hbox) # add the items to our list self.baseColorsItem = i = QTreeWidgetItem() self.tree.addTopLevelItem(i) self.defaultStylesItem = i = QTreeWidgetItem() self.tree.addTopLevelItem(i) self.defaultStyles = {} for name in textformats.defaultStyles: self.defaultStyles[name] = i = QTreeWidgetItem() self.defaultStylesItem.addChild(i) i.name = name self.defaultStylesItem.setExpanded(True) self.allStyles = {} for group, styles in ly.colorize.default_mapping(): i = QTreeWidgetItem() children = {} self.allStyles[group] = (i, children) self.tree.addTopLevelItem(i) i.group = group for name, base, clss in styles: j = QTreeWidgetItem() j.name = name j.base = base i.addChild(j) children[name] = j self.baseColorsWidget = BaseColors(self) self.customAttributesWidget = CustomAttributes(self) self.emptyWidget = QWidget(self) self.stack.addWidget(self.baseColorsWidget) self.stack.addWidget(self.customAttributesWidget) self.stack.addWidget(self.emptyWidget) self.tree.currentItemChanged.connect(self.currentItemChanged) self.tree.setCurrentItem(self.baseColorsItem) self.scheme.currentChanged.connect(self.currentSchemeChanged) self.scheme.changed.connect(self.changed) self.baseColorsWidget.changed.connect(self.baseColorsChanged) self.customAttributesWidget.changed.connect(self.customAttributesChanged) self.fontChooser.currentFontChanged.connect(self.fontChanged) self.fontSize.valueChanged.connect(self.fontChanged) self.printScheme.clicked.connect(self.printSchemeChanged) app.translateUI(self) def translateUI(self): self.printScheme.setText(_("Use this scheme for printing")) self.fontLabel.setText(_("Font:")) self.baseColorsItem.setText(0, _("Base Colors")) self.defaultStylesItem.setText(0, _("Default Styles")) self.defaultStyleNames = defaultStyleNames() self.allStyleNames = allStyleNames() for name in textformats.defaultStyles: self.defaultStyles[name].setText(0, self.defaultStyleNames[name]) for group, styles in ly.colorize.default_mapping(): self.allStyles[group][0].setText(0, self.allStyleNames[group][0]) for name, base, clss in styles: self.allStyles[group][1][name].setText(0, self.allStyleNames[group][1][name]) def currentItemChanged(self, item, previous): if item is self.baseColorsItem: self.stack.setCurrentWidget(self.baseColorsWidget) elif not item.parent(): self.stack.setCurrentWidget(self.emptyWidget) else: data = self.data[self.scheme.currentScheme()] w = self.customAttributesWidget self.stack.setCurrentWidget(w) toptext = None if item.parent() is self.defaultStylesItem: # default style w.setTitle(item.text(0)) w.setTristate(False) w.setTextFormat(data.defaultStyles[item.name]) else: # specific style of specific group group, name = item.parent().group, item.name w.setTitle("{0}: {1}".format(item.parent().text(0), item.text(0))) inherit = item.base if inherit: toptext = _("(Inherits: {name})").format(name=self.defaultStyleNames[inherit]) w.setTristate(bool(inherit)) w.setTextFormat(data.allStyles[group][name]) w.setTopText(toptext) def currentSchemeChanged(self): scheme = self.scheme.currentScheme() if scheme not in self.data: self.data[scheme] = textformats.TextFormatData(scheme) self.updateDisplay() if self.tree.currentItem(): self.currentItemChanged(self.tree.currentItem(), None) with qutil.signalsBlocked(self.printScheme): self.printScheme.setChecked(scheme == self._printScheme) def fontChanged(self): data = self.data[self.scheme.currentScheme()] data.font = self.fontChooser.currentFont() data.font.setPointSizeF(self.fontSize.value()) self.updateDisplay() self.changed.emit() def printSchemeChanged(self): if self.printScheme.isChecked(): self._printScheme = self.scheme.currentScheme() else: self._printScheme = None self.changed.emit() def addSchemeData(self, scheme, tfd): self.data[scheme] = tfd def currentSchemeData(self): return self.data[self.scheme.currentScheme()] def updateDisplay(self): data = self.data[self.scheme.currentScheme()] with qutil.signalsBlocked(self.fontChooser, self.fontSize): self.fontChooser.setCurrentFont(data.font) self.fontSize.setValue(data.font.pointSizeF()) with qutil.signalsBlocked(self): # update base colors for name in textformats.baseColors: self.baseColorsWidget.color[name].setColor(data.baseColors[name]) # update base colors for whole treewidget p = QApplication.palette() p.setColor(QPalette.Base, data.baseColors['background']) p.setColor(QPalette.Text, data.baseColors['text']) p.setColor(QPalette.Highlight, data.baseColors['selectionbackground']) p.setColor(QPalette.HighlightedText, data.baseColors['selectiontext']) self.tree.setPalette(p) def setItemTextFormat(item, f): font = QFont(data.font) if f.hasProperty(QTextFormat.ForegroundBrush): item.setForeground(0, f.foreground().color()) else: item.setForeground(0, data.baseColors['text']) if f.hasProperty(QTextFormat.BackgroundBrush): item.setBackground(0, f.background().color()) else: item.setBackground(0, QBrush()) font.setWeight(f.fontWeight()) font.setItalic(f.fontItalic()) font.setUnderline(f.fontUnderline()) item.setFont(0, font) # update looks of default styles for name in textformats.defaultStyles: setItemTextFormat(self.defaultStyles[name], data.defaultStyles[name]) # update looks of all the specific styles for group, styles in ly.colorize.default_mapping(): children = self.allStyles[group][1] for name, inherit, clss in styles: f = QTextCharFormat(data.defaultStyles[inherit]) if inherit else QTextCharFormat() f.merge(data.allStyles[group][name]) setItemTextFormat(children[name], f) def baseColorsChanged(self, name): # keep data up to date with base colors data = self.data[self.scheme.currentScheme()] data.baseColors[name] = self.baseColorsWidget.color[name].color() self.updateDisplay() self.changed.emit() def customAttributesChanged(self): item = self.tree.currentItem() if not item or not item.parent(): return data = self.data[self.scheme.currentScheme()] if item.parent() is self.defaultStylesItem: # a default style has been changed data.defaultStyles[item.name] = self.customAttributesWidget.textFormat() else: # a specific style has been changed group, name = item.parent().group, item.name data.allStyles[group][name] = self.customAttributesWidget.textFormat() self.updateDisplay() self.changed.emit() def import_(self, filename): from . import import_export import_export.importTheme(filename, self, self.scheme) def export(self, name, filename): from . import import_export try: import_export.exportTheme(self, name, filename) except (IOError, OSError) as e: QMessageBox.critical(self, _("Error"), _( "Can't write to destination:\n\n{url}\n\n{error}").format( url=filename, error=e.strerror)) def loadSettings(self): self.data = {} # holds all data with scheme as key self._printScheme = QSettings().value("printer_scheme", "default", type("")) self.scheme.loadSettings("editor_scheme", "editor_schemes") def saveSettings(self): self.scheme.saveSettings("editor_scheme", "editor_schemes", "fontscolors") for scheme in self.scheme.schemes(): if scheme in self.data: self.data[scheme].save(scheme) if self._printScheme: QSettings().setValue("printer_scheme", self._printScheme) else: QSettings().remove("printer_scheme")
class Shortcuts(preferences.Page): def __init__(self, dialog): super(Shortcuts, self).__init__(dialog) layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.scheme = SchemeSelector(self) layout.addWidget(self.scheme) self.tree = QTreeWidget(self) self.tree.setHeaderLabels([_("Command"), _("Shortcut")]) self.tree.setRootIsDecorated(False) self.tree.setColumnCount(2) self.tree.setAllColumnsShowFocus(True) self.tree.setAnimated(True) layout.addWidget(self.tree) self.edit = QPushButton( icons.get("preferences-desktop-keyboard-shortcuts"), '') layout.addWidget(self.edit) # signals self.scheme.currentChanged.connect(self.slotSchemeChanged) self.scheme.changed.connect(self.changed) self.tree.currentItemChanged.connect(self.slotCurrentItemChanged) self.tree.itemDoubleClicked.connect(self.editCurrentItem) self.edit.clicked.connect(self.editCurrentItem) # make a dict of all actions with the actions as key and the names as # value, with the collection prepended (for loading/saving) win = dialog.parent() allactions = {} for collection in actioncollectionmanager.manager( win).actionCollections(): for name, action in collection.actions().items(): allactions[action] = (collection, name) # keep a list of actions not in the menu structure left = list(allactions.keys()) def add_actions(menuitem, actions): """Add actions to a QTreeWidgetItem.""" for a in actions: if a.menu(): item = build_menu_item(a) if item.childCount(): menuitem.addChild(item) elif a in left: left.remove(a) menuitem.addChild(ShortcutItem(a, *allactions[a])) menuitem.setFlags(Qt.ItemIsEnabled) # disable selection def build_menu_item(action): """Return a QTreeWidgetItem with children for all the actions in the submenu.""" menuitem = QTreeWidgetItem() text = qutil.removeAccelerator(action.text()) menuitem.setText(0, _("Menu {name}").format(name=text)) add_actions(menuitem, action.menu().actions()) return menuitem # present the actions nicely ordered as in the menus for a in win.menuBar().actions(): menuitem = build_menu_item(a) if menuitem.childCount(): self.tree.addTopLevelItem(menuitem) # sort leftover actions left.sort(key=lambda i: i.text()) # show actions that are left, grouped by collection titlegroups = {} for a in left[:]: # copy collection, name = allactions[a] if collection.title(): titlegroups.setdefault(collection.title(), []).append(a) left.remove(a) for title in sorted(titlegroups): item = QTreeWidgetItem(["{0}:".format(title)]) for a in titlegroups[title]: item.addChild(ShortcutItem(a, *allactions[a])) self.tree.addTopLevelItem(item) item.setFlags(Qt.ItemIsEnabled) # disable selection # show other actions that were not in the menus item = QTreeWidgetItem([_("Other commands:")]) for a in left: if a.text() and not a.menu(): item.addChild(ShortcutItem(a, *allactions[a])) if item.childCount(): self.tree.addTopLevelItem(item) item.setFlags(Qt.ItemIsEnabled) # disable selection self.tree.expandAll() item = self.tree.topLevelItem(0).child(0) if _lastaction: # find the previously selected item for i in self.items(): if i.name == _lastaction: item = i break self.tree.setCurrentItem(item) self.tree.resizeColumnToContents(0) def items(self): """Yield all the items in the actions tree.""" def children(item): for i in range(item.childCount()): c = item.child(i) if c.childCount(): for c1 in children(c): yield c1 else: yield c for c in children(self.tree.invisibleRootItem()): yield c def item(self, collection, name): for item in self.items(): if item.collection.name == collection and item.name == name: return item def saveSettings(self): self.scheme.saveSettings("shortcut_scheme", "shortcut_schemes", "shortcuts") for item in self.items(): for scheme in self.scheme.schemes(): item.save(scheme) item.clearSettings() item.switchScheme(self.scheme.currentScheme()) def loadSettings(self): self.scheme.loadSettings("shortcut_scheme", "shortcut_schemes") # clear the settings in all the items for item in self.items(): item.clearSettings() item.switchScheme(self.scheme.currentScheme()) def slotSchemeChanged(self): """Called when the Scheme combobox is changed by the user.""" for item in self.items(): item.switchScheme(self.scheme.currentScheme()) def slotCurrentItemChanged(self, item): if isinstance(item, ShortcutItem): self.edit.setText( _("&Edit Shortcut for \"{name}\"").format(name=item.text(0))) self.edit.setEnabled(True) global _lastaction _lastaction = item.name else: self.edit.setText(_("(no shortcut)")) self.edit.setEnabled(False) def import_(self, filename): from . import import_export import_export.importShortcut(filename, self, self.scheme) def export(self, name, filename): from . import import_export try: import_export.exportShortcut(self, self.scheme.currentScheme(), name, filename) except (IOError, OSError) as e: QMessageBox.critical( self, _("Error"), _("Can't write to destination:\n\n{url}\n\n{error}").format( url=filename, error=e.strerror)) def findShortcutConflict(self, shortcut): """Find the possible shortcut conflict and return the conflict name.""" if shortcut: item = self.tree.currentItem() if not isinstance(item, ShortcutItem): return None scheme = self.scheme.currentScheme() for i in self.items(): a = i.action(scheme) if i != item and a.shortcuts(): for s1 in a.shortcuts(): if s1.matches(shortcut) or shortcut.matches(s1): return qutil.removeAccelerator(a.text()) return None def editCurrentItem(self): item = self.tree.currentItem() if not isinstance(item, ShortcutItem): return dlg = ShortcutEditDialog(self, self.findShortcutConflict) scheme = self.scheme.currentScheme() action = item.action(scheme) default = item.defaultShortcuts() or None if dlg.editAction(action, default): shortcuts = action.shortcuts() # check for conflicts conflicting = [] for i in self.items(): if i is not item: for s1, s2 in itertools.product(i.shortcuts(scheme), shortcuts): if s1.matches(s2) or s2.matches(s1): conflicting.append(i) if conflicting: for i in conflicting: l = i.shortcuts(scheme) for s1 in list(l): # copy for s2 in shortcuts: if s1.matches(s2) or s2.matches(s1): l.remove(s1) i.setShortcuts(l, scheme) # store the shortcut item.setShortcuts(shortcuts, scheme) self.changed.emit()
class RunDialog( QDialog ): """ Run parameters dialog implementation """ # See utils.run for runParameters def __init__( self, path, runParameters, termType, profilerParams, debuggerParams, action = "", parent = None ): QDialog.__init__( self, parent ) # Used as a return value self.termType = termType self.profilerParams = copy.deepcopy( profilerParams ) self.debuggerParams = copy.deepcopy( debuggerParams ) self.__action = action.lower() # Avoid pylint complains self.__argsEdit = None self.__scriptWDRButton = None self.__dirRButton = None self.__dirEdit = None self.__dirSelectButton = None self.__inheritParentRButton = None self.__inheritParentPlusRButton = None self.__inhPlusEnvTable = None self.__addInhButton = None self.__delInhButton = None self.__editInhButton = None self.__specificRButton = None self.__specEnvTable = None self.__addSpecButton = None self.__delSpecButton = None self.__editSpecButton = None self.__runButton = None self.__nodeLimitEdit = None self.__edgeLimitEdit = None self.__createLayout( action ) self.setWindowTitle( action + " parameters for " + path ) # Restore the values self.runParams = copy.deepcopy( runParameters ) self.__argsEdit.setText( self.runParams.arguments ) # Working dir if self.runParams.useScriptLocation: self.__scriptWDRButton.setChecked( True ) self.__dirEdit.setEnabled( False ) self.__dirSelectButton.setEnabled( False ) else: self.__dirRButton.setChecked( True ) self.__dirEdit.setEnabled( True ) self.__dirSelectButton.setEnabled( True ) self.__dirEdit.setText( self.runParams.specificDir ) # Environment self.__populateTable( self.__inhPlusEnvTable, self.runParams.additionToParentEnv ) self.__populateTable( self.__specEnvTable, self.runParams.specificEnv ) if self.runParams.envType == RunParameters.InheritParentEnv: self.__inheritParentRButton.setChecked( True ) self.__setEnabledInheritedPlusEnv( False ) self.__setEnabledSpecificEnv( False ) elif self.runParams.envType == RunParameters.InheritParentEnvPlus: self.__inheritParentPlusRButton.setChecked( True ) self.__setEnabledSpecificEnv( False ) else: self.__specificRButton.setChecked( True ) self.__setEnabledInheritedPlusEnv( False ) # Terminal if self.termType == TERM_REDIRECT: self.__redirectRButton.setChecked( True ) elif self.termType == TERM_AUTO: self.__autoRButton.setChecked( True ) elif self.termType == TERM_KONSOLE: self.__konsoleRButton.setChecked( True ) elif self.termType == TERM_GNOME: self.__gnomeRButton.setChecked( True ) else: self.__xtermRButton.setChecked( True ) # Close checkbox self.__closeCheckBox.setChecked( self.runParams.closeTerminal ) if self.termType == TERM_REDIRECT: self.__closeCheckBox.setEnabled( False ) # Profile limits if so if self.__action == "profile": if self.profilerParams.nodeLimit < 0.0 or \ self.profilerParams.nodeLimit > 100.0: self.profilerParams.nodeLimit = 1.0 self.__nodeLimitEdit.setText( str( self.profilerParams.nodeLimit ) ) if self.profilerParams.edgeLimit < 0.0 or \ self.profilerParams.edgeLimit > 100.0: self.profilerParams.edgeLimit = 1.0 self.__edgeLimitEdit.setText( str( self.profilerParams.edgeLimit ) ) elif self.__action == "debug": self.__reportExceptionCheckBox.setChecked( self.debuggerParams.reportExceptions ) self.__traceInterpreterCheckBox.setChecked( self.debuggerParams.traceInterpreter ) self.__stopAtFirstCheckBox.setChecked( self.debuggerParams.stopAtFirstLine ) self.__autoforkCheckBox.setChecked( self.debuggerParams.autofork ) self.__debugChildCheckBox.setChecked( self.debuggerParams.followChild ) self.__debugChildCheckBox.setEnabled( self.debuggerParams.autofork ) self.__setRunButtonProps() return @staticmethod def __populateTable( table, dictionary ): " Populates the given table " for key, value in dictionary.iteritems(): item = QTreeWidgetItem( [ key, value ] ) table.addTopLevelItem( item ) if dictionary: table.setCurrentItem( table.topLevelItem( 0 ) ) return def __setEnabledInheritedPlusEnv( self, value ): " Disables/enables 'inherited and add' section controls " self.__inhPlusEnvTable.setEnabled( value ) self.__addInhButton.setEnabled( value ) self.__delInhButton.setEnabled( value ) self.__editInhButton.setEnabled( value ) return def __setEnabledSpecificEnv( self, value ): " Disables/enables 'specific env' section controls " self.__specEnvTable.setEnabled( value ) self.__addSpecButton.setEnabled( value ) self.__delSpecButton.setEnabled( value ) self.__editSpecButton.setEnabled( value ) return def __createLayout( self, action ): """ Creates the dialog layout """ self.resize( 650, 300 ) self.setSizeGripEnabled( True ) # Top level layout layout = QVBoxLayout( self ) # Cmd line arguments argsLabel = QLabel( "Command line arguments" ) self.__argsEdit = QLineEdit() self.__argsEdit.textChanged.connect( self.__argsChanged ) argsLayout = QHBoxLayout() argsLayout.addWidget( argsLabel ) argsLayout.addWidget( self.__argsEdit ) layout.addLayout( argsLayout ) # Working directory workDirGroupbox = QGroupBox( self ) workDirGroupbox.setTitle( "Working directory" ) sizePolicy = QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred ) sizePolicy.setHorizontalStretch( 0 ) sizePolicy.setVerticalStretch( 0 ) sizePolicy.setHeightForWidth( \ workDirGroupbox.sizePolicy().hasHeightForWidth() ) workDirGroupbox.setSizePolicy( sizePolicy ) gridLayoutWD = QGridLayout( workDirGroupbox ) self.__scriptWDRButton = QRadioButton( workDirGroupbox ) self.__scriptWDRButton.setText( "&Use script location" ) gridLayoutWD.addWidget( self.__scriptWDRButton, 0, 0 ) self.__scriptWDRButton.clicked.connect( self.__scriptWDirClicked ) self.__dirRButton = QRadioButton( workDirGroupbox ) self.__dirRButton.setText( "Select &directory" ) gridLayoutWD.addWidget( self.__dirRButton, 1, 0 ) self.__dirRButton.clicked.connect( self.__dirClicked ) self.__dirEdit = QLineEdit( workDirGroupbox ) gridLayoutWD.addWidget( self.__dirEdit, 1, 1 ) self.__dirEdit.textChanged.connect( self.__workingDirChanged ) self.__dirSelectButton = QPushButton( workDirGroupbox ) self.__dirSelectButton.setText( "..." ) gridLayoutWD.addWidget( self.__dirSelectButton, 1, 2 ) self.__dirSelectButton.clicked.connect( self.__selectDirClicked ) layout.addWidget( workDirGroupbox ) # Environment envGroupbox = QGroupBox( self ) envGroupbox.setTitle( "Environment" ) sizePolicy = QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred ) sizePolicy.setHorizontalStretch( 0 ) sizePolicy.setVerticalStretch( 0 ) sizePolicy.setHeightForWidth( \ envGroupbox.sizePolicy().hasHeightForWidth() ) envGroupbox.setSizePolicy( sizePolicy ) layoutEnv = QVBoxLayout( envGroupbox ) self.__inheritParentRButton = QRadioButton( envGroupbox ) self.__inheritParentRButton.setText( "Inherit &parent" ) self.__inheritParentRButton.clicked.connect( self.__inhClicked ) layoutEnv.addWidget( self.__inheritParentRButton ) self.__inheritParentPlusRButton = QRadioButton( envGroupbox ) self.__inheritParentPlusRButton.setText( "Inherit parent and add/&modify" ) self.__inheritParentPlusRButton.clicked.connect( self.__inhPlusClicked ) layoutEnv.addWidget( self.__inheritParentPlusRButton ) hInhPlusLayout = QHBoxLayout() self.__inhPlusEnvTable = QTreeWidget() self.__inhPlusEnvTable.itemActivated.connect( self.__inhPlusItemActivated ) self.__tuneTable( self.__inhPlusEnvTable ) hInhPlusLayout.addWidget( self.__inhPlusEnvTable ) vInhPlusLayout = QVBoxLayout() self.__addInhButton = QPushButton() self.__addInhButton.clicked.connect( self.__addInhClicked ) self.__addInhButton.setText( 'Add' ) vInhPlusLayout.addWidget( self.__addInhButton ) self.__delInhButton = QPushButton() self.__delInhButton.clicked.connect( self.__delInhClicked ) self.__delInhButton.setText( 'Delete' ) vInhPlusLayout.addWidget( self.__delInhButton ) self.__editInhButton = QPushButton() self.__editInhButton.clicked.connect( self.__editInhClicked ) self.__editInhButton.setText( "Edit" ) vInhPlusLayout.addWidget( self.__editInhButton ) hInhPlusLayout.addLayout( vInhPlusLayout ) layoutEnv.addLayout( hInhPlusLayout ) self.__specificRButton = QRadioButton( envGroupbox ) self.__specificRButton.setText( "&Specific" ) self.__specificRButton.clicked.connect( self.__specClicked ) layoutEnv.addWidget( self.__specificRButton ) hSpecLayout = QHBoxLayout() self.__specEnvTable = QTreeWidget() self.__specEnvTable.itemActivated.connect( self.__specItemActivated ) self.__tuneTable( self.__specEnvTable ) hSpecLayout.addWidget( self.__specEnvTable ) vSpecLayout = QVBoxLayout() self.__addSpecButton = QPushButton() self.__addSpecButton.clicked.connect( self.__addSpecClicked ) self.__addSpecButton.setText( 'Add' ) vSpecLayout.addWidget( self.__addSpecButton ) self.__delSpecButton = QPushButton() self.__delSpecButton.clicked.connect( self.__delSpecClicked ) self.__delSpecButton.setText( 'Delete' ) vSpecLayout.addWidget( self.__delSpecButton ) self.__editSpecButton = QPushButton() self.__editSpecButton.clicked.connect( self.__editSpecClicked ) self.__editSpecButton.setText( "Edit" ) vSpecLayout.addWidget( self.__editSpecButton ) hSpecLayout.addLayout( vSpecLayout ) layoutEnv.addLayout( hSpecLayout ) layout.addWidget( envGroupbox ) # Terminal and profile limits if self.__action in [ "profile", "debug" ]: layout.addWidget( self.__getIDEWideGroupbox() ) else: termGroupbox = self.__getTermGroupbox() termGroupbox.setTitle( "Terminal to run in (IDE wide setting)" ) layout.addWidget( termGroupbox ) # Close checkbox self.__closeCheckBox = QCheckBox( "&Close terminal upon " "successful completion" ) self.__closeCheckBox.stateChanged.connect( self.__onCloseChanged ) layout.addWidget( self.__closeCheckBox ) # Buttons at the bottom buttonBox = QDialogButtonBox( self ) buttonBox.setOrientation( Qt.Horizontal ) buttonBox.setStandardButtons( QDialogButtonBox.Cancel ) self.__runButton = buttonBox.addButton( action, QDialogButtonBox.AcceptRole ) self.__runButton.setDefault( True ) self.__runButton.clicked.connect( self.onAccept ) layout.addWidget( buttonBox ) buttonBox.rejected.connect( self.close ) return def __getTermGroupbox( self ): " Creates the term groupbox " termGroupbox = QGroupBox( self ) sizePolicy = QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred ) sizePolicy.setHorizontalStretch( 0 ) sizePolicy.setVerticalStretch( 0 ) sizePolicy.setHeightForWidth( termGroupbox.sizePolicy().hasHeightForWidth() ) termGroupbox.setSizePolicy( sizePolicy ) layoutTerm = QVBoxLayout( termGroupbox ) self.__redirectRButton = QRadioButton( termGroupbox ) self.__redirectRButton.setText( "&Redirect to IDE" ) self.__redirectRButton.toggled.connect( self.__redirectedChanged ) layoutTerm.addWidget( self.__redirectRButton ) self.__autoRButton = QRadioButton( termGroupbox ) self.__autoRButton.setText( "Aut&o detection" ) layoutTerm.addWidget( self.__autoRButton ) self.__konsoleRButton = QRadioButton( termGroupbox ) self.__konsoleRButton.setText( "Default &KDE konsole" ) layoutTerm.addWidget( self.__konsoleRButton ) self.__gnomeRButton = QRadioButton( termGroupbox ) self.__gnomeRButton.setText( "gnome-&terminal" ) layoutTerm.addWidget( self.__gnomeRButton ) self.__xtermRButton = QRadioButton( termGroupbox ) self.__xtermRButton.setText( "&xterm" ) layoutTerm.addWidget( self.__xtermRButton ) return termGroupbox def __redirectedChanged( self, checked ): " Triggered when the redirected radio button changes its state " self.__closeCheckBox.setEnabled( not checked ) return def __getIDEWideGroupbox( self ): " Creates the IDE wide groupbox " ideGroupbox = QGroupBox( self ) ideGroupbox.setTitle( "IDE Wide Settings" ) sizePolicy = QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred ) sizePolicy.setHorizontalStretch( 0 ) sizePolicy.setVerticalStretch( 0 ) sizePolicy.setHeightForWidth( ideGroupbox.sizePolicy().hasHeightForWidth() ) ideGroupbox.setSizePolicy( sizePolicy ) layoutIDE = QHBoxLayout( ideGroupbox ) termGroupbox = self.__getTermGroupbox() termGroupbox.setTitle( "Terminal to run in" ) layoutIDE.addWidget( termGroupbox ) if self.__action == "profile": # Profile version of the dialog limitsGroupbox = self.__getProfileLimitsGroupbox() layoutIDE.addWidget( limitsGroupbox ) else: # Debug version of the dialog dbgGroupbox = self.__getDebugGroupbox() layoutIDE.addWidget( dbgGroupbox ) return ideGroupbox def __getProfileLimitsGroupbox( self ): " Creates the profile limits groupbox " limitsGroupbox = QGroupBox( self ) limitsGroupbox.setTitle( "Profiler diagram limits" ) sizePolicy = QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred ) sizePolicy.setHorizontalStretch( 0 ) sizePolicy.setVerticalStretch( 0 ) sizePolicy.setHeightForWidth( limitsGroupbox.sizePolicy().hasHeightForWidth() ) limitsGroupbox.setSizePolicy( sizePolicy ) layoutLimits = QGridLayout( limitsGroupbox ) self.__nodeLimitEdit = QLineEdit() self.__nodeLimitEdit.textEdited.connect( self.__setRunButtonProps ) self.__nodeLimitValidator = QDoubleValidator( 0.0, 100.0, 2, self ) self.__nodeLimitValidator.setNotation( QDoubleValidator.StandardNotation ) self.__nodeLimitEdit.setValidator( self.__nodeLimitValidator ) nodeLimitLabel = QLabel( "Hide nodes below" ) self.__edgeLimitEdit = QLineEdit() self.__edgeLimitEdit.textEdited.connect( self.__setRunButtonProps ) self.__edgeLimitValidator = QDoubleValidator( 0.0, 100.0, 2, self ) self.__edgeLimitValidator.setNotation( QDoubleValidator.StandardNotation ) self.__edgeLimitEdit.setValidator( self.__edgeLimitValidator ) edgeLimitLabel = QLabel( "Hide edges below" ) layoutLimits.addWidget( nodeLimitLabel, 0, 0 ) layoutLimits.addWidget( self.__nodeLimitEdit, 0, 1 ) layoutLimits.addWidget( QLabel( "%" ), 0, 2 ) layoutLimits.addWidget( edgeLimitLabel, 1, 0 ) layoutLimits.addWidget( self.__edgeLimitEdit, 1, 1 ) layoutLimits.addWidget( QLabel( "%" ), 1, 2 ) return limitsGroupbox def __getDebugGroupbox( self ): " Creates the debug settings groupbox " dbgGroupbox = QGroupBox( self ) dbgGroupbox.setTitle( "Debugger" ) sizePolicy = QSizePolicy( QSizePolicy.Expanding, QSizePolicy.Preferred ) sizePolicy.setHorizontalStretch( 0 ) sizePolicy.setVerticalStretch( 0 ) sizePolicy.setHeightForWidth( dbgGroupbox.sizePolicy().hasHeightForWidth() ) dbgGroupbox.setSizePolicy( sizePolicy ) dbgLayout = QVBoxLayout( dbgGroupbox ) self.__reportExceptionCheckBox = QCheckBox( "Report &exceptions" ) self.__reportExceptionCheckBox.stateChanged.connect( self.__onReportExceptionChanged ) self.__traceInterpreterCheckBox = QCheckBox( "T&race interpreter libs" ) self.__traceInterpreterCheckBox.stateChanged.connect( self.__onTraceInterpreterChanged ) self.__stopAtFirstCheckBox = QCheckBox( "Stop at first &line" ) self.__stopAtFirstCheckBox.stateChanged.connect( self.__onStopAtFirstChanged ) self.__autoforkCheckBox = QCheckBox( "&Fork without asking" ) self.__autoforkCheckBox.stateChanged.connect(self.__onAutoforkChanged ) self.__debugChildCheckBox = QCheckBox( "Debu&g child process" ) self.__debugChildCheckBox.stateChanged.connect( self.__onDebugChild ) dbgLayout.addWidget( self.__reportExceptionCheckBox ) dbgLayout.addWidget( self.__traceInterpreterCheckBox ) dbgLayout.addWidget( self.__stopAtFirstCheckBox ) dbgLayout.addWidget( self.__autoforkCheckBox ) dbgLayout.addWidget( self.__debugChildCheckBox ) return dbgGroupbox @staticmethod def __tuneTable( table ): " Sets the common settings for a table " table.setAlternatingRowColors( True ) table.setRootIsDecorated( False ) table.setItemsExpandable( False ) table.setUniformRowHeights( True ) table.setSelectionMode( QAbstractItemView.SingleSelection ) table.setSelectionBehavior( QAbstractItemView.SelectRows ) table.setItemDelegate( NoOutlineHeightDelegate( 4 ) ) table.setHeaderLabels( [ "Variable", "Value" ] ) header = table.header() header.setSortIndicator( 0, Qt.AscendingOrder ) header.setSortIndicatorShown( True ) header.setClickable( True ) table.setSortingEnabled( True ) return def __scriptWDirClicked( self ): " The script working dir button is clicked " self.__dirEdit.setEnabled( False ) self.__dirSelectButton.setEnabled( False ) self.runParams.useScriptLocation = True self.__setRunButtonProps() return def __dirClicked( self ): " The script specific working dir button is clicked " self.__dirEdit.setEnabled( True ) self.__dirSelectButton.setEnabled( True ) self.runParams.useScriptLocation = False self.__setRunButtonProps() return def __argsChanged( self, value ): " Triggered when cmd line args are changed " value = str( value ).strip() self.runParams.arguments = value self.__setRunButtonProps() return def __workingDirChanged( self, value ): " Triggered when a working dir value is changed " value = str( value ) self.runParams.specificDir = value self.__setRunButtonProps() return def __onCloseChanged( self, state ): " Triggered when the close terminal check box changed " self.runParams.closeTerminal = state != 0 return def __onReportExceptionChanged( self, state ): " Triggered when exception report check box changed " self.debuggerParams.reportExceptions = state != 0 return def __onTraceInterpreterChanged( self, state ): " Triggered when trace interpreter changed " self.debuggerParams.traceInterpreter = state != 0 return def __onStopAtFirstChanged( self, state ): " Triggered when stop at first changed " self.debuggerParams.stopAtFirstLine = state != 0 return def __onAutoforkChanged( self, state ): " Triggered when autofork changed " self.debuggerParams.autofork = state != 0 self.__debugChildCheckBox.setEnabled( self.debuggerParams.autofork ) return def __onDebugChild( self, state ): " Triggered when debug child changed " self.debuggerParams.followChild = state != 0 return def __argumentsOK( self ): " Returns True if the arguments are OK " try: parseCommandLineArguments( self.runParams.arguments ) return True except: return False def __dirOK( self ): " Returns True if the working dir is OK " if self.__scriptWDRButton.isChecked(): return True return os.path.isdir( self.__dirEdit.text() ) def __setRunButtonProps( self, newText = None ): " Enable/disable run button and set its tooltip " if not self.__argumentsOK(): self.__runButton.setEnabled( False ) self.__runButton.setToolTip( "No closing quotation in arguments" ) return if not self.__dirOK(): self.__runButton.setEnabled( False ) self.__runButton.setToolTip( "The given working " "dir is not found" ) return if self.__nodeLimitEdit is not None: txt = self.__nodeLimitEdit.text().strip() try: value = float( txt ) if value < 0.0 or value > 100.0: raise Exception( "Out of range" ) except: self.__runButton.setEnabled( False ) self.__runButton.setToolTip( "The given node limit " "is out of range" ) return if self.__edgeLimitEdit is not None: txt = self.__edgeLimitEdit.text().strip() try: value = float( txt ) if value < 0.0 or value > 100.0: raise Exception( "Out of range" ) except: self.__runButton.setEnabled( False ) self.__runButton.setToolTip( "The given edge limit " "is out of range" ) return self.__runButton.setEnabled( True ) self.__runButton.setToolTip( "Save parameters and " + self.__action + " script" ) return def __selectDirClicked( self ): " Selects the script working dir " dirName = QFileDialog.getExistingDirectory( self, "Select the script working directory", self.__dirEdit.text(), QFileDialog.Options( QFileDialog.ShowDirsOnly ) ) if dirName: self.__dirEdit.setText( os.path.normpath( dirName ) ) return def __inhClicked( self ): " Inerit parent env radio button clicked " self.__setEnabledInheritedPlusEnv( False ) self.__setEnabledSpecificEnv( False ) self.runParams.envType = RunParameters.InheritParentEnv return def __inhPlusClicked( self ): " Inherit parent and add radio button clicked " self.__setEnabledInheritedPlusEnv( True ) self.__setEnabledSpecificEnv( False ) self.runParams.envType = RunParameters.InheritParentEnvPlus if self.__inhPlusEnvTable.selectedIndexes(): self.__delInhButton.setEnabled( True ) self.__editInhButton.setEnabled( True ) else: self.__delInhButton.setEnabled( False ) self.__editInhButton.setEnabled( False ) return def __specClicked( self ): " Specific env radio button clicked " self.__setEnabledInheritedPlusEnv( False ) self.__setEnabledSpecificEnv( True ) self.runParams.envType = RunParameters.SpecificEnvironment if self.__specEnvTable.selectedIndexes(): self.__delSpecButton.setEnabled( True ) self.__editSpecButton.setEnabled( True ) else: self.__delSpecButton.setEnabled( False ) self.__editSpecButton.setEnabled( False ) return @staticmethod def __delAndInsert( table, name, value ): " Deletes an item by name if so; insert new; highlight it " for index in xrange( table.topLevelItemCount() ): item = table.topLevelItem( index ) if str( item.text( 0 ) ) == name: table.takeTopLevelItem( index ) break item = QTreeWidgetItem( [ name, value ] ) table.addTopLevelItem( item ) table.setCurrentItem( item ) return item def __addInhClicked( self ): " Add env var button clicked " dlg = EnvVarDialog() if dlg.exec_() == QDialog.Accepted: name = str( dlg.name ) value = str( dlg.value ) self.__delAndInsert( self.__inhPlusEnvTable, name, value ) self.runParams.additionToParentEnv[ name ] = value self.__delInhButton.setEnabled( True ) self.__editInhButton.setEnabled( True ) return def __addSpecClicked( self ): " Add env var button clicked " dlg = EnvVarDialog() if dlg.exec_() == QDialog.Accepted: name = str( dlg.name ) value = str( dlg.value ) self.__delAndInsert( self.__specEnvTable, name, value ) self.runParams.specificEnv[ name ] = value self.__delSpecButton.setEnabled( True ) self.__editSpecButton.setEnabled( True ) return def __delInhClicked( self ): " Delete the highlighted variable " if self.__inhPlusEnvTable.topLevelItemCount() == 0: return name = self.__inhPlusEnvTable.currentItem().text( 0 ) for index in xrange( self.__inhPlusEnvTable.topLevelItemCount() ): item = self.__inhPlusEnvTable.topLevelItem( index ) if name == item.text( 0 ): self.__inhPlusEnvTable.takeTopLevelItem( index ) break del self.runParams.additionToParentEnv[ str( name ) ] if self.__inhPlusEnvTable.topLevelItemCount() == 0: self.__delInhButton.setEnabled( False ) self.__editInhButton.setEnabled( False ) else: self.__inhPlusEnvTable.setCurrentItem( \ self.__inhPlusEnvTable.topLevelItem( 0 ) ) return def __delSpecClicked( self ): " Delete the highlighted variable " if self.__specEnvTable.topLevelItemCount() == 0: return name = self.__specEnvTable.currentItem().text( 0 ) for index in xrange( self.__specEnvTable.topLevelItemCount() ): item = self.__specEnvTable.topLevelItem( index ) if name == item.text( 0 ): self.__specEnvTable.takeTopLevelItem( index ) break del self.runParams.specificEnv[ str( name ) ] if self.__specEnvTable.topLevelItemCount() == 0: self.__delSpecButton.setEnabled( False ) self.__editSpecButton.setEnabled( False ) else: self.__specEnvTable.setCurrentItem( \ self.__specEnvTable.topLevelItem( 0 ) ) return def __editInhClicked( self ): " Edits the highlighted variable " if self.__inhPlusEnvTable.topLevelItemCount() == 0: return item = self.__inhPlusEnvTable.currentItem() dlg = EnvVarDialog( str( item.text( 0 ) ), str( item.text( 1 ) ), self ) if dlg.exec_() == QDialog.Accepted: name = str( dlg.name ) value = str( dlg.value ) self.__delAndInsert( self.__inhPlusEnvTable, name, value ) self.runParams.additionToParentEnv[ name ] = value return def __inhPlusItemActivated( self, item, column ): " Triggered when a table item is activated " self.__editInhClicked() return def __editSpecClicked( self ): " Edits the highlighted variable " if self.__specEnvTable.topLevelItemCount() == 0: return item = self.__specEnvTable.currentItem() dlg = EnvVarDialog( str( item.text( 0 ) ), str( item.text( 1 ) ), self ) if dlg.exec_() == QDialog.Accepted: name = str( dlg.name ) value = str( dlg.value ) self.__delAndInsert( self.__specEnvTable, name, value ) self.runParams.specificEnv[ name ] = value return def __specItemActivated( self, item, column ): " Triggered when a table item is activated " self.__editSpecClicked() return def onAccept( self ): " Saves the selected terminal and profiling values " if self.__redirectRButton.isChecked(): self.termType = TERM_REDIRECT elif self.__autoRButton.isChecked(): self.termType = TERM_AUTO elif self.__konsoleRButton.isChecked(): self.termType = TERM_KONSOLE elif self.__gnomeRButton.isChecked(): self.termType = TERM_GNOME else: self.termType = TERM_XTERM if self.__action == "profile": self.profilerParams.nodeLimit = float( self.__nodeLimitEdit.text() ) self.profilerParams.edgeLimit = float( self.__edgeLimitEdit.text() ) self.accept() return
class LibrarySearchDialog(QtGui.QDialog): def __init__(self, ms, parent=None): QtGui.QDialog.__init__(self, parent) settings = QSettings() size = settings.value("MainWindow/Size", QVariant(QSize(1024, 600))).toSize() self.resize(size) self.setWindowTitle( 'Identify unknown compound by mass spectra Library') self.ms = ms pms = processMS(ms) self.axis = pms[0] self.mass = pms[1] self.peak_MS = pms[2] self.maxmass = int(self.axis[-1]) self.initControls() self.initPlots() self.selectedIndex = [] self.percent = [] self._cpointsPicker1 = Qwt.QwtPicker(self.plot1.canvas()) self._cpointsPicker1.setSelectionFlags(Qwt.QwtPicker.PointSelection) self._cpointsPicker1.widgetMouseDoubleClickEvent = self.plot1MouseDoubleClickEvent def updatePlots(self): reply = QtGui.QMessageBox.question( self, 'EleComp Parameters', "Are you sure to Use Single Mass %s?" % self.selected_mz, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.Yes: # print self.x self.ElemCompDialog1() # self.m.setLabel(self.text1) # self.m.setValue(self.x, 0.0) # rowMs=int((self.x-self.scan_acquisition_time.data[0])/0.2) # self.showMs(rowMs) # self.plot1.replot() def plot1MouseDoubleClickEvent(self, event): self.xp = self.plot1.invTransform(Qwt.QwtPlot.xBottom, event.x()) n1 = np.searchsorted(self.axis, self.xp - 1) n2 = np.searchsorted(self.axis, self.xp + 1) self.selected_mz = self.axis[np.argmax(self.mass[n1:n2]) + n1] print self.xp print self.selected_mz self.updatePlots() def ElemCompDialog1(self): dialog = ElemCompDialog(mz=self.axis, mass=self.mass, xp=self.selected_mz) dialog.move(QPoint(100, 10)) res = dialog.exec_() def initControls(self): self.plot3 = Qwt.QwtPlot(self) self.plot3.setCanvasBackground(Qt.white) self.plot3.enableAxis(Qwt.QwtPlot.yLeft, False) self.plot3.enableAxis(Qwt.QwtPlot.xBottom, False) self.plot1 = Qwt.QwtPlot(self) self.plot1.setCanvasBackground(Qt.white) self.plot2 = Qwt.QwtPlot(self) self.plot2.setCanvasBackground(Qt.white) library_label = QLabel("MS in mass spectra Library:") self.library_list = QTreeWidget() self.library_list.setColumnCount(3) self.library_list.setHeaderLabels( ['No.', 'Similarity', 'Mol Wt', 'Formula', 'Name']) self.library_list.setSortingEnabled(False) self.connect(self.library_list, SIGNAL("itemSelectionChanged()"), self.libraryListClicked) self.connect(self.library_list, SIGNAL("itemActivated (QTreeWidgetItem *,int)"), self.libraryListDoubleClicked) mxiture_label = QLabel("Molecular structure :") # self.mixture_list = QListWidget() okButton = QPushButton("&Search") self.connect(okButton, SIGNAL("clicked()"), self.Seach) left_vbox = QVBoxLayout() left_vbox.addWidget(self.plot1) left_vbox.addWidget(self.plot2) right_vbox = QVBoxLayout() right_vbox.addWidget(library_label) right_vbox.addWidget(self.library_list) hboxPercent = QHBoxLayout() # hboxPercent.addWidget(percent_label) # hboxPercent.addWidget(self.edit_percent) right_vbox.addLayout(hboxPercent) # right_vbox.addWidget(self.add_button) right_vbox.addWidget(mxiture_label) right_vbox.addWidget(self.plot3) right_vbox.addWidget(okButton) hbox = QHBoxLayout() hbox.addLayout(left_vbox, 2.5) hbox.addLayout(right_vbox, 1.5) self.setLayout(hbox) #self.setCentralWidget(self.main_frame) def initPlots(self): self.plot3.clear() self.plot3.setAxisScale(self.plot1.xBottom, -4, 4) self.plot3.setAxisScale(self.plot1.yLeft, -4, 4) self.plot1.clear() self.plot1.setTitle("Search MS") self.plot1.setAxisTitle(Qwt.QwtPlot.yLeft, 'Intensity') grid = Qwt.QwtPlotGrid() pen = QPen(Qt.DotLine) pen.setColor(Qt.black) pen.setWidth(0) grid.setPen(pen) grid.attach(self.plot1) self.plot1.setAxisScale(self.plot1.yLeft, 0, 1.1 * np.max(self.mass)) color = QColor('black') curve = Qwt.QwtPlotCurve("test1") pen = QPen(color) pen.setWidth(1) curve.setPen(pen) #self.axis= np.arange(len(self.mass)) curve.setData(self.axis, self.mass) curve.setStyle(Qwt.QwtPlotCurve.Sticks) curve.attach(self.plot1) for i in range(len(self.peak_MS)): text_MS = Qwt.QwtText('%s' % (str(self.peak_MS[i][0]))) marker_MS = Qwt.QwtPlotMarker() marker_MS.setLabelAlignment(Qt.AlignCenter | Qt.AlignTop) marker_MS.setLabel(text_MS) marker_MS.setValue(self.peak_MS[i][0], self.peak_MS[i][1]) marker_MS.attach(self.plot1) self.plot1.replot() self.plot2.clear() self.plot2.setTitle("NIST MS") # self.plot2.setAxisTitle(Qwt.QwtPlot.xBottom, 'Raman shift (cm-1)') self.plot2.setAxisTitle(Qwt.QwtPlot.yLeft, 'Intensity') grid = Qwt.QwtPlotGrid() pen = QPen(Qt.DotLine) pen.setColor(Qt.black) pen.setWidth(0) grid.setPen(pen) grid.attach(self.plot2) self.plot2.replot() def libraryListClicked(self): row = self.library_list.indexOfTopLevelItem( self.library_list.currentItem()) self.row1 = self.masscor[row][0] print 'row: %s' % self.row1 self.showMs(self.row1) def libraryListDoubleClicked(self, item, pos): dialog = NistLibraryDialog(num=self.row1) dialog.move(QPoint(100, 10)) res = dialog.exec_() def showMs(self, row1): self.row1 = row1 self.cur.execute( "select name,peakindex,peakintensity from catalog where id=%d" % row1) temp = self.cur.fetchall() masstemp = np.frombuffer(temp[0][1], dtype=np.int) intensitytemp = np.frombuffer(temp[0][2], dtype=np.int) intensitytemp = 100 * intensitytemp / np.max(intensitytemp) row = np.zeros(len(masstemp)) mass = coo_matrix((intensitytemp, (row, masstemp)), shape=(1, ceil(masstemp[-1]) + 1)).todense() self.massSeacher = mass.tolist() radio_MS = 0.01 * (np.max(self.massSeacher[0]) - np.min(self.massSeacher[0])) peak_MS = [] for i in range(5, len(self.massSeacher[0]) - 5): if (self.massSeacher[0][i] == max(self.massSeacher[0][i - 5:i + 5]) and self.massSeacher[0][i] >= radio_MS): peak_intensity_MS = (i, self.massSeacher[0][i]) peak_MS.append(peak_intensity_MS) self.plot2.clear() self.plot2.setTitle("MS of %s" % str(temp[0][0][:-2])) color = QColor('black') curve2 = Qwt.QwtPlotCurve("test1") pen = QPen(color) pen.setWidth(1) curve2.setPen(pen) self.axis2 = masstemp curve2.setData(masstemp, intensitytemp) curve2.setStyle(Qwt.QwtPlotCurve.Sticks) curve2.attach(self.plot2) for i in range(len(peak_MS)): text_MS = Qwt.QwtText('%s' % (str(peak_MS[i][0]))) marker_MS = Qwt.QwtPlotMarker() marker_MS.setLabelAlignment(Qt.AlignCenter | Qt.AlignTop) marker_MS.setLabel(text_MS) marker_MS.setValue(peak_MS[i][0], peak_MS[i][1]) marker_MS.attach(self.plot2) x = np.hstack((self.axis, self.axis2)) x_min = np.min(x) x_max = np.max(x) y1_max = np.max(self.mass) y1_min = np.min(self.mass) y2_max = np.max(intensitytemp) y2_min = np.min(intensitytemp) self.plot1.setAxisScale(self.plot1.xBottom, 0, x_max * 1.1) self.plot2.setAxisScale(self.plot1.xBottom, 0, x_max * 1.1) self.plot1.setAxisScale(self.plot1.yLeft, 0, y1_max * 1.1) self.plot2.setAxisScale(self.plot1.yLeft, 0, y2_max * 1.1) self.plot1.replot() self.plot2.replot() self.ShowMolFile() def comnum(self): i = 0 for x in self.findms: if x in self.basems: i = i + 1 cor = i * 2.0 / (len(self.findms) + len(self.basems)) return cor def Seach_ZDJ(self): self.findms = [] (mz_bin, val_bin, peaks_bin) = processMS(binMS(self.ms)) peaks_bin.sort(key=lambda d: d[1], reverse=True) self.peak_index = [] self.peak_inten = [] for i in range(0, len(peaks_bin)): self.peak_index.append(int(peaks_bin[i][0])) self.peak_inten.append(peaks_bin[i][1]) if len(peaks_bin) < 10: self.findms = self.peak_index else: self.findms = self.peak_index[0:10] time0 = time.time() db = sqlite3.connect(NIST_DBPath) self.cur = db.cursor() self.cur.execute( "select id,top10peakindex from catalog where MW>%d-28 and MW<%d+28" % (self.maxmass, self.maxmass)) self.c = self.cur.fetchall() ms = [] for i in range(len(self.c)): self.basems = np.frombuffer(self.c[i][1], dtype=np.int) cor = self.comnum() if cor > 0.4: temp = (self.c[i][0], cor) ms.append(temp) print ms self.masscor = [] tic = time.time() for i in range(len(ms)): self.cur.execute( "select peakindex, peakintensity from catalog where id=%d" % (ms[i][0])) temp = self.cur.fetchall() masstemp = np.frombuffer(temp[0][0], dtype=np.int) intensitytemp = np.frombuffer(temp[0][1], dtype=np.int) temp2 = (ms[i][0], corrcoef_ms(masstemp, intensitytemp, mz_bin, val_bin)) self.masscor.append(temp2) print time.time() - time0 print time.time() - tic self.masscor.sort(key=lambda d: d[1], reverse=True) for i in range(min(25, len(ms))): self.cur.execute( "select name,Formula,MW from catalog where id=%d" % self.masscor[i][0]) temp = self.cur.fetchall() strsimilarity = '%.2f' % self.masscor[i][1] temp3 = temp[0][1][:-1] temp1 = temp[0][2] temp2 = temp[0][0][:-2] item = QTreeWidgetItem([ str(i + 1), str(strsimilarity), str(temp1), str(temp3), str(temp2) ]) self.library_list.addTopLevelItem(item) if len(ms) > 0: self.showMs(self.masscor[0][0]) zoomer = Qwt.QwtPlotZoomer(Qwt.QwtPlot.xBottom, Qwt.QwtPlot.yLeft, Qwt.QwtPicker.DragSelection, Qwt.QwtPicker.AlwaysOn, self.plot1.canvas()) zoomer.setRubberBandPen(QPen(Qt.black)) zoomer.setTrackerPen(QPen(Qt.blue)) self.plot1.zoomer = zoomer self.plot1.zoomer.setZoomBase() def Seach(self): ms = self.ms nist = NISTSearch(NIST_DBPath) nist.top10_screen(self.ms) nist.corr() self.masscor = nist.corrs db = sqlite3.connect(NIST_DBPath) self.cur = db.cursor() for i in range(min(25, len(self.masscor))): self.cur.execute( "select name,Formula,MW from catalog where id=%d" % self.masscor[i][0]) temp = self.cur.fetchall() strsimilarity = '%.2f' % self.masscor[i][1] temp3 = temp[0][1][:-1] temp1 = temp[0][2] temp2 = temp[0][0][:-2] item = QTreeWidgetItem([ str(i + 1), str(strsimilarity), str(temp1), str(temp3), str(temp2) ]) self.library_list.addTopLevelItem(item) if len(ms) > 0: self.showMs(self.masscor[0][0]) zoomer = Qwt.QwtPlotZoomer(Qwt.QwtPlot.xBottom, Qwt.QwtPlot.yLeft, Qwt.QwtPicker.DragSelection, Qwt.QwtPicker.AlwaysOn, self.plot1.canvas()) zoomer.setRubberBandPen(QPen(Qt.black)) zoomer.setTrackerPen(QPen(Qt.blue)) self.plot1.zoomer = zoomer self.plot1.zoomer.setZoomBase() def ShowMolFile(self): self.plot3.clear() self.ID = self.row1 Molecular = {} db = sqlite3.connect(MOL_DBPath) cur = db.cursor() cur.execute("select * from catalog where id=%d" % self.ID) c = cur.fetchall() Molecular["MolName"] = c[0][1] Molecular["MolNum"] = c[0][2] Molecular["MolBondNum"] = c[0][3] Molecular["Mol"] = c[0][4].split() Molecular["MolXAxis"] = np.frombuffer(c[0][5], dtype=np.float) Molecular["MolYAxis"] = np.frombuffer(c[0][6], dtype=np.float) Molecular["MolStyle"] = np.frombuffer(c[0][7], dtype=np.int) Molecular["bondX"] = np.frombuffer(c[0][8], dtype=np.int) Molecular["bondY"] = np.frombuffer(c[0][9], dtype=np.int) Molecular["bondNum"] = np.frombuffer(c[0][10], dtype=np.int) self.Molecular = Molecular color = QColor('black') curve = Qwt.QwtPlotCurve() pen = QPen(color) pen.setWidth(1) curve.setPen(pen) curve.setStyle(Qwt.QwtPlotCurve.NoCurve) curve.setSymbol( Qwt.QwtSymbol(Qwt.QwtSymbol.Ellipse, Qt.black, QPen(Qt.black), QSize(3, 3))) curve.attach(self.plot3) curve.setData(self.Molecular["MolXAxis"], self.Molecular["MolYAxis"]) tempstyl1 = [] tempstyl2 = [] tempstyl3 = [] tempstyl4 = [] for i in range(Molecular["MolBondNum"]): if Molecular["bondNum"][i] == 1 and Molecular["MolStyle"][ Molecular["bondX"][i] - 1] == 0 and Molecular["MolStyle"][Molecular["bondY"][i] - 1] == 0: tempstyl2.append(Molecular["bondX"][i]) tempstyl2.append(Molecular["bondY"][i]) for i in range(Molecular["MolBondNum"]): if Molecular["bondNum"][i] == 2 and Molecular["MolStyle"][ Molecular["bondX"][i] - 1] == 0 and Molecular["MolStyle"][Molecular["bondY"][i] - 1] == 0: if (Molecular["bondX"][i] in tempstyl2) and (Molecular["bondY"][i] in tempstyl2): tempstyl1.append(Molecular["bondX"][i]) tempstyl1.append(Molecular["bondY"][i]) for i in range(len(tempstyl2) / 2): if (tempstyl2[2 * i] in tempstyl1) and (tempstyl2[2 * i + 1] in tempstyl1): tempstyl3.append(tempstyl2[2 * i]) tempstyl3.append(tempstyl2[2 * i + 1]) for i in range(len(tempstyl1) / 2): if (tempstyl1[2 * i] in tempstyl3) and (tempstyl1[2 * i + 1] in tempstyl3): tempstyl4.append(tempstyl1[2 * i]) tempstyl4.append(tempstyl1[2 * i + 1]) tempstyl6 = [] for i in range(len(tempstyl3) / 2): if (tempstyl3[2 * i] in tempstyl4) and (tempstyl3[2 * i + 1] in tempstyl4): tempstyl6.append(tempstyl3[2 * i]) tempstyl6.append(tempstyl3[2 * i + 1]) tempstyl5 = [] # print tempstyl4 while True: if len(tempstyl6) == 0 or len(tempstyl4) == 0: break for i in range(len(tempstyl4) / 2): # print i if not (tempstyl4[2 * i] in tempstyl5): tempindex3 = tempstyl6.index(tempstyl4[2 * i]) tempindex4 = tempstyl6.index(tempstyl4[2 * i + 1]) temp1 = tempstyl4[2 * i] temp2 = tempstyl4[2 * i + 1] if tempindex3 % 2 == 0: temp3 = tempstyl6[tempindex3 + 1] tempindex3other = tempindex3 + 1 else: temp3 = tempstyl6[tempindex3 - 1] tempindex3other = tempindex3 - 1 if tempindex4 % 2 == 0: temp4 = tempstyl6[tempindex4 + 1] tempindex4other = tempindex4 + 1 else: temp4 = tempstyl6[tempindex4 - 1] tempindex4other = tempindex4 - 1 tempindex5 = tempstyl4.index(temp3) tempindex6 = tempstyl4.index(temp4) if tempindex5 % 2 == 0: temp5 = tempstyl4[tempindex5 + 1] else: temp5 = tempstyl4[tempindex5 - 1] if tempindex6 % 2 == 0: temp6 = tempstyl4[tempindex6 + 1] else: temp6 = tempstyl4[tempindex6 - 1] tempindex7 = tempstyl6.index(temp5) if tempindex7 % 2 == 0: temp7 = tempstyl6[tempindex7 + 1] tempindex7other = tempindex7 + 1 else: temp7 = tempstyl6[tempindex7 - 1] tempindex7other = tempindex7 - 1 if temp7 == temp6: if not ((temp1 in tempstyl5) and (temp2 in tempstyl5) and (temp3 in tempstyl5) and (temp4 in tempstyl5) and (temp5 in tempstyl5) and (temp6 in tempstyl5)): tempstyl5.append(temp1) tempstyl5.append(temp2) tempstyl5.append(temp4) tempstyl5.append(temp3) tempstyl5.append(temp6) tempstyl5.append(temp5) temp = [ tempindex3, tempindex3other, tempindex4, tempindex4other, tempindex7, tempindex7other ] temp.sort(reverse=True) del tempstyl6[temp[0]] del tempstyl6[temp[1]] del tempstyl6[temp[2]] del tempstyl6[temp[3]] del tempstyl6[temp[4]] del tempstyl6[temp[5]] for i in np.arange((len(tempstyl4) - 1) / 2, -1, -1): if not (tempstyl4[2 * i] in tempstyl6) or not ( tempstyl4[2 * i + 1] in tempstyl6): del tempstyl4[2 * i + 1] del tempstyl4[2 * i] for i in np.arange((len(tempstyl6) - 1) / 2, -1, -1): if not (tempstyl6[2 * i] in tempstyl4) or not ( tempstyl6[2 * i + 1] in tempstyl4): del tempstyl6[2 * i + 1] del tempstyl6[2 * i] for i in np.arange((len(tempstyl4) - 1) / 2, -1, -1): if not (tempstyl4[2 * i] in tempstyl6) or not ( tempstyl4[2 * i + 1] in tempstyl6): del tempstyl4[2 * i + 1] del tempstyl4[2 * i] for i in np.arange((len(tempstyl6) - 1) / 2, -1, -1): if not (tempstyl6[2 * i] in tempstyl4) or not ( tempstyl6[2 * i + 1] in tempstyl4): del tempstyl6[2 * i + 1] del tempstyl6[2 * i] break # tempstylCom=list(set(tempstyl1) & set(tempstyl2)) # styl=np.setdiff1d(tempstyl1,tempstylCom) for i in range(Molecular["MolBondNum"]): x1 = self.Molecular["MolXAxis"][self.Molecular["bondX"][i] - 1] x2 = self.Molecular["MolXAxis"][self.Molecular["bondY"][i] - 1] y1 = self.Molecular["MolYAxis"][self.Molecular["bondX"][i] - 1] y2 = self.Molecular["MolYAxis"][self.Molecular["bondY"][i] - 1] if (y2 - y1) == 0: Xdiff = 0 Ydiff = np.sqrt(0.003) else: h = (x2 - x1) / (y2 - y1) Xdiff = np.sqrt(0.003 / (h * h + 1)) Ydiff = Xdiff * h if (Molecular["bondNum"][i] == 2) and not (Molecular["bondX"][i] in tempstyl5): tempx1 = [] tempy1 = [] tempx2 = [] tempy2 = [] tempx1.append(x1 + Xdiff) tempx1.append(x2 + Xdiff) tempy1.append(y1 - Ydiff) tempy1.append(y2 - Ydiff) tempx2.append(x1 - Xdiff) tempx2.append(x2 - Xdiff) tempy2.append(y1 + Ydiff) tempy2.append(y2 + Ydiff) curve2 = Qwt.QwtPlotCurve() curve2.setStyle(Qwt.QwtPlotCurve.Lines) curve2.attach(self.plot3) curve2.setData(tempx1, tempy1) curve3 = Qwt.QwtPlotCurve() curve3.setStyle(Qwt.QwtPlotCurve.Lines) curve3.attach(self.plot3) curve3.setData(tempx2, tempy2) elif (Molecular["bondNum"][i] == 3): tempx = [] tempy = [] tempx.append(x1) tempx.append(x2) tempy.append(y1) tempy.append(y2) curve1 = Qwt.QwtPlotCurve() curve1.setStyle(Qwt.QwtPlotCurve.Lines) curve1.attach(self.plot3) curve1.setData(tempx, tempy) tempx1 = [] tempy1 = [] tempx2 = [] tempy2 = [] tempx1.append(x1 + Xdiff) tempx1.append(x2 + Xdiff) tempy1.append(y1 - Ydiff) tempy1.append(y2 - Ydiff) tempx2.append(x1 - Xdiff) tempx2.append(x2 - Xdiff) tempy2.append(y1 + Ydiff) tempy2.append(y2 + Ydiff) curve2 = Qwt.QwtPlotCurve() curve2.setStyle(Qwt.QwtPlotCurve.Lines) curve2.attach(self.plot3) curve2.setData(tempx1, tempy1) curve3 = Qwt.QwtPlotCurve() curve3.setStyle(Qwt.QwtPlotCurve.Lines) curve3.attach(self.plot3) curve3.setData(tempx2, tempy2) else: tempx = [] tempy = [] tempx.append(x1) tempx.append(x2) tempy.append(y1) tempy.append(y2) curve1 = Qwt.QwtPlotCurve() curve1.setStyle(Qwt.QwtPlotCurve.Lines) curve1.attach(self.plot3) curve1.setData(tempx, tempy) t = np.linspace(0, np.pi * 2, 100) diffx1 = np.sin(t) * 0.3 diffy1 = np.cos(t) * 0.3 for i in range(len(tempstyl5) / 6): x0 = 0 y0 = 0 diffx = [] diffy = [] x0 = Molecular["MolXAxis"][tempstyl5[ 6 * i] - 1] + Molecular["MolXAxis"][tempstyl5[6 * i + 1] - 1] x0 = x0 + Molecular["MolXAxis"][tempstyl5[6 * i + 2] - 1] + Molecular["MolXAxis"][ tempstyl5[6 * i + 3] - 1] x0 = x0 + Molecular["MolXAxis"][tempstyl5[6 * i + 4] - 1] + Molecular["MolXAxis"][ tempstyl5[6 * i + 5] - 1] x0 = x0 / 6 y0 = Molecular["MolYAxis"][tempstyl5[ 6 * i] - 1] + Molecular["MolYAxis"][tempstyl5[6 * i + 1] - 1] y0 = y0 + Molecular["MolYAxis"][tempstyl5[6 * i + 2] - 1] + Molecular["MolYAxis"][ tempstyl5[6 * i + 3] - 1] y0 = y0 + Molecular["MolYAxis"][tempstyl5[6 * i + 4] - 1] + Molecular["MolYAxis"][ tempstyl5[6 * i + 5] - 1] y0 = y0 / 6 for i in range(len(diffx1)): diffx.append(diffx1[i] + x0) diffy.append(diffy1[i] + y0) curve4 = Qwt.QwtPlotCurve() curve4.setStyle(Qwt.QwtPlotCurve.Lines) curve4.attach(self.plot3) curve4.setData(diffx, diffy) for i in range(Molecular["MolNum"]): if Molecular["MolStyle"][i] != 0: text = Qwt.QwtText('%s' % Molecular["Mol"][i]) # text=Qwt.QwtText('%s'%str(i+1)) text.setColor(Qt.blue) text.setFont(QFont("Sans", 12)) text.setBackgroundBrush(Qt.white) marker = Qwt.QwtPlotMarker() marker.setLabelAlignment(Qt.AlignCenter | Qt.AlignCenter) marker.setLabel(text) marker.setValue(self.Molecular["MolXAxis"][i], self.Molecular["MolYAxis"][i]) marker.attach(self.plot3) self.plot3.setAxisScale(self.plot3.xBottom, min((min(Molecular["MolXAxis"]) - 0.5), -4), max((max(Molecular["MolXAxis"]) + 0.5), 4)) self.plot3.setAxisScale(self.plot3.yLeft, min((min(Molecular["MolYAxis"]) - 0.5), -4), max((max(Molecular["MolYAxis"]) + 0.5), 4)) self.plot3.replot()
class EditorConfiguration(QWidget): """EditorConfiguration widget class""" def __init__(self, parent): super(EditorConfiguration, self).__init__() self._preferences, vbox = parent, QVBoxLayout(self) # groups group1 = QGroupBox(translations.TR_PREFERENCES_EDITOR_CONFIG_INDENT) group2 = QGroupBox(translations.TR_PREFERENCES_EDITOR_CONFIG_MARGIN) group3 = QGroupBox(translations.TR_LINT_DIRTY_TEXT) group4 = QGroupBox(translations.TR_PEP8_DIRTY_TEXT) group5 = QGroupBox(translations.TR_HIGHLIGHTER_EXTRAS) group6 = QGroupBox(translations.TR_TYPING_ASSISTANCE) group7 = QGroupBox(translations.TR_DISPLAY) # groups container container_widget_with_all_preferences = QWidget() formFeatures = QGridLayout(container_widget_with_all_preferences) # Indentation hboxg1 = QHBoxLayout(group1) hboxg1.setContentsMargins(5, 15, 5, 5) self._spin, self._checkUseTabs = QSpinBox(), QComboBox() self._spin.setRange(1, 10) self._spin.setValue(settings.INDENT) hboxg1.addWidget(self._spin) self._checkUseTabs.addItems([ translations.TR_PREFERENCES_EDITOR_CONFIG_SPACES.capitalize(), translations.TR_PREFERENCES_EDITOR_CONFIG_TABS.capitalize() ]) self._checkUseTabs.setCurrentIndex(int(settings.USE_TABS)) hboxg1.addWidget(self._checkUseTabs) formFeatures.addWidget(group1, 0, 0) # Margin Line hboxg2 = QHBoxLayout(group2) hboxg2.setContentsMargins(5, 15, 5, 5) self._checkShowMargin = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_MARGIN_LINE) self._checkShowMargin.setChecked(settings.SHOW_MARGIN_LINE) hboxg2.addWidget(self._checkShowMargin) self._spinMargin = QSpinBox() self._spinMargin.setRange(50, 100) self._spinMargin.setSingleStep(2) self._spinMargin.setValue(settings.MARGIN_LINE) hboxg2.addWidget(self._spinMargin) hboxg2.addWidget(QLabel(translations.TR_CHARACTERS)) formFeatures.addWidget(group2, 0, 1) # Display Errors vboxDisplay = QVBoxLayout(group7) vboxDisplay.setContentsMargins(5, 15, 5, 5) self._checkHighlightLine = QComboBox() self._checkHighlightLine.addItems([ translations.TR_PREFERENCES_EDITOR_CONFIG_ERROR_USE_BACKGROUND, translations.TR_PREFERENCES_EDITOR_CONFIG_ERROR_USE_UNDERLINE ]) self._checkHighlightLine.setCurrentIndex( int(settings.UNDERLINE_NOT_BACKGROUND)) hboxDisplay1 = QHBoxLayout() hboxDisplay1.addWidget(QLabel(translations.TR_DISPLAY_ERRORS)) hboxDisplay1.addWidget(self._checkHighlightLine) hboxDisplay2 = QHBoxLayout() self._checkDisplayLineNumbers = QCheckBox( translations.TR_DISPLAY_LINE_NUMBERS) self._checkDisplayLineNumbers.setChecked(settings.SHOW_LINE_NUMBERS) hboxDisplay2.addWidget(self._checkDisplayLineNumbers) vboxDisplay.addLayout(hboxDisplay1) vboxDisplay.addLayout(hboxDisplay2) formFeatures.addWidget(group7, 1, 0, 1, 0) # Find Lint Errors (highlighter) vboxg3 = QVBoxLayout(group3) self._checkErrors = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_FIND_ERRORS) self._checkErrors.setChecked(settings.FIND_ERRORS) self.connect(self._checkErrors, SIGNAL("stateChanged(int)"), self._disable_show_errors) self._showErrorsOnLine = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_TOOLTIP_ERRORS) self._showErrorsOnLine.setChecked(settings.ERRORS_HIGHLIGHT_LINE) self.connect(self._showErrorsOnLine, SIGNAL("stateChanged(int)"), self._enable_errors_inline) vboxg3.addWidget(self._checkErrors) vboxg3.addWidget(self._showErrorsOnLine) vboxg3.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding)) formFeatures.addWidget(group3, 2, 0) # Find PEP8 Errors (highlighter) vboxg4 = QHBoxLayout(group4) vboxg4.setContentsMargins(5, 15, 5, 5) vvbox = QVBoxLayout() self._checkStyle = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_PEP8) self._checkStyle.setChecked(settings.CHECK_STYLE) self.connect(self._checkStyle, SIGNAL("stateChanged(int)"), self._disable_check_style) vvbox.addWidget(self._checkStyle) self._checkStyleOnLine = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_TOOLTIP_PEP8) self._checkStyleOnLine.setChecked(settings.CHECK_HIGHLIGHT_LINE) self.connect(self._checkStyleOnLine, SIGNAL("stateChanged(int)"), self._enable_check_inline) vvbox.addWidget(self._checkStyleOnLine) vvbox.addItem( QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) vboxg4.addLayout(vvbox) # Container for tree widget and buttons widget = QWidget() hhbox = QHBoxLayout(widget) hhbox.setContentsMargins(0, 0, 0, 0) # Tree Widget with custom item delegate # always adds uppercase text self._listIgnoreViolations = QTreeWidget() self._listIgnoreViolations.setObjectName("ignore_pep8") self._listIgnoreViolations.setItemDelegate(ui_tools.CustomDelegate()) self._listIgnoreViolations.setMaximumHeight(80) self._listIgnoreViolations.setHeaderLabel( translations.TR_PREFERENCES_EDITOR_CONFIG_IGNORE_PEP8) for ic in settings.IGNORE_PEP8_LIST: self._listIgnoreViolations.addTopLevelItem(QTreeWidgetItem([ic])) hhbox.addWidget(self._listIgnoreViolations) box = QVBoxLayout() box.setContentsMargins(0, 0, 0, 0) btn_add = QPushButton(QIcon(":img/add_small"), '') btn_add.setMaximumSize(26, 24) btn_add.clicked.connect(self._add_code_pep8) box.addWidget(btn_add) btn_remove = QPushButton(QIcon(":img/delete_small"), '') btn_remove.setMaximumSize(26, 24) btn_remove.clicked.connect(self._remove_code_pep8) box.addWidget(btn_remove) box.addItem(QSpacerItem(0, 0, QSizePolicy.Fixed, QSizePolicy.Expanding)) hhbox.addLayout(box) vboxg4.addWidget(widget) formFeatures.addWidget(group4) # Show Python3 Migration, DocStrings and Spaces (highlighter) vboxg5 = QVBoxLayout(group5) vboxg5.setContentsMargins(5, 15, 5, 5) self._showMigrationTips = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_MIGRATION) self._showMigrationTips.setChecked(settings.SHOW_MIGRATION_TIPS) vboxg5.addWidget(self._showMigrationTips) self._checkForDocstrings = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_CHECK_FOR_DOCSTRINGS) self._checkForDocstrings.setChecked(settings.CHECK_FOR_DOCSTRINGS) vboxg5.addWidget(self._checkForDocstrings) self._checkShowSpaces = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_SHOW_TABS_AND_SPACES) self._checkShowSpaces.setChecked(settings.SHOW_TABS_AND_SPACES) vboxg5.addWidget(self._checkShowSpaces) self._checkIndentationGuide = QCheckBox( translations.TR_SHOW_INDENTATION_GUIDE) self._checkIndentationGuide.setChecked(settings.SHOW_INDENTATION_GUIDE) vboxg5.addWidget(self._checkIndentationGuide) formFeatures.addWidget(group5, 3, 0) # End of line, Stop Scrolling At Last Line, Trailing space, Word wrap vboxg6 = QVBoxLayout(group6) vboxg6.setContentsMargins(5, 15, 5, 5) self._checkEndOfLine = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_END_OF_LINE) self._checkEndOfLine.setChecked(settings.USE_PLATFORM_END_OF_LINE) vboxg6.addWidget(self._checkEndOfLine) self._checkEndAtLastLine = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_END_AT_LAST_LINE) self._checkEndAtLastLine.setChecked(settings.END_AT_LAST_LINE) vboxg6.addWidget(self._checkEndAtLastLine) self._checkTrailing = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_REMOVE_TRAILING) self._checkTrailing.setChecked(settings.REMOVE_TRAILING_SPACES) vboxg6.addWidget(self._checkTrailing) self._allowWordWrap = QCheckBox( translations.TR_PREFERENCES_EDITOR_CONFIG_WORD_WRAP) self._allowWordWrap.setChecked(settings.ALLOW_WORD_WRAP) vboxg6.addWidget(self._allowWordWrap) formFeatures.addWidget(group6, 3, 1) # pack all the groups vbox.addWidget(container_widget_with_all_preferences) vbox.addItem( QSpacerItem(0, 10, QSizePolicy.Expanding, QSizePolicy.Expanding)) self.connect(self._preferences, SIGNAL("savePreferences()"), self.save) def _add_code_pep8(self): item = QTreeWidgetItem() item.setFlags(item.flags() | Qt.ItemIsEditable) self._listIgnoreViolations.addTopLevelItem(item) self._listIgnoreViolations.setCurrentItem(item) self._listIgnoreViolations.editItem(item, 0) def _remove_code_pep8(self): index = self._listIgnoreViolations.indexOfTopLevelItem( self._listIgnoreViolations.currentItem()) self._listIgnoreViolations.takeTopLevelItem(index) def _enable_check_inline(self, val): """Method that takes a value to enable the inline style checking""" if val == Qt.Checked: self._checkStyle.setChecked(True) def _enable_errors_inline(self, val): """Method that takes a value to enable the inline errors checking""" if val == Qt.Checked: self._checkErrors.setChecked(True) def _disable_check_style(self, val): """Method that takes a value to disable the inline style checking""" if val == Qt.Unchecked: self._checkStyleOnLine.setChecked(False) def _disable_show_errors(self, val): """Method that takes a value to disable the inline errors checking""" if val == Qt.Unchecked: self._showErrorsOnLine.setChecked(False) def save(self): """Method to save settings""" qsettings = IDE.ninja_settings() settings.USE_TABS = bool(self._checkUseTabs.currentIndex()) qsettings.setValue('preferences/editor/useTabs', settings.USE_TABS) margin_line = self._spinMargin.value() settings.MARGIN_LINE = margin_line settings.pycodestylemod_update_margin_line_length(margin_line) qsettings.setValue('preferences/editor/marginLine', margin_line) settings.SHOW_MARGIN_LINE = self._checkShowMargin.isChecked() qsettings.setValue('preferences/editor/showMarginLine', settings.SHOW_MARGIN_LINE) settings.INDENT = self._spin.value() qsettings.setValue('preferences/editor/indent', settings.INDENT) endOfLine = self._checkEndOfLine.isChecked() settings.USE_PLATFORM_END_OF_LINE = endOfLine qsettings.setValue('preferences/editor/platformEndOfLine', endOfLine) settings.UNDERLINE_NOT_BACKGROUND = \ bool(self._checkHighlightLine.currentIndex()) qsettings.setValue('preferences/editor/errorsUnderlineBackground', settings.UNDERLINE_NOT_BACKGROUND) settings.FIND_ERRORS = self._checkErrors.isChecked() qsettings.setValue('preferences/editor/errors', settings.FIND_ERRORS) settings.ERRORS_HIGHLIGHT_LINE = self._showErrorsOnLine.isChecked() qsettings.setValue('preferences/editor/errorsInLine', settings.ERRORS_HIGHLIGHT_LINE) settings.CHECK_STYLE = self._checkStyle.isChecked() qsettings.setValue('preferences/editor/checkStyle', settings.CHECK_STYLE) settings.SHOW_MIGRATION_TIPS = self._showMigrationTips.isChecked() qsettings.setValue('preferences/editor/showMigrationTips', settings.SHOW_MIGRATION_TIPS) settings.CHECK_HIGHLIGHT_LINE = self._checkStyleOnLine.isChecked() qsettings.setValue('preferences/editor/checkStyleInline', settings.CHECK_HIGHLIGHT_LINE) settings.END_AT_LAST_LINE = self._checkEndAtLastLine.isChecked() qsettings.setValue('preferences/editor/endAtLastLine', settings.END_AT_LAST_LINE) settings.REMOVE_TRAILING_SPACES = self._checkTrailing.isChecked() qsettings.setValue('preferences/editor/removeTrailingSpaces', settings.REMOVE_TRAILING_SPACES) settings.ALLOW_WORD_WRAP = self._allowWordWrap.isChecked() qsettings.setValue('preferences/editor/allowWordWrap', settings.ALLOW_WORD_WRAP) settings.SHOW_TABS_AND_SPACES = self._checkShowSpaces.isChecked() qsettings.setValue('preferences/editor/showTabsAndSpaces', settings.SHOW_TABS_AND_SPACES) settings.SHOW_INDENTATION_GUIDE = ( self._checkIndentationGuide.isChecked()) qsettings.setValue('preferences/editor/showIndentationGuide', settings.SHOW_INDENTATION_GUIDE) settings.CHECK_FOR_DOCSTRINGS = self._checkForDocstrings.isChecked() qsettings.setValue('preferences/editor/checkForDocstrings', settings.CHECK_FOR_DOCSTRINGS) settings.SHOW_LINE_NUMBERS = self._checkDisplayLineNumbers.isChecked() qsettings.setValue('preferences/editor/showLineNumbers', settings.SHOW_LINE_NUMBERS) current_ignores = set(settings.IGNORE_PEP8_LIST) new_ignore_codes = [] # Get pep8 from tree widget for index in range(self._listIgnoreViolations.topLevelItemCount()): ignore_code = self._listIgnoreViolations.topLevelItem(index).text( 0) if ignore_code: new_ignore_codes.append(ignore_code.strip()) # pep8 list that will be removed to_remove = [x for x in current_ignores if x not in new_ignore_codes] # Update list settings.IGNORE_PEP8_LIST = new_ignore_codes qsettings.setValue('preferences/editor/defaultIgnorePep8', settings.IGNORE_PEP8_LIST) # Add for ignore_code in settings.IGNORE_PEP8_LIST: settings.pycodestylemod_add_ignore(ignore_code) # Remove for ignore_code in to_remove: settings.pycodestylemod_remove_ignore(ignore_code) if settings.USE_TABS: settings.pycodestylemod_add_ignore("W191") else: settings.pycodestylemod_remove_ignore("W191")
class NPhotoMainWindow(QMainWindow): rootAlbum = None currentPage = 0 def __init__(self, parent=None): super(NPhotoMainWindow, self).__init__(parent) self.image = None self.status = self.statusBar() self.status.setSizeGripEnabled(False) fileMenu = self.menuBar().addMenu("&File") fileEditAction = createAction(self, "&Edit", self.doEdit, "Ctrl-E", "fileedit", "Edit photo details") fileDeleteAction = createAction(self, "&Delete", self.doDelete, "Ctrl-D", "filedelete", "Delete selected file(s)") fileImportAction = createAction(self, "&Import", self.doImport, "Ctrl-I", "fileimport", "Import photos into your library") fileRescanLibraryAction = createAction(self, "&Rescan", self.doRescan, "Ctrl-R", "filerescan", "Rescan library folder and update sidecar files, and thumbnails") fileBackupAction = createAction(self, "&Backup", self.doBackup, "Ctrl-B", "filebkup", "Backup your library") fileSettingsAction = createAction(self, "&Settings", self.doSettings, "Ctrl-S", "filesettings", "Settings") fileQuitAction = createAction(self, "&Quit", self.close, "Ctrl+Q", "filequit", "Close the application") helpMenu = self.menuBar().addMenu("&Help") helpAboutAction = createAction(self, "&About", self.doAbout, None, "helpabout", "About nPhoto") addActions(fileMenu, (fileEditAction, fileDeleteAction, None, fileImportAction, fileRescanLibraryAction, fileBackupAction, fileSettingsAction, None, fileQuitAction)) addActions(helpMenu, (helpAboutAction,)) size = getSettingQVar("MainWindow/Size", QSize(600,500)).toSize() self.resize(size) position = getSettingQVar("MainWindow/Position", QPoint(0,0)).toPoint() self.move(position) self.restoreState(getSettingQVar("MainWindow/State").toByteArray()) self.setWindowTitle("nPhoto") self.controlFrame = QFrame() self.controlLayout = QBoxLayout(QBoxLayout.TopToBottom) #TODO Make this a combo box that populates the tree by date or by folder self.viewByCombo = QLabel("PLACEHOLDER") self.tree = QTreeWidget() self.tree.setColumnCount(1) self.tree.setHeaderLabels(["Album"]) self.tree.setItemsExpandable(True) self.connect(self.tree, SIGNAL("itemSelectionChanged()"), self.treeSelection) self.controlLayout.addWidget(self.viewByCombo) self.controlLayout.addWidget(self.tree) self.controlFrame.setLayout(self.controlLayout) self.browserFrame = QFrame() self.browserGrid = QGridLayout() self.imageLabels = [] for row in range(0,BROWSER_GRID_HEIGHT): self.imageLabels.append([]) for col in range(0,BROWSER_GRID_WIDTH): self.imageLabels[row].append(QLabel()) self.imageLabels[row][col].setBackgroundRole(QPalette.Base) self.imageLabels[row][col].setSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) self.imageLabels[row][col].setScaledContents = True self.imageLabels[row][col].setAlignment(Qt.AlignCenter) self.imageLabels[row][col].setStyleSheet("border:2px solid #000") dbl = functools.partial(self.imgDoubleClick, row, col) click = functools.partial(self.imgMouseRelease, row, col) self.imageLabels[row][col].mouseDoubleClickEvent = dbl self.imageLabels[row][col].mouseReleaseEvent = click self.browserGrid.addWidget(self.imageLabels[row][col],row,col) self.prevPage = QPushButton("Prev") self.pageInfoLabel = QLabel("Page 0 of 0") self.pageInfoLabel.setAlignment(Qt.AlignCenter) self.nextPage = QPushButton("Next") self.prevPage.clicked.connect(self.goPreviousPage) self.nextPage.clicked.connect(self.goNextPage) self.browserGrid.addWidget(self.prevPage, row+1, 0) self.browserGrid.addWidget(self.pageInfoLabel, row+1, 1) self.browserGrid.addWidget(self.nextPage, row+1, 2) self.browserFrame.setLayout(self.browserGrid) self.mainSplitter = QSplitter(Qt.Horizontal) self.mainSplitter.addWidget(self.controlFrame) self.mainSplitter.addWidget(self.browserFrame) self.mainSplitter.setStretchFactor(1,4) self.setCentralWidget(self.mainSplitter) self.mainSplitter.restoreState(getSettingQVar("MainWindow/Splitter").toByteArray()) if getSettingStr("Paths/Library") not in (None, ''): QTimer.singleShot(0, self.loadLibrary) else: self.status.showMessage("No Library Path in settings", 10000) def getPhotoByBrowserLocation(self, row, col): idx = ((self.currentPage - 1) * BROWSER_THUMBS_PER_PAGE) + (row * BROWSER_GRID_WIDTH) + col if idx < len(self.currentAlbum.photos): return self.currentAlbum.photos[idx] else: return None def imgDoubleClick(self, row, col, event): if event.button() == Qt.LeftButton: if event.modifiers() & Qt.ControlModifier or event.modifiers() & Qt.AltModifier \ or event.modifiers() & Qt.ShiftModifier: pass else: curr = self.getPhotoByBrowserLocation(row,col) if curr: self.currentSelection = [curr,] self.highlightSelected() self.doEdit() def imgMouseRelease(self, row, col, event): if event.button() == Qt.LeftButton: if event.modifiers() & Qt.ControlModifier or event.modifiers() & Qt.AltModifier \ or event.modifiers() & Qt.ShiftModifier: pass else: curr = self.getPhotoByBrowserLocation(row,col) if curr: if not hasattr(self, "currentSelection"): self.currentSelection = [] if curr in self.currentSelection: self.currentSelection.remove(curr) else: self.currentSelection.append(curr) self.highlightSelected() def highlightSelected(self): if hasattr(self, "currentSelection"): for x in range(0, BROWSER_GRID_HEIGHT): for y in range(0, BROWSER_GRID_WIDTH): ph = self.getPhotoByBrowserLocation(x,y) if ph: if ph in self.currentSelection: self.imageLabels[x][y].setStyleSheet("border:2px solid #FFF") else: self.imageLabels[x][y].setStyleSheet("border:2px solid #000") def regenAlbumThumbnails(self, album): for al in album.albums: self.regenAlbumThumbnails(al) for ph in album.photos: createThumbnail(ph.path, True) def doRescan(self): #TODO Rebuild sidecar files! self.regenAlbumThumbnails(self.rootAlbum) self.reloadLibrary() def treeSelection(self): curr = self.tree.currentItem() path = curr.data(0,0).toString() tmp = curr while tmp.parent() is not None: tmp = tmp.parent() path = tmp.data(0,0).toString() + "." + path album = self.getAlbum(path) if hasattr(self, 'currentAlbum'): if self.currentAlbum != album: self.currentAlbum = album else: self.currentAlbum = album self.changeAlbums() def changeAlbums(self): if len(self.currentAlbum.photos) == 0: self.currentPage = 0 else: self.currentPage = 1 for row in range(0, BROWSER_GRID_HEIGHT): for col in range(0, BROWSER_GRID_WIDTH): if len(self.currentAlbum.photos)<= (row*BROWSER_GRID_WIDTH + col): self.imageLabels[row][col].setPixmap(QPixmap()) else: self.imageLabels[row][col].setPixmap(loadQPixMap(self.image, self.currentAlbum.photos[ (BROWSER_THUMBS_PER_PAGE * (self.currentPage - 1)) + row*BROWSER_GRID_WIDTH+col] .path, self.imageLabels[0][0].width(), self.imageLabels[0][0].height(), True)) self.imageLabels[row][col].adjustSize() self.updatePageInfo() def loadPageThumbs(self): for row in range(0, BROWSER_GRID_HEIGHT): for col in range(0, BROWSER_GRID_WIDTH): if len(self.currentAlbum.photos)<= ( (BROWSER_THUMBS_PER_PAGE * (self.currentPage - 1)) + row*BROWSER_GRID_WIDTH + col): self.imageLabels[row][col].setPixmap(QPixmap()) else: self.imageLabels[row][col].setPixmap(loadQPixMap(self.image, self.currentAlbum.photos[ (BROWSER_THUMBS_PER_PAGE * (self.currentPage - 1)) + row*BROWSER_GRID_WIDTH+col] .path, self.imageLabels[0][0].width(), self.imageLabels[0][0].height(), True)) self.imageLabels[row][col].adjustSize() def goPreviousPage(self): if self.currentPage > 1: self.currentPage -= 1 self.loadPageThumbs() self.updatePageInfo() def goNextPage(self): if self.currentPage < self.getMaxPage(): self.currentPage += 1 self.loadPageThumbs() self.updatePageInfo() def getMaxPage(self): totalPages = len(self.currentAlbum.photos) / BROWSER_THUMBS_PER_PAGE if (len(self.currentAlbum.photos) % BROWSER_THUMBS_PER_PAGE) != 0: totalPages += 1 return totalPages def updatePageInfo(self): if self.currentPage == 0: self.pageInfoLabel.setText("Page 0 of 0") else: self.pageInfoLabel.setText("Page %d of %d" % (self.currentPage, self.getMaxPage())) def getAlbum(self, path): nodes = path.split(".") if nodes[0] != 'Library': print "WTF?!?!?!" else: album = self.rootAlbum for albumName in nodes[1:]: album = album.albums[unicode(albumName)] return album def doBackup(self): libDir = getSettingStr("Paths/Library") bkupPaths = getSettingStr("Paths/Backup") if libDir in (None, ''): QMessageBox.warning(self, "Backup Failed", "You need to specify a library directory in your settings") return if not os.path.exists(libDir) or os.path.isfile(libDir): QMessageBox.warning(self, "Backup Failed", "The library directory in your settings either doesn't exist, or its not a directory") return if bkupPaths in (None, ''): QMessageBox.warning(self, "Backup Failed", "You need to specify at least one backup directory in your settings") return dt = datetime.date.today() bkupDirName = str(dt.year) + str(dt.month) + str(dt.day) for path in bkupPaths.split(","): if not os.path.exists(path.strip()) or os.path.isfile(path.strip()): QMessageBox.warning(self, "Backup Failed", "The backup directory <%s> in your settings either doesn't exist, or its not a directory" % (path)) return if os.path.exists(path.strip() + os.sep + bkupDirName): QMessageBox.warning(self, "Backup Failed", "There is already a backup for today in a backup directory <%s>" % (path.strip())) return for path in bkupPaths.split(","): shutil.copytree(libDir, path.strip() + os.sep + bkupDirName) QMessageBox.information(self, "Backup", "Backup completed!") def doDelete(self): if hasattr(self, "currentSelection"): if len(self.currentSelection) > 0: msg = "Are you sure you want to delete the selected image?" if len(self.currentSelection) > 1: msg = "Are you sure you want to delete the %s selected images?" % len(self.currentSelection) if QMessageBox.warning(self, "Delete Image(s)", msg, QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes: for ph in self.currentSelection: msg = ph.delete() if msg not in (None, ''): QMessageBox.warning(self, "Error while deleting", msg) break self.reloadLibrary() def reloadLibrary(self): self.currentSelection = [] self.highlightSelected() currPage = self.currentPage self.loadLibrary() if currPage > self.getMaxPage(): #Assumes you can't delete more than one page worth of photos at a time currPage = self.getMaxPage() self.currentPage = currPage self.loadPageThumbs() self.updatePageInfo() def doEdit(self): if hasattr(self, "currentSelection"): if len(self.currentSelection) == 1: ph = self.currentSelection[0] comment = ph.comment keywords = (" ".join(ph.keywords)).strip() dialog = EditPhotoDialog(self, ph.path, comment, keywords) if dialog.exec_(): ph.comment = unicode(dialog.commentEdit.text()).strip() ph.keywords = unicode(dialog.keywordEdit.text()).strip().split(" ") ph.save(ph.path) def doSettings(self): libPath = getSettingStr("Paths/Library", "") backupPaths = getSettingStr("Paths/Backup", "") fileExt = getSettingStr("FileExtensions", "jpg, CR2") fileExtOther = getSettingStr("FileExtensionsOther", "mov, avi") dialog = SettingsDialog(self, libPath, backupPaths, fileExt, fileExtOther) if dialog.exec_(): saveSetting("Paths/Library", dialog.libPathEdit.text()) saveSetting("Paths/Backup", dialog.backupPathsEdit.text()) saveSetting("FileExtensions", dialog.fileExtensionEdit.text()) saveSetting("FileExtensionsOther", dialog.fileExtensionOtherEdit.text()) self.status.showMessage("Settings updated", 5000) def buildTree(self, parentNode, parentAlbum): for name in parentAlbum.albums: childNode = QTreeWidgetItem(parentNode, [name]) childAlbum = parentAlbum.albums[name] if childAlbum.albums != None and len(childAlbum.albums) > 0: self.buildTree(childNode, childAlbum) def loadLibrary(self): self.status.showMessage("Loading Photo Library") self.rootAlbum = self.loadAlbum(getSettingStr("Paths/Library"), "Library") if self.rootAlbum == None: self.rootAlbum = Album(name="Library") self.refreshTree() self.status.showMessage("Library successfully loaded", 5000) def refreshTree(self): self.tree.clear() node = QTreeWidgetItem(self.tree, ["Library"]) self.buildTree(node, self.rootAlbum) self.tree.setCurrentItem(node) def loadAlbum(self, path, title = None): album = Album() if title not in (None, ''): album.name = title else: album.name = path[path.rfind(os.sep)+1:] album.albums = {} album.photos = [] album.path = path files = os.listdir(path) files.sort() tmpPhotos = [] for fl in files: if not os.path.isfile(path + os.sep + fl): album.albums[fl] = self.loadAlbum(path + os.sep + fl) else: if self.isImageFile(path + os.sep + fl): ph = None if os.path.exists(path + os.sep + fl + ".sidecar"): ph = Photo.load(path + os.sep + fl + ".sidecar") else: ph = Photo() ph.comment = "" ph.keywords = {} ph.srcPath = None ph.path = path + os.sep + fl exif = loadExif(path + os.sep + fl, EXIF_TAGS) ph.setExif(exif) ph.save(path + os.sep + fl) ph.path = path + os.sep + fl tmpPhotos.append(ph) album.photos = sorted(tmpPhotos, key = lambda photo: photo.date) return album def doImport(self): libPath = getSettingStr("Paths/Library") fileExt = getSettingStr("FileExtensions") if libPath in (None, ''): QMessageBox.warning(self, "Import Failed", "You need to specify a library directory in your settings") return if not os.path.exists(libPath) or os.path.isfile(libPath): QMessageBox.warning(self, "Import Failed", "The library directory in your settings either doesn't exist, or its not a directory") return if not fileExt or fileExt in (None, ''): QMessageBox.warning(self, "Import Failed", "You need to specify file extensions to manage in your settings") return lastImport = getSettingStr("Paths/LastImport") importFrom = QFileDialog.getExistingDirectory(self, "Choose a Path to Import From", lastImport) if importFrom in (None, ''): return if not os.path.exists(importFrom) or os.path.isfile(importFrom): QMessageBox.warning(self, "Import Failed", "The import directory either doesn't exist, or is not a directory") return if importFrom == libPath: QMessageBox.warning(self, "Import Failed", "Your import directory and library directory can not be the same") return imd = ImportMetadataDialog(self) if imd.exec_(): album = imd.albumEdit.text() comments = imd.commentsEdit.text() keywords = imd.keywordsEdit.text() if album and album not in (None, ''): albumpath = album + os.sep else: album = None albumpath = "" if not keywords or keywords in (None, ''): keywords = "" if not comments or comments in (None, ''): comments = "" paths = self.buildFileList(importFrom) numTotal = len(paths) nonDupes = self.removeDuplicates(paths, importFrom, albumpath) numDuplicates = numTotal - len(nonDupes) if QMessageBox.question(self, "Import", "Out of %d files found, %d look to be duplicates. Continue with import?" % (numTotal, numDuplicates), QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes: saveSetting("Paths/LastImport", importFrom) for path in nonDupes: dest = self.buildLibPath(importFrom, path, albumpath) copyFileIncludingDirectories(path, dest) # TODO Handle copy failure exceptions! if not os.path.exists(dest): QMessageBox.warming(self, "Import Failed", "The file <%s> was not imported properly, aborting import" % (path)) return if self.isImageFile(path): exif = loadExif(unicode(path), EXIF_TAGS) ph = Photo() ph.path = dest ph.srcPath = path ph.comment = comments ph.keywords = keywords ph.setExif(exif) ph.save(dest) #Create Thumbnail createThumbnail(unicode(ph.path)) QMessageBox.information(self, "Import", "Import completed") self.loadLibrary() def buildLibPath(self, importFrom, path, albumpath): relPath = path[len(importFrom):] libPath = getSettingStr("Paths/Library") + os.sep + albumpath + relPath return libPath def isImageFile(self, filepath): extensionList = unicode(getSettingStr("FileExtensions")).split(",") for extension in extensionList: if unicode(filepath).upper().endswith(unicode(extension).upper()): return True return False def isOtherManagedFile(self, filepath): #TODO Implement list of other files to import into lib folders and to backup extensionList = unicode(getSettingStr("FileExtensionsOther")).split(",") for extension in extensionList: if unicode(filepath).upper().endswith(unicode(extension).upper()): return True return False def removeDuplicates(self, paths, importFrom, albumpath): nonDupes = [] for path in paths: libPath = self.buildLibPath(importFrom, path, albumpath) if not os.path.exists(libPath): nonDupes.append(path) return nonDupes def buildFileList(self, importFrom): #TODO Can probably be done with Glob or whatever it is? paths = [] for f in os.listdir(importFrom): fullpath = importFrom + os.sep + f if not os.path.isfile(fullpath): paths.extend(self.buildFileList(fullpath)) else: if self.isImageFile(fullpath): paths.append(fullpath) elif self.isOtherManagedFile(fullpath): paths.append(fullpath) return paths def closeEvent(self, event): saveSetting("MainWindow/Size", self.size()) saveSetting("MainWindow/Position", self.pos()) saveSetting("MainWindow/State", self.saveState()) saveSetting("MainWindow/Splitter", self.mainSplitter.saveState()) def doAbout(self): QMessageBox.about(self, "About nPhoto", "<p>nPhoto allows simple reviewing, commenting, and keywording of images, useful for running" " on a netbook while travelling, to then import into programs such as Lightroom" " on return from your holiday</p>")
class Preferences(QDialog): configuration = {} weight = 0 def __init__(self, parent=None): super(Preferences, self).__init__(parent, Qt.Dialog) self.setWindowTitle(translations.TR_PREFERENCES_TITLE) self.setMinimumSize(QSize(800, 600)) self.setMaximumSize(QSize(0, 0)) vbox = QVBoxLayout(self) hbox = QHBoxLayout() vbox.setContentsMargins(0, 0, 5, 5) hbox.setContentsMargins(0, 0, 0, 0) self.tree = QTreeWidget() self.tree.header().setHidden(True) self.tree.setSelectionMode(QTreeWidget.SingleSelection) self.tree.setAnimated(True) self.tree.header().setHorizontalScrollMode( QAbstractItemView.ScrollPerPixel) self.tree.header().setResizeMode(0, QHeaderView.ResizeToContents) self.tree.header().setStretchLastSection(False) self.tree.setFixedWidth(200) self.stacked = QStackedLayout() hbox.addWidget(self.tree) hbox.addLayout(self.stacked) vbox.addLayout(hbox) hbox_footer = QHBoxLayout() self._btnSave = QPushButton(translations.TR_SAVE) self._btnCancel = QPushButton(translations.TR_CANCEL) hbox_footer.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_footer.addWidget(self._btnCancel) hbox_footer.addWidget(self._btnSave) vbox.addLayout(hbox_footer) self.connect(self.tree, SIGNAL("itemSelectionChanged()"), self._change_current) self.connect(self._btnCancel, SIGNAL("clicked()"), self.close) self.connect(self._btnSave, SIGNAL("clicked()"), self._save_preferences) self.load_ui() self.tree.setCurrentItem(self.tree.topLevelItem(0)) def _save_preferences(self): self.emit(SIGNAL("savePreferences()")) self.close() def load_ui(self): sections = sorted( list(Preferences.configuration.keys()), key=lambda item: Preferences.configuration[item]['weight']) for section in sections: text = Preferences.configuration[section]['text'] Widget = Preferences.configuration[section]['widget'] widget = Widget(self) area = QScrollArea() area.setWidgetResizable(True) area.setWidget(widget) index = self.stacked.addWidget(area) item = QTreeWidgetItem([text]) item.setData(0, Qt.UserRole, index) self.tree.addTopLevelItem(item) #Sort Item Children subcontent = Preferences.configuration[section].get( 'subsections', {}) subsections = sorted(list(subcontent.keys()), key=lambda item: subcontent[item]['weight']) for sub in subsections: text = subcontent[sub]['text'] Widget = subcontent[sub]['widget'] widget = Widget(self) area = QScrollArea() area.setWidgetResizable(True) area.setWidget(widget) index = self.stacked.addWidget(area) subitem = QTreeWidgetItem([text]) subitem.setData(0, Qt.UserRole, index) item.addChild(subitem) self.tree.expandAll() def _change_current(self): item = self.tree.currentItem() index = item.data(0, Qt.UserRole) self.stacked.setCurrentIndex(index) @classmethod def register_configuration(cls, section, widget, text, weight=None, subsection=None): if weight is None: Preferences.weight += 1 weight = Preferences.weight if not subsection: Preferences.configuration[section] = { 'widget': widget, 'weight': weight, 'text': text } else: config = Preferences.configuration.get(section, {}) if not config: config[section] = {'widget': None, 'weight': 100} subconfig = config.get('subsections', {}) subconfig[subsection] = { 'widget': widget, 'weight': weight, 'text': text } config['subsections'] = subconfig Preferences.configuration[section] = config
class DBBrowser(QMainWindow): def __init__(self, parent, server): QMainWindow.__init__(self, parent) self.debug = False self.server = server self.db = None self.setWindowTitle("Database Browser") #s#elf.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) topBar = QToolBar() self.addToolBar(Qt.TopToolBarArea, topBar) self.cenWid = QWidget() self.setCentralWidget(self.cenWid) self.mainLayout = QHBoxLayout() self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.setSpacing(0) self.cenWid.setLayout( self.mainLayout ) self.treeTables = QTreeWidget() self.mainLayout.addWidget(self.treeTables, 1) self.treeTables.setHeaderLabels(["Table"]) self.treeTables.setSelectionBehavior( QAbstractItemView.SelectRows ) self.treeTables.setSelectionMode( QTreeView.SingleSelection ) self.connect( self.treeTables, SIGNAL( 'itemSelectionChanged()' ), self.on_table ) self.treeColumns = QTreeWidget() self.mainLayout.addWidget(self.treeColumns, 4) self.treeColumns.setHeaderLabels(["Column", "Type", "Nullable"]) self.db_connect() #self.fetch() def on_table(self): item = self.treeTables.currentItem() if item == None: return self.fetch( table = str(item.text(0)) ) def db_connect(self): #print "db_connect", self.server self.db = QSqlDatabase.addDatabase("QMYSQL") self.db.setHostName(self.server['server']) self.db.setUserName(self.server['user']) self.db.setPassword(self.server['passwd']) ok = self.db.open() print "open", ok #self.db.setHostName(self.server['server']) def load_data(self, data): if "tables" in data: self.treeTables.clear() for t in data['tables']: item = QTreeWidgetItem() item.setText(0, t['table']) self.treeTables.addTopLevelItem(item) else: self.treeColumns.clear() for t in data['columns']: item = QTreeWidgetItem() item.setText(0, t['column']) item.setText(1, t['type']) item.setText(2, "Yes" if t['nullable'] else "-") self.treeColumns.addTopLevelItem(item)
class Preferences(QDialog): configuration = {} weight = 0 def __init__(self, parent=None): super(Preferences, self).__init__(parent, Qt.Dialog) self.setWindowTitle(translations.TR_PREFERENCES_TITLE) self.setMinimumSize(QSize(800, 600)) self.setMaximumSize(QSize(0, 0)) vbox = QVBoxLayout(self) hbox = QHBoxLayout() vbox.setContentsMargins(0, 0, 5, 5) hbox.setContentsMargins(0, 0, 0, 0) self.tree = QTreeWidget() self.tree.header().setHidden(True) self.tree.setSelectionMode(QTreeWidget.SingleSelection) self.tree.setAnimated(True) self.tree.header().setHorizontalScrollMode( QAbstractItemView.ScrollPerPixel) self.tree.header().setResizeMode(0, QHeaderView.ResizeToContents) self.tree.header().setStretchLastSection(False) self.tree.setFixedWidth(200) self.stacked = QStackedLayout() hbox.addWidget(self.tree) hbox.addLayout(self.stacked) vbox.addLayout(hbox) hbox_footer = QHBoxLayout() self._btnSave = QPushButton(translations.TR_SAVE) self._btnCancel = QPushButton(translations.TR_CANCEL) hbox_footer.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_footer.addWidget(self._btnCancel) hbox_footer.addWidget(self._btnSave) vbox.addLayout(hbox_footer) self.connect(self.tree, SIGNAL("itemSelectionChanged()"), self._change_current) self.connect(self._btnCancel, SIGNAL("clicked()"), self.close) self.connect(self._btnSave, SIGNAL("clicked()"), self._save_preferences) self.load_ui() self.tree.setCurrentItem(self.tree.topLevelItem(0)) def _save_preferences(self): self.emit(SIGNAL("savePreferences()")) self.close() def load_ui(self): sections = sorted(list(Preferences.configuration.keys()), key=lambda item: Preferences.configuration[item]['weight']) for section in sections: text = Preferences.configuration[section]['text'] Widget = Preferences.configuration[section]['widget'] widget = Widget(self) area = QScrollArea() area.setWidgetResizable(True) area.setWidget(widget) index = self.stacked.addWidget(area) item = QTreeWidgetItem([text]) item.setData(0, Qt.UserRole, index) self.tree.addTopLevelItem(item) #Sort Item Children subcontent = Preferences.configuration[section].get( 'subsections', {}) subsections = sorted(list(subcontent.keys()), key=lambda item: subcontent[item]['weight']) for sub in subsections: text = subcontent[sub]['text'] Widget = subcontent[sub]['widget'] widget = Widget(self) area = QScrollArea() area.setWidgetResizable(True) area.setWidget(widget) index = self.stacked.addWidget(area) subitem = QTreeWidgetItem([text]) subitem.setData(0, Qt.UserRole, index) item.addChild(subitem) self.tree.expandAll() def _change_current(self): item = self.tree.currentItem() index = item.data(0, Qt.UserRole) self.stacked.setCurrentIndex(index) @classmethod def register_configuration(cls, section, widget, text, weight=None, subsection=None): if weight is None: Preferences.weight += 1 weight = Preferences.weight if not subsection: Preferences.configuration[section] = {'widget': widget, 'weight': weight, 'text': text} else: config = Preferences.configuration.get(section, {}) if not config: config[section] = {'widget': None, 'weight': 100} subconfig = config.get('subsections', {}) subconfig[subsection] = {'widget': widget, 'weight': weight, 'text': text} config['subsections'] = subconfig Preferences.configuration[section] = config
class DBDatabasesWidget(QWidget): """Displays a list of Databases""" def __init__(self, parent=None): QWidget.__init__(self, parent) self.debug = False self.db = None self.setWindowTitle("Databases") #s#elf.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) self.mainLayout = QVBoxLayout() self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.setSpacing(0) self.setLayout(self.mainLayout) #============================================= ## Top Toolbar topBar = QToolBar() topBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.mainLayout.addWidget(topBar) ## Add the action buttons topBar.addAction(Ico.icon(Ico.ServerAdd), "Add", self.on_server_add) self.actionServerEdit = topBar.addAction(Ico.icon(Ico.ServerEdit), "Edit", self.on_server_edit) self.actionServerDelete = topBar.addAction(Ico.icon(Ico.ServerDelete), "Delete", self.on_server_delete) #============================================= ## Tree self.tree = QTreeWidget() self.mainLayout.addWidget(self.tree) self.tree.setHeaderLabels(["Server", "User", ""]) self.tree.setUniformRowHeights(True) self.tree.setRootIsDecorated(False) self.tree.setColumnWidth(C.widget, 20) self.connect(self.tree, SIGNAL('itemSelectionChanged()'), self.on_tree_selection_changed) self.connect(self.tree, SIGNAL('itemDoubleClicked (QTreeWidgetItem *,int)'), self.on_tree_double_clicked) self.buttGroup = QButtonGroup(self) self.connect(self.buttGroup, SIGNAL("buttonClicked(QAbstractButton*)"), self.on_open_server) self.on_tree_selection_changed() self.load_servers() #======================================= ##== Tree Events def on_tree_selection_changed(self): disabled = self.tree.selectionModel().hasSelection() == False self.actionServerEdit.setDisabled(disabled) self.actionServerDelete.setDisabled(disabled) def on_tree_double_clicked(self): self.actionServerEdit.trigger() #======================================= ## Server Actions def on_server_add(self): self.show_server_dialog(None) def on_server_edit(self): item = self.tree.currentItem() if item == None: return server = str(item.text(C.server)) self.show_server_dialog(server) def show_server_dialog(self, server=None): d = DBServerDialog.DBServerDialog(self, server) if d.exec_(): self.load_servers() def on_open_server(self, butt): self.emit(SIGNAL("open_server"), butt.property("server").toString()) def load_servers(self): """Load servers from :py:meth:`pyqtdb.XSettings.XSettings.get_servers` """ self.tree.clear() for butt in self.buttGroup.buttons(): self.buttGroup.removeButton(butt) for srv in G.settings.get_servers_list(): item = QTreeWidgetItem() item.setText(C.server, srv['server']) item.setText(C.user, srv['user']) self.tree.addTopLevelItem(item) butt = QToolButton() butt.setIcon(Ico.icon(Ico.Connect)) butt.setProperty("server", srv['server']) self.tree.setItemWidget(item, C.widget, butt) self.buttGroup.addButton(butt) def on_server_delete(self): item = self.tree.currentItem() if item == None: return srv = str(item.text(C.server)) G.settings.delete_server(srv) self.load_servers()
class DBServersWidget(QWidget): """Displays a list of servers""" def __init__(self, parent=None): QWidget.__init__(self, parent) self.debug = False self.connections = {} self.setWindowTitle("Servers") #s#elf.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) self.mainLayout = QVBoxLayout() self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.setSpacing(0) self.setLayout(self.mainLayout) #============================================= ## Top Toolbar topBar = QToolBar() topBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.mainLayout.addWidget(topBar) ## Add the action buttons topBar.addAction(Ico.icon(Ico.ServerAdd), "Add", self.on_server_add) self.actionServerEdit = topBar.addAction(Ico.icon(Ico.ServerEdit), "Edit", self.on_server_edit) self.actionServerDelete = topBar.addAction(Ico.icon(Ico.ServerDelete), "Delete", self.on_server_delete) #============================================= ## Tree self.tree = QTreeWidget() self.mainLayout.addWidget(self.tree) self.tree.setUniformRowHeights(True) self.tree.setRootIsDecorated(True) self.tree.setHeaderLabels(["Server", "Butt"]) # set header, but hide anyway self.tree.header().hide() self.tree.header().setResizeMode(C.node, QHeaderView.Stretch) self.tree.setColumnWidth(C.butt, 20) self.connect(self.tree, SIGNAL('itemSelectionChanged()'), self.on_tree_selection_changed) self.connect(self.tree, SIGNAL('itemDoubleClicked (QTreeWidgetItem *,int)'), self.on_tree_double_clicked) self.buttGroup = QButtonGroup(self) self.connect(self.buttGroup, SIGNAL("buttonClicked(QAbstractButton*)"), self.on_open_server) self.on_tree_selection_changed() self.load_servers() #======================================= ##== Tree Events def on_tree_selection_changed(self): disabled = self.tree.selectionModel().hasSelection() == False self.actionServerEdit.setDisabled(disabled) self.actionServerDelete.setDisabled(disabled) def on_tree_double_clicked(self): self.actionServerEdit.trigger() #======================================= ## Server Actions def on_server_add(self): self.show_server_dialog(None) def on_server_edit(self): item = self.tree.currentItem() if item == None: return server = str(item.text(C.server)) self.show_server_dialog(server) def show_server_dialog(self, server=None): d = DBServerDialog.DBServerDialog(self, server) if d.exec_(): self.load_servers() def load_servers(self): """Load servers from :py:meth:`pyqtdb.XSettings.XSettings.get_servers` """ self.tree.clear() for butt in self.buttGroup.buttons(): self.buttGroup.removeButton(butt) for srv in G.settings.get_servers_list(): item = QTreeWidgetItem() item.setText(C.node, srv['server']) #item.setText(C.user, srv['user']) self.tree.addTopLevelItem(item) butt = QToolButton() butt.setIcon(Ico.icon(Ico.Connect)) butt.setProperty("server", srv['server']) self.tree.setItemWidget(item, C.butt, butt) self.buttGroup.addButton(butt) def on_server_delete(self): item = self.tree.currentItem() if item == None: return srv = str(item.text(C.server)) G.settings.delete_server(srv) self.load_servers() def on_open_server(self, butt): # self.emit(SIGNAL("open_server"), butt.property("server").toString()) srv_ki = str(butt.property("server").toString()) server = G.settings.get_server(srv_ki) db = QSqlDatabase.addDatabase("QMYSQL", srv_ki) db.setHostName(server['server']) db.setUserName(server['user']) db.setPassword(server['passwd']) ok = db.open() if ok: #self.connections[srv_ki] = self.load_databases(srv_ki) print "open", ok def load_databases(self, srv_ki): """Load databases into tree node for server; executes 'show databases;' or aslike """ sql = "show databases;" query = QSqlQuery(QSqlDatabase.database(srv_ki)) ok = query.exec_(sql) print ok, sql, query.result() # Get the parent node, ie the server node pItem = self.tree.findItems(srv_ki, Qt.MatchExactly, C.node)[0] ## Assumed value(0) is the table.. we need the defs (ie mysql case) while query.next(): table_name = query.value(0).toString() nuItem = QTreeWidgetItem(pItem) nuItem.setText(C.node, table_name) #print table_name self.tree.setItemExpanded(pItem, True)
class PluginWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.pluginMetadata = {} # Main layout self.mainLayout = QVBoxLayout() self.setLayout(self.mainLayout) # Define size used for the underlines self.underlineSize = QSize() self.underlineSize.setHeight(1) # Define font used for headers self.font = QFont() self.font.setPointSize(11) self.font.setBold(True) self.font.setUnderline(True) # Plugins Description self.pluginDescription = QLabel() self.pluginDescription.setText( "Click a plugin to see more information." + " Plugins can be configured from the Recording tab. \n") self.pluginDescription.setWordWrap(True) # Plugins GroupBox self.pluginLayout = QVBoxLayout() self.pluginGroupBox = QGroupBox( "Plugins extend the functionality of Freeseer") self.pluginGroupBox.setLayout(self.pluginLayout) self.pluginLayout.insertWidget(0, self.pluginDescription) self.mainLayout.insertWidget(0, self.pluginGroupBox) # Plugins list self.list = QTreeWidget() self.list.setHeaderHidden(True) self.list.headerItem().setText(0, "1") self.pluginLayout.insertWidget(1, self.list) # Details self.detailPane = QGroupBox() self.detailLayout = QVBoxLayout() self.detailPane.setLayout(self.detailLayout) self.detailPaneDesc = QLabel() self.detailPaneDesc.setWordWrap(True) self.detailLayout.addWidget(self.detailPaneDesc) self.pluginLayout.insertWidget(2, self.detailPane) self.list.itemSelectionChanged.connect(self.treeViewSelect) def treeViewSelect(self): item = self.list.currentItem() key = str(item.text(0)) if key in self.pluginMetadata.keys(): self.showDetails(key) else: self.hideDetails() def showDetails(self, key): self.detailPane.setTitle(key) self.detailPaneDesc.setText(self.pluginMetadata[key]) self.detailPane.show() def hideDetails(self): self.detailPane.hide() def getWidgetPlugin(self, plugin, plugin_category, plugman): plugin_name = plugin.plugin_object.get_name() item = QTreeWidgetItem() # Display Plugin's meta data in a tooltip pluginDetails = """ <table> <tr> <td>Name: </td> <td><b>%(name)s</b></td> </tr> <tr> <td>Version: </td> <td><b>%(version)s</b></td> <tr> <td>Author: </td> <td><b>%(author)s</b></td> </tr> <tr> <td>Website: </td> <td><b>%(website)s</b></td> </tr> <tr> <td>Description: </td> <td><b>%(description)s</b></td> </tr> </table> """ % { "name": plugin.name, "version": plugin.version, "author": plugin.author, "website": plugin.website, "description": plugin.description } # put the details in the hash table self.pluginMetadata[plugin_name] = pluginDetails item.setText(0, plugin_name) return item