def __init__(self, parent=None): super().__init__(parent, Qt.Dialog | Qt.FramelessWindowHint) # parent, # Qt.Dialog | Qt.FramelessWindowHint # ) self._operations = {'row': False, 'col': True} self.setModal(True) # self.setAttribute(Qt.WA_TranslucentBackground) # self.setStyleSheet("background:transparent;") self.setFixedHeight(150) self.setFixedWidth(300) # Create the QML user interface. view = QQuickWidget() view.rootContext().setContextProperty("theme", NTheme.get_colors()) view.setResizeMode(QQuickWidget.SizeRootObjectToView) view.setSource(ui_tools.get_qml_resource("SplitOrientation.qml")) self._root = view.rootObject() vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) vbox.addWidget(view) view.setFocusPolicy(Qt.StrongFocus) short_esc = QShortcut(QKeySequence(Qt.Key_Escape), self) short_esc.activated.connect(self.hide) self._root.selected['QString'].connect(self._split_operation)
def __init__(self, parent=None): super(LocatorWidget, self).__init__( parent, Qt.Dialog | Qt.FramelessWindowHint) self._parent = parent self.setModal(True) self.setAttribute(Qt.WA_TranslucentBackground) self.setStyleSheet("background:transparent;") self.setFixedHeight(400) self.setFixedWidth(500) view = QQuickWidget() view.rootContext().setContextProperty("theme", resources.QML_COLORS) view.setResizeMode(QQuickWidget.SizeRootObjectToView) view.setSource(ui_tools.get_qml_resource("Locator.qml")) self._root = view.rootObject() vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) vbox.addWidget(view) self.locate_symbols = locator.LocateSymbolsThread() self.locate_symbols.finished.connect(self._cleanup) # FIXME: invalid signal # self.locate_symbols.terminated.connect(self._cleanup) # Hide locator with Escape key shortEscMisc = QShortcut(QKeySequence(Qt.Key_Escape), self) shortEscMisc.activated.connect(self.hide) # Locator things self.filterPrefix = re.compile(r'(@|<|>|-|!|\.|/|:)') self.page_items_step = 10 self._colors = { "@": "#5dade2", "<": "#4becc9", ">": "#ff555a", "-": "#66ff99", ".": "#a591c6", "/": "#f9d170", ":": "#18ffd6", "!": "#ff884d"} self._filters_list = [ ("@", "Filename"), ("<", "Class"), (">", "Function"), ("-", "Attribute"), (".", "Current"), ("/", "Opened"), (":", "Line"), ("!", "NoPython") ] self._replace_symbol_type = {"<": "<", ">": ">"} self.reset_values() self._filter_actions = { '.': self._filter_this_file, '/': self._filter_tabs, ':': self._filter_lines } self._root.textChanged['QString'].connect(self.set_prefix) self._root.open['QString', int].connect(self._open_item) self._root.fetchMore.connect(self._fetch_more)
class ErrorsList(QWidget): def __init__(self, parent=None): super(ErrorsList, self).__init__() self._main_container = IDE.get_service("main_container") # Create the QML user interface. self.view = QQuickWidget() self.view.rootContext().setContextProperty( "theme", resources.QML_COLORS) # Colors from theme warn_bug_colors = {} warn_bug_colors["warning"] = resources.COLOR_SCHEME.get("editor.pep8") warn_bug_colors["bug"] = resources.COLOR_SCHEME.get("editor.checker") self.view.rootContext().setContextProperty("colors", warn_bug_colors) self.view.setResizeMode(QQuickWidget.SizeRootObjectToView) self.view.setSource(ui_tools.get_qml_resource("ErrorsList.qml")) self._root = self.view.rootObject() vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) vbox.addWidget(self.view) self._root.open.connect(self._open) def _open(self, row): self._main_container.editor_go_to_line(row) def update_pep8_model(self, model): self._root.set_pep8_model(model) def update_error_model(self, model): self._root.set_error_model(model)
def __init__(self, parent=None): super(LocatorWidget, self).__init__( parent, Qt.Dialog | Qt.FramelessWindowHint) self._parent = parent self.setModal(True) self.setAttribute(Qt.WA_TranslucentBackground) self.setStyleSheet("background:transparent;") self.setFixedHeight(400) self.setFixedWidth(500) view = QQuickWidget() view.rootContext().setContextProperty("theme", NTheme.get_colors()) view.setResizeMode(QQuickWidget.SizeRootObjectToView) view.setSource(ui_tools.get_qml_resource("Locator.qml")) self._root = view.rootObject() vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) vbox.addWidget(view) self.locate_symbols = locator.LocateSymbolsThread() self.locate_symbols.finished.connect(self._cleanup) # FIXME: invalid signal # self.locate_symbols.terminated.connect(self._cleanup) # Hide locator with Escape key shortEscMisc = QShortcut(QKeySequence(Qt.Key_Escape), self) shortEscMisc.activated.connect(self.hide) # Locator things self.filterPrefix = re.compile(r'(@|<|>|-|!|\.|/|:)') self.page_items_step = 10 self._colors = { "@": "#5dade2", "<": "#4becc9", ">": "#ff555a", "-": "#66ff99", ".": "#a591c6", "/": "#f9d170", ":": "#18ffd6", "!": "#ff884d"} self._filters_list = [ ("@", "Filename"), ("<", "Class"), (">", "Function"), ("-", "Attribute"), (".", "Current"), ("/", "Opened"), (":", "Line"), ("!", "NoPython") ] self._replace_symbol_type = {"<": "<", ">": ">"} self.reset_values() self._filter_actions = { '.': self._filter_this_file, '/': self._filter_tabs, ':': self._filter_lines } self._root.textChanged['QString'].connect(self.set_prefix) self._root.open['QString', int].connect(self._open_item) self._root.fetchMore.connect(self._fetch_more)
class QmlWindow(QtWidgets.QWidget): def __init__(self, url): super(QmlWindow, self).__init__() self.setAttribute(Qt.WA_QuitOnClose, True) self.setAttribute(Qt.WA_DeleteOnClose, True) self.setAttribute(Qt.WA_TranslucentBackground, True) #self.setTransBackground(True) self.qmlWindow = QQuickWidget(self) self.qmlWindow.setResizeMode(QQuickWidget.SizeRootObjectToView) self.qmlWindow.rootContext().setContextProperty( "qmlWindow", self.qmlWindow) self.qmlWindow.setSource(QUrl(url)) windowFlags = Qt.FramelessWindowHint self.setWindowFlags(windowFlags) self.show() @pyqtSlot(bool) def setTransBackground(self, transBackground): palette = self.palette() if transBackground: palette.setBrush(QPalette.Base, Qt.transparent) else: palette.setBrush(QPalette.Base, Qt.white) self.setPalette(palette)
def __init__(self, parent=None): super().__init__(parent, Qt.Dialog | Qt.FramelessWindowHint) self._main_container = parent self.setModal(True) self.setAttribute(Qt.WA_TranslucentBackground) self.setFixedWidth(650) # Create the QML UI view = QQuickWidget() view.rootContext().setContextProperty("theme", NTheme.get_colors()) view.setResizeMode(QQuickWidget.SizeRootObjectToView) view.setSource(ui_tools.get_qml_resource("AddFileFolder.qml")) self._root = view.rootObject() vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) vbox.addWidget(view) self._base_path = "" self._create_file_operation = True short_esc = QShortcut(QKeySequence(Qt.Key_Escape), self) short_esc.activated.connect(self.close) # Connection self._root.create.connect(self._create)
class ErrorsList(QWidget): def __init__(self, parent=None): super(ErrorsList, self).__init__() self._main_container = IDE.get_service("main_container") # Create the QML user interface. self.view = QQuickWidget() self.view.rootContext().setContextProperty("theme", resources.QML_COLORS) # Colors from theme warn_bug_colors = {} warn_bug_colors["warning"] = resources.COLOR_SCHEME.get("editor.pep8") warn_bug_colors["bug"] = resources.COLOR_SCHEME.get("editor.checker") self.view.rootContext().setContextProperty("colors", warn_bug_colors) self.view.setResizeMode(QQuickWidget.SizeRootObjectToView) self.view.setSource(ui_tools.get_qml_resource("ErrorsList.qml")) self._root = self.view.rootObject() vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) vbox.addWidget(self.view) self._root.open.connect(self._open) def _open(self, row): self._main_container.editor_go_to_line(row) def update_pep8_model(self, model): self._root.set_pep8_model(model) def update_error_model(self, model): self._root.set_error_model(model)
def __init__(self, parent=None): super().__init__(parent, Qt.Dialog | Qt.FramelessWindowHint) self._main_container = parent self.setModal(True) self.setAttribute(Qt.WA_TranslucentBackground) self.setFixedWidth(650) # Create the QML UI view = QQuickWidget() view.rootContext().setContextProperty("theme", resources.QML_COLORS) view.setResizeMode(QQuickWidget.SizeRootObjectToView) view.setSource(ui_tools.get_qml_resource("AddFileFolder.qml")) self._root = view.rootObject() vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) vbox.addWidget(view) self._base_path = "" self._create_file_operation = True short_esc = QShortcut(QKeySequence(Qt.Key_Escape), self) short_esc.activated.connect(self.close) # Connection self._root.create.connect(self._create)
def ui(self): layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) widget = QQuickWidget(self) widget.setContentsMargins(0, 0, 0, 0) widget.rootContext().setContextProperty('self', self.obj) widget.setSource(QUrl(self.qml)) layout.addWidget(widget) return layout
class TutorialView(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent=parent) self._presenter = TutorialPresenter(self) self._widget = QQuickWidget(self) self.testComponent = TestComponent(self._widget.engine(), self) self._widget.setResizeMode(QQuickWidget.SizeRootObjectToView) self._widget.rootContext().setContextProperty('tutorialView', self) self._widget.rootContext().setContextProperty('testComponent', self.testComponent) self._widget.setSource( QUrl('modules/tutorial/tutorialForm/TutorialForm.qml')) self.__setConnections() self.__locateWidgets() self.getSections() def __setConnections(self): self.reqReprSections.connect(self.setModel) self.reqReprTopics.connect(self.setModel) def __locateWidgets(self): self.setLayout(QHBoxLayout()) self.layout().setContentsMargins(1, 1, 1, 1) self.layout().addWidget(self._widget) _reqSections = pyqtSignal(name='requireSections') _reqTopics = pyqtSignal(str, name='requireTopics') _reqReprSections = pyqtSignal(QQuickItem, str, list, name='reqReprSections') _reqReprTopics = pyqtSignal(QQuickItem, str, list, name='reqReprTopics') @pyqtSlot(name='getSections') def _getSections(self): self.requireSections.emit() def reprSectionsList(self, sections): self.reqReprSections.emit(self._widget.rootObject(), 'setSectionsModel', sections) @pyqtSlot(str, name='getTopics') def _getTopics(self, section_id): self.requireTopics.emit(section_id) def reprTopicsList(self, topics): self.reqReprTopics.emit(self._widget.rootObject(), 'setTopicsModel', topics) @pyqtSlot(QQuickItem, str, list, name='setModel') def _setModel(self, obj, callF, values): QMetaObject.invokeMethod(obj, callF, Q_ARG(QVariant, values))
def __init__(self, parent=None): super().__init__(parent, Qt.WindowStaysOnTopHint) box = QVBoxLayout(self) box.setContentsMargins(0, 0, 0, 0) box.setSpacing(0) # Model self._manager = BookmarkManager() # QML UI view = QQuickWidget() view.setResizeMode(QQuickWidget.SizeRootObjectToView) view.rootContext().setContextProperty("bookmarkModel", self._manager) view.rootContext().setContextProperty("theme", resources.QML_COLORS) view.setSource(ui_tools.get_qml_resource("BookmarkList.qml")) box.addWidget(view) self._root = view.rootObject() self._root.openBookmark.connect(self._open_bookmark) self._root.menuRequested.connect(self._show_menu) IDE.register_service("bookmarks", self) ExplorerContainer.register_tab("Bookmarks", self)
def __init__(self, parent=None): super().__init__(parent, Qt.WindowStaysOnTopHint) box = QVBoxLayout(self) box.setContentsMargins(3, 3, 3, 3) box.setSpacing(0) # Model self._manager = BookmarkManager() # QML UI view = QQuickWidget() view.setResizeMode(QQuickWidget.SizeRootObjectToView) view.rootContext().setContextProperty("bookmarkModel", self._manager) view.rootContext().setContextProperty("theme", resources.QML_COLORS) view.setSource(ui_tools.get_qml_resource("BookmarkList.qml")) box.addWidget(view) self._root = view.rootObject() self._root.openBookmark.connect(self._open_bookmark) self._root.menuRequested.connect(self._show_menu) IDE.register_service("bookmarks", self) ExplorerContainer.register_tab("Bookmarks", self)
def ui(self): layout = QVBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) widget = QQuickWidget(self) widget.setContentsMargins(0, 0, 0, 0) widget.rootContext().setContextProperty('self', self.obj) widget.setSource(QtCore.QUrl(self.qml)) layout.addWidget(widget) pdsWidget = ProductList(self.products) width = 750 pdsWidget.setMinimumWidth(width) pdsWidget.setMaximumWidth(width) product_layout = QHBoxLayout(self) product_layout.setContentsMargins(0, 0, 0, 0) product_layout.addSpacing(30) product_layout.addWidget(pdsWidget) product_layout.addStretch(1) layout.addLayout(product_layout) layout.addStretch(1) return layout
class ScheduleView(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent=parent) self._presenter = SchedulePresenter(self) self._widget = QQuickWidget(self) self.setLayout(QHBoxLayout()) self.layout().setContentsMargins(1, 1, 1, 1) self.layout().addWidget(self._widget) self._widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self._widget.setResizeMode(QQuickWidget.SizeRootObjectToView) self._widget.rootContext().setContextProperty('scheduleView', self) self._widget.rootContext().setContextProperty('groupsModel', self) self._widget.setSource( QUrl('modules/schedule/scheduleForm/ScheduleForm.qml')) self.reqReprSchedules.connect(self.setModel) self.reqInitSchedule.connect(self.initSchedule) @pyqtSlot(int, name='changeWidth') def _changeWidth(self, _width): self.setFixedWidth(_width) _reqGroups = pyqtSignal(name='requireGroups') _reqSchedules = pyqtSignal(str, name='requireSchedules', arguments=['group']) _reqReprSchedules = pyqtSignal(QQuickItem, str, list, name='reqReprSchedules') _reqInitSchedule = pyqtSignal(QQuickItem, name='reqInitSchedule') @pyqtSlot(name='getGroups') def _getGroups(self): self.requireGroups.emit() def reprGroupsList(self, groups): self.setPropertyList('groupsModel', groups) def setPropertyList(self, objectName, values): self._widget.rootContext().setContextProperty(objectName, values) @pyqtSlot(str, name='getSchedules') def _getSchedules(self, group): self.requireSchedules.emit(group) def reprSchedules(self, schedules): self.reqReprSchedules.emit(self._widget.rootObject(), 'setScheduleModel', schedules) @pyqtSlot(QQuickItem, str, list, name='setModel') def _setModel(self, obj, callF, values): QMetaObject.invokeMethod(obj, callF, Q_ARG(QVariant, values)) @pyqtSlot(QQuickItem, name='initSchedule') def _initSchedule(self, obj): QMetaObject.invokeMethod(obj, "initSchedule")
def __init__(self, parent=None): super().__init__(parent, Qt.Dialog | Qt.FramelessWindowHint) self._operations = {'row': False, 'col': True} self.setModal(True) self.setAttribute(Qt.WA_TranslucentBackground) self.setStyleSheet("background:transparent;") self.setFixedHeight(150) self.setFixedWidth(290) # Create the QML user interface. view = QQuickWidget() view.setClearColor(Qt.transparent) view.rootContext().setContextProperty("theme", resources.QML_COLORS) view.setResizeMode(QQuickWidget.SizeRootObjectToView) view.setSource(ui_tools.get_qml_resource("SplitOrientation.qml")) self._root = view.rootObject() vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) vbox.addWidget(view) view.setFocusPolicy(Qt.StrongFocus) short_esc = QShortcut(QKeySequence(Qt.Key_Escape), self) short_esc.activated.connect(self.hide) self._root.selected['QString'].connect(self._split_operation)
class FilesHandler(QFrame): #Qt.WindowStaysOnTopHint | _changedForJava = pyqtSignal() def __init__(self, combofiles, Force_Free=False): #SplashScreen super(FilesHandler, self).__init__( None, Qt.SplashScreen) #, Qt.Popup | Qt.FramelessWindowHint # self.setAttribute(Qt.WA_TranslucentBackground) # self.setStyleSheet("background:transparent;") # self.setStyleSheet("background-color: rgb(25, 255, 60);") self.setWindowState(Qt.WindowActive) # | Qt.SplashScreen # self.setAttribute(Qt.WA_AlwaysStackOnTop, False) # Create the QML user interface. self._main_container = combofiles.container #IDE.get_service('main_container') self.comboParent = combofiles self.Force_Free = combofiles.undocked or Force_Free # self.rawObj = raww(self) self.view = QQuickWidget() self.view.setResizeMode(QQuickWidget.SizeRootObjectToView) self.view.engine().quit.connect(self.hide) # self.view.rootContext().setContextProperty("rawObj", self.rawObj) self.view.setSource(ui_tools.get_qml_resource("FilesHandler.qml")) self._root = self.view.rootObject() cntx = self.view.rootContext() cntx.setProperty("tools", Tools()) self._contextMenu_Incert = self._root.property("_window_") vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) vbox.addWidget(self.view) # {"name": model[i][0], # "path": model[i][1], # "checkers": model[i][2], # "modified": model[i][3], # "tempFile": model[i][4], # "project": "", # "itemVisible": true}); self._ntup = ("name", "path", "checkers", "modified", "tempFile", "project", "itemVisible") # self._Ndtup = namedtuple("_Ndtup", self._ntup) self._filePathPosition = {} self._filesModel = [] self._temp_files = {} self._max_index = 0 print("\n\nFilesHandler", self, self._contextMenu_Incert) # QApplication.instance().focusChanged["QWidget*", "QWidget*"].connect(\ # lambda w1, w2: print("\n\n:focusChanged:", w1, w1.geometry() if w1\ # else "_No es un widget", w2, w2.geometry() if w2 else "_No es un widget")) QApplication.instance().focusChanged["QWidget*", "QWidget*"].connect(\ lambda old, now, this=self: print("\n\n:focusChanged:", this.hide(), old, now) if old == this.view else None) self._root.open.connect(self._open) self._root.close.connect(self._close) self._root.hide.connect(self.hide) self._root.fuzzySearch.connect(self._fuzzy_search) #QTimer.singleShot(15000, lambda: print("QTimer::", self.show())) # self._root.setVisible(True) def _open(self, path, temp, project): print("\n\n_open", path, "|", temp, "|", project, "|", self) if project: path = os.path.join(os.path.split(project)[0], path) self._main_container.open_file(path) elif temp: nfile = self._temp_files[temp] ninjaide = IDE.getInstance() neditable = ninjaide.get_or_create_editable(nfile=nfile) print("nfile", nfile, neditable, self._temp_files, temp) self._main_container.current_comboEditor.set_current(neditable) else: # self._main_container.open_file(path) # self._main_container.open_file_from_nEditable(self.comboParent.get_editable_fromPath(path),\ # self.comboParent.ParentalComboEditor) self.comboParent.ParentalComboEditor.set_current(\ self.comboParent.get_editable_fromPath(path) ) index = self._filePathPosition[path] self._max_index = max(self._max_index, index) + 1 self._filePathPosition[path] = self._max_index self.hide() def _close(self, path, temp): if temp: nfile = self._temp_files.get(temp, None) else: ninjaide = IDE.getInstance() nfile = ninjaide.get_or_create_nfile(path) if nfile is not None: nfile.close() def _fuzzy_search(self, search): search = '.+'.join(re.escape(search).split('\\ ')) pattern = re.compile(search, re.IGNORECASE) model = [] for project_path in locator.files_paths: files_in_project = locator.files_paths[project_path] base_project = os.path.basename(project_path) for file_path in files_in_project: file_path = os.path.join( base_project, os.path.relpath(file_path, project_path)) if pattern.search(file_path): model.append( [os.path.basename(file_path), file_path, project_path]) self._root.set_fuzzy_model(model) def getNewIndex(self): self._max_index += 1 return self._max_index - 1 def currentEditable(self): return self.comboParent.get_editable() def removeFile(self, nedit): self.removeFilePath(nedit.file_path) def removeFilePath(self, path): # del self._filesModel[self._filePathPosition[path]] del self._filePathPosition[path] self._changedForJava.emit() @pyqtProperty(QJsonValue, notify=_changedForJava) def fileModel(self): return self._filesModel def add_Data(self, dat): self._filesModel.append(dict(zip(self._tup, dat))) # sort by Path model = sorted(self._filesModel,\ key=lambda x: self._filePathPosition.get(x[1], False), reverse=True) self._filesModel = model self._changedForJava.emit() def addFile(self, neditable): nfile = neditable.nfile current_editor = ninjaide.getCurrentEditor() current_path = current_editor.file_path if current_editor else "" model = [] if nfile.file_path not in self._filePathPosition and nfile.file_path is not None: self._filePathPosition[ nfile.file_path] = 0 # default position for NEW FILE checkers = neditable.sorted_checkers checks = [] for items in checkers: checker, color, _ = items if checker.dirty: # Colors needs to be reversed for QML color = "#%s" % color[::-1] checks.append({ "checker_text": checker.dirty_text, "checker_color": color }) modified = neditable.editor.is_modified temp_file = str(uuid.uuid4()) if nfile.file_path is None else "" filepath = nfile.file_path if nfile.file_path is not None else "" if temp_file: self._temp_files[temp_file] = nfile self.add_Data( (nfile.file_name, filepath, checks, modified, temp_file,\ "", current_path and current_path != nfile.file_path) ) def _add_model(self): # print("_add_model:_add_model") ninjaide = IDE.getInstance() #files = ninjaide.opened_files# list<neditable> # if True:#self.Force_Free: # files = self.comboParent.opened_files # else: # files = ninjaide.opened_files files = self.comboParent.opened_files print("_add_model::", len(files)) past = set(self._filePathPosition.keys()) now = set([neditable.file_path for neditable in files]) old = past - now # print("\n_model:past:", past) # print("\n_model:now:", now) # print("\n_model:old:", old) # Update model for item in old: # print("\n to Delete", item) del self._filePathPosition[item] current_editor = ninjaide.getCurrentEditor() # if current_editor.neditable != self.currentEditable(): # QMessageBox.critical(None, "current_editor", "el QSCiEditor que la aplicación dice que es el actual\n"\ # "NO coincide con el Editor de éste FilesHandler()") current_path = current_editor.file_path if current_editor else "" model = [] # print("len(files)", len(files), [nfile.file_path for nfile in files], "\n\n") for neditable in files: nfile = neditable.nfile if nfile.file_path not in self._filePathPosition and nfile.file_path is not None: self._filePathPosition[nfile.file_path] = self.getNewIndex() # print("\n_add_model->", not self.Force_Free, type(nfile)) # if not self.Force_Free: # neditable = ninjaide.get_or_create_editable_EXTERNAL(nfile=nfile) # print("\n_add_model->->", neditable, self._filePathPosition, neditable.editor) checkers = neditable.sorted_checkers checks = [] for items in checkers: checker, color, _ = items if checker.dirty: # Colors needs to be reversed for QML color = "#%s" % color[::-1][:-1] checks.append({ "checker_text": checker.dirty_text, "checker_color": color }) modified = neditable.editor.is_modified temp_file = str(uuid.uuid4()) if nfile.file_path is None else "" filepath = nfile.file_path if nfile.file_path is not None else "" model.append([ nfile.file_name, filepath, checks, modified, temp_file, "", current_path and current_path != nfile.file_path ]) if temp_file: self._temp_files[temp_file] = nfile # if current_path: # index = self._filePathPosition[current_path] # self._max_index = max(self._max_index, index) + 1 # self._filePathPosition[current_path] = self._max_index # print("\n\nmodel:1:", self._filePathPosition, "\n///", model) # sort by Path model = sorted(model, key=lambda x: self._filePathPosition.get(x[1], False), reverse=True) # print("\n\nmodel:2:", model) self._root.set_model(model) def showEvent(self, event): print("\nshowEvent:::showEvent", self.isVisible(), self.view.isVisible()) self._add_model() widget = self.comboParent.ParentalComboEditor.currentEditor() if widget is None: widget = self._main_container if self._main_container.splitter.count() < 2: width = max(widget.width() / 2, 500) height = max(widget.height() / 2, 400) else: width = widget.width() height = widget.height() self.view.setFixedWidth(width) self.view.setFixedHeight(height) point = widget.mapToGlobal(self.view.pos()) self.move(point.x(), point.y()) super(FilesHandler, self).showEvent(event) self._root.show_animation() self.view.setFocus() self._root.activateInput() def hideEvent(self, event): print("\nhideEvent:::", self.isVisible(), self.view.isVisible()) super(FilesHandler, self).hideEvent(event) self._temp_files = {} self._root.clear_model() def next_item(self): print("next_item()", self) if not self.isVisible(): self.show() self._root.next_item() def previous_item(self): print("previous_item()", self) if not self.isVisible(): self.show() self._root.previous_item() def keyPressEvent(self, event): print("keyPressEvent()", event.key(), event.key() == Qt.Key_Escape) if event.key() == Qt.Key_Escape: self.hide() elif (event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_PageDown) or event.key() == Qt.Key_Down: self._root.next_item() elif (event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_PageUp) or event.key() == Qt.Key_Up: self._root.previous_item() elif event.key() in (Qt.Key_Return, Qt.Key_Enter): self._root.open_item() # elif event.key() == Qt.Key_Asterisk): # print("keyPressEvent()", self,self.isVisible()) super(FilesHandler, self).keyPressEvent(event) def mousePressEvent(self, event): print("\n\nFILESHANDLER.mousePressEvent", QApplication.instance().widgetAt(self.mapToGlobal(event.pos()))) if QApplication.instance().widgetAt(self.mapToGlobal( event.pos())) == self.comboParent: print("TRUE!!!") # event.ignore() # self.comboParent.hidePopup() return super(FilesHandler, self).mousePressEvent(event)
class FilesHandler(QWidget): def __init__(self, parent=None): super(FilesHandler, self).__init__( None, Qt.FramelessWindowHint | Qt.Popup) self.setAttribute(Qt.WA_TranslucentBackground) self._main_container = parent # Create the QML user interface. self.setFixedHeight(300) self.setFixedWidth(400) self.view = QQuickWidget() self.view.rootContext().setContextProperty( "theme", resources.QML_COLORS) self.view.setResizeMode(QQuickWidget.SizeRootObjectToView) self.view.setSource(ui_tools.get_qml_resource("FilesHandler.qml")) # self.view.setClearColor(Qt.transparent) self._root = self.view.rootObject() vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) vbox.addWidget(self.view) self._model = {} self._temp_files = {} self._max_index = 0 self._root.open.connect(self._open) self._root.close.connect(self._close) self._root.fuzzySearch.connect(self._fuzzy_search) self._root.hide.connect(self.hide) def _open(self, path, temp, project): if project: path = os.path.join(os.path.split(project)[0], path) self._main_container.open_file(path) elif temp: nfile = self._temp_files[temp] ninjaide = IDE.get_service("ide") neditable = ninjaide.get_or_create_editable(nfile=nfile) self._main_container.combo_area.set_current(neditable) else: self._main_container.open_file(path) index = self._model[path] self._max_index = max(self._max_index, index) + 1 self._model[path] = self._max_index self.hide() def _close(self, path, temp): # FIXME: when we have splitters? if temp: nfile = self._temp_files.get(temp, None) else: ninjaide = IDE.get_service("ide") nfile = ninjaide.get_or_create_nfile(path) if nfile is not None: nfile.close() def _fuzzy_search(self, search): search = '.+'.join(re.escape(search).split('\\ ')) pattern = re.compile(search, re.IGNORECASE) model = [] for project_path in locator.files_paths: files_in_project = locator.files_paths[project_path] base_project = os.path.basename(project_path) for file_path in files_in_project: file_path = os.path.join( base_project, os.path.relpath(file_path, project_path)) if pattern.search(file_path): model.append([os.path.basename(file_path), file_path, project_path]) self._root.set_fuzzy_model(model) def _add_model(self): ninjaide = IDE.get_service("ide") files = ninjaide.opened_files # Update model current_editor = self._main_container.get_current_editor() current_path = None if current_editor is not None: current_path = current_editor.file_path model = [] for nfile in files: if nfile.file_path is not None and \ nfile.file_path not in self._model: self._model[nfile.file_path] = 0 neditable = ninjaide.get_or_create_editable(nfile=nfile) checkers = neditable.sorted_checkers checks = [] for item in checkers: checker, color, _ = item if checker.dirty: checks.append({ "checker_text": checker.dirty_text, "checker_color": color }) modified = neditable.editor.is_modified temp_file = str(uuid.uuid4()) if nfile.file_path is None else "" filepath = nfile.file_path if nfile.file_path is not None else "" model.append([ nfile.file_name, filepath, checks, modified, temp_file]) if temp_file: self._temp_files[temp_file] = nfile if current_path is not None: index = self._model[current_path] self._max_index = max(self._max_index, index) + 1 self._model[current_path] = self._max_index model = sorted(model, key=lambda x: self._model.get(x[1], False), reverse=True) self._root.set_model(model) def showEvent(self, event): self._add_model() editor_widget = self._main_container.get_current_editor() simple = False if editor_widget.height() < 400 or editor_widget.width() < 350: width = editor_widget.width() height = self._main_container.height() / 3 simple = True else: width = max(editor_widget.width() / 3, 550) height = max(editor_widget.height() / 2, 400) self.setFixedWidth(width) self.setFixedHeight(height) self._root.setMode(simple) super(FilesHandler, self).showEvent(event) # self._root.show_animation() point = editor_widget.mapToGlobal(self.view.pos()) self.move(point) # Trick QTimer.singleShot(100, self.__set_focus) def __set_focus(self): self.view.setFocus() self._root.activateInput() def hideEvent(self, event): super(FilesHandler, self).hideEvent(event) self._temp_files = {} self._root.clear_model() # Recovery focus editor_widget = self._main_container.get_current_editor() if editor_widget is not None: editor_widget.setFocus() def next_item(self): if not self.isVisible(): self.show() # self._root.next_item() def previous_item(self): if not self.isVisible(): self.show() self._root.previous_item() def keyPressEvent(self, event): if event.key() == Qt.Key_Escape: self.hide() elif (event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_Tab): self._root.next_item() elif (event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_PageDown) or event.key() == Qt.Key_Down: self._root.next_item() elif (event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_PageUp) or event.key() == Qt.Key_Up: self._root.previous_item() elif event.key() in (Qt.Key_Return, Qt.Key_Enter): self._root.open_item() super(FilesHandler, self).keyPressEvent(event)
class StartPage(QWidget): # Signals openPreferences = pyqtSignal() newFile = pyqtSignal() def __init__(self, parent=None): super(StartPage, self).__init__(parent) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.view = QQuickWidget() self.view.rootContext().setContextProperty( "theme", resources.QML_COLORS) self.view.rootContext().setContextProperty( "shortcuts", self.get_shortcuts()) self.view.setMinimumWidth(400) self.view.setResizeMode(QQuickWidget.SizeRootObjectToView) self.view.setSource(ui_tools.get_qml_resource("StartPage.qml")) self.root = self.view.rootObject() vbox.addWidget(self.view) # Connections self.root.onDrop.connect(self.__open_drop_files) self.root.openProject.connect(self._open_project) self.root.newFile.connect(lambda: self.newFile.emit()) self.load_items() @pyqtSlot('QString') def _open_project(self, path): projects_explorer = IDE.get_service("projects_explorer") projects_explorer.open_project_folder(path) def get_shortcuts(self): shortcuts = {k: v.toString() for k, v in resources.SHORTCUTS.items()} return shortcuts def load_items(self): # dsettings = IDE.data_settings() # recent_projects_dict = dict(dsettings.value('recentProjects', {})) # for prj, values in recent_projects_dict.items(): # prj_name = values["name"] # last_open = values["lastopen"] # self.root.addProject(prj_name, prj, last_open) self.root.forceActiveFocus() """ # Connections self.root.openProject['QString'].connect(self._open_project) self.root.removeProject['QString'].connect(self._on_click_on_delete) self.root.markAsFavorite['QString', bool].connect(self._on_click_on_favorite) self.root.openPreferences.connect( lambda: self.openPreferences.emit()) self.root.newFile.connect(lambda: self.newFile.emit()) def _open_project(self, path): projects_explorer = IDE.get_service('projects_explorer') if projects_explorer: projects_explorer.open_project_folder(path) def _on_click_on_delete(self, path): settings = IDE.data_settings() recent_projects = settings.value("recentProjects") if path in recent_projects: del recent_projects[path] settings.setValue("recentProjects", recent_projects) def _on_click_on_favorite(self, path, value): settings = IDE.data_settings() recent_projects = settings.value("recentProjects") properties = recent_projects[path] properties["isFavorite"] = value recent_projects[path] = properties settings.setValue("recentProjects", recent_projects) def load_items(self): settings = IDE.data_settings() listByFavorites = [] listNoneFavorites = [] recent_projects_dict = dict(settings.value('recentProjects', {})) # Filter for favorites for recent_project_path, content in list(recent_projects_dict.items()): if bool(dict(content)["isFavorite"]): listByFavorites.append((recent_project_path, content["lastopen"])) else: listNoneFavorites.append((recent_project_path, content["lastopen"])) if len(listByFavorites) > 1: # sort by date favorites listByFavorites = sorted(listByFavorites, key=lambda date: listByFavorites[1]) if len(listNoneFavorites) > 1: # sort by date last used listNoneFavorites = sorted(listNoneFavorites, key=lambda date: listNoneFavorites[1]) for recent_project_path in listByFavorites: path = recent_project_path[0] name = recent_projects_dict[path]['name'] self.root.add_project(name, path, True) for recent_project_path in listNoneFavorites: path = recent_project_path[0] name = recent_projects_dict[path]['name'] self.root.add_project(name, path, False) self.root.forceActiveFocus() """ def __open_drop_files(self, files: str): """Open dragged files to Start Page""" files = files.split(',') # FIXME: it's ok? main_container = IDE.get_service("main_container") for f in files: main_container.open_file(QUrl(f).toLocalFile())
class PageThumbnailer(QObject): def __init__(self, parent=None): super().__init__(parent) self._view = QQuickWidget() # QQuickWidget self._size = QSize(450, 253) * gVar.app.devicePixelRatio() self._url = QUrl() self._title = '' self._loadTitle = False self._view.setAttribute(Qt.WA_DontShowOnScreen) self._view.setSource(QUrl('qrc:data/thumbnailer.qml')) self._view.rootContext().setContextProperty('thumbnailer', self) self._view.show() def setSize(self, size): if size.isValid(): self._size = size def setUrl(self, url): if url.isValid(): self._url = url def url(self): return self._url def loadTitle(self): ''' @return: bool ''' return self._loadTitle def setLoadTitle(self, load): ''' @param: load bool ''' self._loadTitle = load def title(self): title = self._title if not title: title = self._url.host() if not title: title = self._url.toString() return title def start(self): if self._view.rootObject() and WebView.isUrlValid(self._url): self._view.rootObject().setProperty('url', self._url) else: def func(): self.thumbnailCreated.emit(QPixmap()) QTimer.singleShot(500, func) # Q_SIGNALS: thumbnailCreated = pyqtSignal(QPixmap) # public Q_SLOTS: @pyqtSlot(result=str) def afterLoadScript(self): ''' @return: QString ''' return Scripts.setCss('::~webkit-scrollbar{display:none;}') @pyqtSlot(bool) def createThumbnail(self, status): ''' @param: status bool ''' if not status: self.thumbnailCreated.emit(QPixmap()) return def func(): self._title = self._view.rootObject().property('title').strip() img = self._view.grabFramebuffer().scaled(self._size, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) pixmap = QPixmap.fromImage(img) self.thumbnailCreated.emit(pixmap) QTimer.singleShot(1000, func)
class RelationEditorFeatureSideWidget(QgsAbstractRelationEditorWidget, WidgetUi): class LastView(str, Enum): ListView = "ListView" IconView = "IconView" settingsLastView = QgsSettingsEntryString( 'relationEditorFeatureSideLastView', PluginHelper.PLUGIN_SLUG, LastView.ListView, PluginHelper.tr( 'Last view used in the relation editor document side widget')) signalCurrentViewChanged = pyqtSignal() def __init__(self, config, parent): super().__init__(config, parent) self._updateUiTimer = QTimer() self._updateUiTimer.setSingleShot(True) self._updateUiTimer.timeout.connect(self.updateUiTimeout) self.setupUi(self) print('DocumentRelationEditorFeatureSideWidget.__init__') self.documents_path = str() self.document_filename = str() self.model = DocumentModel() self._nmRelation = QgsRelation() self._layerInSameTransactionGroup = False self._currentDocumentId = None # Actions self.actionToggleEditing = QAction( QIcon(":/images/themes/default/mActionToggleEditing.svg"), self.tr("Toggle editing mode for child layers")) self.actionToggleEditing.setCheckable(True) self.actionSaveEdits = QAction( QIcon(":/images/themes/default/mActionSaveEdits.svg"), self.tr("Save child layer edits")) self.actionShowForm = QAction( QIcon(":/images/themes/default/mActionMultiEdit.svg"), self.tr("Show form")) self.actionAddFeature = QAction( QIcon(":/images/themes/default/symbologyAdd.svg"), self.tr("Add document")) self.actionDeleteFeature = QAction( QIcon(":/images/themes/default/mActionDeleteSelected.svg"), self.tr("Drop document")) self.actionLinkFeature = QAction( QIcon(":/images/themes/default/mActionLink.svg"), self.tr("Link document")) self.actionUnlinkFeature = QAction( QIcon(":/images/themes/default/mActionUnlink.svg"), self.tr("Unlink document")) # Tool buttons self.mToggleEditingToolButton.setDefaultAction( self.actionToggleEditing) self.mSaveEditsToolButton.setDefaultAction(self.actionSaveEdits) self.mShowFormToolButton.setDefaultAction(self.actionShowForm) self.mAddFeatureToolButton.setDefaultAction(self.actionAddFeature) self.mDeleteFeatureToolButton.setDefaultAction( self.actionDeleteFeature) self.mLinkFeatureToolButton.setDefaultAction(self.actionLinkFeature) self.mUnlinkFeatureToolButton.setDefaultAction( self.actionUnlinkFeature) self.mListViewToolButton.setIcon( QIcon(":/images/themes/default/mIconListView.svg")) self.mIconViewToolButton.setIcon( QIcon(":/images/themes/default/mActionIconView.svg")) self.mListViewToolButton.setChecked(self.currentView == str( RelationEditorFeatureSideWidget.LastView.ListView)) self.mIconViewToolButton.setChecked(self.currentView == str( RelationEditorFeatureSideWidget.LastView.IconView)) # Quick image providers self._previewImageProvider = PreviewImageProvider() self._fileTypeSmallIconProvider = FileTypeIconImageProvider(32) self._fileTypeBigIconProvider = FileTypeIconImageProvider(100) # Setup QML part self.view = QQuickWidget() self.view.rootContext().setContextProperty("documentModel", self.model) self.view.rootContext().setContextProperty("parentWidget", self) self.view.rootContext().setContextProperty( "CONST_LIST_VIEW", str(RelationEditorFeatureSideWidget.LastView.ListView)) self.view.rootContext().setContextProperty( "CONST_ICON_VIEW", str(RelationEditorFeatureSideWidget.LastView.IconView)) self.view.engine().addImageProvider("previewImageProvider", self._previewImageProvider) self.view.engine().addImageProvider("fileTypeSmallIconProvider", self._fileTypeSmallIconProvider) self.view.engine().addImageProvider("fileTypeBigIconProvider", self._fileTypeBigIconProvider) self.view.setSource( QUrl.fromLocalFile( os.path.join(os.path.dirname(__file__), '../qml/DocumentList.qml'))) self.view.setResizeMode(QQuickWidget.SizeRootObjectToView) self.layout().addWidget(self.view) # Set initial state for add / remove etc.buttons self.updateButtons() # Signal slots self.actionToggleEditing.triggered.connect(self.toggleEditing) self.actionSaveEdits.triggered.connect(self.saveChildLayerEdits) self.actionShowForm.triggered.connect(self.showDocumentForm) self.actionAddFeature.triggered.connect(self.addDocument) self.actionDeleteFeature.triggered.connect(self.dropDocument) self.actionLinkFeature.triggered.connect(self.linkDocument) self.actionUnlinkFeature.triggered.connect(self.unlinkDocument) self.mListViewToolButton.toggled.connect( self.listViewToolButtonToggled) self.mIconViewToolButton.toggled.connect( self.iconViewToolButtonToggled) @pyqtProperty(str) def currentView(self): return self.settingsLastView.value() def updateCurrentView(self): if self.mListViewToolButton.isChecked(): self.settingsLastView.setValue( str(RelationEditorFeatureSideWidget.LastView.ListView)) else: self.settingsLastView.setValue( str(RelationEditorFeatureSideWidget.LastView.IconView)) self.signalCurrentViewChanged.emit() @pyqtProperty(QVariant) def currentDocumentId(self): return self._currentDocumentId @pyqtSlot(QVariant) def setCurrentDocumentId(self, value): self._currentDocumentId = value self.updateButtons() def nmRelation(self): return self._nmRelation def config(self): return {} def setConfig(self, config): self.documents_path = config['documents_path'] self.document_filename = config['document_filename'] def updateUi(self): self._updateUiTimer.start(200) def updateUiTimeout(self): self.model.init(self.relation(), self.nmRelation(), self.feature(), self.documents_path, self.document_filename) def updateButtons(self): toggleEditingButtonEnabled = False editable = False linkable = False spatial = False selectionNotEmpty = self._currentDocumentId is not None if self.relation().isValid(): toggleEditingButtonEnabled = self.relation().referencingLayer( ).supportsEditing() editable = self.relation().referencingLayer().isEditable() linkable = self.relation().referencingLayer().isEditable() spatial = self.relation().referencingLayer().isSpatial() if self.nmRelation().isValid(): toggleEditingButtonEnabled |= self.nmRelation().referencedLayer( ).supportsEditing() editable = self.nmRelation().referencedLayer().isEditable() spatial = self.nmRelation().referencedLayer().isSpatial() self.mToggleEditingToolButton.setEnabled(toggleEditingButtonEnabled) self.mAddFeatureToolButton.setEnabled(editable) self.mLinkFeatureToolButton.setEnabled(linkable) self.mDeleteFeatureToolButton.setEnabled(editable and selectionNotEmpty) self.mUnlinkFeatureToolButton.setEnabled(linkable and selectionNotEmpty) self.mToggleEditingToolButton.setChecked(editable) self.mSaveEditsToolButton.setEnabled(editable or linkable) self.mShowFormToolButton.setEnabled(selectionNotEmpty) self.mToggleEditingToolButton.setVisible( self._layerInSameTransactionGroup is False) self.mSaveEditsToolButton.setVisible( self._layerInSameTransactionGroup is False) def afterSetRelations(self): self._nmRelation = QgsProject.instance().relationManager().relation( str(self.nmRelationId())) self._checkTransactionGroup() if self.relation().isValid(): self.relation().referencingLayer().editingStopped.connect( self.updateButtons) self.relation().referencingLayer().editingStarted.connect( self.updateButtons) if self.nmRelation().isValid(): self.nmRelation().referencedLayer().editingStarted.connect( self.updateButtons) self.nmRelation().referencedLayer().editingStopped.connect( self.updateButtons) self.updateButtons() def _checkTransactionGroup(self): self._layerInSameTransactionGroup = False connectionString = PluginHelper.connectionString( self.relation().referencedLayer().source()) transactionGroup = QgsProject.instance().transactionGroup( self.relation().referencedLayer().providerType(), connectionString) if transactionGroup is None: return if self.nmRelation().isValid(): if (self.relation().referencedLayer() in transactionGroup.layers() and self.relation().referencingLayer() in transactionGroup.layers() and self.nmRelation().referencedLayer() in transactionGroup.layers()): self._layerInSameTransactionGroup = True else: if (self.relation().referencedLayer() in transactionGroup.layers() and self.relation().referencingLayer() in transactionGroup.layers()): self._layerInSameTransactionGroup = True def parentFormValueChanged(self, attribute, newValue): pass def checkLayerEditingMode(self): if self.relation().referencingLayer().isEditable() is False: QMessageBox.critical( self, self.tr("Layer not editable"), self.tr("Layer '{0}' is not in editing mode.").format( self.relation().referencingLayer().name())) return False if self.nmRelation().isValid(): if self.nmRelation().referencedLayer().isEditable() is False: QMessageBox.critical( self, self.tr("Layer not editable"), self.tr("Layer '{0}' is not in editing mode.").format( self.nmRelation().referencedLayer().name())) return False return True @pyqtSlot(bool) def toggleEditing(self, state): super().toggleEditing(state) self.updateButtons() @pyqtSlot() def saveChildLayerEdits(self): super().saveEdits() @pyqtSlot() def addDocument(self): # Workaround because of QGIS not resetting this property after linking features self.editorContext().vectorLayerTools().setForceSuppressFormPopup( False) self.addFeature() @pyqtSlot() def dropDocument(self): if self._currentDocumentId is None: return self.deleteFeature(self._currentDocumentId) @pyqtSlot(str) def addDroppedDocument(self, fileUrl): if self.checkLayerEditingMode() is False: return # Workaround because of QGIS not resetting this property after linking features self.editorContext().vectorLayerTools().setForceSuppressFormPopup( False) layer = self.relation().referencingLayer() if self.nmRelation().isValid(): layer = self.nmRelation().referencedLayer() default_documents_path = str() if self.documents_path: exp = QgsExpression(self.documents_path) context = QgsExpressionContext() context.appendScopes( QgsExpressionContextUtils.globalProjectLayerScopes(layer)) default_documents_path = str(exp.evaluate(context)) filename = QUrl(fileUrl).toLocalFile() if default_documents_path: filename = QDir(default_documents_path).relativeFilePath(filename) keyAttrs = dict() # Fields of the linking table fields = self.relation().referencingLayer().fields() # For generated relations insert the referenced layer field if self.relation().type() == QgsRelation.Generated: polyRel = self.relation().polymorphicRelation() keyAttrs[fields.indexFromName( polyRel.referencedLayerField())] = polyRel.layerRepresentation( self.relation().referencedLayer()) if self.nmRelation().isValid(): # only normal relations support m:n relation if self.nmRelation().type() != QgsRelation.Normal: QMessageBox.critical( self, self.tr("Add document"), self. tr("Invalid relation, Only normal relations support m:n relation." )) return # Pre fill inserting document filepath attributes = { self.nmRelation().referencedLayer().fields().indexFromName(self.document_filename): filename } # n:m Relation: first let the user create a new feature on the other table # and autocreate a new linking feature. ok, feature = self.editorContext().vectorLayerTools().addFeature( self.nmRelation().referencedLayer(), attributes, QgsGeometry()) if not ok: QMessageBox.critical( self, self.tr("Add document"), self.tr("Could not add a new linking feature.")) return for key in self.relation().fieldPairs(): keyAttrs[fields.indexOf(key)] = self.feature().attribute( self.relation().fieldPairs()[key]) for key in self.nmRelation().fieldPairs(): keyAttrs[fields.indexOf(key)] = feature.attribute( self.nmRelation().fieldPairs()[key]) linkFeature = QgsVectorLayerUtils.createFeature( self.relation().referencingLayer(), QgsGeometry(), keyAttrs, self.relation().referencingLayer().createExpressionContext()) if not self.relation().referencingLayer().addFeature(linkFeature): QMessageBox.critical(self, self.tr("Add document"), self.tr("Could not add a new feature.")) return else: for key in self.relation().fieldPairs(): keyAttrs[fields.indexFromName(key)] = self.feature().attribute( self.relation().fieldPairs()[key]) # Pre fill inserting document filepath keyAttrs[fields] = filename ok, feature = self.editorContext().vectorLayerTools().addFeature( self.relation().referencingLayer(), keyAttrs, QgsGeometry()) if not ok: QMessageBox.critical(self, self.tr("Add document"), self.tr("Could not add a new feature.")) return self.updateUi() @pyqtSlot() def linkDocument(self): self.linkFeature() @pyqtSlot() def unlinkDocument(self): if self._currentDocumentId is None: return self.unlinkFeature(self._currentDocumentId) @pyqtSlot() def showDocumentForm(self): if self._currentDocumentId is None: return layer = self.relation().referencingLayer() if self.nmRelation().isValid(): layer = self.nmRelation().referencedLayer() showDocumentFormDialog = QgsAttributeDialog( layer, layer.getFeature(self._currentDocumentId), False, self, True) showDocumentFormDialog.exec() self.updateUi() @pyqtSlot(bool) def listViewToolButtonToggled(self, checked): self.mIconViewToolButton.blockSignals(True) self.mIconViewToolButton.setChecked(checked is False) self.mIconViewToolButton.blockSignals(False) self.updateCurrentView() @pyqtSlot(bool) def iconViewToolButtonToggled(self, checked): self.mListViewToolButton.blockSignals(True) self.mListViewToolButton.setChecked(checked is False) self.mListViewToolButton.blockSignals(False) self.updateCurrentView()
class FilesHandler(QWidget): def __init__(self, parent=None): super(FilesHandler, self).__init__( None, Qt.FramelessWindowHint | Qt.Popup) self.setAttribute(Qt.WA_TranslucentBackground) self._main_container = parent # Create the QML user interface. self.setFixedHeight(300) self.setFixedWidth(400) self.view = QQuickWidget() self.view.rootContext().setContextProperty( "theme", resources.QML_COLORS) self.view.setResizeMode(QQuickWidget.SizeRootObjectToView) self.view.setSource(ui_tools.get_qml_resource("FilesHandler.qml")) self._root = self.view.rootObject() vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) vbox.addWidget(self.view) self._model = {} self._temp_files = {} self._max_index = 0 self._root.open.connect(self._open) self._root.close.connect(self._close) self._root.fuzzySearch.connect(self._fuzzy_search) self._root.hide.connect(self.hide) def _open(self, path, temp, project): if project: path = os.path.join(os.path.split(project)[0], path) self._main_container.open_file(path) elif temp: nfile = self._temp_files[temp] ninjaide = IDE.get_service("ide") neditable = ninjaide.get_or_create_editable(nfile=nfile) self._main_container.combo_area.set_current(neditable) else: self._main_container.open_file(path) index = self._model[path] self._max_index = max(self._max_index, index) + 1 self._model[path] = self._max_index self.hide() def _close(self, path, temp): # FIXME: when we have splitters? if temp: nfile = self._temp_files.get(temp, None) else: ninjaide = IDE.get_service("ide") nfile = ninjaide.get_or_create_nfile(path) if nfile is not None: nfile.close() def _fuzzy_search(self, search): search = '.+'.join(re.escape(search).split('\\ ')) pattern = re.compile(search, re.IGNORECASE) model = [] for project_path in locator.files_paths: files_in_project = locator.files_paths[project_path] base_project = os.path.basename(project_path) for file_path in files_in_project: file_path = os.path.join( base_project, os.path.relpath(file_path, project_path)) if pattern.search(file_path): model.append([os.path.basename(file_path), file_path, project_path]) self._root.set_fuzzy_model(model) def _add_model(self): ninjaide = IDE.get_service("ide") files = ninjaide.opened_files # Update model current_editor = self._main_container.get_current_editor() current_path = None if current_editor is not None: current_path = current_editor.file_path model = [] for nfile in files: if nfile.file_path is not None and \ nfile.file_path not in self._model: self._model[nfile.file_path] = 0 neditable = ninjaide.get_or_create_editable(nfile=nfile) checkers = neditable.sorted_checkers checks = [] for item in checkers: checker, color, _ = item if checker.dirty: checks.append({ "checker_text": checker.dirty_text, "checker_color": color }) modified = neditable.editor.is_modified temp_file = str(uuid.uuid4()) if nfile.file_path is None else "" filepath = nfile.file_path if nfile.file_path is not None else "" model.append([ nfile.file_name, filepath, checks, modified, temp_file]) if temp_file: self._temp_files[temp_file] = nfile if current_path is not None: index = self._model[current_path] self._max_index = max(self._max_index, index) + 1 self._model[current_path] = self._max_index model = sorted(model, key=lambda x: self._model.get(x[1], False), reverse=True) self._root.set_model(model) def showEvent(self, event): self._add_model() editor_widget = self._main_container.get_current_editor() simple = False if editor_widget.height() < 400 or editor_widget.width() < 350: width = editor_widget.width() height = self._main_container.height() / 3 simple = True else: width = max(editor_widget.width() / 3, 550) height = max(editor_widget.height() / 2, 400) self.setFixedWidth(width) self.setFixedHeight(height) self._root.setMode(simple) super(FilesHandler, self).showEvent(event) point = editor_widget.mapToGlobal(self.view.pos()) self.move(point) # Trick QTimer.singleShot(100, self.__set_focus) def __set_focus(self): self.view.setFocus() self._root.activateInput() def hideEvent(self, event): super(FilesHandler, self).hideEvent(event) self._temp_files = {} self._root.clear_model() # Recovery focus editor_widget = self._main_container.get_current_editor() if editor_widget is not None: editor_widget.setFocus() def next_item(self): if not self.isVisible(): self.show() def previous_item(self): if not self.isVisible(): self.show() self._root.previous_item() def keyPressEvent(self, event): if event.key() == Qt.Key_Escape: self.hide() elif (event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_Tab): self._root.next_item() elif (event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_PageDown) or event.key() == Qt.Key_Down: self._root.next_item() elif (event.modifiers() == Qt.ControlModifier and event.key() == Qt.Key_PageUp) or event.key() == Qt.Key_Up: self._root.previous_item() elif event.key() in (Qt.Key_Return, Qt.Key_Enter): self._root.open_item() super(FilesHandler, self).keyPressEvent(event)
class StartPage(QWidget): # Signals openPreferences = pyqtSignal() newFile = pyqtSignal() def __init__(self, parent=None): super(StartPage, self).__init__(parent) vbox = QVBoxLayout(self) vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) self.view = QQuickWidget() self.view.rootContext().setContextProperty("theme", resources.QML_COLORS) self.view.rootContext().setContextProperty("shortcuts", self.get_shortcuts()) self.view.setMinimumWidth(400) self.view.setResizeMode(QQuickWidget.SizeRootObjectToView) self.view.setSource(ui_tools.get_qml_resource("StartPage.qml")) self.root = self.view.rootObject() vbox.addWidget(self.view) # Connections self.root.onDrop.connect(self.__open_drop_files) self.root.openProject.connect(self._open_project) self.root.newFile.connect(lambda: self.newFile.emit()) self.load_items() @pyqtSlot('QString') def _open_project(self, path): projects_explorer = IDE.get_service("projects_explorer") projects_explorer.open_project_folder(path) def get_shortcuts(self): shortcuts = {k: v.toString() for k, v in resources.SHORTCUTS.items()} return shortcuts def load_items(self): # dsettings = IDE.data_settings() # recent_projects_dict = dict(dsettings.value('recentProjects', {})) # for prj, values in recent_projects_dict.items(): # prj_name = values["name"] # last_open = values["lastopen"] # self.root.addProject(prj_name, prj, last_open) self.root.forceActiveFocus() """ # Connections self.root.openProject['QString'].connect(self._open_project) self.root.removeProject['QString'].connect(self._on_click_on_delete) self.root.markAsFavorite['QString', bool].connect(self._on_click_on_favorite) self.root.openPreferences.connect( lambda: self.openPreferences.emit()) self.root.newFile.connect(lambda: self.newFile.emit()) def _open_project(self, path): projects_explorer = IDE.get_service('projects_explorer') if projects_explorer: projects_explorer.open_project_folder(path) def _on_click_on_delete(self, path): settings = IDE.data_settings() recent_projects = settings.value("recentProjects") if path in recent_projects: del recent_projects[path] settings.setValue("recentProjects", recent_projects) def _on_click_on_favorite(self, path, value): settings = IDE.data_settings() recent_projects = settings.value("recentProjects") properties = recent_projects[path] properties["isFavorite"] = value recent_projects[path] = properties settings.setValue("recentProjects", recent_projects) def load_items(self): settings = IDE.data_settings() listByFavorites = [] listNoneFavorites = [] recent_projects_dict = dict(settings.value('recentProjects', {})) # Filter for favorites for recent_project_path, content in list(recent_projects_dict.items()): if bool(dict(content)["isFavorite"]): listByFavorites.append((recent_project_path, content["lastopen"])) else: listNoneFavorites.append((recent_project_path, content["lastopen"])) if len(listByFavorites) > 1: # sort by date favorites listByFavorites = sorted(listByFavorites, key=lambda date: listByFavorites[1]) if len(listNoneFavorites) > 1: # sort by date last used listNoneFavorites = sorted(listNoneFavorites, key=lambda date: listNoneFavorites[1]) for recent_project_path in listByFavorites: path = recent_project_path[0] name = recent_projects_dict[path]['name'] self.root.add_project(name, path, True) for recent_project_path in listNoneFavorites: path = recent_project_path[0] name = recent_projects_dict[path]['name'] self.root.add_project(name, path, False) self.root.forceActiveFocus() """ def __open_drop_files(self, files: str): """Open dragged files to Start Page""" files = files.split(',') # FIXME: it's ok? main_container = IDE.get_service("main_container") for f in files: main_container.open_file(QUrl(f).toLocalFile())