def initializeUi(self): """ This method initializes the Component ui. :return: Method success. ( Boolean ) """ LOGGER.debug("> Initializing '{0}' Component ui.".format( self.__class__.__name__)) umbra.ui.common.setToolBoxHeight(self.Search_toolBox) self.Tags_Cloud_listWidget.setParent(None) self.Tags_Cloud_listWidget = TagsCloud_QListView( self, message="No Tag to view!") self.Tags_Cloud_listWidget.setObjectName("Tags_Cloud_listWidget") self.Tags_Cloud_verticalLayout.addWidget(self.Tags_Cloud_listWidget) self.__view = self.Tags_Cloud_listWidget self.__view.setMovement(QListView.Static) self.__view.setResizeMode(QListView.Adjust) self.__view.setViewMode(QListView.IconMode) self.Search_Database_lineEdit = Search_QLineEdit(self) self.Search_Database_lineEdit.setPlaceholderText( "Search In Tags Cloud ...") self.Search_Database_horizontalLayout.addWidget( self.Search_Database_lineEdit) self.__view.setSpacing(self.__viewSpacing) self.__cloudExcludedTags = list( itertools.chain.from_iterable([ (r"^{0}$".format(tag), r"^{0}$".format(tag.title()), r"^{0}$".format(tag.upper())) for tag in self.__cloudExcludedTags ])) self.setTagsCloudMatchingIblsSetsUi() # Remove vertical scrollBars from **Search_toolBox** Widget. for scrollArea in self.findChildren(QScrollArea): scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # Signals / Slots. self.Search_Database_lineEdit.textChanged.connect( self.__Search_Database_lineEdit__textChanged) self.Case_Sensitive_Matching_pushButton.clicked.connect( self.__Case_Sensitive_Matching_pushButton__clicked) self.Time_Low_timeEdit.timeChanged.connect( self.__Time_Low_timeEdit__timeChanged) self.Time_High_timeEdit.timeChanged.connect( self.__Time_High_timeEdit__timeChanged) self.__view.itemDoubleClicked.connect(self.__view__doubleClicked) self.__collectionsOutliner.view.selectionModel( ).selectionChanged.connect( self.__collectionsOutliner_view_selectionModel__selectionChanged) self.initializedUi = True return True
def initializeUi(self): """ Initializes the Component ui. :return: Method success. :rtype: bool """ LOGGER.debug("> Initializing '{0}' Component ui.".format(self.__class__.__name__)) self.Trace_Modules_Filter_lineEdit = Search_QLineEdit(self) self.Trace_Modules_Filter_lineEdit.searchActiveLabel.hide() self.Trace_Modules_Filter_lineEdit.setPlaceholderText("Objects Trace Filter ...") self.Trace_Modules_Filter_horizontalLayout.addWidget(self.Trace_Modules_Filter_lineEdit) self.__model = ModulesModel(self, horizontalHeaders=self.__headers) self.Modules_treeView.setParent(None) self.Modules_treeView = Modules_QTreeView(self, self.__model) self.Modules_treeView.setObjectName("Modules_treeView") self.Modules_treeView.setContextMenuPolicy(Qt.ActionsContextMenu) self.Trace_Ui_dockWidgetContents_gridLayout.addWidget(self.Modules_treeView, 0, 0) self.__view = self.Modules_treeView self.__view_addActions() self.setModules() # Signals / Slots. self.refreshNodes.connect(self.__model__refreshNodes) self.initializedUi = True return True
def __initializeUi(self): """ Initializes the Widget ui. """ umbra.ui.common.setWindowDefaultIcon(self) self.__model = SearchResultsModel(self) self.__delegate = RichText_QStyledItemDelegate(self) self.Search_Results_treeView.setParent(None) self.Search_Results_treeView = SearchResults_QTreeView(self, self.__model, message="No Search Result to view!") self.Search_Results_treeView.setItemDelegate(self.__delegate) self.Search_Results_treeView.setObjectName("Search_Results_treeView") self.Search_Results_frame_gridLayout.addWidget(self.Search_Results_treeView, 0, 0) self.__view = self.Search_Results_treeView self.__view.setContextMenuPolicy(Qt.ActionsContextMenu) self.__view_addActions() self.__searchPatternsModel = self.__container.searchAndReplace.searchPatternsModel self.Search_comboBox.setModel(self.__container.searchAndReplace.searchPatternsModel) self.Search_comboBox.setInsertPolicy(QComboBox.InsertAtTop) self.Search_comboBox.completer().setCaseSensitivity(Qt.CaseSensitive) self.__replaceWithPatternsModel = self.__container.searchAndReplace.replaceWithPatternsModel self.Replace_With_comboBox.setModel(self.__container.searchAndReplace.replaceWithPatternsModel) self.Replace_With_comboBox.setInsertPolicy(QComboBox.InsertAtTop) self.Replace_With_comboBox.completer().setCaseSensitivity(Qt.CaseSensitive) self.Where_lineEdit.setParent(None) self.Where_lineEdit = Search_QLineEdit(self) self.Where_lineEdit.setObjectName("Where_lineEdit") self.Where_frame_gridLayout.addWidget(self.Where_lineEdit, 0, 0) self.__locationsMenu = QMenu() for title, location in self.__locations.iteritems(): self.__locationsMenu.addAction(self.__container.engine.actionsManager.registerAction( "Actions|Umbra|Components|factory.scriptEditor|Search In Files|{0}".format(title), text="{0}".format(title), slot=functools.partial(self.__addLocation, location))) self.Where_lineEdit.searchActiveLabel.setMenu(self.__locationsMenu) self.Where_lineEdit.setPlaceholderText("Use the magnifier to add locations!") self.installEventFilter(ValidationFilter(self)) # Signals / Slots. self.__view.selectionModel().selectionChanged.connect(self.__view_selectionModel__selectionChanged) self.__view.doubleClicked.connect(self.__view__doubleClicked) self.__searchPatternsModel.patternInserted.connect(functools.partial( self.__patternsModel__patternInserted, self.Search_comboBox)) self.__replaceWithPatternsModel.patternInserted.connect(functools.partial( self.__patternsModel__patternInserted, self.Replace_With_comboBox)) self.Search_pushButton.clicked.connect(self.__Search_pushButton__clicked) self.Close_pushButton.clicked.connect(self.__Close_pushButton__clicked)
def initializeUi(self): """ Initializes the Component ui. :return: Method success. :rtype: bool """ LOGGER.debug("> Initializing '{0}' Component ui.".format(self.__class__.__name__)) umbra.ui.common.setToolBoxHeight(self.Search_toolBox) self.Tags_Cloud_listWidget.setParent(None) self.Tags_Cloud_listWidget = TagsCloud_QListView(self, message="No Tag to view!") self.Tags_Cloud_listWidget.setObjectName("Tags_Cloud_listWidget") self.Tags_Cloud_verticalLayout.addWidget(self.Tags_Cloud_listWidget) self.__view = self.Tags_Cloud_listWidget self.__view.setMovement(QListView.Static) self.__view.setResizeMode(QListView.Adjust) self.__view.setViewMode(QListView.IconMode) self.Search_Database_lineEdit = Search_QLineEdit(self) self.Search_Database_lineEdit.setPlaceholderText("Search In Tags Cloud ...") self.Search_Database_horizontalLayout.addWidget(self.Search_Database_lineEdit) self.__view.setSpacing(self.__viewSpacing) self.__cloudExcludedTags = list(itertools.chain.from_iterable( [(r"^{0}$".format(tag), r"^{0}$".format(tag.title()), r"^{0}$".format(tag.upper())) for tag in self.__cloudExcludedTags])) self.setTagsCloudMatchingIblsSetsUi() # Remove vertical scrollBars from **Search_toolBox** Widget. for scrollArea in self.findChildren(QScrollArea): scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # Signals / Slots. self.Search_Database_lineEdit.textChanged.connect(self.__Search_Database_lineEdit__textChanged) self.Case_Sensitive_Matching_pushButton.clicked.connect(self.__Case_Sensitive_Matching_pushButton__clicked) self.Time_Low_timeEdit.timeChanged.connect(self.__Time_Low_timeEdit__timeChanged) self.Time_High_timeEdit.timeChanged.connect(self.__Time_High_timeEdit__timeChanged) self.__view.itemDoubleClicked.connect(self.__view__doubleClicked) self.__collectionsOutliner.view.selectionModel().selectionChanged.connect( self.__collectionsOutliner_view_selectionModel__selectionChanged) self.initializedUi = True return True
class SearchInFiles(foundations.ui.common.QWidgetFactory(uiFile=UI_FILE)): """ Defines search and replace in files dialog used by the **ScriptEditor** Component. """ def __init__(self, parent, *args, **kwargs): """ Initializes the class. :param parent: Object parent. :type parent: QObject :param \*args: Arguments. :type \*args: \* :param \*\*kwargs: Keywords arguments. :type \*\*kwargs: \*\* """ LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__)) super(SearchInFiles, self).__init__(parent, *args, **kwargs) # --- Setting class attributes. --- self.__container = self.__scriptEditor = parent self.__filesCache = foundations.cache.Cache() self.__searchPatternsModel = None self.__replaceWithPatternsModel = None self.__model = None self.__view = None self.__delegate = None self.__locations = OrderedDict([("Add Directory ...", "directory"), ("Add File ...", "file"), ("Add Opened Files", "editors"), ("Add Include Filter", "includeFilter"), ("Add Exclude Filter", "excludeFilter")]) self.__locationsMenu = None self.__defaultFilterIn = "*.txt" self.__filtersInFormat = "{0}" self.__defaultFilterOut = "*.txt" self.__filtersOutFormat = "!{0}" self.__defaultTarget = "Opened Files" self.__targetsFormat = "<{0}>" self.__defaultLineNumberWidth = 6 self.__defaultLineColor = QColor(144, 144, 144) self.__ignoreHiddenFiles = True self.__searchWorkerThread = None SearchInFiles.__initializeUi(self) #****************************************************************************************************************** #*** Attributes properties. #****************************************************************************************************************** @property def container(self): """ Property for **self.__container** attribute. :return: self.__container. :rtype: QObject """ return self.__container @container.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def container(self, value): """ Setter for **self.__container** attribute. :param value: Attribute value. :type value: QObject """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "container")) @container.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def container(self): """ Deleter for **self.__container** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "container")) @property def scriptEditor(self): """ Property for **self.__scriptEditor** attribute. :return: self.__scriptEditor. :rtype: QWidget """ return self.__scriptEditor @scriptEditor.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def scriptEditor(self, value): """ Setter for **self.__scriptEditor** attribute. :param value: Attribute value. :type value: QWidget """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "scriptEditor")) @scriptEditor.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def scriptEditor(self): """ Deleter for **self.__scriptEditor** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "scriptEditor")) @property def filesCache(self): """ Property for **self.__filesCache** attribute. :return: self.__filesCache. :rtype: Cache """ return self.__filesCache @filesCache.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def filesCache(self, value): """ Setter for **self.__filesCache** attribute. :param value: Attribute value. :type value: Cache """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "filesCache")) @filesCache.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def filesCache(self): """ Deleter for **self.__filesCache** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "filesCache")) @property def searchPatternsModel(self): """ Property for **self.__searchPatternsModel** attribute. :return: self.__searchPatternsModel. :rtype: PatternsModel """ return self.__searchPatternsModel @searchPatternsModel.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def searchPatternsModel(self, value): """ Setter for **self.__searchPatternsModel** attribute. :param value: Attribute value. :type value: PatternsModel """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "searchPatternsModel")) @searchPatternsModel.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def searchPatternsModel(self): """ Deleter for **self.__searchPatternsModel** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "searchPatternsModel")) @property def replaceWithPatternsModel(self): """ Property for **self.__replaceWithPatternsModel** attribute. :return: self.__replaceWithPatternsModel. :rtype: PatternsModel """ return self.__replaceWithPatternsModel @replaceWithPatternsModel.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def replaceWithPatternsModel(self, value): """ Setter for **self.__replaceWithPatternsModel** attribute. :param value: Attribute value. :type value: PatternsModel """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "replaceWithPatternsModel")) @replaceWithPatternsModel.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def replaceWithPatternsModel(self): """ Deleter for **self.__replaceWithPatternsModel** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "replaceWithPatternsModel")) @property def model(self): """ Property for **self.__model** attribute. :return: self.__model. :rtype: SearchResultsModel """ return self.__model @model.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def model(self, value): """ Setter for **self.__model** attribute. :param value: Attribute value. :type value: SearchResultsModel """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "model")) @model.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def model(self): """ Deleter for **self.__model** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "model")) @property def view(self): """ Property for **self.__view** attribute. :return: self.__view. :rtype: QWidget """ return self.__view @view.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def view(self, value): """ Setter for **self.__view** attribute. :param value: Attribute value. :type value: QWidget """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "view")) @view.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def view(self): """ Deleter for **self.__view** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "view")) @property def delegate(self): """ Property for **self.__delegate** attribute. :return: self.__delegate. :rtype: QItemDelegate """ return self.__delegate @delegate.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def delegate(self, value): """ Setter for **self.__delegate** attribute. :param value: Attribute value. :type value: QItemDelegate """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "delegate")) @delegate.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def delegate(self): """ Deleter for **self.__delegate** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "delegate")) @property def locations(self): """ Property for **self.__locations** attribute. :return: self.__locations. :rtype: OrderedDict """ return self.__locations @locations.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def locations(self, value): """ Setter for **self.__locations** attribute. :param value: Attribute value. :type value: OrderedDict """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "locations")) @locations.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def locations(self): """ Deleter for **self.__locations** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "locations")) @property def locationsMenu(self): """ Property for **self.__locationsMenu** attribute. :return: self.__locationsMenu. :rtype: QMenu """ return self.__locationsMenu @locationsMenu.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def locationsMenu(self, value): """ Setter for **self.__locationsMenu** attribute. :param value: Attribute value. :type value: QMenu """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "locationsMenu")) @locationsMenu.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def locationsMenu(self): """ Deleter for **self.__locationsMenu** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "locationsMenu")) @property def defaultFilterIn(self): """ Property for **self.__defaultFilterIn** attribute. :return: self.__defaultFilterIn. :rtype: unicode """ return self.__defaultFilterIn @defaultFilterIn.setter @foundations.exceptions.handleExceptions(AssertionError) def defaultFilterIn(self, value): """ Setter for **self.__defaultFilterIn** attribute. :param value: Attribute value. :type value: unicode """ if value is not None: assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "defaultFilterIn", value) assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("defaultFilterIn", value) self.__defaultFilterIn = value @defaultFilterIn.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def defaultFilterIn(self): """ Deleter for **self.__defaultFilterIn** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "defaultFilterIn")) @property def filtersInFormat(self): """ Property for **self.__filtersInFormat** attribute. :return: self.__filtersInFormat. :rtype: unicode """ return self.__filtersInFormat @filtersInFormat.setter @foundations.exceptions.handleExceptions(AssertionError) def filtersInFormat(self, value): """ Setter for **self.__filtersInFormat** attribute. :param value: Attribute value. :type value: unicode """ if value is not None: assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "filtersInFormat", value) assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("filtersInFormat", value) self.__filtersInFormat = value @filtersInFormat.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def filtersInFormat(self): """ Deleter for **self.__filtersInFormat** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "filtersInFormat")) @property def defaultFilterOut(self): """ Property for **self.__defaultFilterOut** attribute. :return: self.__defaultFilterOut. :rtype: unicode """ return self.__defaultFilterOut @defaultFilterOut.setter @foundations.exceptions.handleExceptions(AssertionError) def defaultFilterOut(self, value): """ Setter for **self.__defaultFilterOut** attribute. :param value: Attribute value. :type value: unicode """ if value is not None: assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "defaultFilterOut", value) assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("defaultFilterOut", value) self.__defaultFilterOut = value @defaultFilterOut.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def defaultFilterOut(self): """ Deleter for **self.__defaultFilterOut** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "defaultFilterOut")) @property def filtersOutFormat(self): """ Property for **self.__filtersOutFormat** attribute. :return: self.__filtersOutFormat. :rtype: unicode """ return self.__filtersOutFormat @filtersOutFormat.setter @foundations.exceptions.handleExceptions(AssertionError) def filtersOutFormat(self, value): """ Setter for **self.__filtersOutFormat** attribute. :param value: Attribute value. :type value: unicode """ if value is not None: assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "filtersOutFormat", value) assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("filtersOutFormat", value) self.__filtersOutFormat = value @filtersOutFormat.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def filtersOutFormat(self): """ Deleter for **self.__filtersOutFormat** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "filtersOutFormat")) @property def defaultTarget(self): """ Property for **self.__defaultTarget** attribute. :return: self.__defaultTarget. :rtype: unicode """ return self.__defaultTarget @defaultTarget.setter @foundations.exceptions.handleExceptions(AssertionError) def defaultTarget(self, value): """ Setter for **self.__defaultTarget** attribute. :param value: Attribute value. :type value: unicode """ if value is not None: assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "defaultTarget", value) assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("defaultTarget", value) self.__defaultTarget = value @defaultTarget.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def defaultTarget(self): """ Deleter for **self.__defaultTarget** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "defaultTarget")) @property def targetsFormat(self): """ Property for **self.__targetsFormat** attribute. :return: self.__targetsFormat. :rtype: unicode """ return self.__targetsFormat @targetsFormat.setter @foundations.exceptions.handleExceptions(AssertionError) def targetsFormat(self, value): """ Setter for **self.__targetsFormat** attribute. :param value: Attribute value. :type value: unicode """ if value is not None: assert type(value) is unicode, "'{0}' attribute: '{1}' type is not 'unicode'!".format( "targetsFormat", value) assert os.path.exists(value), "'{0}' attribute: '{1}' file doesn't exists!".format("targetsFormat", value) self.__targetsFormat = value @targetsFormat.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def targetsFormat(self): """ Deleter for **self.__targetsFormat** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "targetsFormat")) @property def defaultLineNumberWidth(self): """ Property for **self.__defaultLineNumberWidth** attribute. :return: self.__defaultLineNumberWidth. :rtype: int """ return self.__defaultLineNumberWidth @defaultLineNumberWidth.setter @foundations.exceptions.handleExceptions(AssertionError) def defaultLineNumberWidth(self, value): """ Setter for **self.__defaultLineNumberWidth** attribute. :param value: Attribute value. :type value: int """ if value is not None: assert type(value) is int, "'{0}' attribute: '{1}' type is not 'int'!".format( "defaultLineNumberWidth", value) assert value > 0, "'{0}' attribute: '{1}' need to be exactly positive!".format("defaultLineNumberWidth", value) self.__defaultLineNumberWidth = value @defaultLineNumberWidth.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def defaultLineNumberWidth(self): """ Deleter for **self.__defaultLineNumberWidth** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "defaultLineNumberWidth")) @property def defaultLineColor(self): """ Property for **self.__defaultLineColor** attribute. :return: self.__defaultLineColor. :rtype: QColor """ return self.__defaultLineColor @defaultLineColor.setter @foundations.exceptions.handleExceptions(AssertionError) def defaultLineColor(self, value): """ Setter for **self.__defaultLineColor** attribute. :param value: Attribute value. :type value: QColor """ if value is not None: assert type(value) is QColor, "'{0}' attribute: '{1}' type is not 'QColor'!".format("defaultLineColor", value) self.__defaultLineColor = value @defaultLineColor.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def defaultLineColor(self): """ Deleter for **self.__defaultLineColor** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "defaultLineColor")) @property def ignoreHiddenFiles(self): """ Property for **self.__ignoreHiddenFiles** attribute. :return: self.__ignoreHiddenFiles. :rtype: bool """ return self.__ignoreHiddenFiles @ignoreHiddenFiles.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def ignoreHiddenFiles(self, value): """ Setter for **self.__ignoreHiddenFiles** attribute. :param value: Attribute value. :type value: bool """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "ignoreHiddenFiles")) @ignoreHiddenFiles.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def ignoreHiddenFiles(self): """ Deleter for **self.__ignoreHiddenFiles** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "ignoreHiddenFiles")) @property def searchWorkerThread(self): """ Property for **self.__searchWorkerThread** attribute. :return: self.__searchWorkerThread. :rtype: QThread """ return self.__searchWorkerThread @searchWorkerThread.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def searchWorkerThread(self, value): """ Setter for **self.__searchWorkerThread** attribute. :param value: Attribute value. :type value: QThread """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "searchWorkerThread")) @searchWorkerThread.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def searchWorkerThread(self): """ Deleter for **self.__searchWorkerThread** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "searchWorkerThread")) #****************************************************************************************************************** #*** Class methods #****************************************************************************************************************** def show(self): """ Reimplements the :meth:`QWidget.show` method. """ selectedText = self.__container.getCurrentEditor().getSelectedText() selectedText and SearchAndReplace.insertPattern(selectedText, self.__searchPatternsModel) self.Search_comboBox.lineEdit().selectAll() self.Search_comboBox.setFocus() super(SearchInFiles, self).show() self.raise_() def closeEvent(self, event): """ Reimplements the :meth:`QWidget.closeEvent` method. :param event: QEvent. :type event: QEvent """ self.__interruptSearch() super(SearchInFiles, self).closeEvent(event) def __initializeUi(self): """ Initializes the Widget ui. """ umbra.ui.common.setWindowDefaultIcon(self) self.__model = SearchResultsModel(self) self.__delegate = RichText_QStyledItemDelegate(self) self.Search_Results_treeView.setParent(None) self.Search_Results_treeView = SearchResults_QTreeView(self, self.__model, message="No Search Result to view!") self.Search_Results_treeView.setItemDelegate(self.__delegate) self.Search_Results_treeView.setObjectName("Search_Results_treeView") self.Search_Results_frame_gridLayout.addWidget(self.Search_Results_treeView, 0, 0) self.__view = self.Search_Results_treeView self.__view.setContextMenuPolicy(Qt.ActionsContextMenu) self.__view_addActions() self.__searchPatternsModel = self.__container.searchAndReplace.searchPatternsModel self.Search_comboBox.setModel(self.__container.searchAndReplace.searchPatternsModel) self.Search_comboBox.setInsertPolicy(QComboBox.InsertAtTop) self.Search_comboBox.completer().setCaseSensitivity(Qt.CaseSensitive) self.__replaceWithPatternsModel = self.__container.searchAndReplace.replaceWithPatternsModel self.Replace_With_comboBox.setModel(self.__container.searchAndReplace.replaceWithPatternsModel) self.Replace_With_comboBox.setInsertPolicy(QComboBox.InsertAtTop) self.Replace_With_comboBox.completer().setCaseSensitivity(Qt.CaseSensitive) self.Where_lineEdit.setParent(None) self.Where_lineEdit = Search_QLineEdit(self) self.Where_lineEdit.setObjectName("Where_lineEdit") self.Where_frame_gridLayout.addWidget(self.Where_lineEdit, 0, 0) self.__locationsMenu = QMenu() for title, location in self.__locations.iteritems(): self.__locationsMenu.addAction(self.__container.engine.actionsManager.registerAction( "Actions|Umbra|Components|factory.scriptEditor|Search In Files|{0}".format(title), text="{0}".format(title), slot=functools.partial(self.__addLocation, location))) self.Where_lineEdit.searchActiveLabel.setMenu(self.__locationsMenu) self.Where_lineEdit.setPlaceholderText("Use the magnifier to add locations!") self.installEventFilter(ValidationFilter(self)) # Signals / Slots. self.__view.selectionModel().selectionChanged.connect(self.__view_selectionModel__selectionChanged) self.__view.doubleClicked.connect(self.__view__doubleClicked) self.__searchPatternsModel.patternInserted.connect(functools.partial( self.__patternsModel__patternInserted, self.Search_comboBox)) self.__replaceWithPatternsModel.patternInserted.connect(functools.partial( self.__patternsModel__patternInserted, self.Replace_With_comboBox)) self.Search_pushButton.clicked.connect(self.__Search_pushButton__clicked) self.Close_pushButton.clicked.connect(self.__Close_pushButton__clicked) def __view_addActions(self): """ Sets the View actions. """ self.__view.addAction(self.__container.engine.actionsManager.registerAction( "Actions|Umbra|Components|factory.scriptEditor|Search In Files|Replace All", slot=self.__view_replaceAllAction__triggered)) self.__view.addAction(self.__container.engine.actionsManager.registerAction( "Actions|Umbra|Components|factory.scriptEditor|Search In Files|Replace Selected", slot=self.__view_replaceSelectedAction__triggered)) separatorAction = QAction(self.__view) separatorAction.setSeparator(True) self.__view.addAction(separatorAction) self.__view.addAction(self.__container.engine.actionsManager.registerAction( "Actions|Umbra|Components|factory.scriptEditor|Search In Files|Save All", slot=self.__view_saveAllAction__triggered)) self.__view.addAction(self.__container.engine.actionsManager.registerAction( "Actions|Umbra|Components|factory.scriptEditor|Search In Files|Save Selected", slot=self.__view_saveSelectedAction__triggered)) def __view_replaceAllAction__triggered(self, checked): """ Defines the slot triggered by **'Actions|Umbra|Components|factory.scriptEditor|Search In Files|Replace All'** action. :param checked: Action checked state. :type checked: bool :return: Method success. :rtype: bool """ allNodes = filter(lambda x: x.family in ("SearchFile", "SearchOccurence"), self.__model.rootNode.children) if allNodes: return self.replace(allNodes) def __view_replaceSelectedAction__triggered(self, checked): """ Defines the slot triggered by **'Actions|Umbra|Components|factory.scriptEditor|Search In Files|Replace Selected'** action. :param checked: Action checked state. :type checked: bool :return: Method success. :rtype: bool """ selectedNodes = filter(lambda x: x.family in ("SearchFile", "SearchOccurence"), self.__view.getSelectedNodes()) if selectedNodes: return self.replace(filter(lambda x: x.parent not in selectedNodes, selectedNodes)) def __view_saveAllAction__triggered(self, checked): """ Defines the slot triggered by **'Actions|Umbra|Components|factory.scriptEditor|Search In Files|Save All'** action. :param checked: Action checked state. :type checked: bool :return: Method success. :rtype: bool """ allNodes = filter(lambda x: x.family is "ReplaceResult", self.__model.rootNode.children) if allNodes: return self.saveFiles(allNodes) def __view_saveSelectedAction__triggered(self, checked): """ Defines the slot triggered by **'Actions|Umbra|Components|factory.scriptEditor|Search In Files|Save Selected'** action. :param checked: Action checked state. :type checked: bool :return: Method success. :rtype: bool """ selectedNodes = filter(lambda x: x.family is "ReplaceResult", self.__view.getSelectedNodes()) if selectedNodes: return self.saveFiles(selectedNodes) def __patternsModel__patternInserted(self, comboBox, index): """ Defines the slot triggered by a pattern when inserted into a patterns Model. :param comboBox: Pattern Model attached comboBox. :type comboBox: QComboBox :param index: Inserted pattern index. :type index: QModelIndex """ comboBox.setCurrentIndex(index.row()) def __Search_pushButton__clicked(self, checked): """ Defines the slot triggered by **Search_pushButton** Widget when clicked. :param checked: Checked state. :type checked: bool """ self.search() def __Close_pushButton__clicked(self, checked): """ Defines the slot triggered by **Close_pushButton** Widget when clicked. :param checked: Checked state. :type checked: bool """ self.close() def __view__doubleClicked(self, index): """ Defines the slot triggered by a View when double clicked. :param index: Clicked item index. :type index: QModelIndex """ node = self.__model.getNode(index) if node.family == "SearchOccurence": file = node.parent.file occurence = node elif node.family in ("SearchFile", "ReplaceResult"): file = node.file occurence = None self.__highlightOccurence(file, occurence) def __view_selectionModel__selectionChanged(self, selectedItems, deselectedItems): """ Defines the slot triggered by the View **selectionModel** when selection changed. :param selectedItems: Selected items. :type selectedItems: QItemSelection :param deselectedItems: Deselected items. :type deselectedItems: QItemSelection """ indexes = selectedItems.indexes() if not indexes: return node = self.__model.getNode(indexes.pop()) if node.family == "SearchOccurence": file = node.parent.file occurence = node elif node.family in ("SearchFile", "ReplaceResult"): file = node.file occurence = None if self.__container.getEditor(file): self.__highlightOccurence(file, occurence) def __searchWorkerThread__searchFinished(self, searchResults): """ Defines the slot triggered by :attr:`SearchInFiles.grepWorkerThread` attribute worker thread when the search is finished. :param searchResults: Search results. :type searchResults: list """ self.setSearchResults(searchResults) self.__container.engine.stopProcessing() metrics = self.__model.getMetrics() self.__container.engine.notificationsManager.notify( "{0} | '{1}' pattern occurence(s) found in '{2}' files!".format(self.__class__.__name__, metrics["SearchOccurence"], metrics["SearchFile"])) def __addLocation(self, type, *args): """ Defines the slot triggered by **Where_lineEdit** Widget when a context menu entry is clicked. :param type: Location type. :type type: unicode :param \*args: Arguments. :type \*args: \* """ if type == "directory": location = umbra.ui.common.storeLastBrowsedPath((QFileDialog.getExistingDirectory(self, "Add Directory:", RuntimeGlobals.lastBrowsedPath))) elif type == "file": location = umbra.ui.common.storeLastBrowsedPath((QFileDialog.getOpenFileName(self, "Add File:", RuntimeGlobals.lastBrowsedPath, "All Files (*)"))) elif type == "editors": location = self.__targetsFormat.format(self.__defaultTarget) elif type == "includeFilter": location = self.__filtersInFormat.format(self.__defaultFilterIn) elif type == "excludeFilter": location = self.__filtersOutFormat.format(self.__defaultFilterOut) location and self.Where_lineEdit.setText(", ".join(filter(bool, (foundations.strings.toString( self.Where_lineEdit.text()), location)))) def __formatOccurence(self, occurence): """ Formats the given occurence and returns the matching rich html text. :param occurence: Occurence to format. :type occurence: Occurence :return: Rich text. :rtype: unicode """ color = "rgb({0}, {1}, {2})" spanFormat = "<span style=\"color: {0};\">{{0}}</span>".format(color.format(self.__defaultLineColor.red(), self.__defaultLineColor.green(), self.__defaultLineColor.blue())) line = foundations.strings.toString(occurence.text) start = spanFormat.format(line[:occurence.column]) pattern = "<b>{0}</b>".format(line[occurence.column:occurence.column + occurence.length]) end = spanFormat.format(line[occurence.column + occurence.length:]) return "".join((start, pattern, end)) def __formatReplaceMetrics(self, file, metrics): """ Formats the given replace metrics and returns the matching rich html text. :param file: File. :type file: unicode :param metrics: Replace metrics to format. :type metrics: unicode :return: Rich text. :rtype: unicode """ color = "rgb({0}, {1}, {2})" spanFormat = "<span style=\"color: {0};\">{{0}}</span>".format(color.format(self.__defaultLineColor.red(), self.__defaultLineColor.green(), self.__defaultLineColor.blue())) dirName, baseName = (os.path.dirname(file), os.path.basename(file)) return "".join((spanFormat.format("'"), spanFormat.format(dirName), spanFormat.format(os.path.sep), baseName, spanFormat.format("' file: '"), foundations.strings.toString(metrics), spanFormat.format("' occurence(s) replaced!"))) def __highlightOccurence(self, file, occurence): """ Highlights given file occurence. :param file: File containing the occurence. :type file: unicode :param occurence: Occurence to highlight. :type occurence: Occurence or SearchOccurenceNode """ if not self.__container.getEditor(file): cacheData = self.__filesCache.getContent(file) if cacheData: document = cacheData.document or self.__getDocument(cacheData.content) self.__container.loadDocument(document, file) self.__uncache(file) else: self.__container.loadFile(file) else: self.__container.setCurrentEditor(file) if not occurence: return cursor = self.__container.getCurrentEditor().textCursor() cursor.setPosition(occurence.position, QTextCursor.MoveAnchor) cursor.setPosition(occurence.position + occurence.length, QTextCursor.KeepAnchor) self.__container.getCurrentEditor().setTextCursor(cursor) def __getDocument(self, content): """ Returns a `QTextDocument <http://doc.qt.nokia.com/qtextdocument.html>`_ class instance with given content. :return: Document. :rtype: QTextDocument """ document = QTextDocument(QString(content)) document.clearUndoRedoStacks() document.setModified(False) return document def __replaceWithinDocument(self, document, occurrences, replacementPattern): """ Replaces given pattern occurrences in given document using given settings. :param document: Document. :type document: QTextDocument :param replacementPattern: Replacement pattern. :type replacementPattern: unicode :return: Replaced occurrences count. :rtype: int """ cursor = QTextCursor(document) cursor.beginEditBlock() offset = count = 0 for occurence in sorted(occurrences, key=lambda x: x.position): cursor.setPosition(offset + occurence.position, QTextCursor.MoveAnchor) cursor.setPosition(offset + occurence.position + occurence.length, QTextCursor.KeepAnchor) cursor.insertText(replacementPattern) offset += len(replacementPattern) - occurence.length count += 1 cursor.endEditBlock() return count def __getSettings(self): """ Returns the current search and replace settings. :return: Settings. :rtype: dict """ return {"caseSensitive" : self.Case_Sensitive_checkBox.isChecked(), "wholeWord" : self.Whole_Word_checkBox.isChecked(), "regularExpressions" : self.Regular_Expressions_checkBox.isChecked()} def __interruptSearch(self): """ Interrupt the current search. """ if self.__searchWorkerThread: self.__searchWorkerThread.quit() self.__searchWorkerThread.wait() self.__container.engine.stopProcessing(warning=False) def __cache(self, file, content, document): """ Caches given file. :param file: File to cache. :type file: unicode :param content: File content. :type content: list :param document: File document. :type document: QTextDocument """ self.__filesCache.addContent(**{file : CacheData(content=content, document=document)}) def __uncache(self, file): """ Uncaches given file. :param file: File to uncache. :type file: unicode """ if file in self.__filesCache: self.__filesCache.removeContent(file) def setSearchResults(self, searchResults): """ Sets the Model Nodes using given search results. :param searchResults: Search results. :type searchResults: list :return: Method success. :rtype: bool """ rootNode = umbra.ui.nodes.DefaultNode(name="InvisibleRootNode") for searchResult in searchResults: searchFileNode = SearchFileNode(name=searchResult.file, parent=rootNode) searchFileNode.update(searchResult) width = \ max(self.__defaultLineNumberWidth, max([len(foundations.strings.toString(occurence.line)) for occurence in searchResult.occurrences])) for occurence in searchResult.occurrences: formatter = "{{0:>{0}}}".format(width) name = "{0}:{1}".format(formatter.format(occurence.line + 1).replace(" ", " "), self.__formatOccurence(occurence)) searchOccurenceNode = SearchOccurenceNode(name=name, parent=searchFileNode) searchOccurenceNode.update(occurence) self.__model.initializeModel(rootNode) return True def setReplaceResults(self, replaceResults): """ Sets the Model Nodes using given replace results. :param replaceResults: Replace results. :type replaceResults: list :return: Method success. :rtype: bool """ rootNode = umbra.ui.nodes.DefaultNode(name="InvisibleRootNode") for file, metrics in sorted(replaceResults.iteritems()): replaceResultNode = ReplaceResultNode(name=self.__formatReplaceMetrics(file, metrics), parent=rootNode, file=file) self.__model.initializeModel(rootNode) return True def search(self): """ Searchs user defined locations for search pattern. :return: Method success. :rtype: bool """ self.__interruptSearch() searchPattern = self.Search_comboBox.currentText() replacementPattern = self.Replace_With_comboBox.currentText() if not searchPattern: return False SearchAndReplace.insertPattern(searchPattern, self.__searchPatternsModel) SearchAndReplace.insertPattern(replacementPattern, self.__replaceWithPatternsModel) location = umbra.ui.common.parseLocation( foundations.strings.toString(self.Where_lineEdit.text()) or \ self.__targetsFormat.format(self.__defaultTarget)) self.__ignoreHiddenFiles and location.filtersOut.append("\\\.|/\.") settings = self.__getSettings() self.__searchWorkerThread = Search_worker(self, searchPattern, location, settings) # Signals / Slots. self.__searchWorkerThread.searchFinished.connect(self.__searchWorkerThread__searchFinished) self.__container.engine.workerThreads.append(self.__searchWorkerThread) self.__container.engine.startProcessing("Searching In Files ...") self.__searchWorkerThread.start() return True def replace(self, nodes): """ Replaces user defined files search pattern occurrences with replacement pattern using given nodes. :param nodes: Nodes. :type nodes: list :return: Method success. :rtype: bool """ files = {} for node in nodes: if node.family == "SearchFile": files[node.file] = node.children elif node.family == "SearchOccurence": file = node.parent.file if not file in files: files[file] = [] files[file].append(node) replacementPattern = self.Replace_With_comboBox.currentText() SearchAndReplace.insertPattern(replacementPattern, self.__replaceWithPatternsModel) replaceResults = {} for file, occurrences in files.iteritems(): editor = self.__container.getEditor(file) if editor: document = editor.document() else: cacheData = self.__filesCache.getContent(file) if cacheData is None: LOGGER.warning( "!> {0} | '{1}' file doesn't exists in files cache!".format(self.__class__.__name__, file)) continue content = self.__filesCache.getContent(file).content document = self.__getDocument(content) self.__cache(file, content, document) replaceResults[file] = self.__replaceWithinDocument(document, occurrences, replacementPattern) self.setReplaceResults(replaceResults) self.__container.engine.notificationsManager.notify( "{0} | '{1}' pattern occurence(s) replaced in '{2}' files!".format(self.__class__.__name__, sum(replaceResults.values()), len(replaceResults.keys()))) def saveFiles(self, nodes): """ Saves user defined files using give nodes. :param nodes: Nodes. :type nodes: list :return: Method success. :rtype: bool """ metrics = {"Opened" : 0, "Cached" : 0} for node in nodes: file = node.file if self.__container.getEditor(file): if self.__container.saveFile(file): metrics["Opened"] += 1 self.__uncache(file) else: cacheData = self.__filesCache.getContent(file) if cacheData is None: LOGGER.warning( "!> {0} | '{1}' file doesn't exists in files cache!".format(self.__class__.__name__, file)) continue if cacheData.document: fileHandle = File(file) fileHandle.content = [cacheData.document.toPlainText().toUtf8()] if fileHandle.write(): metrics["Cached"] += 1 self.__uncache(file) else: LOGGER.warning( "!> {0} | '{1}' file document doesn't exists in files cache!".format(self.__class__.__name__, file)) self.__container.engine.notificationsManager.notify( "{0} | '{1}' opened file(s) and '{2}' cached file(s) saved!".format(self.__class__.__name__, metrics["Opened"], metrics["Cached"]))
class SearchDatabase(QWidgetComponentFactory(uiFile=COMPONENT_UI_FILE)): """ | Defines the :mod:`sibl_gui.components.addons.searchDatabase.searchDatabase` Component Interface class. | It provides methods for the user to search into the Database using various filters. """ def __init__(self, parent=None, name=None, *args, **kwargs): """ Initializes the class. :param parent: Object parent. :type parent: QObject :param name: Component name. :type name: unicode :param \*args: Arguments. :type \*args: \* :param \*\*kwargs: Keywords arguments. :type \*\*kwargs: \*\* """ LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__)) super(SearchDatabase, self).__init__(parent, name, *args, **kwargs) # --- Setting class attributes. --- self.deactivatable = True self.__dockArea = 2 self.__viewSpacing = 4 self.__engine = None self.__iblSetsOutliner = None self.__collectionsOutliner = None self.__view = None self.__cloudExcludedTags = ("a", "and", "by", "for", "from", "in", "of", "on", "or", "the", "to", "with") #****************************************************************************************************************** #*** Attributes properties. #****************************************************************************************************************** @property def dockArea(self): """ Property for **self.__dockArea** attribute. :return: self.__dockArea. :rtype: int """ return self.__dockArea @dockArea.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def dockArea(self, value): """ Setter for **self.__dockArea** attribute. :param value: Attribute value. :type value: int """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "dockArea")) @dockArea.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def dockArea(self): """ Deleter for **self.__dockArea** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "dockArea")) @property def viewSpacing(self): """ Property for **self.__viewSpacing** attribute. :return: self.__viewSpacing. :rtype: int """ return self.__viewSpacing @viewSpacing.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def viewSpacing(self, value): """ Setter for **self.__viewSpacing** attribute. :param value: Attribute value. :type value: int """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "viewSpacing")) @viewSpacing.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def viewSpacing(self): """ Deleter for **self.__viewSpacing** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "viewSpacing")) @property def engine(self): """ Property for **self.__engine** attribute. :return: self.__engine. :rtype: QObject """ return self.__engine @engine.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def engine(self, value): """ Setter for **self.__engine** attribute. :param value: Attribute value. :type value: QObject """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "engine")) @engine.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def engine(self): """ Deleter for **self.__engine** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "engine")) @property def iblSetsOutliner(self): """ Property for **self.__iblSetsOutliner** attribute. :return: self.__iblSetsOutliner. :rtype: QWidget """ return self.__iblSetsOutliner @iblSetsOutliner.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def iblSetsOutliner(self, value): """ Setter for **self.__iblSetsOutliner** attribute. :param value: Attribute value. :type value: QWidget """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "iblSetsOutliner")) @iblSetsOutliner.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def iblSetsOutliner(self): """ Deleter for **self.__iblSetsOutliner** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "iblSetsOutliner")) @property def collectionsOutliner(self): """ Property for **self.__collectionsOutliner** attribute. :return: self.__collectionsOutliner. :rtype: QWidget """ return self.__collectionsOutliner @collectionsOutliner.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def collectionsOutliner(self, value): """ Setter for **self.__collectionsOutliner** attribute. :param value: Attribute value. :type value: QWidget """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "collectionsOutliner")) @collectionsOutliner.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def collectionsOutliner(self): """ Deleter for **self.__collectionsOutliner** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "collectionsOutliner")) @property def view(self): """ Property for **self.__view** attribute. :return: self.__view. :rtype: QWidget """ return self.__view @view.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def view(self, value): """ Setter for **self.__view** attribute. :param value: Attribute value. :type value: QWidget """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "view")) @view.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def view(self): """ Deleter for **self.__view** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "view")) @property def cloudExcludedTags(self): """ Property for **self.__cloudExcludedTags** attribute. :return: self.__cloudExcludedTags. :rtype: list """ return self.__cloudExcludedTags @cloudExcludedTags.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def cloudExcludedTags(self, value): """ Setter for **self.__cloudExcludedTags** attribute. :param value: Attribute value. :type value: list """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "cloudExcludedTags")) @cloudExcludedTags.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def cloudExcludedTags(self): """ Deleter for **self.__cloudExcludedTags** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "cloudExcludedTags")) #****************************************************************************************************************** #*** Class methods. #****************************************************************************************************************** def activate(self, engine): """ Activates the Component. :param engine: Engine to attach the Component to. :type engine: QObject :return: Method success. :rtype: bool """ LOGGER.debug("> Activating '{0}' Component.".format(self.__class__.__name__)) self.__engine = engine self.__iblSetsOutliner = self.__engine.componentsManager["core.iblSetsOutliner"] self.__collectionsOutliner = self.__engine.componentsManager["core.collectionsOutliner"] self.activated = True return True def deactivate(self): """ Deactivates the Component. :return: Method success. :rtype: bool """ LOGGER.debug("> Deactivating '{0}' Component.".format(self.__class__.__name__)) self.__engine = None self.__iblSetsOutliner = None self.__collectionsOutliner = None self.activated = False return True def initializeUi(self): """ Initializes the Component ui. :return: Method success. :rtype: bool """ LOGGER.debug("> Initializing '{0}' Component ui.".format(self.__class__.__name__)) umbra.ui.common.setToolBoxHeight(self.Search_toolBox) self.Tags_Cloud_listWidget.setParent(None) self.Tags_Cloud_listWidget = TagsCloud_QListView(self, message="No Tag to view!") self.Tags_Cloud_listWidget.setObjectName("Tags_Cloud_listWidget") self.Tags_Cloud_verticalLayout.addWidget(self.Tags_Cloud_listWidget) self.__view = self.Tags_Cloud_listWidget self.__view.setMovement(QListView.Static) self.__view.setResizeMode(QListView.Adjust) self.__view.setViewMode(QListView.IconMode) self.Search_Database_lineEdit = Search_QLineEdit(self) self.Search_Database_lineEdit.setPlaceholderText("Search In Tags Cloud ...") self.Search_Database_horizontalLayout.addWidget(self.Search_Database_lineEdit) self.__view.setSpacing(self.__viewSpacing) self.__cloudExcludedTags = list(itertools.chain.from_iterable( [(r"^{0}$".format(tag), r"^{0}$".format(tag.title()), r"^{0}$".format(tag.upper())) for tag in self.__cloudExcludedTags])) self.setTagsCloudMatchingIblsSetsUi() # Remove vertical scrollBars from **Search_toolBox** Widget. for scrollArea in self.findChildren(QScrollArea): scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # Signals / Slots. self.Search_Database_lineEdit.textChanged.connect(self.__Search_Database_lineEdit__textChanged) self.Case_Sensitive_Matching_pushButton.clicked.connect(self.__Case_Sensitive_Matching_pushButton__clicked) self.Time_Low_timeEdit.timeChanged.connect(self.__Time_Low_timeEdit__timeChanged) self.Time_High_timeEdit.timeChanged.connect(self.__Time_High_timeEdit__timeChanged) self.__view.itemDoubleClicked.connect(self.__view__doubleClicked) self.__collectionsOutliner.view.selectionModel().selectionChanged.connect( self.__collectionsOutliner_view_selectionModel__selectionChanged) self.initializedUi = True return True def uninitializeUi(self): """ Uninitializes the Component ui. :return: Method success. :rtype: bool """ LOGGER.debug("> Uninitializing '{0}' Component ui.".format(self.__class__.__name__)) # Signals / Slots. self.Search_Database_lineEdit.textChanged.disconnect(self.__Search_Database_lineEdit__textChanged) self.Case_Sensitive_Matching_pushButton.clicked.disconnect(self.__Case_Sensitive_Matching_pushButton__clicked) self.Time_Low_timeEdit.timeChanged.disconnect(self.__Time_Low_timeEdit__timeChanged) self.Time_High_timeEdit.timeChanged.disconnect(self.__Time_High_timeEdit__timeChanged) self.__view.itemDoubleClicked.disconnect(self.__view__doubleClicked) self.__collectionsOutliner.view.selectionModel().selectionChanged.disconnect( self.__collectionsOutliner_view_selectionModel__selectionChanged) self.Search_Database_lineEdit.setParent(None) self.Search_Database_lineEdit = None self.initializedUi = False return True def addWidget(self): """ Adds the Component Widget to the engine. :return: Method success. :rtype: bool """ LOGGER.debug("> Adding '{0}' Component Widget.".format(self.__class__.__name__)) self.__engine.addDockWidget(Qt.DockWidgetArea(self.__dockArea), self) return True def removeWidget(self): """ Removes the Component Widget from the engine. :return: Method success. :rtype: bool """ LOGGER.debug("> Removing '{0}' Component Widget.".format(self.__class__.__name__)) self.__engine.removeDockWidget(self) self.setParent(None) return True def __Search_Database_lineEdit__textChanged(self, text): """ Defines the slot triggered by **Search_Database_lineEdit** Widget when text changed. :param text: Current text value. :type text: QString """ self.setTagsCloudMatchingIblsSetsUi() def __Case_Sensitive_Matching_pushButton__clicked(self, checked): """ Defines the slot triggered by **Case_Sensitive_Matching_pushButton** Widget when clicked. :param checked: Checked state. :type checked: bool """ self.setTagsCloudMatchingIblsSetsUi() def __Time_Low_timeEdit__timeChanged(self, time): """ Defines the slot triggered by **Time_Low_timeEdit** Widget when time changed. :param time: Current time. :type time: QTime """ self.Time_Low_timeEdit.time() >= self.Time_High_timeEdit.time() and \ self.Time_Low_timeEdit.setTime(self.Time_High_timeEdit.time().addSecs(-60)) self.setTimeMatchingIblSetsUi() def __Time_High_timeEdit__timeChanged(self, time): """ Defines the slot triggered by **Time_Low_timeEdit** Widget when time changed. :param time: Current time. :type time: QTime """ self.Time_High_timeEdit.time() <= self.Time_Low_timeEdit.time() and \ self.Time_High_timeEdit.setTime(self.Time_Low_timeEdit.time().addSecs(60)) self.setTimeMatchingIblSetsUi() def __view__doubleClicked(self, listWidgetItem): """ Defines the slot triggered by the View when double clicked. :param listWidgetItem: List Widget item. :type listWidgetItem: QlistWidgetItem """ self.Search_Database_lineEdit.setText("{0} {1}".format(self.Search_Database_lineEdit.text(), listWidgetItem.text())) def __collectionsOutliner_view_selectionModel__selectionChanged(self, selectedItems, deselectedItems): """ Defines the slot triggered by **collectionsOutliner.view** Model when selection changed :param selectedItems: Selected items. :type selectedItems: QItemSelection :param deselectedItems: Deselected items. :type deselectedItems: QItemSelection """ self.setTagsCloudMatchingIblsSetsUi() def setTagsCloudMatchingIblsSetsUi(self): """ Sets the user defined pattern matching Ibl Sets and updates :mod:`sibl_gui.components.core.iblSetsOutliner.iblSetsOutliner` Component Model content. :return: Method success. :rtype: bool :note: May require user interaction. """ return self.setTagsCloudMatchingIblsSets(foundations.strings.toString(self.Search_Database_lineEdit.text()), not self.Case_Sensitive_Matching_pushButton.isChecked() and re.IGNORECASE or 0) def setTimeMatchingIblSetsUi(self): """ Sets the user defined time matching Ibl Sets and updates :mod:`sibl_gui.components.core.iblSetsOutliner.iblSetsOutliner` Component Model content. :return: Method success. :rtype: bool :note: May require user interaction. """ return self.setTimeMatchingIblSets(self.Time_Low_timeEdit.time(), self.Time_High_timeEdit.time()) def setTagsCloudMatchingIblsSets(self, pattern, flags=re.IGNORECASE): """ Sets the pattern matching Ibl Sets and updates :mod:`sibl_gui.components.core.iblSetsOutliner.iblSetsOutliner` Component Model content. :param pattern: Filtering pattern. :type pattern: unicode :param flags: Regex filtering flags. :type flags: int :return: Method success. :rtype: bool """ LOGGER.debug("> Filtering Ibl Sets by Tags.") patternsDefault = (".*",) patternTokens = pattern.split() or patternsDefault allTags = set() filteredIblSets = [] iblSets = self.__collectionsOutliner.getCollectionsIblSets( self.__collectionsOutliner.getSelectedCollections() or self.__collectionsOutliner.getCollections()) for iblSet in iblSets: comment = getattr(iblSet, "comment") if not comment: continue tagsCloud = foundations.strings.filterWords(foundations.strings.getWords(comment), filtersOut=self.__cloudExcludedTags, flags=flags) patternsMatched = True if patternTokens != patternsDefault: for pattern in patternTokens: patternMatched = False try: pattern = re.compile(pattern, flags) for tag in tagsCloud: if re.search(pattern, tag, flags=flags): patternMatched = True break except re.error: LOGGER.warning("!> {0} | '{1}' regex pattern is invalid!".format(self.__class__.__name__, pattern)) patternsMatched *= patternMatched if patternsMatched: allTags.update(tagsCloud) filteredIblSets.append(iblSet) self.__view.clear() self.__view.addItems(sorted(allTags, key=lambda x:x.lower())) if Counter(filteredIblSets) != Counter(iblSets) or \ len(self.__iblSetsOutliner.getActiveView().filterNodes("IblSet", "family")) != len(iblSets): filteredIblSets = [iblSet for iblSet in set(iblSets).intersection(set(filteredIblSets))] LOGGER.debug("> Tags Cloud filtered Ibl Set(s): '{0}'".format( ", ".join((foundations.strings.toString(iblSet.name) for iblSet in filteredIblSets)))) self.__iblSetsOutliner.setIblSets(filteredIblSets) return True def setTimeMatchingIblSets(self, timeLow, timeHigh): """ Sets the time matching Ibl Sets and updates :mod:`sibl_gui.components.core.iblSetsOutliner.iblSetsOutliner` Component Model content. :param timeLow: Time low. :type timeLow: QTime :param timeHigh: Time high. :type timeHigh: QTime :return: Method success. :rtype: bool """ LOGGER.debug("> Filtering Ibl Sets by time range from '{0}' to '{1}'.".format(timeLow, timeHigh)) iblSets = self.__collectionsOutliner.getCollectionsIblSets( self.__collectionsOutliner.getSelectedCollections()) filteredIblSets = [] for iblSet in iblSets: if not iblSet.time: continue hours, minutes, seconds = iblSet.time.split(":") int(hours) * 60 + int(minutes) >= timeLow.hour() * 60 + timeLow.minute() and \ int(hours) * 60 + int(minutes) <= timeHigh.hour() * 60 + timeHigh.minute() and \ filteredIblSets.append(iblSet) filteredIblSets = [iblSet for iblSet in set(iblSets).intersection(filteredIblSets)] if Counter(filteredIblSets) != Counter(iblSets) or \ len(self.__iblSetsOutliner.getActiveView().filterNodes("IblSet", "family")) != len(iblSets): LOGGER.debug("> Time range filtered Ibl Set(s): '{0}'".format( ", ".join((iblSet.name for iblSet in filteredIblSets)))) self.__iblSetsOutliner.setIblSets(filteredIblSets) return True
class TraceUi(QWidgetComponentFactory(uiFile=COMPONENT_UI_FILE)): """ Defines the :mod:`umbra.components.addons.traceUi.traceUi` Component Interface class. """ # Custom signals definitions. refreshNodes = pyqtSignal() """ This signal is emited by the :class:`TraceUi` class when :obj:`TraceUi.model` class property model nodes needs to be refreshed. ( pyqtSignal ) """ def __init__(self, parent=None, name=None, *args, **kwargs): """ Initializes the class. :param parent: Object parent. :type parent: QObject :param name: Component name. :type name: unicode :param \*args: Arguments. :type \*args: \* :param \*\*kwargs: Keywords arguments. :type \*\*kwargs: \*\* """ LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__)) super(TraceUi, self).__init__(parent, name, *args, **kwargs) # --- Setting class attributes. --- self.deactivatable = True self.__dockArea = 1 self.__engine = None self.__settings = None self.__settingsSection = None self.__model = None self.__view = None self.__headers = OrderedDict([("Module", "name"), ("Traced", "traced")]) #****************************************************************************************************************** #*** Attributes properties. #****************************************************************************************************************** @property def dockArea(self): """ Property for **self.__dockArea** attribute. :return: self.__dockArea. :rtype: int """ return self.__dockArea @dockArea.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def dockArea(self, value): """ Setter for **self.__dockArea** attribute. :param value: Attribute value. :type value: int """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "dockArea")) @dockArea.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def dockArea(self): """ Deleter for **self.__dockArea** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "dockArea")) @property def engine(self): """ Property for **self.__engine** attribute. :return: self.__engine. :rtype: QObject """ return self.__engine @engine.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def engine(self, value): """ Setter for **self.__engine** attribute. :param value: Attribute value. :type value: QObject """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "engine")) @engine.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def engine(self): """ Deleter for **self.__engine** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "engine")) @property def settings(self): """ Property for **self.__settings** attribute. :return: self.__settings. :rtype: QSettings """ return self.__settings @settings.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def settings(self, value): """ Setter for **self.__settings** attribute. :param value: Attribute value. :type value: QSettings """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "settings")) @settings.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def settings(self): """ Deleter for **self.__settings** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "settings")) @property def settingsSection(self): """ Property for **self.__settingsSection** attribute. :return: self.__settingsSection. :rtype: unicode """ return self.__settingsSection @settingsSection.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def settingsSection(self, value): """ Setter for **self.__settingsSection** attribute. :param value: Attribute value. :type value: unicode """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "settingsSection")) @settingsSection.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def settingsSection(self): """ Deleter for **self.__settingsSection** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "settingsSection")) @property def model(self): """ Property for **self.__model** attribute. :return: self.__model. :rtype: CollectionsModel """ return self.__model @model.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def model(self, value): """ Setter for **self.__model** attribute. :param value: Attribute value. :type value: CollectionsModel """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "model")) @model.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def model(self): """ Deleter for **self.__model** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "model")) @property def view(self): """ Property for **self.__view** attribute. :return: self.__view. :rtype: QWidget """ return self.__view @view.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def view(self, value): """ Setter for **self.__view** attribute. :param value: Attribute value. :type value: QWidget """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "view")) @view.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def view(self): """ Deleter for **self.__view** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "view")) @property def headers(self): """ Property for **self.__headers** attribute. :return: self.__headers. :rtype: OrderedDict """ return self.__headers @headers.setter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def headers(self, value): """ Setter for **self.__headers** attribute. :param value: Attribute value. :type value: OrderedDict """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "headers")) @headers.deleter @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def headers(self): """ Deleter for **self.__headers** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "view")) #****************************************************************************************************************** #*** Class methods. #****************************************************************************************************************** def activate(self, engine): """ Activates the Component. :param engine: Engine to attach the Component to. :type engine: QObject :return: Method success. :rtype: bool """ LOGGER.debug("> Activating '{0}' Component.".format(self.__class__.__name__)) self.__engine = engine self.__settings = self.__engine.settings self.__settingsSection = self.name self.activated = True return True def deactivate(self): """ Deactivates the Component. :return: Method success. :rtype: bool """ LOGGER.debug("> Deactivating '{0}' Component.".format(self.__class__.__name__)) self.__engine = None self.__settings = None self.__settingsSection = None self.activated = False return True def initializeUi(self): """ Initializes the Component ui. :return: Method success. :rtype: bool """ LOGGER.debug("> Initializing '{0}' Component ui.".format(self.__class__.__name__)) self.Trace_Modules_Filter_lineEdit = Search_QLineEdit(self) self.Trace_Modules_Filter_lineEdit.searchActiveLabel.hide() self.Trace_Modules_Filter_lineEdit.setPlaceholderText("Objects Trace Filter ...") self.Trace_Modules_Filter_horizontalLayout.addWidget(self.Trace_Modules_Filter_lineEdit) self.__model = ModulesModel(self, horizontalHeaders=self.__headers) self.Modules_treeView.setParent(None) self.Modules_treeView = Modules_QTreeView(self, self.__model) self.Modules_treeView.setObjectName("Modules_treeView") self.Modules_treeView.setContextMenuPolicy(Qt.ActionsContextMenu) self.Trace_Ui_dockWidgetContents_gridLayout.addWidget(self.Modules_treeView, 0, 0) self.__view = self.Modules_treeView self.__view_addActions() self.setModules() # Signals / Slots. self.refreshNodes.connect(self.__model__refreshNodes) self.initializedUi = True return True def uninitializeUi(self): """ Uninitializes the Component ui. :return: Method success. :rtype: bool """ LOGGER.debug("> Uninitializing '{0}' Component ui.".format(self.__class__.__name__)) # Signals / Slots. self.refreshNodes.disconnect(self.__model__refreshNodes) self.__view_removeActions() self.__model = None self.__view = None self.initializedUi = False return True def addWidget(self): """ Adds the Component Widget to the engine. :return: Method success. :rtype: bool """ LOGGER.debug("> Adding '{0}' Component Widget.".format(self.__class__.__name__)) self.__engine.addDockWidget(Qt.DockWidgetArea(self.__dockArea), self) return True def removeWidget(self): """ Removes the Component Widget from the engine. :return: Method success. :rtype: bool """ LOGGER.debug("> Removing '{0}' Component Widget.".format(self.__class__.__name__)) self.__engine.removeDockWidget(self) self.setParent(None) return True def __model__refreshNodes(self): """ Defines the slot triggered by the Model when Nodes need refresh. """ self.setModules() def __model__refreshAttributes(self): """ Refreshes the Model Nodes attributes. """ for node in foundations.walkers.nodesWalker(self.__model.rootNode): if foundations.trace.isTraced(node.module) == node.traced.value: continue node.updateNodeAttributes() def __view_addActions(self): """ Sets the View actions. """ self.__view.addAction(self.__engine.actionsManager.registerAction( "Actions|Umbra|Components|addons.traceUi|Trace Module(s)", slot=self.__view_traceModulesAction__triggered)) self.__view.addAction(self.__engine.actionsManager.registerAction( "Actions|Umbra|Components|addons.traceUi|Untrace Module(s)", slot=self.__view_untraceModulesAction__triggered)) def __view_removeActions(self): """ Removes the View actions. """ traceModulesAction = "Actions|Umbra|Components|addons.traceUi|Trace Module(s)" untraceModulesAction = "Actions|Umbra|Components|addons.traceUi|Untrace Module(s)" for action in (traceModulesAction, untraceModulesAction): self.__view.removeAction(self.__engine.actionsManager.getAction(action)) self.__engine.actionsManager.unregisterAction(action) def __view_traceModulesAction__triggered(self, checked): """ Defines the slot triggered by **'Actions|Umbra|Components|addons.traceUi|Trace Module(s)'** action. :param checked: Action checked state. :type checked: bool :return: Method success. :rtype: bool """ pattern = foundations.strings.toString(self.Trace_Modules_Filter_lineEdit.text()) or r".*" flags = re.IGNORECASE if self.Case_Sensitive_Matching_pushButton.isChecked() else 0 return self.traceModules(self.getSelectedModules(), pattern, flags) def __view_untraceModulesAction__triggered(self, checked): """ Defines the slot triggered by **'Actions|Umbra|Components|addons.traceUi|Untrace Module(s)'** action. :param checked: Action checked state. :type checked: bool :return: Method success. :rtype: bool """ return self.untraceModules(self.getSelectedModules()) def getSelectedNodes(self): """ Returns the View selected nodes. :return: View selected nodes. :rtype: dict """ return self.__view.getSelectedNodes() def getSelectedModules(self): """ Returns the View selected modules. :return: View selected modules. :rtype: list """ return [node.module for node in self.getSelectedNodes()] @foundations.exceptions.handleExceptions(umbra.exceptions.notifyExceptionHandler, foundations.exceptions.UserError) def traceModules(self, modules, pattern=r".*", flags=re.IGNORECASE): """ Traces given modules using given filter pattern. :param modules: Modules to trace. :type modules: list :param pattern: Matching pattern. :type pattern: unicode :param flags: Matching regex flags. :type flags: int :return: Method success. :rtype: bool """ try: pattern = re.compile(pattern, flags) except Exception: raise foundations.exceptions.UserError( "{0} | Invalid objects trace filter pattern: Regex compilation failed!".format(self.__class__.__name__)) for module in modules: foundations.trace.traceModule(module, foundations.verbose.tracer, pattern) self.__model__refreshAttributes() return True def untraceModules(self, modules): """ Untraces given modules. :param modules: Modules to untrace. :type modules: list :return: Method success. :rtype: bool """ for module in modules: foundations.trace.untraceModule(module) self.__model__refreshAttributes() return True def getModules(self): """ Sets the registered Modules. :return: Registered modules. :rtype: list """ return foundations.trace.REGISTERED_MODULES def setModules(self, modules=None): """ Sets the modules Model nodes. :param modules: Modules to set. :type modules: list :return: Method success. :rtype: bool """ nodeFlags = int(Qt.ItemIsSelectable | Qt.ItemIsEnabled) modules = modules or self.getModules() rootNode = umbra.ui.nodes.DefaultNode(name="InvisibleRootNode") for module in modules: moduleNode = ModuleNode(module=module, name=foundations.strings.toString(module.__name__), parent=rootNode, nodeFlags=nodeFlags, attributesFlags=int(Qt.ItemIsSelectable | Qt.ItemIsEnabled)) rootNode.sortChildren() self.__model.initializeModel(rootNode) return True