class HyphenDialog(QDialog): def __init__(self, mainwindow): super(HyphenDialog, self).__init__(mainwindow) self.setWindowModality(Qt.WindowModal) layout = QVBoxLayout() self.setLayout(layout) self.topLabel = QLabel() self.listWidget = QListWidget() layout.addWidget(self.topLabel) layout.addWidget(self.listWidget) layout.addWidget(widgets.Separator()) self.buttons = b = QDialogButtonBox() layout.addWidget(b) b.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) help.addButton(b, lyrics_help) b.rejected.connect(self.reject) b.accepted.connect(self.accept) self.load() app.translateUI(self) qutil.saveDialogSize(self, "hyphenation/dialog/size") def translateUI(self): self.setWindowTitle(app.caption(_("Hyphenate Lyrics Text"))) self.topLabel.setText(_("Please select a language:")) def load(self): self._langs = [(language_names.languageName(lang, po.setup.current()), lang, dic) for lang, dic in findDicts().iteritems()] self._langs.sort() for name, lang, dic in self._langs: self.listWidget.addItem("{0} ({1})".format(name, lang)) def select(): lastused = settings().value("lastused", "", type("")) if lastused: yield lastused lang = po.setup.preferred()[0] yield lang yield lang.split('_')[0] langs = [item[1] for item in self._langs] for preselect in select(): try: self.listWidget.setCurrentRow(langs.index(preselect)) break except ValueError: continue def hyphenator(self): if self.exec_() and self._langs: lang, dic = self._langs[self.listWidget.currentRow()][1:] result = hyphenator.Hyphenator(dic) settings().setValue("lastused", lang) else: result = None self.deleteLater() return result
class PageProjectType(QWizardPage): def __init__(self, wizard): QWizardPage.__init__(self) self.setTitle(self.tr("Project Type")) self.setSubTitle(self.tr("Choose the Project Type")) self._wizard = wizard vbox = QVBoxLayout(self) self.listWidget = QListWidget() vbox.addWidget(self.listWidget) types = settings.get_all_project_types() types.sort() index = types.index('Python') types.insert(0, types.pop(index)) self.listWidget.addItems(types) self.listWidget.setCurrentRow(0) self.connect(self.listWidget, SIGNAL("itemClicked(QListWidgetItem *)"), self.load_pages) def validatePage(self): self._wizard.option = self.listWidget.currentItem().text() return True def load_pages(self): self.wizard().add_project_pages(self.listWidget.currentItem().text())
class BookView(QSplitter): def __init__(self, parent=None): super(BookView, self).__init__(parent=parent) self.create_layout() self.create_connections() def create_layout(self): self.web_view = QWebView() self.chapter_list = QListWidget() self.next_button = QPushButton("Next chapter") self.previous_button = QPushButton("Previous chapter") hbox = QHBoxLayout() hbox.addStretch() hbox.addWidget(self.previous_button) hbox.addWidget(self.next_button) vbox = QVBoxLayout() vbox.addWidget(QLabel("Chapters")) vbox.addWidget(self.chapter_list) vbox.addLayout(hbox) widget = QWidget() widget.setLayout(vbox) self.addWidget(self.web_view) self.addWidget(widget) def create_connections(self): chlist = self.chapter_list self.connect( self.next_button, SIGNAL("clicked()"), lambda: chlist.setCurrentRow(0 if chlist.currentRow( ) == chlist.count() - 1 else chlist.currentRow() + 1)) self.connect( self.previous_button, SIGNAL("clicked()"), lambda: chlist.setCurrentRow(chlist.count( ) - 1 if chlist.currentRow() == 0 else chlist.currentRow() - 1)) self.connect(self.chapter_list, SIGNAL("currentRowChanged(int)"), self.set_chapter) page = self.web_view.page() page.setLinkDelegationPolicy(QWebPage.DelegateAllLinks) def set_chapter(self, num=None): if num is None: num = self.chapter_list.currentRow() if num < 0: num = len(self.book.chapters) - 1 elif num >= len(self.book.chapters): num = 0 self.web_view.setHtml( self.book.get_chapter(num).decode(encoding="utf-8")) def load_book(self, book_id): self.book = Book(book_id) self.chapter_list.clear() for chapter in self.book.chapters: self.chapter_list.addItem(chapter[0]) self.chapter_list.setCurrentRow(0)
class OpenProjectType(QDialog, ProjectWizard): def __init__(self, main): QDialog.__init__(self) ProjectWizard.__init__(self) self._main = main self.setModal(True) vbox = QVBoxLayout(self) vbox.addWidget(QLabel('Select the Type of Project:')) self.listWidget = QListWidget() projectTypes = self.types.keys() projectTypes.sort() self.listWidget.addItems(projectTypes) vbox.addWidget(self.listWidget) btnNext = QPushButton('Next') vbox.addWidget(btnNext) if len(projectTypes) > 0: self.listWidget.setCurrentRow(0) else: btnNext.setEnabled(False) self.connect(btnNext, SIGNAL("clicked()"), self._open_project) def _open_project(self): type_ = str(self.listWidget.currentItem().text()) extensions = self.types[type_].projectFiles() if extensions is None: self._main.open_project_folder() else: self._main.open_project_type(extensions)
class BookView(QSplitter): def __init__(self, parent=None): super(BookView, self).__init__(parent=parent) self.create_layout() self.create_connections() def create_layout(self): self.web_view = QWebView() self.chapter_list = QListWidget() self.next_button = QPushButton("Next chapter") self.previous_button = QPushButton("Previous chapter") hbox = QHBoxLayout() hbox.addStretch() hbox.addWidget(self.previous_button) hbox.addWidget(self.next_button) vbox = QVBoxLayout() vbox.addWidget(QLabel("Chapters")) vbox.addWidget(self.chapter_list) vbox.addLayout(hbox) widget = QWidget() widget.setLayout(vbox) self.addWidget(self.web_view) self.addWidget(widget) def create_connections(self): chlist = self.chapter_list self.connect(self.next_button, SIGNAL("clicked()"), lambda: chlist.setCurrentRow(0 if chlist.currentRow() == chlist.count() - 1 else chlist.currentRow() + 1)) self.connect(self.previous_button, SIGNAL("clicked()"), lambda: chlist.setCurrentRow(chlist.count() - 1 if chlist.currentRow() == 0 else chlist.currentRow() - 1)) self.connect(self.chapter_list, SIGNAL("currentRowChanged(int)"), self.set_chapter) page = self.web_view.page() page.setLinkDelegationPolicy(QWebPage.DelegateAllLinks) def set_chapter(self, num=None): if num is None: num = self.chapter_list.currentRow() if num < 0: num = len(self.book.chapters) - 1 elif num >= len(self.book.chapters): num = 0 self.web_view.setHtml(self.book.get_chapter(num).decode(encoding="utf-8")) def load_book(self, book_id): self.book = Book(book_id) self.chapter_list.clear() for chapter in self.book.chapters: self.chapter_list.addItem(chapter[0]) self.chapter_list.setCurrentRow(0)
class PopupCompleter(QFrame): def __init__(self, model): QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.listWidget = QListWidget() for i, item in enumerate(model): self.listWidget.addItem(item) self.listWidget.setCurrentRow(0) vbox.addWidget(self.listWidget) def refresh(self, model): self.listWidget.clear() for i, item in enumerate(model): self.listWidget.addItem(item) self.listWidget.setCurrentRow(0)
class PageProjectType(QWizardPage): def __init__(self, wizard): QWizardPage.__init__(self) self.setTitle(self.tr("Project Type")) self.setSubTitle(self.tr("Choose the Project Type")) self._wizard = wizard vbox = QVBoxLayout(self) self.listWidget = QListWidget() vbox.addWidget(self.listWidget) types = settings.get_all_project_types() types.sort() index = types.index('Python') types.insert(0, types.pop(index)) self.listWidget.addItems(types) self.listWidget.setCurrentRow(0)
class PythonDetectDialog(QDialog): def __init__(self, suggested, parent=None): super(PythonDetectDialog, self).__init__(parent, Qt.Dialog) self.setMaximumSize(QSize(0, 0)) self.setWindowTitle("Configure Python Path") vbox = QVBoxLayout(self) lblMessage = QLabel(self.tr("We have detected that you are using " + "Windows,\nplease choose the proper " + "Python application for you:")) vbox.addWidget(lblMessage) self.listPaths = QListWidget() self.listPaths.setSelectionMode(QListWidget.SingleSelection) vbox.addWidget(self.listPaths) hbox = QHBoxLayout() hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) btnCancel = QPushButton(self.tr("Cancel")) btnAccept = QPushButton(self.tr("Accept")) hbox.addWidget(btnCancel) hbox.addWidget(btnAccept) vbox.addLayout(hbox) self.connect(btnAccept, SIGNAL("clicked()"), self._set_python_path) self.connect(btnCancel, SIGNAL("clicked()"), self.close) for path in suggested: self.listPaths.addItem(path) self.listPaths.setCurrentRow(0) def _set_python_path(self): python_path = self.listPaths.currentItem().text() qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat) settings.PYTHON_PATH = python_path settings.PYTHON_EXEC = python_path settings.PYTHON_EXEC_CONFIGURED_BY_USER = True qsettings.setValue('preferences/execution/pythonPath', python_path) qsettings.setValue('preferences/execution/pythonPathConfigured', True) self.close()
class PythonDetectDialog(QDialog): def __init__(self, suggested, parent=None): super(PythonDetectDialog, self).__init__(parent, Qt.Dialog) self.setMaximumSize(QSize(0, 0)) self.setWindowTitle("Configure Python Path") vbox = QVBoxLayout(self) msg_str = ("We have detected that you are using " "Windows,\nplease choose the proper " "Python application for you:") lblMessage = QLabel(self.tr(msg_str)) vbox.addWidget(lblMessage) self.listPaths = QListWidget() self.listPaths.setSelectionMode(QListWidget.SingleSelection) vbox.addWidget(self.listPaths) hbox = QHBoxLayout() hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) btnCancel = QPushButton(self.tr("Cancel")) btnAccept = QPushButton(self.tr("Accept")) hbox.addWidget(btnCancel) hbox.addWidget(btnAccept) vbox.addLayout(hbox) self.connect(btnAccept, SIGNAL("clicked()"), self._set_python_path) self.connect(btnCancel, SIGNAL("clicked()"), self.close) for path in suggested: self.listPaths.addItem(path) self.listPaths.setCurrentRow(0) def _set_python_path(self): python_path = self.listPaths.currentItem().text() qsettings = QSettings(resources.SETTINGS_PATH, QSettings.IniFormat) settings.PYTHON_PATH = python_path settings.PYTHON_EXEC = python_path settings.PYTHON_EXEC_CONFIGURED_BY_USER = True qsettings.setValue('preferences/execution/pythonExec', python_path) qsettings.setValue('preferences/execution/pythonExecConfigured', True) self.close()
class PageProjectType(QWizardPage): def __init__(self, wizard): QWizardPage.__init__(self) self.setTitle("Project Type") self.setSubTitle("Choose the Project Type") self._wizard = wizard vbox = QVBoxLayout(self) self.listWidget = QListWidget() vbox.addWidget(self.listWidget) types = self._wizard.types.keys() types.sort() self.listWidget.addItems(types) index = types.index("Python") self.listWidget.setCurrentRow(index) self.connect(self.listWidget, SIGNAL("itemSelectionChanged()"), self.item_changed) def item_changed(self): self._wizard.add_project_pages(str(self.listWidget.currentItem().text()))
class PageProjectType(QWizardPage): def __init__(self, wizard): QWizardPage.__init__(self) self.setTitle('Project Type') self.setSubTitle('Choose the Project Type') self._wizard = wizard vbox = QVBoxLayout(self) self.listWidget = QListWidget() vbox.addWidget(self.listWidget) types = self._wizard.types.keys() types.sort() self.listWidget.addItems(types) index = types.index('Python') self.listWidget.setCurrentRow(index) self.connect(self.listWidget, SIGNAL("itemSelectionChanged()"), self.item_changed) def item_changed(self): self._wizard.add_project_pages(str(self.listWidget.currentItem().text()))
class EpisodeSelector(QDialog): def __init__(self, feed): super(EpisodeSelector, self).__init__() layout = QVBoxLayout() layout.addWidget(QLabel(feed['title'])) self.eplist = QListWidget() self.eps = sorted(feed['entries'], key = lambda x: x['updated']) selectionIndex = -1 i = 0 for ep in self.eps: self.eplist.addItem(QString(ep['title'])) if ep['updated'] == feed['lastUpdate']: selectionIndex = i i += 1 self.eplist.setCurrentRow(selectionIndex) layout.addWidget(self.eplist) cancelButton = QPushButton('Cancel') okButton = QPushButton('Set as last episode') self.connect(cancelButton, SIGNAL('clicked()'), self.reject) self.connect(okButton, SIGNAL('clicked()'), self.acceptLocal) buttonsLayout = QHBoxLayout() buttonsLayout.addStretch() buttonsLayout.addWidget(cancelButton) buttonsLayout.addWidget(okButton) layout.addLayout(buttonsLayout) self.setLayout(layout) def acceptLocal(self): self.lastUpdate = self.eps[self.eplist.currentRow()]['updated'] self.accept()
def hyphenate(text, mainwindow): """ Ask the user which language to use. Returns None if the user cancels the dialog or no hyphenation pattern files could be found. """ if not hyphdicts: KMessageBox.sorry(mainwindow, i18n( "Could not find any hyphenation dictionaries.\n\n" "Please install a package containing some and/or or configure the " "search path to find them in the Frescobaldi settings under " "\"Paths.\"")) return conf = config("hyphenation") lang = conf.readEntry("lastused", "") langs = list(sorted(hyphdicts.keys())) index = lang in langs and langs.index(lang) or 0 d = KDialog(mainwindow) d.setButtons(KDialog.ButtonCode(KDialog.Ok | KDialog.Cancel | KDialog.Help)) d.setCaption(i18n("Hyphenate Lyrics Text")) d.setHelp("lyrics") layout = QVBoxLayout() d.mainWidget().setLayout(layout) layout.addWidget(QLabel(i18n("Please select a language:"))) listbox = QListWidget() layout.addWidget(listbox) listbox.addItems(langs) listbox.setCurrentRow(index) listbox.setFocus() if d.exec_(): lang = langs[listbox.currentRow()] conf.writeEntry("lastused", lang) conf.sync() # get hyphenator h = Hyphenator(hyphdicts[lang]) return ly.rx.lyric_word.sub(lambda m: h.inserted(m.group(), ' -- '), text)
class Navegador(custom_dock.CustomDock): def __init__(self): custom_dock.CustomDock.__init__(self) self.navegador = QListWidget() self.setWidget(self.navegador) self.navegador.itemClicked.connect(self._cambiar_editor) EDIS.cargar_lateral("navegador", self) def agregar(self, archivo): self.navegador.addItem(archivo) def eliminar(self, indice): self.navegador.takeItem(indice) def cambiar_foco(self, indice): self.navegador.setCurrentRow(indice) def _cambiar_editor(self): indice = self.navegador.row(self.navegador.currentItem()) principal = EDIS.componente("principal") principal.cambiar_widget(indice)
class PopupCompleter(QFrame): def __init__(self): QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.listWidget = QListWidget() self.listWidget.setMinimumHeight(350) vbox.addWidget(self.listWidget) self.listWidget.currentItemChanged.connect(self._repaint_items) def _repaint_items(self, current, previous): if current is not None: widget = self.listWidget.itemWidget(current) if widget is not None: widget.set_selected() if previous is not None: widget = self.listWidget.itemWidget(previous) if widget is not None: widget.set_not_selected() def reload(self, model): """Reload the data of the Popup Completer, and restart the state.""" self.listWidget.clear() self.add_help() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) self.listWidget.setCurrentRow(8) def clear(self): """Remove all the items of the list (deleted), and reload the help.""" self.listWidget.clear() def refresh(self, model, has_text=True): """Refresh the list when the user search for some word.""" self.listWidget.clear() if not has_text: self.add_help() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) if model: self.listWidget.setCurrentItem(model[0][0]) else: self.add_no_found() def fetch_more(self, model): """Add more items to the list on user scroll.""" for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) def add_no_found(self): #Load no results found message noFoundItem = QListWidgetItem( QIcon(resources.IMAGES['delete']), 'No results were found!') font = noFoundItem.font() font.setBold(True) noFoundItem.setSizeHint(QSize(20, 30)) noFoundItem.setBackground(QBrush(Qt.lightGray)) noFoundItem.setForeground(QBrush(Qt.black)) noFoundItem.setFont(font) self.listWidget.addItem(noFoundItem) def add_help(self): #Load help fileItem = QListWidgetItem( QIcon(resources.IMAGES['locate-file']), '@\t(Filter only by Files)') font = fileItem.font() font.setBold(True) fileItem.setSizeHint(QSize(20, 30)) fileItem.setBackground(QBrush(Qt.lightGray)) fileItem.setForeground(QBrush(Qt.black)) fileItem.setFont(font) self.listWidget.addItem(fileItem) classItem = QListWidgetItem( QIcon(resources.IMAGES['locate-class']), '<\t(Filter only by Classes)') self.listWidget.addItem(classItem) classItem.setSizeHint(QSize(20, 30)) classItem.setBackground(QBrush(Qt.lightGray)) classItem.setForeground(QBrush(Qt.black)) classItem.setFont(font) methodItem = QListWidgetItem( QIcon(resources.IMAGES['locate-function']), '>\t(Filter only by Methods)') self.listWidget.addItem(methodItem) methodItem.setSizeHint(QSize(20, 30)) methodItem.setBackground(QBrush(Qt.lightGray)) methodItem.setForeground(QBrush(Qt.black)) methodItem.setFont(font) attributeItem = QListWidgetItem( QIcon(resources.IMAGES['locate-attributes']), '-\t(Filter only by Attributes)') self.listWidget.addItem(attributeItem) attributeItem.setSizeHint(QSize(20, 30)) attributeItem.setBackground(QBrush(Qt.lightGray)) attributeItem.setForeground(QBrush(Qt.black)) attributeItem.setFont(font) thisFileItem = QListWidgetItem( QIcon(resources.IMAGES['locate-on-this-file']), '.\t(Filter only by Classes and Methods in this File)') font = thisFileItem.font() font.setBold(True) thisFileItem.setSizeHint(QSize(20, 30)) thisFileItem.setBackground(QBrush(Qt.lightGray)) thisFileItem.setForeground(QBrush(Qt.black)) thisFileItem.setFont(font) self.listWidget.addItem(thisFileItem) tabsItem = QListWidgetItem( QIcon(resources.IMAGES['locate-tab']), '/\t(Filter only by the current Tabs)') font = tabsItem.font() font.setBold(True) tabsItem.setSizeHint(QSize(20, 30)) tabsItem.setBackground(QBrush(Qt.lightGray)) tabsItem.setForeground(QBrush(Qt.black)) tabsItem.setFont(font) self.listWidget.addItem(tabsItem) lineItem = QListWidgetItem( QIcon(resources.IMAGES['locate-line']), ':\t(Go to Line)') font = lineItem.font() font.setBold(True) lineItem.setSizeHint(QSize(20, 30)) lineItem.setBackground(QBrush(Qt.lightGray)) lineItem.setForeground(QBrush(Qt.black)) lineItem.setFont(font) self.listWidget.addItem(lineItem) nonPythonItem = QListWidgetItem( QIcon(resources.IMAGES['locate-nonpython']), '!\t(Filter only by Non Python Files)') self.listWidget.addItem(nonPythonItem) nonPythonItem.setSizeHint(QSize(20, 30)) nonPythonItem.setBackground(QBrush(Qt.lightGray)) nonPythonItem.setForeground(QBrush(Qt.black)) nonPythonItem.setFont(font)
class ProfilesLoader(QDialog): def __init__(self, load_func, create_func, save_func, profiles, parent=None): QDialog.__init__(self, parent, Qt.Dialog) self.setWindowTitle(self.tr("Profile Manager")) self.setMinimumWidth(400) self._profiles = profiles self.load_function = load_func self.create_function = create_func self.save_function = save_func self.ide = parent vbox = QVBoxLayout(self) vbox.addWidget( QLabel( self.tr("Save your opened files and projects " "into a profile and change really quick\n" "between projects and files sessions.\n" "This allows you to save your working environment, " "keep working in another\nproject and then go back " "exactly where you left."))) self.profileList = QListWidget() self.profileList.addItems([key for key in profiles]) self.profileList.setCurrentRow(0) self.contentList = QListWidget() self.btnDelete = QPushButton(self.tr("Delete Profile")) self.btnDelete.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnUpdate = QPushButton(self.tr("Update Profile")) self.btnUpdate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnCreate = QPushButton(self.tr("Create New Profile")) self.btnCreate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnOpen = QPushButton(self.tr("Open Profile")) self.btnOpen.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnOpen.setDefault(True) hbox = QHBoxLayout() hbox.addWidget(self.btnDelete) hbox.addWidget(self.btnUpdate) hbox.addWidget(self.btnCreate) hbox.addWidget(self.btnOpen) vbox.addWidget(self.profileList) vbox.addWidget(self.contentList) vbox.addLayout(hbox) self.connect(self.profileList, SIGNAL("itemSelectionChanged()"), self.load_profile_content) self.connect(self.btnOpen, SIGNAL("clicked()"), self.open_profile) self.connect(self.btnUpdate, SIGNAL("clicked()"), self.save_profile) self.connect(self.btnCreate, SIGNAL("clicked()"), self.create_profile) self.connect(self.btnDelete, SIGNAL("clicked()"), self.delete_profile) def load_profile_content(self): item = self.profileList.currentItem() self.contentList.clear() if item is not None: key = item.text() files = [self.tr('Files:')] + \ [file[0] for file in self._profiles[key][0]] projects = [self.tr('Projects:')] + self._profiles[key][1] content = files + projects self.contentList.addItems(content) def create_profile(self): profileName = self.create_function() self.ide.Profile = profileName self.close() def save_profile(self): if self.profileList.currentItem(): profileName = self.profileList.currentItem().text() self.save_function(profileName) self.ide.show_status_message( self.tr("Profile %s Updated!" % profileName)) self.load_profile_content() def open_profile(self): if self.profileList.currentItem(): key = self.profileList.currentItem().text() self.load_function(key) self.ide.Profile = key self.close() def delete_profile(self): if self.profileList.currentItem(): key = self.profileList.currentItem().text() self._profiles.pop(key) self.profileList.takeItem(self.profileList.currentRow()) self.contentList.clear()
class ConfigDialog(QDialog): def __init__(self, parent=None): QDialog.__init__(self, parent) self.contents_widget = QListWidget() self.contents_widget.setMovement(QListView.Static) self.contents_widget.setMinimumWidth(120) self.contents_widget.setMaximumWidth(120) self.contents_widget.setSpacing(1) bbox = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Apply |QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()")) self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()")) self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"), self.button_clicked) self.pages_widget = QStackedWidget() self.connect(self.pages_widget, SIGNAL("currentChanged(int)"), self.current_page_changed) self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"), self.pages_widget.setCurrentIndex) self.contents_widget.setCurrentRow(0) hlayout = QHBoxLayout() hlayout.addWidget(self.contents_widget) hlayout.addWidget(self.pages_widget) hlayout.setStretch(1,1) btnlayout = QHBoxLayout() btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addLayout(hlayout) vlayout.addLayout(btnlayout) self.setLayout(vlayout) self.setWindowTitle("Preferences") self.setWindowIcon(get_icon("configure.png")) def get_current_index(self): """Return current page index""" return self.contents_widget.currentRow() def set_current_index(self, index): """Set current page index""" self.contents_widget.setCurrentRow(index) def accept(self): """Reimplement Qt method""" for index in range(self.pages_widget.count()): configpage = self.pages_widget.widget(index) if not configpage.is_valid(): return configpage.apply_changes() QDialog.accept(self) def button_clicked(self, button): if button is self.apply_btn: # Apply button was clicked configpage = self.pages_widget.currentWidget() if not configpage.is_valid(): return configpage.apply_changes() def current_page_changed(self, index): widget = self.pages_widget.widget(index) self.apply_btn.setVisible(widget.apply_callback is not None) self.apply_btn.setEnabled(widget.is_modified) def add_page(self, widget): self.connect(self, SIGNAL('check_settings()'), widget.check_settings) self.connect(widget, SIGNAL('show_this_page()'), lambda row=self.contents_widget.count(): self.contents_widget.setCurrentRow(row)) self.connect(widget, SIGNAL("apply_button_enabled(bool)"), self.apply_btn.setEnabled) self.pages_widget.addWidget(widget) item = QListWidgetItem(self.contents_widget) item.setIcon(widget.get_icon()) item.setText(widget.get_name()) item.setFlags(Qt.ItemIsSelectable|Qt.ItemIsEnabled) item.setSizeHint(QSize(0, 25)) def check_all_settings(self): """This method is called to check all configuration page settings after configuration dialog has been shown""" self.emit(SIGNAL('check_settings()'))
class EditorGeneral(QWidget): """EditorGeneral widget class.""" def __init__(self, parent): super(EditorGeneral, self).__init__() self._preferences, vbox = parent, QVBoxLayout(self) self.original_style = copy.copy(resources.CUSTOM_SCHEME) self.current_scheme, self._modified_editors = 'default', [] self._font = settings.FONT groupBoxMini = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_MINIMAP) groupBoxTypo = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_TYPOGRAPHY) groupBoxScheme = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_SCHEME) #Minimap formMini = QGridLayout(groupBoxMini) formMini.setContentsMargins(5, 15, 5, 5) self._checkShowMinimap = QCheckBox( translations.TR_PREFERENCES_EDITOR_GENERAL_ENABLE_MINIMAP) self._spinMaxOpacity = QSpinBox() self._spinMaxOpacity.setRange(0, 100) self._spinMaxOpacity.setSuffix("% Max.") self._spinMinOpacity = QSpinBox() self._spinMinOpacity.setRange(0, 100) self._spinMinOpacity.setSuffix("% Min.") self._spinSize = QSpinBox() self._spinSize.setMaximum(100) self._spinSize.setMinimum(0) self._spinSize.setSuffix( translations.TR_PREFERENCES_EDITOR_GENERAL_AREA_MINIMAP) formMini.addWidget(self._checkShowMinimap, 0, 1) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_SIZE_MINIMAP), 1, 0, Qt.AlignRight) formMini.addWidget(self._spinSize, 1, 1) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_OPACITY), 2, 0, Qt.AlignRight) formMini.addWidget(self._spinMinOpacity, 2, 1) formMini.addWidget(self._spinMaxOpacity, 2, 2) #Typo gridTypo = QGridLayout(groupBoxTypo) gridTypo.setContentsMargins(5, 15, 5, 5) self._btnEditorFont = QPushButton('') gridTypo.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_EDITOR_FONT), 0, 0, Qt.AlignRight) gridTypo.addWidget(self._btnEditorFont, 0, 1) #Scheme vboxScheme = QVBoxLayout(groupBoxScheme) vboxScheme.setContentsMargins(5, 15, 5, 5) self._listScheme = QListWidget() vboxScheme.addWidget(self._listScheme) hbox = QHBoxLayout() btnDownload = QPushButton( translations.TR_PREFERENCES_EDITOR_DOWNLOAD_SCHEME) btnDownload.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.connect(btnDownload, SIGNAL("clicked()"), self._open_schemes_manager) hbox.addWidget(btnDownload) btnAdd = QPushButton(QIcon(":img/add"), translations.TR_EDITOR_CREATE_SCHEME) btnAdd.setIconSize(QSize(16, 16)) btnAdd.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.connect(btnAdd, SIGNAL("clicked()"), self._open_schemes_designer) btnRemove = QPushButton(QIcon(":img/delete"), translations.TR_EDITOR_REMOVE_SCHEME) btnRemove.setIconSize(QSize(16, 16)) btnRemove.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.connect(btnRemove, SIGNAL("clicked()"), self._remove_scheme) hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox.addWidget(btnAdd) hbox.addWidget(btnRemove) vboxScheme.addLayout(hbox) vbox.addWidget(groupBoxMini) vbox.addWidget(groupBoxTypo) vbox.addWidget(groupBoxScheme) #Settings qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') self._checkShowMinimap.setChecked(settings.SHOW_MINIMAP) if settings.IS_MAC_OS: self._spinMinOpacity.setValue(100) self._spinMaxOpacity.setValue(100) self._spinMinOpacity.setDisabled(True) self._spinMaxOpacity.setDisabled(True) else: self._spinMinOpacity.setValue(settings.MINIMAP_MIN_OPACITY * 100) self._spinMaxOpacity.setValue(settings.MINIMAP_MAX_OPACITY * 100) self._spinSize.setValue(settings.SIZE_PROPORTION * 100) btnText = ', '.join(self._font.toString().split(',')[0:2]) self._btnEditorFont.setText(btnText) self._listScheme.clear() self._listScheme.addItem('default') self._schemes = json_manager.load_editor_skins() for item in self._schemes: self._listScheme.addItem(item) items = self._listScheme.findItems( qsettings.value('scheme', defaultValue='', type='QString'), Qt.MatchExactly) if items: self._listScheme.setCurrentItem(items[0]) else: self._listScheme.setCurrentRow(0) qsettings.endGroup() qsettings.endGroup() #Signals self.connect(self._btnEditorFont, SIGNAL("clicked()"), self._load_editor_font) self.connect(self._listScheme, SIGNAL("itemSelectionChanged()"), self._preview_style) self.connect(self._preferences, SIGNAL("savePreferences()"), self.save) def _open_schemes_manager(self): ninjaide = IDE.get_service("ide") ninjaide.show_schemes() # refresh schemes def _open_schemes_designer(self): name = self._listScheme.currentItem().text() scheme = self._schemes.get(name, resources.COLOR_SCHEME) designer = preferences_editor_scheme_designer.EditorSchemeDesigner( scheme, self) designer.exec_() if designer.saved: scheme_name = designer.line_name.text() scheme = designer.original_style self._schemes[scheme_name] = scheme result = self._listScheme.findItems(scheme_name, Qt.MatchExactly) if not result: self._listScheme.addItem(scheme_name) def _remove_scheme(self): name = self._listScheme.currentItem().text() fileName = ('{0}.color'.format( file_manager.create_path(resources.EDITOR_SKINS, name))) file_manager.delete_file(fileName) item = self._listScheme.takeItem(self._listScheme.currentRow()) del item def hideEvent(self, event): super(EditorGeneral, self).hideEvent(event) resources.CUSTOM_SCHEME = self.original_style for editorWidget in self._modified_editors: try: editorWidget.restyle(editorWidget.lang) except RuntimeError: print('the editor has been removed') def _preview_style(self): scheme = self._listScheme.currentItem().text() if scheme == self.current_scheme: return main_container = IDE.get_service('main_container') if not main_container: return editorWidget = main_container.get_current_editor() if editorWidget is not None: resources.CUSTOM_SCHEME = self._schemes.get( scheme, resources.COLOR_SCHEME) editorWidget.restyle(editorWidget.lang) self._modified_editors.append(editorWidget) self.current_scheme = scheme def _load_editor_font(self): try: font, ok = QFontDialog.getFont(self._font, self) if ok: self._font = font btnText = ', '.join(self._font.toString().split(',')[0:2]) self._btnEditorFont.setText(btnText) except: QMessageBox.warning( self, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_TITLE, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_BODY) def save(self): qsettings = IDE.ninja_settings() settings.FONT = self._font qsettings.setValue('preferences/editor/font', settings.FONT) settings.SHOW_MINIMAP = self._checkShowMinimap.isChecked() settings.MINIMAP_MAX_OPACITY = self._spinMaxOpacity.value() / 100.0 settings.MINIMAP_MIN_OPACITY = self._spinMinOpacity.value() / 100.0 settings.SIZE_PROPORTION = self._spinSize.value() / 100.0 qsettings.setValue('preferences/editor/minimapMaxOpacity', settings.MINIMAP_MAX_OPACITY) qsettings.setValue('preferences/editor/minimapMinOpacity', settings.MINIMAP_MIN_OPACITY) qsettings.setValue('preferences/editor/minimapSizeProportion', settings.SIZE_PROPORTION) qsettings.setValue('preferences/editor/minimapShow', settings.SHOW_MINIMAP) scheme = self._listScheme.currentItem().text() resources.CUSTOM_SCHEME = self._schemes.get(scheme, resources.COLOR_SCHEME) qsettings.setValue('preferences/editor/scheme', scheme)
class NotebookListDialog(QDialog): """ Functions to display, create, remove, modify notebookList """ def __init__(self, parent=None): super(NotebookListDialog, self).__init__(parent) self.notebookList = QListWidget() self.moveUp = QPushButton('<<') self.moveDown = QPushButton('>>') self.add = QPushButton('Add') self.remove = QPushButton('Remove') self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) layout = QGridLayout() layout.addWidget(self.notebookList, 0, 0, 4, 6) layout.addWidget(self.moveUp, 1, 6) layout.addWidget(self.moveDown, 2, 6) layout.addWidget(self.add, 4, 0) layout.addWidget(self.remove, 4, 1) layout.addWidget(self.buttonBox, 4, 5, 1, 2) self.setLayout(layout) self.notebookList.setItemDelegate(ListDelegate(self.notebookList)) self.notebookList.currentRowChanged.connect(self.updateUi) self.add.clicked.connect(self.actionAdd) self.remove.clicked.connect(self.actionRemove) self.moveUp.clicked.connect(self.moveItemUp) self.moveDown.clicked.connect(self.moveItemDown) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.initList() def initList(self): self.notebookList.clear() notebooks = Mikibook.read() for nb in notebooks: item = QListWidgetItem() item.setData(Qt.DisplayRole, nb[0]) item.setData(Qt.UserRole, nb[1]) self.notebookList.addItem(item) self.updateUi(len(notebooks) != 0) self.notebookList.setCurrentRow(0) # QListWidgetItem(nb, self.notebookList) def updateUi(self, row): flag = (row != -1) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(flag) self.remove.setEnabled(flag) self.moveUp.setEnabled(flag) self.moveDown.setEnabled(flag) def actionAdd(self): Mikibook.create() self.initList() count = self.notebookList.count() self.notebookList.setCurrentRow(count - 1) def actionRemove(self): item = self.notebookList.currentItem() row = self.notebookList.currentRow() name = item.data(Qt.DisplayRole) path = item.data(Qt.UserRole) self.notebookList.takeItem(row) Mikibook.remove(name, path) def moveItemUp(self): item = self.notebookList.currentItem() row = self.notebookList.currentRow() if row != 0: # self.notebookList.removeItemWidget(item) self.notebookList.takeItem(row) self.notebookList.insertItem(row - 1, item) self.notebookList.setCurrentRow(row - 1) def moveItemDown(self): item = self.notebookList.currentItem() row = self.notebookList.currentRow() count = self.notebookList.count() if row != count - 1: self.notebookList.takeItem(row) self.notebookList.insertItem(row + 1, item) self.notebookList.setCurrentRow(row + 1) def accept(self): notebookPath = self.notebookList.currentItem().data(Qt.UserRole) notebookName = self.notebookList.currentItem().data(Qt.DisplayRole) settings = Setting([[notebookName, notebookPath]]) window = mikidown.MikiWindow(settings) window.show() count = self.notebookList.count() notebooks = [] for i in range(count): name = self.notebookList.item(i).data(Qt.DisplayRole) path = self.notebookList.item(i).data(Qt.UserRole) notebooks.append([name, path]) Mikibook.write(notebooks) QDialog.accept(self)
class EditorGeneral(QWidget): def __init__(self, parent): super(EditorGeneral, self).__init__() self._preferences = parent vbox = QVBoxLayout(self) self.original_style = copy.copy(resources.CUSTOM_SCHEME) self.current_scheme = 'default' groupBoxMini = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_MINIMAP) groupBoxTypo = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_TYPOGRAPHY) groupBoxScheme = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_SCHEME) #Minimap formMini = QGridLayout(groupBoxMini) self._checkShowMinimap = QCheckBox() self._spinMaxOpacity = QSpinBox() self._spinMaxOpacity.setMaximum(100) self._spinMaxOpacity.setMinimum(0) self._spinMinOpacity = QSpinBox() self._spinMinOpacity.setMaximum(100) self._spinMinOpacity.setMinimum(0) self._spinSize = QSpinBox() self._spinSize.setMaximum(100) self._spinSize.setMinimum(0) formMini.addWidget( QLabel(translations.TR_PREFERENCES_EDITOR_GENERAL_ENABLE_MINIMAP), 0, 0, Qt.AlignRight) formMini.addWidget( QLabel(translations.TR_PREFERENCES_EDITOR_GENERAL_MAX_OPACITY), 1, 0, Qt.AlignRight) formMini.addWidget( QLabel(translations.TR_PREFERENCES_EDITOR_GENERAL_MIN_OPACITY), 2, 0, Qt.AlignRight) formMini.addWidget( QLabel(translations.TR_PREFERENCES_EDITOR_GENERAL_AREA_MINIMAP), 3, 0, Qt.AlignRight) formMini.addWidget(self._checkShowMinimap, 0, 1) formMini.addWidget(self._spinMaxOpacity, 1, 1) formMini.addWidget(self._spinMinOpacity, 2, 1) formMini.addWidget(self._spinSize, 3, 1) #Typo gridTypo = QGridLayout(groupBoxTypo) self._btnEditorFont = QPushButton('') gridTypo.addWidget( QLabel(translations.TR_PREFERENCES_EDITOR_GENERAL_EDITOR_FONT), 0, 0, Qt.AlignRight) gridTypo.addWidget(self._btnEditorFont, 0, 1) #Scheme hbox = QHBoxLayout(groupBoxScheme) self._listScheme = QListWidget() hbox.addWidget(self._listScheme) vbox.addWidget(groupBoxMini) vbox.addWidget(groupBoxTypo) vbox.addWidget(groupBoxScheme) #Settings qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') self._checkShowMinimap.setChecked(settings.SHOW_MINIMAP) self._spinMaxOpacity.setValue(settings.MINIMAP_MAX_OPACITY * 100) self._spinMinOpacity.setValue(settings.MINIMAP_MIN_OPACITY * 100) self._spinSize.setValue(settings.SIZE_PROPORTION * 100) self._btnEditorFont.setText(', '.join( [settings.FONT_FAMILY, str(settings.FONT_SIZE)])) self._listScheme.clear() self._listScheme.addItem('default') self._schemes = json_manager.load_editor_skins() for item in self._schemes: self._listScheme.addItem(item) items = self._listScheme.findItems( qsettings.value('scheme', defaultValue='', type='QString'), Qt.MatchExactly) if items: self._listScheme.setCurrentItem(items[0]) else: self._listScheme.setCurrentRow(0) qsettings.endGroup() qsettings.endGroup() #Signals self.connect(self._btnEditorFont, SIGNAL("clicked()"), self._load_editor_font) self.connect(self._listScheme, SIGNAL("itemSelectionChanged()"), self._preview_style) self.connect(self._preferences, SIGNAL("savePreferences()"), self.save) def showEvent(self, event): super(EditorGeneral, self).showEvent(event) self.thread_callback = ui_tools.ThreadExecution(self._get_editor_skins) self.connect(self.thread_callback, SIGNAL("finished()"), self._show_editor_skins) self.thread_callback.start() def _get_editor_skins(self): qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') self._schemes = json_manager.load_editor_skins() self._selected_scheme = qsettings.value('scheme', defaultValue='', type='QString') qsettings.endGroup() qsettings.endGroup() def _show_editor_skins(self): self._listScheme.clear() self._listScheme.addItem('default') for item in self._schemes: self._listScheme.addItem(item) items = self._listScheme.findItems(self._selected_scheme, Qt.MatchExactly) if items: self._listScheme.setCurrentItem(items[0]) else: self._listScheme.setCurrentRow(0) self.thread_callback.wait() def hideEvent(self, event): super(EditorGeneral, self).hideEvent(event) resources.CUSTOM_SCHEME = self.original_style main_container = IDE.get_service('main_container') editorWidget = main_container.get_current_editor() if editorWidget is not None: editorWidget.restyle(editorWidget.lang) editorWidget._sidebarWidget.repaint() def _preview_style(self): scheme = self._listScheme.currentItem().text() if scheme == self.current_scheme: return main_container = IDE.get_service('main_container') editorWidget = main_container.get_current_editor() if editorWidget is not None: resources.CUSTOM_SCHEME = self._schemes.get( scheme, resources.COLOR_SCHEME) editorWidget.restyle(editorWidget.lang) editorWidget._sidebarWidget.repaint() self.current_scheme = scheme def _load_editor_font(self): try: font = self._load_font( self._get_font_from_string(self._btnEditorFont.text()), self) self._btnEditorFont.setText(font) except: QMessageBox.warning( self, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_TITLE, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_BODY) def _get_font_from_string(self, font): if not font: font = QFont(settings.FONT_FAMILY, settings.FONT_SIZE) else: listFont = font.split(',') font = QFont(listFont[0].strip(), int(listFont[1].strip())) return font def _load_font(self, initialFont, parent=0): font, ok = QFontDialog.getFont(initialFont, parent) if ok: newFont = font.toString().split(',') else: newFont = initialFont.toString().split(',') return newFont[0] + ', ' + newFont[1] def save(self): qsettings = IDE.ninja_settings() settings.SHOW_MINIMAP = self._checkShowMinimap.isChecked() settings.MINIMAP_MAX_OPACITY = self._spinMaxOpacity.value() / 100.0 settings.MINIMAP_MIN_OPACITY = self._spinMinOpacity.value() / 100.0 settings.SIZE_PROPORTION = self._spinSize.value() / 100.0 qsettings.setValue('preferences/editor/minimapShow', settings.SHOW_MINIMAP) qsettings.setValue('preferences/editor/minimapMaxOpacity', settings.MINIMAP_MAX_OPACITY) qsettings.setValue('preferences/editor/minimapMinOpacity', settings.MINIMAP_MIN_OPACITY) qsettings.setValue('preferences/editor/minimapSizeProportion', settings.SIZE_PROPORTION) fontText = self._btnEditorFont.text().replace(' ', '') settings.FONT_FAMILY = fontText.split(',')[0] settings.FONT_SIZE = int(fontText.split(',')[1]) qsettings.setValue('preferences/editor/fontFamily', settings.FONT_FAMILY) qsettings.setValue('preferences/editor/fontSize', settings.FONT_SIZE) scheme = self._listScheme.currentItem().text() self.original_style = resources.CUSTOM_SCHEME qsettings.setValue('preferences/editor/scheme', scheme) resources.CUSTOM_SCHEME = self._schemes.get(scheme, resources.COLOR_SCHEME)
class StringListDlg(QDialog): acceptedList = Signal(QStringList) def __init__(self, name, stringlist=None, parent=None): super(StringListDlg, self).__init__(parent) self.name = name self.create_widgets(stringlist) self.layout_widgets() self.setWindowTitle("Edit {0} List".format(self.name)) def create_widgets(self, stringlist): self.listWidget = QListWidget() if stringlist is not None: self.listWidget.addItems(stringlist) self.listWidget.setCurrentRow(0) def layout_widgets(self): buttonLayout = QVBoxLayout() for text, slot in (("&Add...", self.add), ("&Edit...", self.edit), ("&Remove...", self.remove), ("&Up", self.up), ("&Down", self.down), ("&Sort", self.listWidget.sortItems), ("Close", self.accept)): button = QPushButton(text) if not MAC: button.setFocusPolicy(Qt.NoFocus) if text == "Close": buttonLayout.addStretch() buttonLayout.addWidget(button) button.clicked.connect(slot) layout = QHBoxLayout() layout.addWidget(self.listWidget) layout.addLayout(buttonLayout) self.setLayout(layout) def add(self): row = self.listWidget.currentRow() title = "Add {0}".format(self.name) string, ok = QInputDialog.getText(self, title, title) if ok and not string.isEmpty(): self.listWidget.insertItem(row, string) def edit(self): row = self.listWidget.currentRow() item = self.listWidget.item(row) if item is not None: title = "Edit {0}".format(self.name) string, ok = QInputDialog.getText(self, title, title, QLineEdit.Normal, item.text()) if ok and not string.isEmpty(): item.setText(string) def remove(self): row = self.listWidget.currentRow() item = self.listWidget.item(row) if item is None: return reply = QMessageBox.question(self, "Remove {0}".format( self.name), "Remove {0} `{1}'?".format( self.name, unicode(item.text())), QMessageBox.Yes|QMessageBox.No) if reply == QMessageBox.Yes: item = self.listWidget.takeItem(row) del item def up(self): row = self.listWidget.currentRow() if row >= 1: item = self.listWidget.takeItem(row) self.listWidget.insertItem(row - 1, item) self.listWidget.setCurrentItem(item) def down(self): row = self.listWidget.currentRow() if row < self.listWidget.count() - 1: item = self.listWidget.takeItem(row) self.listWidget.insertItem(row + 1, item) self.listWidget.setCurrentItem(item) def reject(self): self.accept() def accept(self): self.stringlist = QStringList() for row in range(self.listWidget.count()): self.stringlist.append(self.listWidget.item(row).text()) self.acceptedList.emit(self.stringlist) QDialog.accept(self)
class ShowPresets(QDialog): def __init__(self, parent=None): super(ShowPresets, self).__init__(parent) self.original_presets_file = '/usr/share/ffmulticonverter/presets.xml' self.config_folder = os.getenv('HOME') + '/.config/ffmulticonverter/' self.current_presets_file = self.config_folder + 'presets.xml' self.presListWidget = QListWidget() labelLabel = QLabel(self.tr('Preset label')) self.labelLineEdit = QLineEdit() self.labelLineEdit.setReadOnly(True) commandLabel = QLabel(self.tr('Preset command line parameters')) self.commandLineEdit = QLineEdit() self.commandLineEdit.setReadOnly(True) extLabel = QLabel(self.tr('Output file extension')) self.extLineEdit = QLineEdit() self.extLineEdit.setReadOnly(True) addButton = QPushButton(self.tr('Add')) self.deleteButton = QPushButton(self.tr('Delete')) self.delete_allButton = QPushButton(self.tr('Delete all')) self.editButton = QPushButton(self.tr('Edit')) okButton = QPushButton(self.tr('OK')) okButton.setDefault(True) spc1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) spc2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) grid = pyqttools.add_to_grid(QGridLayout(), [self.delete_allButton, addButton, spc1, None], [self.deleteButton, self.editButton, spc2, okButton]) final_layout = pyqttools.add_to_layout(QVBoxLayout(), self.presListWidget, labelLabel, self.labelLineEdit, commandLabel, self.commandLineEdit, extLabel, self.extLineEdit, grid) self.setLayout(final_layout) okButton.clicked.connect(self.accept) self.presListWidget.currentRowChanged.connect(self.show_preset) addButton.clicked.connect(self.add_preset) self.deleteButton.clicked.connect(self.delete_preset) self.delete_allButton.clicked.connect(self.delete_all_presets) self.editButton.clicked.connect(self.edit_preset) self.resize(410, 410) self.setWindowTitle(self.tr('Edit Presets')) QTimer.singleShot(0, self.load_xml) QTimer.singleShot(0, self.fill_presListWidget) def load_xml(self): """Load xml tree and set xml root.""" try: self.tree = etree.parse(self.current_presets_file) except (etree.ParseError, IOError): try: self.tree = etree.parse(self.original_presets_file) except IOError: # when program is not installed self.tree = etree.parse('../share/presets.xml') if not os.path.exists(self.config_folder): os.makedirs(self.config_folder) self.root = self.tree.getroot() def set_buttons_clear_lineEdits(self): """Enable or disable button's and clear lineEdits.""" enable = bool(self.presListWidget) self.editButton.setEnabled(enable) self.deleteButton.setEnabled(enable) self.delete_allButton.setEnabled(enable) if not enable: self.labelLineEdit.clear() self.commandLineEdit.clear() self.extLineEdit.clear() def fill_presListWidget(self): """Clear self.presListWidget and to it presets' tags.""" self.presListWidget.clear() for i in sorted([y.tag for y in self.root]): elem = self.root.find(i) self.presListWidget.addItem(MyListItem(i, elem)) self.presListWidget.setCurrentRow(0) self.set_buttons_clear_lineEdits() def show_preset(self): """Fill LineEdits with current xml element's values.""" try: xml_elem = self.presListWidget.currentItem().xml_element except AttributeError: return self.labelLineEdit.setText(xml_elem[0].text) self.commandLineEdit.setText(xml_elem[1].text) self.commandLineEdit.home(False) self.extLineEdit.setText(xml_elem[2].text) def add_preset(self): """Open AddorEditPreset() dialog and add a preset xml root.""" dialog = AddorEditPreset(None, False, self) if dialog.exec_(): element = etree.Element(dialog.name_text) label = etree.Element('label') label.text = dialog.label_text command = etree.Element('params') command.text = dialog.command_text ext = etree.Element('extension') ext.text = dialog.ext_text category = etree.Element('category') category.text = 'Scattered' for num, elem in enumerate([label, command, ext, category]): element.insert(num, elem) index = sorted([i.tag for i in self.root] + [dialog.name_text])\ .index(dialog.name_text) self.root.insert(index, element) self.save_tree() self.fill_presListWidget() def delete_preset(self): """ Ask user wether he wants to delete the selected preset. If so, delete the preset from xml root. """ try: xml_elem = self.presListWidget.currentItem().xml_element except AttributeError: return reply = QMessageBox.question(self, 'FF Multi Converter - ' + self.tr( 'Delete Preset'), self.tr('Are you sure that you want to delete ' 'the %1 preset?').arg(xml_elem.tag), QMessageBox.Yes|QMessageBox.Cancel) if reply == QMessageBox.Yes: self.root.remove(xml_elem) self.save_tree() self.fill_presListWidget() def delete_all_presets(self): """ Ask user if he wants to delete all presets. If so, clear xml root. """ reply = QMessageBox.question(self, 'FF Multi Converter - ' + self.tr( 'Delete Preset'), self.tr('Are you sure that you want to delete ' 'all presets?'), QMessageBox.Yes|QMessageBox.Cancel) if reply == QMessageBox.Yes: self.root.clear() self.save_tree() self.fill_presListWidget() def edit_preset(self): """Call the AddorEditPreset() dialog and update xml element's values.""" elem = self.presListWidget.currentItem().xml_element dialog = AddorEditPreset(elem, True) if dialog.exec_(): elem.tag = dialog.name_text elem[0].text = dialog.label_text elem[1].text = dialog.command_text elem[2].text = dialog.ext_text self.save_tree() self.fill_presListWidget() def save_tree(self): """Save xml tree.""" with open(self.current_presets_file, 'w') as _file: try: etree.ElementTree(self.root).write(_file) except: pass def import_presets(self): """Import an xml tree.""" title = 'FF Multi Converter - Import' reply = QMessageBox.question(self, title, self.tr('All current ' 'presets will be deleted.\nAre you sure that you want to ' 'continue?'), QMessageBox.Yes|QMessageBox.Cancel) if reply == QMessageBox.Yes: fname = QFileDialog.getOpenFileName(self, title) if fname: msg = 'Succesful import!' try: self.tree = etree.parse(fname) except: msg = 'Import failed!' else: self.root = self.tree.getroot() self.save_tree() QMessageBox.information(self, title, msg) def export_presets(self): """Export the xml tree.""" fname = QFileDialog.getSaveFileName(self, 'FF Multi Converter - Export presets','.xml') if fname: self.load_xml() with open(fname, 'w') as _file: try: etree.ElementTree(self.root).write(_file) except: pass def reset(self): """Import the default xml tree.""" reply = QMessageBox.question(self, 'FF Multi Converter - ' + self.tr( 'Delete Preset'), self.tr('Are you sure that you want to restore ' 'the default presets?'), QMessageBox.Yes|QMessageBox.Cancel) if reply == QMessageBox.Yes: if os.path.exists(self.current_presets_file): os.remove(self.current_presets_file) def accept(self): """ Save current xml element's values in order to be used from main program and close (accept) dialog. """ self.the_command = None if self.presListWidget: self.the_command = self.presListWidget.currentItem()\ .xml_element[1].text self.the_extension = self.presListWidget.currentItem()\ .xml_element[2].text QDialog.accept(self)
class PreferencesDialog(QDialog): def __init__(self, mainwindow): super(PreferencesDialog, self).__init__(mainwindow) self.setWindowModality(Qt.WindowModal) if mainwindow: self.addAction(mainwindow.actionCollection.help_whatsthis) layout = QVBoxLayout() layout.setSpacing(10) self.setLayout(layout) # listview to the left, stacked widget to the right top = QHBoxLayout() layout.addLayout(top) self.pagelist = QListWidget(self) self.stack = QStackedWidget(self) top.addWidget(self.pagelist, 0) top.addWidget(self.stack, 2) layout.addWidget(widgets.Separator(self)) b = self.buttons = QDialogButtonBox(self) b.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel | QDialogButtonBox.Apply | QDialogButtonBox.Reset | QDialogButtonBox.Help) layout.addWidget(b) b.accepted.connect(self.accept) b.rejected.connect(self.reject) b.button(QDialogButtonBox.Apply).clicked.connect(self.saveSettings) b.button(QDialogButtonBox.Reset).clicked.connect(self.loadSettings) b.button(QDialogButtonBox.Help).clicked.connect(self.showHelp) b.button(QDialogButtonBox.Help).setShortcut(QKeySequence.HelpContents) b.button(QDialogButtonBox.Apply).setEnabled(False) # fill the pagelist self.pagelist.setIconSize(QSize(32, 32)) self.pagelist.setSpacing(2) for item in pageorder(): self.pagelist.addItem(item()) self.pagelist.currentItemChanged.connect(self.slotCurrentItemChanged) app.translateUI(self, 100) # read our size and selected page qutil.saveDialogSize(self, "preferences/dialog/size", QSize(500, 300)) self.pagelist.setCurrentRow(_prefsindex) def translateUI(self): self.pagelist.setFixedWidth(self.pagelist.sizeHintForColumn(0) + 12) self.setWindowTitle(app.caption(_("Preferences"))) def done(self, result): if result and self.buttons.button(QDialogButtonBox.Apply).isEnabled(): self.saveSettings() # save our size and selected page global _prefsindex _prefsindex = self.pagelist.currentRow() super(PreferencesDialog, self).done(result) def pages(self): """Yields the settings pages that are already instantiated.""" for n in range(self.stack.count()): yield self.stack.widget(n) def showHelp(self): userguide.show(self.pagelist.currentItem().help) def loadSettings(self): """Loads the settings on reset.""" for page in self.pages(): page.loadSettings() page.hasChanges = False self.buttons.button(QDialogButtonBox.Apply).setEnabled(False) def saveSettings(self): """Saves the settings and applies them.""" for page in self.pages(): if page.hasChanges: page.saveSettings() page.hasChanges = False self.buttons.button(QDialogButtonBox.Apply).setEnabled(False) # emit the signal app.settingsChanged() def slotCurrentItemChanged(self, item): item.activate() def changed(self): """Call this to enable the Apply button.""" self.buttons.button(QDialogButtonBox.Apply).setEnabled(True)
class NotebookSettingsDialog(QDialog): """GUI for adjusting notebook settings""" def __init__(self, parent=None): super(NotebookSettingsDialog, self).__init__(parent) #widgets for tab 1 self.mdExts = QListWidget() self.mjEdit = QLineEdit() self.moveUp = QPushButton('<<') self.moveDown = QPushButton('>>') self.configureExtension = QPushButton('Edit Settings for this extension') self.tmpdict = deepcopy(self.parent().settings.extcfg) #widgets for tab 2 self.fExtEdit = QLineEdit() self.attImgEdit = QLineEdit() self.attDocEdit = QLineEdit() # mandatory button box self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) #tab panels tabs = QTabWidget() markupTab = QWidget() fileExtsTab = QWidget() tabs.addTab(markupTab, "Markdown") tabs.addTab(fileExtsTab, "File extensions") #initialization functions self.initExtList() self.mdExts.setDragDropMode(QAbstractItemView.InternalMove) self.mjEdit.setText(self.parent().settings.mathjax) self.attImgEdit.setText(', '.join(self.parent().settings.attachmentImage)) self.attDocEdit.setText(', '.join(self.parent().settings.attachmentDocument)) self.fExtEdit.setText(self.parent().settings.fileExt) #set up tab 1 layout=QGridLayout(markupTab) layout.addWidget(QLabel("Markdown extensions"),0,0,1,4) layout.addWidget(self.mdExts,1,0,1,4) layout.addWidget(self.moveUp,2,0,1,1) layout.addWidget(self.moveDown,2,1,1,1) layout.addWidget(self.configureExtension,2,2,1,2) layout.addWidget(QLabel("MathJax Location"),3,0,1,1) layout.addWidget(self.mjEdit,3,1,1,3) #set up tab 2 layout=QGridLayout(fileExtsTab) layout.addWidget(QLabel("Note file extension"),0,0,1,1) layout.addWidget(QLabel("Image file extension"),1,0,1,1) layout.addWidget(QLabel("Document file extension"),2,0,1,1) layout.addWidget(self.fExtEdit,0,1,1,1) layout.addWidget(self.attImgEdit,1,1,1,1) layout.addWidget(self.attDocEdit,2,1,1,1) #put it together vlayout = QVBoxLayout(self) vlayout.addWidget(tabs) vlayout.addWidget(self.buttonBox) #setup signal handlers self.moveUp.clicked.connect(self.moveItemUp) self.configureExtension.clicked.connect(self.configExt) self.moveDown.clicked.connect(self.moveItemDown) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) def configExt(self, checked=False, ext=None): if ext is None: ext = self.mdExts.currentItem().text() cfg = self.tmpdict.get(ext,[]) dialog = NotebookExtSettingsDialog(cfg_list=cfg) done = dialog.exec() if done: self.tmpdict[ext] = dialog.configToList() def initExtList(self): extset=set(self.parent().settings.extensions) #for easier performance in checking for ext in self.parent().settings.extensions: item = QListWidgetItem(ext, self.mdExts) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(Qt.Checked) for ext in self.parent().settings.faulty_exts: item = QListWidgetItem(ext, self.mdExts) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setBackground(QBrush(QColor('red'))) item.setForeground(QBrush(QColor('black'))) item.setCheckState(Qt.Checked) for ext in allMDExtensions(): if ext in extset: continue item = QListWidgetItem(ext, self.mdExts) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(Qt.Unchecked) #self.mdExts.addItem(item) def moveItemUp(self): item = self.mdExts.currentItem() row = self.mdExts.currentRow() if row != 0: # self.mdExts.removeItemWidget(item) self.mdExts.takeItem(row) self.mdExts.insertItem(row-1, item) self.mdExts.setCurrentRow(row-1) def moveItemDown(self): item = self.mdExts.currentItem() row = self.mdExts.currentRow() count = self.mdExts.count() if row != count-1: self.mdExts.takeItem(row) self.mdExts.insertItem(row+1, item) self.mdExts.setCurrentRow(row+1) def accept(self): #write to settings first msettings = self.parent().settings nbsettings = msettings.qsettings nbsettings.setValue('mathJax', self.mjEdit.text()) extlist = [] for i in range(self.mdExts.count()): item = self.mdExts.item(i) if item.checkState() == Qt.Checked: extlist.append(item.text()) writeListToSettings(nbsettings, 'extensions', extlist) writeListToSettings(nbsettings, 'attachmentImage', self.attImgEdit.text().split(", ")) writeListToSettings(nbsettings, 'attachmentDocument', self.attDocEdit.text().split(", ")) writeDictToSettings(nbsettings, 'extensionsConfig', self.tmpdict) #then to memory msettings.extensions = extlist msettings.mathjax = self.mjEdit.text() msettings.attachmentDocument = readListFromSettings(nbsettings, 'attachmentDocument') msettings.attachmentImage = readListFromSettings(nbsettings, 'attachmentImage') msettings.extcfg.update(self.tmpdict) msettings.md = markdown.Markdown(msettings.extensions, extension_configs=msettings.extcfg) #then make mikidown use these settings NOW curitem=self.parent().notesTree.currentItem() self.parent().currentItemChangedWrapper(curitem, curitem) QDialog.accept(self)
class CodeCompletionWidget(QFrame): def __init__(self, editor): super(CodeCompletionWidget, self).__init__(None, Qt.FramelessWindowHint | Qt.ToolTip) self._editor = editor self.stack_layout = QStackedLayout(self) self.stack_layout.setContentsMargins(0, 0, 0, 0) self.stack_layout.setSpacing(0) self.completion_list = QListWidget() self.completion_list.setMinimumHeight(200) self.completion_list.setAlternatingRowColors(True) self._list_index = self.stack_layout.addWidget(self.completion_list) self._icons = { "a": resources.IMAGES["attribute"], "f": resources.IMAGES["function"], "c": resources.IMAGES["class"], } self.cc = code_completion.CodeCompletion() self._completion_results = [] self._prefix = u"" self.setVisible(False) self.source = "" self._key_operations = { Qt.Key_Up: self._select_previous_row, Qt.Key_Down: self._select_next_row, Qt.Key_PageUp: (lambda: self._select_previous_row(6)), Qt.Key_PageDown: (lambda: self._select_next_row(6)), Qt.Key_Right: lambda: None, Qt.Key_Left: lambda: None, Qt.Key_Enter: self.pre_key_insert_completion, Qt.Key_Return: self.pre_key_insert_completion, Qt.Key_Tab: self.pre_key_insert_completion, Qt.Key_Space: self.hide_completer, Qt.Key_Escape: self.hide_completer, Qt.Key_Backtab: self.hide_completer, Qt.NoModifier: self.hide_completer, Qt.ShiftModifier: self.hide_completer, } desktop = QApplication.instance().desktop() self._desktop_geometry = desktop.availableGeometry() self.connect(self._editor.document(), SIGNAL("blockCountChanged(int)"), self.update_metadata) def _select_next_row(self, move=1): new_row = self.completion_list.currentRow() + move if new_row < self.completion_list.count(): self.completion_list.setCurrentRow(new_row) else: self.completion_list.setCurrentRow(0) return True def _select_previous_row(self, move=1): new_row = self.completion_list.currentRow() - move if new_row >= 0: self.completion_list.setCurrentRow(new_row) else: self.completion_list.setCurrentRow(self.completion_list.count() - move) return True def update_metadata(self): source = self._editor.get_text() source = source.encode(self._editor.encoding) self.cc.analyze_file("", source) def insert_completion(self, insert): if insert != self._prefix: extra = len(self._prefix) - len(insert) self._editor.textCursor().insertText(insert[extra:]) self.hide_completer() def _get_geometry(self): cr = self._editor.cursorRect() point = self._editor.mapToGlobal(cr.topLeft()) cr.moveTopLeft(point) # Check new position according desktop geometry width = ( self.completion_list.sizeHintForColumn(0) + self.completion_list.verticalScrollBar().sizeHint().width() + 10 ) height = 200 orientation = (point.y() + height) < self._desktop_geometry.height() if orientation: cr.moveTop(cr.bottom()) cr.setWidth(width) cr.setHeight(height) if not orientation: cr.moveBottom(cr.top()) xpos = self._desktop_geometry.width() - (point.x() + width) if xpos < 0: cr.moveLeft(cr.left() + xpos) return cr def complete(self, results): self.add_list_items(results) self.completion_list.setCurrentRow(0) cr = self._get_geometry() self.setGeometry(cr) self.completion_list.updateGeometries() self.show() def add_list_items(self, proposals): self.completion_list.clear() for p in proposals: self.completion_list.addItem( QListWidgetItem(QIcon(self._icons.get(p[0], resources.IMAGES["attribute"])), p[1]) ) def set_completion_prefix(self, prefix): self._prefix = prefix proposals = [] proposals += [("c", item) for item in self.completion_results.get("classes", []) if item.startswith(prefix)] proposals += [("a", item) for item in self.completion_results.get("attributes", []) if item.startswith(prefix)] proposals += [("f", item) for item in self.completion_results.get("functions", []) if item.startswith(prefix)] if proposals: self.complete(proposals) else: self.hide_completer() def fill_completer(self): source = self._editor.get_text() source = source.encode(self._editor.encoding) offset = self._editor.textCursor().position() results = self.cc.get_completion(source, offset) self.completion_results = results prefix = self._editor._text_under_cursor() self.set_completion_prefix(prefix) def hide_completer(self): self._prefix = "" self.hide() def pre_key_insert_completion(self): insert = unicode(self.completion_list.currentItem().text()) self.insert_completion(insert) self.hide_completer() return True def process_pre_key_event(self, event): if not self.isVisible(): return False skip = self._key_operations.get(event.key(), lambda: False)() self._key_operations.get(event.modifiers(), lambda: False)() if skip is None: skip = False return skip def process_post_key_event(self, event): if not settings.CODE_COMPLETION or self._editor.lang != "python": return if self.isVisible(): source = self._editor.get_text() source = source.encode(self._editor.encoding) offset = self._editor.textCursor().position() prefix = self.cc.get_prefix(source, offset) self.set_completion_prefix(prefix) self.completion_list.setCurrentRow(0) if event.key() == Qt.Key_Period or (event.key() == Qt.Key_Space and event.modifiers() == Qt.ControlModifier): self.fill_completer()
class HyphenDialog(QDialog): def __init__(self, mainwindow): super(HyphenDialog, self).__init__(mainwindow) self.setWindowModality(Qt.WindowModal) layout = QVBoxLayout() self.setLayout(layout) self.topLabel = QLabel() self.listWidget = QListWidget() layout.addWidget(self.topLabel) layout.addWidget(self.listWidget) layout.addWidget(widgets.Separator()) self.buttons = b = QDialogButtonBox() layout.addWidget(b) b.setStandardButtons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) userguide.addButton(b, "lyrics") b.rejected.connect(self.reject) b.accepted.connect(self.accept) self.load() app.translateUI(self) qutil.saveDialogSize(self, "hyphenation/dialog/size") def translateUI(self): self.setWindowTitle(app.caption(_("Hyphenate Lyrics Text"))) self.topLabel.setText(_("Please select a language:")) def load(self): current = po.setup.current() self._langs = [(language_names.languageName(lang, current), lang, dic) for lang, dic in findDicts().iteritems()] self._langs.sort() for name, lang, dic in self._langs: self.listWidget.addItem("{0} ({1})".format(name, lang)) def select(): lastused = settings().value("lastused", "", type("")) if lastused: yield lastused lang = po.setup.preferred()[0] yield lang yield lang.split('_')[0] langs = [item[1] for item in self._langs] for preselect in select(): try: self.listWidget.setCurrentRow(langs.index(preselect)) break except ValueError: continue def hyphenator(self): if self.exec_() and self._langs: lang, dic = self._langs[self.listWidget.currentRow()][1:] result = hyphenator.Hyphenator(dic) settings().setValue("lastused", lang) else: result = None self.deleteLater() return result
class ListDialog(QDialog): def __init__(self, name, l, parent=None): super(ListDialog, self).__init__(parent) self.name = name self.l = l self.listWidget = QListWidget() try: res = l.search_s( ldap_dn, ldap.SCOPE_SUBTREE, "objectclass=*", ) n = 0 for entry in res: if n != 0: self.listWidget.addItem(entry[1]["uid"][0]) self.listWidget.setCurrentRow(0) n += 1 editLayout = QHBoxLayout() editLayout.addWidget(self.listWidget) button1Layout = QVBoxLayout() for text, slot, icon in ((_("&Edit..."), self.edit, ""), (_("&New"), self.new, "add.png"), (_("&Remove"), self.remove, "delete.png"), ): button = QPushButton(text) button.setFocusPolicy(Qt.NoFocus) if icon != "": button.setStyleSheet("QPushButton { text-align: left; }") button.setIcon(QIcon(os.path.join(imagespath,icon))) button1Layout.addWidget(button) self.connect(button, SIGNAL("clicked()"), slot) button1Layout.addStretch() editLayout.addLayout(button1Layout) button2Layout = QHBoxLayout() button2Layout.addStretch() for text, slot, icon in ((_("Ok"), self.close, "dialog-ok-apply.png"), ): button = QPushButton(text) button.setFocusPolicy(Qt.NoFocus) if icon != "": button.setIcon(QIcon(os.path.join(imagespath,icon))) button2Layout.addWidget(button) self.connect(button, SIGNAL("clicked()"), slot) button2Layout.addStretch() layout = QVBoxLayout() layout.addLayout(editLayout) layout.addLayout(button2Layout) self.setLayout(layout) self.setWindowTitle(self.name) except ldap.LDAPError, e: error_msg(self, _("LDAP Error"), e)
class Theme(QWidget): """Theme widget class.""" def __init__(self, parent): super(Theme, self).__init__() self._preferences, vbox = parent, QVBoxLayout(self) vbox.addWidget(QLabel(self.tr("<b>Select Theme:</b>"))) self.list_skins = QListWidget() self.list_skins.setSelectionMode(QListWidget.SingleSelection) vbox.addWidget(self.list_skins) self.btn_delete = QPushButton(self.tr("Delete Theme")) self.btn_preview = QPushButton(self.tr("Preview Theme")) self.btn_create = QPushButton(self.tr("Create Theme")) hbox = QHBoxLayout() hbox.addWidget(self.btn_delete) hbox.addSpacerItem( QSpacerItem(10, 0, QSizePolicy.Expanding, QSizePolicy.Fixed)) hbox.addWidget(self.btn_preview) hbox.addWidget(self.btn_create) vbox.addLayout(hbox) self._refresh_list() self.connect(self.btn_preview, SIGNAL("clicked()"), self.preview_theme) self.connect(self.btn_delete, SIGNAL("clicked()"), self.delete_theme) self.connect(self.btn_create, SIGNAL("clicked()"), self.create_theme) self.connect(self._preferences, SIGNAL("savePreferences()"), self.save) def delete_theme(self): if self.list_skins.currentRow() != 0: file_name = ("%s.qss" % self.list_skins.currentItem().text()) qss_file = file_manager.create_path(resources.NINJA_THEME_DOWNLOAD, file_name) file_manager.delete_file(qss_file) self._refresh_list() def create_theme(self): designer = preferences_theme_editor.ThemeEditor(self) designer.exec_() self._refresh_list() def showEvent(self, event): self._refresh_list() super(Theme, self).showEvent(event) def _refresh_list(self): self.list_skins.clear() self.list_skins.addItem("Default") files = sorted([ file_manager.get_file_name(filename) for filename in file_manager.get_files_from_folder( resources.NINJA_THEME_DOWNLOAD, "qss") ]) self.list_skins.addItems(files) if settings.NINJA_SKIN in files: index = files.index(settings.NINJA_SKIN) self.list_skins.setCurrentRow(index + 1) else: self.list_skins.setCurrentRow(0) def save(self): qsettings = IDE.ninja_settings() settings.NINJA_SKIN = self.list_skins.currentItem().text() qsettings.setValue("preferences/theme/skin", settings.NINJA_SKIN) self.preview_theme() def preview_theme(self): if self.list_skins.currentRow() == 0: qss_file = resources.NINJA_THEME else: file_name = ("%s.qss" % self.list_skins.currentItem().text()) qss_file = file_manager.create_path(resources.NINJA_THEME_DOWNLOAD, file_name) with open(qss_file) as f: qss = f.read() QApplication.instance().setStyleSheet(qss)
class StringListDlg(QDialog): acceptedList = Signal(QStringList) def __init__(self, name, stringlist=None, parent=None): super(StringListDlg, self).__init__(parent) self.name = name self.create_widgets(stringlist) self.layout_widgets() self.setWindowTitle("Edit {0} List".format(self.name)) def create_widgets(self, stringlist): self.listWidget = QListWidget() if stringlist is not None: self.listWidget.addItems(stringlist) self.listWidget.setCurrentRow(0) def layout_widgets(self): buttonLayout = QVBoxLayout() for text, slot in (("&Add...", self.add), ("&Edit...", self.edit), ("&Remove...", self.remove), ("&Up", self.up), ("&Down", self.down), ("&Sort", self.listWidget.sortItems), ("Close", self.accept)): button = QPushButton(text) if not MAC: button.setFocusPolicy(Qt.NoFocus) if text == "Close": buttonLayout.addStretch() buttonLayout.addWidget(button) button.clicked.connect(slot) layout = QHBoxLayout() layout.addWidget(self.listWidget) layout.addLayout(buttonLayout) self.setLayout(layout) def add(self): row = self.listWidget.currentRow() title = "Add {0}".format(self.name) string, ok = QInputDialog.getText(self, title, title) if ok and not string.isEmpty(): self.listWidget.insertItem(row, string) def edit(self): row = self.listWidget.currentRow() item = self.listWidget.item(row) if item is not None: title = "Edit {0}".format(self.name) string, ok = QInputDialog.getText(self, title, title, QLineEdit.Normal, item.text()) if ok and not string.isEmpty(): item.setText(string) def remove(self): row = self.listWidget.currentRow() item = self.listWidget.item(row) if item is None: return reply = QMessageBox.question( self, "Remove {0}".format(self.name), "Remove {0} `{1}'?".format(self.name, unicode(item.text())), QMessageBox.Yes | QMessageBox.No) if reply == QMessageBox.Yes: item = self.listWidget.takeItem(row) del item def up(self): row = self.listWidget.currentRow() if row >= 1: item = self.listWidget.takeItem(row) self.listWidget.insertItem(row - 1, item) self.listWidget.setCurrentItem(item) def down(self): row = self.listWidget.currentRow() if row < self.listWidget.count() - 1: item = self.listWidget.takeItem(row) self.listWidget.insertItem(row + 1, item) self.listWidget.setCurrentItem(item) def reject(self): self.accept() def accept(self): self.stringlist = QStringList() for row in range(self.listWidget.count()): self.stringlist.append(self.listWidget.item(row).text()) self.acceptedList.emit(self.stringlist) QDialog.accept(self)
class CodeCompletionWidget(QFrame): def __init__(self, editor): super(CodeCompletionWidget, self).__init__(None, Qt.FramelessWindowHint | Qt.ToolTip) self._editor = editor self._revision = 0 self._block = 0 self.stack_layout = QStackedLayout(self) self.stack_layout.setContentsMargins(0, 0, 0, 0) self.stack_layout.setSpacing(0) self.completion_list = QListWidget() self.completion_list.setMinimumHeight(200) self.completion_list.setAlternatingRowColors(True) self._list_index = self.stack_layout.addWidget(self.completion_list) self._icons = { 'a': resources.IMAGES['attribute'], 'f': resources.IMAGES['function'], 'c': resources.IMAGES['class'], 'm': resources.IMAGES['module'] } self.cc = code_completion.CodeCompletion() self._completion_results = {} self._prefix = '' self.setVisible(False) self.source = '' self._key_operations = { Qt.Key_Up: self._select_previous_row, Qt.Key_Down: self._select_next_row, Qt.Key_PageUp: (lambda: self._select_previous_row(6)), Qt.Key_PageDown: (lambda: self._select_next_row(6)), Qt.Key_Right: lambda: None, Qt.Key_Left: lambda: None, Qt.Key_Enter: self.pre_key_insert_completion, Qt.Key_Return: self.pre_key_insert_completion, Qt.Key_Tab: self.pre_key_insert_completion, Qt.Key_Space: self.hide_completer, Qt.Key_Escape: self.hide_completer, Qt.Key_Backtab: self.hide_completer, Qt.NoModifier: self.hide_completer, Qt.ShiftModifier: self.hide_completer, } self.desktop = QApplication.instance().desktop() self.connect(self.completion_list, SIGNAL("itemClicked(QListWidgetItem*)"), self.pre_key_insert_completion) self.connect(self._editor.document(), SIGNAL("cursorPositionChanged(QTextCursor)"), self.update_metadata) def _select_next_row(self, move=1): new_row = self.completion_list.currentRow() + move if new_row < self.completion_list.count(): self.completion_list.setCurrentRow(new_row) else: self.completion_list.setCurrentRow(0) return True def _select_previous_row(self, move=1): new_row = self.completion_list.currentRow() - move if new_row >= 0: self.completion_list.setCurrentRow(new_row) else: self.completion_list.setCurrentRow(self.completion_list.count() - move) return True def update_metadata(self, cursor): if settings.CODE_COMPLETION: if self._editor.document().revision() != self._revision and \ cursor.block().blockNumber() != self._block: source = self._editor.get_text() source = source.encode(self._editor.encoding) self.cc.analyze_file(self._editor.ID, source, self._editor.indent, self._editor.useTabs) self._revision = self._editor.document().revision() self._block = cursor.block().blockNumber() def insert_completion(self, insert, type_=ord('a')): if insert != self._prefix: closing = '' if type_ in (ord('f'), ord('c')): closing = '()' extra = len(self._prefix) - len(insert) insertion = '%s%s' % (insert[extra:], closing) self._editor.textCursor().insertText(insertion) self.hide_completer() def _get_geometry(self): cr = self._editor.cursorRect() desktop_geometry = self.desktop.availableGeometry(self._editor) point = self._editor.mapToGlobal(cr.topLeft()) cr.moveTopLeft(point) #Check new position according desktop geometry width = (self.completion_list.sizeHintForColumn(0) + self.completion_list.verticalScrollBar().sizeHint().width() + 10) height = 200 orientation = (point.y() + height) < desktop_geometry.height() if orientation: cr.moveTop(cr.bottom()) cr.setWidth(width) cr.setHeight(height) if not orientation: cr.moveBottom(cr.top()) xpos = desktop_geometry.width() - (point.x() + width) if xpos < 0: cr.moveLeft(cr.left() + xpos) return cr def complete(self, results): self.add_list_items(results) self.completion_list.setCurrentRow(0) cr = self._get_geometry() self.setGeometry(cr) self.completion_list.updateGeometries() self.show() def add_list_items(self, proposals): self.completion_list.clear() for p in proposals: self.completion_list.addItem( QListWidgetItem(QIcon( self._icons.get(p[0], resources.IMAGES['attribute'])), p[1], type=ord(p[0]))) def set_completion_prefix(self, prefix, valid=True): self._prefix = prefix proposals = [] proposals += [('m', item) for item in self._completion_results.get('modules', []) if item.startswith(prefix)] proposals += [('c', item) for item in self._completion_results.get('classes', []) if item.startswith(prefix)] proposals += [ ('a', item) for item in self._completion_results.get('attributes', []) if item.startswith(prefix) ] proposals += [ ('f', item) for item in self._completion_results.get('functions', []) if item.startswith(prefix) ] if proposals and valid: self.complete(proposals) else: self.hide_completer() def _invalid_completion_position(self): result = False cursor = self._editor.textCursor() cursor.movePosition(QTextCursor.StartOfLine, QTextCursor.KeepAnchor) selection = cursor.selectedText()[:-1].split(' ') if len(selection) == 0 or selection[-1] == '' or \ selection[-1].isdigit(): result = True return result def fill_completer(self, force_completion=False): if not force_completion and (self._editor.cursor_inside_string() or self._editor.cursor_inside_comment() or self._invalid_completion_position()): return source = self._editor.get_text() source = source.encode(self._editor.encoding) offset = self._editor.textCursor().position() results = self.cc.get_completion(source, offset) self._completion_results = results if force_completion: cursor = self._editor.textCursor() cursor.movePosition(QTextCursor.StartOfWord, QTextCursor.KeepAnchor) prefix = cursor.selectedText() else: prefix = self._editor._text_under_cursor() self.set_completion_prefix(prefix) def hide_completer(self): self._prefix = '' self.hide() def pre_key_insert_completion(self): type_ = ord('a') current = self.completion_list.currentItem() insert = current.text() if not insert.endswith(')'): type_ = current.type() self.insert_completion(insert, type_) self.hide_completer() return True def process_pre_key_event(self, event): if not self.isVisible() or self._editor.lang != "python": return False skip = self._key_operations.get(event.key(), lambda: False)() self._key_operations.get(event.modifiers(), lambda: False)() if skip is None: skip = False return skip def process_post_key_event(self, event): if not settings.CODE_COMPLETION or self._editor.lang != "python": return if self.isVisible(): source = self._editor.get_text() source = source.encode(self._editor.encoding) offset = self._editor.textCursor().position() prefix, valid = self.cc.get_prefix(source, offset) self.set_completion_prefix(prefix, valid) self.completion_list.setCurrentRow(0) force_completion = (event.key() == Qt.Key_Space and event.modifiers() == Qt.ControlModifier) if event.key() == Qt.Key_Period or force_completion: self.fill_completer(force_completion)
class ConfigDialog(QDialog): def __init__(self, parent=None): QDialog.__init__(self, parent) self.contents_widget = QListWidget() self.contents_widget.setMovement(QListView.Static) self.contents_widget.setMinimumWidth(120) self.contents_widget.setMaximumWidth(120) self.contents_widget.setSpacing(1) bbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Cancel) self.apply_btn = bbox.button(QDialogButtonBox.Apply) self.connect(bbox, SIGNAL("accepted()"), SLOT("accept()")) self.connect(bbox, SIGNAL("rejected()"), SLOT("reject()")) self.connect(bbox, SIGNAL("clicked(QAbstractButton*)"), self.button_clicked) self.pages_widget = QStackedWidget() self.connect(self.pages_widget, SIGNAL("currentChanged(int)"), self.current_page_changed) self.connect(self.contents_widget, SIGNAL("currentRowChanged(int)"), self.pages_widget.setCurrentIndex) self.contents_widget.setCurrentRow(0) hlayout = QHBoxLayout() hlayout.addWidget(self.contents_widget) hlayout.addWidget(self.pages_widget) hlayout.setStretch(1, 1) btnlayout = QHBoxLayout() btnlayout.addStretch(1) btnlayout.addWidget(bbox) vlayout = QVBoxLayout() vlayout.addLayout(hlayout) vlayout.addLayout(btnlayout) self.setLayout(vlayout) self.setWindowTitle("Preferences") self.setWindowIcon(get_icon("configure.png")) def get_current_index(self): """Return current page index""" return self.contents_widget.currentRow() def set_current_index(self, index): """Set current page index""" self.contents_widget.setCurrentRow(index) def accept(self): """Reimplement Qt method""" for index in range(self.pages_widget.count()): configpage = self.pages_widget.widget(index) if not configpage.is_valid(): return configpage.apply_changes() QDialog.accept(self) def button_clicked(self, button): if button is self.apply_btn: # Apply button was clicked configpage = self.pages_widget.currentWidget() if not configpage.is_valid(): return configpage.apply_changes() def current_page_changed(self, index): widget = self.pages_widget.widget(index) self.apply_btn.setVisible(widget.apply_callback is not None) self.apply_btn.setEnabled(widget.is_modified) def add_page(self, widget): self.connect(self, SIGNAL('check_settings()'), widget.check_settings) self.connect(widget, SIGNAL('show_this_page()'), lambda row=self.contents_widget.count(): self. contents_widget.setCurrentRow(row)) self.connect(widget, SIGNAL("apply_button_enabled(bool)"), self.apply_btn.setEnabled) self.pages_widget.addWidget(widget) item = QListWidgetItem(self.contents_widget) item.setIcon(widget.get_icon()) item.setText(widget.get_name()) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) item.setSizeHint(QSize(0, 25)) def check_all_settings(self): """This method is called to check all configuration page settings after configuration dialog has been shown""" self.emit(SIGNAL('check_settings()'))
class NewChartPage0(QWizardPage): """WizardPage to select chart type and name""" def __init__(self, parent, sensorgroup): QWizardPage.__init__(self, parent) self.setTitle(QCoreApplication.translate('DataStorageBrowser', 'Select type/template of chart')) self.setFinalPage(True) self.sensorgroup = sensorgroup self.mainLayout = QVBoxLayout() self.setLayout(self.mainLayout) layout0 = QHBoxLayout() self.templateSelect = QListWidget(self) self.templateSelect.setSelectionMode(QAbstractItemView.SingleSelection) layout0.addWidget(self.templateSelect) self.templatePreview = QLabel(self) self.templatePreview.setScaledContents(True) self.templatePreview.setMinimumSize(200, 200) self.templatePreview.setMaximumSize(200, 200) self.templatePreview.setFrameStyle(QFrame.Panel|QFrame.Sunken) layout0.addWidget(self.templatePreview) self.mainLayout.addLayout(layout0) self.templateInfo = QTextEdit(self) self.templateInfo.setReadOnly(True) self.templateInfo.setMinimumSize(400, 80) self.mainLayout.addWidget(self.templateInfo) layout1 = QHBoxLayout() nameLabel = QLabel(self) nameLabel.setText(QCoreApplication.translate('DataStorageBrowser', 'Chart name:')) layout1.addWidget(nameLabel) self.nameInput = QLineEdit(self) layout1.addWidget(self.nameInput) self.mainLayout.addLayout(layout1) openChartButton = QCheckBox(self) openChartButton.setChecked(True) openChartButton.setText(QCoreApplication.translate('DataStorageBrowser', 'Open chart window after creation')) self.mainLayout.addWidget(openChartButton) for t in chartTemplates: self.templateSelect.addItem(t.name) self.registerField('templateNumber', self.templateSelect, 'currentRow') self.registerField('chartName', self.nameInput, 'text') self.registerField('openChart', openChartButton, 'checked') self.ownPlugIn = SimuVis4.Globals.plugInManager['DataStorageBrowser'] self.connect(self.templateSelect, SIGNAL("currentRowChanged(int)"), self.templateChanged) self.templateSelect.setCurrentRow(0) def templateChanged(self, i): t = chartTemplates[i] self.templateInfo.setPlainText(t.description) n = t.chartName while n in self.sensorgroup.charts.keys(): n += '_X' self.nameInput.setText(n) if t.previewImage: xpm = QPixmap() path = os.path.join('previewImages', t.previewImage) data = self.ownPlugIn.getFile(path).read() xpm.loadFromData(data) self.templatePreview.setPixmap(xpm) def validatePage(self): i, x = self.field('templateNumber').toInt() n = str(self.field('chartName').toString()) if n in self.sensorgroup.charts.keys(): QMessageBox.warning(self, QCoreApplication.translate('DataStorageBrowser', 'Chart name already exists!'), QCoreApplication.translate('DataStorageBrowser', 'Chart names must be unique. Choose another name or delete existing chart first!')) return False chartTemplates[i].chartName = n return True
class PopupCompleter(QFrame): def __init__(self): QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.listWidget = QListWidget() self.listWidget.setMinimumHeight(300) vbox.addWidget(self.listWidget) def reload(self, model): """Reload the data of the Popup Completer, and restart the state.""" self.listWidget.clear() self.add_help() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) self.listWidget.setCurrentRow(6) def clear(self): """Remove all the items of the list (deleted), and reload the help.""" self.listWidget.clear() def refresh(self, model): """Refresh the list when the user search for some word.""" self.listWidget.clear() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) if model: self.listWidget.setCurrentItem(model[0][0]) def fetch_more(self, model): """Add more items to the list on user scroll.""" for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) def add_help(self): #Load help fileItem = QListWidgetItem(QIcon(resources.IMAGES['locate-file']), '@\t(Filter only by Files)') font = fileItem.font() font.setBold(True) fileItem.setSizeHint(QSize(20, 30)) fileItem.setBackground(QBrush(Qt.lightGray)) fileItem.setForeground(QBrush(Qt.black)) fileItem.setFont(font) self.listWidget.addItem(fileItem) classItem = QListWidgetItem(QIcon(resources.IMAGES['locate-class']), '<\t(Filter only by Classes)') self.listWidget.addItem(classItem) classItem.setSizeHint(QSize(20, 30)) classItem.setBackground(QBrush(Qt.lightGray)) classItem.setForeground(QBrush(Qt.black)) classItem.setFont(font) methodItem = QListWidgetItem( QIcon(resources.IMAGES['locate-function']), '>\t(Filter only by Methods)') self.listWidget.addItem(methodItem) methodItem.setSizeHint(QSize(20, 30)) methodItem.setBackground(QBrush(Qt.lightGray)) methodItem.setForeground(QBrush(Qt.black)) methodItem.setFont(font) attributeItem = QListWidgetItem( QIcon(resources.IMAGES['locate-attributes']), '-\t(Filter only by Attributes)') self.listWidget.addItem(attributeItem) attributeItem.setSizeHint(QSize(20, 30)) attributeItem.setBackground(QBrush(Qt.lightGray)) attributeItem.setForeground(QBrush(Qt.black)) attributeItem.setFont(font) thisFileItem = QListWidgetItem( QIcon(resources.IMAGES['locate-on-this-file']), '.\t(Filter only by Classes and Methods in this File)') font = thisFileItem.font() font.setBold(True) thisFileItem.setSizeHint(QSize(20, 30)) thisFileItem.setBackground(QBrush(Qt.lightGray)) thisFileItem.setForeground(QBrush(Qt.black)) thisFileItem.setFont(font) self.listWidget.addItem(thisFileItem) nonPythonItem = QListWidgetItem( QIcon(resources.IMAGES['locate-nonpython']), '!\t(Filter only by Non Python Files)') self.listWidget.addItem(nonPythonItem) nonPythonItem.setSizeHint(QSize(20, 30)) nonPythonItem.setBackground(QBrush(Qt.lightGray)) nonPythonItem.setForeground(QBrush(Qt.black)) nonPythonItem.setFont(font)
class AutoComplete(PopupWidget): def init_popup(self): self.list = QListWidget(self) self.connect(self.list, SIGNAL("itemClicked(QListWidgetItem*)"), self.insertItem) self.layout().addWidget(self.list) self.items = [] def insertItem(self, item): self.insert() def insert(self): completion = self.items[self.list.currentRow()].value cursor = self.textedit.textCursor() col = cursor.columnNumber() line = unicode(cursor.block().text()) i = self.cursor_start_col while i > 0: #print `line[i:col]` if completion.startswith(line[i:col]): #print "break" break i -= 1 #print col,i cursor.insertText(completion[col - i:]) self.hide() def setItems(self, proposals): proposals = sorted(proposals, cmp=lambda p1, p2: cmp(p1.name, p2.name)) del self.items[:] self.list.clear() for entry in proposals: i = AutoCompleteItem(entry) self.list.addItem(i) self.items.append(i) def keyPressEvent(self, event): self.list.keyPressEvent(event) key = event.key() text = event.text() if key in [Qt.Key_Right, Qt.Key_Enter, Qt.Key_Return]: text = "" cursor = self.textedit.textCursor() line = unicode(cursor.block().text()) col = cursor.columnNumber() prefix = line[self.cursor_start_col:col] + unicode(text) found = False for row, item in enumerate(self.items): if item.value.startswith(prefix): current = self.items[self.list.currentRow()].value if not current.startswith(prefix): self.list.setCurrentRow(row) found = True break if not found: self.hide() return if key in [Qt.Key_Up, Qt.Key_Down, Qt.Key_PageUp, Qt.Key_PageDown]: return True elif key in [Qt.Key_Tab, Qt.Key_Right, Qt.Key_Enter, Qt.Key_Return]: self.insert() return True elif not text: self.hide()
class getFontDialog(QDialog): def __init__(self, parent, currFont): QDialog.__init__(self, parent) #--------------------- self.currFont = currFont if self.currFont.get_file() == None: self.currFontFile = fm.findfont(self.currFont) self.currFontSize = self.currFont.get_size() self.currFontStyle = self.currFont.get_style() self.currFontWeight = self.currFont.get_weight() self.currFont = fm.FontProperties(fname=self.currFontFile, style=self.currFontStyle, weight=self.currFontWeight, size=self.currFontSize) self.currFontFamily = self.currFont.get_name() else: self.currFontFile = self.currFont.get_file() self.currFontSize = self.currFont.get_size() self.currFontStyle = self.currFont.get_style() self.currFontWeight = self.currFont.get_weight() self.currFontFamily = self.currFont.get_name() self.fontsCacheFile = os.path.expanduser("~") +'/.config/pysoundanalyser/fontsCache' if os.path.exists(self.fontsCacheFile): fIn = open(self.fontsCacheFile, 'rb') self.fontsDic = pickle.load(fIn) fIn.close() else: x = fm.FontManager() weight_lookup = { '100': 'ultralight', '200': 'light', '400': 'normal', '500': 'medium', '600': 'demibold', '700': 'bold', '800': 'extra bold', '900': 'black'} fontList = x.ttflist fontNamesAll = [] for i in range(len(x.ttflist)): fontNamesAll.append(x.ttflist[i].name) fontNames = unique(fontNamesAll) self.fontsDic = {} for i in range(len(fontNames)): self.fontsDic[fontNames[i]] = {} self.fontsDic[fontNames[i]]['style'] = [] self.fontsDic[fontNames[i]]['styleAbb'] = [] for font in fontList: style = font.style weight = font.weight self.fontsDic[font.name]['style'].append(style + ':' + str(weight) + ':' + font.fname) weightName = weight_lookup[str(weight)] styleName = style + ' ' + weightName self.fontsDic[font.name]['styleAbb'].append(styleName) f = open(self.fontsCacheFile, 'wb') pickle.dump(self.fontsDic, f) f.close() #--------------------- self.currLocale = self.parent().prm['data']['currentLocale'] self.currLocale.setNumberOptions(self.currLocale.OmitGroupSeparator | self.currLocale.RejectGroupSeparator) grid = QGridLayout() fontNameLabel = QLabel(self.tr('Font Name')) grid.addWidget(fontNameLabel, 0, 0) fontStyleLabel = QLabel(self.tr('Font Style')) grid.addWidget(fontStyleLabel, 0, 1) fontSizeLabel = QLabel(self.tr('Font Size')) grid.addWidget(fontSizeLabel, 0, 2) ind = sorted(self.fontsDic.keys()).index(self.currFontFamily) self.fontListWidget = QListWidget(self) self.fontListWidget.insertItems(0, sorted(self.fontsDic.keys())) self.fontListWidget.setCurrentRow(ind) self.fontListWidget.itemClicked.connect(self.onChangeFontName) grid.addWidget(self.fontListWidget, 1, 0) self.fontStylesWidget = QListWidget(self) self.fontStylesWidget.insertItems(0, self.fontsDic[sorted(self.fontsDic.keys())[ind]]['styleAbb']) indStyle = self.fontsDic[sorted(self.fontsDic.keys())[ind]]['styleAbb'].index(self.currFontStyle + ' ' + self.currFontWeight) self.fontStylesWidget.setCurrentRow(indStyle) grid.addWidget(self.fontStylesWidget, 1, 1) self.fontSizeWidget = QListWidget(self) self.pointSizeList = ['4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '22', '24', '26', '28', '32', '48', '64', '72', '80', '96', '128'] self.fontSizeWidget.insertItems(0, self.pointSizeList) self.fontSizeWidget.setCurrentRow(self.pointSizeList.index(str(int(self.currFontSize)))) grid.addWidget(self.fontSizeWidget, 1, 2) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok| QDialogButtonBox.Cancel) buttonBox.accepted.connect(self.accept) buttonBox.rejected.connect(self.reject) grid.addWidget(buttonBox, 3, 2) self.setLayout(grid) self.setWindowTitle(self.tr("Choose Font")) def onChangeFontName(self): currFontName = str(self.fontListWidget.currentItem().text()) self.fontStylesWidget.clear() self.fontStylesWidget.insertItems(0, self.fontsDic[currFontName]['styleAbb']) self.fontStylesWidget.setCurrentRow(0)
class CommandWindow(QFrame): """Miow main window """ def __init__(self, parent=None): super(CommandWindow, self).__init__(parent) self.parent = parent self.setWindowFlags(QtCore.Qt.Popup) self.setFont(QFont("Monospace", 14)) self.setMinimumWidth(400) self.setMinimumHeight(300) self.setGeometry(0, 0, 600, 300) # create widgets layout = QVBoxLayout(self) self.line_edit = QLineEdit(self) layout.addWidget(self.line_edit) self.list_widget = QListWidget(self) self.list_widget.currentItemChanged.connect(self.on_current_item_changed) layout.addWidget(self.list_widget) layout.setStretchFactor(self.list_widget, 15) layout.setMargin(0) layout.setSpacing(0) layout.setContentsMargins(0,0,0,0) self.setLayout(layout) self.line_edit.setFocus() self.full_command = QPlainTextEdit(self) self.full_command.setFont(QFont("Monospace", 8)) size_policy = self.full_command.sizePolicy() size_policy.setVerticalPolicy(QSizePolicy.Ignored) self.full_command.setSizePolicy(size_policy) layout.addWidget(self.full_command) layout.setStretchFactor(self.full_command, 3) layout2 = QHBoxLayout(self) self.weight = QLabel(self) self.weight.setFont(QFont("Monospace", 8)) size_policy = self.weight.sizePolicy() size_policy.setVerticalPolicy(QSizePolicy.Ignored) self.weight.setSizePolicy(size_policy) layout2.addWidget(self.weight) layout2.setStretchFactor(self.weight, 1) self.labels = QLabel(self) self.labels.setFont(QFont("Monospace", 8)) size_policy = self.labels.sizePolicy() size_policy.setVerticalPolicy(QSizePolicy.Ignored) self.labels.setSizePolicy(size_policy) layout2.addWidget(self.labels) layout2.setStretchFactor(self.labels, 8) layout.addLayout(layout2) layout.setStretchFactor(layout2, 1) self.line_edit.textChanged.connect(self.on_text_changed) self.list_widget.itemDoubleClicked.connect(self.on_item_double_clicked) self.event_selected_command = Event() def show_hide(self, context): if self.isVisible() == False or context is not None: self.command_list = self.parent.get_command_list(context) self.filter_commands("") self.show() else: self.hide() def showEvent(self, event): geom = self.frameGeometry() self.line_edit.setFocus() self.line_edit.clear() #parent_widget = self.parentWidget() if self.parent: geom.moveCenter(QtCore.QPoint(self.parent.pos().x()+self.parent.width()/2, self.parent.pos().y()+self.parent.height()/3)) self.setGeometry(geom) super(QFrame, self).showEvent(event) def _get_command_from_text(self, text): for command_text, tags, weight, command in self.command_list: if command_text == text: return command return None def _get_full_command_from_text(self, text): for command_text, tags, weight, command in self.command_list: if command_text == text: return (command_text, tags, weight, command) return None def keyPressEvent(self, event): if event.type() == QEvent.KeyPress: key_event = QKeyEvent(event) if(key_event.key() == Qt.Key_Down or key_event.key() == Qt.Key_Up): return self.list_widget.keyPressEvent(event) elif((event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return) and self.list_widget.currentItem()>=0): self.hide() self.event_selected_command(str(self.full_command.toPlainText())) return super(CommandWindow, self).keyPressEvent(event) def on_item_double_clicked(self, item): self.hide() self.event_selected_command(str(self.full_command.toPlainText())) def on_current_item_changed(self, prev, current): if(self.list_widget.currentItem()): command_text, tags, weight, command = self._get_full_command_from_text( self.list_widget.currentItem().text()) self.full_command.setPlainText(command) self.labels.setText(tags) self.weight.setText(str(weight)) else: self.full_command.setPlainText("") self.labels.setText("") self.weight.setText("") def filter_commands(self, text): self.list_widget.clear() text = str(text).upper() def get_item_map_def0(_map, key): if(key in _map): return _map[key] else: return 0. def get_command_matches(command_list, words): result_map = {} for command, tags, _, _ in command_list: for word in words: located_command_weight = 1 located_tag_weight = 0.3 if word == '': located_command_weight = 0. located_tag_weight = 0. if command.upper().find(word) != -1: result_map[command] = (get_item_map_def0(result_map, command) - located_command_weight) for tag in tags.split(" "): if tag.upper().find(word) != -1: result_map[command] = (get_item_map_def0(result_map, command) - located_tag_weight) for command, _, current_weight, _ in command_list: if command in result_map: result_map[command] -= current_weight return sorted(result_map, key=result_map.get) words = str(text).strip().split(" ") matches_map = get_command_matches(self.command_list, words) for command in matches_map: self.list_widget.addItem(command) self.list_widget.setCurrentRow(0) def on_text_changed(self, text): self.filter_commands(text)
class NotebookSettingsDialog(QDialog): """GUI for adjusting notebook settings""" def __init__(self, parent=None): super(NotebookSettingsDialog, self).__init__(parent) #widgets for tab 1 self.mdExts = QListWidget() self.mjEdit = QLineEdit() self.moveUp = QPushButton('<<') self.moveDown = QPushButton('>>') self.configureExtension = QPushButton( 'Edit Settings for this extension') self.tmpdict = deepcopy(self.parent().settings.extcfg) #widgets for tab 2 self.fExtEdit = QLineEdit() self.attImgEdit = QLineEdit() self.attDocEdit = QLineEdit() # mandatory button box self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) #tab panels tabs = QTabWidget() markupTab = QWidget() fileExtsTab = QWidget() tabs.addTab(markupTab, "Markdown") tabs.addTab(fileExtsTab, "File extensions") #initialization functions self.initExtList() self.mdExts.setDragDropMode(QAbstractItemView.InternalMove) self.mjEdit.setText(self.parent().settings.mathjax) self.attImgEdit.setText(', '.join( self.parent().settings.attachmentImage)) self.attDocEdit.setText(', '.join( self.parent().settings.attachmentDocument)) self.fExtEdit.setText(self.parent().settings.fileExt) #set up tab 1 layout = QGridLayout(markupTab) layout.addWidget(QLabel("Markdown extensions"), 0, 0, 1, 4) layout.addWidget(self.mdExts, 1, 0, 1, 4) layout.addWidget(self.moveUp, 2, 0, 1, 1) layout.addWidget(self.moveDown, 2, 1, 1, 1) layout.addWidget(self.configureExtension, 2, 2, 1, 2) layout.addWidget(QLabel("MathJax Location"), 3, 0, 1, 1) layout.addWidget(self.mjEdit, 3, 1, 1, 3) #set up tab 2 layout = QGridLayout(fileExtsTab) layout.addWidget(QLabel("Note file extension"), 0, 0, 1, 1) layout.addWidget(QLabel("Image file extension"), 1, 0, 1, 1) layout.addWidget(QLabel("Document file extension"), 2, 0, 1, 1) layout.addWidget(self.fExtEdit, 0, 1, 1, 1) layout.addWidget(self.attImgEdit, 1, 1, 1, 1) layout.addWidget(self.attDocEdit, 2, 1, 1, 1) #put it together vlayout = QVBoxLayout(self) vlayout.addWidget(tabs) vlayout.addWidget(self.buttonBox) #setup signal handlers self.moveUp.clicked.connect(self.moveItemUp) self.configureExtension.clicked.connect(self.configExt) self.moveDown.clicked.connect(self.moveItemDown) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) def configExt(self, checked=False, ext=None): if ext is None: ext = self.mdExts.currentItem().text() cfg = self.tmpdict.get(ext, []) dialog = NotebookExtSettingsDialog(cfg_list=cfg) done = dialog.exec() if done: self.tmpdict[ext] = dialog.configToList() def initExtList(self): extset = set(self.parent().settings.extensions) #for easier performance in checking for ext in self.parent().settings.extensions: item = QListWidgetItem(ext, self.mdExts) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(Qt.Checked) for ext in self.parent().settings.faulty_exts: item = QListWidgetItem(ext, self.mdExts) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setBackground(QBrush(QColor('red'))) item.setForeground(QBrush(QColor('black'))) item.setCheckState(Qt.Checked) for ext in allMDExtensions(): if ext in extset: continue item = QListWidgetItem(ext, self.mdExts) item.setFlags(item.flags() | Qt.ItemIsUserCheckable) item.setCheckState(Qt.Unchecked) #self.mdExts.addItem(item) def moveItemUp(self): item = self.mdExts.currentItem() row = self.mdExts.currentRow() if row != 0: # self.mdExts.removeItemWidget(item) self.mdExts.takeItem(row) self.mdExts.insertItem(row - 1, item) self.mdExts.setCurrentRow(row - 1) def moveItemDown(self): item = self.mdExts.currentItem() row = self.mdExts.currentRow() count = self.mdExts.count() if row != count - 1: self.mdExts.takeItem(row) self.mdExts.insertItem(row + 1, item) self.mdExts.setCurrentRow(row + 1) def accept(self): #write to settings first msettings = self.parent().settings nbsettings = msettings.qsettings nbsettings.setValue('mathJax', self.mjEdit.text()) extlist = [] for i in range(self.mdExts.count()): item = self.mdExts.item(i) if item.checkState() == Qt.Checked: extlist.append(item.text()) writeListToSettings(nbsettings, 'extensions', extlist) writeListToSettings(nbsettings, 'attachmentImage', self.attImgEdit.text().split(", ")) writeListToSettings(nbsettings, 'attachmentDocument', self.attDocEdit.text().split(", ")) writeDictToSettings(nbsettings, 'extensionsConfig', self.tmpdict) #then to memory msettings.extensions = extlist msettings.mathjax = self.mjEdit.text() msettings.attachmentDocument = readListFromSettings( nbsettings, 'attachmentDocument') msettings.attachmentImage = readListFromSettings( nbsettings, 'attachmentImage') msettings.extcfg.update(self.tmpdict) msettings.md = markdown.Markdown(msettings.extensions, extension_configs=msettings.extcfg) #then make mikidown use these settings NOW curitem = self.parent().notesTree.currentItem() self.parent().currentItemChangedWrapper(curitem, curitem) QDialog.accept(self)
class ListEdit(QWidget): """A widget to edit a list of items (e.g. a list of directories).""" # emitted when anything changed in the listbox. changed = pyqtSignal() def __init__(self, *args, **kwargs): QWidget.__init__(self, *args, **kwargs) layout = QGridLayout(self) self.setLayout(layout) self.addButton = QPushButton(icons.get('list-add'), '') self.editButton = QPushButton(icons.get('document-edit'), '') self.removeButton = QPushButton(icons.get('list-remove'), '') self.listBox = QListWidget() layout.setContentsMargins(1, 1, 1, 1) layout.setSpacing(0) layout.addWidget(self.listBox, 0, 0, 4, 1) layout.addWidget(self.addButton, 0, 1) layout.addWidget(self.editButton, 1, 1) layout.addWidget(self.removeButton, 2, 1) @self.addButton.clicked.connect def addClicked(): item = self.createItem() if self.openEditor(item): self.addItem(item) @self.editButton.clicked.connect def editClicked(): item = self.listBox.currentItem() item and self.editItem(item) @self.removeButton.clicked.connect def removeClicked(): item = self.listBox.currentItem() if item: self.removeItem(item) @self.listBox.itemDoubleClicked.connect def itemDoubleClicked(item): item and self.editItem(item) self.listBox.model().layoutChanged.connect(self.changed) def updateSelection(): selected = bool(self.listBox.currentItem()) self.editButton.setEnabled(selected) self.removeButton.setEnabled(selected) self.changed.connect(updateSelection) self.listBox.itemSelectionChanged.connect(updateSelection) updateSelection() app.translateUI(self) def translateUI(self): self.addButton.setText(_("&Add...")) self.editButton.setText(_("&Edit...")) self.removeButton.setText(_("&Remove")) def createItem(self): return QListWidgetItem() def addItem(self, item): self.listBox.addItem(item) self.itemChanged(item) self.changed.emit() def removeItem(self, item): self.listBox.takeItem(self.listBox.row(item)) self.changed.emit() def editItem(self, item): if self.openEditor(item): self.itemChanged(item) self.changed.emit() def setCurrentItem(self, item): self.listBox.setCurrentItem(item) def setCurrentRow(self, row): self.listBox.setCurrentRow(row) def openEditor(self, item): """Opens an editor (dialog) for the item. Returns True if the dialog was accepted and the item edited. Returns False if the dialog was cancelled (the item must be left unedited). """ pass def itemChanged(self, item): """Called after an item has been added or edited. Re-implement to do something at this moment if needed, e.g. alter the text or display of other items. """ pass def setValue(self, strings): """Sets the listbox to a list of strings.""" self.listBox.clear() self.listBox.addItems(strings) self.changed.emit() def value(self): """Returns the list of paths in the listbox.""" return [ self.listBox.item(i).text() for i in range(self.listBox.count()) ] def setItems(self, items): """Sets the listbox to a list of items.""" self.listBox.clear() for item in items: self.listBox.addItem(item) self.itemChanged(item) self.changed.emit() def items(self): """Returns the list of items in the listbox.""" return [self.listBox.item(i) for i in range(self.listBox.count())] def clear(self): """Clears the listbox.""" self.listBox.clear() self.changed.emit()
class PopupCompleter(QFrame): def __init__(self): QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.listWidget = QListWidget() self.listWidget.setMinimumHeight(350) vbox.addWidget(self.listWidget) self.listWidget.currentItemChanged.connect(self._repaint_items) def _repaint_items(self, current, previous): if current is not None: widget = self.listWidget.itemWidget(current) if widget is not None: widget.set_selected() if previous is not None: widget = self.listWidget.itemWidget(previous) if widget is not None: widget.set_not_selected() def reload(self, model): """Reload the data of the Popup Completer, and restart the state.""" self.listWidget.clear() self.add_help() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) self.listWidget.setCurrentRow(8) def clear(self): """Remove all the items of the list (deleted), and reload the help.""" self.listWidget.clear() def refresh(self, model, has_text=True): """Refresh the list when the user search for some word.""" self.listWidget.clear() if not has_text: self.add_help() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) if model: self.listWidget.setCurrentItem(model[0][0]) else: self.add_no_found() def fetch_more(self, model): """Add more items to the list on user scroll.""" for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) def add_no_found(self): """Load no results found message""" noFoundItem = self._create_help_item(resources.IMAGES['delete'], translations.TR_NO_RESULTS) self.listWidget.addItem(noFoundItem) def add_help(self): #Load help fileItem = self._create_help_item(resources.IMAGES['locate-file'], translations.TR_ONLY_FILES) self.listWidget.addItem(fileItem) classItem = self._create_help_item(resources.IMAGES['locate-class'], translations.TR_ONLY_CLASSES) self.listWidget.addItem(classItem) methodItem = self._create_help_item( resources.IMAGES['locate-function'], translations.TR_ONLY_METHODS) self.listWidget.addItem(methodItem) attributeItem = self._create_help_item( resources.IMAGES['locate-attributes'], translations.TR_ONLY_ATRIBUTES) self.listWidget.addItem(attributeItem) thisFileItem = self._create_help_item( resources.IMAGES['locate-on-this-file'], translations.TR_ONLY_CLASSES_METHODS) self.listWidget.addItem(thisFileItem) tabsItem = self._create_help_item(resources.IMAGES['locate-tab'], translations.TR_ONLY_CURRENT_TABS) self.listWidget.addItem(tabsItem) lineItem = self._create_help_item(resources.IMAGES['locate-line'], translations.TR_GO_TO_LINE) self.listWidget.addItem(lineItem) nonPythonItem = self._create_help_item( resources.IMAGES['locate-nonpython'], translations.TR_ONLY_NON_PYTHON) self.listWidget.addItem(nonPythonItem) def _create_help_item(self, image, text): Item = QListWidgetItem(QIcon(image), text) font = Item.font() font.setBold(True) Item.setSizeHint(QSize(20, 30)) Item.setBackground(QBrush(Qt.lightGray)) Item.setForeground(QBrush(Qt.black)) Item.setFont(font) return Item
class GraphDialog(QDialog): edit_patterns = 0 edit_curves = 1 titles = {edit_patterns: 'Pattern editor', edit_curves: 'Curve editor'} labels = {edit_patterns: 'Patterns', edit_curves: 'Curves'} def __init__(self, dockwidget, parent, params, edit_type): QDialog.__init__(self, parent) main_lay = QVBoxLayout(self) self.dockwidget = dockwidget self.params = params self.edit_type = edit_type self.x_label = '' self.y_label = '' self.setMinimumWidth(600) self.setMinimumHeight(400) self.setWindowTitle(self.titles[edit_type]) # TODO: softcode self.setWindowModality(QtCore.Qt.ApplicationModal) self.current = None self.current_saved = False # File self.lbl_file = QLabel('File:') self.fra_file = QFrame() self.fra_file.setContentsMargins(0, 0, 0, 0) fra_file_lay = QHBoxLayout(self.fra_file) if edit_type == self.edit_patterns: self.txt_file = QLineEdit(self.params.patterns_file) elif edit_type == self.edit_curves: self.txt_file = QLineEdit(self.params.curves_file) self.txt_file.setReadOnly(True) self.txt_file.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignVCenter) self.txt_file.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Minimum) fra_file_lay.addWidget(self.txt_file) self.btn_file = QPushButton('Change') # TODO: softcode self.btn_file.clicked.connect(self.import_file) fra_file_lay.addWidget(self.btn_file) fra_file_lay.setContentsMargins(0, 0, 0, 0) self.lbl_list = QLabel(self.labels[edit_type]) self.lst_list = QListWidget() self.lst_list.currentItemChanged.connect(self.list_item_changed) # Form self.fra_form = QFrame() fra_form1_lay = QFormLayout(self.fra_form) fra_form1_lay.setContentsMargins(0, 0, 0, 0) fra_form1_lay.addRow(self.lbl_list, self.lst_list) # Buttons self.fra_buttons = QFrame() fra_buttons_lay = QHBoxLayout(self.fra_buttons) fra_buttons_lay.setContentsMargins(0, 0, 0, 0) if self.edit_type == self.edit_patterns: ele_name = 'pattern' elif self.edit_type == self.edit_curves: ele_name = 'curve' self.btn_new = QPushButton('New ' + ele_name) # TODO: softcode self.btn_new.clicked.connect(self.new_element) fra_buttons_lay.addWidget(self.btn_new) self.btn_import = QPushButton('Import ' + ele_name + 's') # TODO: softcode self.btn_import.clicked.connect(self.import_file) fra_buttons_lay.addWidget(self.btn_import) self.btn_save = QPushButton('Save current ' + ele_name) # TODO: softcode self.btn_save.clicked.connect(self.save) fra_buttons_lay.addWidget(self.btn_save) self.btn_del = QPushButton('Delete current ' + ele_name) # TODO: softcode self.btn_del.clicked.connect(self.del_item) fra_buttons_lay.addWidget(self.btn_del) # ID self.lbl_id = QLabel('ID:') self.txt_id = QLineEdit() self.txt_id.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.MinimumExpanding) self.lbl_desc = QLabel('Desc.:') self.txt_desc = QLineEdit() self.fra_id = QFrame() fra_id_lay = QHBoxLayout(self.fra_id) fra_id_lay.addWidget(self.lbl_id) fra_id_lay.addWidget(self.txt_id) fra_id_lay.addWidget(self.lbl_desc) fra_id_lay.addWidget(self.txt_desc) # Table form self.table = QTableWidget(self) self.rows_nr = 24 self.cols_nr = 2 self.table.setRowCount(self.rows_nr) self.table.setColumnCount(self.cols_nr) self.table.verticalHeader().setVisible(False) # Initialize empty table self.clear_table() self.table.itemChanged.connect(self.data_changed) self.fra_table = QFrame() fra_table_lay = QVBoxLayout(self.fra_table) fra_table_lay.setContentsMargins(0, 0, 0, 0) if edit_type == self.edit_curves: self.fra_pump_type = QFrame() fra_pump_type_lay = QFormLayout(self.fra_pump_type) self.lbl_pump_type = QLabel('Curve type:') # TODO: softcode self.cbo_pump_type = QComboBox() for key, name in Curve.type_names.iteritems(): self.cbo_pump_type.addItem(name, key) fra_pump_type_lay.addRow(self.lbl_pump_type, self.cbo_pump_type) fra_table_lay.addWidget(self.fra_pump_type) self.cbo_pump_type.activated.connect(self.cbo_pump_type_activated) fra_table_lay.addWidget(self.table) self.btn_add_row = QPushButton('Add row') self.btn_add_row.clicked.connect(self.add_row) fra_table_lay.addWidget(self.btn_add_row) # Graph canvas self.fra_graph = QFrame() self.static_canvas = StaticMplCanvas(self.fra_graph, width=5, height=4, dpi=100) fra_graph_lay = QVBoxLayout(self.fra_graph) fra_graph_lay.addWidget(self.static_canvas) # Top frame self.fra_top = QFrame() fra_top_lay = QVBoxLayout(self.fra_top) fra_top_lay.addWidget(self.fra_form) fra_top_lay.addWidget(self.fra_id) fra_top_lay.addWidget(self.fra_buttons) # Bottom frame self.fra_bottom = QFrame() fra_bottom_lay = QHBoxLayout(self.fra_bottom) fra_bottom_lay.addWidget(self.fra_table) fra_bottom_lay.addWidget(self.fra_graph) # Main main_lay.addWidget(self.fra_top) main_lay.addWidget(self.fra_bottom) # Get existing patterns/curves self.need_to_update_graph = False if self.edit_type == self.edit_patterns: for pattern_id, pattern in self.params.patterns.iteritems(): self.lst_list.addItem(pattern.id) elif self.edit_type == self.edit_curves: for curve_id, curve in self.params.curves.iteritems(): self.lst_list.addItem(curve.id) if self.lst_list.count() > 0: self.lst_list.setCurrentRow(0) self.txt_id.setEnabled(True) self.txt_desc.setEnabled(True) self.btn_save.setEnabled(True) self.btn_del.setEnabled(True) self.table.setEnabled(True) self.table.setEditTriggers(QAbstractItemView.AllEditTriggers) else: self.txt_id.setEnabled(False) self.txt_desc.setEnabled(False) self.btn_save.setEnabled(False) self.btn_del.setEnabled(False) self.table.setEnabled(False) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) self.new_dialog = None self.need_to_update_graph = True def cbo_pump_type_activated(self): self.update_table_headers() self.update_graph() def add_row(self): row_pos = self.table.rowCount() self.table.insertRow(row_pos) col = 0 item = QTableWidgetItem(str(row_pos)) if self.edit_type == self.edit_patterns: self.table.setItem(row_pos, col, item) item.setFlags(QtCore.Qt.ItemIsSelectable) def setVisible(self, bool): QDialog.setVisible(self, bool) self.update_table_headers() self.update_graph() def list_item_changed(self): p_index = self.lst_list.currentRow() flags = Qt.ItemFlags() flags != Qt.ItemIsEnabled # Clear table self.clear_table() self.need_to_update_graph = False if p_index >= 0: self.table.setRowCount(0) if self.edit_type == self.edit_patterns: self.current = self.params.patterns[ self.lst_list.currentItem().text()] for v in range(len(self.current.values)): row_pos = self.table.rowCount() self.table.insertRow(row_pos) item = QTableWidgetItem(str(v)) item.setFlags(flags) self.table.setItem(v, 0, item) self.table.setItem( v, 1, QTableWidgetItem(str(self.current.values[v]))) elif self.edit_type == self.edit_curves: self.current = self.params.curves[ self.lst_list.currentItem().text()] for v in range(len(self.current.xs)): row_pos = self.table.rowCount() self.table.insertRow(row_pos) self.table.setItem( v, 0, QTableWidgetItem(str(self.current.xs[v]))) self.table.setItem( v, 1, QTableWidgetItem(str(self.current.ys[v]))) curve_type = self.current.type self.cbo_pump_type.setCurrentIndex(curve_type) # Update GUI self.txt_id.setText(self.current.id) self.txt_desc.setText(self.current.desc) self.update_table_headers() # Update graph self.need_to_update_graph = True self.update_graph() else: # No curves self.txt_id.setText('') self.txt_desc.setText('') # Update table and chart self.need_to_update_graph = False for v in range(self.table.columnCount()): self.table.setItem(v, 1, QTableWidgetItem('')) self.need_to_update_graph = True self.update_graph() def import_file(self): config_file = ConfigFile(Parameters.config_file_path) directory = None if self.edit_type == GraphDialog.edit_curves: directory = self.params.last_curves_dir elif self.edit_type == GraphDialog.edit_patterns: directory = self.params.last_patterns_dir if directory is None: directory = self.params.last_project_dir file_path = QFileDialog.getOpenFileName(self, 'Select file', directory, 'Files (*.txt *.inp)') if file_path is None or file_path == '': return else: if self.edit_type == GraphDialog.edit_patterns: # Save patterns file path in configuration file config_file.set_patterns_file_path(file_path) Parameters.patterns_file = file_path elif self.edit_type == GraphDialog.edit_curves: # Save curve file path in configuration file config_file.set_curves_file_path(file_path) Parameters.curves_file = file_path self.read(file_path) def read(self, file_path): self.lst_list.clear() if self.edit_type == self.edit_patterns: InpFile.read_patterns(self.params, file_path) for pattern_id, pattern in self.params.patterns.iteritems(): # desc = ' (' + pattern.desc + ')' if pattern.desc is not None else '' self.lst_list.addItem(pattern.id) self.params.patterns[pattern.id] = pattern elif self.edit_type == self.edit_curves: InpFile.read_curves(self.params, file_path) for curve_id, curve in self.params.curves.iteritems(): # desc = ' (' + curve.desc + ')' if curve.desc is not None else '' self.lst_list.addItem(curve.id) self.params.curves[curve.id] = curve if self.lst_list.count() > 0: self.lst_list.setCurrentRow(0) def new_element(self): old_ids = [] if self.edit_type == self.edit_patterns: for pattern in self.params.patterns.itervalues(): old_ids.append(pattern.id) elif self.edit_type == self.edit_curves: for curve in self.params.curves.itervalues(): old_ids.append(curve.id) self.new_dialog = NewIdDialog(self, old_ids) self.new_dialog.exec_() new_id = self.new_dialog.get_newid() description = self.new_dialog.get_description() if new_id is None or description is None: return if self.edit_type == self.edit_patterns: new_pattern = Pattern(new_id, description) self.params.patterns[new_pattern.id] = new_pattern self.lst_list.addItem(new_pattern.id) elif self.edit_type == self.edit_curves: curve_type = self.cbo_pump_type.itemData( self.cbo_pump_type.currentIndex()) new_curve = Curve(new_id, curve_type, desc=description) self.params.curves[new_curve.id] = new_curve self.lst_list.addItem(new_curve.id) self.lst_list.setCurrentRow(self.lst_list.count() - 1) self.txt_id.setText(new_id) self.txt_desc.setText(description) # Clear table self.clear_table() self.static_canvas.axes.clear() self.txt_id.setEnabled(True) self.txt_desc.setEnabled(True) self.btn_save.setEnabled(True) self.btn_del.setEnabled(True) self.table.setEnabled(True) self.table.setEditTriggers(QAbstractItemView.AllEditTriggers) def save(self): self.need_to_update_graph = False # Check for ID if not self.txt_id.text(): QMessageBox.warning( self, Parameters.plug_in_name, u'Please specify the ID.', # TODO: softcode QMessageBox.Ok) return if self.edit_type == GraphDialog.edit_patterns: values = [] for row in range(self.table.rowCount()): item = self.table.item(row, 1) if item is not None and item.text() != '': values.append(self.from_item_to_val(item)) else: values.append('0') pattern = Pattern(self.txt_id.text(), self.txt_desc.text(), values) old_patterns = self.params.patterns old_patterns[pattern.id] = pattern self.params.patterns = old_patterns self.lst_list.currentItem().setText(pattern.id) elif self.edit_type == GraphDialog.edit_curves: # Check for ID unique xs = [] ys = [] for row in range(self.table.rowCount()): item_x = self.table.item(row, 0) item_y = self.table.item(row, 1) if item_x.text() != '' and item_y.text() != '': xs.append(self.from_item_to_val(item_x)) ys.append(self.from_item_to_val(item_y)) curve_type = self.cbo_pump_type.itemData( self.cbo_pump_type.currentIndex()) curve = Curve(self.txt_id.text(), curve_type, self.txt_desc.text()) for v in range(len(xs)): curve.append_xy(xs[v], ys[v]) old_curves = self.params.curves old_curves[curve.id] = curve self.params.curves = old_curves self.lst_list.currentItem().setText(curve.id) # Update GUI self.dockwidget.update_curves_combo() # self.read() self.need_to_update_graph = True def clear_table(self): self.need_to_update_graph = False for r in range(self.table.rowCount()): self.table.setItem(r, 0, QTableWidgetItem(None)) self.table.setItem(r, 1, QTableWidgetItem(None)) for row in range(self.rows_nr): for col in range(self.cols_nr): if self.edit_type == self.edit_patterns: if col == 0: item = QTableWidgetItem(str(row)) self.table.setItem(row, col, item) item.setFlags(QtCore.Qt.ItemIsSelectable) # elif col == 1 and row == 0: # item = QTableWidgetItem(str(1)) # self.table.setItem(row, col, item) # item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) # elif self.edit_type == self.edit_curves: # if row == 0: # item = QTableWidgetItem(str(0)) # self.table.setItem(row, 0, item) # item = QTableWidgetItem(str(1)) # self.table.setItem(row, 1, item) # item.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.need_to_update_graph = True def del_item(self): selected_row = self.lst_list.currentRow() name = self.lst_list.currentItem().text() if selected_row < 0: return self.lst_list.takeItem(selected_row) if self.lst_list.count() == 0: self.txt_id.setEnabled(False) self.txt_desc.setEnabled(False) self.btn_save.setEnabled(False) self.btn_del.setEnabled(False) self.table.setEnabled(False) self.table.setEditTriggers(QAbstractItemView.NoEditTriggers) if self.edit_type == GraphDialog.edit_curves: del self.params.curves[name] # Update GUI self.dockwidget.update_curves_combo() elif self.edit_type == GraphDialog.edit_patterns: del self.params.patterns[name] # Update GUI self.dockwidget.update_patterns_combo() def data_changed(self): if self.need_to_update_graph: self.update_graph() def update_table_headers(self): if self.edit_type == self.edit_patterns: self.x_label = 'Time period' self.y_label = 'Multiplier' elif self.edit_type == self.edit_curves: cbo_data = self.cbo_pump_type.itemData( self.cbo_pump_type.currentIndex()) if cbo_data == Curve.type_efficiency: self.x_label = 'Flow ' + '[' + self.params.options.flow_units + ']' self.y_label = 'Efficiency ' + '[' + self.params.options.units_deltaz[ self.params.options.units] + ']' if cbo_data == Curve.type_headloss: self.x_label = 'Flow ' + '[' + self.params.options.flow_units + ']' self.y_label = 'Headloss ' + '[' + self.params.options.units_deltaz[ self.params.options.units] + ']' if cbo_data == Curve.type_pump: self.x_label = 'Flow ' + '[' + self.params.options.flow_units + ']' self.y_label = 'Head ' + '[' + self.params.options.units_deltaz[ self.params.options.units] + ']' if cbo_data == Curve.type_volume: self.x_label = 'Height ' + '[' + self.params.options.flow_units + ']' self.y_label = 'Volume ' + '[' + self.params.options.units_deltaz[ self.params.options.units] + ']' self.table.setHorizontalHeaderLabels([self.x_label, self.y_label]) # TODO: softcode def update_graph(self): if not self.need_to_update_graph: return xs = [] ys = [] for row in range(self.table.rowCount()): item = self.table.item(row, 0) x = self.from_item_to_val(item) item = self.table.item(row, 1) y = self.from_item_to_val(item) if x is not None: xs.append(float(x)) if y is not None: ys.append(float(y)) if len(xs) == 0 or len(ys) == 0: self.static_canvas.clear() return xys_t = zip(xs, ys) xys_t.sort() xys = zip(*xys_t) xs = xys[0] ys = xys[1] if self.edit_type == self.edit_patterns: y_axis_label = 'Mult. avg.: ' + '{0:.2f}'.format( (numpy.average(ys))) self.static_canvas.draw_bars_graph( ys, time_period=self.params.times.pattern_timestep, y_axes_label=y_axis_label) elif self.edit_type == self.edit_curves: # Account for different types of curves cbo_data = self.cbo_pump_type.itemData( self.cbo_pump_type.currentIndex()) series_length = min(len(xs), len(ys)) # Need to account for different types of curves if cbo_data == Curve.type_efficiency or cbo_data == Curve.type_headloss or cbo_data == Curve.type_volume: self.static_canvas.draw_line_graph(xs[:series_length], ys[:series_length], self.x_label, self.y_label) elif cbo_data == Curve.type_pump: if series_length == 1 or series_length == 3: if series_length == 1: # 3 curve points curve_xs = [0, xs[0], xs[0] * 2] curve_ys = [ys[0] * 1.33, ys[0], 0] # y = a * x^2 + b * x + c elif series_length == 3: # 3 curve points curve_xs = [xs[0], xs[1], xs[2]] curve_ys = [ys[0], ys[1], ys[2]] (a, b, c) = numpy.polyfit(curve_xs, curve_ys, 2) # Create a few interpolated values interp_xs = [] interp_ys = [] n_vals = 30 for v in range(n_vals + 1): x = (curve_xs[2] - curve_xs[0]) / n_vals * v interp_xs.append(x) y = a * x**2 + b * x + c interp_ys.append(y) self.static_canvas.draw_line_graph(interp_xs, interp_ys, self.x_label, self.y_label) else: self.static_canvas.draw_line_graph(xs[:series_length], ys[:series_length], self.x_label, self.y_label) def from_item_to_val(self, item): if item is None: value = None else: value = item.text() try: value = float(value) value = max(value, 0) except: value = None return value
class SessionsManager(QDialog): """Session Manager, to load different configurations of ninja.""" def __init__(self, parent=None): super(SessionsManager, self).__init__(parent, Qt.Dialog) self._ide = parent self.setWindowTitle(translations.TR_SESSIONS_TITLE) self.setMinimumWidth(400) vbox = QVBoxLayout(self) vbox.addWidget(QLabel(translations.TR_SESSIONS_DIALOG_BODY)) self.sessionList = QListWidget() self.sessionList.addItems([key for key in settings.SESSIONS]) self.sessionList.setCurrentRow(0) self.contentList = QListWidget() self.btnDelete = QPushButton(translations.TR_SESSIONS_BTN_DELETE) self.btnDelete.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnUpdate = QPushButton(translations.TR_SESSIONS_BTN_UPDATE) self.btnUpdate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnCreate = QPushButton(translations.TR_SESSIONS_BTN_CREATE) self.btnCreate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnOpen = QPushButton(translations.TR_SESSIONS_BTN_ACTIVATE) self.btnOpen.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnOpen.setDefault(True) hbox = QHBoxLayout() hbox.addWidget(self.btnDelete) hbox.addWidget(self.btnUpdate) hbox.addWidget(self.btnCreate) hbox.addWidget(self.btnOpen) vbox.addWidget(self.sessionList) vbox.addWidget(self.contentList) vbox.addLayout(hbox) self.connect(self.sessionList, SIGNAL("itemSelectionChanged()"), self.load_session_content) self.connect(self.btnOpen, SIGNAL("clicked()"), self.open_session) self.connect(self.btnUpdate, SIGNAL("clicked()"), self.save_session) self.connect(self.btnCreate, SIGNAL("clicked()"), self.create_session) self.connect(self.btnDelete, SIGNAL("clicked()"), self.delete_session) self.load_session_content() def load_session_content(self): """Load the selected session, replacing the current session.""" item = self.sessionList.currentItem() self.contentList.clear() if item is not None: key = item.text() files = [self.tr('Files:')] + \ [file[0] for file in settings.SESSIONS[key][0]] projects = [self.tr('Projects:')] + settings.SESSIONS[key][1] content = files + projects self.contentList.addItems(content) def create_session(self): """Create a new Session.""" sessionInfo = QInputDialog.getText( None, translations.TR_SESSIONS_CREATE_TITLE, translations.TR_SESSIONS_CREATE_BODY) if sessionInfo[1]: sessionName = sessionInfo[0] if not sessionName or sessionName in settings.SESSIONS: QMessageBox.information(self, translations.TR_SESSIONS_MESSAGE_TITLE, translations.TR_SESSIONS_MESSAGE_BODY) return SessionsManager.save_session_data(sessionName, self._ide) self._ide.Session = sessionName self.close() @classmethod def save_session_data(cls, sessionName, ide): """Save the updates from a session.""" openedFiles = ide.filesystem.get_files() files_info = [] for path in openedFiles: editable = ide.get_or_create_editable(path) if editable.is_dirty: stat_value = 0 else: stat_value = os.stat(path).st_mtime files_info.append( [path, editable.editor.get_cursor_position(), stat_value]) projects_obj = ide.filesystem.get_projects() projects = [projects_obj[proj].path for proj in projects_obj] settings.SESSIONS[sessionName] = [files_info, projects] qsettings = ide.data_settings() qsettings.setValue('ide/sessions', settings.SESSIONS) def save_session(self): if self.sessionList.currentItem(): sessionName = self.sessionList.currentItem().text() SessionsManager.save_session_data(sessionName, self._ide) self._ide.show_message( translations.TR_SESSIONS_UPDATED_NOTIF % {'session': sessionName}, 2000) self.load_session_content() def open_session(self): if self.sessionList.currentItem(): key = self.sessionList.currentItem().text() self._load_session_data(key) self._ide.Session = key self.close() def delete_session(self): if self.sessionList.currentItem(): key = self.sessionList.currentItem().text() settings.SESSIONS.pop(key) self.sessionList.takeItem(self.sessionList.currentRow()) self.contentList.clear() qsettings = self._ide.data_settings() qsettings.setValue('ide/sessions', settings.SESSIONS) def _load_session_data(self, key): """Activate the selected session, closing the current files/projects""" main_container = self._ide.get_service('main_container') projects_explorer = self._ide.get_service('projects_explorer') if projects_explorer and main_container: projects_explorer.close_opened_projects() for fileData in settings.SESSIONS[key][0]: path, line, stat_value = fileData if file_manager.file_exists(path): mtime = os.stat(path).st_mtime ignore_checkers = (mtime == stat_value) main_container.open_file(path, line, ignore_checkers=ignore_checkers) if projects_explorer: projects_explorer.load_session_projects( settings.SESSIONS[key][1])
class PopupCompleter(QFrame): def __init__(self): QFrame.__init__(self, None, Qt.FramelessWindowHint | Qt.ToolTip) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.listWidget = QListWidget() self.listWidget.setMinimumHeight(300) vbox.addWidget(self.listWidget) def reload(self, model): """Reload the data of the Popup Completer, and restart the state.""" self.listWidget.clear() self.add_help() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) self.listWidget.setCurrentRow(6) def clear(self): """Remove all the items of the list (deleted), and reload the help.""" self.listWidget.clear() def refresh(self, model): """Refresh the list when the user search for some word.""" self.listWidget.clear() for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) if model: self.listWidget.setCurrentItem(model[0][0]) def fetch_more(self, model): """Add more items to the list on user scroll.""" for item in model: self.listWidget.addItem(item[0]) self.listWidget.setItemWidget(item[0], item[1]) def add_help(self): #Load help fileItem = QListWidgetItem( QIcon(resources.IMAGES['locate-file']), '@\t(Filter only by Files)') font = fileItem.font() font.setBold(True) fileItem.setSizeHint(QSize(20, 30)) fileItem.setBackground(QBrush(Qt.lightGray)) fileItem.setForeground(QBrush(Qt.black)) fileItem.setFont(font) self.listWidget.addItem(fileItem) classItem = QListWidgetItem( QIcon(resources.IMAGES['locate-class']), '<\t(Filter only by Classes)') self.listWidget.addItem(classItem) classItem.setSizeHint(QSize(20, 30)) classItem.setBackground(QBrush(Qt.lightGray)) classItem.setForeground(QBrush(Qt.black)) classItem.setFont(font) methodItem = QListWidgetItem( QIcon(resources.IMAGES['locate-function']), '>\t(Filter only by Methods)') self.listWidget.addItem(methodItem) methodItem.setSizeHint(QSize(20, 30)) methodItem.setBackground(QBrush(Qt.lightGray)) methodItem.setForeground(QBrush(Qt.black)) methodItem.setFont(font) attributeItem = QListWidgetItem( QIcon(resources.IMAGES['locate-attributes']), '-\t(Filter only by Attributes)') self.listWidget.addItem(attributeItem) attributeItem.setSizeHint(QSize(20, 30)) attributeItem.setBackground(QBrush(Qt.lightGray)) attributeItem.setForeground(QBrush(Qt.black)) attributeItem.setFont(font) thisFileItem = QListWidgetItem( QIcon(resources.IMAGES['locate-on-this-file']), '.\t(Filter only by Classes and Methods in this File)') font = thisFileItem.font() font.setBold(True) thisFileItem.setSizeHint(QSize(20, 30)) thisFileItem.setBackground(QBrush(Qt.lightGray)) thisFileItem.setForeground(QBrush(Qt.black)) thisFileItem.setFont(font) self.listWidget.addItem(thisFileItem) nonPythonItem = QListWidgetItem( QIcon(resources.IMAGES['locate-nonpython']), '!\t(Filter only by Non Python Files)') self.listWidget.addItem(nonPythonItem) nonPythonItem.setSizeHint(QSize(20, 30)) nonPythonItem.setBackground(QBrush(Qt.lightGray)) nonPythonItem.setForeground(QBrush(Qt.black)) nonPythonItem.setFont(font)
class ProjectPropertiesDialog( QDialog, object ): """ project properties dialog implementation """ def __init__( self, project = None, parent = None ): QDialog.__init__( self, parent ) # The dialog caller reads this member if the dialog was finished # successfully. self.absProjectFileName = None self.__createLayout() self.__project = project if project is None: # It a new project creation self.setWindowTitle( "New Project Properties" ) userRecord = pwd.getpwuid( os.getuid() ) if not userRecord[ 5 ].endswith( os.path.sep ): self.dirEdit.setText( userRecord[ 5 ] + os.path.sep ) else: self.dirEdit.setText( userRecord[ 5 ] ) self.initialDirName = self.dirEdit.text() self.lastProjectName = "" if userRecord[ 4 ] != "": self.authorEdit.setText( userRecord[ 4 ].split( ',' )[ 0 ].strip() ) else: self.authorEdit.setText( userRecord[ 0 ] ) try: self.emailEdit.setText( userRecord[ 0 ] + "@" + socket.gethostname() ) except: pass self.versionEdit.setText( "0.0.1" ) self.licenseEdit.setText( "GPL v3" ) self.copyrightEdit.setText( "Copyright (c) " + self.authorEdit.text() + ", " + str( datetime.date.today().year ) ) self.creationDateEdit.setText( getLocaleDate() ) self.nameEdit.setFocus() elif type( project ) == type( "" ): self.setWindowTitle( "Viewing Project Properties" ) # This is viewing properties and the argument is the path to the # project file scriptName, importDirs, creationDate, author, lic, \ copy_right, description, \ version, email, uuid = getProjectProperties( project ) if not os.path.isabs( scriptName ) and scriptName != "": scriptName = os.path.normpath( os.path.dirname( project ) + os.path.sep + scriptName ) self.nameEdit.setText( os.path.basename( project ) ) self.nameEdit.setToolTip( "" ) self.dirEdit.setText( os.path.dirname( project ) ) self.dirEdit.setToolTip( "" ) self.scriptEdit.setText( scriptName ) self.versionEdit.setText( version ) self.authorEdit.setText( author ) self.emailEdit.setText( email ) self.licenseEdit.setText( lic ) self.copyrightEdit.setText( copy_right ) self.descriptionEdit.setText( description ) self.creationDateEdit.setText( creationDate ) self.uuidEdit.setText( str( uuid ) ) self.uuidEdit.setToolTip( settingsDir + str( uuid ) + os.path.sep + " (double click to copy path)" ) for item in importDirs: self.importDirList.addItem( item ) self.disableEditing() else: self.setWindowTitle( "Editing Project Properties" ) # This is editing the loaded project. self.nameEdit.setText( os.path.basename( project.fileName ) ) self.nameEdit.setToolTip( "" ) self.dirEdit.setText( project.getProjectDir() ) self.dirEdit.setToolTip( "" ) self.scriptEdit.setText( project.getProjectScript() ) self.versionEdit.setText( project.version ) self.authorEdit.setText( project.author ) self.emailEdit.setText( project.email ) self.licenseEdit.setText( project.license ) self.copyrightEdit.setText( project.copyright ) self.descriptionEdit.setText( project.description ) self.creationDateEdit.setText( project.creationDate ) self.uuidEdit.setText( str( project.uuid ) ) self.uuidEdit.setToolTip( project.userProjectDir + " (double click to copy path)" ) self.setReadOnly() for item in project.importDirs: self.importDirList.addItem( item ) if self.importDirList.count() > 0: self.importDirList.setCurrentRow( 0 ) self.delImportDirButton.setEnabled( True ) # The project could be the one belonging to another user # so there might be no write permissions. if not os.access( project.fileName, os.W_OK ): # Disable editing self.setWindowTitle( "Viewing Project Properties (no write permissions)" ) self.disableEditing() else: self.scriptEdit.setFocus() return def __createLayout( self ): """ Creates the dialog layout """ self.resize( 600, 400 ) self.setSizeGripEnabled( True ) verticalLayout = QVBoxLayout( self ) gridLayout = QGridLayout() # Project name nameLabel = QLabel( self ) nameLabel.setText( "Project name:" ) gridLayout.addWidget( nameLabel, 0, 0, 1, 1 ) self.nameEdit = QLineEdit( self ) self.nameEdit.setToolTip( "Type a project name without a path" ) self.nameEdit.installEventFilter( self ) gridLayout.addWidget( self.nameEdit, 0, 1, 1, 1 ) # Project dir dirLabel = QLabel( self ) dirLabel.setText( "Project directory:" ) gridLayout.addWidget( dirLabel, 1, 0, 1, 1 ) self.dirEdit = QLineEdit( self ) self.dirEdit.setToolTip( "Not existed directories will be created" ) gridLayout.addWidget( self.dirEdit, 1, 1, 1, 1 ) self.dirButton = QPushButton( self ) self.dirButton.setText( "..." ) gridLayout.addWidget( self.dirButton, 1, 2, 1, 1 ) self.dirCompleter = DirCompleter( self.dirEdit ) # Project script mainScriptLabel = QLabel( "Main script:", self ) gridLayout.addWidget( mainScriptLabel, 2, 0, 1, 1 ) self.scriptEdit = QLineEdit( self ) self.scriptEdit.setToolTip( "Project main script, " "used when the project is run" ) gridLayout.addWidget( self.scriptEdit, 2, 1, 1, 1 ) self.scriptButton = QPushButton( "...", self ) gridLayout.addWidget( self.scriptButton, 2, 2, 1, 1 ) self.fileCompleter = FileCompleter( self.scriptEdit ) # Import dirs importLabel = QLabel( self ) importLabel.setText( "Import directories:" ) importLabel.setAlignment( Qt.AlignTop ) gridLayout.addWidget( importLabel, 3, 0, 1, 1 ) self.importDirList = QListWidget( self ) self.importDirList.setAlternatingRowColors( True ) self.importDirList.setSelectionMode( QAbstractItemView.SingleSelection ) self.importDirList.setSelectionBehavior( QAbstractItemView.SelectRows ) self.importDirList.setItemDelegate( NoOutlineHeightDelegate( 4 ) ) self.importDirList.setToolTip( "Directories where to look for " "project specific imports" ) gridLayout.addWidget( self.importDirList, 3, 1, 1, 1 ) self.addImportDirButton = QPushButton( self ) self.addImportDirButton.setText( "Add dir" ) self.delImportDirButton = QPushButton( self ) self.delImportDirButton.setText( "Delete dir" ) self.delImportDirButton.setEnabled( False ) vLayout = QVBoxLayout() vLayout.addWidget( self.addImportDirButton ) vLayout.addWidget( self.delImportDirButton ) vLayout.addStretch( 0 ) gridLayout.addLayout( vLayout, 3, 2, 1, 1 ) # Version versionLabel = QLabel( self ) versionLabel.setText( "Version:" ) gridLayout.addWidget( versionLabel, 4, 0, 1, 1 ) self.versionEdit = QLineEdit( self ) gridLayout.addWidget( self.versionEdit, 4, 1, 1, 1 ) # Author authorLabel = QLabel( self ) authorLabel.setText( "Author:" ) gridLayout.addWidget( authorLabel, 5, 0, 1, 1 ) self.authorEdit = QLineEdit( self ) gridLayout.addWidget( self.authorEdit, 5, 1, 1, 1 ) # E-mail emailLabel = QLabel( self ) emailLabel.setText( "E-mail:" ) gridLayout.addWidget( emailLabel, 6, 0, 1, 1 ) self.emailEdit = QLineEdit( self ) gridLayout.addWidget( self.emailEdit, 6, 1, 1, 1 ) # License licenseLabel = QLabel( self ) licenseLabel.setText( "License:" ) gridLayout.addWidget( licenseLabel, 7, 0, 1, 1 ) self.licenseEdit = QLineEdit( self ) gridLayout.addWidget( self.licenseEdit, 7, 1, 1, 1 ) # Copyright copyrightLabel = QLabel( self ) copyrightLabel.setText( "Copyright:" ) gridLayout.addWidget( copyrightLabel, 8, 0, 1, 1 ) self.copyrightEdit = QLineEdit( self ) gridLayout.addWidget( self.copyrightEdit, 8, 1, 1, 1 ) # Description descriptionLabel = QLabel( self ) descriptionLabel.setText( "Description:" ) descriptionLabel.setAlignment( Qt.AlignTop ) gridLayout.addWidget( descriptionLabel, 9, 0, 1, 1 ) self.descriptionEdit = QTextEdit( self ) self.descriptionEdit.setTabChangesFocus( True ) self.descriptionEdit.setAcceptRichText( False ) gridLayout.addWidget( self.descriptionEdit, 9, 1, 1, 1 ) # Creation date creationDateLabel = QLabel( self ) creationDateLabel.setText( "Creation date:" ) gridLayout.addWidget( creationDateLabel, 10, 0, 1, 1 ) self.creationDateEdit = FramedLabelWithDoubleClick() self.creationDateEdit.setToolTip( "Double click to copy" ) gridLayout.addWidget( self.creationDateEdit, 10, 1, 1, 1 ) # Project UUID uuidLabel = QLabel( self ) uuidLabel.setText( "UUID:" ) gridLayout.addWidget( uuidLabel, 11, 0, 1, 1 ) self.uuidEdit = FramedLabelWithDoubleClick( "", self.__copyProjectPath ) gridLayout.addWidget( self.uuidEdit, 11, 1, 1, 1 ) verticalLayout.addLayout( gridLayout ) # Buttons at the bottom buttonBox = QDialogButtonBox( self ) buttonBox.setOrientation( Qt.Horizontal ) buttonBox.setStandardButtons( QDialogButtonBox.Cancel | \ QDialogButtonBox.Ok ) verticalLayout.addWidget( buttonBox ) nameLabel.setBuddy( self.nameEdit ) dirLabel.setBuddy( self.dirEdit ) versionLabel.setBuddy( self.versionEdit ) authorLabel.setBuddy( self.authorEdit ) emailLabel.setBuddy( self.emailEdit ) licenseLabel.setBuddy( self.licenseEdit ) copyrightLabel.setBuddy( self.copyrightEdit ) descriptionLabel.setBuddy( self.descriptionEdit ) buttonBox.accepted.connect( self.onOKButton ) buttonBox.rejected.connect( self.reject ) self.dirButton.clicked.connect( self.onDirButton ) self.scriptButton.clicked.connect( self.onScriptButton ) self.importDirList.currentRowChanged.connect( self.onImportDirRowChanged ) self.addImportDirButton.clicked.connect( self.onAddImportDir ) self.delImportDirButton.clicked.connect( self.onDelImportDir ) self.nameEdit.textEdited.connect( self.onProjectNameChanged ) self.setTabOrder( self.nameEdit, self.dirEdit ) self.setTabOrder( self.dirEdit, self.dirButton ) self.setTabOrder( self.dirButton, self.scriptEdit ) self.setTabOrder( self.scriptEdit, self.scriptButton ) self.setTabOrder( self.scriptButton, self.importDirList ) self.setTabOrder( self.importDirList, self.addImportDirButton ) self.setTabOrder( self.addImportDirButton, self.delImportDirButton ) self.setTabOrder( self.delImportDirButton, self.versionEdit ) self.setTabOrder( self.versionEdit, self.authorEdit ) self.setTabOrder( self.authorEdit, self.emailEdit ) self.setTabOrder( self.emailEdit, self.licenseEdit ) self.setTabOrder( self.licenseEdit, self.copyrightEdit ) self.setTabOrder( self.copyrightEdit, self.descriptionEdit ) self.setTabOrder( self.descriptionEdit, buttonBox ) return def eventFilter( self, obj, event ): " Event filter for the project name field " # Do not allow path separators if event.type() == QEvent.KeyPress: if event.key() == ord( os.path.sep ): return True return QObject.eventFilter( self, obj, event ) def onDirButton( self ): " Displays a directory selection dialog " dirName = QFileDialog.getExistingDirectory( self, "Select project directory", self.dirEdit.text(), QFileDialog.Options( QFileDialog.ShowDirsOnly ) ) if dirName: self.dirEdit.setText( os.path.normpath( dirName ) ) return def onScriptButton( self ): " Displays a file selection dialog " scriptName = QFileDialog.getOpenFileName( self, "Select project main script", self.dirEdit.text() ) if scriptName: self.scriptEdit.setText( os.path.normpath( scriptName ) ) return def onImportDirRowChanged( self, row ): " Triggered when a current row in the import dirs is changed " self.delImportDirButton.setEnabled( row != -1 ) return def onAddImportDir( self ): " Displays a directory selection dialog " dirName = QFileDialog.getExistingDirectory( self, "Select import directory", self.dirEdit.text(), QFileDialog.Options( QFileDialog.ShowDirsOnly ) ) if not dirName: return # There are 2 cases: new project or # editing the existed project properties if self.__project is None: # It a new project; the project path could be editedd dirToInsert = dirName else: # This is an existed project; no way the project path is changed # Let's decide it a relative path should be used here if self.__project.isProjectDir( dirName ): dirToInsert = relpath( dirName, self.dirEdit.text() ) else: dirToInsert = dirName index = 0 while index < self.importDirList.count(): if self.importDirList.item( index ).text() == dirToInsert: logging.warning( "The directory '" + dirName + "' is already in the list of " "imported directories and is not added." ) return index += 1 self.importDirList.addItem( dirToInsert ) self.importDirList.setCurrentRow( self.importDirList.count() - 1 ) return def onDelImportDir( self ): " Triggered when an import dir should be deleted " rowToDelete = self.importDirList.currentRow() if rowToDelete == -1: self.delImportDirButton.setEnabled( False ) return self.importDirList.takeItem( rowToDelete ) if self.importDirList.count() == 0: self.delImportDirButton.setEnabled( False ) else: self.importDirList.setCurrentRow( self.importDirList.count() - 1 ) return def onOKButton( self ): " Checks that the mandatory fields are filled properly " # The checks must be done for a new project only if not self.nameEdit.isEnabled(): self.accept() return # Check that the project name does not have path separators and is not # empty if not self.nameEdit.text().strip(): QMessageBox.critical( self, "Error", "The project name must not be empty" ) return if os.path.sep in self.nameEdit.text(): QMessageBox.critical( self, "Error", "The project name must not " "contain path separators" ) return # Check that the project directory is given dirName = self.dirEdit.text().strip() if not dirName: QMessageBox.critical( self, "Error", "The project directory must not be empty" ) return dirName = os.path.abspath( dirName ) self.dirEdit.setText( dirName ) # Check that the project file does not exist projectFileName = dirName if not projectFileName.endswith( os.path.sep ): projectFileName += os.path.sep projectFileName += self.nameEdit.text().strip() if not projectFileName.endswith( ".cdm" ): projectFileName += ".cdm" if os.path.exists( projectFileName ): QMessageBox.critical( self, "Error", "The project file " + projectFileName + " exists. Please provide another " "directory / project name." ) return # Check that the project dir is not a file if os.path.exists( dirName ): # It might be a link, so read it first dirName = os.path.realpath( dirName ) if not os.path.exists( dirName ): QMessageBox.critical( self, "Error", "Broken link: " + dirName ) return if not os.path.isdir( dirName ): QMessageBox.critical( self, "Error", "The project directory " "may not be a file" ) return # Check that the dir is writable if not os.access( dirName, os.W_OK ): QMessageBox.critical( self, "Error", "You don't have write permissions on " + dirName ) return else: # Create the directory try: os.makedirs( dirName ) except OSError: QMessageBox.critical( self, "Error", "Cannot create the project directory" ) return # Save the absolute file name for further reading it by the caller self.absProjectFileName = projectFileName # The minimum is provided so we can accept it self.accept() return def onProjectNameChanged( self, newName ): " Called when the project name changed " if newName.endswith( ".cdm" ): newName = newName[ :-4 ] if self.dirEdit.text().strip() == (self.initialDirName + self.lastProjectName): self.dirEdit.setText( self.initialDirName + newName ) self.lastProjectName = newName return def setReadOnly( self ): """ Disables editing some fields """ self.dirEdit.setReadOnly( True ) self.dirEdit.setFocusPolicy( Qt.NoFocus ) self.dirEdit.setDisabled( True ) self.dirButton.setDisabled( True ) self.dirButton.setFocusPolicy( Qt.NoFocus ) self.nameEdit.setReadOnly( True ) self.nameEdit.setFocusPolicy( Qt.NoFocus ) self.nameEdit.setDisabled( True ) return def disableEditing( self ): " Disables all the editing " self.nameEdit.setDisabled( True ) self.dirEdit.setDisabled( True ) self.dirButton.setDisabled( True ) self.scriptEdit.setDisabled( True ) self.scriptButton.setDisabled( True ) self.importDirList.setDisabled( True ) self.addImportDirButton.setDisabled( True ) self.delImportDirButton.setDisabled( True ) self.versionEdit.setDisabled( True ) self.authorEdit.setDisabled( True ) self.emailEdit.setDisabled( True ) self.licenseEdit.setDisabled( True ) self.copyrightEdit.setDisabled( True ) self.descriptionEdit.setDisabled( True ) return def __copyProjectPath( self ): " Copies the project path when a label is double clicked " text = self.uuidEdit.text().strip() if text: path = settingsDir + text + os.path.sep QApplication.clipboard().setText( path ) return
class EditorGeneral(QWidget): def __init__(self, main): QWidget.__init__(self) self._main = main vbox = QVBoxLayout(self) groupBoxTypo = QGroupBox('Typography:') groupBoxScheme = QGroupBox('Scheme Color:') #Settings settings = QSettings() settings.beginGroup('preferences') settings.beginGroup('editor') #Typo gridTypo = QGridLayout(groupBoxTypo) self.btnEditorFont = QPushButton(settings.value('font', 'Monospace, 11').toString()) gridTypo.addWidget(QLabel('Editor Font:'), 0, 0, Qt.AlignRight) gridTypo.addWidget(self.btnEditorFont, 0, 1) #Scheme hbox = QHBoxLayout(groupBoxScheme) self.listScheme = QListWidget() self.listScheme.addItem('default') self.schemes = loader.load_editor_skins() for item in self.schemes: self.listScheme.addItem(item) items = self.listScheme.findItems(settings.value('scheme', '').toString(), Qt.MatchExactly) if items: self.listScheme.setCurrentItem(items[0]) else: self.listScheme.setCurrentRow(0) hbox.addWidget(self.listScheme) settings.endGroup() settings.endGroup() vbox.addWidget(groupBoxTypo) vbox.addWidget(groupBoxScheme) vbox.addWidget(QLabel('Scheme Color requires restart.')) #Signals self.connect(self.btnEditorFont, SIGNAL("clicked()"), self._load_editor_font) def _load_editor_font(self): font = self._load_font(self._get_font_from_string(self.btnEditorFont.text()), self) self.btnEditorFont.setText(font) def _get_font_from_string(self, font): if (font.isEmpty()): return QFont("Monospace", 11) listFont = font.remove(' ').split(',') return QFont(listFont[0], listFont[1].toInt()[0]) def _load_font(self, initialFont, parent=0): font, ok = QFontDialog.getFont(initialFont, parent) if ok: newFont = font.toString().split(',') return newFont[0] + ', ' + newFont[1] else: return initialFont def save(self): settings = QSettings() settings.beginGroup('preferences') settings.beginGroup('editor') settings.setValue('font', self.btnEditorFont.text()) editor = self._main._central.obtain_editor() editor.set_font(self._get_font_from_string(self.btnEditorFont.text())) settings.setValue('scheme', self.listScheme.currentItem().text()) settings.endGroup() settings.endGroup()
class NewSessionPagePermutations(QWizardPage): def __init__(self): super(NewSessionPagePermutations, self).__init__() self.setTitle(_('Configuration of permutations')) self.setSubTitle( _('Select the position of each question' ' and its choices in every model of the exam.')) layout = QGridLayout() self.question_list = QListWidget() self.permutation_grid = QGridLayout() self.alternatives_rows = {} layout.addWidget(QLabel(_('Questions of model A')), 0, 0, 1, 1) layout.addWidget(self.question_list, 1, 0, 1, 1) layout.addWidget(QLabel(_('Model equivalence')), 0, 1, 1, 5) self.permutation_grid.setVerticalSpacing(20) layout.addLayout(self.permutation_grid, 1, 1, 1, 5) layout.setColumnStretch(0, 1) layout.setColumnStretch(1, 5) self.setLayout(layout) def initializePage(self): paramNAlts = int(self.field("paramNAlts").toString()) paramNPerm = int(self.field("paramNPerm").toString()) self.question_list.clear() # Creation of the list section paramNCols_array = self.field("paramNCols").toString().split(',') total_questions = 1 + (int(paramNCols_array[0]) \ if len(paramNCols_array) == 1 \ else reduce(lambda x, y: int(x) + int(y), paramNCols_array)) for i in range(1, total_questions): questions_list = QListWidgetItem(_('Question ') + str(i)) questions_list.setData(Qt.UserRole, widgets.ItemList( optionName=_('Question ') + str(i), optionNumber=i)) # Custom item list self.question_list.addItem(questions_list) self.question_list.setCurrentRow(0) self.question_list.itemClicked.connect(self._on_item_changed) # Creation of the grid section add_header = True # Header of the columns (Name of alternatives) for j in range(0, paramNPerm): self.permutation_grid.addWidget( \ QLabel(_('Model ') + chr(97 + j).upper()), j, 1) self.alternatives_rows[j] = {} for k in range(0, paramNAlts): if add_header: if k == 0: self.permutation_grid.addWidget(QLabel(''), 0, 1) self.permutation_grid.addWidget( \ QLabel(chr(97 + k).upper()), 0, k + 2) self.alternatives_rows[j][k] = \ widgets.InputComboBox(self, c_type='alternative', form=j, alternative=k) self.alternatives_rows[j][k].addItems( \ [chr(97+x).upper() for x in range(0,paramNAlts)]) self.alternatives_rows[j][k].setCurrentIndex(0) self.permutation_grid.addWidget(self.alternatives_rows[j][k], j, k + 2) add_header = False self.alternatives_rows[j][k + 1] = \ widgets.InputComboBox(self, c_type='question', form=j, alternative=self.question_list.\ currentItem().\ data(Qt.UserRole).toPyObject().\ get_question_number()) self.alternatives_rows[j][k + 1].addItems( \ [str(x) for x in range(1,total_questions)]) self.alternatives_rows[j][k + 1].setCurrentIndex(0) self.permutation_grid.addWidget(QLabel(_('Question Number')), j, k + 3) self.permutation_grid.addWidget(self.alternatives_rows[j][k + 1], j, k + 4) button_save = QPushButton(_('Save values')) self.permutation_grid.addWidget(button_save, j + 1, 1, 1, k + 4) button_save.clicked.connect(self._save_values) def _on_item_changed(self, arg=None): permutation = arg.data(Qt.UserRole).toPyObject().get_permutation() for k, v in self.alternatives_rows.iteritems(): for sk, sv in v.iteritems(): if not permutation: sv.setCurrentIndex(0) else: sv.setCurrentIndex( \ [x for x in permutation \ if (x['altr'] == sv.alternative and x['form'] == sv.form and x['c_type'] == sv.c_type)][0]['perm'] - 1) return True def _save_values(self): localItem = self.question_list.currentItem() formatted_grid = self._get_formatted_permutation_grid() if self._validate_grid(formatted_grid): localItem.setBackgroundColor(QColor(0, 255, 68)) localItem.data(Qt.UserRole).toPyObject()\ .set_permutation(formatted_grid) self._reset_permutation_grid() QMessageBox.information( self, _('Information status'), _('The values for the question have been successfully saved')) return True else: QMessageBox.critical(self, _('Error in grid'), _('There is an inconsistence in the options')) return False def _get_formatted_permutation_grid(self): local_alternatives_rows = [] for k, v in self.alternatives_rows.iteritems(): for sk, sv in v.iteritems(): alternative = { 'c_type': sv.c_type, 'form': sv.form, 'altr': sv.alternative, 'perm': sv.currentIndex() + 1 } local_alternatives_rows.append(alternative) return local_alternatives_rows def _validate_grid(self, grid): #validate current grid and questions number forms = {} for row in grid: if row['c_type'] == 'alternative': if row['form'] not in forms: forms[row['form']] = [] if row['perm'] in forms[row['form']]: return False else: forms[row['form']].append(row['perm']) if row['c_type'] == 'question': for i in xrange(self.question_list.count()): if i == self.question_list.currentRow(): continue perm = self.question_list.item(i).data(Qt.UserRole)\ .toPyObject().get_permutation() for perm_row in perm: if (perm_row['c_type'] == 'question' and perm_row['form'] == row['form'] and perm_row['perm'] == row['perm']): return False return True def _reset_permutation_grid(self): for k, v in self.alternatives_rows.iteritems(): for sk, sv in v.iteritems(): sv.setCurrentIndex(0) def _get_values(self): formated_permutation = {} formated_permutation_m = {} for i in xrange(self.question_list.count()): permutations = self.question_list.item(i).data(Qt.UserRole)\ .toPyObject().get_permutation() a = {} for p in permutations: if p['form'] not in formated_permutation: formated_permutation[p['form']] = [] if p['form'] not in a: a[p['form']] = [] if p['c_type'] == 'alternative': a[p['form']].append(p['perm']) if p['c_type'] == 'question': formated_permutation[p['form']].append( \ "%s{%s}" % (p['perm'], ','.join(str(x) \ for x in a[p['form']]))) for k, v in formated_permutation.iteritems(): formated_permutation_m[chr(97 + k).upper()] = '/'.join(v) return formated_permutation_m def validatePage(self): valid = True msg = '' for i in xrange(self.question_list.count()): if not self.question_list.item(i).data(Qt.UserRole)\ .toPyObject().get_permutation(): valid = False msg = _('You must select all permutations for all questions') break if not valid: QMessageBox.critical(self, _('Error'), msg) else: current_permutations = self._get_values() for k, v in current_permutations.iteritems(): self.wizard().exam_config.set_permutations(k, v) return valid def nextId(self): return WizardNewSession.PageIdFiles
class ShowPresets(QDialog): def __init__(self, parent=None): super(ShowPresets, self).__init__(parent) self.original_presets_file = '/usr/share/ffmulticonverter/presets.xml' self.config_folder = os.getenv('HOME') + '/.config/ffmulticonverter/' self.current_presets_file = self.config_folder + 'presets.xml' self.presListWidget = QListWidget() labelLabel = QLabel(self.tr('Preset label')) self.labelLineEdit = QLineEdit() self.labelLineEdit.setReadOnly(True) commandLabel = QLabel(self.tr('Preset command line parameters')) self.commandLineEdit = QLineEdit() self.commandLineEdit.setReadOnly(True) extLabel = QLabel(self.tr('Output file extension')) self.extLineEdit = QLineEdit() self.extLineEdit.setReadOnly(True) addButton = QPushButton(self.tr('Add')) self.deleteButton = QPushButton(self.tr('Delete')) self.delete_allButton = QPushButton(self.tr('Delete all')) self.editButton = QPushButton(self.tr('Edit')) searchLabel = QLabel(self.tr('Search')) self.searchLineEdit = QLineEdit() okButton = QPushButton(self.tr('OK')) okButton.setDefault(True) spc1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) spc2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) spc3 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) grid = pyqttools.add_to_grid( QGridLayout(), [self.delete_allButton, addButton, spc1], [self.deleteButton, self.editButton, spc2]) hlayout = pyqttools.add_to_layout(QHBoxLayout(), searchLabel, self.searchLineEdit, None, okButton) final_layout = pyqttools.add_to_layout( QVBoxLayout(), self.presListWidget, labelLabel, self.labelLineEdit, commandLabel, self.commandLineEdit, extLabel, self.extLineEdit, grid, spc3, hlayout) self.setLayout(final_layout) okButton.clicked.connect(self.accept) self.presListWidget.currentRowChanged.connect(self.show_preset) addButton.clicked.connect(self.add_preset) self.deleteButton.clicked.connect(self.delete_preset) self.delete_allButton.clicked.connect(self.delete_all_presets) self.editButton.clicked.connect(self.edit_preset) self.searchLineEdit.textEdited.connect(self.search) del_shortcut = QShortcut(self) del_shortcut.setKey(Qt.Key_Delete) del_shortcut.activated.connect(self.delete_preset) self.resize(430, 480) self.setWindowTitle(self.tr('Edit Presets')) QTimer.singleShot(0, self.load_xml) QTimer.singleShot(0, self.fill_presListWidget) def load_xml(self): """Load xml tree and set xml root.""" try: self.tree = etree.parse(self.current_presets_file) except (etree.ParseError, IOError): try: self.tree = etree.parse(self.original_presets_file) except IOError: # when program is not installed self.tree = etree.parse('../share/presets.xml') if not os.path.exists(self.config_folder): os.makedirs(self.config_folder) self.root = self.tree.getroot() def set_buttons_clear_lineEdits(self): """Enable or disable button's and clear lineEdits.""" enable = bool(self.presListWidget) self.editButton.setEnabled(enable) self.deleteButton.setEnabled(enable) self.delete_allButton.setEnabled(enable) if not enable: self.labelLineEdit.clear() self.commandLineEdit.clear() self.extLineEdit.clear() def fill_presListWidget(self): """Clear self.presListWidget and to it presets' tags.""" self.presListWidget.clear() for i in sorted([y.tag for y in self.root]): elem = self.root.find(i) self.presListWidget.addItem(MyListItem(i, elem)) self.presListWidget.setCurrentRow(0) self.set_buttons_clear_lineEdits() self.searchLineEdit.clear() def show_preset(self): """Fill LineEdits with current xml element's values.""" try: xml_elem = self.presListWidget.currentItem().xml_element except AttributeError: return self.labelLineEdit.setText(xml_elem[0].text) self.commandLineEdit.setText(xml_elem[1].text) self.commandLineEdit.home(False) self.extLineEdit.setText(xml_elem[2].text) def add_preset(self): """Open AddorEditPreset() dialog and add a preset xml root.""" dialog = AddorEditPreset(None, False, self) if dialog.exec_(): element = etree.Element(dialog.name_text) label = etree.Element('label') label.text = dialog.label_text command = etree.Element('params') command.text = dialog.command_text ext = etree.Element('extension') ext.text = dialog.ext_text category = etree.Element('category') category.text = 'Scattered' for num, elem in enumerate([label, command, ext, category]): element.insert(num, elem) index = sorted([i.tag for i in self.root] + [dialog.name_text])\ .index(dialog.name_text) self.root.insert(index, element) self.save_tree() self.fill_presListWidget() def delete_preset(self): """ Ask user wether he wants to delete the selected preset. If so, delete the preset from xml root. """ try: xml_elem = self.presListWidget.currentItem().xml_element except AttributeError: return reply = QMessageBox.question( self, 'FF Multi Converter - ' + self.tr('Delete Preset'), self.tr('Are you sure that you want to delete ' 'the %1 preset?').arg(xml_elem.tag), QMessageBox.Yes | QMessageBox.Cancel) if reply == QMessageBox.Yes: self.root.remove(xml_elem) self.save_tree() self.fill_presListWidget() def delete_all_presets(self): """ Ask user if he wants to delete all presets. If so, clear xml root. """ reply = QMessageBox.question( self, 'FF Multi Converter - ' + self.tr('Delete Preset'), self.tr('Are you sure that you want to delete ' 'all presets?'), QMessageBox.Yes | QMessageBox.Cancel) if reply == QMessageBox.Yes: self.root.clear() self.save_tree() self.fill_presListWidget() def edit_preset(self): """Call the AddorEditPreset() dialog and update xml element's values.""" elem = self.presListWidget.currentItem().xml_element dialog = AddorEditPreset(elem, True) if dialog.exec_(): elem.tag = dialog.name_text elem[0].text = dialog.label_text elem[1].text = dialog.command_text elem[2].text = dialog.ext_text self.save_tree() self.fill_presListWidget() def search(self): """ Search for keywords in presets data. Show a preset only if its tag, label or extension matches any of search string's tokens. """ txt = str(self.searchLineEdit.text()).strip().lower() if not txt: self.fill_presListWidget() return self.presListWidget.clear() for i in txt.split(' '): for p in sorted([y.tag for y in self.root]): elem = self.root.find(p) if (i.strip() and (i in elem.tag.lower() or i in elem[0].text.lower() or i in elem[2].text.lower())): self.presListWidget.addItem(MyListItem(p, elem)) self.presListWidget.setCurrentRow(0) self.set_buttons_clear_lineEdits() def save_tree(self): """Save xml tree.""" with open(self.current_presets_file, 'w') as _file: try: etree.ElementTree(self.root).write(_file) except: pass def import_presets(self): """Import an xml tree.""" title = 'FF Multi Converter - Import' reply = QMessageBox.question( self, title, self.tr('All current ' 'presets will be deleted.\nAre you sure that you want to ' 'continue?'), QMessageBox.Yes | QMessageBox.Cancel) if reply == QMessageBox.Yes: fname = QFileDialog.getOpenFileName(self, title) if fname: msg = self.tr('Succesful import!') try: self.tree = etree.parse(fname) except: msg = self.tr('Import failed!') else: self.root = self.tree.getroot() self.save_tree() QMessageBox.information(self, title, msg) def export_presets(self): """Export the xml tree.""" fname = QFileDialog.getSaveFileName( self, 'FF Multi Converter - Export presets', '.xml') if fname: self.load_xml() with open(fname, 'w') as _file: try: etree.ElementTree(self.root).write(_file) except: pass def reset(self): """Import the default xml tree.""" reply = QMessageBox.question( self, 'FF Multi Converter - ' + self.tr('Delete Preset'), self.tr('Are you sure that you want to restore ' 'the default presets?'), QMessageBox.Yes | QMessageBox.Cancel) if reply == QMessageBox.Yes: if os.path.exists(self.current_presets_file): os.remove(self.current_presets_file) def synchronize(self): """ Synchronize current presets with default presets. For each preset in default presets: - if not contained in current presets, add it to current presets - if has the same name with some preset in current presets but different attributes, then add this preset to current presets and add an '__OLD' suffix to matching preset's name """ reply = QMessageBox.question( self, 'FF Multi Converter - ' + self.tr('Presets Synchronization'), self. tr('Current presets and default ' 'presets will be merged. Are you sure that you want to continue?' ), QMessageBox.Yes | QMessageBox.Cancel) if not reply == QMessageBox.Yes: return def_tree = etree.parse(self.original_presets_file) def_root = def_tree.getroot() self.load_xml() for i in def_root: for n, y in enumerate(self.root): if i.tag == y.tag: if not (i[0].text == y[0].text and i[1].text == y[1].text and i[2].text == y[2].text): # copy element and change its name elem = etree.Element(y.tag) label = etree.Element('label') label.text = i[0].text command = etree.Element('params') command.text = i[1].text ext = etree.Element('extension') ext.text = i[2].text elem.insert(0, label) elem.insert(1, command) elem.insert(2, ext) y.tag = y.tag + '__OLD' self.root.insert(n + 1, elem) break else: # preset not found index = sorted([x.tag for x in self.root] + [i.tag]).index(i.tag) self.root.insert(index, i) self.save_tree() def remove_old(self): """Remove those xml elements which their tags has an __OLD prefix.""" reply = QMessageBox.question( self, 'FF Multi Converter - ' + self.tr('Remove old presets'), self.tr( 'All presets with an __OLD prefix ' 'will be deleted. Are you sure that you want to continue?'), QMessageBox.Yes | QMessageBox.Cancel) if not reply == QMessageBox.Yes: return self.load_xml() for i in self.root: if i.tag.endswith('__OLD'): self.root.remove(i) self.save_tree() def accept(self): """ Save current xml element's values in order to be used from main program and close (accept) dialog. """ self.the_command = None if self.presListWidget: self.the_command = self.presListWidget.currentItem()\ .xml_element[1].text self.the_extension = self.presListWidget.currentItem()\ .xml_element[2].text QDialog.accept(self)
class ProfilesLoader(QDialog): def __init__(self, load_func, create_func, save_func, profiles, parent=None): QDialog.__init__(self, parent, Qt.Dialog) self.setWindowTitle(self.tr("Profile Manager")) self.setMinimumWidth(400) self._profiles = profiles self.load_function = load_func self.create_function = create_func self.save_function = save_func self.ide = parent vbox = QVBoxLayout(self) vbox.addWidget(QLabel(self.tr("Save your opened files and projects " "into a profile and change really quick\n" "between projects and files sessions.\n" "This allows you to save your working environment, " "keep working in another\nproject and then go back " "exactly where you left."))) self.profileList = QListWidget() self.profileList.addItems([key for key in profiles]) self.profileList.setCurrentRow(0) self.contentList = QListWidget() self.btnDelete = QPushButton(self.tr("Delete Profile")) self.btnDelete.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnUpdate = QPushButton(self.tr("Update Profile")) self.btnUpdate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnCreate = QPushButton(self.tr("Create New Profile")) self.btnCreate.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnOpen = QPushButton(self.tr("Open Profile")) self.btnOpen.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnOpen.setDefault(True) hbox = QHBoxLayout() hbox.addWidget(self.btnDelete) hbox.addWidget(self.btnUpdate) hbox.addWidget(self.btnCreate) hbox.addWidget(self.btnOpen) vbox.addWidget(self.profileList) vbox.addWidget(self.contentList) vbox.addLayout(hbox) self.connect(self.profileList, SIGNAL("itemSelectionChanged()"), self.load_profile_content) self.connect(self.btnOpen, SIGNAL("clicked()"), self.open_profile) self.connect(self.btnUpdate, SIGNAL("clicked()"), self.save_profile) self.connect(self.btnCreate, SIGNAL("clicked()"), self.create_profile) self.connect(self.btnDelete, SIGNAL("clicked()"), self.delete_profile) def load_profile_content(self): item = self.profileList.currentItem() self.contentList.clear() if item is not None: key = unicode(item.text()) files = [self.tr('Files:')] + \ [file[0] for file in self._profiles[key][0]] projects = [self.tr('Projects:')] + self._profiles[key][1] content = files + projects self.contentList.addItems(content) def create_profile(self): profileName = self.create_function() self.ide.Profile = profileName self.close() def save_profile(self): if self.profileList.currentItem(): profileName = unicode(self.profileList.currentItem().text()) self.save_function(profileName) self.ide.show_status_message(self.tr("Profile %1 Updated!").arg( profileName)) self.load_profile_content() def open_profile(self): if self.profileList.currentItem(): key = unicode(self.profileList.currentItem().text()) self.load_function(key) self.ide.Profile = key self.close() def delete_profile(self): if self.profileList.currentItem(): key = unicode(self.profileList.currentItem().text()) self._profiles.pop(key) self.profileList.takeItem(self.profileList.currentRow()) self.contentList.clear()
class EditorGeneral(QWidget): def __init__(self, parent): super(EditorGeneral, self).__init__() self._preferences = parent vbox = QVBoxLayout(self) self.original_style = copy.copy(resources.CUSTOM_SCHEME) self.current_scheme = 'default' groupBoxMini = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_MINIMAP) groupBoxTypo = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_TYPOGRAPHY) groupBoxScheme = QGroupBox( translations.TR_PREFERENCES_EDITOR_GENERAL_SCHEME) #Minimap formMini = QGridLayout(groupBoxMini) self._checkShowMinimap = QCheckBox() self._spinMaxOpacity = QSpinBox() self._spinMaxOpacity.setMaximum(100) self._spinMaxOpacity.setMinimum(0) self._spinMinOpacity = QSpinBox() self._spinMinOpacity.setMaximum(100) self._spinMinOpacity.setMinimum(0) self._spinSize = QSpinBox() self._spinSize.setMaximum(100) self._spinSize.setMinimum(0) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_ENABLE_MINIMAP), 0, 0, Qt.AlignRight) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_MAX_OPACITY), 1, 0, Qt.AlignRight) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_MIN_OPACITY), 2, 0, Qt.AlignRight) formMini.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_AREA_MINIMAP), 3, 0, Qt.AlignRight) formMini.addWidget(self._checkShowMinimap, 0, 1) formMini.addWidget(self._spinMaxOpacity, 1, 1) formMini.addWidget(self._spinMinOpacity, 2, 1) formMini.addWidget(self._spinSize, 3, 1) #Typo gridTypo = QGridLayout(groupBoxTypo) self._btnEditorFont = QPushButton('') gridTypo.addWidget(QLabel( translations.TR_PREFERENCES_EDITOR_GENERAL_EDITOR_FONT), 0, 0, Qt.AlignRight) gridTypo.addWidget(self._btnEditorFont, 0, 1) #Scheme hbox = QHBoxLayout(groupBoxScheme) self._listScheme = QListWidget() hbox.addWidget(self._listScheme) vbox.addWidget(groupBoxMini) vbox.addWidget(groupBoxTypo) vbox.addWidget(groupBoxScheme) #Settings qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') self._checkShowMinimap.setChecked(settings.SHOW_MINIMAP) self._spinMaxOpacity.setValue(settings.MINIMAP_MAX_OPACITY * 100) self._spinMinOpacity.setValue(settings.MINIMAP_MIN_OPACITY * 100) self._spinSize.setValue(settings.SIZE_PROPORTION * 100) self._btnEditorFont.setText( ', '.join([settings.FONT_FAMILY, str(settings.FONT_SIZE)])) self._listScheme.clear() self._listScheme.addItem('default') self._schemes = json_manager.load_editor_skins() for item in self._schemes: self._listScheme.addItem(item) items = self._listScheme.findItems( qsettings.value('scheme', defaultValue='', type='QString'), Qt.MatchExactly) if items: self._listScheme.setCurrentItem(items[0]) else: self._listScheme.setCurrentRow(0) qsettings.endGroup() qsettings.endGroup() #Signals self.connect(self._btnEditorFont, SIGNAL("clicked()"), self._load_editor_font) self.connect(self._listScheme, SIGNAL("itemSelectionChanged()"), self._preview_style) self.connect(self._preferences, SIGNAL("savePreferences()"), self.save) def showEvent(self, event): super(EditorGeneral, self).showEvent(event) self.thread_callback = ui_tools.ThreadExecution(self._get_editor_skins) self.connect(self.thread_callback, SIGNAL("finished()"), self._show_editor_skins) self.thread_callback.start() def _get_editor_skins(self): qsettings = IDE.ninja_settings() qsettings.beginGroup('preferences') qsettings.beginGroup('editor') self._schemes = json_manager.load_editor_skins() self._selected_scheme = qsettings.value('scheme', defaultValue='', type='QString') qsettings.endGroup() qsettings.endGroup() def _show_editor_skins(self): self._listScheme.clear() self._listScheme.addItem('default') for item in self._schemes: self._listScheme.addItem(item) items = self._listScheme.findItems( self._selected_scheme, Qt.MatchExactly) if items: self._listScheme.setCurrentItem(items[0]) else: self._listScheme.setCurrentRow(0) self.thread_callback.wait() def hideEvent(self, event): super(EditorGeneral, self).hideEvent(event) resources.CUSTOM_SCHEME = self.original_style main_container = IDE.get_service('main_container') editorWidget = main_container.get_current_editor() if editorWidget is not None: editorWidget.restyle(editorWidget.lang) editorWidget._sidebarWidget.repaint() def _preview_style(self): scheme = self._listScheme.currentItem().text() if scheme == self.current_scheme: return main_container = IDE.get_service('main_container') editorWidget = main_container.get_current_editor() if editorWidget is not None: resources.CUSTOM_SCHEME = self._schemes.get(scheme, resources.COLOR_SCHEME) editorWidget.restyle(editorWidget.lang) editorWidget._sidebarWidget.repaint() self.current_scheme = scheme def _load_editor_font(self): try: font = self._load_font( self._get_font_from_string(self._btnEditorFont.text()), self) self._btnEditorFont.setText(font) except: QMessageBox.warning(self, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_TITLE, translations.TR_PREFERENCES_EDITOR_GENERAL_FONT_MESSAGE_BODY) def _get_font_from_string(self, font): if not font: font = QFont(settings.FONT_FAMILY, settings.FONT_SIZE) else: listFont = font.split(',') font = QFont(listFont[0].strip(), int(listFont[1].strip())) return font def _load_font(self, initialFont, parent=0): font, ok = QFontDialog.getFont(initialFont, parent) if ok: newFont = font.toString().split(',') else: newFont = initialFont.toString().split(',') return newFont[0] + ', ' + newFont[1] def save(self): qsettings = IDE.ninja_settings() settings.SHOW_MINIMAP = self._checkShowMinimap.isChecked() settings.MINIMAP_MAX_OPACITY = self._spinMaxOpacity.value() / 100.0 settings.MINIMAP_MIN_OPACITY = self._spinMinOpacity.value() / 100.0 settings.SIZE_PROPORTION = self._spinSize.value() / 100.0 qsettings.setValue('preferences/editor/minimapShow', settings.SHOW_MINIMAP) qsettings.setValue('preferences/editor/minimapMaxOpacity', settings.MINIMAP_MAX_OPACITY) qsettings.setValue('preferences/editor/minimapMinOpacity', settings.MINIMAP_MIN_OPACITY) qsettings.setValue('preferences/editor/minimapSizeProportion', settings.SIZE_PROPORTION) fontText = self._btnEditorFont.text().replace(' ', '') settings.FONT_FAMILY = fontText.split(',')[0] settings.FONT_SIZE = int(fontText.split(',')[1]) qsettings.setValue('preferences/editor/fontFamily', settings.FONT_FAMILY) qsettings.setValue('preferences/editor/fontSize', settings.FONT_SIZE) scheme = self._listScheme.currentItem().text() self.original_style = resources.CUSTOM_SCHEME qsettings.setValue('preferences/editor/scheme', scheme) resources.CUSTOM_SCHEME = self._schemes.get(scheme, resources.COLOR_SCHEME)
class MainWindow(QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setWindowTitle('Address Book') self.resize(704, 459) self.db_file = self.database_file() self.db = database.Database(self.db_file) dialog = dialogs.UserPanelDlg(self) if dialog.exec_(): self.user = dialog.user else: self.close() self.categComboBox = QComboBox() self.cont_numLabel = QLabel() self.contactsListWidget = QListWidget() self.searchLineEdit = QLineEdit() widgets = ((QLabel('Category:'), self.categComboBox), (self.cont_numLabel, None), (self.contactsListWidget,), (QLabel('Search:'), self.searchLineEdit)) vlayout1 = QVBoxLayout() for i in widgets: hlayout = pyqttools.add_to_layout(QHBoxLayout(), i) vlayout1.addLayout(hlayout) addToolButton = QToolButton() addToolButton.setIcon(QIcon(':addcontact.jpeg')) addToolButton.setIconSize(QSize(45, 45)) self.showLabel = QLabel() self.showLabel.setFrameShape(QFrame.StyledPanel) self.showLabel.setAlignment(Qt.AlignLeading|Qt.AlignLeft|Qt.AlignTop) self.editButton = QPushButton('Edit') self.delButton = QPushButton('Delete') widgets = ((None, addToolButton, None), (self.showLabel,), (None, self.editButton, self.delButton)) vlayout2 = QVBoxLayout() for i in widgets: hlayout = pyqttools.add_to_layout(QHBoxLayout(), i) vlayout2.addLayout(hlayout) f_layout = pyqttools.add_to_layout(QHBoxLayout(), (vlayout1, vlayout2)) Widget = QWidget() Widget.setLayout(f_layout) self.setCentralWidget(Widget) self.statusBar = self.statusBar() self.userLabel = QLabel() self.statusBar.addPermanentWidget(self.userLabel) c_action = pyqttools.create_action panelAction = c_action(self, 'User panel', triggered=self.user_panel) quitAction = c_action(self, 'Quit', 'Ctrl+Q',triggered=self.close) add_contactAction = c_action(self, 'Add contact', 'Ctrl+N', triggered=self.add_contact) delete_allAction = c_action(self, 'Delete all contacts', triggered=self.delete_all) delete_categAction = c_action(self, 'Delete categories', triggered=self.delete_categories) backupAction = c_action(self, 'Backup', triggered=self.backup) restoreAction = c_action(self, 'Restore', triggered=self.restore) aboutAction = c_action(self, 'About', 'Ctrl+?', triggered=self.about) fileMenu = self.menuBar().addMenu('File') contactsMenu = self.menuBar().addMenu('Contacts') deleteMenu = self.menuBar().addMenu(self.tr('Delete')) backupMenu = self.menuBar().addMenu(self.tr('Backup')) helpMenu = self.menuBar().addMenu('Help') pyqttools.add_actions(fileMenu, [panelAction, None, quitAction]) pyqttools.add_actions(contactsMenu, [add_contactAction]) pyqttools.add_actions(deleteMenu,[delete_allAction,delete_categAction]) pyqttools.add_actions(backupMenu, [backupAction, restoreAction]) pyqttools.add_actions(helpMenu, [aboutAction]) addToolButton.clicked.connect(self.add_contact) self.editButton.clicked.connect(self.edit_contact) self.delButton.clicked.connect(self.delete_contact) self.categComboBox.currentIndexChanged.connect(self.fill_ListWidget) self.contactsListWidget.currentRowChanged.connect(self.show_contact) self.searchLineEdit.textEdited.connect(self.search) self.fill_categComboBox() self.refresh_userLabel() def fill_categComboBox(self): categories = ['All'] categories.extend([i[1] for i in self.db.get_categories(self.user)]) self.categComboBox.currentIndexChanged.disconnect(self.fill_ListWidget) self.categComboBox.clear() self.categComboBox.addItems(categories) self.categComboBox.currentIndexChanged.connect(self.fill_ListWidget) self.fill_ListWidget() def fill_ListWidget(self): self.showLabel.clear() self.contactsListWidget.clear() if self.categComboBox.currentIndex() != 0: self.searchLineEdit.clear() category = self.categComboBox.currentText() if category == 'All': contacts = self.db.get_all_contacts(self.user) else: categ_id = self.db.get_category_id(category, self.user) if categ_id is None: return contacts = self.db.get_contacts(categ_id) for i in contacts: self.contactsListWidget.addItem(MyListItem(i[1]+' '+i[2], i[0])) self.contactsListWidget.setCurrentRow(0) self.refresh_contacts_number() self.set_buttons_enabled() def refresh_userLabel(self): self.userLabel.setText('User: '******'Contacts Numer: {0}'.format(self.contactsListWidget.count()) self.cont_numLabel.setText(text) def set_buttons_enabled(self): enable = bool(self.contactsListWidget) self.editButton.setEnabled(enable) self.delButton.setEnabled(enable) def user_panel(self): dialog = dialogs.UserPanelDlg(self) if dialog.exec_(): self.user = dialog.user self.fill_categComboBox() self.refresh_userLabel() def show_contact(self): try: _id = self.contactsListWidget.currentItem()._id except AttributeError: return _id, name, surname, mail, address, tel, categ_id = \ self.db.get_contact_from_id(_id)[0] category = self.db.get_category_from_id(categ_id) text = '' data = (name, surname, mail, address, tel, category) labs = ('Name', 'Surname', 'e-mail', 'Address', 'Telephone', 'Category') for i, y in zip(labs, data): text += '''<p style=\' margin-top:0px; margin-bottom:0px; \'> <span style=\' font-weight:600;\'>{0}:</span> {1} </p>\n'''\ .format(i, y) self.showLabel.setText(text) def add_contact(self): categories = [i[1] for i in self.db.get_categories(self.user)] dialog = dialogs.AddorEditContactDlg(categories) if dialog.exec_(): data = dialog.values if data[-1] not in categories: self.db.addto_categories(data[-1], self.user) categ_id = self.db.get_category_id(data[-1], self.user) data[-1] = categ_id self.db.addto_contacts(data) self.fill_categComboBox() def edit_contact(self): _id = self.contactsListWidget.currentItem()._id data = list(self.db.get_contact_from_id(_id)[0]) categ = self.db.get_category_from_id(data[-1]) data[-1] = categ categories = [i[1] for i in self.db.get_categories(self.user)] dialog = dialogs.AddorEditContactDlg(categories, True, data) if dialog.exec_(): new_data = dialog.values if new_data[-1] not in categories: self.db.addto_categories(new_data[-1], self.user) categ_id = self.db.get_category_id(new_data[-1], self.user) new_data[-1] = categ_id self.db.edit_contact(new_data, _id) self.fill_categComboBox() def delete_contact(self): reply = QMessageBox.question(self, 'Address Book - Delete Contact', 'Are you sure that you want to delete this contact?', QMessageBox.Yes|QMessageBox.Cancel) if reply == QMessageBox.Yes: _id = self.contactsListWidget.currentItem()._id self.db.delete_contact(_id) self.fill_ListWidget() def delete_all(self): reply = QMessageBox.question(self, 'Address Book - Delete Contact', 'Are you sure that you want to delete all contacts?', QMessageBox.Yes|QMessageBox.Cancel) if reply == QMessageBox.Yes: self.db.delete_all_contacts() self.fill_ListWidget() def delete_categories(self): categories = [i[1] for i in self.db.get_categories(self.user)] dialogs.DelCategoriesDlg(categories, self).exec_() self.fill_categComboBox() def search(self): self.categComboBox.setCurrentIndex(0) self.showLabel.clear() self.contactsListWidget.clear() txt = self.searchLineEdit.text() if all(i == ' ' for i in txt): self.fill_ListWidget() return must_appear = [] contacts = self.db.get_all_contacts(self.user) if not ' ' in txt: for i in contacts: if txt.lower() in i[1].lower() or txt.lower() in i[2].lower(): must_appear.append(i) else: try: first, last = txt.split() except ValueError: return for i in contacts: _bool = bool(first.lower() in i[1].lower() or first.lower() in i[2].lower() or last.lower() in i[1].lower() or last.lower() in i[2].lower()) if _bool: must_appear.append(i) for i in must_appear: item = MyListItem(i[1] + ' ' + i[2], i[0]) self.contactsListWidget.addItem(item) self.contactsListWidget.setCurrentRow(0) self.refresh_contacts_number() self.set_buttons_enabled() def backup(self): fname = QFileDialog.getSaveFileName(self,'Address Book - Backup','.db') if fname: try: shutil.copy(self.db_file, fname) except IOError: pass def restore(self): reply = QMessageBox.question(self, 'Address Book - Restore', 'All current contacts will be deleted.\nAre you sure that you want' ' to continue?', QMessageBox.Yes|QMessageBox.Cancel) if reply == QMessageBox.Yes: fname = QFileDialog.getOpenFileName(self, 'Address Book - Restore') if fname: msg = 'Succesful restore!' try: os.remove(self.db_file) shutil.copy(fname, self.db_file) except (OSError, IOError): msg = 'Restore failed!' QMessageBox.information(self, 'Addess Book - Restore', msg) self.db = database.Database(self.db_file) self.fill_categComboBox() def database_file(self): _file = 'addressbook.db' if not platform.platform().startswith('Windows'): folder = os.getenv('HOME') + os.sep + '.addressbook' if not os.path.exists(folder): os.mkdir(folder) _file = folder + os.sep + _file return _file def about(self): link = 'http://wiki.ubuntu-gr.org/Address%20Book' QMessageBox.about(self, self.tr('About') + ' FF Multi Converter', '''<b> Address Book {0} </b> <p>Gui application to organize your contacts! <p>Copyright © 2012 Ilias Stamatis <br>License: GNU GPL3 <p><a href='{1}'>http://wiki.ubuntu-gr.org/Address Book</a> <p>Python {2} - Qt {3} - PyQt {4} on {5}''' .format(__version__, link, platform.python_version()[:5], QT_VERSION_STR, PYQT_VERSION_STR, platform.system())) def close(self): self.db.close() sys.exit()
class CodeCompletionWidget(QFrame): def __init__(self, editor): super(CodeCompletionWidget, self).__init__(None, Qt.FramelessWindowHint | Qt.ToolTip) self._editor = editor self.stack_layout = QStackedLayout(self) self.stack_layout.setContentsMargins(0, 0, 0, 0) self.stack_layout.setSpacing(0) self.completion_list = QListWidget() self.completion_list.setMinimumHeight(200) self.completion_list.setAlternatingRowColors(True) self._list_index = self.stack_layout.addWidget(self.completion_list) self._icons = { 'a': resources.IMAGES['attribute'], 'f': resources.IMAGES['function'], 'c': resources.IMAGES['class'], 'm': resources.IMAGES['module'] } self.cc = code_completion.CodeCompletion() self._completion_results = {} self._prefix = u'' self.setVisible(False) self.source = '' self._key_operations = { Qt.Key_Up: self._select_previous_row, Qt.Key_Down: self._select_next_row, Qt.Key_PageUp: (lambda: self._select_previous_row(6)), Qt.Key_PageDown: (lambda: self._select_next_row(6)), Qt.Key_Right: lambda: None, Qt.Key_Left: lambda: None, Qt.Key_Enter: self.pre_key_insert_completion, Qt.Key_Return: self.pre_key_insert_completion, Qt.Key_Tab: self.pre_key_insert_completion, Qt.Key_Space: self.hide_completer, Qt.Key_Escape: self.hide_completer, Qt.Key_Backtab: self.hide_completer, Qt.NoModifier: self.hide_completer, Qt.ShiftModifier: self.hide_completer, } desktop = QApplication.instance().desktop() self._desktop_geometry = desktop.availableGeometry() self.connect(self._editor.document(), SIGNAL("blockCountChanged(int)"), self.update_metadata) def _select_next_row(self, move=1): new_row = self.completion_list.currentRow() + move if new_row < self.completion_list.count(): self.completion_list.setCurrentRow(new_row) else: self.completion_list.setCurrentRow(0) return True def _select_previous_row(self, move=1): new_row = self.completion_list.currentRow() - move if new_row >= 0: self.completion_list.setCurrentRow(new_row) else: self.completion_list.setCurrentRow(self.completion_list.count() - move) return True def update_metadata(self): source = self._editor.get_text() source = source.encode(self._editor.encoding) self.cc.analyze_file('', source) def insert_completion(self, insert): if insert != self._prefix: extra = len(self._prefix) - len(insert) self._editor.textCursor().insertText(insert[extra:]) self.hide_completer() def _get_geometry(self): cr = self._editor.cursorRect() point = self._editor.mapToGlobal(cr.topLeft()) cr.moveTopLeft(point) #Check new position according desktop geometry width = (self.completion_list.sizeHintForColumn(0) + \ self.completion_list.verticalScrollBar().sizeHint().width() + 10) height = 200 orientation = (point.y() + height) < self._desktop_geometry.height() if orientation: cr.moveTop(cr.bottom()) cr.setWidth(width) cr.setHeight(height) if not orientation: cr.moveBottom(cr.top()) xpos = self._desktop_geometry.width() - (point.x() + width) if xpos < 0: cr.moveLeft(cr.left() + xpos) return cr def complete(self, results): self.add_list_items(results) self.completion_list.setCurrentRow(0) cr = self._get_geometry() self.setGeometry(cr) self.completion_list.updateGeometries() self.show() def add_list_items(self, proposals): self.completion_list.clear() for p in proposals: self.completion_list.addItem( QListWidgetItem( QIcon(self._icons.get(p[0], resources.IMAGES['attribute'])), p[1])) def set_completion_prefix(self, prefix, valid=True): self._prefix = prefix proposals = [] proposals += [('m', item) \ for item in self._completion_results.get('modules', []) \ if item.startswith(prefix)] proposals += [('c', item) \ for item in self._completion_results.get('classes', []) \ if item.startswith(prefix)] proposals += [('a', item) \ for item in self._completion_results.get('attributes', []) \ if item.startswith(prefix)] proposals += [('f', item) \ for item in self._completion_results.get('functions', []) \ if item.startswith(prefix)] if proposals and valid: self.complete(proposals) else: self.hide_completer() def fill_completer(self): source = self._editor.get_text() source = source.encode(self._editor.encoding) offset = self._editor.textCursor().position() results = self.cc.get_completion(source, offset) self._completion_results = results prefix = self._editor._text_under_cursor() self.set_completion_prefix(prefix) def hide_completer(self): self._prefix = '' self.hide() def pre_key_insert_completion(self): insert = unicode(self.completion_list.currentItem().text()) self.insert_completion(insert) self.hide_completer() return True def process_pre_key_event(self, event): if not self.isVisible() or self._editor.lang != "python": return False skip = self._key_operations.get(event.key(), lambda: False)() self._key_operations.get(event.modifiers(), lambda: False)() if skip is None: skip = False return skip def process_post_key_event(self, event): if not settings.CODE_COMPLETION or self._editor.lang != "python": return if self.isVisible(): source = self._editor.get_text() source = source.encode(self._editor.encoding) offset = self._editor.textCursor().position() prefix, valid = self.cc.get_prefix(source, offset) self.set_completion_prefix(prefix, valid) self.completion_list.setCurrentRow(0) if event.key() == Qt.Key_Period or (event.key() == Qt.Key_Space and \ event.modifiers() == Qt.ControlModifier): self.fill_completer()
class CodeCompletionWidget(QFrame): def __init__(self, editor): super(CodeCompletionWidget, self).__init__( None, Qt.FramelessWindowHint | Qt.ToolTip) self._editor = editor self._revision = 0 self._block = 0 self.stack_layout = QStackedLayout(self) self.stack_layout.setContentsMargins(0, 0, 0, 0) self.stack_layout.setSpacing(0) self.completion_list = QListWidget() self.completion_list.setMinimumHeight(200) self.completion_list.setAlternatingRowColors(True) self._list_index = self.stack_layout.addWidget(self.completion_list) self._icons = {'a': resources.IMAGES['attribute'], 'f': resources.IMAGES['function'], 'c': resources.IMAGES['class'], 'm': resources.IMAGES['module']} self.cc = code_completion.CodeCompletion() self._completion_results = {} self._prefix = u'' self.setVisible(False) self.source = '' self._key_operations = { Qt.Key_Up: self._select_previous_row, Qt.Key_Down: self._select_next_row, Qt.Key_PageUp: (lambda: self._select_previous_row(6)), Qt.Key_PageDown: (lambda: self._select_next_row(6)), Qt.Key_Right: lambda: None, Qt.Key_Left: lambda: None, Qt.Key_Enter: self.pre_key_insert_completion, Qt.Key_Return: self.pre_key_insert_completion, Qt.Key_Tab: self.pre_key_insert_completion, Qt.Key_Space: self.hide_completer, Qt.Key_Escape: self.hide_completer, Qt.Key_Backtab: self.hide_completer, Qt.NoModifier: self.hide_completer, Qt.ShiftModifier: self.hide_completer, } self.desktop = QApplication.instance().desktop() self.connect(self.completion_list, SIGNAL("itemClicked(QListWidgetItem*)"), self.pre_key_insert_completion) self.connect(self._editor.document(), SIGNAL("cursorPositionChanged(QTextCursor)"), self.update_metadata) def _select_next_row(self, move=1): new_row = self.completion_list.currentRow() + move if new_row < self.completion_list.count(): self.completion_list.setCurrentRow(new_row) else: self.completion_list.setCurrentRow(0) return True def _select_previous_row(self, move=1): new_row = self.completion_list.currentRow() - move if new_row >= 0: self.completion_list.setCurrentRow(new_row) else: self.completion_list.setCurrentRow( self.completion_list.count() - move) return True def update_metadata(self, cursor): if settings.CODE_COMPLETION: if self._editor.document().revision() != self._revision and \ cursor.block().blockNumber() != self._block: source = self._editor.get_text() source = source.encode(self._editor.encoding) self.cc.analyze_file(self._editor.ID, source) self._revision = self._editor.document().revision() self._block = cursor.block().blockNumber() def insert_completion(self, insert, type_=ord('a')): if insert != self._prefix: closing = '' if type_ in (ord('f'), ord('c')): closing = '()' extra = len(self._prefix) - len(insert) insertion = '%s%s' % (insert[extra:], closing) self._editor.textCursor().insertText(insertion) self.hide_completer() def _get_geometry(self): cr = self._editor.cursorRect() desktop_geometry = self.desktop.availableGeometry(self._editor) point = self._editor.mapToGlobal(cr.topLeft()) cr.moveTopLeft(point) #Check new position according desktop geometry width = (self.completion_list.sizeHintForColumn(0) + self.completion_list.verticalScrollBar().sizeHint().width() + 10) height = 200 orientation = (point.y() + height) < desktop_geometry.height() if orientation: cr.moveTop(cr.bottom()) cr.setWidth(width) cr.setHeight(height) if not orientation: cr.moveBottom(cr.top()) xpos = desktop_geometry.width() - (point.x() + width) if xpos < 0: cr.moveLeft(cr.left() + xpos) return cr def complete(self, results): self.add_list_items(results) self.completion_list.setCurrentRow(0) cr = self._get_geometry() self.setGeometry(cr) self.completion_list.updateGeometries() self.show() def add_list_items(self, proposals): self.completion_list.clear() for p in proposals: self.completion_list.addItem( QListWidgetItem( QIcon(self._icons.get(p[0], resources.IMAGES['attribute'])), p[1], type=ord(p[0]))) def set_completion_prefix(self, prefix, valid=True): self._prefix = prefix proposals = [] proposals += [('m', item) for item in self._completion_results.get('modules', []) if item.startswith(prefix)] proposals += [('c', item) for item in self._completion_results.get('classes', []) if item.startswith(prefix)] proposals += [('a', item) for item in self._completion_results.get('attributes', []) if item.startswith(prefix)] proposals += [('f', item) for item in self._completion_results.get('functions', []) if item.startswith(prefix)] if proposals and valid: self.complete(proposals) else: self.hide_completer() def _invalid_completion_position(self): result = False cursor = self._editor.textCursor() cursor.movePosition(QTextCursor.StartOfLine, QTextCursor.KeepAnchor) selection = unicode(cursor.selectedText())[:-1].split(' ') if len(selection) == 0 or selection[-1] == '' or \ selection[-1].isdigit(): result = True return result def fill_completer(self, force_completion=False): if not force_completion and (self._editor.cursor_inside_string() or self._editor.cursor_inside_comment() or self._invalid_completion_position()): return source = self._editor.get_text() source = source.encode(self._editor.encoding) offset = self._editor.textCursor().position() results = self.cc.get_completion(source, offset) self._completion_results = results if force_completion: cursor = self._editor.textCursor() cursor.movePosition(QTextCursor.StartOfWord, QTextCursor.KeepAnchor) prefix = cursor.selectedText() else: prefix = self._editor._text_under_cursor() self.set_completion_prefix(prefix) def hide_completer(self): self._prefix = '' self.hide() def pre_key_insert_completion(self): type_ = ord('a') current = self.completion_list.currentItem() insert = unicode(current.text()) if not insert.endswith(')'): type_ = current.type() self.insert_completion(insert, type_) self.hide_completer() return True def process_pre_key_event(self, event): if not self.isVisible() or self._editor.lang != "python": return False skip = self._key_operations.get(event.key(), lambda: False)() self._key_operations.get(event.modifiers(), lambda: False)() if skip is None: skip = False return skip def process_post_key_event(self, event): if not settings.CODE_COMPLETION or self._editor.lang != "python": return if self.isVisible(): source = self._editor.get_text() source = source.encode(self._editor.encoding) offset = self._editor.textCursor().position() prefix, valid = self.cc.get_prefix(source, offset) self.set_completion_prefix(prefix, valid) self.completion_list.setCurrentRow(0) force_completion = (event.key() == Qt.Key_Space and event.modifiers() == Qt.ControlModifier) if event.key() == Qt.Key_Period or force_completion: self.fill_completer(force_completion)
class PreferencesDialog(QDialog): def __init__(self, mainwindow): super(PreferencesDialog, self).__init__(mainwindow) self.setWindowModality(Qt.WindowModal) self.addAction(mainwindow.actionCollection.help_whatsthis) layout = QVBoxLayout() layout.setSpacing(10) self.setLayout(layout) # listview to the left, stacked widget to the right top = QHBoxLayout() layout.addLayout(top) self.pagelist = QListWidget(self) self.stack = QStackedWidget(self) top.addWidget(self.pagelist, 0) top.addWidget(self.stack, 2) layout.addWidget(widgets.Separator(self)) b = self.buttons = QDialogButtonBox(self) b.setStandardButtons( QDialogButtonBox.Ok | QDialogButtonBox.Cancel | QDialogButtonBox.Apply | QDialogButtonBox.Reset | QDialogButtonBox.Help) layout.addWidget(b) b.accepted.connect(self.accept) b.rejected.connect(self.reject) b.button(QDialogButtonBox.Apply).clicked.connect(self.saveSettings) b.button(QDialogButtonBox.Reset).clicked.connect(self.loadSettings) b.button(QDialogButtonBox.Help).clicked.connect(self.showHelp) b.button(QDialogButtonBox.Help).setShortcut(QKeySequence.HelpContents) b.button(QDialogButtonBox.Apply).setEnabled(False) # fill the pagelist self.pagelist.setIconSize(QSize(32, 32)) self.pagelist.setSpacing(2) for item in pageorder(): self.pagelist.addItem(item()) self.pagelist.currentItemChanged.connect(self.slotCurrentItemChanged) app.translateUI(self, 100) # read our size and selected page qutil.saveDialogSize(self, "preferences/dialog/size", QSize(500, 300)) self.pagelist.setCurrentRow(_prefsindex) def translateUI(self): self.pagelist.setFixedWidth(self.pagelist.sizeHintForColumn(0) + 12) self.setWindowTitle(app.caption(_("Preferences"))) def done(self, result): if result and self.buttons.button(QDialogButtonBox.Apply).isEnabled(): self.saveSettings() # save our size and selected page global _prefsindex _prefsindex = self.pagelist.currentRow() super(PreferencesDialog, self).done(result) def pages(self): """Yields the settings pages that are already instantiated.""" for n in range(self.stack.count()): yield self.stack.widget(n) def showHelp(self): userguide.show(self.pagelist.currentItem().help) def loadSettings(self): """Loads the settings on reset.""" for page in self.pages(): page.loadSettings() page.hasChanges = False self.buttons.button(QDialogButtonBox.Apply).setEnabled(False) def saveSettings(self): """Saves the settings and applies them.""" for page in self.pages(): if page.hasChanges: page.saveSettings() page.hasChanges = False self.buttons.button(QDialogButtonBox.Apply).setEnabled(False) # emit the signal app.settingsChanged() def slotCurrentItemChanged(self, item): item.activate() def changed(self): """Call this to enable the Apply button.""" self.buttons.button(QDialogButtonBox.Apply).setEnabled(True)
class NotebookListDialog(QDialog): """ Funtions to display, create, remove, modify notebookList """ def __init__(self, parent=None): super(NotebookListDialog, self).__init__(parent) self.notebookList = QListWidget() self.moveUp = QPushButton('<<') self.moveDown = QPushButton('>>') self.add = QPushButton('Add') self.remove = QPushButton('Remove') self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(False) layout = QGridLayout() layout.addWidget(self.notebookList, 0, 0, 4, 6) layout.addWidget(self.moveUp, 1, 6) layout.addWidget(self.moveDown, 2, 6) layout.addWidget(self.add, 4, 0) layout.addWidget(self.remove, 4, 1) layout.addWidget(self.buttonBox, 4, 5, 1, 2) self.setLayout(layout) self.notebookList.setItemDelegate(ListDelegate(self.notebookList)) self.notebookList.currentRowChanged.connect(self.updateUi) self.add.clicked.connect(self.actionAdd) self.remove.clicked.connect(self.actionRemove) self.moveUp.clicked.connect(self.moveItemUp) self.moveDown.clicked.connect(self.moveItemDown) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.initList() def initList(self): self.notebookList.clear() notebooks = Mikibook.read() for nb in notebooks: item = QListWidgetItem() item.setData(Qt.DisplayRole, nb[0]) item.setData(Qt.UserRole, nb[1]) self.notebookList.addItem(item) self.updateUi(len(notebooks) != 0) self.notebookList.setCurrentRow(0) # QListWidgetItem(nb, self.notebookList) def updateUi(self, row): flag = (row != -1) self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(flag) self.remove.setEnabled(flag) self.moveUp.setEnabled(flag) self.moveDown.setEnabled(flag) def actionAdd(self): Mikibook.create() self.initList() count = self.notebookList.count() self.notebookList.setCurrentRow(count-1) def actionRemove(self): item = self.notebookList.currentItem() row = self.notebookList.currentRow() name = item.data(Qt.DisplayRole) path = item.data(Qt.UserRole) self.notebookList.takeItem(row) Mikibook.remove(name, path) def moveItemUp(self): item = self.notebookList.currentItem() row = self.notebookList.currentRow() if row != 0: # self.notebookList.removeItemWidget(item) self.notebookList.takeItem(row) self.notebookList.insertItem(row-1, item) self.notebookList.setCurrentRow(row-1) def moveItemDown(self): item = self.notebookList.currentItem() row = self.notebookList.currentRow() count = self.notebookList.count() if row != count-1: self.notebookList.takeItem(row) self.notebookList.insertItem(row+1, item) self.notebookList.setCurrentRow(row+1) def accept(self): notebookPath = self.notebookList.currentItem().data(Qt.UserRole) notebookName = self.notebookList.currentItem().data(Qt.DisplayRole) settings = Setting([[notebookName, notebookPath]]) window = mikidown.MikiWindow(settings) window.show() count = self.notebookList.count() notebooks = [] for i in range(count): name = self.notebookList.item(i).data(Qt.DisplayRole) path = self.notebookList.item(i).data(Qt.UserRole) notebooks.append([name, path]) Mikibook.write(notebooks) QDialog.accept(self)