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 ErrorsWidget(QWidget): def __init__(self): QWidget.__init__(self) self.pep8 = None self._outRefresh = True vbox = QVBoxLayout(self) self.listErrors = QListWidget() self.listPep8 = QListWidget() self.errorsLabel = QLabel(self.tr(ERRORS_TEXT).arg(0)) vbox.addWidget(self.errorsLabel) vbox.addWidget(self.listErrors) self.pep8Label = QLabel(self.tr(PEP8_TEXT).arg(0)) vbox.addWidget(self.pep8Label) vbox.addWidget(self.listPep8) self.connect(self.listErrors, SIGNAL("itemSelectionChanged()"), self.errors_selected) self.connect(self.listPep8, SIGNAL("itemSelectionChanged()"), self.pep8_selected) def errors_selected(self): editorWidget = main_container.MainContainer().get_actual_editor() if editorWidget and self._outRefresh: lineno = self.listErrors.currentItem().data(Qt.UserRole).toInt()[0] editorWidget.jump_to_line(lineno) editorWidget.setFocus() def pep8_selected(self): editorWidget = main_container.MainContainer().get_actual_editor() if editorWidget and self._outRefresh: lineno = self.listPep8.currentItem().data(Qt.UserRole).toInt()[0] editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_lists(self, errors, pep8): self._outRefresh = False self.listErrors.clear() self.listPep8.clear() for lineno in errors.errorsSummary: linenostr = 'L%s\t' % str(lineno + 1) for data in errors.errorsSummary[lineno]: item = QListWidgetItem(linenostr + data) item.setToolTip(linenostr + data) item.setData(Qt.UserRole, lineno) self.listErrors.addItem(item) self.errorsLabel.setText(self.tr(ERRORS_TEXT).arg( len(errors.errorsSummary))) for lineno in pep8.pep8checks: linenostr = 'L%s\t' % str(lineno + 1) for data in pep8.pep8checks[lineno]: item = QListWidgetItem(linenostr + data.split('\n')[0]) item.setToolTip(linenostr + data.split('\n')[0]) item.setData(Qt.UserRole, lineno) self.listPep8.addItem(item) self.pep8Label.setText(self.tr(PEP8_TEXT).arg( len(pep8.pep8checks))) self._outRefresh = True
class ProfilesLoader(QDialog): def __init__(self, load_func, profiles, parent=None): QDialog.__init__(self, parent, Qt.Dialog) self.setMinimumWidth(400) self._profiles = profiles self.load_function = load_func vbox = QVBoxLayout(self) self.profileList = QListWidget() self.profileList.addItems([key for key in profiles]) self.contentList = QListWidget() self.contentList.setSortingEnabled(True) self.btnDelete = QPushButton(self.tr("Delete Profile")) self.btnDelete.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.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.btnDelete, SIGNAL("clicked()"), self.delete_profile) def load_profile_content(self): item = self.profileList.currentItem() self.contentList.clear() key = unicode(item.text()) content = self._profiles[key] self.contentList.addItems(content) def open_profile(self): if self.profileList.currentItem(): key = unicode(self.profileList.currentItem().text()) self.load_function(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 ErrorsWidget(QWidget): def __init__(self): QWidget.__init__(self) self.pep8 = None self._outRefresh = True vbox = QVBoxLayout(self) self.listErrors = QListWidget() self.listPep8 = QListWidget() self.errorsLabel = QLabel(self.tr(ERRORS_TEXT).arg(0)) vbox.addWidget(self.errorsLabel) vbox.addWidget(self.listErrors) self.pep8Label = QLabel(self.tr(PEP8_TEXT).arg(0)) vbox.addWidget(self.pep8Label) vbox.addWidget(self.listPep8) self.connect(self.listErrors, SIGNAL("itemSelectionChanged()"), self.errors_selected) self.connect(self.listPep8, SIGNAL("itemSelectionChanged()"), self.pep8_selected) def errors_selected(self): editorWidget = main_container.MainContainer().get_actual_editor() if editorWidget and self._outRefresh: index = self.listErrors.currentItem().data(Qt.UserRole).toInt()[0] editorWidget.jump_to_line(editorWidget.errors.errorsLines[index] - 1) editorWidget.setFocus() def pep8_selected(self): editorWidget = main_container.MainContainer().get_actual_editor() if editorWidget and self._outRefresh: index = self.listPep8.currentItem().data(Qt.UserRole).toInt()[0] editorWidget.jump_to_line(editorWidget.pep8.pep8lines[index] - 1) editorWidget.setFocus() def refresh_lists(self, errors, pep8): self._outRefresh = False self.listErrors.clear() self.listPep8.clear() for index, data in enumerate(errors.errorsLines): item = QListWidgetItem(errors.errorsSummary[data]) item.setData(Qt.UserRole, index) self.listErrors.addItem(item) self.errorsLabel.setText(self.tr(ERRORS_TEXT).arg(len(errors.errorsLines))) for index, data in enumerate(pep8.pep8checks): item = QListWidgetItem(data.split("\n")[0]) item.setData(Qt.UserRole, index) self.listPep8.addItem(item) self.pep8Label.setText(self.tr(PEP8_TEXT).arg(len(pep8.pep8checks))) self._outRefresh = True
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 FinishPage(QWizardPage): def __init__(self): super(FinishPage, self).__init__() container = QVBoxLayout(self) self.setSubTitle(self.tr("Elige una plantilla")) self.list_template = QListWidget() self.list_template.addItem(self.tr("Proyecto en blanco")) self.list_template.addItem(self.tr("Incluir achivo y función main")) container.addWidget(self.list_template) @property def template(self): selection = self.list_template.selectedItems() if not selection: self.list_template.currentItem().setSelected(True) return self.list_template.row(self.list_template.selectedItems()[0])
class ArrayWidget(QWidget, NodeWidget): data_type = "Array" two_rows = True data_class = ArrayNode def __init__(self, name, data, scheme, parent=None): QWidget.__init__(self, parent) NodeWidget.__init__(self, name, data, scheme) self.layout = QVBoxLayout(self) self.layout.setMargin(0) self.layout.setContentsMargins(0,0,0,0) self._listwidget = QListWidget(self) self.layout.addWidget(self._listwidget) hlayout = QHBoxLayout() self.layout.addLayout(hlayout) self._plus_minus_widget = PlusMinusWidget(self.create_item, self.delete_item, self) hlayout.addWidget(self._plus_minus_widget) self.element_scheme = self.scheme["ElementScheme"] self.new_data = NodeWidget.get_default_data(self.element_scheme, self.data) hlayout.addStretch(1) self.add_widget = NodeWidget.create_node_widget("__not_exist", self.new_data, self.element_scheme) hlayout.addWidget(self.add_widget) def delete_item(self): row = self._listwidget.row(self._listwidget.currentItem()) new_data = list(self.data.get()) del new_data[row] self.data.set(tuple(new_data)) def create_item(self): self.data.set(list(self.data.get())+[Node.create_node(self.new_data.get()),]) def __createItem(self, itemname): item = QListWidgetItem(itemname) # item.setFlags (Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled ) self._listwidget.addItem(item) def dump(self): pass def load(self): self._listwidget.clear() for item in self.data.get(): self.__createItem(unicode(item)) @classmethod def _get_default_data(cls, scheme, data): return ArrayNode([])
class ListWindow(QWidget): def __init__(self, parent=None): super(ListWindow, self).__init__(parent) self.listWidget = QListWidget() for i in range(1, 11): self.listWidget.addItem("Item {}".format(i)) item1 = QListWidgetItem('Text', self.listWidget) item1.setData(Qt.UserRole, 'chunk-124.xml.bz2') # self.listWidget.addItem(item1) self.listWidget.itemActivated.connect(self.printItemText) mainLayout = QHBoxLayout() mainLayout.addWidget(self.listWidget) self.setLayout(mainLayout) def printItemText(self, item): """These two are equivalent""" w = self.listWidget.currentItem() print(w.text()) print(w.data(Qt.UserRole).toPyObject())
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 DelCategoriesDlg(QDialog): def __init__(self, categories, parent=None): super(DelCategoriesDlg, self).__init__(parent) self.setWindowTitle('Address Book - Delete Categories') self.resize(302, 307) self.parent = parent self.db = self.parent.db self.categories = categories self.ListWidget = QListWidget() self.delButton = QPushButton('Delete') vlayout = pyqttools.add_to_layout(QVBoxLayout(),(self.delButton, None)) f_layout = pyqttools.add_to_layout(QHBoxLayout(), (self.ListWidget, vlayout)) self.setLayout(f_layout) self.delButton.clicked.connect(self.delete) self.fill_ListWidget() def fill_ListWidget(self): self.ListWidget.clear() self.ListWidget.addItems(self.categories) self.set_enable() def set_enable(self): self.delButton.setEnabled(bool(self.ListWidget)) def delete(self): categ = self.ListWidget.currentItem().text() categ_id = self.db.get_category_id(categ, self.parent.user) reply = QMessageBox.question(self, 'Address Book - Delete User', 'Are sou sure that you want to delete {0} and all its contacts?'\ .format(categ), QMessageBox.Yes|QMessageBox.Cancel) if reply == QMessageBox.Yes: self.db.delete_category(categ_id) self.categories.remove(categ) self.fill_ListWidget()
class CompleterWidget(QCompleter): def __init__(self, editor): QCompleter.__init__(self) self.setWidget(editor) self.popupView = QListWidget() self.popupView.setAlternatingRowColors(True) self.popupView.setWordWrap(False) self.setPopup(self.popupView) self.setCompletionMode(QCompleter.PopupCompletion) self.setCaseSensitivity(Qt.CaseInsensitive) self.connect(self.popupView, SIGNAL("itemClicked(QListWidgetItem*)"), self.insert_completion) def insert_completion(self): insert = self.popupView.currentItem().text() extra = insert.length() - self.completionPrefix().length() self.widget().textCursor().insertText(insert.right(extra)) self.popup().hide() def complete(self, cr, results): self.popupView.clear() model = self.obtain_model_items(results) self.setModel(model) self.popup().setCurrentIndex(model.index(0, 0)) cr.setWidth(self.popup().sizeHintForColumn(0) \ + self.popup().verticalScrollBar().sizeHint().width() + 10) self.popupView.updateGeometries() QCompleter.complete(self, cr) def obtain_model_items(self, proposals): proposals.sort() for p in proposals: self.popupView.addItem(QListWidgetItem(p)) return self.popupView.model()
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 MigrationWidget(QWidget): def __init__(self): super(MigrationWidget, self).__init__() self._migration = {} vbox = QVBoxLayout(self) lbl_title = QLabel(self.tr("Current code:")) self.current_list = QListWidget() lbl_suggestion = QLabel(self.tr("Suggested changes:")) self.suggestion = QPlainTextEdit() self.suggestion.setReadOnly(True) self.btn_apply = QPushButton(self.tr("Apply change!")) hbox = QHBoxLayout() hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox.addWidget(self.btn_apply) vbox.addWidget(lbl_title) vbox.addWidget(self.current_list) vbox.addWidget(lbl_suggestion) vbox.addWidget(self.suggestion) vbox.addLayout(hbox) self.connect(self.current_list, SIGNAL("itemClicked(QListWidgetItem*)"), self.load_suggestion) self.connect(self.btn_apply, SIGNAL("clicked()"), self.apply_changes) def apply_changes(self): lineno = int(self.current_list.currentItem().data(Qt.UserRole)) lines = self._migration.migration_data[lineno][0].split('\n') remove = -1 code = '' for line in lines: if line.startswith('-'): remove += 1 elif line.startswith('+'): code += '%s\n' % line[1:] main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_actual_editor() block_start = editorWidget.document().findBlockByLineNumber(lineno) block_end = editorWidget.document().findBlockByLineNumber( lineno + remove) cursor = editorWidget.textCursor() cursor.setPosition(block_start.position()) cursor.setPosition(block_end.position(), QTextCursor.KeepAnchor) cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor) cursor.insertText(code[:-1]) def load_suggestion(self, item): lineno = int(item.data(Qt.UserRole)) lines = self._migration.migration_data[lineno][0].split('\n') code = '' for line in lines: if line.startswith('+'): code += '%s\n' % line[1:] self.suggestion.setPlainText(code) main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_actual_editor() if editorWidget: editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_lists(self, migration): self._migration = migration self.current_list.clear() base_lineno = -1 for lineno in sorted(migration.migration_data.keys()): linenostr = 'L%s\n' % str(lineno + 1) data = migration.migration_data[lineno] lines = data[0].split('\n') if base_lineno == data[1]: continue base_lineno = data[1] message = '' for line in lines: if line.startswith('-'): message += '%s\n' % line item = QListWidgetItem(linenostr + message) item.setToolTip(linenostr + message) item.setData(Qt.UserRole, lineno) self.current_list.addItem(item) def clear(self): """ Clear the widget """ self.current_list.clear() self.suggestion.clear()
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 ErrorsWidget(QWidget): ############################################################################### # ERRORS WIDGET SIGNALS ############################################################################### """ pep8Activated(bool) lintActivated(bool) """ ############################################################################### def __init__(self): super(ErrorsWidget, self).__init__() self.pep8 = None self._outRefresh = True vbox = QVBoxLayout(self) self.listErrors = QListWidget() self.listErrors.setSortingEnabled(True) self.listPep8 = QListWidget() self.listPep8.setSortingEnabled(True) hbox_lint = QHBoxLayout() if settings.FIND_ERRORS: self.btn_lint_activate = QPushButton(self.tr("Lint: ON")) else: self.btn_lint_activate = QPushButton(self.tr("Lint: OFF")) self.errorsLabel = QLabel(self.tr("Static Errors: %s") % 0) hbox_lint.addWidget(self.errorsLabel) hbox_lint.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_lint.addWidget(self.btn_lint_activate) vbox.addLayout(hbox_lint) vbox.addWidget(self.listErrors) hbox_pep8 = QHBoxLayout() if settings.CHECK_STYLE: self.btn_pep8_activate = QPushButton(self.tr("PEP8: ON")) else: self.btn_pep8_activate = QPushButton(self.tr("PEP8: OFF")) self.pep8Label = QLabel(self.tr("PEP8 Errors: %s") % 0) hbox_pep8.addWidget(self.pep8Label) hbox_pep8.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_pep8.addWidget(self.btn_pep8_activate) vbox.addLayout(hbox_pep8) vbox.addWidget(self.listPep8) self.connect(self.listErrors, SIGNAL("itemSelectionChanged()"), self.errors_selected) self.connect(self.listPep8, SIGNAL("itemSelectionChanged()"), self.pep8_selected) self.connect(self.btn_lint_activate, SIGNAL("clicked()"), self._turn_on_off_lint) self.connect(self.btn_pep8_activate, SIGNAL("clicked()"), self._turn_on_off_pep8) IDE.register_service('tab_errors', self) ExplorerContainer.register_tab(translations.TR_TAB_ERRORS, self) def _turn_on_off_lint(self): """Change the status of the lint checker state.""" settings.FIND_ERRORS = not settings.FIND_ERRORS if settings.FIND_ERRORS: self.btn_lint_activate.setText(self.tr("Lint: ON")) else: self.btn_lint_activate.setText(self.tr("Lint: OFF")) self.emit(SIGNAL("lintActivated(bool)"), settings.FIND_ERRORS) def _turn_on_off_pep8(self): """Change the status of the lint checker state.""" settings.CHECK_STYLE = not settings.CHECK_STYLE if settings.CHECK_STYLE: self.btn_pep8_activate.setText(self.tr("PEP8: ON")) else: self.btn_pep8_activate.setText(self.tr("PEP8: OFF")) self.emit(SIGNAL("pep8Activated(bool)"), settings.CHECK_STYLE) def errors_selected(self): main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() if editorWidget and self._outRefresh: lineno = int(self.listErrors.currentItem().data(Qt.UserRole)) editorWidget.jump_to_line(lineno) editorWidget.setFocus() def pep8_selected(self): main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() if editorWidget and self._outRefresh: lineno = int(self.listPep8.currentItem().data(Qt.UserRole)) editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_pep8_list(self, pep8): self._outRefresh = False self.listPep8.clear() for lineno in pep8: linenostr = 'L%s\t' % str(lineno + 1) for data in pep8[lineno]: item = QListWidgetItem(linenostr + data.split('\n')[0]) item.setToolTip(linenostr + data.split('\n')[0]) item.setData(Qt.UserRole, lineno) self.listPep8.addItem(item) self.pep8Label.setText(self.tr("PEP8 Errors: %s") % len(pep8)) self._outRefresh = True def refresh_error_list(self, errors): self._outRefresh = False self.listErrors.clear() for lineno in errors: linenostr = 'L%s\t' % str(lineno + 1) for data in errors[lineno]: item = QListWidgetItem(linenostr + data) item.setToolTip(linenostr + data) item.setData(Qt.UserRole, lineno) self.listErrors.addItem(item) self.errorsLabel.setText(self.tr("Static Errors: %s") % len(errors)) self._outRefresh = True def clear(self): """ Clear the widget """ self.listErrors.clear() self.listPep8.clear()
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 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 BookKeeping(QFrame): # ======================================================================= def __init__(self, parent=None, _PARENT=None): # ------------------------------------------------------------------- QFrame.__init__(self, parent); # ------------------------------------------------------------------- self.PARENT = _PARENT; self.CONF = _PARENT.CONF; #self.SHA256 = hashlib.sha256; #UID_SHA256 = self.SHA256( str(time.time()) ).hexdigest(); self.SELECTED_BKKPG_UID = None; # ------------------------------------------------------------------- self.setGeometry( 3, 5, 975, 555 ); self.setStyleSheet( "QFrame{ font: 12px 'monospace'; color: #000; background-color: transparent; background-image: url('./data/imgs/TAB_BookKeeping.png'); }" ); self.PAIR_COMBO = QComboBox( self); self.PAIR_COMBO.setGeometry( 86, 20, 108, 44 ); self.connect( self.PAIR_COMBO, SIGNAL('currentIndexChanged(int)'), self.CREATE_LISTS ); #self.PAIR_COMBO.setStyleSheet( "QComboBox{ font: 16px 'monospace'; background-color: #333; color: #FFF; border-style: solid; border-width: 1px; border-color: #000; border-radius: none; }" ); self.PAIR_COMBO.setEditable(False); """ #self.PAIR_COMBO.setItemIcon( 0, QIcon("./data/imgs/500.png") ); print(self.PAIR_COMBO.__len__()); #set at tooltip combo.setItemData(0,"a tooltip",Qt.ToolTipRole) # set the Font Color combo.setItemData(0,QColor("#FF333D"), Qt.BackgroundColorRole) #set the font combo.setItemData(0, QtGui.QFont('Verdana', bold=True), Qt.FontRole) """ # ------------------------------------------------------------------- list_style = "QListWidget{ font: 10px 'monospace'; color: #fff; background-color: #000; border-style: none; background-image: url('./data/imgs/TAB_BookKeeping_line.png'); }"; # ./data/imgs/BookKeeping_line.png lable_style = "QLabel{ font: 10px 'monospace'; color: #fff; background-color: transparent; border-style: none; background-image: url(''); }"; # ------------------------------------------------------------------- self.DATA_TO_SEND = None; self._i_ = "|"; # List delimiter self.CALCULATE_ONLY_COMPLETED = True; self.DATA_TO_SEND_SELECTED = False; # ------------------------------------------------------------------- self.BOOKKEEPING_WIDGET = QListWidget( self ); self.BOOKKEEPING_WIDGET.setGeometry( 13, 144, 949, 259 ); self.BOOKKEEPING_WIDGET.setStyleSheet( list_style ); self.connect( self.BOOKKEEPING_WIDGET, SIGNAL('itemSelectionChanged()'), lambda: self.SEND_VALUES_TO_TRADE_TERMINAL("SOLD_WIDGET") ); self.BOOKKEEPING_WIDGET.itemClicked.connect( lambda: self.SEND_VALUES_TO_TRADE_TERMINAL("SELECT_VALUES") ); self.BOUGHT_TTL_LABLE = QLabel("0.0", self); self.BOUGHT_TTL_LABLE.setGeometry( 304, 406, 85, 17 ); #self.BOUGHT_TTL_LABLE.setEditable( False ); self.BOUGHT_TTL_LABLE.setStyleSheet( lable_style ); self.BOUGHT_TTL = 0; self.BOUGHT_TTL_PLUS_FEE_LABLE = QLabel("0.0", self); self.BOUGHT_TTL_PLUS_FEE_LABLE.setGeometry( 396, 406, 85, 17 ); #self.BOUGHT_TTL_PLUS_FEE_LABLE.setEditable( False ); self.BOUGHT_TTL_PLUS_FEE_LABLE.setStyleSheet( lable_style ); self.BOUGHT_TTL_PLUS_FEE = 0; self.SOLD_TTL_LABLE = QLabel("0.0", self); self.SOLD_TTL_LABLE.setGeometry( 694, 406, 85, 17 ); #self.SOLD_TTL_LABLE.setEditable( False ); self.SOLD_TTL_LABLE.setStyleSheet( lable_style ); self.SOLD_TTL = 0; self.SOLD_TTL_PLUS_FEE_LABLE = QLabel("0.0", self); self.SOLD_TTL_PLUS_FEE_LABLE.setGeometry( 784, 406, 85, 17 ); #self.SOLD_TTL_PLUS_FEE_LABLE.setEditable( False ); self.SOLD_TTL_PLUS_FEE_LABLE.setStyleSheet( lable_style ); self.SOLD_TTL_PLUS_FEE = 0; self.PROFIT_TTL_LABLE = QLabel("0.0", self); self.PROFIT_TTL_LABLE.setGeometry( 874, 406, 88, 17 ); #self.PROFIT_TTL_LABLE.setEditable( False ); self.PROFIT_TTL_LABLE.setStyleSheet( lable_style ); self.PROFIT_TTL = 0; # ------------------------------------------------------------------- self.SEND_ID_LABLE = QLabel("n/a", self); self.SEND_ID_LABLE.setGeometry( 18, 467, 43, 17 ); self.SEND_ID_LABLE.setStyleSheet( lable_style ); self.SEND_AMOUNT_LABLE = QLabel("n/a", self); self.SEND_AMOUNT_LABLE.setGeometry( 66, 467, 85, 17 ); self.SEND_AMOUNT_LABLE.setStyleSheet( lable_style ); self.SEND_AT_PRICE_LABLE = QLabel("n/a", self); self.SEND_AT_PRICE_LABLE.setGeometry( 156, 467, 43, 17 ); self.SEND_AT_PRICE_LABLE.setStyleSheet( lable_style ); self.SEND_VALUES_BTN = QPushButton("", self); self.SEND_VALUES_BTN.setGeometry( 60, 502, 131, 33 ); self.SEND_VALUES_BTN.setStyleSheet( "QPushButton{ background-color: transparent; border-style: none; }" ); self.connect( self.SEND_VALUES_BTN, SIGNAL('clicked()'), lambda: self.SEND_VALUES_TO_TRADE_TERMINAL("SEND_VALUES") ); # ------------------------------------------------------------------- self.ONLY_COMPLETED_CHECKBOX = QCheckBox("", self); self.ONLY_COMPLETED_CHECKBOX.setGeometry( 665, 444, 17, 17 ); self.ONLY_COMPLETED_CHECKBOX.setCheckState(Qt.Checked); #self.ONLY_COMPLETED_CHECKBOX.setEnabled(False); self.connect(self.ONLY_COMPLETED_CHECKBOX, SIGNAL('stateChanged(int)'), lambda: self.CHANGE_VALUES("only_completed") ); # ------------------------------------------------------------------- self.INIT(); # ------------------------------------------------------------------- # ======================================================================= def INIT(self): # ------------------------------------------------------------------- try: self.CREATE_PAIRS_SELECTOR(); self.CREATE_LISTS(); except Exception as _exception: print("-----------------------------------------------------"); print("[INIT]"+str(_exception)); # ------------------------------------------------------------------- # ======================================================================= def BKKPG_UID_ACTION(self, _ACTION, BKKPG_UID, _D): # ------------------------------------------------------------------- #print("_ACTION: ", _ACTION, "BKKPG_UID: ", BKKPG_UID) # ------------------------------------------------------------------- try: CURR_PAIR = str(self.PAIR_COMBO.currentText()).lower().strip(); order_id = _D[0]; unix_time = _D[1]; filled = _D[2]; amount = _D[3]; at_price = _D[4]; if _ACTION == "buy": # For CRYPTO ttl = amount; fee = ( ttl/100*self.PARENT.FEE ); elif _ACTION == "sell": # For USD ttl = amount*at_price; fee = ( ttl/100*self.PARENT.FEE ); grand_ttl = ttl-fee; # ------------------------------------------------------------------- if BKKPG_UID == "": # Is New Record TPL = "buy_order_id, buy_unix_time, buy_filled, buy_amount, buy_at_price, buy_fee, buy_ttl, buy_grand_ttl, sell_order_id, sell_unix_time, sell_filled, sell_amount, sell_at_price, sell_fee, sell_ttl, sell_grand_ttl "; _SQL = "INSERT INTO "+CURR_PAIR+"( BKKPG_UID, completed, started, "+TPL+", profit_ttl ) "; if _ACTION == "buy": _SQL += "VALUES( NULL,0,1,{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}, 0 )".format( _D[0],_D[1],_D[2],_D[3],_D[4],fee, ttl, grand_ttl, 0, 0, 0, 0, 0, 0, 0, 0 ); else: _SQL += "VALUES( NULL,0,1,{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15}, 0 )".format( 0, 0, 0, 0, 0, 0, 0, 0, _D[0], _D[1],_D[2],_D[3],_D[4],fee, ttl, grand_ttl ); self.PARENT.DB.EXEC("BOOK_DB", _SQL); else: # Existing Record # ------------------------------------------------ if filled == 1: completed = 1; _SQL = "SELECT ACT_grand_ttl from "+CURR_PAIR+" WHERE BKKPG_UID="+BKKPG_UID; if _ACTION == "buy": DATA = self.PARENT.DB.FETCH("BOOK_DB", _SQL.replace("ACT","sell"), ALL=False); profit_ttl = DATA - grand_ttl; else: DATA = self.PARENT.DB.FETCH("BOOK_DB", _SQL.replace("ACT","buy"), ALL=False); profit_ttl = grand_ttl - DATA; else: profit_ttl = 0; completed = 0; # ------------------------------------------------ A = _ACTION; _SQL = "UPDATE "+CURR_PAIR+" SET completed={0}, "+A+"_order_id={1}, "+A+"_unix_time={2}, "+A+"_filled={3}, "; _SQL += A+"_amount={4}, "+A+"_at_price={5}, "+A+"_fee={6}, "+A+"_ttl={7}, "+A+"_grand_ttl={8}"; _SQL += " WHERE BKKPG_UID="+BKKPG_UID; _SQL = _SQL.format( completed, order_id, unix_time, filled, amount, at_price, fee, ttl, grand_ttl ); self.PARENT.DB.EXEC("BOOK_DB", _SQL); except Exception as _exception: print(" BOOKKEEPING[0:0]"); print(_exception); # ------------------------------------------------------------------- """ BKKPG_UID, completed, started, buy_order_id, buy_unix_time, buy_filled, buy_amount, buy_at_price, buy_fee, buy_ttl, buy_grand_ttl, sell_order_id, sell_unix_time, sell_filled, sell_amount, sell_at_price, sell_fee, sell_ttl, sell_grand_ttl, profit_ttl """ # ------------------------------------------------------------------- # ======================================================================= def DELETE_ORDER(self, _order_id, _pair, _type): # ------------------------------------------------------------------- _SQL = "SELECT buy_order_id, sell_order_id FROM "+_pair; _SQL += " WHERE buy_order_id="+str(_order_id)+" OR sell_order_id="+str(_order_id); DATA = self.PARENT.DB.FETCH("BOOK_DB", _SQL, ALL=False); if DATA is None: pass; if _type == "buy" and DATA[1] == 0: _SQL = "DELETE FROM "+_pair+" WHERE buy_order_id="+str(_order_id)+" OR sell_order_id="+str(_order_id); self.PARENT.DB.EXEC("BOOK_DB", _SQL); self.CREATE_LISTS(); elif _type == "sell" and DATA[0] == 0: _SQL = "DELETE FROM "+_pair+" WHERE buy_order_id="+str(_order_id)+" OR sell_order_id="+str(_order_id); self.PARENT.DB.EXEC("BOOK_DB", _SQL); self.CREATE_LISTS(); else: A = _type; _SQL = "UPDATE "+self.PARENT.CURR_PAIR+" SET "; _SQL += " completed=0, "+A+"_order_id=0, "+A+"_unix_time=0, "+A+"_filled=0, "; _SQL += A+"_amount=0, "+A+"_at_price=0, "+A+"_fee=0, "+A+"_ttl=0, "+A+"_grand_ttl=0 "; _SQL += "WHERE "+A+"_order_id="+str(_order_id); self.PARENT.DB.EXEC("BOOK_DB", _SQL); # ------------------------------------------------------------------- # ======================================================================= def CREATE_LISTS(self): # ------------------------------------------------------------------- try: CURR_PAIR = str(self.PAIR_COMBO.currentText()).lower(); # ------------------------------------------------------------------- self.BOOK = { "bought" : [], "sold" : [] }; self.BOUGHT_TTL = 0; self.BOUGHT_TTL_PLUS_FEE = 0; self.SOLD_TTL = 0; self.SOLD_TTL_PLUS_FEE = 0; # ------------------------------------------------------------------- #self.PARENT.DB.EXEC( "BOOK_DB", "DELETE FROM "+CURR_PAIR+" WHERE BKKPG_UID>7" ); DATA = self.PARENT.DB.FETCH("BOOK_DB", "SELECT * FROM "+CURR_PAIR+" ORDER BY BKKPG_UID DESC", ALL=True); self.BOOKKEEPING_WIDGET.clear(); for data in DATA: # --------------------------------------------------------------- """ " "" print( data ) for d in data: print( d ) exit(); "" " """ # --------------------------------------------------------------- # In-Memory DATA BKKPG_UID = data[0] completed = data[1] started = data[2] buy_order_id = data[3] buy_unix_time = data[4] buy_filled = data[5] buy_amount = data[6] buy_at_price = data[7] #buy_fee = data[8] buy_ttl = data[9] buy_grand_ttl = data[10] sell_order_id = data[11] sell_unix_time = data[12] sell_filled = data[13] sell_amount = data[14] sell_at_price = data[15] #sell_fee = data[16] sell_ttl = data[17] sell_grand_ttl = data[18] profit_ttl = data[19] # --------------------------------------------------------------- # --------------------------------------------------------------- """ self.BOOK[ data[3] ].append( { BKKPG_UID, completed, started, buy_order_id, buy_unix_time, buy_filled, buy_amount, buy_at_price, buy_fee, buy_ttl, buy_grand_ttl, sell_order_id, sell_unix_time, sell_filled, sell_amount, sell_at_price, sell_fee, sell_ttl, sell_grand_ttl, profit_ttl } ); """ # --------------------------------------------------------------- if self.CALCULATE_ONLY_COMPLETED: if buy_filled == 1 and sell_filled == 1: self.BOUGHT_TTL += buy_ttl; self.BOUGHT_TTL_PLUS_FEE += buy_grand_ttl*buy_at_price; self.SOLD_TTL += sell_ttl; self.SOLD_TTL_PLUS_FEE += sell_grand_ttl; else: self.BOUGHT_TTL += buy_ttl; self.BOUGHT_TTL_PLUS_FEE += buy_grand_ttl*buy_at_price; self.SOLD_TTL += sell_ttl; self.SOLD_TTL_PLUS_FEE += sell_grand_ttl; self.PROFIT_TTL_LABLE.setText( "{:10,.6f}".format(self.SOLD_TTL_PLUS_FEE - self.BOUGHT_TTL_PLUS_FEE) ); # --------------------------------------------------------------- # Formating data to Display in BookKeeping Wodget item = ""; item += "DEL{:7} ".format(str( BKKPG_UID )); # id # BUY / BOUGHT item += "#{:11} DEL".format( str(buy_order_id) ); # order_id item += "{:4} DEL".format( str(buy_filled) ); # filed item += "{:13} DEL".format( str("{:10,.6f}".format( float(buy_amount) )).strip() ); # Amount item += "{:13} DEL".format( str("{:10,.6f}".format( buy_at_price )).strip() ); # at_price #item += "{:13} DEL".format( str("{:10,.6f}".format( data[7] )).strip() ); # fee #item += "{:13} DEL".format( str("{:10,.6f}".format( buy_ttl )).strip() ); # ttl item += "{:14} ".format( str("{:10,.6f}".format( buy_grand_ttl )).strip() ); # grand_ttl # SELL / SOLD item += "#{:11} DEL".format( str(sell_order_id) ); # order_id item += "{:4} DEL".format( str(sell_filled) ); # filed item += "{:13} DEL".format( str("{:10,.6f}".format( sell_amount )).strip() ); # Amount item += "{:13} DEL".format( str("{:10,.6f}".format( sell_at_price )).strip() ); # at_price #item += "{:13} DEL".format( str("{:10,.6f}".format( data[7] )).strip() ); # fee #item += "{:13} DEL".format( str("{:10,.6f}".format( sell_ttl )).strip() ); # ttl item += "{:14} ".format( str("{:10,.6f}".format( sell_grand_ttl )).strip() ); # grand_ttl # PROFIT item += "{:13}".format( str("{:10,.6f}".format( profit_ttl )).strip() ); # grand_ttl newItem = QListWidgetItem( QIcon("./data/imgs/icon_filled_status_0.png"), item.replace("DEL", self._i_), self.BOOKKEEPING_WIDGET, 0); #newItemToolTip = "Order ID: #"+str()+" Created: "+time.ctime(int(data[2])); #newItem.setToolTip(newItemToolTip); # --------------------------------------------------------------- # / for # ------------------------------------------------------------------- try: self.BOUGHT_TTL_LABLE.setText( str("{:10,.6f}".format( self.BOUGHT_TTL ).strip()) ); self.BOUGHT_TTL_PLUS_FEE_LABLE.setText( str("{:10,.6f}".format( self.BOUGHT_TTL_PLUS_FEE ).strip()) ); self.SOLD_TTL_LABLE.setText( str("{:10,.6f}".format( self.SOLD_TTL ).strip()) ); self.SOLD_TTL_PLUS_FEE_LABLE.setText( str("{:10,.6f}".format( self.SOLD_TTL_PLUS_FEE ).strip()) ); except Exception as e: print("BOOKKEEPING[3:0]"+str(e)) except Exception as _exception: print(" BOOKKEEPING[1:0]"); print(_exception); # ------------------------------------------------------------------- # ======================================================================= def RESET_BKKPG_UID(self): # ------------------------------------------------------------------- #CURR_PAIR = str(self.PAIR_COMBO.currentText()).lower(); self.PARENT.GUI.BKKPG_UID_VALUE.setText(""); self.PARENT.GUI.CONTROL_TRADINGS_BTNS("buy", "show"); self.PARENT.GUI.CONTROL_TRADINGS_BTNS("sell", "show"); # ------------------------------------------------------------------- # ======================================================================= def CHANGE_VALUES(self, _this): # ------------------------------------------------------------------- if _this == "only_completed": if self.ONLY_COMPLETED_CHECKBOX.isChecked(): self.CALCULATE_ONLY_COMPLETED = True; else: self.CALCULATE_ONLY_COMPLETED = False; # ------------------------------------------------------------------- self.CREATE_LISTS(); # ------------------------------------------------------------------- # ======================================================================= def CREATE_PAIRS_SELECTOR(self, ALL=False): # ------------------------------------------------------------------- if not ALL: for PAIR in self.CONF["API"]["PAIRS"]: self.PAIR_COMBO.addItem(PAIR.upper()); else: for PAIR in self.CONF["API"]["ALL_PAIRS"]: self.PAIR_COMBO.addItem(PAIR.upper()); for i in xrange(0, self.PAIR_COMBO.__len__()): self.PAIR_COMBO.setItemData( i, QColor("#333"),Qt.BackgroundRole ); self.PAIR_COMBO.setItemData( i, QColor("#fff"),Qt.ForegroundRole ); #self.PAIR_COMBO.setItemData( i, QFont('monospace', 16, -1, False), Qt.FontRole); # ------------------------------------------------------------------- # ======================================================================= def SEND_VALUES_TO_TRADE_TERMINAL(self, _action): # ------------------------------------------------------------------- if _action == "SELECT_VALUES": self.DATA_TO_SEND_SELECTED = True; #self.DATA_TO_SEND = [ str(item).stip() for iten in str(self.BOOKKEEPING_WIDGET.currentItem().text()).strip().split("|")]; self.DATA_TO_SEND = str(self.BOOKKEEPING_WIDGET.currentItem().text()).strip().split("|")[1].split("#")[0].strip(); elif _action == "SEND_VALUES": if self.DATA_TO_SEND_SELECTED: _SQL = "SELECT buy_order_id, sell_order_id FROM "+self.PARENT.CURR_PAIR; _SQL += " WHERE BKKPG_UID="+self.DATA_TO_SEND; DATA = self.PARENT.DB.FETCH("BOOK_DB", _SQL, ALL=False); if DATA[0] != 0 and DATA[1] != 0: self.PARENT.GUI.SHOW_QMESSAGE("info", "This UID is Full!<br> You can't add data to it enymore.<br>Bud You can delete sell and/or buy part<br/> and add new part."); return; self.PARENT.GUI.BKKPG_UID_VALUE.setText( self.DATA_TO_SEND ); self.PARENT.GUI.CONTROL_TRADINGS_BTNS("buy", "show"); self.PARENT.GUI.CONTROL_TRADINGS_BTNS("sell", "show"); self.DATA_TO_SEND_SELECTED = False; self.DATA_TO_SEND = None; # Clear Lables self.SEND_ID_LABLE.setText( "n/a" ); self.SEND_AMOUNT_LABLE.setText( "n/a" ); self.SEND_AT_PRICE_LABLE.setText( "n/a" ); if DATA[0] == 0: self.PARENT.GUI.CONTROL_TRADINGS_BTNS("sell", "hide"); else: self.PARENT.GUI.CONTROL_TRADINGS_BTNS("buy", "hide"); # Switch to Trader-Tab self.PARENT.GUI.MAIN_TABS.setCurrentIndex(0); else: self.PARENT.GUI.SHOW_QMESSAGE("info", " Select first item which one you would like<br/> send to the Trade-Terminal !"); return; # ------------------------------------------------------------------- if self.DATA_TO_SEND is not None: self.SEND_ID_LABLE.setText( self.DATA_TO_SEND );
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 ToolDialog(QDialog): def __init__(self, parent=None): logging.debug(__name__ + ': __init__') QDialog.__init__(self, parent) self.resize(600, 500) self._selectedTool = None self._processCopy = None self._configDataAccessor = None self._toolsDir = standardToolsDir self.setWindowFlags(Qt.Window) self.setWindowTitle("Apply tool...") self.fill() def fill(self): logging.debug(__name__ + ': fill') self.setLayout(QVBoxLayout()) self._splitter = QSplitter() self.layout().addWidget(self._splitter) self._toolList = QListWidget(self._splitter) self.connect(self._toolList, SIGNAL("itemSelectionChanged()"), self.toolSelected) self._properties = PropertyView(self._splitter) bottom = QHBoxLayout() self.layout().addLayout(bottom) changedir = QPushButton("&Change tools directory...") bottom.addWidget(changedir) self.connect(changedir, SIGNAL('clicked()'), self.changedir) help = QPushButton("&Help") bottom.addWidget(help) self.connect(help, SIGNAL('clicked()'), self.help) bottom.addStretch() cancel = QPushButton('&Cancel') bottom.addWidget(cancel) self.connect(cancel, SIGNAL('clicked()'), self.reject) self.ok = QPushButton("&Apply") bottom.addWidget(self.ok) self.ok.setDefault(True) self.connect(self.ok, SIGNAL('clicked()'), self.apply) def updateToolList(self): self._toolList.clear() # import all tools and register them in toolsDict toolsFiles = [ os.path.join(self._toolsDir, f) for f in os.listdir(self._toolsDir) if f.endswith(".py") and not f.startswith("_") ] self._toolsDict = {} for toolsFile in toolsFiles: pythonModule = os.path.splitext(os.path.basename(toolsFile))[0] module = imp.load_source(pythonModule, toolsFile) for name in dir(module): tool = getattr(module, name) if inspect.isclass(tool) and issubclass( tool, ConfigToolBase) and not self._toolDataAccessor.label( tool) in self._toolsDict.keys( ) and not tool == ConfigToolBase: self._toolsDict[self._toolDataAccessor.label(tool)] = tool # Show test tool #from FWCore.GuiBrowsers.editorTools import ChangeSource #self._toolsDict["ChangeSource"]=ChangeSource if len(self._toolsDict) == 0 and self._toolsDir == standardToolsDir: logging.error( __name__ + ": Could not find any PAT tools. These will be available for the ConfigEditor in a future release." ) QCoreApplication.instance().errorMessage( "Could not find any PAT tools. These will be available for the ConfigEditor in a future release." ) return for item in self._toolsDict.keys(): self._toolList.addItem(item) self._toolList.sortItems() def keyPressEvent(self, event): if event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_W: self.reject() QDialog.keyPressEvent(self, event) def tool(self): return self._selectedTool def toolSelected(self): self._selectedTool = self._toolsDict[str( self._toolList.currentItem().text())]() self._properties.setDataObject(self._selectedTool) self._properties.updateContent() def setDataAccessor(self, accessor): self._properties.setDataAccessor(accessor) self._toolDataAccessor = accessor # save process copy to undo changes during the tool dialog self._processCopy = copy.deepcopy( self._toolDataAccessor.configDataAccessor().process()) self.updateToolList() def apply(self): # allow property view to process parameter changes if not self.ok.hasFocus(): self._properties.clearFocus() self.ok.setFocus() return parameterErrors = self._toolDataAccessor.parameterErrors( self._selectedTool) if len(parameterErrors) > 0: message = "\n".join([error for error in parameterErrors]) QCoreApplication.instance().errorMessage(message) return ok = True if self._selectedTool: try: self._selectedTool.apply( self._toolDataAccessor.configDataAccessor().process()) if not self._toolDataAccessor.configDataAccessor().process( ).checkRecording(): ok = False logging.error( __name__ + ": Could not apply tool " + self._toolDataAccessor.label(self._selectedTool) + " (problem with enable recording flag) Please restart the ConfigEditor." ) QCoreApplication.instance().errorMessage( "Could not apply tool " + self._toolDataAccessor.label(self._selectedTool) + " (problem with enable recording flag) Please restart the ConfigEditor." ) except Exception as e: ok = False logging.error( __name__ + ": Could not apply tool " + self._toolDataAccessor.label(self._selectedTool) + ": " + exception_traceback()) QCoreApplication.instance().errorMessage( "Cannot apply tool " + self._toolDataAccessor.label(self._selectedTool) + " (see log file for details):\n" + str(e)) else: ok = False logging.error(__name__ + ": Could not apply tool: No tool selected.") QCoreApplication.instance().errorMessage( "Cannot apply tool: No tool selected.") # recover process copy to undo changes during the tool dialog self._toolDataAccessor.configDataAccessor().setProcess( self._processCopy) if ok: self.accept() def changedir(self): filename = QFileDialog.getExistingDirectory(self, 'Select a directory', self._toolsDir, QFileDialog.ShowDirsOnly) if not filename.isEmpty(): self._toolsDir = str(filename) self.updateToolList() def help(self): QMessageBox.about( self, 'Info', "This dialog let's you choose and configure a tool.\n 1. Select a tool on the left\n 2. Set the parameters on the right. If you hold the mouse over a parameter name a tooltip with a description of the parameter will show up.\n 3. Apply the tool. In case the tool has wrong parameters set an error message will be displayed." )
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 FieldMappingTab(QWidget, object): """Widget class for field mapping.""" def __init__(self, field_group=None, parent=None, iface=None): """Constructor.""" # Init from parent class QWidget.__init__(self, parent) # Attributes self.layer = None self.metadata = {} self.parent = parent self.iface = iface self.field_group = field_group self.setting = QSettings() # TODO(IS): Make dynamic # Main container self.main_layout = QVBoxLayout() # Inner layout self.header_layout = QHBoxLayout() self.content_layout = QHBoxLayout() self.footer_layout = QHBoxLayout() # Header self.header_label = QLabel() self.header_label.setWordWrap(True) # Content self.field_layout = QVBoxLayout() self.parameter_layout = QHBoxLayout() self.field_description = QLabel(tr('List of fields')) self.field_list = QListWidget() self.field_list.setSelectionMode(QAbstractItemView.ExtendedSelection) self.field_list.setDragDropMode(QAbstractItemView.DragDrop) self.field_list.setDefaultDropAction(Qt.MoveAction) self.field_list.setSizePolicy( QSizePolicy.Maximum, QSizePolicy.Expanding) # noinspection PyUnresolvedReferences self.field_list.itemSelectionChanged.connect(self.update_footer) # Footer self.footer_label = QLabel() # Parameters self.extra_parameters = [ (GroupSelectParameter, GroupSelectParameterWidget) ] self.parameters = [] self.parameter_container = None # Adding to layout self.header_layout.addWidget(self.header_label) self.field_layout.addWidget(self.field_description) self.field_layout.addWidget(self.field_list) self.field_layout.setSizeConstraint(QLayout.SetMaximumSize) self.content_layout.addLayout(self.field_layout) self.content_layout.addLayout(self.parameter_layout) self.footer_layout.addWidget(self.footer_label) self.main_layout.addLayout(self.header_layout) self.main_layout.addLayout(self.content_layout) self.main_layout.addLayout(self.footer_layout) self.setLayout(self.main_layout) def set_layer(self, layer, keywords=None): """Set layer and update UI accordingly. :param layer: A vector layer that has been already patched with metadata. :type layer: QgsVectorLayer :param keywords: Custom keyword for the layer. :type keywords: dict, None """ self.layer = layer if keywords is not None: self.metadata = keywords else: # Check if it has keywords if not hasattr(layer, 'keywords'): message = 'Layer {layer_name} does not have keywords.'.format( layer_name=layer.name()) raise KeywordNotFoundError(message) self.metadata = layer.keywords self.populate_parameter() def populate_field_list(self, excluded_fields=None): """Helper to add field of the layer to the list. :param excluded_fields: List of field that want to be excluded. :type excluded_fields: list """ # Populate fields list if excluded_fields is None: excluded_fields = [] self.field_list.clear() for field in self.layer.dataProvider().fields(): # Skip if it's excluded if field.name() in excluded_fields: continue # Skip if it's not number (float, int, etc) if field.type() not in qvariant_numbers: continue field_item = QListWidgetItem(self.field_list) field_item.setFlags( Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsDragEnabled) field_item.setData(Qt.UserRole, field.name()) field_item.setText(field.name()) self.field_list.addItem(field_item) def populate_parameter(self): """Helper to setup the parameter widget.""" used_fields = [] self.parameters = [] for field in self.field_group.get('fields', []): selected_option = DO_NOT_USE options = OrderedDict([ (DO_NOT_USE, { 'label': tr('Do not use'), 'value': None, 'type': STATIC, 'constraint': {} }), ]) # Example: count if field['absolute']: # Used in field options field_label = tr('Count fields') else: # Example: ratio # Used in field options field_label = tr('Ratio fields') global_default_value = get_inasafe_default_value_qsetting( self.setting, GLOBAL, field['key']) options[GLOBAL_DEFAULT] = { 'label': tr('Global default'), 'value': global_default_value, 'type': STATIC, 'constraint': {} } default_custom_value = get_inasafe_default_value_qsetting( self.setting, RECENT, field['key']) custom_value = self.metadata.get( 'inasafe_default_values', {}).get( field['key'], default_custom_value) if field['key'] in self.metadata.get( 'inasafe_default_values', {}): if custom_value == global_default_value: selected_option = GLOBAL_DEFAULT else: selected_option = CUSTOM_VALUE min_value = field['default_value'].get('min_value', 0) max_value = field['default_value'].get('max_value', 100) default_step = (max_value - min_value) / 100.0 step = field['default_value'].get('increment', default_step) options[CUSTOM_VALUE] = { 'label': tr('Custom'), 'value': custom_value, 'type': SINGLE_DYNAMIC, 'constraint': { 'min': min_value, 'max': max_value, 'step': step } } custom_fields = self.metadata.get('inasafe_fields', {}).get( field['key'], []) if field['key'] in self.metadata.get('inasafe_fields', {}): selected_option = FIELDS if isinstance(custom_fields, basestring): custom_fields = [custom_fields] options[FIELDS] = { 'label': field_label, 'value': custom_fields, 'type': MULTIPLE_DYNAMIC, 'constraint': {} } used_fields.extend(custom_fields) parameter = GroupSelectParameter() parameter.guid = field['key'] parameter.name = field['name'] parameter.options = options parameter.selected = selected_option parameter.help_text = field['help_text'] parameter.description = field['description'] self.parameters.append(parameter) self.parameter_container = ParameterContainer( parameters=self.parameters, extra_parameters=self.extra_parameters, vertical=False ) self.parameter_container.setup_ui() constraints = self.field_group.get('constraints', {}) for key, value in constraints.items(): self.parameter_container.add_validator( validators[key], kwargs=value['kwargs'], validation_message=value['message']) self.parameter_layout.addWidget(self.parameter_container) # Set move or copy if self.field_group.get('exclusive', False): # If exclusive, do not add used field. self.populate_field_list(excluded_fields=used_fields) # Use move action since it's exclusive self.field_list.setDefaultDropAction(Qt.MoveAction) # Just make sure that the signal is disconnected try: # noinspection PyUnresolvedReferences self.field_list.itemChanged.disconnect(self.drop_remove) except TypeError: pass # Set header header_text = self.field_group['description'] header_text += '\n\n' + tr( 'You can only map one field to one concept.') else: # If not exclusive, add all field. self.populate_field_list() # Use copy action since it's not exclusive self.field_list.setDefaultDropAction(Qt.CopyAction) # noinspection PyUnresolvedReferences self.field_list.itemChanged.connect( partial(self.drop_remove, field_list=self.field_list)) self.connect_drop_remove_parameter() # Set header header_text = self.field_group['description'] header_text += '\n\n' + tr( 'You can map one field to more than one concepts.') self.header_label.setText(header_text) def get_parameter_value(self): """Get parameter of the tab. :returns: Dictionary of parameters by type in this format: {'fields': {}, 'values': {}}. :rtype: dict """ try: parameters = self.parameter_container.get_parameters(True) except InvalidValidationException as e: raise OriginalValidationException(e) field_parameters = {} value_parameters = {} for parameter in parameters: if parameter.selected_option_type() in [SINGLE_DYNAMIC, STATIC]: value_parameters[parameter.guid] = parameter.value elif parameter.selected_option_type() == MULTIPLE_DYNAMIC: field_parameters[parameter.guid] = parameter.value return { 'fields': field_parameters, 'values': value_parameters } def update_footer(self): """Update footer when the field list change.""" field_item = self.field_list.currentItem() if not field_item: self.footer_label.setText('') return field_name = field_item.data(Qt.UserRole) field = self.layer.fields().field(field_name) index = self.layer.fieldNameIndex(field_name) unique_values = self.layer.uniqueValues(index) pretty_unique_values = ', '.join([str(v) for v in unique_values[:10]]) footer_text = tr('Field type: {0}\n').format(field.typeName()) footer_text += tr('Unique values: {0}').format(pretty_unique_values) self.footer_label.setText(footer_text) def connect_drop_remove_parameter(self): parameter_widgets = self.parameter_container.get_parameter_widgets() for parameter_widget in parameter_widgets: field_list = parameter_widget.widget().list_widget field_list.itemChanged.connect( partial(self.drop_remove, field_list=field_list)) @staticmethod def drop_remove(*args, **kwargs): """Action when we need to remove dropped item. :param args: Position arguments. :type args: list :param kwargs: Keywords arguments. :type kwargs: dict """ dropped_item = args[0] field_list = kwargs['field_list'] num_duplicate = 0 for i in range(field_list.count()): if dropped_item.text() == field_list.item(i).text(): num_duplicate += 1 if num_duplicate > 1: # Notes(IS): For some reason, removeItemWidget is not working. field_list.takeItem(field_list.row(dropped_item))
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 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 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 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 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 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 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 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 MigrationWidget(QWidget): def __init__(self): super(MigrationWidget, self).__init__() self._migration = {} vbox = QVBoxLayout(self) lbl_title = QLabel(self.tr("Current code:")) self.current_list = QListWidget() lbl_suggestion = QLabel(self.tr("Suggested changes:")) self.suggestion = QPlainTextEdit() self.suggestion.setReadOnly(True) self.btn_apply = QPushButton(self.tr("Apply change!")) hbox = QHBoxLayout() hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox.addWidget(self.btn_apply) vbox.addWidget(lbl_title) vbox.addWidget(self.current_list) vbox.addWidget(lbl_suggestion) vbox.addWidget(self.suggestion) vbox.addLayout(hbox) self.connect(self.current_list, SIGNAL("itemClicked(QListWidgetItem*)"), self.load_suggestion) self.connect(self.btn_apply, SIGNAL("clicked()"), self.apply_changes) def apply_changes(self): lineno = int(self.current_list.currentItem().data(Qt.UserRole)) lines = self._migration.migration_data[lineno][0].split('\n') remove = -1 code = '' for line in lines: if line.startswith('-'): remove += 1 elif line.startswith('+'): code += '%s\n' % line[1:] editorWidget = main_container.MainContainer().get_actual_editor() block_start = editorWidget.document().findBlockByLineNumber(lineno) block_end = editorWidget.document().findBlockByLineNumber(lineno + remove) cursor = editorWidget.textCursor() cursor.setPosition(block_start.position()) cursor.setPosition(block_end.position(), QTextCursor.KeepAnchor) cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor) cursor.insertText(code[:-1]) def load_suggestion(self, item): lineno = int(item.data(Qt.UserRole)) lines = self._migration.migration_data[lineno][0].split('\n') code = '' for line in lines: if line.startswith('+'): code += '%s\n' % line[1:] self.suggestion.setPlainText(code) editorWidget = main_container.MainContainer().get_actual_editor() if editorWidget: editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_lists(self, migration): self._migration = migration self.current_list.clear() base_lineno = -1 for lineno in sorted(migration.migration_data.keys()): linenostr = 'L%s\n' % str(lineno + 1) data = migration.migration_data[lineno] lines = data[0].split('\n') if base_lineno == data[1]: continue base_lineno = data[1] message = '' for line in lines: if line.startswith('-'): message += '%s\n' % line item = QListWidgetItem(linenostr + message) item.setToolTip(linenostr + message) item.setData(Qt.UserRole, lineno) self.current_list.addItem(item) def clear(self): """ Clear the widget """ self.current_list.clear() self.suggestion.clear()
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 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 ErrorsWidget(QWidget): ############################################################################### # ERRORS WIDGET SIGNALS ############################################################################### """ pep8Activated(bool) lintActivated(bool) """ ############################################################################### def __init__(self): QWidget.__init__(self) self.pep8 = None self._outRefresh = True vbox = QVBoxLayout(self) self.listErrors = QListWidget() self.listErrors.setSortingEnabled(True) self.listPep8 = QListWidget() self.listPep8.setSortingEnabled(True) hbox_lint = QHBoxLayout() if settings.FIND_ERRORS: self.btn_lint_activate = QPushButton(self.tr("Lint: ON")) else: self.btn_lint_activate = QPushButton(self.tr("Lint: OFF")) self.errorsLabel = QLabel(self.tr("Static Errors: %s") % 0) hbox_lint.addWidget(self.errorsLabel) hbox_lint.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_lint.addWidget(self.btn_lint_activate) vbox.addLayout(hbox_lint) vbox.addWidget(self.listErrors) hbox_pep8 = QHBoxLayout() if settings.CHECK_STYLE: self.btn_pep8_activate = QPushButton(self.tr("PEP8: ON")) else: self.btn_pep8_activate = QPushButton(self.tr("PEP8: OFF")) self.pep8Label = QLabel(self.tr("PEP8 Errors: %s") % 0) hbox_pep8.addWidget(self.pep8Label) hbox_pep8.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_pep8.addWidget(self.btn_pep8_activate) vbox.addLayout(hbox_pep8) vbox.addWidget(self.listPep8) self.connect(self.listErrors, SIGNAL("itemSelectionChanged()"), self.errors_selected) self.connect(self.listPep8, SIGNAL("itemSelectionChanged()"), self.pep8_selected) self.connect(self.btn_lint_activate, SIGNAL("clicked()"), self._turn_on_off_lint) self.connect(self.btn_pep8_activate, SIGNAL("clicked()"), self._turn_on_off_pep8) def _turn_on_off_lint(self): """Change the status of the lint checker state.""" settings.FIND_ERRORS = not settings.FIND_ERRORS if settings.FIND_ERRORS: self.btn_lint_activate.setText(self.tr("Lint: ON")) else: self.btn_lint_activate.setText(self.tr("Lint: OFF")) self.emit(SIGNAL("lintActivated(bool)"), settings.FIND_ERRORS) def _turn_on_off_pep8(self): """Change the status of the lint checker state.""" settings.CHECK_STYLE = not settings.CHECK_STYLE if settings.CHECK_STYLE: self.btn_pep8_activate.setText(self.tr("PEP8: ON")) else: self.btn_pep8_activate.setText(self.tr("PEP8: OFF")) self.emit(SIGNAL("pep8Activated(bool)"), settings.CHECK_STYLE) def errors_selected(self): main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_actual_editor() if editorWidget and self._outRefresh: lineno = int(self.listErrors.currentItem().data(Qt.UserRole)) editorWidget.jump_to_line(lineno) editorWidget.setFocus() def pep8_selected(self): main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_actual_editor() if editorWidget and self._outRefresh: lineno = int(self.listPep8.currentItem().data(Qt.UserRole)) editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_lists(self, errors, pep8): self._outRefresh = False self.listErrors.clear() self.listPep8.clear() for lineno in errors.errorsSummary: linenostr = 'L%s\t' % str(lineno + 1) for data in errors.errorsSummary[lineno]: item = QListWidgetItem(linenostr + data) item.setToolTip(linenostr + data) item.setData(Qt.UserRole, lineno) self.listErrors.addItem(item) self.errorsLabel.setText( self.tr("Static Errors: %s") % len(errors.errorsSummary)) for lineno in pep8.pep8checks: linenostr = 'L%s\t' % str(lineno + 1) for data in pep8.pep8checks[lineno]: item = QListWidgetItem(linenostr + data.split('\n')[0]) item.setToolTip(linenostr + data.split('\n')[0]) item.setData(Qt.UserRole, lineno) self.listPep8.addItem(item) self.pep8Label.setText( self.tr("PEP8 Errors: %s") % len(pep8.pep8checks)) self._outRefresh = True def clear(self): """ Clear the widget """ self.listErrors.clear() self.listPep8.clear()
class ErrorsWidget(QDialog): ############################################################################### # ERRORS WIDGET SIGNALS ############################################################################### """ pep8Activated(bool) lintActivated(bool) """ ############################################################################### def __init__(self, parent=None): super(ErrorsWidget, self).__init__(parent, Qt.WindowStaysOnTopHint) self.pep8 = None self._outRefresh = True vbox = QVBoxLayout(self) self.listErrors = QListWidget() self.listErrors.setSortingEnabled(True) self.listPep8 = QListWidget() self.listPep8.setSortingEnabled(True) hbox_lint = QHBoxLayout() if settings.FIND_ERRORS: self.btn_lint_activate = QPushButton(self.tr("Lint: ON")) else: self.btn_lint_activate = QPushButton(self.tr("Lint: OFF")) self.errorsLabel = QLabel(self.tr("Static Errors: %s") % 0) hbox_lint.addWidget(self.errorsLabel) hbox_lint.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_lint.addWidget(self.btn_lint_activate) vbox.addLayout(hbox_lint) vbox.addWidget(self.listErrors) hbox_pep8 = QHBoxLayout() if settings.CHECK_STYLE: self.btn_pep8_activate = QPushButton(self.tr("PEP8: ON")) else: self.btn_pep8_activate = QPushButton(self.tr("PEP8: OFF")) self.pep8Label = QLabel(self.tr("PEP8 Errors: %s") % 0) hbox_pep8.addWidget(self.pep8Label) hbox_pep8.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox_pep8.addWidget(self.btn_pep8_activate) vbox.addLayout(hbox_pep8) vbox.addWidget(self.listPep8) self.connect(self.listErrors, SIGNAL("itemSelectionChanged()"), self.errors_selected) self.connect(self.listPep8, SIGNAL("itemSelectionChanged()"), self.pep8_selected) self.connect(self.btn_lint_activate, SIGNAL("clicked()"), self._turn_on_off_lint) self.connect(self.btn_pep8_activate, SIGNAL("clicked()"), self._turn_on_off_pep8) IDE.register_service('tab_errors', self) ExplorerContainer.register_tab(translations.TR_TAB_ERRORS, self) def install_tab(self): ide = IDE.get_service('ide') self.connect(ide, SIGNAL("goingDown()"), self.close) def _turn_on_off_lint(self): """Change the status of the lint checker state.""" settings.FIND_ERRORS = not settings.FIND_ERRORS if settings.FIND_ERRORS: self.btn_lint_activate.setText(self.tr("Lint: ON")) self.listErrors.show() else: self.btn_lint_activate.setText(self.tr("Lint: OFF")) self.listErrors.hide() self.emit(SIGNAL("lintActivated(bool)"), settings.FIND_ERRORS) def _turn_on_off_pep8(self): """Change the status of the lint checker state.""" settings.CHECK_STYLE = not settings.CHECK_STYLE if settings.CHECK_STYLE: self.btn_pep8_activate.setText(self.tr("PEP8: ON")) self.listPep8.show() else: self.btn_pep8_activate.setText(self.tr("PEP8: OFF")) self.listPep8.hide() self.emit(SIGNAL("pep8Activated(bool)"), settings.CHECK_STYLE) def errors_selected(self): main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() if editorWidget and self._outRefresh: lineno = int(self.listErrors.currentItem().data(Qt.UserRole)) editorWidget.jump_to_line(lineno) editorWidget.setFocus() def pep8_selected(self): main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() if editorWidget and self._outRefresh: lineno = int(self.listPep8.currentItem().data(Qt.UserRole)) editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_pep8_list(self, pep8): self._outRefresh = False self.listPep8.clear() for lineno in pep8: linenostr = 'L%s\t' % str(lineno + 1) for data in pep8[lineno]: item = QListWidgetItem(linenostr + data.split('\n')[0]) item.setToolTip(linenostr + data.split('\n')[0]) item.setData(Qt.UserRole, lineno) self.listPep8.addItem(item) self.pep8Label.setText(self.tr("PEP8 Errors: %s") % len(pep8)) self._outRefresh = True def refresh_error_list(self, errors): self._outRefresh = False self.listErrors.clear() for lineno in errors: linenostr = 'L%s\t' % str(lineno + 1) for data in errors[lineno]: item = QListWidgetItem(linenostr + data) item.setToolTip(linenostr + data) item.setData(Qt.UserRole, lineno) self.listErrors.addItem(item) self.errorsLabel.setText(self.tr("Static Errors: %s") % len(errors)) self._outRefresh = True def clear(self): """ Clear the widget """ self.listErrors.clear() self.listPep8.clear() def reject(self): if self.parent() is None: self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self) def closeEvent(self, event): self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self) event.ignore()
class MigrationWidget(QDialog): def __init__(self, parent=None): super(MigrationWidget, self).__init__(parent, Qt.WindowStaysOnTopHint) self._migration = {} vbox = QVBoxLayout(self) lbl_title = QLabel(self.tr("Current code:")) self.current_list = QListWidget() lbl_suggestion = QLabel(self.tr("Suggested changes:")) self.suggestion = QPlainTextEdit() self.suggestion.setReadOnly(True) self.btn_apply = QPushButton(self.tr("Apply change!")) hbox = QHBoxLayout() hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox.addWidget(self.btn_apply) vbox.addWidget(lbl_title) vbox.addWidget(self.current_list) vbox.addWidget(lbl_suggestion) vbox.addWidget(self.suggestion) vbox.addLayout(hbox) self.connect(self.current_list, SIGNAL("itemClicked(QListWidgetItem*)"), self.load_suggestion) self.connect(self.btn_apply, SIGNAL("clicked()"), self.apply_changes) IDE.register_service('tab_migration', self) ExplorerContainer.register_tab(translations.TR_TAB_MIGRATION, self) def install_tab(self): ide = IDE.get_service('ide') self.connect(ide, SIGNAL("goingDown()"), self.close) def apply_changes(self): lineno = int(self.current_list.currentItem().data(Qt.UserRole)) lines = self._migration[lineno][0].split('\n') remove = -1 code = '' for line in lines: if line.startswith('-'): remove += 1 elif line.startswith('+'): code += '%s\n' % line[1:] main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() block_start = editorWidget.document().findBlockByLineNumber(lineno) block_end = editorWidget.document().findBlockByLineNumber(lineno + remove) cursor = editorWidget.textCursor() cursor.setPosition(block_start.position()) cursor.setPosition(block_end.position(), QTextCursor.KeepAnchor) cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor) cursor.insertText(code[:-1]) def load_suggestion(self, item): lineno = int(item.data(Qt.UserRole)) lines = self._migration[lineno][0].split('\n') code = '' for line in lines: if line.startswith('+'): code += '%s\n' % line[1:] self.suggestion.setPlainText(code) main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() if editorWidget: editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_lists(self, migration): self._migration = migration self.current_list.clear() base_lineno = -1 for lineno in sorted(migration.keys()): linenostr = 'L%s\n' % str(lineno + 1) data = migration[lineno] lines = data[0].split('\n') if base_lineno == data[1]: continue base_lineno = data[1] message = '' for line in lines: if line.startswith('-'): message += '%s\n' % line item = QListWidgetItem(linenostr + message) item.setToolTip(linenostr + message) item.setData(Qt.UserRole, lineno) self.current_list.addItem(item) def clear(self): """ Clear the widget """ self.current_list.clear() self.suggestion.clear() def reject(self): if self.parent() is None: self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self) def closeEvent(self, event): self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self) event.ignore()
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 MigrationWidget(QDialog): """2to3 Migration Assistance Widget Class""" def __init__(self, parent=None): super(MigrationWidget, self).__init__(parent, Qt.WindowStaysOnTopHint) self._migration, vbox, hbox = {}, QVBoxLayout(self), QHBoxLayout() lbl_title = QLabel(translations.TR_CURRENT_CODE) lbl_suggestion = QLabel(translations.TR_SUGGESTED_CHANGES) self.current_list, self.suggestion = QListWidget(), QPlainTextEdit() self.suggestion.setReadOnly(True) self.btn_apply = QPushButton(translations.TR_APPLY_CHANGES + " !") self.suggestion.setToolTip(translations.TR_SAVE_BEFORE_APPLY + " !") self.btn_apply.setToolTip(translations.TR_SAVE_BEFORE_APPLY + " !") # pack up all widgets hbox.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) hbox.addWidget(self.btn_apply) vbox.addWidget(lbl_title) vbox.addWidget(self.current_list) vbox.addWidget(lbl_suggestion) vbox.addWidget(self.suggestion) vbox.addLayout(hbox) # connections self.connect(self.current_list, SIGNAL("itemClicked(QListWidgetItem*)"), self.load_suggestion) self.connect(self.btn_apply, SIGNAL("clicked()"), self.apply_changes) # registers IDE.register_service('tab_migration', self) ExplorerContainer.register_tab(translations.TR_TAB_MIGRATION, self) def install_tab(self): """Install the Tab on the IDE.""" ide = IDE.get_service('ide') self.connect(ide, SIGNAL("goingDown()"), self.close) def apply_changes(self): """Apply the suggested changes on the Python code.""" lineno = int(self.current_list.currentItem().data(Qt.UserRole)) lines = self._migration[lineno][0].split('\n') remove, code = -1, "" for line in lines: if line.startswith('-'): remove += 1 # line to remove elif line.startswith('+'): code += '{line_to_add}\n'.format(line_to_add=line[1:]) # get and apply changes on editor main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() position = editorWidget.SendScintilla( editorWidget.SCI_POSITIONFROMLINE, lineno) curpos = editorWidget.SendScintilla(editorWidget.SCI_GETCURRENTPOS) if curpos != position: editorWidget.SendScintilla(editorWidget.SCI_GOTOPOS, position) endpos = editorWidget.SendScintilla( editorWidget.SCI_GETLINEENDPOSITION, lineno) editorWidget.SendScintilla(editorWidget.SCI_SETCURRENTPOS, endpos) editorWidget.replaceSelectedText(code[:-1]) def load_suggestion(self, item): """Take an argument item and load the suggestion.""" lineno, code = int(item.data(Qt.UserRole)), "" lines = self._migration[lineno][0].split('\n') for line in lines: if line.startswith('+'): code += '{line_to_add}\n'.format(line_to_add=line[1:]) self.suggestion.setPlainText(code) main_container = IDE.get_service('main_container') if main_container: editorWidget = main_container.get_current_editor() if editorWidget: editorWidget.jump_to_line(lineno) editorWidget.setFocus() def refresh_lists(self, migration): """Refresh the list of code suggestions.""" self._migration, base_lineno = migration, -1 self.current_list.clear() for lineno in sorted(migration.keys()): linenostr = 'L{line_number}\n'.format(line_number=str(lineno + 1)) data = migration[lineno] lines = data[0].split('\n') if base_lineno == data[1]: continue base_lineno = data[1] message = '' for line in lines: if line.startswith('-'): message += '{line_to_load}\n'.format(line_to_load=line) item = QListWidgetItem(linenostr + message) item.setToolTip(linenostr + message) item.setData(Qt.UserRole, lineno) self.current_list.addItem(item) def clear(self): """Clear the widget.""" self.current_list.clear() self.suggestion.clear() def reject(self): """Reject""" if self.parent() is None: self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self) def closeEvent(self, event): """Close""" self.emit(SIGNAL("dockWidget(PyQt_PyObject)"), self) event.ignore()
class OrdersWidget(QFrame): # ======================================================================= def __init__(self, parent=None, _PARENT=None): # ------------------------------------------------------------------- QFrame.__init__(self, parent) # ------------------------------------------------------------------- self.setGeometry(3, 5, 968, 555) self.setStyleSheet( "QFrame{ color: #fff; background-image: url('./data/imgs/TAB_Orders.png'); }" ) # ------------------------------------------------------------------- self.PARENT = _PARENT self.CONF = _PARENT.CONF self.ORDER_ID_TO_CANCEL = False self.ORDER_TYPE_TO_CANCEL = False # buy/sell to be able delete records from bookkeeping separatly self.ORDERS_FROM_DB = {} # ------------------------------------------------------------------- WIDGETS_W = 469 WIDGETS_H = 325 WIDGETS_ML = 13 WIDGETS_MT = 144 list_style = "QListWidget{ font: 10px 'monospace'; color: #fff; background-color: #000; border-style: none; background-image: url('./data/imgs/TAB_Orders_line.png'); }" # BUY self.ORDERS_LIST_BUY = QListWidget(self) self.ORDERS_LIST_BUY.setGeometry(WIDGETS_ML, WIDGETS_MT, WIDGETS_W, WIDGETS_H) self.ORDERS_LIST_BUY.setStyleSheet(list_style) self.ORDERS_LIST_BUY.setViewMode(QListView.ListMode) self.connect(self.ORDERS_LIST_BUY, SIGNAL('itemSelectionChanged()'), lambda: self.SELECT_ORDER_ID("buy")) self.ORDERS_LIST_BUY.itemClicked.connect( lambda: self.SELECT_ORDER_ID("buy")) # SELL self.ORDERS_LIST_SELL = QListWidget(self) self.ORDERS_LIST_SELL.setGeometry(WIDGETS_W + (WIDGETS_ML * 2) - 1, WIDGETS_MT, WIDGETS_W - 1, WIDGETS_H) self.ORDERS_LIST_SELL.setStyleSheet(list_style) self.connect(self.ORDERS_LIST_SELL, SIGNAL('itemSelectionChanged()'), lambda: self.SELECT_ORDER_ID("sell")) self.ORDERS_LIST_SELL.itemClicked.connect( lambda: self.SELECT_ORDER_ID("sell")) # ------------------------------------------------------------------- self.CANCEL_ORDER_BTN = QPushButton("Apply", self) self.CANCEL_ORDER_BTN.setGeometry(555, 506, 80, 30) self._i_ = "|" # List delimiter # ------------------------------------------------------------------- self.INIT() # ------------------------------------------------------------------- # ======================================================================= def INIT(self): # ------------------------------------------------------------------- self.GET_ORDERS_FROM_DB() # ------------------------------------------------------------------- # ======================================================================= def SELECT_ORDER_ID(self, _type): # ------------------------------------------------------------------- try: self.ORDER_TYPE_TO_CANCEL = _type if _type == "sell": self.ORDER_ID_TO_CANCEL = str( self.ORDERS_LIST_SELL.currentItem().text()).split( "|")[0].strip()[1:] elif _type == "buy": self.ORDER_ID_TO_CANCEL = str( self.ORDERS_LIST_BUY.currentItem().text()).split( "|")[0].strip()[1:] except Exception as _exception: print(_exception) # ------------------------------------------------------------------- # ======================================================================= def CREATE_LISTS(self): # ------------------------------------------------------------------- try: self.ORDERS_LIST_SELL.clear() self.ORDERS_LIST_BUY.clear() for ID in self.ORDERS_FROM_DB: item = "" item += "#{:11} DEL".format(str(ID)) # order_id item += "{:7} DEL".format(self.ORDERS_FROM_DB[ID]["pair"]) # type item += "{:13} DEL".format( str("{:10,.6f}".format( self.ORDERS_FROM_DB[ID]["amount"])).strip()) # Amount item += "{:13} DEL".format( str("{:10,.6f}".format( self.ORDERS_FROM_DB[ID]["at_price"])).strip()) # at_price newItemToolTip = "Order ID: #" + str( ID) + " Created: " + time.ctime( self.ORDERS_FROM_DB[ID]["unix_time"]) if self.ORDERS_FROM_DB[ID]["type"] == "buy": ttl = self.ORDERS_FROM_DB[ID]["amount"] - ( self.ORDERS_FROM_DB[ID]["amount"] / 100 * self.PARENT.FEE) item += "{:13}".format( str("{:10,.6f}".format(ttl)).strip()) # ttl_usd newItem = QListWidgetItem( QIcon("./data/imgs/icon_filled_status_0.png"), item.replace("DEL", self._i_), self.ORDERS_LIST_BUY, 0) newItem.setToolTip(newItemToolTip) elif self.ORDERS_FROM_DB[ID]["type"] == "sell": ttl = self.ORDERS_FROM_DB[ID][ "at_price"] * self.ORDERS_FROM_DB[ID]["amount"] ttl -= (ttl / 100 * self.PARENT.FEE) item += "{:13}".format( str("{:10,.6f}".format(ttl)).strip()) # ttl_usd newItem = QListWidgetItem( QIcon("./data/imgs/icon_filled_status_0.png"), item.replace("DEL", self._i_), self.ORDERS_LIST_SELL, 0) newItem.setToolTip(newItemToolTip) except Exception as _exception: print("FRAME_ORDER.CREATE_LISTS: " + str(_exception)) # ------------------------------------------------------------------- # ======================================================================= def DELETE_ORDER(self, _order_id, _pair, _type): # ------------------------------------------------------------------ _SQL = "DELETE FROM " + _pair + " WHERE order_id=" + str(_order_id) self.PARENT.DB.EXEC("ORDERS_DB", _SQL) # ------------------------------------------------------------------ # ======================================================================= def UPDATE_ACTIVE_ORDERS(self): # ------------------------------------------------------------------ pass # ------------------------------------------------------------------ # ======================================================================= def GET_ORDERS_FROM_DB(self): # ------------------------------------------------------------------ #del self.ORDERS_FROM_DB; #self.ORDERS_FROM_DB = {}; # ------------------------------------------------------------------ for PAIR in self.CONF["API"]["ALL_PAIRS"]: THIS_FIELDS = "order_id, unix_time, filled, at_price, amount, pair, type" DATA = self.PARENT.DB.FETCH("ORDERS_DB", "SELECT " + THIS_FIELDS + " FROM " + PAIR + " WHERE filled=0", ALL=True) _len = len(DATA) for order_id, unix_time, filled, at_price, amount, pair, _type in DATA: self.ORDERS_FROM_DB[order_id] = { "order_id": order_id, "unix_time": unix_time, "filled": filled, "at_price": at_price, "amount": amount, "pair": pair, "type": _type } """ if _len > 0: #print(order_id, "->", self.ORDERS_FROM_DB[ order_id ]) print(self.ORDERS_FROM_DB) exit(); """ # ------------------------------------------------------------------ # ======================================================================= ###################################################################################################
class NewProjectManager(QDialog): def __init__(self, parent=None): super(NewProjectManager, self).__init__(parent, Qt.Dialog) self.setWindowTitle(translations.TR_NEW_PROJECT) self.setMinimumHeight(500) vbox = QVBoxLayout(self) vbox.addWidget(QLabel(translations.TR_CHOOSE_TEMPLATE)) vbox.addWidget(QLabel(translations.TR_TAB_PROJECTS)) hbox = QHBoxLayout() self.list_projects = QListWidget() self.list_projects.setProperty("wizard", True) hbox.addWidget(self.list_projects) self.list_templates = QListWidget() self.list_templates.setProperty("wizard", True) hbox.addWidget(self.list_templates) self.text_info = QTextBrowser() self.text_info.setProperty("wizard", True) hbox.addWidget(self.text_info) vbox.addLayout(hbox) hbox2 = QHBoxLayout() cancel = QPushButton(translations.TR_CANCEL) choose = QPushButton(translations.TR_CHOOSE) hbox2.addSpacerItem(QSpacerItem(1, 0, QSizePolicy.Expanding, QSizePolicy.Fixed)) hbox2.addWidget(cancel) hbox2.addWidget(choose) vbox.addLayout(hbox2) self.template_registry = IDE.get_service("template_registry") categories = self.template_registry.list_project_categories() for category in categories: self.list_projects.addItem(category) self.connect(cancel, SIGNAL("clicked()"), self.close) self.connect(choose, SIGNAL("clicked()"), self._start_wizard) self.connect(self.list_projects, SIGNAL("itemSelectionChanged()"), self._project_selected) self.connect(self.list_templates, SIGNAL("itemSelectionChanged()"), self._template_selected) def _project_selected(self): self.list_templates.clear() item = self.list_projects.currentItem() category = item.text() for template in self.template_registry.list_templates_for_cateogory( category): item = QListWidgetItem(template.type_name) item.setData(Qt.UserRole, template) item = self.list_templates.addItem(item) def _template_selected(self): item = self.list_templates.currentItem() ptype = item.data(Qt.UserRole) self.text_info.setText(ptype.description) def _start_wizard(self): item = self.list_templates.currentItem() if item is not None: ptype = item.data(Qt.UserRole)
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 AbstractStructuredWidget(QWidget, NodeWidget): data_type = None two_rows = True data_class = None def __init__(self, name, data, scheme, parent=None): QWidget.__init__(self, parent) NodeWidget.__init__(self, name, data, scheme) self.layout = QVBoxLayout(self) self.layout.setMargin(0) self._listwidget = QListWidget(self) self.layout.addWidget(self._listwidget) hlayout = QHBoxLayout() self.layout.setMargin(0) self.layout.setContentsMargins(0,0,0,0) self.layout.addLayout(hlayout) self._plus_minus_widget = PlusMinusWidget(self.create_item, self.delete_item, self) hlayout.addWidget(self._plus_minus_widget) # self._edit_button = SmallSquareButton("edit", self) # hlayout.addWidget(self._edit_button) # self._edit_button.clicked.connect(self.edit_item) self._listwidget.itemDoubleClicked.connect(self.edit_item) hlayout.addStretch(1) self._listwidget.setEditTriggers(QAbstractItemView.EditKeyPressed) self._listwidget.itemChanged.connect(self.rename_item) self._listwidget.currentItemChanged.connect(self.current_item_changed) self.current_item_index = None def edit_item(self): name = unicode(self._listwidget.currentItem().text()) self.parent().open(Path(self.data.path()+(name,))) def delete_item(self): item_name = unicode(self._listwidget.currentItem().text()) self._listwidget.takeItem(self._listwidget.row(self._listwidget.currentItem())) del self.data[item_name] def _createItem(self, itemname): item = QListWidgetItem(itemname) item.setFlags (Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled ) self._listwidget.addItem(item) def rename_item(self, item): self.data.rename_item(self.current_item_index, unicode(item.text())) def current_item_changed(self, item): if item: self.current_item_index = unicode(item.text()) else: self.current_item_index = None def dump(self): pass
class MiniCalculation(QDialog): AppName = u"迷你计算器" def __init__(self, parent=None): super(MiniCalculation, self).__init__(parent) self.btnHelpState = False self.setWindowTitle(MiniCalculation.AppName) self.txtBrower = QTextBrowser() self.txtLine = QLineEdit() self.txtLine.setPlaceholderText(u"请输入表达式,按回车结束...") self.btnCal = QPushButton(u"计算") self.btnClear = QPushButton(u"清空") self.btnHelp = QPushButton(u"特殊函数表>>") self.btnHelp.setCheckable(True) self.btnHelp.setChecked(True) mathList = [s for s in dir(math) if not s.startswith("__")] self.listWidget = QListWidget() self.listWidget.addItems(mathList) for i in range(len(mathList)): item = self.listWidget.item(i) strFun = item.text() + '.__doc__' item.setToolTip(eval(str(strFun))) self.listWidget.setMaximumWidth(100) midLay = QHBoxLayout() midLay.addWidget(self.btnCal) midLay.addWidget(self.btnClear) midLay.addStretch() midLay.addWidget(self.btnHelp) bottomLay = QHBoxLayout() bottomLay.addWidget(self.txtBrower) bottomLay.addWidget(self.listWidget) lay = QVBoxLayout() lay.addWidget(self.txtLine) lay.addItem(midLay) lay.addItem(bottomLay) self.resize(450, 300) self.setLayout(lay) self.updateUI() self.btnCal.clicked.connect(self.btnCalClicked) self.btnClear.clicked.connect(self.txtLine.clear) self.btnClear.clicked.connect(self.txtBrower.clear) self.btnHelp.clicked.connect(self.updateUI) self.listWidget.itemDoubleClicked.connect(self.listItemDoubleClicked) def updateUI(self): state = not self.btnHelp.isChecked() self.listWidget.setHidden(state) text = u"特殊函数表>>" if state else u"特殊函数表<<" self.btnHelp.setText(text) def btnCalClicked(self): try: txt = str(self.txtLine.text()) self.txtBrower.append("%s = <b>%s</b>" % (txt, eval(txt))) except UnicodeEncodeError: QMessageBox.warning(self,u"QData -- 迷你计算机", u"表达式中存在中文或全角字符\n", QMessageBox.Ok) except: self.txtBrower.append("<font color=red>%s <b>is invalid</b>" % txt) def listItemDoubleClicked(self): item = self.listWidget.currentItem() self.txtLine.insert(item.text()) self.txtLine.setFocus()
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)
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 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 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 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