Source code for umbra.components.addons.projectsExplorer.projectsExplorer

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
**projectsExplorer.py**

**Platform:**
	Windows, Linux, Mac Os X.

**Description:**
	This module defines the :class:`ProjectsExplorer` Component Interface class and others helper objects.

**Others:**

"""

#**********************************************************************************************************************
#***	Future imports.
#**********************************************************************************************************************
from __future__ import unicode_literals

#**********************************************************************************************************************
#***	External imports.
#**********************************************************************************************************************
import itertools
import os
import shutil
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QInputDialog
from PyQt4.QtGui import QMessageBox

#**********************************************************************************************************************
#***	Internal imports.
#**********************************************************************************************************************
import foundations.exceptions
import foundations.strings
import foundations.verbose
import umbra.exceptions
import umbra.ui.widgets.messageBox as messageBox
from manager.qwidgetComponent import QWidgetComponentFactory
from umbra.components.addons.projectsExplorer.models import ProjectsProxyModel
from umbra.components.addons.projectsExplorer.views import Projects_QTreeView
from umbra.ui.delegates import RichText_QStyledItemDelegate
from umbra.ui.delegates import Style

#**********************************************************************************************************************
#***	Module attributes.
#**********************************************************************************************************************
__author__ = "Thomas Mansencal"
__copyright__ = "Copyright (C) 2008 - 2013 - Thomas Mansencal"
__license__ = "GPL V3.0 - http://www.gnu.org/licenses/"
__maintainer__ = "Thomas Mansencal"
__email__ = "thomas.mansencal@gmail.com"
__status__ = "Production"

__all__ = ["LOGGER", "COMPONENT_UI_FILE", "ProjectsExplorer"]

LOGGER = foundations.verbose.installLogger()

COMPONENT_UI_FILE = os.path.join(os.path.dirname(__file__), "ui", "Projects_Explorer.ui")

#**********************************************************************************************************************
#***	Module classes and definitions.
#**********************************************************************************************************************
[docs]class ProjectsExplorer(QWidgetComponentFactory(uiFile=COMPONENT_UI_FILE)): """ This class is the :mod:`sibl_gui.components.addons.projectsExplorer.projectsExplorer` Component Interface class. """ def __init__(self, parent=None, name=None, *args, **kwargs): """ .. Sphinx: Statements updated for auto-documentation purpose. :param parent: Object parent. ( QObject ) :param name: Component name. ( String ) :param \*args: Arguments. ( \* ) :param \*\*kwargs: Keywords arguments. ( \*\* ) """ LOGGER.debug("> Initializing '{0}()' class.".format(self.__class__.__name__)) super(ProjectsExplorer, 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.__scriptEditor = None self.__model = None self.__view = None self.__delegate = None self.__style = Style(default=\ """ QLabel, QLabel link { background-color: rgb(32, 32, 32); color: rgb(192, 192, 192); } """, hover=\ """ QLabel, QLabel link { background-color: rgb(64, 64, 64); color: rgb(192, 192, 192); } """, highlight=\ """ QLabel, QLabel link { background-color: rgb(128, 128, 128); color: rgb(224, 224, 224); } """) #****************************************************************************************************************** #*** Attributes properties. #****************************************************************************************************************** @property def dockArea(self): """ This method is the property for **self.__dockArea** attribute. :return: self.__dockArea. ( Integer ) """ return self.__dockArea @dockArea.setter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def dockArea(self, value): """ This method is the setter method for **self.__dockArea** attribute. :param value: Attribute value. ( Integer ) """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "dockArea")) @dockArea.deleter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def dockArea(self): """ This method is the deleter method for **self.__dockArea** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "dockArea"))
@property def engine(self): """ This method is the property for **self.__engine** attribute. :return: self.__engine. ( QObject ) """ return self.__engine @engine.setter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def engine(self, value): """ This method is the setter method for **self.__engine** attribute. :param value: Attribute value. ( QObject ) """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "engine")) @engine.deleter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def engine(self): """ This method is the deleter method for **self.__engine** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "engine"))
@property def settings(self): """ This method is the property for **self.__settings** attribute. :return: self.__settings. ( QSettings ) """ return self.__settings @settings.setter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def settings(self, value): """ This method is the setter method for **self.__settings** attribute. :param value: Attribute value. ( QSettings ) """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "settings")) @settings.deleter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def settings(self): """ This method is the deleter method for **self.__settings** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "settings"))
@property def settingsSection(self): """ This method is the property for **self.__settingsSection** attribute. :return: self.__settingsSection. ( String ) """ return self.__settingsSection @settingsSection.setter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def settingsSection(self, value): """ This method is the setter method for **self.__settingsSection** attribute. :param value: Attribute value. ( String ) """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "settingsSection")) @settingsSection.deleter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def settingsSection(self): """ This method is the deleter method for **self.__settingsSection** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "settingsSection"))
@property def scriptEditor(self): """ This method is the property for **self.__scriptEditor** attribute. :return: self.__scriptEditor. ( QWidget ) """ return self.__scriptEditor @scriptEditor.setter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def scriptEditor(self, value): """ This method is the setter method for **self.__scriptEditor** attribute. :param value: Attribute value. ( QWidget ) """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "scriptEditor")) @scriptEditor.deleter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def scriptEditor(self): """ This method is the deleter method for **self.__scriptEditor** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "scriptEditor"))
@property def model(self): """ This method is the property for **self.__model** attribute. :return: self.__model. ( CollectionsModel ) """ return self.__model @model.setter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def model(self, value): """ This method is the setter method for **self.__model** attribute. :param value: Attribute value. ( CollectionsModel ) """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "model")) @model.deleter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def model(self): """ This method is the deleter method for **self.__model** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "model"))
@property def view(self): """ This method is the property for **self.__view** attribute. :return: self.__view. ( QWidget ) """ return self.__view @view.setter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def view(self, value): """ This method is the setter method for **self.__view** attribute. :param value: Attribute value. ( QWidget ) """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "view")) @view.deleter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def view(self): """ This method is the deleter method for **self.__view** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "view"))
@property def delegate(self): """ This method is the property for **self.__delegate** attribute. :return: self.__delegate. ( QItemDelegate ) """ return self.__delegate @delegate.setter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def delegate(self, value): """ This method is the setter method for **self.__delegate** attribute. :param value: Attribute value. ( QItemDelegate ) """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "delegate")) @delegate.deleter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def delegate(self): """ This method is the deleter method for **self.__delegate** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "delegate"))
@property def style(self): """ This method is the property for **self.__style** attribute. :return: self.__style. ( Style ) """ return self.__style @style.setter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError) def style(self, value): """ This method is the setter method for **self.__style** attribute. :param value: Attribute value. ( Style ) """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is read only!".format(self.__class__.__name__, "style")) @style.deleter #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(foundations.exceptions.ProgrammingError)
[docs] def style(self): """ This method is the deleter method for **self.__style** attribute. """ raise foundations.exceptions.ProgrammingError( "{0} | '{1}' attribute is not deletable!".format(self.__class__.__name__, "style")) #****************************************************************************************************************** #*** Class methods. #******************************************************************************************************************
[docs] def activate(self, engine): """ This method activates the Component. :param engine: Engine to attach the Component to. ( QObject ) :return: Method success. ( Boolean ) """ LOGGER.debug("> Activating '{0}' Component.".format(self.__class__.__name__)) self.__engine = engine self.__settings = self.__engine.settings self.__settingsSection = self.name self.__scriptEditor = self.__engine.componentsManager["factory.scriptEditor"] self.activated = True return True
[docs] def deactivate(self): """ This method deactivates the Component. :return: Method success. ( Boolean ) """ LOGGER.debug("> Deactivating '{0}' Component.".format(self.__class__.__name__)) self.__engine = None self.__settings = None self.__settingsSection = None self.__scriptEditor = None self.activated = False return True
[docs] def initializeUi(self): """ This method initializes the Component ui. :return: Method success. ( Boolean ) """ LOGGER.debug("> Initializing '{0}' Component ui.".format(self.__class__.__name__)) self.__model = ProjectsProxyModel(self) self.__model.setSourceModel(self.__scriptEditor.model) self.__delegate = RichText_QStyledItemDelegate(self, self.__style) self.Projects_Explorer_treeView.setParent(None) self.Projects_Explorer_treeView = Projects_QTreeView(self, self.__model) self.Projects_Explorer_treeView.setItemDelegate(self.__delegate) self.Projects_Explorer_treeView.setObjectName("Projects_Explorer_treeView") self.Projects_Explorer_treeView.setContextMenuPolicy(Qt.ActionsContextMenu) self.Projects_Explorer_dockWidgetContents_gridLayout.addWidget(self.Projects_Explorer_treeView, 0, 0) self.__view = self.Projects_Explorer_treeView self.__view_addActions() self.__addActions() # Signals / Slots. self.__view.expanded.connect(self.__view__expanded) self.__view.doubleClicked.connect(self.__view__doubleClicked) self.__view.selectionModel().selectionChanged.connect(self.__view_selectionModel__selectionChanged) self.__scriptEditor.Script_Editor_tabWidget.currentChanged.connect( self.__scriptEditor_Script_Editor_tabWidget__currentChanged) self.__scriptEditor.model.projectRegistered.connect(self.__scriptEditor_model__projectRegistered) self.initializedUi = True return True
[docs] def uninitializeUi(self): """ This method uninitializes the Component ui. :return: Method success. ( Boolean ) """ LOGGER.debug("> Uninitializing '{0}' Component ui.".format(self.__class__.__name__)) self.__removeActions() # Signals / Slots. self.__view.expanded.disconnect(self.__view__expanded) self.__view.doubleClicked.disconnect(self.__view__doubleClicked) self.__view.selectionModel().selectionChanged.disconnect(self.__view_selectionModel__selectionChanged) self.__scriptEditor.Script_Editor_tabWidget.currentChanged.disconnect( self.__scriptEditor_Script_Editor_tabWidget__currentChanged) self.__scriptEditor.model.projectRegistered.disconnect(self.__scriptEditor_model__projectRegistered) self.__view_removeActions() self.__model = None self.__delegate = None self.__view = None self.initializedUi = False return True
[docs] def addWidget(self): """ This method adds the Component Widget to the engine. :return: Method success. ( Boolean ) """ LOGGER.debug("> Adding '{0}' Component Widget.".format(self.__class__.__name__)) self.__engine.addDockWidget(Qt.DockWidgetArea(self.__dockArea), self) return True
[docs] def removeWidget(self): """ This method removes the Component Widget from the engine. :return: Method success. ( Boolean ) """ LOGGER.debug("> Removing '{0}' Component Widget.".format(self.__class__.__name__)) self.__engine.removeDockWidget(self) self.setParent(None) return True
def __addActions(self): """ This method sets Component actions. """ LOGGER.debug("> Adding '{0}' Component actions.".format(self.__class__.__name__)) addProjectAction = self.__engine.actionsManager.getAction( "Actions|Umbra|Components|factory.scriptEditor|&File|Add Project ...") removeProjectAction = self.__engine.actionsManager.registerAction( "Actions|Umbra|Components|factory.scriptEditor|&File|Remove Project", slot=self.__view_removeProjectAction__triggered) self.__scriptEditor.fileMenu.insertAction(addProjectAction, removeProjectAction) self.__scriptEditor.fileMenu.removeAction(addProjectAction) self.__scriptEditor.fileMenu.insertAction(removeProjectAction, addProjectAction) def __removeActions(self): """ This method removes actions. """ LOGGER.debug("> Removing '{0}' Component actions.".format(self.__class__.__name__)) removeProjectAction = "Actions|Umbra|Components|factory.scriptEditor|&File|Remove Project" self.__scriptEditor.commandMenu.removeAction(self.__engine.actionsManager.getAction(removeProjectAction)) self.__engine.actionsManager.unregisterAction(removeProjectAction) def __view_addActions(self): """ This method sets the View actions. """ self.__view.addAction(self.__engine.actionsManager.registerAction( "Actions|Umbra|Components|addons.projectsExplorer|Add Project ...", slot=self.__view_addProjectAction__triggered)) self.__view.addAction(self.__engine.actionsManager.registerAction( "Actions|Umbra|Components|addons.projectsExplorer|Remove Project", slot=self.__view_removeProjectAction__triggered)) separatorAction = QAction(self.__view) separatorAction.setSeparator(True) self.__view.addAction(separatorAction) self.__view.addAction(self.__engine.actionsManager.registerAction( "Actions|Umbra|Components|addons.projectsExplorer|Add New File ...", slot=self.__view_addNewFileAction__triggered)) self.__view.addAction(self.__engine.actionsManager.registerAction( "Actions|Umbra|Components|addons.projectsExplorer|Add New Directory ...", slot=self.__view_addNewDirectoryAction__triggered)) separatorAction = QAction(self.__view) separatorAction.setSeparator(True) self.__view.addAction(separatorAction) self.__view.addAction(self.__engine.actionsManager.registerAction( "Actions|Umbra|Components|addons.projectsExplorer|Rename ...", slot=self.__view_renameAction__triggered)) # self.__view.addAction(self.__engine.actionsManager.registerAction( # "Actions|Umbra|Components|addons.projectsExplorer|Copy ...", # slot=self.__view_copyAction__triggered)) # self.__view.addAction(self.__engine.actionsManager.registerAction( # "Actions|Umbra|Components|addons.projectsExplorer|Move ...", # slot=self.__view_moveAction__triggered)) separatorAction = QAction(self.__view) separatorAction.setSeparator(True) self.__view.addAction(separatorAction) self.__view.addAction(self.__engine.actionsManager.registerAction( "Actions|Umbra|Components|addons.projectsExplorer|Delete ...", slot=self.__view_deleteAction__triggered)) separatorAction = QAction(self.__view) separatorAction.setSeparator(True) self.__view.addAction(separatorAction) self.__view.addAction(self.__engine.actionsManager.registerAction( "Actions|Umbra|Components|addons.projectsExplorer|Find In Files ...", slot=self.__view_findInFilesAction__triggered)) separatorAction = QAction(self.__view) separatorAction.setSeparator(True) self.__view.addAction(separatorAction) self.__view.addAction(self.__engine.actionsManager.registerAction( "Actions|Umbra|Components|addons.projectsExplorer|Output Selected Path", slot=self.__view_outputSelectedPathAction__triggered)) def __view_removeActions(self): """ This method removes the View actions. """ addProjectAction = "Actions|Umbra|Components|addons.projectsExplorer|Add Project ..." removeProjectAction = "Actions|Umbra|Components|addons.projectsExplorer|Remove Project" addNewFileAction = "Actions|Umbra|Components|addons.projectsExplorer|Add New File ..." addNewDirectoryAction = "Actions|Umbra|Components|addons.projectsExplorer|Add New Directory ..." renameAction = "Actions|Umbra|Components|addons.projectsExplorer|Rename ..." # copyAction = "Actions|Umbra|Components|addons.projectsExplorer|Copy ..." # moveAction = "Actions|Umbra|Components|addons.projectsExplorer|Move ..." deleteAction = "Actions|Umbra|Components|addons.projectsExplorer|Delete ..." findInFilesAction = "Actions|Umbra|Components|addons.projectsExplorer|Find In Files ..." outputSelectedPathAction = "Actions|Umbra|Components|addons.projectsExplorer|Output Selected Path" for action in (addProjectAction, removeProjectAction, addNewFileAction, addNewDirectoryAction, renameAction, # copyAction, # moveAction, deleteAction, outputSelectedPathAction): self.__view.removeAction(self.__engine.actionsManager.getAction(action)) self.__engine.actionsManager.unregisterAction(action) def __view__expanded(self, index): """ This method is triggered when a View item is expanded. :param index: Expdanded item. ( QModelIndex ) """ node = self.__model.getNode(index) if node.family != "DirectoryNode": return self.__scriptEditor.model.setProjectNodes(node) def __view__doubleClicked(self, index): """ This method is triggered when a View Widget is double clicked. :param index: Clicked item index. ( QModelIndex ) """ node = self.__model.getNode(index) if not node.family == "FileNode": return foundations.common.pathExists(node.path) and self.__scriptEditor.loadFile(node.path) def __view_selectionModel__selectionChanged(self, selectedItems, deselectedItems): """ This method is triggered when the View **selectionModel** has changed. :param selectedItems: Selected items. ( QItemSelection ) :param deselectedItems: Deselected items. ( QItemSelection ) """ for node in self.__view.getSelectedNodes(): if node.family == "FileNode": self.__scriptEditor.setCurrentEditor(node.path) def __scriptEditor_Script_Editor_tabWidget__currentChanged(self, index): """ This method is triggered by the :class:`umbra.components.factory.scriptEditor.scriptEditor.ScriptEditor` Component Interface class when the current tab is changed. :param index: Tab index. ( Integer ) """ editor = self.__scriptEditor.getCurrentEditor() if not editor: return editorNode = foundations.common.getFirstItem(self.__scriptEditor.model.getEditorNodes(editor)) if not editorNode: return indexes = [self.__model.mapFromSource(self.__model.sourceModel().getNodeIndex(editorNode.parent))] self.__view.clearSelection() self.__view.selectIndexes(indexes) def __scriptEditor_model__projectRegistered(self, projectNode): """ This method is triggered by the:class:`umbra.components.factory.scriptEditor.scriptEditor` class Model when a project is registered. :param projectNode: Registered project ProjectNode. ( ProjectNode ) """ index = self.__model.mapFromSource(self.__scriptEditor.model.getNodeIndex(projectNode)) self.__view.setExpanded(index, True) def __view_addProjectAction__triggered(self, checked): """ This method is triggered by **'Actions|Umbra|Components|addons.projectsExplorer|Add Project ...'** action. :param checked: Checked state. ( Boolean ) :return: Method success. ( Boolean ) """ return self.__scriptEditor.addProjectUi() def __view_removeProjectAction__triggered(self, checked): """ This method is triggered by **'Actions|Umbra|Components|addons.projectsExplorer|Remove Project'** action. :param checked: Checked state. ( Boolean ) :return: Method success. ( Boolean ) """ node = foundations.common.getFirstItem(self.getSelectedNodes()) if not node: return False return self.removeProject(node) def __view_addNewFileAction__triggered(self, checked): """ This method is triggered by **'"Actions|Umbra|Components|addons.projectsExplorer|Add New File ..."'** action. :param checked: Checked state. ( Boolean ) :return: Method success. ( Boolean ) """ node = foundations.common.getFirstItem(self.getSelectedNodes()) if not node: return False return self.addNewFile(node) def __view_addNewDirectoryAction__triggered(self, checked): """ This method is triggered by **'"Actions|Umbra|Components|addons.projectsExplorer|Add New Directory ..."'** action. :param checked: Checked state. ( Boolean ) :return: Method success. ( Boolean ) """ node = foundations.common.getFirstItem(self.getSelectedNodes()) if not node: return False return self.addNewDirectory(node) def __view_renameAction__triggered(self, checked): """ This method is triggered by **'"Actions|Umbra|Components|addons.projectsExplorer|Rename ..."'** action. :param checked: Checked state. ( Boolean ) :return: Method success. ( Boolean ) """ node = foundations.common.getFirstItem(self.getSelectedNodes()) if not node: return False return self.rename(node) # def __view_copyAction__triggered(self, checked): # """ # This method is triggered by **'"Actions|Umbra|Components|addons.projectsExplorer|Copy ..."'** action. # # :param checked: Checked state. ( Boolean ) # :return: Method success. ( Boolean ) # """ # # print "Actions|Umbra|Components|addons.projectsExplorer|Copy ..." # def __view_moveAction__triggered(self, checked): # """ # This method is triggered by **'"Actions|Umbra|Components|addons.projectsExplorer|Move ..."'** action. # # :param checked: Checked state. ( Boolean ) # :return: Method success. ( Boolean ) # """ # # print "Actions|Umbra|Components|addons.projectsExplorer|Move ..." def __view_deleteAction__triggered(self, checked): """ This method is triggered by **'"Actions|Umbra|Components|addons.projectsExplorer|Delete ..."'** action. :param checked: Checked state. ( Boolean ) :return: Method success. ( Boolean ) """ node = foundations.common.getFirstItem(self.getSelectedNodes()) if not node: return False return self.delete(node) def __view_findInFilesAction__triggered(self, checked): """ This method is triggered by **'Actions|Umbra|Components|addons.projectsExplorer|Find In Files ...'** action. :param checked: Checked state. ( Boolean ) :return: Method success. ( Boolean ) """ node = foundations.common.getFirstItem(self.__view.getSelectedNodes().iterkeys()) if not node: return False self.__scriptEditor.searchInFiles.Where_lineEdit.setText(node.path) self.__scriptEditor.searchInFiles.show() return True def __view_outputSelectedPathAction__triggered(self, checked): """ This method is triggered by **'Actions|Umbra|Components|addons.projectsExplorer|Output Selected Path'** action. :param checked: Checked state. ( Boolean ) :return: Method success. ( Boolean ) """ node = foundations.common.getFirstItem(self.__view.getSelectedNodes().iterkeys()) if not node: return False LOGGER.info("{0} | '{1}'.".format(self.__class__.__name__, node.path)) return True #*** Sphinx: Decorator commented for auto-documentation purpose. @foundations.exceptions.handleExceptions(umbra.exceptions.notifyExceptionHandler, #*** Sphinx: Decorator commented for auto-documentation purpose. foundations.exceptions.FileExistsError, #*** Sphinx: Decorator commented for auto-documentation purpose. foundations.exceptions.DirectoryExistsError, #*** Sphinx: Decorator commented for auto-documentation purpose. Exception) def __raiseFileSystemException(self, item, directory): """ This method raises a common fileSystem exception. :param item: Name of the item generating the exception. ( String ) :param directory: Name of the target directory. ( String ) """ path = os.path.join(directory, item) if os.path.isfile(path): raise foundations.exceptions.FileExistsError( "{0} | A file with '{1}' name already exists in '{2}' directory!".format(self.__class__.__name__, item, directory)) else: raise foundations.exceptions.DirectoryExistsError( "{0} | A directory with '{1}' name already exists in '{2}' directory!".format(self.__class__.__name__, item, directory)) def __setAuthoringNodes(self, source, target): """ This method sets given editor authoring nodes. :param source: Source file. ( String ) :param target: Target file. ( String ) """ editor = self.__scriptEditor.getEditor(source) editor.setFile(target) self.__scriptEditor.model.updateAuthoringNodes(editor) def __renamePath(self, source, target): """ This method renames given source with given target name. :param source: Source file. ( String ) :param target: Target file. ( String ) """ if not foundations.common.pathExists(source): return parentDirectory = os.path.dirname(source) isPathRegistered = self.__engine.fileSystemEventsManager.isPathRegistered(parentDirectory) isPathRegistered and self.__engine.fileSystemEventsManager.unregisterPath(parentDirectory) os.rename(source, target) isPathRegistered and self.__engine.fileSystemEventsManager.registerPath(parentDirectory) def __deletePath(self, path): """ This method deletes given path. :param path: Path to delete. ( String ) """ if not foundations.common.pathExists(path): return parentDirectory = os.path.dirname(path) isPathRegistered = self.__engine.fileSystemEventsManager.isPathRegistered(parentDirectory) isPathRegistered and self.__engine.fileSystemEventsManager.unregisterPath(parentDirectory) if os.path.isfile(path): os.remove(path) else: shutil.rmtree(path) isPathRegistered and self.__engine.fileSystemEventsManager.registerPath(parentDirectory) def __renameFile(self, source, target): """ This method renames a file using given source and target names. :param source: Source file. ( String ) :param target: Target file. ( String ) """ for fileNode in self.__scriptEditor.model.getFileNodes(source, self.__scriptEditor.model.rootNode): self.__scriptEditor.unregisterNodePath(fileNode) self.__renamePath(source, target) self.__scriptEditor.registerNodePath(fileNode) if self.__scriptEditor.model.isAuthoringNode(fileNode): self.__setAuthoringNodes(source, target) else: self.__scriptEditor.model.updateProjectNodes(fileNode.parent) def __renameDirectory(self, source, target): """ This method renames a directory using given source and target names. :param source: Source file. ( String ) :param target: Target file. ( String ) """ for node in itertools.chain(self.__scriptEditor.model.getProjectNodes(source), self.__scriptEditor.model.getDirectoryNodes(source)): self.__scriptEditor.model.unregisterProjectNodes(node) self.__scriptEditor.unregisterNodePath(node) self.__renamePath(source, target) node.name = os.path.basename(target) node.path = target self.__scriptEditor.model.nodeChanged(node) self.__scriptEditor.registerNodePath(node) self.__scriptEditor.model.setProjectNodes(node) def __renameProject(self, source, target): """ This method renames a project using given source and target names. :param source: Source project. ( String ) :param target: Target project. ( String ) """ self.__renameDirectory(source, target) def __deleteFile(self, file): """ This method deletes given file. :param file: File to delete. ( String ) """ for fileNode in self.__scriptEditor.model.getFileNodes(file, self.__scriptEditor.model.rootNode): self.__scriptEditor.unregisterNodePath(fileNode) self.__deletePath(file) if self.__scriptEditor.model.isAuthoringNode(fileNode): self.__scriptEditor.getEditor(file).setModified(True) else: self.__scriptEditor.model.unregisterFile(fileNode) def __deleteDirectory(self, directory): """ This method deletes given directory. :param directory: Directory to delete. ( String ) """ for node in itertools.chain(self.__scriptEditor.model.getProjectNodes(directory), self.__scriptEditor.model.getDirectoryNodes(directory)): self.__scriptEditor.model.unregisterProjectNodes(node) if node.family == "DirectoryNode": self.__scriptEditor.model.unregisterProjectNodes(node) self.__scriptEditor.model.unregisterDirectory(node) elif node.family == "ProjectNode": self.__scriptEditor.removeProject(directory) self.__deletePath(directory)
[docs] def getSelectedNodes(self): """ This method returns the View selected nodes. :return: View selected nodes. ( Dictionary ) """ return self.__view.getSelectedNodes()
[docs] def removeProject(self, node): """ This method removes the project associated with given node. :param node: Node. ( ProjectNode / DirectoryNode / FileNode ) :return: Method success. ( Boolean ) """ if node.family == "ProjectNode": self.__scriptEditor.removeProject(node.path) return True for node in foundations.walkers.nodesWalker(node, ascendants=True): if node.family == "ProjectNode" and not node is self.__scriptEditor.model.defaultProjectNode: self.__scriptEditor.removeProject(node.path) return True
[docs] def addNewFile(self, node): """ This method adds a new file next to given Node associated path. :param node: Node. ( ProjectNode / DirectoryNode / FileNode ) :return: Method success. ( Boolean ) """ if self.__scriptEditor.model.isAuthoringNode(node): return self.__scriptEditor.newFile() file, state = QInputDialog.getText(self, "Add File", "Enter your new file name:") if not state: return False if node.family in ("ProjectNode", "DirectoryNode"): directory = node.path elif node.family == "FileNode": directory = os.path.dirname(node.path) # file = foundations.strings.toString(file) if not file in os.listdir(directory): file = os.path.join(directory, file) LOGGER.info("{0} | Adding '{1}' file!".format(self.__class__.__name__, file)) open(file, "w").close() else: self.__raiseFileSystemException(file, directory) return True
[docs] def addNewDirectory(self, node): """ This method adds a new directory next to given Node associated path. :param node: Node. ( ProjectNode / DirectoryNode / FileNode ) :return: Method success. ( Boolean ) """ if self.__scriptEditor.model.isAuthoringNode(node): return False directory, state = QInputDialog.getText(self, "Add Directory", "Enter your new directory name:") if not state: return False if node.family in ("ProjectNode", "DirectoryNode"): parentDirectory = node.path elif node.family == "FileNode": parentDirectory = os.path.dirname(node.path) directory = foundations.strings.toString(directory) if not directory in os.listdir(parentDirectory): directory = os.path.join(parentDirectory, directory) LOGGER.info("{0} | Adding '{1}' directory!".format(self.__class__.__name__, directory)) os.makedirs(directory) else: self.__raiseFileSystemException(file, parentDirectory) return True
[docs] def rename(self, node): """ This method renames given Node associated path. :param node: Node. ( ProjectNode / DirectoryNode / FileNode ) :return: Method success. ( Boolean ) """ source = node.path baseName, state = QInputDialog.getText(self, "Rename", "Enter your new name:", text=os.path.basename(source)) if not state: return False baseName = foundations.strings.toString(baseName) if baseName == os.path.basename(source): return False parentDirectory = os.path.dirname(source) target = os.path.join(parentDirectory, baseName) if self.__scriptEditor.model.isAuthoringNode(node): if not foundations.common.pathExists(source): LOGGER.info("{0} | Renaming '{1}' untitled file to '{2}'!".format(self.__class__.__name__, source, target)) self.__setAuthoringNodes(source, target) return True if not baseName in os.listdir(parentDirectory): if node.family == "FileNode": LOGGER.info("{0} | Renaming '{1}' file to '{2}'!".format(self.__class__.__name__, source, target)) self.__renameFile(source, target) elif node.family == "DirectoryNode": LOGGER.info("{0} | Renaming '{1}' directory to '{2}'!".format(self.__class__.__name__, source, target)) self.__renameDirectory(source, target) elif node.family == "ProjectNode": LOGGER.info("{0} | Renaming '{1}' project to '{2}'!".format(self.__class__.__name__, source, target)) self.__renameProject(source, target) else: self.__raiseFileSystemException(baseName, parentDirectory) return True
[docs] def delete(self, node): """ This method deletes given Node associated path. :param node: Node. ( ProjectNode / DirectoryNode / FileNode ) :return: Method success. ( Boolean ) """ path = node.path if self.__scriptEditor.model.isAuthoringNode(node): if not foundations.common.pathExists(path): return False if messageBox.messageBox("Question", "Question", "Are you sure you want to delete '{0}' {1}?".format(path, "file" if os.path.isfile(path) else "directory"), buttons=QMessageBox.Yes | QMessageBox.No) == QMessageBox.Yes: if os.path.isfile(path): LOGGER.info("{0} | Deleting '{1}' file!".format(self.__class__.__name__, path)) self.__deleteFile(path) else: LOGGER.info("{0} | Deleting '{1}' directory!".format(self.__class__.__name__, path)) self.__deleteDirectory(path) return True