Exemplo n.º 1
1
class FilenamePrompt(_BasePrompt):

    """A prompt for a filename."""

    def __init__(self, question, parent=None):
        super().__init__(question, parent)
        self._init_texts(question)
        self._init_fileview()
        self._set_fileview_root(question.default)

        self._lineedit = LineEdit(self)
        if question.default:
            self._lineedit.setText(question.default)
        self._lineedit.textEdited.connect(self._set_fileview_root)
        self._vbox.addWidget(self._lineedit)

        self.setFocusProxy(self._lineedit)
        self._init_key_label()

        if config.get('ui', 'prompt-filebrowser'):
            self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)

    @pyqtSlot(str)
    def _set_fileview_root(self, path, *, tabbed=False):
        """Set the root path for the file display."""
        separators = os.sep
        if os.altsep is not None:
            separators += os.altsep

        dirname = os.path.dirname(path)

        try:
            if not path:
                pass
            elif path in separators and os.path.isdir(path):
                # Input "/" -> don't strip anything
                pass
            elif path[-1] in separators and os.path.isdir(path):
                # Input like /foo/bar/ -> show /foo/bar/ contents
                path = path.rstrip(separators)
            elif os.path.isdir(dirname) and not tabbed:
                # Input like /foo/ba -> show /foo contents
                path = dirname
            else:
                return
        except OSError:
            log.prompt.exception("Failed to get directory information")
            return

        root = self._file_model.setRootPath(path)
        self._file_view.setRootIndex(root)

    @pyqtSlot(QModelIndex)
    def _insert_path(self, index, *, clicked=True):
        """Handle an element selection.

        Args:
            index: The QModelIndex of the selected element.
            clicked: Whether the element was clicked.
        """
        path = os.path.normpath(self._file_model.filePath(index))
        if clicked:
            path += os.sep
        else:
            # On Windows, when we have C:\foo and tab over .., we get C:\
            path = path.rstrip(os.sep)

        log.prompt.debug('Inserting path {}'.format(path))
        self._lineedit.setText(path)
        self._lineedit.setFocus()
        self._set_fileview_root(path, tabbed=True)
        if clicked:
            # Avoid having a ..-subtree highlighted
            self._file_view.setCurrentIndex(QModelIndex())

    def _init_fileview(self):
        self._file_view = QTreeView(self)
        self._file_model = QFileSystemModel(self)
        self._file_view.setModel(self._file_model)
        self._file_view.clicked.connect(self._insert_path)

        if config.get('ui', 'prompt-filebrowser'):
            self._vbox.addWidget(self._file_view)
        else:
            self._file_view.hide()

        # Only show name
        self._file_view.setHeaderHidden(True)
        for col in range(1, 4):
            self._file_view.setColumnHidden(col, True)
        # Nothing selected initially
        self._file_view.setCurrentIndex(QModelIndex())
        # The model needs to be sorted so we get the correct first/last index
        self._file_model.directoryLoaded.connect(
            lambda: self._file_model.sort(0))

    def accept(self, value=None):
        text = value if value is not None else self._lineedit.text()
        text = downloads.transform_path(text)
        if text is None:
            message.error("Invalid filename")
            return False
        self.question.answer = text
        return True

    def item_focus(self, which):
        # This duplicates some completion code, but I don't see a nicer way...
        assert which in ['prev', 'next'], which
        selmodel = self._file_view.selectionModel()

        parent = self._file_view.rootIndex()
        first_index = self._file_model.index(0, 0, parent)
        row = self._file_model.rowCount(parent) - 1
        last_index = self._file_model.index(row, 0, parent)

        if not first_index.isValid():
            # No entries
            return

        assert last_index.isValid()

        idx = selmodel.currentIndex()
        if not idx.isValid():
            # No item selected yet
            idx = last_index if which == 'prev' else first_index
        elif which == 'prev':
            idx = self._file_view.indexAbove(idx)
        else:
            assert which == 'next', which
            idx = self._file_view.indexBelow(idx)

        # wrap around if we arrived at beginning/end
        if not idx.isValid():
            idx = last_index if which == 'prev' else first_index

        selmodel.setCurrentIndex(
            idx, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
        self._insert_path(idx, clicked=False)

    def _allowed_commands(self):
        return [('prompt-accept', 'Accept'), ('leave-mode', 'Abort')]
Exemplo n.º 2
0
 def update_file_tree(self):
     model = QFileSystemModel()
     model.setRootPath(self._root_dir)
     self.localFilesTreeView.setModel(model)
     local_selection_model = self.localFilesTreeView.selectionModel()
     local_selection_model.selectionChanged.connect(self.local_file_selection_changed)
     self.localFilesTreeView.setRootIndex(model.index(self._root_dir))
Exemplo n.º 3
0
class E5DirCompleter(QCompleter):
    """
    Class implementing a completer for directory names.
    """

    def __init__(self, parent=None, completionMode=QCompleter.PopupCompletion, showHidden=False):
        """
        Constructor
        
        @param parent parent widget of the completer (QWidget)
        @keyparam completionMode completion mode of the
            completer (QCompleter.CompletionMode)
        @keyparam showHidden flag indicating to show hidden entries as well
            (boolean)
        """
        super(E5DirCompleter, self).__init__(parent)
        self.__model = QFileSystemModel(self)
        if showHidden:
            self.__model.setFilter(QDir.Filters(QDir.Drives | QDir.AllDirs | QDir.Hidden))
        else:
            self.__model.setFilter(QDir.Filters(QDir.Drives | QDir.AllDirs))
        self.setModel(self.__model)
        self.setCompletionMode(completionMode)
        if isWindowsPlatform():
            self.setCaseSensitivity(Qt.CaseInsensitive)
        if parent:
            parent.setCompleter(self)
Exemplo n.º 4
0
    def __init__(self, module_manager):
        super(AssetBrowser, self).__init__()
        self.setupUi(self)

        self.init_module(module_manager)

        self.dir_model = QFileSystemModel()
        self.dir_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)
        self.dir_model.setReadOnly(False)

        self.dir_view.setModel(self.dir_model)
        self.dir_view.hideColumn(1)
        self.dir_view.hideColumn(2)
        self.dir_view.hideColumn(3)

        self.file_model = QFileSystemModel()
        self.file_model.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.file_model.setReadOnly(False)

        self.file_view.setModel(self.file_model)

        self.dock = self.modules_manager.new_docked(self, self.Name, "Asset browser",
                                                    Qt.BottomDockWidgetArea)

        self.modules_manager.main_window.splitDockWidget(self.dock,
                                                         self.modules_manager["asset_view"].dock, Qt.Horizontal)
Exemplo n.º 5
0
class FileTree(QTreeView):
    def __init__(self):
        super(FileTree, self).__init__()
        self.model = QFileSystemModel()
        self.model.setRootPath('')
        self.setModel(self.model)
        self.setAnimated(False)
        self.setIndentation(20)
        self.setSortingEnabled(True)
Exemplo n.º 6
0
	def initRootDir(self,indexDir):
		if not indexDir:
			return
		self.indexDir = indexDir
		model = QFileSystemModel()
		model.setRootPath('')
		self.setModel(model)
		self.setAnimated(False)
		self.setIndentation(20)
		self.setSortingEnabled(True)
		self.setRootIndex(model.index(self.indexDir))
		for i in range(1,model.columnCount()):
			self.hideColumn(i)
Exemplo n.º 7
0
class E5FileCompleter(QCompleter):
    """
    Class implementing a completer for file names.
    """
    def __init__(self, parent=None,
                 completionMode=QCompleter.PopupCompletion,
                 showHidden=False):
        """
        Constructor
        
        @param parent parent widget of the completer (QWidget)
        @keyparam completionMode completion mode of the
            completer (QCompleter.CompletionMode)
        @keyparam showHidden flag indicating to show hidden entries as well
            (boolean)
        """
        super(E5FileCompleter, self).__init__(parent)
        self.__model = QFileSystemModel(self)
        if showHidden:
            self.__model.setFilter(
                QDir.Filters(QDir.Dirs | QDir.Files | QDir.Drives |
                             QDir.AllDirs | QDir.Hidden))
        else:
            self.__model.setFilter(QDir.Filters(
                QDir.Dirs | QDir.Files | QDir.Drives | QDir.AllDirs))
        self.__model.directoryLoaded.connect(self.complete)
        self.__model.setRootPath("")
        self.setModel(self.__model)
        self.setCompletionMode(completionMode)
        if isWindowsPlatform():
            self.setCaseSensitivity(Qt.CaseInsensitive)
        if parent:
            parent.setCompleter(self)
    
    def setRootPath(self, path):
        """
        Public method to set the root path of the model.
        
        @param path root path for the model
        @type str
        """
        if not os.path.isdir(path):
            path = os.path.dirname(path)
        self.__model.setRootPath(path)
    
    def rootPath(self):
        """
        Public method to get the root path of the model.
        
        @return root path of the model
        @rtype str
        """
        return self.__model.rootPath()
Exemplo n.º 8
0
    def dropMimeData(self, data, action, row, column, parent):
        # print 'dropMimeData %s %s %s %s' % (data.data('text/uri-list'), action, row, parent)

        # print data.text()
        # print data.formats()
        # print data.data('text/uri-list')
        # print row, "row"
        # print column, "col"
        # print action, "action"
        # print parent, "parent"
        # print parent.data(Qt.DisplayRole),"parent"

        filePath = data.data('text/uri-list').data()[7:]
        # filesFolderPath = filePath  # canonical , os path parent falan

        fileName = os.path.basename(filePath)
        # fileName = ""
        # print type(filePath.data())
        # print fileName

        # os.path.normpath(unicode(self.model().fileInfo(self.selectedIndexes()[0]).absoluteFilePath()))

        # dfolder = self.fileInfo(parent).absoluteFilePath()
        destFinalPath = os.path.normpath("%s/%s" % (self.filePath(parent), fileName))

        # ya da emit.fileMoved filepath move to destFolder+filename
        self.fileDraggedAndMoved.emit("%s -------->   %s" % (filePath, destFinalPath))

        # return True
        return QFileSystemModel.dropMimeData(self, data, action, row, column, parent)
Exemplo n.º 9
0
    def _init_ui(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        model = QFileSystemModel(self)
        model.setRootPath('')
        view = QTreeView()
        view.setModel(model)

        view.setAnimated(False)
        view.setIndentation(20)
        view.setSortingEnabled(True)

        layout = QVBoxLayout()
        layout.addWidget(view)
        self.setLayout(layout)
Exemplo n.º 10
0
    def __init__(self, path):
        super(NProject, self).__init__()
        project = json_manager.read_ninja_project(path)

        self.path = path
        self._name = project.get('name', '')
        if self._name == '':
            self._name = file_manager.get_basename(path)
        self.project_type = project.get('project-type', '')
        self.description = project.get('description', '')
        if self.description == '':
            self.description = translations.TR_NO_DESCRIPTION
        self.url = project.get('url', '')
        self.license = project.get('license', '')
        self.main_file = project.get('mainFile', '')
        self.pre_exec_script = project.get('preExecScript', '')
        self.post_exec_script = project.get('postExecScript', '')
        self.indentation = project.get('indentation', settings.INDENT)
        self.use_tabs = project.get('use-tabs', settings.USE_TABS)
        self.extensions = project.get('supported-extensions',
            settings.SUPPORTED_EXTENSIONS)
        self.python_exec = project.get('pythonExec', settings.PYTHON_EXEC)
        self.python_path = project.get('PYTHONPATH', '')
        self.additional_builtins = project.get('additional_builtins', [])
        self.program_params = project.get('programParams', '')
        self.venv = project.get('venv', '')
        self.related_projects = project.get('relatedProjects', [])
        self.added_to_console = False
        self.is_current = False
        #Model is a QFileSystemModel to be set on runtime
        self.__model = QFileSystemModel()
        self.__model.setRootPath(path)
Exemplo n.º 11
0
    def _iconForPath(self, path):
        """Get icon for file or directory path. Uses QFileSystemModel
        """
        if self._model is None:
            self._model = QFileSystemModel()

        index = self._model.index(path)
        return self._model.data(index, Qt.DecorationRole)
Exemplo n.º 12
0
    def __init__(self):
        super(AssetBrowser, self).__init__()
        self.setupUi(self)

        self.dir_model = QFileSystemModel()
        self.dir_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)
        self.dir_model.setReadOnly(False)

        self.dir_view.setModel(self.dir_model)
        self.dir_view.hideColumn(1)
        self.dir_view.hideColumn(2)
        self.dir_view.hideColumn(3)

        self.file_model = QFileSystemModel()
        self.file_model.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.file_model.setReadOnly(False)

        self.file_view.setModel(self.file_model)
Exemplo n.º 13
0
    def load_dir(self, dir_path):
        if dir_path == self.dir_path:
            return

        self.dir_path = dir_path

        model = QFileSystemModel()
        model.setRootPath(dir_path)
        self.setModel(model)

        index_root = model.index(model.rootPath())
        self.setRootIndex(index_root)

        # hide unwanted info
        self.hideColumn(1)
        self.hideColumn(2)
        self.hideColumn(3)
        self.setHeaderHidden(True)
Exemplo n.º 14
0
class ComplexDialog(QDialog, Ui_ComplexForm):

	def __init__(self, parent=None):
		super(ComplexDialog, self).__init__(parent)
		self.setupUi(self)
		self.file_model = QFileSystemModel()
		self.bundle_model = QStringListModel()
		bundle_lists = []
		self.bundle_model.setStringList(bundle_lists)

		root = self.file_model.setRootPath("/Volumes")



		self.columnView_files.setModel(self.file_model)
		self.columnView_files.setRootIndex(root)
		self.listView_files.setModel(self.bundle_model)

		# connect the buttons
		self.pushButton_add_file.clicked.connect(self._add_to_bundle)
		self.pushButton_remove_file.clicked.connect(self._remove_from_bundle)
		self.pushButton_cancle.clicked.connect(self.close_window)
		self.pushButton_add_object.clicked.connect(self.return_bundle)



	def _add_to_bundle(self):
		selection = self.columnView_files.selectedIndexes()
		files = self.bundle_model.stringList()
		model = self.columnView_files.model()
		for index in selection:
			# path = os.path.join()
			if model.isDir(index):
				continue
			newfile = model.filePath(index)
			files.append(newfile)
		self.bundle_model.setStringList(files)
			# self.bundle_model.inser

	def _remove_from_bundle(self):
		selection = self.listView_files.selectedIndexes()
		model = self.listView_files.model()
		for index in selection:
			row = index.row()
			model.removeRows(row, 1)

	def return_bundle(self):
		self.close_window()

	@property
	def bundle(self):
		return self.bundle_model.stringList()

	def close_window(self):
		self.close()
Exemplo n.º 15
0
    def __init__(self):
        super(FileSystemOpener, self).__init__()
        hbox = QHBoxLayout(self)
        hbox.setContentsMargins(0, 0, 0, 0)
        self.btnClose = QPushButton(
            self.style().standardIcon(QStyle.SP_DialogCloseButton), '')
        self.completer = QCompleter(self)
        self.pathLine = ui_tools.LineEditTabCompleter(self.completer)
        fileModel = QFileSystemModel(self.completer)
        fileModel.setRootPath("")
        self.completer.setModel(fileModel)
        self.pathLine.setCompleter(self.completer)
        self.btnOpen = QPushButton(
            self.style().standardIcon(QStyle.SP_ArrowRight), 'Open!')
        hbox.addWidget(self.btnClose)
        hbox.addWidget(QLabel(_translate("FileSystemOpener", "Path:")))
        hbox.addWidget(self.pathLine)
        hbox.addWidget(self.btnOpen)

        self.pathLine.returnPressed.connect(self._open_file)
        self.btnOpen.clicked['bool'].connect(self._open_file)
Exemplo n.º 16
0
 def open_project(self, project):
     project_path = project.path
     qfsm = None  # Should end up having a QFileSystemModel
     if project_path not in self.__projects:
         qfsm = QFileSystemModel()
         project.model = qfsm
         qfsm.setRootPath(project_path)
         qfsm.setFilter(QDir.AllDirs | QDir.Files | QDir.NoDotAndDotDot)
         # If set to true items that dont match are displayed disabled
         qfsm.setNameFilterDisables(False)
         pext = ["*{0}".format(x) for x in project.extensions]
         logger.debug(pext)
         qfsm.setNameFilters(pext)
         self.__projects[project_path] = project
         self.__check_files_for(project_path)
         self.projectOpened.emit(project_path)
     else:
         qfsm = self.__projects[project_path]
     return qfsm
Exemplo n.º 17
0
 def _init_fileview(self):
     self._file_view = QTreeView(self)
     self._file_model = QFileSystemModel(self)
     self._file_view.setModel(self._file_model)
     self._file_view.clicked.connect(self._insert_path)
     self._vbox.addWidget(self._file_view)
     # Only show name
     self._file_view.setHeaderHidden(True)
     for col in range(1, 4):
         self._file_view.setColumnHidden(col, True)
     # Nothing selected initially
     self._file_view.setCurrentIndex(QModelIndex())
     # The model needs to be sorted so we get the correct first/last index
     self._file_model.directoryLoaded.connect(
         lambda: self._file_model.sort(0))
Exemplo n.º 18
0
	def _init_more(self):
		self.setWindowTitle('Tags4')

		self.dirModel = QFileSystemModel()
		self.dirModel.setFilter(QDir.AllDirs | QDir.Drives | QDir.Hidden | QDir.NoDotAndDotDot)
		qidx = self.dirModel.setRootPath(self.rootPath)
		self.dirChooser.setModel(self.dirModel)
		self.dirChooser.setRootIndex(qidx)

		self.dirChooser.clicked.connect(self.browseSelectedDir)
		self.imageList.itemSelectionChanged.connect(self._editTagsItems)
		self.imageList.itemDoubleClicked.connect(self._spawnViewerItem)
		self.imageList.setSelectionMode(QAbstractItemView.ExtendedSelection)

		self.tabWidget.currentChanged.connect(self._tabSelected)
		self.tagChooser.changed.connect(self.browseSelectedTags)
Exemplo n.º 19
0
    def __init__(self, parent=None):
        super().__init__(parent)
        self.folderBox = QComboBox(self)
        self.explorerTree = FileTreeView(self)
        self.explorerTree.doubleClickCallback = self._fileOpened
        self.explorerModel = QFileSystemModel(self)
        self.explorerModel.setFilter(QDir.AllDirs | QDir.Files | QDir.NoDotAndDotDot)
        self.explorerModel.setNameFilters(["*.py"])
        self.explorerModel.setNameFilterDisables(False)
        self.explorerTree.setModel(self.explorerModel)
        for index in range(1, self.explorerModel.columnCount()):
            self.explorerTree.hideColumn(index)
        self.setCurrentFolder()
        self.folderBox.currentIndexChanged[int].connect(self.updateCurrentFolder)

        layout = QVBoxLayout(self)
        layout.addWidget(self.folderBox)
        layout.addWidget(self.explorerTree)
        layout.setContentsMargins(5, 5, 0, 5)
Exemplo n.º 20
0
	def __init__(self, parent=None):
		super(ComplexDialog, self).__init__(parent)
		self.setupUi(self)
		self.file_model = QFileSystemModel()
		self.bundle_model = QStringListModel()
		bundle_lists = []
		self.bundle_model.setStringList(bundle_lists)

		root = self.file_model.setRootPath("/Volumes")



		self.columnView_files.setModel(self.file_model)
		self.columnView_files.setRootIndex(root)
		self.listView_files.setModel(self.bundle_model)

		# connect the buttons
		self.pushButton_add_file.clicked.connect(self._add_to_bundle)
		self.pushButton_remove_file.clicked.connect(self._remove_from_bundle)
		self.pushButton_cancle.clicked.connect(self.close_window)
		self.pushButton_add_object.clicked.connect(self.return_bundle)
Exemplo n.º 21
0
 def load_project_structure2(self):
     model = QFileSystemModel()
     model.setRootPath(My_Sync.path2)
     self.treeView_2.setModel(model)
     self.treeView_2.setRootIndex(model.index(My_Sync.path2))
     self.treeView_2.show()
class Main(QtWidgets.QMainWindow):
    def __init__(self):
        super(Main, self).__init__()

        # ================================================= CARGA FICHERO UI ==================================================

        uifile = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                              'InterfaceUI.ui')
        uic.loadUi(uifile, self)

        # ================================================= INICIA BOTONES ====================================================

        # Boton añadir carpeta:
        self.boton_anadir_carpeta.clicked.connect(self.fn_boton_anadir_carpeta)

        # Boton borrar fichero
        self.boton_borrar_fichero.clicked.connect(self.fn_boton_borrar_fichero)

        # Boton reset
        self.boton_Reset.clicked.connect(self.fn_boton_Reset)

        # Botones patogeno
        self.boton_AB.clicked.connect(
            lambda: self.obten_nombre_patogeno_analisis(nombre_boton=self.
                                                        boton_AB))
        self.boton_BC.clicked.connect(
            lambda: self.obten_nombre_patogeno_analisis(nombre_boton=self.
                                                        boton_BC))
        self.boton_CA.clicked.connect(
            lambda: self.obten_nombre_patogeno_analisis(nombre_boton=self.
                                                        boton_CA))
        self.boton_EC.clicked.connect(
            lambda: self.obten_nombre_patogeno_analisis(nombre_boton=self.
                                                        boton_EC))
        self.boton_PA.clicked.connect(
            lambda: self.obten_nombre_patogeno_analisis(nombre_boton=self.
                                                        boton_PA))
        self.boton_SA.clicked.connect(
            lambda: self.obten_nombre_patogeno_analisis(nombre_boton=self.
                                                        boton_SA))
        self.boton_MO.clicked.connect(
            lambda: self.obten_nombre_patogeno_analisis(nombre_boton=self.
                                                        boton_MO))
        self.boton_LE.clicked.connect(
            lambda: self.obten_nombre_patogeno_analisis(nombre_boton=self.
                                                        boton_LE))
        self.boton_AM.clicked.connect(
            lambda: self.obten_nombre_patogeno_analisis(nombre_boton=self.
                                                        boton_AM))

        # Botones dilucion
        self.boton_D1.clicked.connect(
            lambda: self.obten_nombre_dilucion(nombre_boton=self.boton_D1))
        self.boton_D2.clicked.connect(
            lambda: self.obten_nombre_dilucion(nombre_boton=self.boton_D2))
        self.boton_D3.clicked.connect(
            lambda: self.obten_nombre_dilucion(nombre_boton=self.boton_D3))
        self.comboBox_DOtro.currentIndexChanged.connect(
            self.obten_nombre_dilucion_comboBox)

        # Botones tiempo
        self.boton_T0.clicked.connect(
            lambda: self.obten_nombre_tiempo(nombre_boton=self.boton_T0))
        self.boton_T7.clicked.connect(
            lambda: self.obten_nombre_tiempo(nombre_boton=self.boton_T7))
        self.boton_T14.clicked.connect(
            lambda: self.obten_nombre_tiempo(nombre_boton=self.boton_T14))
        self.boton_T28.clicked.connect(
            lambda: self.obten_nombre_tiempo(nombre_boton=self.boton_T28))

        # Boton zona
        self.comboBox_zona.currentIndexChanged.connect(
            self.obten_nombre_zona_comboBox)

        # Botones ver-ocultar
        self.boton_ver.clicked.connect(self.fn_boton_ver)
        self.boton_ocultar.clicked.connect(self.fn_boton_ocultar)
        # Boton inferencia
        self.boton_Evaluar.clicked.connect(self.fn_boton_Evaluar)

        # Botones ventana
        finish = QAction("Quit", self)
        finish.triggered.connect(self.closeEvent)

        # Tabla resultados
        # columnas = ['ID Placa', 'CH', 'Ref', 'Resultado']
        # self.tabla.setColumnCount(4)
        # self.tabla.setRowCount(1)
        # self.tabla.setHorizontalHeaderLabels(columnas)
        # self.tabla.setItem(0, 0, QTableWidgetItem('Hola'))
        # self.tabla.cellClicked.connect(self.fn_mostrarItem)

        self.db = QSqlDatabase.addDatabase('QODBC')
        self.db.setDatabaseName(CONN_STRING)
        self.db.open()
        self.qry = QSqlQuery(self.db)
        self.modelo_query = QSqlQueryModel()

        SQL_STATEMENT = 'INSERT INTO dbo.Tabla_Placa(id_TipoAnalisis, id_TipoPatogeno) VALUES (AG, EC)'
        self.ejecuta_query(SQL_STATEMENT)

        # Botones camara
        self.boton_camara.clicked.connect(self.fn_boton_camara)
        self.boton_CapturaImagen.clicked.connect(self.fn_boton_CapturaImagen)
        self.FLAG_CAMARA_ACTIVA = 0
        self.FLAG_CAPTURA_IMAGEN = 0
        self.inicializa_nombre_imagen()

        # Botones edicion
        self.boton_lapiz.clicked.connect(self.fn_boton_lapiz)
        self.boton_borrar.clicked.connect(self.fn_boton_borrar)
        self.boton_validar.clicked.connect(self.fn_boton_validar)
        self.boton_cancelar.clicked.connect(self.fn_boton_cancelar)
        self.boton_ausencia.clicked.connect(self.fn_boton_ausencia)
        self.boton_presencia.clicked.connect(self.fn_boton_presencia)
        self.visor.mousePressEvent = self.mousePressEvent
        self.primer_click_x = 0
        self.primer_click_y = 0
        self.segundo_click_x = 0
        self.segundo_click_y = 0
        self.lista_nuevas_boxes = []
        self.lista_borrar_boxes = []

        self.FLAG_DIBUJAR = False
        self.FLAG_BORRAR = False
        self.FLAG_PRIMER_CLICK = True
        self.FLAG_SEGUNDO_CLICK = False
        self.FLAG_VALIDAR_EDICION_DETECCION = False
        self.FLAG_VALIDAR_EDICION_CLASIFICACION = False

        # ================================================= INICIA DIRECTORIOS ============================================
        """ El pipeline de este apartado se encarga de obtener y mostrar las imagenes que hay en el directorio, incluyendo
        las distintas subcarpetas de tipos de analisis, refererencias, etc. Concretamente, al clicar sobre el directorio
        de tipos de analisis, se actualiza su hijo, y asi consecutivamente. Para ello se han creado unas funciones externas
        que se encargan de ello. Además, tambien se obtiene la ruta de la imagen objetivo seleccionada para poder usarla
        en el resto de funciones de la interfaz. Si el elemento seleccionado es una imagen, se mostrará en el visor. Si
        esta imagen se ha inferenciado anteriormente, se mostrará la imagen con las regiones. Si no se ha inferenciado,
        se habilitará el botón de evaluacion de placa.
        """
        # Asociamos la ruta donde se encuentran las carpetas de los tipos de analisis y creamos el objeto para listar el directorio
        self.dirModel = QFileSystemModel()
        self.dirModel.setRootPath(PATH_IMGS_PRUEBA)

        # Mediante la funcion externa, se recorren todos los ficheros existentes en el directorio padre
        lista_primer_directorio(self.lista_analisis, self.dirModel)

        # Mediante los clicks en las carpetas de los subdirectorios se llama a ciertas funciones que recorren el interior de
        # la carpeta seleccionada y lo muestran por pantalla.
        self.lista_analisis.clicked.connect(lambda: lista_resto_directorios(
            self.lista_analisis, self.lista_lotes, self.lista_imagenes, self.
            dirModel, 1))
        self.lista_lotes.clicked.connect(lambda: lista_resto_directorios(
            self.lista_lotes, self.lista_imagenes, None, self.dirModel))
        self.lista_lotes.clicked.connect(
            lambda: self.obten_path_del_directorio(Qlist=self.lista_lotes))
        self.lista_imagenes.clicked.connect(
            lambda: self.obten_path_del_directorio(Qlist=self.lista_imagenes))

    # La siguiente funcion obtiene el elemento seleccionado de los directorios, y en caso de ser una imagen, la mostrará en el visor.
    # tambien se adquiere el nombre del elemento seleccionado para poder trabajar futuramente con el.

    def obten_path_del_directorio(self, Qlist):
        index = Qlist.currentIndex()
        self.path_seleccionado_del_directorio = self.dirModel.filePath(index)
        self.elemento_seleccionado = self.path_seleccionado_del_directorio.split(
            '/')[-1]
        self.label_elemento_seleccionado.setText(self.elemento_seleccionado)
        self.boton_Evaluar.setEnabled(True)

        if self.path_seleccionado_del_directorio[-3:] == 'png':
            self.decide_que_imagen_colocar_en_visor()

# ================================================= VISOR DE IMAGEN ==================================================
        """Este apartado contiene las funciones que manejan la imagen que se coloca en el visor. En funcion de si la imagen
        ha sido inferenciada o no, se carga su solucion o no. Si existe solucion, se permite activar el modo edicion, y
        los botones de ver/ocultar regiones. Si se ha clicado una imagen y anteriormente la camara estaba encendida, esta
        se apagara, y la imagen mostrada se sustituira por la seleccionada.
        """
    def decide_que_imagen_colocar_en_visor(self):
        # Miramos si la imagen ha sido inferencia, y en caso de que si, la colocamos en el visor. Si no, colocamos la imagen
        # sin inferenciar.
        self.path_seleccionado_del_directorio_modificado = self.path_seleccionado_del_directorio

        self.lista_archivos_directorio = os.listdir(
            os.path.join(self.path_seleccionado_del_directorio_modificado,
                         os.pardir))
        imagen_con_OK = self.path_seleccionado_del_directorio_modificado.split(
            '/')[-1][:-4] + "_OK.png"

        self.activar_desactivar_botones_edicion(0)
        self.boton_Evaluar.setEnabled(True)
        self.label_resultado_prediccion.setText("Resultado no disponible")

        if imagen_con_OK in self.lista_archivos_directorio:
            self.path_seleccionado_del_directorio_modificado = self.path_seleccionado_del_directorio_modificado[:
                                                                                                                -4] + "_OK.png"

            self.boton_ver.setDisabled(True)
            self.boton_ocultar.setEnabled(True)
            self.activar_desactivar_botones_edicion(1)
            self.label_resultado_prediccion.setText(
                muestra_resultado_enLabel(
                    self.path_seleccionado_del_directorio_modificado))

        if self.FLAG_CAMARA_ACTIVA:
            self.activa_desactiva_camara(1)

        self.coloca_imagen_seleccionada_en_visor(
            path=self.path_seleccionado_del_directorio_modificado)

    def coloca_imagen_seleccionada_en_visor(self,
                                            path,
                                            camara=0,
                                            imagen_camara=None):

        # Colocamos la imagen correspondiente en el visor
        if camara == 1:
            imagen_visor = QPixmap.fromImage(imagen_camara)
        else:
            imagen_visor = QPixmap(f"{path}")

        self.imagen_visor_escalada = imagen_visor.scaled(
            int(self.visor.width()), int(self.visor.height()),
            QtCore.Qt.KeepAspectRatio)
        self.visor.setPixmap(self.imagen_visor_escalada)

        # Obtenemos las medidas del visor y de la imagen para despues poder comprobar si los click en modo edicion se efectuan dentro de la imagen
        ancho_imagen_visor = imagen_visor.width()
        alto_imagen_visor = imagen_visor.height()
        ancho_imagen_visor_escalada = self.imagen_visor_escalada.width()
        alto_imagen_visor_escalada = self.imagen_visor_escalada.height()
        ancho_visor = self.visor.width()
        alto_visor = self.visor.height()

        self.ancho_zonaClick_imagen = [
            (ancho_visor - ancho_imagen_visor_escalada) / 2,
            (ancho_visor - ancho_imagen_visor_escalada) / 2 +
            ancho_imagen_visor_escalada
        ]
        self.alto_zonaClick_imagen = [
            (alto_visor - alto_imagen_visor_escalada) / 2,
            (alto_visor - alto_imagen_visor_escalada) / 2 +
            alto_imagen_visor_escalada
        ]
        self.offset_X = (ancho_visor - ancho_imagen_visor_escalada) / 2
        self.offset_Y = (alto_visor - alto_imagen_visor_escalada) / 2
        self.factor_escala_dimension_x = ancho_imagen_visor_escalada / ancho_imagen_visor
        self.factor_escala_dimension_y = alto_imagen_visor_escalada / alto_imagen_visor

        # ================================================== MANEJAR CAMARA ==================================================
        """A traves del siguiente apartado se maneja mediante multihilo la ejecucion de la camara, de manera que esta se activa
        o desactiva segun los botones pulsados. En funcion de esto, se activan y desactivan ciertos botones. Ademas,
        al final del apartado se configura el estilo del boton de activar la camara para saber la sitaucion de esta.
        """

    def fn_boton_camara(self):
        self.activa_desactiva_camara(self.FLAG_CAMARA_ACTIVA)

    def recibeImagenCamara(self, imagen_camara):
        self.coloca_imagen_seleccionada_en_visor(path=None,
                                                 camara=1,
                                                 imagen_camara=imagen_camara)
        # self.lista_imagenes.setDisabled(False)

        if self.FLAG_CAPTURA_IMAGEN:
            self.guarda_imagen_capturada(imagen_camara)

    def activa_desactiva_camara(self, FLAG_CAMARA):

        # Se enchufa la camara
        if FLAG_CAMARA == 0:

            self.camaraQThread = ActivaCamara()
            self.boton_camara.setDisabled(True)
            self.camaraQThread.envio_imagen.connect(self.recibeImagenCamara)
            self.camaraQThread.envio_imagen_capturar.connect(
                self.recibeImagenCamara)
            self.camaraQThread.start()
            self.boton_CapturaImagen.setEnabled(True)
            self.activar_desactivar_botones_eleccion(1)
            self.activar_desactivar_botones_edicion(0)
            self.styleSheet_boton_camara(FLAG_CAMARA)
            self.boton_camara.setDisabled(False)
            self.FLAG_CAMARA_ACTIVA = 1

        # Se apaga la camara
        else:
            self.camaraQThread.stop()
            self.boton_camara.setDisabled(True)
            self.boton_CapturaImagen.setDisabled(True)
            self.activar_desactivar_botones_eleccion(0)
            self.styleSheet_boton_camara(FLAG_CAMARA)
            self.boton_camara.setDisabled(False)
            self.FLAG_CAMARA_ACTIVA = 0

    def fn_boton_CapturaImagen(self):
        self.FLAG_CAPTURA_IMAGEN = 1

    def styleSheet_boton_camara(self, FLAG_CAMARA):
        if FLAG_CAMARA:
            self.boton_camara.setStyleSheet(
                "QPushButton{background-color: #06aa58;; border: None; border-radius: 5px;}"
                "QPushButton:disabled{background-color: rgb(124, 124, 124);} #gris oscuro"
            )
            self.boton_camara.setText("ACTIVAR CAMARA")
        else:
            self.boton_camara.setStyleSheet(
                "QPushButton{background-color: #06aa58;; border: None; border-radius: 5px;}"
                "QPushButton:disabled{background-color: rgb(124, 124, 124);} #gris oscuro"
            )
            self.boton_camara.setText("DESACTIVAR CAMARA")

# ============================================== GUARDAR IMAGEN CAMARA ===============================================
        """A traves del siguiente apartado se configuran las funciones que permiten guardar una imagen cuando se pulsa el
        boton de capturar imagen. Simplemente, se forma el nombre de la imagen en funcion de los botones seleccionados (tipo
        de patogeno, referencia, fecha, etc), y este nombre se une a la ruta donde se quiere guardar la imagen,
        definida por las carpetas seleccionadas en el menu de archivos. En caso de que el nombre de imagen ya existe,
        automaticamente se renombran las imagenes para que no se sobreescriban.
        """
    def guarda_imagen_capturada(self, imagen_camara):
        imagen = QPixmap.fromImage(imagen_camara)
        carpeta_destino = self.path_seleccionado_del_directorio
        self.comprobar_si_existe_nombre(self.nombre_imagen)
        imagen.save(f"{carpeta_destino}/{self.nombre_imagen}.png")
        self.FLAG_CAPTURA_IMAGEN = 0

    def obten_nombre_patogeno_analisis(self, nombre_boton):
        try:
            self.id_analisis = TEXTO_CARPETAS_ANALISIS[
                self.path_seleccionado_del_directorio.split('/')[-2]]
        except:
            texto = "Debes de seleccionar antes una carpeta de referencia (COLUMNA CENTRAL)"
            crea_mensaje_alerta(texto)

        self.id_num = ""
        self.id_patogeno = f"_{TEXTO_BOTONES_PATOGENO[nombre_boton.text()]}"
        self.forma_nombre_imagen()

    def obten_nombre_dilucion(self, nombre_boton):
        self.id_dilucion = f"-{TEXTO_BOTONES_DILUCION[nombre_boton.text()]}"
        self.forma_nombre_imagen()

    def obten_nombre_dilucion_comboBox(self):
        self.id_dilucion = f"-{TEXTO_COMBOBOX_DILUCION[self.comboBox_DOtro.currentText()]}"
        self.forma_nombre_imagen()

    def obten_nombre_tiempo(self, nombre_boton):
        self.id_tiempo = f"-{TEXTO_BOTONES_TIEMPO[nombre_boton.text()]}"
        self.forma_nombre_imagen()

    def obten_nombre_zona_comboBox(self):
        self.id_zona = f"-{TEXTO_COMBOBOX_ZONAS[self.comboBox_zona.currentText()]}"
        self.forma_nombre_imagen()

    def forma_nombre_imagen(self):
        self.nombre_imagen = f"{self.id_analisis}{self.id_patogeno}{self.id_num}{self.id_tiempo}{self.id_dilucion}{self.id_zona}"

        # self.comprobar_si_existe_nombre(self.nombre_imagen)

        self.label_nombre_imagen.setText(self.nombre_imagen)

    def comprobar_si_existe_nombre(self, nombre_imagen):
        if (f"{nombre_imagen}.png" or
                f"{nombre_imagen[0:5]}0{nombre_imagen[5:]}.png") in os.listdir(
                    self.path_seleccionado_del_directorio):
            id = nombre_imagen.split('-')[0]
            if len(id) == 6:
                self.id_num = int(id[-1]) + 1
            else:
                self.id_num = 1
                os.rename(
                    f"{self.path_seleccionado_del_directorio}/{nombre_imagen}.png",
                    f"{self.path_seleccionado_del_directorio}/{nombre_imagen[0:5]}0{nombre_imagen[5:]}.png"
                )

            self.forma_nombre_imagen()

    def inicializa_nombre_imagen(self):
        self.id_analisis = ""
        self.id_patogeno = ""
        self.id_tiempo = ""
        self.id_dilucion = ""
        self.id_num = ""
        self.id_zona = ""
        self.comboBox_zona.setCurrentIndex(0)
        self.comboBox_DOtro.setCurrentIndex(0)
        self.forma_nombre_imagen()

    def fn_boton_Reset(self):
        self.inicializa_nombre_imagen()

        # ============================================= AÑADIR / ELIMINAR FICHEROS ============================================
        """Mediante las siguientes funciones se añadir o eliminan ficheros y/o carpetas seleecionadas en el menu de archivos.
        Siempre se pedira confirmacion en caso de eliminar algo a través de un mensaje de alerta.
        """

    def fn_boton_anadir_carpeta(self):
        nombre_nueva_carpeta = self.edit_nombre_nueva_carpeta.text()
        if len(nombre_nueva_carpeta) != 0:
            index = self.lista_analisis.currentIndex()
            path_nueva_carpeta_aux = self.dirModel.filePath(index)
            path_nueva_carpeta = f"{path_nueva_carpeta_aux}/{nombre_nueva_carpeta}"

            try:
                os.mkdir(path_nueva_carpeta)

            except:
                texto = "La carpeta que intentas crear ya existe"
                crea_mensaje_alerta(texto)

        else:
            texto = "No has introducido ningun nombre de carpeta"
            crea_mensaje_alerta(texto)

    def fn_boton_borrar_fichero(self, event):

        borrar = QMessageBox.question(
            self, "ELIMINAR FICHERO",
            "¿ESTAS SEGURO DE ELIMINAR ESTE FICHERO?",
            QMessageBox.Yes | QMessageBox.No)
        if borrar == QMessageBox.Yes:
            if self.path_seleccionado_del_directorio[-4:] != ".png":
                shutil.rmtree(self.path_seleccionado_del_directorio)
                model_limpiar_lista_imagenes = QStandardItemModel()
                self.lista_imagenes.setModel(model_limpiar_lista_imagenes)
                model_limpiar_lista_imagenes.removeRow(0)

            else:
                os.remove(self.path_seleccionado_del_directorio)
        else:
            event.ignore()

# ========================================= ACTIVAR DESACTIVAR CONJUNTO DE BOTONES ===================================
        """Aqui se configura la ativacion/desactivacion de los botones de la GUI dependiendo del modo de trabajo en el que
        estemos, ya sea evaluación, o captura de imagenes.
        """
    def activar_desactivar_botones_eleccion(self, FLAG_BOTONES):
        self.boton_AB.setEnabled(FLAG_BOTONES)
        self.boton_BC.setEnabled(FLAG_BOTONES)
        self.boton_CA.setEnabled(FLAG_BOTONES)
        self.boton_EC.setEnabled(FLAG_BOTONES)
        self.boton_PA.setEnabled(FLAG_BOTONES)
        self.boton_SA.setEnabled(FLAG_BOTONES)
        self.boton_MO.setEnabled(FLAG_BOTONES)
        self.boton_LE.setEnabled(FLAG_BOTONES)
        self.boton_AM.setEnabled(FLAG_BOTONES)
        self.boton_D1.setEnabled(FLAG_BOTONES)
        self.boton_D2.setEnabled(FLAG_BOTONES)
        self.boton_D3.setEnabled(FLAG_BOTONES)
        self.comboBox_DOtro.setEnabled(FLAG_BOTONES)
        self.boton_T0.setEnabled(FLAG_BOTONES)
        self.boton_T7.setEnabled(FLAG_BOTONES)
        self.boton_T14.setEnabled(FLAG_BOTONES)
        self.boton_T28.setEnabled(FLAG_BOTONES)
        self.comboBox_zona.setEnabled(FLAG_BOTONES)

    def activar_desactivar_botones_edicion(self, FLAG_BOTONES):
        self.boton_ver.setEnabled(FLAG_BOTONES)
        self.boton_ocultar.setEnabled(FLAG_BOTONES)
        self.boton_lapiz.setEnabled(FLAG_BOTONES)
        self.boton_borrar.setEnabled(FLAG_BOTONES)
        # self.boton_validar.setEnabled(FLAG_BOTONES)
        # self.boton_cancelar.setEnabled(FLAG_BOTONES)
        self.boton_ausencia.setEnabled(FLAG_BOTONES)
        self.boton_presencia.setEnabled(FLAG_BOTONES)
        self.boton_Evaluar.setEnabled(FLAG_BOTONES)

        # ================================================= VER / OCULTAR RESULTADO ==========================================
        """Estas funciones permiten ocultar/mostrar las regiones de una imagen en caso de haberlas.
        """

    def fn_boton_ver(self):
        self.coloca_imagen_seleccionada_en_visor(
            path=self.path_seleccionado_del_directorio_modificado)
        self.boton_ver.setDisabled(True)
        self.boton_ocultar.setEnabled(True)

    def fn_boton_ocultar(self):
        self.coloca_imagen_seleccionada_en_visor(
            path=self.path_seleccionado_del_directorio)
        self.boton_ocultar.setDisabled(True)
        self.boton_ver.setEnabled(True)

        # ================================================ FUNCIONES INFERENCIA ==============================================
        """En este apartado se ejecuta el pipeline asociado a la inferencia de la imagen seleccionada. Se ha de clicar
        en el boton evaluar, y entonces se ejecuta un multihilo que a su vez ejecuta distintas funciones. Entre ellas,
        elegir el modelo de prediccion, determinar si la tarea es de deteccion y clasificacion, y guardar el resultado
        en una nueva imagen/fichero. Además, se ha añadido una progressBar que se actualiza a medida que las imagenes
        se infernecias, ya que se puede inferenciar una unica placa si se selecciona la imagen, o todas las placas
        contenidas en la carpeta si se selecciona la carpeta.
        """

    def fn_boton_Evaluar(self):

        self.progresBar.setValue(0)
        Main.setDisabled(self, True)
        self.prediccionQThread = CalculaPrediccion(
            self.path_seleccionado_del_directorio)
        self.prediccionQThread.envio_prediccion.connect(self.recibePrediccion)
        self.prediccionQThread.envio_valor_progressBar.connect(
            self.maneja_valor_progresBar)
        self.prediccionQThread.start()

    def recibePrediccion(self, prediccion):
        "Se obtiene un diccionario con los paths de las imagenes y la prediccion"

        self.prediccionQThread.stop()
        try:
            guarda_ImagenFichero_prediccion(prediccion)
        except:
            texto = "Todas las placas han sido ya evaluadas"
            Main.setDisabled(self, False)
            self.progresBar.setValue(0)
            crea_mensaje_alerta(texto)

        Main.setDisabled(self, False)
        self.progresBar.setValue(100)

    def maneja_valor_progresBar(self, valor):
        self.progresBar.setValue(valor)

        # ============================================== FUNCIONES CERRAR VENTANA ============================================
        """A traves de estas funciones se define la logica de cierre de ventana.
        """

    def closeEvent(self, event):
        """
        Cerrar la ventana a través de el boton X de la esquina supeior derecha

        :param event: evento del raton
        :return: None
        """
        close = QMessageBox.question(self, "SALIR",
                                     "¿ESTAS SEGURO/A DE QUERER SALIR?",
                                     QMessageBox.Yes | QMessageBox.No)
        if close == QMessageBox.Yes:
            event.accept()
            exit()
        else:
            event.ignore()

    def keyPressEvent(self, e):
        """
        Cerrar la ventana a traves de la tecla ESC

        :param e: evento del teclado
        :return: None
        """
        if e.key() == QtCore.Qt.Key_Escape:
            self.closeEvent(e)
            self.close()
        if e.key() == QtCore.Qt.Key_F11:
            if self.isMaximized():
                self.showNormal()
            else:
                self.showMaximized()

# =================================================== MODO EDICION ====================================================
        """Es en el actual apartado se configuran las funciones de las botoneras de edicion. Para ello, se tiene en cuenta
        la pulsacion del raton. Si se selecciona el lapiz, se pintan las regiones en la pantalla mediante dos clicks y 
        despues se han de confirmar los cambios. Esta confirmacion generara un nuevo archivo con las coordenadas de las regiones
        y una nueva imagen pintada. En caso de utilizar la herramienta de borrar, se selecciona la region a borrar y posteriormente
        se confirma, eliminando asi las respectivas coordenadas. Mediante los botones de ausencia y presencia, y se elige la 
        clase a la cual pertene la placa que se esta editando. 
        """
    def fn_boton_lapiz(self):
        self.activar_desactivar_botones_edicion(False)
        self.boton_validar.setDisabled(False)
        self.boton_cancelar.setDisabled(False)
        self.FLAG_DIBUJAR = True
        self.FLAG_VALIDAR_EDICION_DETECCION = True

    def fn_boton_borrar(self):
        self.activar_desactivar_botones_edicion(False)
        self.boton_validar.setDisabled(False)
        self.boton_cancelar.setDisabled(False)
        self.FLAG_BORRAR = True
        self.FLAG_VALIDAR_EDICION_DETECCION = True

    def fn_boton_ausencia(self):
        self.activar_desactivar_botones_edicion(False)
        self.boton_validar.setDisabled(False)
        self.boton_cancelar.setDisabled(False)
        self.nueva_clase = 'AUSENCIA'
        self.FLAG_VALIDAR_EDICION_CLASIFICACION = True

    def fn_boton_presencia(self):
        self.activar_desactivar_botones_edicion(False)
        self.boton_validar.setDisabled(False)
        self.boton_cancelar.setDisabled(False)
        self.nueva_clase = 'PRESENCIA'
        self.FLAG_VALIDAR_EDICION_CLASIFICACION = True

    def fn_boton_validar(self):
        self.activar_desactivar_botones_edicion(True)
        self.boton_validar.setDisabled(True)
        self.boton_cancelar.setDisabled(True)

        if self.FLAG_DIBUJAR:
            nuevo_resultado = self.lista_nuevas_boxes
        elif self.FLAG_BORRAR:
            nuevo_resultado = self.lista_borrar_boxes
        elif self.FLAG_VALIDAR_EDICION_CLASIFICACION:
            nuevo_resultado = self.nueva_clase

        valida_cambios_edicion(
            nuevo_resultado,
            path_archivo=self.path_seleccionado_del_directorio_modificado,
            flag_dibujar=self.FLAG_DIBUJAR,
            flag_borrar=self.FLAG_BORRAR,
            flag_edicion_clasificacion=self.FLAG_VALIDAR_EDICION_CLASIFICACION)

        self.coloca_imagen_seleccionada_en_visor(
            path=self.path_seleccionado_del_directorio_modificado)

        self.label_resultado_prediccion.setText(
            muestra_resultado_enLabel(
                self.path_seleccionado_del_directorio_modificado))

        self.lista_nuevas_boxes = []
        self.lista_borrar_boxes = []
        self.FLAG_DIBUJAR = False
        self.FLAG_BORRAR = False
        self.FLAG_VALIDAR_EDICION_CLASIFICACION = False

    def fn_boton_cancelar(self):
        self.activar_desactivar_botones_edicion(True)
        self.boton_validar.setDisabled(True)
        self.boton_cancelar.setDisabled(True)

        self.coloca_imagen_seleccionada_en_visor(
            path=self.path_seleccionado_del_directorio_modificado)
        self.label_resultado_prediccion.setText(
            muestra_resultado_enLabel(
                self.path_seleccionado_del_directorio_modificado))

        self.lista_nuevas_boxes = []
        self.lista_borrar_boxes = []
        self.FLAG_DIBUJAR = False
        self.FLAG_BORRAR = False
        self.FLAG_VALIDAR_EDICION_DETECCION = False
        self.FLAG_VALIDAR_EDICION_CLASIFICACION = False

    def mousePressEvent(self, event):

        if self.FLAG_DIBUJAR:

            if self.FLAG_PRIMER_CLICK:
                self.primer_click = self.visor.mapFromParent(event.pos())
                self.primer_click_x = self.primer_click.x()
                self.primer_click_y = self.primer_click.y()

                if comprueba_click_dentro_imagen(self.primer_click_x,
                                                 self.primer_click_y,
                                                 self.ancho_zonaClick_imagen,
                                                 self.alto_zonaClick_imagen):

                    self.FLAG_PRIMER_CLICK = False
                    self.FLAG_SEGUNDO_CLICK = True

            elif self.FLAG_SEGUNDO_CLICK:
                self.segundo_click = self.visor.mapFromParent(event.pos())
                self.segundo_click_x = self.segundo_click.x()
                self.segundo_click_y = self.segundo_click.y()

                if comprueba_click_dentro_imagen(self.segundo_click_x,
                                                 self.segundo_click_y,
                                                 self.ancho_zonaClick_imagen,
                                                 self.alto_zonaClick_imagen):

                    self.FLAG_PRIMER_CLICK = True
                    self.FLAG_SEGUNDO_CLICK = False

                    dibuja_region(QPainter(self.visor.pixmap()),
                                  self.primer_click_x, self.primer_click_y,
                                  self.segundo_click_x, self.segundo_click_y,
                                  'green', 3, self.offset_X, self.offset_Y)

                    self.update()
                    self.visor.update()

                    # Guardamos en una lista la nueva region añadida
                    box_a_anadir = [
                        int(
                            min([
                                self.primer_click_x - self.offset_X,
                                self.segundo_click_x - self.offset_X
                            ]) / self.factor_escala_dimension_x),
                        int(
                            min([
                                self.primer_click_y - self.offset_Y,
                                self.segundo_click_y - self.offset_Y
                            ]) / self.factor_escala_dimension_y),
                        int(
                            max([
                                self.primer_click_x - self.offset_X,
                                self.segundo_click_x - self.offset_X
                            ]) / self.factor_escala_dimension_x),
                        int(
                            max([
                                self.primer_click_y - self.offset_Y,
                                self.segundo_click_y - self.offset_Y
                            ]) / self.factor_escala_dimension_y)
                    ]

                    self.lista_nuevas_boxes.append(box_a_anadir)

        elif self.FLAG_BORRAR:
            self.click_borrar = self.visor.mapFromParent(event.pos())
            self.click_borrar_x = self.click_borrar.x()
            self.click_borrar_y = self.click_borrar.y()

            if comprueba_click_dentro_imagen(self.click_borrar_x,
                                             self.click_borrar_x,
                                             self.ancho_zonaClick_imagen,
                                             self.alto_zonaClick_imagen):

                coordenadas_click = [
                    int(self.click_borrar_x),
                    int(self.click_borrar_y)
                ]

                box_a_borrar, click_correcto = borrar_region(
                    QPainter(self.visor.pixmap()), coordenadas_click,
                    self.path_seleccionado_del_directorio_modificado, 'red', 3,
                    self.offset_X, self.offset_Y,
                    self.factor_escala_dimension_x,
                    self.factor_escala_dimension_y)

                if click_correcto:
                    self.update()
                    self.visor.update()
                    self.lista_borrar_boxes.append(box_a_borrar)

    # def paintEvent(self, event):
    #     if self.FLAG_DIBUJAR:
    #         qp = QPainter(self.visor.pixmap())
    #         br = QtGui.QBrush(QColor(100, 10, 10, 40))
    #         qp.setBrush(br)
    #         qp.drawRect(QtCore.QRect(self.begin, self.end))

    # def mousePressEvent(self, event):
    #     self.begin = self.visor.mapFromParent(event.pos())
    #     self.end = self.visor.mapFromParent(event.pos())
    #     self.update()
    #     # self.visor.update()

    # def mouseMoveEvent(self, event):
    #     self.end = self.visor.mapFromParent(event.pos())
    #     self.update()
    #     # self.visor.update()

    # def mouseReleaseEvent(self, event):
    #     self.begin = self.visor.mapFromParent(event.pos())
    #     self.end = self.visor.mapFromParent(event.pos())
    #     self.update()
    #     self.visor.update()

# =================================================== TABLA RESULTADOS ==================================================

    def fn_mostrarItem(self, fila, columna):
        try:
            print(self.tabla.item(fila, columna).text())
        except:
            pass

    def ejecuta_query(self, sqlStatement):
        self.qry.prepare(sqlStatement)
        self.qry.exec()

        self.fn_muestra_datos(self.qry)

    def fn_muestra_datos(self, query):

        self.modelo_query.setQuery(query)
        self.tabla.setModel(self.modelo_query)
        self.tabla.show()
Exemplo n.º 23
0
class FileChooser(QWidget):
    fileOpened = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        # TODO: migrate to FolderComboBox?
        self.folderBox = QComboBox(self)
        self.explorerTree = FileTreeView(self)
        self.explorerTree.doubleClickCallback = self._fileOpened
        self.explorerModel = QFileSystemModel(self)
        self.explorerModel.setFilter(QDir.AllDirs | QDir.Files
                                     | QDir.NoDotAndDotDot)
        self.explorerModel.setNameFilters(["*.py"])
        self.explorerModel.setNameFilterDisables(False)
        self.explorerTree.setModel(self.explorerModel)
        for index in range(1, self.explorerModel.columnCount()):
            self.explorerTree.hideColumn(index)
        self.setCurrentFolder()
        self.folderBox.currentIndexChanged[int].connect(
            self.updateCurrentFolder)

        layout = QVBoxLayout(self)
        layout.addWidget(self.folderBox)
        layout.addWidget(self.explorerTree)
        layout.setContentsMargins(5, 5, 0, 0)

    def _fileOpened(self, modelIndex):
        path = self.explorerModel.filePath(modelIndex)
        if os.path.isfile(path):
            self.fileOpened.emit(path)

    def currentFolder(self):
        return self.explorerModel.rootPath()

    def setCurrentFolder(self, path=None):
        if path is None:
            app = QApplication.instance()
            path = app.getScriptsDirectory()
        else:
            assert os.path.isdir(path)
        self.explorerModel.setRootPath(path)
        self.explorerTree.setRootIndex(self.explorerModel.index(path))
        self.folderBox.blockSignals(True)
        self.folderBox.clear()
        style = self.style()
        dirIcon = style.standardIcon(style.SP_DirIcon)
        self.folderBox.addItem(dirIcon, os.path.basename(path))
        self.folderBox.insertSeparator(1)
        self.folderBox.addItem(self.tr("Browse…"))
        self.folderBox.setCurrentIndex(0)
        self.folderBox.blockSignals(False)

    def updateCurrentFolder(self, index):
        if index < self.folderBox.count() - 1:
            return
        path = QFileDialog.getExistingDirectory(self,
                                                self.tr("Choose Directory"),
                                                self.currentFolder(),
                                                QFileDialog.ShowDirsOnly)
        if path:
            QSettings().setValue("scripting/path", path)
            self.setCurrentFolder(path)
Exemplo n.º 24
0
Arquivo: gui.py Projeto: minkione/pbtk
class PBTKGUI(QApplication):
    def __init__(self):
        super().__init__(argv)
        signal(SIGINT, SIG_DFL)

        views = dirname(realpath(__file__)) + '/views/'

        self.welcome = loadUi(views + 'welcome.ui')
        self.choose_extractor = loadUi(views + 'choose_extractor.ui')
        self.choose_proto = loadUi(views + 'choose_proto.ui')
        self.create_endpoint = loadUi(views + 'create_endpoint.ui')
        self.choose_endpoint = loadUi(views + 'choose_endpoint.ui')
        self.fuzzer = loadUi(views + 'fuzzer.ui')

        self.welcome.step1.clicked.connect(self.load_extractors)
        self.choose_extractor.rejected.connect(
            partial(self.set_view, self.welcome))
        self.choose_extractor.extractors.itemClicked.connect(
            self.prompt_extractor)

        self.welcome.step2.clicked.connect(self.load_protos)
        self.proto_fs = QFileSystemModel()
        self.choose_proto.protos.setModel(self.proto_fs)
        self.proto_fs.directoryLoaded.connect(
            self.choose_proto.protos.expandAll)

        for i in range(1, self.proto_fs.columnCount()):
            self.choose_proto.protos.hideColumn(i)
        self.choose_proto.protos.setRootIndex(
            self.proto_fs.index(str(BASE_PATH / 'protos')))
        self.choose_proto.rejected.connect(partial(self.set_view,
                                                   self.welcome))
        self.choose_proto.protos.clicked.connect(self.new_endpoint)

        self.create_endpoint.transports.itemClicked.connect(
            self.pick_transport)
        self.create_endpoint.loadRespPbBtn.clicked.connect(
            self.load_another_pb)
        self.create_endpoint.rejected.connect(
            partial(self.set_view, self.choose_proto))
        self.create_endpoint.buttonBox.accepted.connect(self.write_endpoint)

        self.welcome.step3.clicked.connect(self.load_endpoints)
        self.choose_endpoint.rejected.connect(
            partial(self.set_view, self.welcome))
        self.choose_endpoint.endpoints.itemClicked.connect(self.launch_fuzzer)

        self.fuzzer.rejected.connect(
            partial(self.set_view, self.choose_endpoint))
        self.fuzzer.fuzzFields.clicked.connect(self.fuzz_endpoint)
        self.fuzzer.deleteThis.clicked.connect(self.delete_endpoint)
        self.fuzzer.comboBox.activated.connect(self.launch_fuzzer)

        self.fuzzer.urlField.setWordWrapMode(QTextOption.WrapAnywhere)

        for tree in (self.fuzzer.pbTree, self.fuzzer.getTree):
            tree.itemEntered.connect(lambda item, _: item.edit()
                                     if hasattr(item, 'edit') else None)
            tree.itemClicked.connect(
                lambda item, col: item.update_check(col=col))
            tree.header().setSectionResizeMode(QHeaderView.ResizeToContents)

        self.welcome.mydirLabel.setText(self.welcome.mydirLabel.text() %
                                        BASE_PATH)
        self.welcome.mydirBtn.clicked.connect(
            partial(QDesktopServices.openUrl,
                    QUrl.fromLocalFile(str(BASE_PATH))))

        self.set_view(self.welcome)
        self.exec_()

    """
        Step 1 - Extract .proto structures from apps
    """

    def load_extractors(self):
        self.choose_extractor.extractors.clear()

        for name, meta in extractors.items():
            item = QListWidgetItem(meta['desc'],
                                   self.choose_extractor.extractors)
            item.setData(Qt.UserRole, name)

        self.set_view(self.choose_extractor)

    def prompt_extractor(self, item):
        extractor = extractors[item.data(Qt.UserRole)]
        inputs = []
        if not assert_installed(self.view, **extractor.get('depends', {})):
            return

        if not extractor.get('pick_url', False):
            files, mime = QFileDialog.getOpenFileNames()
            for path in files:
                inputs.append((path, Path(path).stem))
        else:
            text, good = QInputDialog.getText(self.view, ' ', 'Input an URL:')
            if text:
                url = urlparse(text)
                inputs.append((url.geturl(), url.netloc))

        if inputs:
            wait = QProgressDialog('Extracting .proto structures...', None, 0,
                                   0)
            wait.setWindowTitle(' ')
            self.set_view(wait)

            self.worker = Worker(inputs, extractor)
            self.worker.progress.connect(self.extraction_progress)
            self.worker.finished.connect(self.extraction_done)
            self.worker.signal_proxy.connect(self.signal_proxy)
            self.worker.start()

    def extraction_progress(self, info, progress):
        self.view.setLabelText(info)

        if progress is not None:
            self.view.setRange(0, 100)
            self.view.setValue(progress * 100)
        else:
            self.view.setRange(0, 0)

    def extraction_done(self, outputs):
        nb_written_all, wrote_endpoints = 0, False

        for folder, output in outputs.items():
            nb_written, wrote_endpoints = extractor_save(
                BASE_PATH, folder, output)
            nb_written_all += nb_written

        if wrote_endpoints:
            self.set_view(self.welcome)
            QMessageBox.information(
                self.view, ' ',
                '%d endpoints and their <i>.proto</i> structures have been extracted! You can now reuse the <i>.proto</i>s or fuzz the endpoints.'
                % nb_written_all)

        elif nb_written_all:
            self.set_view(self.welcome)
            QMessageBox.information(
                self.view, ' ',
                '%d <i>.proto</i> structures have been extracted! You can now reuse the <i>.protos</i> or define endpoints for them to fuzz.'
                % nb_written_all)

        else:
            self.set_view(self.choose_extractor)
            QMessageBox.warning(
                self.view, ' ',
                'This extractor did not find Protobuf structures in the corresponding format for specified files.'
            )

    """
        Step 2 - Link .protos to endpoints
    """

    # Don't load .protos from the filesystem until asked to, in order
    # not to slow down startup.

    def load_protos(self):
        self.proto_fs.setRootPath(str(BASE_PATH / 'protos'))
        self.set_view(self.choose_proto)

    def new_endpoint(self, path):
        if not self.proto_fs.isDir(path):
            path = self.proto_fs.filePath(path)

            if assert_installed(self.choose_proto, binaries=['protoc']):
                if not getattr(self, 'only_resp_combo', False):
                    self.create_endpoint.pbRequestCombo.clear()
                self.create_endpoint.pbRespCombo.clear()

                has_msgs = False
                for name, cls in load_proto_msgs(path):
                    has_msgs = True
                    if not getattr(self, 'only_resp_combo', False):
                        self.create_endpoint.pbRequestCombo.addItem(
                            name, (path, name))
                    self.create_endpoint.pbRespCombo.addItem(
                        name, (path, name))
                if not has_msgs:
                    QMessageBox.warning(
                        self.view, ' ',
                        'There is no message defined in this .proto.')
                    return

                self.create_endpoint.reqDataSubform.hide()

                if not getattr(self, 'only_resp_combo', False):
                    self.create_endpoint.endpointUrl.clear()
                    self.create_endpoint.transports.clear()
                    self.create_endpoint.sampleData.clear()
                    self.create_endpoint.pbParamKey.clear()
                    self.create_endpoint.parsePbCheckbox.setChecked(False)

                    for name, meta in transports.items():
                        item = QListWidgetItem(meta['desc'],
                                               self.create_endpoint.transports)
                        item.setData(Qt.UserRole,
                                     (name, meta.get('ui_data_form')))

                elif getattr(self, 'saved_transport_choice'):
                    self.create_endpoint.transports.setCurrentItem(
                        self.saved_transport_choice)
                    self.pick_transport(self.saved_transport_choice)
                    self.saved_transport_choice = None

                self.only_resp_combo = False
                self.set_view(self.create_endpoint)

    def pick_transport(self, item):
        name, desc = item.data(Qt.UserRole)
        self.has_pb_param = desc and 'regular' in desc
        self.create_endpoint.reqDataSubform.show()
        if self.has_pb_param:
            self.create_endpoint.pbParamSubform.show()
        else:
            self.create_endpoint.pbParamSubform.hide()
        self.create_endpoint.sampleDataLabel.setText(
            'Sample request data, one per line (in the form of %s):' % desc)

    def load_another_pb(self):
        self.only_resp_combo = True
        self.saved_transport_choice = self.create_endpoint.transports.currentItem(
        )
        self.set_view(self.choose_proto)

    def write_endpoint(self):
        request_pb = self.create_endpoint.pbRequestCombo.itemData(
            self.create_endpoint.pbRequestCombo.currentIndex())
        url = self.create_endpoint.endpointUrl.text()
        transport = self.create_endpoint.transports.currentItem()
        sample_data = self.create_endpoint.sampleData.toPlainText()
        pb_param = self.create_endpoint.pbParamKey.text()
        has_resp_pb = self.create_endpoint.parsePbCheckbox.isChecked()
        resp_pb = self.create_endpoint.pbRespCombo.itemData(
            self.create_endpoint.pbRespCombo.currentIndex())

        if not (request_pb and urlparse(url).netloc and transport and
                (not self.has_pb_param or pb_param) and
                (not has_resp_pb or resp_pb)):
            QMessageBox.warning(
                self.view, ' ', 'Please fill all relevant information fields.')

        else:
            json = {
                'request': {
                    'transport':
                    transport.data(Qt.UserRole)[0],
                    'proto_path':
                    request_pb[0].replace(str(BASE_PATH / 'protos'),
                                          '').strip('/\\'),
                    'proto_msg':
                    request_pb[1],
                    'url':
                    url
                }
            }
            if self.has_pb_param:
                json['request']['pb_param'] = pb_param

            sample_data = list(filter(None, sample_data.split('\n')))
            if sample_data:
                transport_obj = transports[transport.data(Qt.UserRole)[0]]
                transport_obj = transport_obj['func'](pb_param, url)

                for sample_id, sample in enumerate(sample_data):
                    try:
                        sample = transport_obj.serialize_sample(sample)
                    except Exception:
                        return QMessageBox.warning(
                            self.view, ' ',
                            'Some of your sample data is not in the specified format.'
                        )
                    if not sample:
                        return QMessageBox.warning(
                            self.view, ' ',
                            "Some of your sample data didn't contain the Protobuf parameter key you specified."
                        )
                    sample_data[sample_id] = sample

                json['request']['samples'] = sample_data

            if has_resp_pb:
                json['response'] = {
                    'format':
                    'raw_pb',
                    'proto_path':
                    resp_pb[0].replace(str(BASE_PATH / 'protos'),
                                       '').strip('/\\'),
                    'proto_msg':
                    resp_pb[1]
                }
            insert_endpoint(BASE_PATH / 'endpoints', json)

            QMessageBox.information(self.view, ' ',
                                    'Endpoint created successfully.')
            self.set_view(self.welcome)

    def load_endpoints(self):
        self.choose_endpoint.endpoints.clear()

        for name in listdir(str(BASE_PATH / 'endpoints')):
            if name.endswith('.json'):
                item = QListWidgetItem(
                    name.split('.json')[0], self.choose_endpoint.endpoints)
                item.setFlags(item.flags() & ~Qt.ItemIsEnabled)

                pb_msg_to_endpoints = defaultdict(list)
                with open(str(BASE_PATH / 'endpoints' / name)) as fd:
                    for endpoint in load(fd):
                        pb_msg_to_endpoints[endpoint['request']['proto_msg'].
                                            split('.')[-1]].append(endpoint)

                for pb_msg, endpoints in pb_msg_to_endpoints.items():
                    item = QListWidgetItem(' ' * 4 + pb_msg,
                                           self.choose_endpoint.endpoints)
                    item.setFlags(item.flags() & ~Qt.ItemIsEnabled)

                    for endpoint in endpoints:
                        item = QListWidgetItem(
                            ' ' * 8 +
                            (urlparse(endpoint['request']['url']).path or '/'),
                            self.choose_endpoint.endpoints)
                        item.setData(Qt.UserRole, endpoint)

        self.set_view(self.choose_endpoint)

    """
        Step 3: Fuzz and test endpoints live
    """

    def launch_fuzzer(self, item):
        if type(item) == int:
            data, sample_id = self.fuzzer.comboBox.itemData(item)
        else:
            data, sample_id = item.data(Qt.UserRole), 0

        if data and assert_installed(self.view, binaries=['protoc']):
            self.current_req_proto = BASE_PATH / 'protos' / data['request'][
                'proto_path']

            self.pb_request = load_proto_msgs(self.current_req_proto)
            self.pb_request = dict(
                self.pb_request)[data['request']['proto_msg']]()

            if data.get('response') and data['response']['format'] == 'raw_pb':
                self.pb_resp = load_proto_msgs(BASE_PATH / 'protos' /
                                               data['response']['proto_path'])
                self.pb_resp = dict(
                    self.pb_resp)[data['response']['proto_msg']]

            self.pb_param = data['request'].get('pb_param')
            self.base_url = data['request']['url']
            self.endpoint = data

            self.transport_meta = transports[data['request']['transport']]
            self.transport = self.transport_meta['func'](self.pb_param,
                                                         self.base_url)

            sample = ''
            if data['request'].get('samples'):
                sample = data['request']['samples'][sample_id]
            self.get_params = self.transport.load_sample(
                sample, self.pb_request)

            # Get initial data into the Protobuf tree view
            self.fuzzer.pbTree.clear()

            self.ds_items = defaultdict(dict)
            self.ds_full_names = {}

            self.parse_desc(self.pb_request.DESCRIPTOR, self.fuzzer.pbTree)
            self.parse_fields(self.pb_request)

            # Do the same for transport-specific data
            self.fuzzer.getTree.clear()
            if self.transport_meta.get('ui_tab'):
                self.fuzzer.tabs.setTabText(1, self.transport_meta['ui_tab'])
                if self.get_params:
                    for key, val in self.get_params.items():
                        ProtocolDataItem(self.fuzzer.getTree, key, val, self)
            else:
                self.fuzzer.tabs.setTabText(1, '(disabled)')
                # how to hide it ?

            # Fill the request samples combo box if we're loading a new
            # endpoint.
            if type(item) != int:
                if len(data['request'].get('samples', [])) > 1:
                    self.fuzzer.comboBox.clear()
                    for sample_id, sample in enumerate(
                            data['request']['samples']):
                        self.fuzzer.comboBox.addItem(
                            sample[self.pb_param] if self.pb_param else
                            str(sample), (data, sample_id))
                    self.fuzzer.comboBoxLabel.show()
                    self.fuzzer.comboBox.show()
                else:
                    self.fuzzer.comboBoxLabel.hide()
                    self.fuzzer.comboBox.hide()

                self.set_view(self.fuzzer)

            self.fuzzer.frame.setUrl(QUrl("about:blank"))
            self.update_fuzzer()

    """
        Parsing and rendering the Protobuf message to a tree view:

        Every Protobuf field is fed to ProtobufItem (a class inheriting
        QTreeWidgetItem), and the created object is saved in the ds_items
        entry for the corresponding descriptor.
    """

    # First, parse the descriptor (structure) of the Protobuf message.

    def parse_desc(self, msg, item, path=[]):
        for ds in msg.fields:
            new_item = ProtobufItem(item, ds, self, path)
            if ds.type == ds.TYPE_MESSAGE and ds.full_name not in path:
                self.parse_desc(ds.message_type, new_item,
                                path + [ds.full_name])

    # Then, parse the fields (contents) of the Protobuf message.

    def parse_fields(self, msg, path=[]):
        for ds, val in msg.ListFields():
            if ds.label == ds.LABEL_REPEATED:
                for val_index, val_value in enumerate(val):
                    if ds.type == ds.TYPE_MESSAGE:
                        self.ds_items[id(ds)][tuple(path)].setExpanded(True)
                        self.ds_items[id(ds)][tuple(path)].setDefault(
                            parent=msg, msg=val, index=val_index)
                        self.parse_fields(val_value, path + [ds.full_name])

                    else:
                        self.ds_items[id(ds)][tuple(path)].setDefault(
                            val_value, parent=msg, msg=val, index=val_index)

                    self.ds_items[id(ds)][tuple(path)].duplicate(True)

            else:
                if ds.type == ds.TYPE_MESSAGE:
                    self.ds_items[id(ds)][tuple(path)].setExpanded(True)
                    self.ds_items[id(ds)][tuple(path)].setDefault(parent=msg,
                                                                  msg=val)
                    self.parse_fields(val, path + [ds.full_name])

                else:
                    self.ds_items[id(ds)][tuple(path)].setDefault(val,
                                                                  parent=msg,
                                                                  msg=val)

    def update_fuzzer(self):
        resp = self.transport.perform_request(self.pb_request, self.get_params)

        data, text, url, mime = resp.content, resp.text, resp.url, resp.headers[
            'Content-Type'].split(';')[0]

        meta = '%s %d %08x\n%s' % (mime, len(data), crc32(data) & 0xffffffff,
                                   resp.url)
        self.fuzzer.urlField.setText(meta)

        self.fuzzer.frame.update_frame(data, text, url, mime,
                                       getattr(self, 'pb_resp', None))

    def fuzz_endpoint(self):
        QMessageBox.information(self.view, ' ',
                                'Automatic fuzzing is not implemented yet.')

    def delete_endpoint(self):
        if QMessageBox.question(self.view, ' ',
                                'Delete this endpoint?') == QMessageBox.Yes:
            path = str(BASE_PATH / 'endpoints' /
                       (urlparse(self.base_url).netloc + '.json'))

            with open(path) as fd:
                json = load(fd)
            json.remove(self.endpoint)

            with open(path, 'w') as fd:
                dump(json, fd, ensure_ascii=False, indent=4)
            if not json:
                remove(path)

            self.load_endpoints()

    """
        Utility methods follow
    """

    def set_view(self, view):
        if hasattr(self, 'view'):
            self.view.hide()
        view.show()
        self.view = view

        resolution = QDesktopWidget().screenGeometry()
        view.move((resolution.width() / 2) - (view.frameSize().width() / 2),
                  (resolution.height() / 2) - (view.frameSize().height() / 2))

    """
        signal() can't be called from inside a thread, and some
        extractors need it in order not to have their GUI child process
        interrupt signal catched by our main thread, so here is an ugly
        way to reach signal() through a slot.
    """

    def signal_proxy(self, *args):
        signal(*args)
Exemplo n.º 25
0
class DisplayDirectory(QMainWindow):

    def __init__(self):
        super().__init__() 
        self.initializeUI() 

    def initializeUI(self):
        """
        Initialize the window and display its contents to the screen. 
        """
        self.setMinimumSize(500, 400)
        self.setWindowTitle('12.1 – View Directory GUI')

        self.createMenu()
        self.setupTree()

        self.show()

    def createMenu(self):
        """
        Set up the menu bar.
        """
        open_dir_act = QAction('Open Directory...', self)
        open_dir_act.triggered.connect(self.chooseDirectory)

        root_act = QAction("Return to Root", self)
        root_act.triggered.connect(self.returnToRootDirectory)

        # Create menubar
        menu_bar = self.menuBar()
        #menu_bar.setNativeMenuBar(False) # uncomment for macOS

        # Create file menu and add actions 
        dir_menu = menu_bar.addMenu('Directories')
        dir_menu.addAction(open_dir_act)
        dir_menu.addAction(root_act)

    def setupTree(self):
        """
        Set up the QTreeView so that it displays the contents 
        of the local filesystem. 
        """
        self.model = QFileSystemModel()
        self.model.setRootPath('')

        self.tree = QTreeView()
        self.tree.setIndentation(10)
        self.tree.setModel(self.model)

        # Set up container and layout 
        frame = QFrame()
        frame_v_box = QVBoxLayout()
        frame_v_box.addWidget(self.tree)
        frame.setLayout(frame_v_box)

        self.setCentralWidget(frame)

    def chooseDirectory(self):
        """
        Select a directory to display.
        """
        file_dialog = QFileDialog(self)
        file_dialog.setFileMode(QFileDialog.Directory)
        directory = file_dialog.getExistingDirectory(self, "Open Directory", 
                "", QFileDialog.ShowDirsOnly)

        self.tree.setRootIndex(self.model.index(directory))

    def returnToRootDirectory(self):
        """
        Re-display the contents of the root directory. 
        """
        self.tree.setRootIndex(self.model.index(''))
Exemplo n.º 26
0
class FileBrowser(QTreeView):
    def __init__(self,
                 parent=None,
                 textPad=None,
                 notebook=None,
                 codeView=None):
        super().__init__()
        self.path = self.checkPath(os.getcwd())
        self.filename = None

        self.text = None

        self.initItems()

        self.textPad = textPad
        self.notebook = notebook
        self.codeView = codeView

        self.mainWindow = parent

        self.index = None

        self.copySourceFilePath = None  # copy / paste items
        self.copySourceFileName = None
        self.isCopyFileFolder = None

        self.setStyleSheet("""
            border: 5 px;
            background-color: black; 
            color: white;
            alternate-background-color: #FFFFFF;
            selection-background-color: #3b5784;
            """)

        # Contextmenu
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.openMenu)

        self.popMenu = QMenu()
        self.popMenu.setStyleSheet("""
            color: #FFFFFF;
            background-color: #2c2c2c;
            selection-background-color: #3b5784;
            alternate-background-color: #FFFFFF;
        """)

        infoAction = QAction('Info', self)
        infoAction.triggered.connect(self.onInfo)
        createFolderAction = QAction('Create New Folder', self)
        createFolderAction.triggered.connect(self.onCreateNewFolder)
        copyAction = QAction('Copy Item', self)
        copyAction.triggered.connect(self.onCopy)
        pasteAction = QAction('Paste Item', self)
        pasteAction.triggered.connect(self.onPaste)
        renameAction = QAction('Rename Item', self)
        renameAction.triggered.connect(self.onRename)
        deleteAction = QAction('Delete Item', self)
        deleteAction.triggered.connect(self.onDelete)
        terminalAction = QAction('Open Terminal', self)
        terminalAction.triggered.connect(self.onTerminal)

        self.popMenu.addAction(infoAction)
        self.popMenu.addSeparator()
        self.popMenu.addAction(createFolderAction)
        self.popMenu.addSeparator()
        self.popMenu.addAction(copyAction)
        self.popMenu.addAction(pasteAction)
        self.popMenu.addAction(renameAction)
        self.popMenu.addSeparator()
        self.popMenu.addAction(deleteAction)
        self.popMenu.addSeparator()
        self.popMenu.addAction(terminalAction)

    def openMenu(self, position):
        # -> open ContextMenu
        self.popMenu.exec_(self.mapToGlobal(position))

    def onInfo(self):
        if not self.index:
            return

        index = self.index
        indexItem = self.model.index(index.row(), 0, index.parent())

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        bundle = fileInfo.isBundle()  # bool
        dir = fileInfo.isDir()  # bool
        file = fileInfo.isFile()  # bool
        executable = fileInfo.isExecutable()  # bool
        readable = fileInfo.isReadable()  # bool
        writable = fileInfo.isWritable()  # bool
        created = fileInfo.created()  # QDateTime
        #modified = fileInfo.lastModified()      # QDateTime
        owner = fileInfo.owner()  # QString
        size = fileInfo.size()  # QInt
        s = format(size, ',d')

        text = ''
        text += 'Type:\t'
        if bundle:
            text += 'Bundle\n\n'
        if dir:
            text += 'Path\n\n'
        if file:
            text += 'File\n\n'

        if readable:
            text += 'read:\tyes\n'
        else:
            text += 'read:\tno\n'
        if writable:
            text += 'write:\tyes\n'
        else:
            text += 'write:\tno\n'
        if executable:
            text += 'exec:\tyes\n\n'
        else:
            text += 'exec:\tno\n\n'

        text += 'size:\t' + str(s) + ' bytes' + '\n'
        text += 'owner:\t' + owner + '\n'
        text += 'created:\t' + str(created.date().day()) + '.' + \
                str(created.date().month()) + '.' + \
                str(created.date().year()) + '  ' + \
                created.time().toString() + '\n'

        q = MessageBox(QMessageBox.Information, fileName, text,
                       QMessageBox.NoButton)
        q.exec_()

    def onCreateNewFolder(self):
        if not self.index:
            return
        else:
            index = self.index
            fileName, filePath, fileDir, fileInfo = self.getFileInformation()

            path = os.getcwd() + '/'
            path = self.checkPath(path)

        index = self.index
        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        dialog = EnterDialog(self.mainWindow, fileName, \
                             filePath, fileDir, fileInfo, False, path)
        dialog.exec_()

        # return

    def onCopy(self):
        if not self.index:
            return

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        if fileName == '..':
            self.clearSelection()
            self.mainWindow.statusBar.showMessage("can't copy this item !",
                                                  3000)
            self.copySourceFilePath = None
            self.copySourceFileName = None
            self.isCopyFileFolder = None
            return

        if fileDir:
            self.copySourceFilePath = filePath
            self.copySourceFileName = fileName
            self.isCopyFileFolder = True
            self.mainWindow.statusBar.showMessage('Path: <' + \
                                                   self.copySourceFileName + \
                                                   '> marked', 3000)
        else:
            self.copySourceFilePath = filePath
            self.copySourceFileName = fileName
            self.mainWindow.statusBar.showMessage('File: <' + \
                                                   self.copySourceFileName + \
                                                   '> marked', 3000)

    def onPaste(self):
        if not self.index:
            return

        if not self.copySourceFilePath:
            self.mainWindow.statusBar.showMessage('nothing marked !', 3000)
            return

        if not self.copySourceFileName:
            self.mainWindow.statusBar.showMessage('nothing marked !', 3000)
            return

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        rootPath = os.getcwd()
        rootPath = self.checkPath(rootPath)
        fileList = os.listdir(self.path)  # File list at current path

        if fileName == '..':
            # clicked on '..'
            rootPath = os.getcwd()
            rootPath = self.checkPath(rootPath)

        if fileDir and self.isCopyFileFolder:
            # copy path to another path
            if fileName == '..':
                path = os.getcwd()
                path = self.checkPath(path)
            else:
                path = filePath

            newPath = path + '/' + self.copySourceFileName
            fileList = os.listdir(path)

            if self.copySourceFileName in fileList:
                q = MessageBox(
                    QMessageBox.Warning, "Error",
                    "Another path with the same name already exists.",
                    QMessageBox.NoButton)
                q.exec_()

                self.resetMarkedItems(True)
                return

            if self.copySourceFilePath in newPath:

                q = MessageBox(QMessageBox.Critical, 'Error',
                               'Name of path already exists in new path',
                               QMessageBox.NoButton)

                q.exec_()
                self.resetMarkedItems(True)
                return

            try:
                os.mkdir(newPath)
                self.copytree(self.copySourceFilePath, newPath)
                self.mainWindow.statusBar.showMessage('Done !', 3000)

            except Exception as e:
                q = MessageBox(QMessageBox.Critical, "Error", str(e),
                               QMessageBox.NoButton)
                q.exec_()

                self.resetMarkedItems(True)
                return

        elif fileDir and not self.isCopyFileFolder:
            # copy file to path
            if fileName == '..':
                path = os.getcwd()
                path = self.checkPath(path)
            else:
                path = filePath

            fileList = os.listdir(path)  # File list at current path

            if self.copySourceFileName in fileList:
                result = MessageBox(QMessageBox.Warning, "Warning",
                                    "File already exists.\n" + "Continue ?",
                                    QMessageBox.Yes | QMessageBox.No)

                if (result.exec_() == QMessageBox.Yes):

                    try:
                        shutil.copy(self.copySourceFilePath, path)
                        self.mainWindow.statusBar.showMessage('Done !', 3000)

                    except Exception as e:
                        q = MessageBox(QMessageBox.Critical, "Error", str(e),
                                       QMessageBox.NoButton)
                        q.exec_()

                        self.resetMarkedItems(True)
                        return
                else:
                    self.resetMarkedItems()
                    return
            else:

                try:
                    shutil.copy(self.copySourceFilePath, path)
                    self.mainWindow.statusBar.showMessage('Done !', 3000)

                except Exception as e:
                    q = MessageBox(QMessageBox.Critical, "Error", str(e),
                                   QMessageBox.NoButton)
                    q.exec_()

                    self.resetMarkedItems(True)
                    return

        elif not fileDir and self.isCopyFileFolder:
            # copy path to selected file -> correct this user input ...
            newPath = rootPath + '/' + self.copySourceFileName

            if self.copySourceFileName in fileList:
                q = MessageBox(
                    QMessageBox.Information, "Error",
                    "Another path with the same name already exists.",
                    QMessageBox.NoButton)
                q.exec_()

                self.resetMarkedItems(True)
                return

            try:
                os.mkdir(newPath)
                self.copytree(self.copySourceFilePath, newPath)
                self.mainWindow.statusBar.showMessage('Done !', 3000)

            except Exception as e:
                q = MessageBox(QMessageBox.Critical, "Error", str(e),
                               QMessageBox.NoButton)
                q.exec_()

                self.resetMarkedItems(True)
                return

        elif not fileDir and not self.isCopyFileFolder:
            # user copy file to another file -> correct this input
            fileList = os.listdir(rootPath)  # File list in current path

            if self.copySourceFileName in fileList:
                result = MessageBox(
                    QMessageBox.Warning, "Warning",
                    "File with this name already exists !" + "Continue ?",
                    QMessageBox.Yes | QMessageBox.No)

                if (result.exec_() == QMessageBox.Yes):

                    try:
                        shutil.copy(self.copySourceFilePath, rootPath)
                        self.mainWindow.statusBar.showMessage('Done !', 3000)

                    except Exception as e:
                        q = MessageBox(QMessageBox.Critical, "Error", str(e),
                                       QMessageBox.NoButton)
                        q.exec_()

                        self.resetMarkedItems(True)
                    return

                else:
                    self.resetMarkedItems(True)
                    return

            else:

                try:
                    shutil.copy(self.copySourceFilePath, rootPath)
                    self.mainWindow.statusBar.showMessage('Done !', 3000)

                except Exception as e:
                    q = MessageBox(QMessageBox.Critical, "Error", str(e),
                                   QMessageBox.Ok)
                    q.exec_()

                    self.resetMarkedItems(True)
                    return

        self.resetMarkedItems()

    def resetMarkedItems(self, showMessage=False):
        # reset marked items
        self.copySourceFilePath = None
        self.copySourceFileName = None
        self.isCopyFileFolder = None

        if showMessage:
            self.mainWindow.statusBar.showMessage('Mark removed !', 3000)

    # copy path with subfolder
    #  thanks to stackoverflow.com ..... !
    def copytree(self, src, dst, symlinks=False, ignore=None):
        if not os.path.exists(dst):
            os.makedirs(dst)
        if not os.path.exists(src):
            os.makedirs(src)

        for item in os.listdir(src):
            s = os.path.join(src, item)
            d = os.path.join(dst, item)

            if os.path.isdir(s):
                self.copytree(s, d, symlinks, ignore)
            else:
                if not os.path.exists(
                        d) or os.stat(s).st_mtime - os.stat(d).st_mtime > 1:
                    shutil.copy2(s, d)

    def onRename(self):
        if not self.index:
            return

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        dialog = EnterDialog(self.mainWindow, fileName, filePath, fileDir,
                             fileInfo, True)
        dialog.exec_()

    def onDelete(self):
        if not self.index:
            return

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        if fileDir:
            if fileName == '..':
                self.mainWindow.statusBar.showMessage(
                    'can not delete this item !', 3000)
                return
            else:
                result = MessageBox(QMessageBox.Warning, 'Delete directory',
                                    '<b>' + filePath + '</b>' + "  ?",
                                    QMessageBox.Yes | QMessageBox.No)

                if (result.exec_() == QMessageBox.Yes):
                    try:
                        shutil.rmtree(filePath)
                        self.mainWindow.statusBar.showMessage('Done !', 3000)
                        self.resetMarkedItems()

                    except Exception as e:
                        q = MessageBox(QMessageBox.Critical, "Error", str(e),
                                       QMessageBox.NoButton)
                        q.exec_()

                        self.resetMarkedItems(True)
                else:
                    return

        else:
            pathList = filePath.split('/')[:-1]
            path = ''
            for elem in pathList:
                path += elem + '/'
            file = filePath.split('/')[-1]
            result = MessageBox(QMessageBox.Warning, 'Delete file',
                                path + "<b>" + file + "</b>" + "  ?",
                                QMessageBox.Yes | QMessageBox.No)

            if (result.exec_() == QMessageBox.Yes):
                try:
                    os.remove(filePath)
                    self.mainWindow.statusBar.showMessage('Done !', 3000)
                except Exception as e:
                    q = MessageBox(QMessageBox.Critical, "Error", str(e),
                                   QMessageBox.NoButton)

                    q.exec_()

                    self.resetMarkedItems(True)

    def onTerminal(self):
        c = Configuration()
        system = c.getSystem()
        command = c.getTerminal(system)

        thread = RunThread(command)
        thread.start()

    def initItems(self):
        font = QFont()
        font.setPixelSize(16)

        self.prepareModel(os.getcwd())

        self.setToolTip(os.getcwd())

        # prepare drag and drop
        self.setDragEnabled(False)

        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        self.setSizePolicy(sizePolicy)
        self.setAutoExpandDelay(2)
        self.setAlternatingRowColors(False)
        self.setAnimated(False)
        self.setIndentation(20)
        self.setSortingEnabled(False)
        self.setRootIsDecorated(False)
        self.setPalette(QPalette(Qt.black))

        self.verticalScrollBar().setStyleSheet("""border: 20px solid black;
            background-color: darkgreen;
            alternate-background-color: #FFFFFF;""")

        self.horizontalScrollBar().setStyleSheet("""border: 20px solid black;
            background-color: darkgreen;
            alternate-background-color: #FFFFFF;""")

        self.setFont(font)

        # signals
        self.doubleClicked.connect(self.onDoubleClicked)
        self.clicked.connect(self.onClicked)
        self.pressed.connect(self.onClicked)
        #self.entered.connect(self.onEntered)
        self.columnMoved()

        # that hides the size, file type and last modified colomns
        self.setHeaderHidden(True)
        self.hideColumn(1)
        self.hideColumn(2)
        self.hideColumn(3)
        self.resize(400, 400)

    def prepareModel(self, path):
        self.model = QFileSystemModel()
        self.model.setRootPath(path)
        #model.setFilter(QDir.AllDirs |QDir.NoDotAndDotDot | QDir.AllEntries)
        self.model.setFilter(QDir.Files | QDir.AllDirs | QDir.NoDot
                             | QDir.Hidden)
        #self.model.setNameFilters(self.filter)

        self.model.rootPathChanged.connect(self.onRootPathChanged)

        self.fsindex = self.model.setRootPath(path)

        self.setModel(self.model)
        self.setRootIndex(self.fsindex)

    def checkPath(self, path):
        if '\\' in path:
            path = path.replace('\\', '/')
        return path

    def getFileInformation(self):
        index = self.index
        indexItem = self.model.index(index.row(), 0, index.parent())

        fileName = self.model.fileName(indexItem)
        filePath = self.model.filePath(indexItem)
        fileDir = self.model.isDir(indexItem)
        fileInfo = self.model.fileInfo(indexItem)

        fileName = self.checkPath(fileName)
        filePath = self.checkPath(filePath)

        return (fileName, filePath, fileDir, fileInfo)

    def onClicked(self, index):
        self.index = index  #.... index des FileSystemModels
        indexItem = self.model.index(index.row(), 0, index.parent())

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()
        self.setToolTip(filePath)

        if fileDir:
            self.path = self.checkPath(os.getcwd())
            self.filename = None
        else:
            self.filename = filePath
            self.path = self.checkPath(os.getcwd())

        #print('self.filename: ', self.filename)
        #print('self.path: ', self.path)

    def refresh(self, dir=None):
        if not dir:
            dir = self.checkPath(os.getcwd())
        else:
            dir = dir

        self.model.setRootPath(dir)

        if self.rootIsDecorated:
            self.setRootIsDecorated(False)

        self.clearSelection()

    def onDoubleClicked(self, index):
        self.index = index  #.... wie oben ... def onClicked(...):
        indexItem = self.model.index(index.row(), 0, index.parent())

        fileName, filePath, fileDir, fileInfo = self.getFileInformation()

        if fileDir:
            filePath = self.checkPath(filePath)
            try:
                os.chdir(filePath)
            except Exception as e:
                self.mainWindow.statusBar.showMessage(str(e), 3000)
            self.path = self.checkPath(os.getcwd())

            self.model.setRootPath(filePath)

            if self.rootIsDecorated:
                self.setRootIsDecorated(False)

        else:
            self.filename = filePath

            try:
                with open(self.filename, 'r') as f:
                    self.text = f.read()
            except Exception as e:
                self.mainWindow.statusBar.showMessage(str(e), 3000)

                self.filename = None
                return

            # debug
            if self.textPad:

                if not self.textPad.filename:
                    editor = CodeEditor(self.mainWindow)
                    editor.setText(self.text)
                    editor.filename = filePath
                    self.notebook.newTab(editor)
                    self.textPad = editor

                    x = self.notebook.count()  # number of tabs
                    index = x - 1
                    self.notebook.setCurrentIndex(index)
                    tabName = os.path.basename(editor.filename)

                    self.notebook.setTabText(x, tabName)
                    self.textPad = editor
                    #self.textPad.filename = filePath

                else:
                    editor = CodeEditor(self.mainWindow)
                    editor.setText(self.text)
                    editor.filename = filePath
                    tabName = os.path.basename(editor.filename)
                    self.notebook.newTab(editor)
                    x = self.notebook.count()  # number of tabs
                    index = x - 1
                    self.notebook.setCurrentIndex(index)
                    self.textPad = editor
                    #self.textPad.filename = filePath

            if not self.textPad:
                editor = CodeEditor(self.mainWindow)
                editor.filename = None
                self.notebook.newTab(editor)
                x = self.notebook.count()
                index = x - 1
                self.notebook.setCurrentIndex(index)
                self.textPad = editor
                #self.textPad.filename = filePath

            # make codeView
            codeViewList = self.codeView.makeDictForCodeView(self.text)
            self.codeView.updateCodeView(codeViewList)

            # update textPad Autocomplete
            autocomplete = Qsci.QsciAPIs(self.textPad.lexer)
            self.textPad.autocomplete = autocomplete
            self.textPad.setPythonAutocomplete()

        self.clearSelection()

    def onRootPathChanged(self):
        self.setModel(None)
        self.setModel(self.model)
        self.fsindex = self.model.setRootPath(QDir.currentPath())
        self.setRootIndex(self.fsindex)
        sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding,
                                 QSizePolicy.MinimumExpanding)
        self.setSizePolicy(sizePolicy)
        self.setAutoExpandDelay(2)
        self.setAlternatingRowColors(False)
        self.setAnimated(True)
        self.setIndentation(20)
        self.setSortingEnabled(False)
        self.setRootIsDecorated(False)

        self.setHeaderHidden(True)
        self.hideColumn(1)
        self.hideColumn(2)
        self.hideColumn(3)
        self.setToolTip(QDir.currentPath())
        self.path = os.getcwd()
        self.path = self.checkPath(self.path)
Exemplo n.º 27
0
 def data(self, index, role):
     if role == Qt.ToolTipRole:
         return self.filePath(index)
     else:
         return QFileSystemModel.data(self, index, role)
Exemplo n.º 28
0
 def __init__(self, *args):
     QFileSystemModel.__init__(self, *args)
class MainWindow(UiBase):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui()
        self.ui.setupUi(self)
        # button actions
        self.ui.actionexit.triggered.connect(self.exit)
        self.ui.actionAbout.triggered.connect(self.about)
        self.ui.actionOpen_Folder.triggered.connect(self.folderOpen)
        # lineEdit input from users. movies, tvmovies, tvshows
        self.ui.movie_lineEdit.textChanged.connect(self.text_Changed)
        self.ui.TVshow_movie_lineEdit.textChanged.connect(self.text_Changed)
        self.ui.TVshow_lineEdit.textChanged.connect(self.text_Changed)
        self.model = QFileSystemModel()
        # set defualt directories
        self.path = (expanduser("~") + '\\Videos')  # windows path
        self.index = self.model.setRootPath(self.path)  # path QT indexed
        print(self.index)
        print(self.index.data())  # gets Videos... nothing else...
        print(self.index.data(
            1))  # I guess I am looking for the rest of the info.
        # if i add an int other then 0 it gives me the object again.
        # the document say nothing to me about what to do about this???
        # self.new_path = (expanduser("~")+'\\Videos')
        # self.future_index = self.model.setRootPath(self.new_path)
        # <widget class="QTreeView" name="treeView">
        self.ui.treeView.setModel(self.model)
        self.ui.treeView.setAnimated(False)
        self.ui.treeView.setIndentation(20)
        self.ui.treeView.setSortingEnabled(True)
        self.ui.treeView.setRootIndex(self.index)
        self.ui.treeView.setColumnHidden(1, True)
        self.ui.treeView.setColumnHidden(2, True)
        self.ui.treeView.setColumnHidden(3, True)
        # <widget class="QTreeView" name="treeView_future">
        self.ui.treeView_future.setModel(self.model)
        self.ui.treeView_future.setAnimated(False)
        self.ui.treeView_future.setIndentation(20)
        self.ui.treeView_future.setSortingEnabled(True)
        #  self.ui.treeView_future.setRootIndex(self.index)
        self.ui.treeView_future.setColumnHidden(1, True)
        self.ui.treeView_future.setColumnHidden(2, True)
        self.ui.treeView_future.setColumnHidden(3, True)

        #  print('this is the path:', M_F_F(self.path)) #  results of
        #  print(str(M_F(self.path)))

    class fake_media():
        now = datetime.now()
        fake_year = (now.strftime("%Y"))
        FakefolderFile = "C:\\mymovies\\B\\The Best Movie Ever.2018.PG\\The Best Movie Ever.2018.PG.mp4"
        # FakefolderFile = "C:\\The Best Movie Ever.2018.PG\\The Best Movie Ever.2018.PG.mp4"
        Title = "The Best Movie Ever"  # Our fake Title
        Year = (fake_year)  # always the curent year
        CR = "Pg"  # CR = Certified Rating

        def F_O(self):  # F_O = Fake Orginize
            parts = self.FakefolderFile.split("\\")
            A = str(self.Title)
            B = self.Title + str(self.Year)
            # B = re.match(self.Title, str(self.Year))
            C = self.Title + str(self.Year) + self.CR
            # C = re.match(self.Title, str(self.Year), self.CR)
            D = "Must have Title and Year name"
            # print(parts)
            # print(parts[3])
            # print(parts[3].split("."))
            # print(A+B+C+D)
            # print(A, B, C, D)

    fake_media().F_O()

    # rules for media title
    class media_title():
        pass

    # rules for media year
    class media_year():
        pass

    # rules for media certified rating
    class media_certified_rating():
        pass

    # user text input from movies, tv movies, tvshows
    def text_Changed(self):
        # user_text = [self.sender().objectName(), repr(self.sender().text())]
        # print(user_text) #wanting to know witch lineEdit text is changing?

        # if text input is from lineEdit change label text
        def label_output(self):
            Txt = self.sender().text()
            Objn = self.sender().objectName()
            if Objn == ('movie_lineEdit'):
                if Txt == (''):
                    self.ui.movie_recipe_results.setText(
                        'Must start with Title')
                elif Txt == ('T'):
                    self.ui.movie_recipe_results.setText('The Best Movie Ever')
                elif Txt == ('T Y'):
                    self.ui.movie_recipe_results.setText(
                        'The Best Movie Ever 2018')
                elif Txt == ('T Y CR'):
                    self.ui.movie_recipe_results.setText(
                        'The Best Movie Ever 2018 PG')
            elif Objn == ('TVshow_movie_lineEdit'):
                if Txt == (''):
                    self.ui.Tvshow_movie_recipe_results.setText(
                        'Must start with Title')
                elif Txt == ('T'):
                    self.ui.Tvshow_movie_recipe_results.setText(
                        'The Best Movie Ever')
                elif Txt == ('T Y'):
                    self.ui.Tvshow_movie_recipe_results.setText(
                        'The Best Movie Ever 2018')
                elif Txt == ('T Y CR'):
                    self.ui.Tvshow_movie_recipe_results.setText(
                        'The Best Movie Ever 2018 TV-PG')
            elif Objn == ('TVshow_lineEdit'):
                if Txt == (''):
                    self.ui.Tvshow_recipe_results.setText(
                        'Must start with Title')
                elif Txt == ('T'):
                    self.ui.Tvshow_recipe_results.setText(
                        'The Best TVShow Ever')
                elif Txt == ('T Y'):
                    self.ui.Tvshow_recipe_results.setText(
                        'The Best TVShow Ever 2018')
                elif Txt == ('T Y CR'):
                    self.ui.Tvshow_recipe_results.setText\
                    ('The Best TVShow Ever 2018 TV-PG')
                elif Txt == ('T Y CR S-E'):
                    self.ui.Tvshow_recipe_results.setText\
                    ('The Best TVShow Ever 2018 TV-PG S01E01')
                elif Txt == ('T Y CR S-E ET'):
                    self.ui.Tvshow_recipe_results.setText\
                    ('The Best TVShow Ever 2018 TV-PG S01E01 Best Episode')

        label_output(self)

    # for gwtting directories of media files
    def folderOpen(self):
        input_dir = QFileDialog.getExistingDirectory(None, 'Select a folder:',
                                                     self.path)
        if input_dir == '':
            return self.path
        else:
            pass
        index = self.model.setRootPath(input_dir)
        self.ui.treeView.setRootIndex(index)

    # to show user what folders and files will look like after they submit
    def futureTreeview(self):
        self.ui.treeView.setRootIndex(self._future_index)

    # the about popup window
    def about(self):
        QMessageBox.about(self, "About", "This is a Template")

    # um, the exit for this application or software
    def exit(self):
        print('exit main window')
        QtWidgets.QApplication.instance().exit()

    def timon(self):
        # print('timer on')
        t = Timer(6.0, self.exit)
        t.start()
Exemplo n.º 30
0
 def setup_events(self):
     model = QFileSystemModel()
     root = model.setRootPath(self.root_path)
     self.filesTreeView.setModel(model)
     self.filesTreeView.setRootIndex(root)
     self.filesTreeView.selectionModel().selectionChanged.connect(self.item_selection_changed_slot)
Exemplo n.º 31
0
def double_click_event(index):
    global model, label

    if model.isDir(index):
        print('Directory') # Directory 출력
    else:
        path = model.filePath(index)
        label.setPixmap(QPixmap(path))

if __name__ == '__main__':
    app = QApplication(sys.argv)

    tree_view = QTreeView()
    tree_view.show()

    model = QFileSystemModel() # 파일 창 띄우기
    tree_view.setModel(model)

    root_path = "../" # 파일 경로
    model.setRootPath(root_path)
    tree_view.setRootIndex(model.index(root_path))
    tree_view.setColumnWidth(0, 400)
    tree_view.resize(700, 500)

    tree_view.setColumnHidden(1, True) # 두번째 컬럼 숨기기
    tree_view.setColumnHidden(2, True) # 세번째 컬럼 숨기기
    tree_view.setColumnHidden(3, True) # 네번째 컬럼 숨기기

    tree_view.doubleClicked.connect(double_click_event) # 트리 창 더블클릭하면 함수 double_click_event수행

    label = QLabel("label") # label 창 띄우기
Exemplo n.º 32
0
class ReTextWindow(QMainWindow):
	def __init__(self, parent=None):
		QMainWindow.__init__(self, parent)
		self.resize(950, 700)
		screenRect = QDesktopWidget().screenGeometry()
		if globalSettings.windowGeometry:
			self.restoreGeometry(globalSettings.windowGeometry)
		else:
			self.move((screenRect.width() - self.width()) // 2,
			          (screenRect.height() - self.height()) // 2)
			if not screenRect.contains(self.geometry()):
				self.showMaximized()
		if sys.platform.startswith('darwin'):
			# https://github.com/retext-project/retext/issues/198
			searchPaths = QIcon.themeSearchPaths()
			searchPaths.append('/opt/local/share/icons')
			searchPaths.append('/usr/local/share/icons')
			QIcon.setThemeSearchPaths(searchPaths)
		setIconThemeFromSettings()
		if QFile.exists(getBundledIcon('retext')):
			self.setWindowIcon(QIcon(getBundledIcon('retext')))
		elif QFile.exists('/usr/share/pixmaps/retext.png'):
			self.setWindowIcon(QIcon('/usr/share/pixmaps/retext.png'))
		else:
			self.setWindowIcon(QIcon.fromTheme('retext',
				QIcon.fromTheme('accessories-text-editor')))
		self.splitter = QSplitter(self)
		self.treeView = QTreeView(self.splitter)
		self.treeView.doubleClicked.connect(self.treeItemSelected)
		self.tabWidget = QTabWidget(self.splitter)
		self.initTabWidget()
		self.splitter.setSizes([self.width() / 5, self.width() * 4 / 5])
		self.initDirectoryTree(globalSettings.showDirectoryTree, globalSettings.directoryPath)
		self.setCentralWidget(self.splitter)
		self.tabWidget.currentChanged.connect(self.changeIndex)
		self.tabWidget.tabCloseRequested.connect(self.closeTab)
		self.toolBar = QToolBar(self.tr('File toolbar'), self)
		self.addToolBar(Qt.TopToolBarArea, self.toolBar)
		self.editBar = QToolBar(self.tr('Edit toolbar'), self)
		self.addToolBar(Qt.TopToolBarArea, self.editBar)
		self.searchBar = QToolBar(self.tr('Search toolbar'), self)
		self.addToolBar(Qt.BottomToolBarArea, self.searchBar)
		self.toolBar.setVisible(not globalSettings.hideToolBar)
		self.editBar.setVisible(not globalSettings.hideToolBar)
		self.actionNew = self.act(self.tr('New'), 'document-new',
			self.createNew, shct=QKeySequence.New)
		self.actionNew.setPriority(QAction.LowPriority)
		self.actionOpen = self.act(self.tr('Open'), 'document-open',
			self.openFile, shct=QKeySequence.Open)
		self.actionOpen.setPriority(QAction.LowPriority)
		self.actionSetEncoding = self.act(self.tr('Set encoding'),
			trig=self.showEncodingDialog)
		self.actionSetEncoding.setEnabled(False)
		self.actionReload = self.act(self.tr('Reload'), 'view-refresh',
			lambda: self.currentTab.readTextFromFile())
		self.actionReload.setEnabled(False)
		self.actionSave = self.act(self.tr('Save'), 'document-save',
			self.saveFile, shct=QKeySequence.Save)
		self.actionSave.setEnabled(False)
		self.actionSave.setPriority(QAction.LowPriority)
		self.actionSaveAs = self.act(self.tr('Save as'), 'document-save-as',
			self.saveFileAs, shct=QKeySequence.SaveAs)
		self.actionNextTab = self.act(self.tr('Next tab'), 'go-next',
			lambda: self.switchTab(1), shct=Qt.CTRL+Qt.Key_PageDown)
		self.actionPrevTab = self.act(self.tr('Previous tab'), 'go-previous',
			lambda: self.switchTab(-1), shct=Qt.CTRL+Qt.Key_PageUp)
		self.actionCloseCurrentTab = self.act(self.tr('Close tab'), 'window-close',
			lambda: self.closeTab(self.ind), shct=QKeySequence.Close)
		self.actionPrint = self.act(self.tr('Print'), 'document-print',
			self.printFile, shct=QKeySequence.Print)
		self.actionPrint.setPriority(QAction.LowPriority)
		self.actionPrintPreview = self.act(self.tr('Print preview'), 'document-print-preview',
			self.printPreview)
		self.actionViewHtml = self.act(self.tr('View HTML code'), 'text-html', self.viewHtml)
		self.actionChangeEditorFont = self.act(self.tr('Change editor font'),
			trig=self.changeEditorFont)
		self.actionChangePreviewFont = self.act(self.tr('Change preview font'),
			trig=self.changePreviewFont)
		self.actionSearch = self.act(self.tr('Find text'), 'edit-find',
			self.search, shct=QKeySequence.Find)
		self.actionGoToLine = self.act(self.tr('Go to line'),
			trig=self.goToLine, shct=Qt.CTRL+Qt.Key_G)
		self.searchBar.visibilityChanged.connect(self.searchBarVisibilityChanged)
		self.actionPreview = self.act(self.tr('Preview'), shct=Qt.CTRL+Qt.Key_E,
			trigbool=self.preview)
		if QIcon.hasThemeIcon('document-preview'):
			self.actionPreview.setIcon(QIcon.fromTheme('document-preview'))
		elif QIcon.hasThemeIcon('preview-file'):
			self.actionPreview.setIcon(QIcon.fromTheme('preview-file'))
		elif QIcon.hasThemeIcon('x-office-document'):
			self.actionPreview.setIcon(QIcon.fromTheme('x-office-document'))
		else:
			self.actionPreview.setIcon(QIcon(getBundledIcon('document-preview')))
		self.actionLivePreview = self.act(self.tr('Live preview'), shct=Qt.CTRL+Qt.Key_L,
		trigbool=self.enableLivePreview)
		menuPreview = QMenu()
		menuPreview.addAction(self.actionLivePreview)
		self.actionPreview.setMenu(menuPreview)
		self.actionInsertTable = self.act(self.tr('Insert table'),
			trig=lambda: self.insertFormatting('table'))
		self.actionTableMode = self.act(self.tr('Table editing mode'),
			shct=Qt.CTRL+Qt.Key_T,
			trigbool=lambda x: self.currentTab.editBox.enableTableMode(x))
		self.actionInsertImages = self.act(self.tr('Insert images by file path'),
			trig=lambda: self.insertImages())
		if ReTextFakeVimHandler:
			self.actionFakeVimMode = self.act(self.tr('FakeVim mode'),
				shct=Qt.CTRL+Qt.ALT+Qt.Key_V, trigbool=self.enableFakeVimMode)
			if globalSettings.useFakeVim:
				self.actionFakeVimMode.setChecked(True)
				self.enableFakeVimMode(True)
		self.actionFullScreen = self.act(self.tr('Fullscreen mode'), 'view-fullscreen',
			shct=Qt.Key_F11, trigbool=self.enableFullScreen)
		self.actionFullScreen.setChecked(self.isFullScreen())
		self.actionFullScreen.setPriority(QAction.LowPriority)
		self.actionConfig = self.act(self.tr('Preferences'), icon='preferences-system',
			trig=self.openConfigDialog)
		self.actionConfig.setMenuRole(QAction.PreferencesRole)
		self.actionSaveHtml = self.act('HTML', 'text-html', self.saveFileHtml)
		self.actionPdf = self.act('PDF', 'application-pdf', self.savePdf)
		self.actionOdf = self.act('ODT', 'x-office-document', self.saveOdf)
		self.getExportExtensionsList()
		self.actionQuit = self.act(self.tr('Quit'), 'application-exit', shct=QKeySequence.Quit)
		self.actionQuit.setMenuRole(QAction.QuitRole)
		self.actionQuit.triggered.connect(self.close)
		self.actionUndo = self.act(self.tr('Undo'), 'edit-undo',
			lambda: self.currentTab.editBox.undo(), shct=QKeySequence.Undo)
		self.actionRedo = self.act(self.tr('Redo'), 'edit-redo',
			lambda: self.currentTab.editBox.redo(), shct=QKeySequence.Redo)
		self.actionCopy = self.act(self.tr('Copy'), 'edit-copy',
			lambda: self.currentTab.editBox.copy(), shct=QKeySequence.Copy)
		self.actionCut = self.act(self.tr('Cut'), 'edit-cut',
			lambda: self.currentTab.editBox.cut(), shct=QKeySequence.Cut)
		self.actionPaste = self.act(self.tr('Paste'), 'edit-paste',
			lambda: self.currentTab.editBox.paste(), shct=QKeySequence.Paste)
		self.actionPasteImage = self.act(self.tr('Paste image'), 'edit-paste',
			lambda: self.currentTab.editBox.pasteImage(), shct=Qt.CTRL+Qt.SHIFT+Qt.Key_V)
		self.actionMoveUp = self.act(self.tr('Move line up'), 'go-up',
			lambda: self.currentTab.editBox.moveLineUp(), shct=Qt.ALT+Qt.Key_Up)
		self.actionMoveDown = self.act(self.tr('Move line down'), 'go-down',
			lambda: self.currentTab.editBox.moveLineDown(), shct=Qt.ALT+Qt.Key_Down)
		self.actionUndo.setEnabled(False)
		self.actionRedo.setEnabled(False)
		self.actionCopy.setEnabled(False)
		self.actionCut.setEnabled(False)
		qApp = QApplication.instance()
		qApp.clipboard().dataChanged.connect(self.clipboardDataChanged)
		self.clipboardDataChanged()
		if enchant is not None:
			self.actionEnableSC = self.act(self.tr('Enable'), trigbool=self.enableSpellCheck)
			self.actionSetLocale = self.act(self.tr('Set locale'), trig=self.changeLocale)
		self.actionWebKit = self.act(self.tr('Use WebKit renderer'), trigbool=self.enableWebKit)
		if ReTextWebKitPreview is None:
			globalSettings.useWebKit = False
			self.actionWebKit.setEnabled(False)
		self.actionWebKit.setChecked(globalSettings.useWebKit)
		self.actionWebEngine = self.act(self.tr('Use WebEngine (Chromium) renderer'),
			trigbool=self.enableWebEngine)
		if ReTextWebEnginePreview is None:
			globalSettings.useWebEngine = False
		self.actionWebEngine.setChecked(globalSettings.useWebEngine)
		self.actionShow = self.act(self.tr('Show directory'), 'system-file-manager', self.showInDir)
		self.actionFind = self.act(self.tr('Next'), 'go-next', self.find,
			shct=QKeySequence.FindNext)
		self.actionFindPrev = self.act(self.tr('Previous'), 'go-previous',
			lambda: self.find(back=True), shct=QKeySequence.FindPrevious)
		self.actionReplace = self.act(self.tr('Replace'), 'edit-find-replace',
			lambda: self.find(replace=True))
		self.actionReplaceAll = self.act(self.tr('Replace all'), trig=self.replaceAll)
		menuReplace = QMenu()
		menuReplace.addAction(self.actionReplaceAll)
		self.actionReplace.setMenu(menuReplace)
		self.actionCloseSearch = self.act(self.tr('Close'), 'window-close',
			lambda: self.searchBar.setVisible(False),
			shct=QKeySequence.Cancel)
		self.actionCloseSearch.setPriority(QAction.LowPriority)
		self.actionHelp = self.act(self.tr('Get help online'), 'help-contents', self.openHelp)
		self.aboutWindowTitle = self.tr('About ReText')
		self.actionAbout = self.act(self.aboutWindowTitle, 'help-about', self.aboutDialog)
		self.actionAbout.setMenuRole(QAction.AboutRole)
		self.actionAboutQt = self.act(self.tr('About Qt'))
		self.actionAboutQt.setMenuRole(QAction.AboutQtRole)
		self.actionAboutQt.triggered.connect(qApp.aboutQt)
		availableMarkups = markups.get_available_markups()
		if not availableMarkups:
			print('Warning: no markups are available!')
		if len(availableMarkups) > 1:
			self.chooseGroup = QActionGroup(self)
			markupActions = []
			for markup in availableMarkups:
				markupAction = self.act(markup.name, trigbool=self.markupFunction(markup))
				if markup.name == globalSettings.defaultMarkup:
					markupAction.setChecked(True)
				self.chooseGroup.addAction(markupAction)
				markupActions.append(markupAction)
		self.actionBold = self.act(self.tr('Bold'), shct=QKeySequence.Bold,
			trig=lambda: self.insertFormatting('bold'))
		self.actionItalic = self.act(self.tr('Italic'), shct=QKeySequence.Italic,
			trig=lambda: self.insertFormatting('italic'))
		self.actionUnderline = self.act(self.tr('Underline'), shct=QKeySequence.Underline,
			trig=lambda: self.insertFormatting('underline'))
		self.usefulTags = ('header', 'italic', 'bold', 'underline', 'numbering',
			'bullets', 'image', 'link', 'inline code', 'code block', 'blockquote',
			'table')
		self.usefulChars = ('deg', 'divide', 'euro', 'hellip', 'laquo', 'larr',
			'lsquo', 'mdash', 'middot', 'minus', 'nbsp', 'ndash', 'raquo',
			'rarr', 'rsquo', 'times')
		self.formattingBox = QComboBox(self.editBar)
		self.formattingBox.addItem(self.tr('Formatting'))
		self.formattingBox.addItems(self.usefulTags)
		self.formattingBox.activated[str].connect(self.insertFormatting)
		self.symbolBox = QComboBox(self.editBar)
		self.symbolBox.addItem(self.tr('Symbols'))
		self.symbolBox.addItems(self.usefulChars)
		self.symbolBox.activated.connect(self.insertSymbol)
		self.updateStyleSheet()
		menubar = self.menuBar()
		menuFile = menubar.addMenu(self.tr('&File'))
		menuEdit = menubar.addMenu(self.tr('&Edit'))
		menuHelp = menubar.addMenu(self.tr('&Help'))
		menuFile.addAction(self.actionNew)
		menuFile.addAction(self.actionOpen)
		self.menuRecentFiles = menuFile.addMenu(self.tr('Open recent'))
		self.menuRecentFiles.aboutToShow.connect(self.updateRecentFiles)
		menuFile.addAction(self.actionShow)
		menuFile.addAction(self.actionSetEncoding)
		menuFile.addAction(self.actionReload)
		menuFile.addSeparator()
		menuFile.addAction(self.actionSave)
		menuFile.addAction(self.actionSaveAs)
		menuFile.addSeparator()
		menuFile.addAction(self.actionNextTab)
		menuFile.addAction(self.actionPrevTab)
		menuFile.addAction(self.actionCloseCurrentTab)
		menuFile.addSeparator()
		menuExport = menuFile.addMenu(self.tr('Export'))
		menuExport.addAction(self.actionSaveHtml)
		menuExport.addAction(self.actionOdf)
		menuExport.addAction(self.actionPdf)
		if self.extensionActions:
			menuExport.addSeparator()
			for action, mimetype in self.extensionActions:
				menuExport.addAction(action)
			menuExport.aboutToShow.connect(self.updateExtensionsVisibility)
		menuFile.addAction(self.actionPrint)
		menuFile.addAction(self.actionPrintPreview)
		menuFile.addSeparator()
		menuFile.addAction(self.actionQuit)
		menuEdit.addAction(self.actionUndo)
		menuEdit.addAction(self.actionRedo)
		menuEdit.addSeparator()
		menuEdit.addAction(self.actionCut)
		menuEdit.addAction(self.actionCopy)
		menuEdit.addAction(self.actionPaste)
		menuEdit.addAction(self.actionPasteImage)
		menuEdit.addSeparator()
		menuEdit.addAction(self.actionMoveUp)
		menuEdit.addAction(self.actionMoveDown)
		menuEdit.addSeparator()
		if enchant is not None:
			menuSC = menuEdit.addMenu(self.tr('Spell check'))
			menuSC.addAction(self.actionEnableSC)
			menuSC.addAction(self.actionSetLocale)
		menuEdit.addAction(self.actionSearch)
		menuEdit.addAction(self.actionGoToLine)
		menuEdit.addAction(self.actionChangeEditorFont)
		menuEdit.addAction(self.actionChangePreviewFont)
		menuEdit.addSeparator()
		if len(availableMarkups) > 1:
			self.menuMode = menuEdit.addMenu(self.tr('Default markup'))
			for markupAction in markupActions:
				self.menuMode.addAction(markupAction)
		menuFormat = menuEdit.addMenu(self.tr('Formatting'))
		menuFormat.addAction(self.actionBold)
		menuFormat.addAction(self.actionItalic)
		menuFormat.addAction(self.actionUnderline)
		if ReTextWebKitPreview is not None or ReTextWebEnginePreview is None:
			menuEdit.addAction(self.actionWebKit)
		else:
			menuEdit.addAction(self.actionWebEngine)
		menuEdit.addSeparator()
		menuEdit.addAction(self.actionViewHtml)
		menuEdit.addAction(self.actionPreview)
		menuEdit.addAction(self.actionInsertTable)
		menuEdit.addAction(self.actionTableMode)
		menuEdit.addAction(self.actionInsertImages)
		if ReTextFakeVimHandler:
			menuEdit.addAction(self.actionFakeVimMode)
		menuEdit.addSeparator()
		menuEdit.addAction(self.actionFullScreen)
		menuEdit.addAction(self.actionConfig)
		menuHelp.addAction(self.actionHelp)
		menuHelp.addSeparator()
		menuHelp.addAction(self.actionAbout)
		menuHelp.addAction(self.actionAboutQt)
		self.toolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
		self.toolBar.addAction(self.actionNew)
		self.toolBar.addSeparator()
		self.toolBar.addAction(self.actionOpen)
		self.toolBar.addAction(self.actionSave)
		self.toolBar.addAction(self.actionPrint)
		self.toolBar.addSeparator()
		self.toolBar.addAction(self.actionPreview)
		self.toolBar.addAction(self.actionFullScreen)
		self.editBar.addAction(self.actionUndo)
		self.editBar.addAction(self.actionRedo)
		self.editBar.addSeparator()
		self.editBar.addAction(self.actionCut)
		self.editBar.addAction(self.actionCopy)
		self.editBar.addAction(self.actionPaste)
		self.editBar.addSeparator()
		self.editBar.addWidget(self.formattingBox)
		self.editBar.addWidget(self.symbolBox)
		self.searchEdit = QLineEdit(self.searchBar)
		self.searchEdit.setPlaceholderText(self.tr('Search'))
		self.searchEdit.returnPressed.connect(self.find)
		self.replaceEdit = QLineEdit(self.searchBar)
		self.replaceEdit.setPlaceholderText(self.tr('Replace with'))
		self.replaceEdit.returnPressed.connect(self.find)
		self.csBox = QCheckBox(self.tr('Case sensitively'), self.searchBar)
		self.searchBar.addWidget(self.searchEdit)
		self.searchBar.addWidget(self.replaceEdit)
		self.searchBar.addSeparator()
		self.searchBar.addWidget(self.csBox)
		self.searchBar.addAction(self.actionFindPrev)
		self.searchBar.addAction(self.actionFind)
		self.searchBar.addAction(self.actionReplace)
		self.searchBar.addAction(self.actionCloseSearch)
		self.searchBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
		self.searchBar.setVisible(False)
		self.autoSaveEnabled = globalSettings.autoSave
		if self.autoSaveEnabled:
			timer = QTimer(self)
			timer.start(60000)
			timer.timeout.connect(self.saveAll)
		self.ind = None
		if enchant is not None:
			self.sl = globalSettings.spellCheckLocale
			try:
				enchant.Dict(self.sl or None)
			except enchant.errors.Error as e:
				warnings.warn(str(e), RuntimeWarning)
				globalSettings.spellCheck = False
			if globalSettings.spellCheck:
				self.actionEnableSC.setChecked(True)
		self.fileSystemWatcher = QFileSystemWatcher()
		self.fileSystemWatcher.fileChanged.connect(self.fileChanged)

	def restoreLastOpenedFiles(self):
		for file in readListFromSettings("lastFileList"):
			self.openFileWrapper(file)

		# Show the tab of last opened file
		lastTabIndex = globalSettings.lastTabIndex
		if lastTabIndex >= 0 and lastTabIndex < self.tabWidget.count():
			self.tabWidget.setCurrentIndex(lastTabIndex)

	def iterateTabs(self):
		for i in range(self.tabWidget.count()):
			yield self.tabWidget.widget(i)

	def updateStyleSheet(self):
		self.ss = None
		if globalSettings.styleSheet:
			sheetfile = QFile(globalSettings.styleSheet)
			sheetfile.open(QIODevice.ReadOnly)
			self.ss = QTextStream(sheetfile).readAll()
			sheetfile.close()

	def initTabWidget(self):
		def dragEnterEvent(e):
			e.acceptProposedAction()
		def dropEvent(e):
			fn = bytes(e.mimeData().data('text/plain')).decode().rstrip()
			if fn.startswith('file:'):
				fn = QUrl(fn).toLocalFile()
			self.openFileWrapper(fn)
		self.tabWidget.setTabsClosable(True)
		self.tabWidget.setAcceptDrops(True)
		self.tabWidget.setMovable(True)
		self.tabWidget.dragEnterEvent = dragEnterEvent
		self.tabWidget.dropEvent = dropEvent
		self.tabWidget.setTabBarAutoHide(globalSettings.tabBarAutoHide)

	def initDirectoryTree(self, visible, path):
		if visible:
			self.fileSystemModel = QFileSystemModel(self.treeView)
			self.fileSystemModel.setRootPath(path)
			supportedExtensions = ['.txt']
			for markup in markups.get_all_markups():
				supportedExtensions += markup.file_extensions
			filters = ["*" + s for s in supportedExtensions]
			self.fileSystemModel.setNameFilters(filters)
			self.fileSystemModel.setNameFilterDisables(False)
			self.treeView.setModel(self.fileSystemModel)
			self.treeView.setRootIndex(self.fileSystemModel.index(path))
			self.treeView.setColumnHidden(1, True)
			self.treeView.setColumnHidden(2, True)
			self.treeView.setColumnHidden(3, True)
			self.treeView.setHeaderHidden(True)
		self.treeView.setVisible(visible)

	def treeItemSelected(self, signal):
		file_path = self.fileSystemModel.filePath(signal)
		if os.path.isdir(file_path):
			return
		self.openFileWrapper(file_path)

	def act(self, name, icon=None, trig=None, trigbool=None, shct=None):
		if not isinstance(shct, QKeySequence):
			shct = QKeySequence(shct)
		if icon:
			action = QAction(self.actIcon(icon), name, self)
		else:
			action = QAction(name, self)
		if trig:
			action.triggered.connect(trig)
		elif trigbool:
			action.setCheckable(True)
			action.triggered[bool].connect(trigbool)
		if shct:
			action.setShortcut(shct)
		return action

	def actIcon(self, name):
		return QIcon.fromTheme(name, QIcon(getBundledIcon(name)))

	def printError(self):
		import traceback
		print('Exception occurred while parsing document:', file=sys.stderr)
		traceback.print_exc()

	def updateTabTitle(self, ind, tab):
		changed = tab.editBox.document().isModified()
		if changed and not self.autoSaveActive(tab):
			title = tab.getBaseName() + '*'
		else:
			title = tab.getBaseName()
		self.tabWidget.setTabText(ind, title)

	def tabFileNameChanged(self, tab):
		'''
		Perform all UI state changes that need to be done when the
		filename of the current tab has changed.
		'''
		if tab == self.currentTab:
			if tab.fileName:
				self.setWindowTitle("")
				if globalSettings.windowTitleFullPath:
					self.setWindowTitle(tab.fileName + '[*]')
				self.setWindowFilePath(tab.fileName)
				self.updateTabTitle(self.ind, tab)
				self.tabWidget.setTabToolTip(self.ind, tab.fileName)
				QDir.setCurrent(QFileInfo(tab.fileName).dir().path())
			else:
				self.setWindowFilePath('')
				self.setWindowTitle(self.tr('New document') + '[*]')

			canReload = bool(tab.fileName) and not self.autoSaveActive(tab)
			self.actionSetEncoding.setEnabled(canReload)
			self.actionReload.setEnabled(canReload)

	def tabActiveMarkupChanged(self, tab):
		'''
		Perform all UI state changes that need to be done when the
		active markup class of the current tab has changed.
		'''
		if tab == self.currentTab:
			markupClass = tab.getActiveMarkupClass()
			dtMarkdown = (markupClass == markups.MarkdownMarkup)
			dtMkdOrReST = dtMarkdown or (markupClass == markups.ReStructuredTextMarkup)
			self.formattingBox.setEnabled(dtMarkdown)
			self.symbolBox.setEnabled(dtMarkdown)
			self.actionUnderline.setEnabled(dtMarkdown)
			self.actionBold.setEnabled(dtMkdOrReST)
			self.actionItalic.setEnabled(dtMkdOrReST)

	def tabModificationStateChanged(self, tab):
		'''
		Perform all UI state changes that need to be done when the
		modification state of the current tab has changed.
		'''

		if tab == self.currentTab:
			changed = tab.editBox.document().isModified()
			if self.autoSaveActive(tab):
				changed = False
			self.actionSave.setEnabled(changed)
			self.updateTabTitle(self.ind, tab)
			self.setWindowModified(changed)

	def createTab(self, fileName):
		previewStatesByName = {
			'editor': PreviewDisabled,
			'normal-preview': PreviewNormal,
			'live-preview': PreviewLive,
		}
		previewState = previewStatesByName.get(globalSettings.defaultPreviewState, PreviewDisabled)
		if previewState == PreviewNormal and not fileName:
			previewState = PreviewDisabled  # Opening empty document in preview mode makes no sense
		self.currentTab = ReTextTab(self, fileName, previewState)
		self.currentTab.fileNameChanged.connect(lambda: self.tabFileNameChanged(self.currentTab))
		self.currentTab.modificationStateChanged.connect(lambda: self.tabModificationStateChanged(self.currentTab))
		self.currentTab.activeMarkupChanged.connect(lambda: self.tabActiveMarkupChanged(self.currentTab))
		self.tabWidget.addTab(self.currentTab, self.tr("New document"))
		self.currentTab.updateBoxesVisibility()
		if previewState > 0:
			QTimer.singleShot(500, self.currentTab.triggerPreviewUpdate)

	def closeTab(self, ind):
		if self.maybeSave(ind):
			if self.tabWidget.count() == 1:
				self.createTab("")
			closedTab = self.tabWidget.widget(ind)
			if closedTab.fileName:
				self.fileSystemWatcher.removePath(closedTab.fileName)
			self.tabWidget.removeTab(ind)
			closedTab.deleteLater()

	def changeIndex(self, ind):
		'''
		This function is called when a different tab is selected.
		It changes the state of the window to mirror the current state
		of the newly selected tab. Future changes to this state will be
		done in response to signals emitted by the tab, to which the
		window was subscribed when the tab was created. The window is
		subscribed to all tabs like this, but only the active tab will
		logically generate these signals.
		Aside from the above this function also calls the handlers for
		the other changes that are implied by a tab switch: filename
		change, modification state change and active markup change.
		'''
		self.currentTab = self.tabWidget.currentWidget()
		editBox = self.currentTab.editBox
		previewState = self.currentTab.previewState
		self.actionUndo.setEnabled(editBox.document().isUndoAvailable())
		self.actionRedo.setEnabled(editBox.document().isRedoAvailable())
		self.actionCopy.setEnabled(editBox.textCursor().hasSelection())
		self.actionCut.setEnabled(editBox.textCursor().hasSelection())
		self.actionPreview.setChecked(previewState >= PreviewLive)
		self.actionLivePreview.setChecked(previewState == PreviewLive)
		self.actionTableMode.setChecked(editBox.tableModeEnabled)
		self.editBar.setEnabled(previewState < PreviewNormal)
		self.ind = ind
		editBox.setFocus(Qt.OtherFocusReason)

		self.tabFileNameChanged(self.currentTab)
		self.tabModificationStateChanged(self.currentTab)
		self.tabActiveMarkupChanged(self.currentTab)

	def changeEditorFont(self):
		font, ok = QFontDialog.getFont(globalSettings.editorFont, self)
		if ok:
			self.setEditorFont(font)

	def setEditorFont(self, font):
		globalSettings.editorFont = font
		for tab in self.iterateTabs():
			tab.editBox.updateFont()

	def changePreviewFont(self):
		font, ok = QFontDialog.getFont(globalSettings.font, self)
		if ok:
			self.setPreviewFont(font)

	def setPreviewFont(self, font):
		globalSettings.font = font
		for tab in self.iterateTabs():
			tab.triggerPreviewUpdate()

	def preview(self, viewmode):
		self.currentTab.previewState = viewmode * 2
		self.actionLivePreview.setChecked(False)
		self.editBar.setDisabled(viewmode)
		self.currentTab.updateBoxesVisibility()
		self.currentTab.triggerPreviewUpdate()

	def enableLivePreview(self, livemode):
		self.currentTab.previewState = int(livemode)
		self.actionPreview.setChecked(livemode)
		self.editBar.setEnabled(True)
		self.currentTab.updateBoxesVisibility()
		self.currentTab.triggerPreviewUpdate()

	def enableWebKit(self, enable):
		globalSettings.useWebKit = enable
		globalSettings.useWebEngine = False
		for tab in self.iterateTabs():
			tab.rebuildPreviewBox()

	def enableWebEngine(self, enable):
		globalSettings.useWebKit = False
		globalSettings.useWebEngine = enable
		for tab in self.iterateTabs():
			tab.rebuildPreviewBox()

	def enableCopy(self, copymode):
		self.actionCopy.setEnabled(copymode)
		self.actionCut.setEnabled(copymode)

	def enableFullScreen(self, yes):
		if yes:
			self.showFullScreen()
		else:
			self.showNormal()

	def openConfigDialog(self):
		dlg = ConfigDialog(self)
		dlg.setWindowTitle(self.tr('Preferences'))
		dlg.show()

	def enableFakeVimMode(self, yes):
		globalSettings.useFakeVim = yes
		if yes:
			FakeVimMode.init(self)
			for tab in self.iterateTabs():
				tab.editBox.installFakeVimHandler()
		else:
			FakeVimMode.exit(self)

	def enableSpellCheck(self, yes):
		try:
			dict = enchant.Dict(self.sl or None)
		except enchant.errors.Error as e:
			QMessageBox.warning(self, '', str(e))
			self.actionEnableSC.setChecked(False)
			yes = False
		self.setAllDictionaries(dict if yes else None)
		globalSettings.spellCheck = yes

	def setAllDictionaries(self, dictionary):
		for tab in self.iterateTabs():
			hl = tab.highlighter
			hl.dictionary = dictionary
			hl.rehighlight()

	def changeLocale(self):
		localedlg = LocaleDialog(self, defaultText=self.sl)
		if localedlg.exec() != QDialog.Accepted:
			return
		sl = localedlg.localeEdit.text()
		try:
			enchant.Dict(sl or None)
		except enchant.errors.Error as e:
			QMessageBox.warning(self, '', str(e))
		else:
			self.sl = sl or None
			self.enableSpellCheck(self.actionEnableSC.isChecked())
			if localedlg.checkBox.isChecked():
				globalSettings.spellCheckLocale = sl

	def search(self):
		self.searchBar.setVisible(True)
		self.searchEdit.setFocus(Qt.ShortcutFocusReason)

	def goToLine(self):
		line, ok = QInputDialog.getInt(self, self.tr("Go to line"), self.tr("Type the line number"))
		if ok:
			self.currentTab.goToLine(line-1)

	def searchBarVisibilityChanged(self, visible):
		if visible:
			self.searchEdit.setFocus(Qt.ShortcutFocusReason)

	def find(self, back=False, replace=False):
		flags = QTextDocument.FindFlags()
		if back:
			flags |= QTextDocument.FindBackward
		if self.csBox.isChecked():
			flags |= QTextDocument.FindCaseSensitively
		text = self.searchEdit.text()
		replaceText = self.replaceEdit.text() if replace else None
		found = self.currentTab.find(text, flags, replaceText=replaceText)
		self.setSearchEditColor(found)

	def replaceAll(self):
		text = self.searchEdit.text()
		replaceText = self.replaceEdit.text()
		found = self.currentTab.replaceAll(text, replaceText)
		self.setSearchEditColor(found)

	def setSearchEditColor(self, found):
		palette = self.searchEdit.palette()
		palette.setColor(QPalette.Active, QPalette.Base,
		                 Qt.white if found else QColor(255, 102, 102))
		self.searchEdit.setPalette(palette)

	def showInDir(self):
		if self.currentTab.fileName:
			path = QFileInfo(self.currentTab.fileName).path()
			QDesktopServices.openUrl(QUrl.fromLocalFile(path))
		else:
			QMessageBox.warning(self, '', self.tr("Please, save the file somewhere."))

	def moveToTopOfRecentFileList(self, fileName):
		if fileName:
			files = readListFromSettings("recentFileList")
			if fileName in files:
				files.remove(fileName)
			files.insert(0, fileName)
			recentCount = globalSettings.recentDocumentsCount
			if len(files) > recentCount:
				del files[recentCount:]
			writeListToSettings("recentFileList", files)

	def createNew(self, text=None):
		self.createTab("")
		self.ind = self.tabWidget.count()-1
		self.tabWidget.setCurrentIndex(self.ind)
		if text:
			self.currentTab.editBox.textCursor().insertText(text)

	def switchTab(self, shift=1):
		self.tabWidget.setCurrentIndex((self.ind + shift) % self.tabWidget.count())

	def updateRecentFiles(self):
		self.menuRecentFiles.clear()
		self.recentFilesActions = []
		filesOld = readListFromSettings("recentFileList")
		files = []
		for f in filesOld:
			if QFile.exists(f):
				files.append(f)
				self.recentFilesActions.append(self.act(f, trig=self.openFunction(f)))
		writeListToSettings("recentFileList", files)
		for action in self.recentFilesActions:
			self.menuRecentFiles.addAction(action)

	def markupFunction(self, markup):
		return lambda: self.setDefaultMarkup(markup)

	def openFunction(self, fileName):
		return lambda: self.openFileWrapper(fileName)

	def extensionFunction(self, data):
		return lambda: \
		self.runExtensionCommand(data['Exec'], data['FileFilter'], data['DefaultExtension'])

	def getExportExtensionsList(self):
		extensions = []
		for extsprefix in datadirs:
			extsdir = QDir(extsprefix+'/export-extensions/')
			if extsdir.exists():
				for fileInfo in extsdir.entryInfoList(['*.desktop', '*.ini'],
				QDir.Files | QDir.Readable):
					extensions.append(self.readExtension(fileInfo.filePath()))
		locale = QLocale.system().name()
		self.extensionActions = []
		for extension in extensions:
			try:
				if ('Name[%s]' % locale) in extension:
					name = extension['Name[%s]' % locale]
				elif ('Name[%s]' % locale.split('_')[0]) in extension:
					name = extension['Name[%s]' % locale.split('_')[0]]
				else:
					name = extension['Name']
				data = {}
				for prop in ('FileFilter', 'DefaultExtension', 'Exec'):
					if 'X-ReText-'+prop in extension:
						data[prop] = extension['X-ReText-'+prop]
					elif prop in extension:
						data[prop] = extension[prop]
					else:
						data[prop] = ''
				action = self.act(name, trig=self.extensionFunction(data))
				if 'Icon' in extension:
					action.setIcon(self.actIcon(extension['Icon']))
				mimetype = extension['MimeType'] if 'MimeType' in extension else None
			except KeyError:
				print('Failed to parse extension: Name is required', file=sys.stderr)
			else:
				self.extensionActions.append((action, mimetype))

	def updateExtensionsVisibility(self):
		markupClass = self.currentTab.getActiveMarkupClass()
		for action in self.extensionActions:
			if markupClass is None:
				action[0].setEnabled(False)
				continue
			mimetype = action[1]
			if mimetype is None:
				enabled = True
			elif markupClass == markups.MarkdownMarkup:
				enabled = (mimetype in ("text/x-retext-markdown", "text/x-markdown", "text/markdown"))
			elif markupClass == markups.ReStructuredTextMarkup:
				enabled = (mimetype in ("text/x-retext-rst", "text/x-rst"))
			else:
				enabled = False
			action[0].setEnabled(enabled)

	def readExtension(self, fileName):
		extFile = QFile(fileName)
		extFile.open(QIODevice.ReadOnly)
		extension = {}
		stream = QTextStream(extFile)
		while not stream.atEnd():
			line = stream.readLine()
			if '=' in line:
				index = line.index('=')
				extension[line[:index].rstrip()] = line[index+1:].lstrip()
		extFile.close()
		return extension

	def openFile(self):
		supportedExtensions = ['.txt']
		for markup in markups.get_all_markups():
			supportedExtensions += markup.file_extensions
		fileFilter = ' (' + str.join(' ', ['*'+ext for ext in supportedExtensions]) + ');;'
		fileNames = QFileDialog.getOpenFileNames(self,
			self.tr("Select one or several files to open"), QDir.currentPath(),
			self.tr("Supported files") + fileFilter + self.tr("All files (*)"))
		for fileName in fileNames[0]:
			self.openFileWrapper(fileName)

	@pyqtSlot(str)
	def openFileWrapper(self, fileName):
		if not fileName:
			return
		fileName = QFileInfo(fileName).canonicalFilePath()
		exists = False
		for i, tab in enumerate(self.iterateTabs()):
			if tab.fileName == fileName:
				exists = True
				ex = i
		if exists:
			self.tabWidget.setCurrentIndex(ex)
		elif QFile.exists(fileName):
			noEmptyTab = (
				(self.ind is None) or
				self.currentTab.fileName or
				self.currentTab.editBox.toPlainText() or
				self.currentTab.editBox.document().isModified()
			)
			if noEmptyTab:
				self.createTab(fileName)
				self.ind = self.tabWidget.count()-1
				self.tabWidget.setCurrentIndex(self.ind)
			if fileName:
				self.fileSystemWatcher.addPath(fileName)
			self.currentTab.readTextFromFile(fileName)
			self.moveToTopOfRecentFileList(self.currentTab.fileName)

	def showEncodingDialog(self):
		if not self.maybeSave(self.ind):
			return
		codecsSet = set(bytes(QTextCodec.codecForName(alias).name())
		                for alias in QTextCodec.availableCodecs())
		encoding, ok = QInputDialog.getItem(self, '',
			self.tr('Select file encoding from the list:'),
			[bytes(b).decode() for b in sorted(codecsSet)],
			0, False)
		if ok:
			self.currentTab.readTextFromFile(None, encoding)

	def saveFileAs(self):
		self.saveFile(dlg=True)

	def saveAll(self):
		for tab in self.iterateTabs():
			if (tab.fileName and tab.editBox.document().isModified()
				and QFileInfo(tab.fileName).isWritable()):
				tab.saveTextToFile()

	def saveFile(self, dlg=False):
		fileNameToSave = self.currentTab.fileName

		if (not fileNameToSave) or dlg:
			proposedFileName = ""
			markupClass = self.currentTab.getActiveMarkupClass()
			if (markupClass is None) or not hasattr(markupClass, 'default_extension'):
				defaultExt = self.tr("Plain text (*.txt)")
				ext = ".txt"
			else:
				defaultExt = self.tr('%s files',
					'Example of final string: Markdown files') \
					% markupClass.name + ' (' + str.join(' ',
					('*'+extension for extension in markupClass.file_extensions)) + ')'
				if markupClass == markups.MarkdownMarkup:
					ext = globalSettings.markdownDefaultFileExtension
				elif markupClass == markups.ReStructuredTextMarkup:
					ext = globalSettings.restDefaultFileExtension
				else:
					ext = markupClass.default_extension
			if fileNameToSave is not None:
				proposedFileName = fileNameToSave
			fileNameToSave = QFileDialog.getSaveFileName(self,
				self.tr("Save file"), proposedFileName, defaultExt)[0]
			if fileNameToSave:
				if not QFileInfo(fileNameToSave).suffix():
					fileNameToSave += ext
				# Make sure we don't overwrite a file opened in other tab
				for tab in self.iterateTabs():
					if tab is not self.currentTab and tab.fileName == fileNameToSave:
						QMessageBox.warning(self, "",
							self.tr("Cannot save to file which is open in another tab!"))
						return False
				self.actionSetEncoding.setDisabled(self.autoSaveActive())
		if fileNameToSave:
			if self.currentTab.saveTextToFile(fileNameToSave):
				self.moveToTopOfRecentFileList(self.currentTab.fileName)
				return True
			else:
				QMessageBox.warning(self, '',
				self.tr("Cannot save to file because it is read-only!"))
		return False

	def saveHtml(self, fileName):
		if not QFileInfo(fileName).suffix():
			fileName += ".html"
		try:
			_, htmltext, _ = self.currentTab.getDocumentForExport(webenv=True)
		except Exception:
			return self.printError()
		htmlFile = QFile(fileName)
		result = htmlFile.open(QIODevice.WriteOnly)
		if not result:
			QMessageBox.warning(self, '',
				self.tr("Cannot save to file because it is read-only!"))
			return
		html = QTextStream(htmlFile)
		if globalSettings.defaultCodec:
			html.setCodec(globalSettings.defaultCodec)
		html << htmltext
		htmlFile.close()

	def textDocument(self, title, htmltext):
		td = QTextDocument()
		td.setMetaInformation(QTextDocument.DocumentTitle, title)
		td.setHtml(htmltext)
		td.setDefaultFont(globalSettings.font)
		return td

	def saveOdf(self):
		title, htmltext, _ = self.currentTab.getDocumentForExport()
		try:
			document = self.textDocument(title, htmltext)
		except Exception:
			return self.printError()
		fileName = QFileDialog.getSaveFileName(self,
			self.tr("Export document to ODT"), self.currentTab.getBaseName() + ".odt",
			self.tr("OpenDocument text files (*.odt)"))[0]
		if not QFileInfo(fileName).suffix():
			fileName += ".odt"
		writer = QTextDocumentWriter(fileName)
		writer.setFormat(b"odf")
		writer.write(document)

	def saveFileHtml(self):
		fileName = QFileDialog.getSaveFileName(self,
			self.tr("Save file"), self.currentTab.getBaseName() + ".html",
			self.tr("HTML files (*.html *.htm)"))[0]
		if fileName:
			self.saveHtml(fileName)

	def getDocumentForPrint(self, title, htmltext, preview):
		if globalSettings.useWebKit:
			return preview
		try:
			return self.textDocument(title, htmltext)
		except Exception:
			self.printError()

	def standardPrinter(self, title):
		printer = QPrinter(QPrinter.HighResolution)
		printer.setDocName(title)
		printer.setCreator('ReText %s' % app_version)
		if globalSettings.paperSize:
			pageSize = self.getPageSizeByName(globalSettings.paperSize)
			if pageSize is not None:
				printer.setPaperSize(pageSize)
			else:
				QMessageBox.warning(self, '',
					self.tr('Unrecognized paperSize setting "%s".') %
					globalSettings.paperSize)
		return printer

	def getPageSizeByName(self, pageSizeName):
		""" Returns a validated PageSize instance corresponding to the given
		name. Returns None if the name is not a valid PageSize.
		"""
		pageSize = None

		lowerCaseNames = {pageSize.lower(): pageSize for pageSize in
		                  self.availablePageSizes()}
		if pageSizeName.lower() in lowerCaseNames:
			pageSize = getattr(QPagedPaintDevice, lowerCaseNames[pageSizeName.lower()])

		return pageSize

	def availablePageSizes(self):
		""" List available page sizes. """

		sizes = [x for x in dir(QPagedPaintDevice)
		         if type(getattr(QPagedPaintDevice, x)) == QPagedPaintDevice.PageSize]
		return sizes

	def savePdf(self):
		fileName = QFileDialog.getSaveFileName(self,
			self.tr("Export document to PDF"),
			self.currentTab.getBaseName() + ".pdf",
			self.tr("PDF files (*.pdf)"))[0]
		if fileName:
			if not QFileInfo(fileName).suffix():
				fileName += ".pdf"
			title, htmltext, preview = self.currentTab.getDocumentForExport()
			if globalSettings.useWebEngine and hasattr(preview.page(), "printToPdf"):
				pageSize = self.getPageSizeByName(globalSettings.paperSize)
				if pageSize is None:
					pageSize = QPageSize(QPageSize.A4)
				margins = QMarginsF(20, 20, 13, 20)  # left, top, right, bottom (in millimeters)
				layout = QPageLayout(pageSize, QPageLayout.Portrait, margins, QPageLayout.Millimeter)
				preview.page().printToPdf(fileName, layout)  # Available since Qt 5.7
				return
			printer = self.standardPrinter(title)
			printer.setOutputFormat(QPrinter.PdfFormat)
			printer.setOutputFileName(fileName)
			document = self.getDocumentForPrint(title, htmltext, preview)
			if document != None:
				document.print(printer)

	def printFile(self):
		title, htmltext, preview = self.currentTab.getDocumentForExport()
		printer = self.standardPrinter(title)
		dlg = QPrintDialog(printer, self)
		dlg.setWindowTitle(self.tr("Print document"))
		if (dlg.exec() == QDialog.Accepted):
			document = self.getDocumentForPrint(title, htmltext, preview)
			if document != None:
				document.print(printer)

	def printPreview(self):
		title, htmltext, preview = self.currentTab.getDocumentForExport()
		document = self.getDocumentForPrint(title, htmltext, preview)
		if document is None:
			return
		printer = self.standardPrinter(title)
		preview = QPrintPreviewDialog(printer, self)
		preview.paintRequested.connect(document.print)
		preview.exec()

	def runExtensionCommand(self, command, filefilter, defaultext):
		import shlex
		of = ('%of' in command)
		html = ('%html' in command)
		if of:
			if defaultext and not filefilter:
				filefilter = '*'+defaultext
			fileName = QFileDialog.getSaveFileName(self,
				self.tr('Export document'), '', filefilter)[0]
			if not fileName:
				return
			if defaultext and not QFileInfo(fileName).suffix():
				fileName += defaultext
		else:
			fileName = 'out' + defaultext
		basename = '.%s.retext-temp' % self.currentTab.getBaseName()
		if html:
			tmpname = basename+'.html'
			self.saveHtml(tmpname)
		else:
			tmpname = basename + self.currentTab.getActiveMarkupClass().default_extension
			self.currentTab.writeTextToFile(tmpname)
		command = command.replace('%of', shlex.quote(fileName))
		command = command.replace('%html' if html else '%if', shlex.quote(tmpname))
		try:
			Popen(str(command), shell=True).wait()
		except Exception as error:
			errorstr = str(error)
			QMessageBox.warning(self, '', self.tr('Failed to execute the command:')
			+ '\n' + errorstr)
		QFile(tmpname).remove()

	def autoSaveActive(self, tab=None):
		tab = tab if tab else self.currentTab
		return bool(self.autoSaveEnabled and tab.fileName and
			    QFileInfo(tab.fileName).isWritable())

	def clipboardDataChanged(self):
		mimeData = QApplication.instance().clipboard().mimeData()
		if mimeData is not None:
			self.actionPaste.setEnabled(mimeData.hasText())
			self.actionPasteImage.setEnabled(mimeData.hasImage())

	def insertFormatting(self, formatting):
		if formatting == 'table':
			dialog = InsertTableDialog(self)
			dialog.show()
			self.formattingBox.setCurrentIndex(0)
			return

		cursor = self.currentTab.editBox.textCursor()
		text = cursor.selectedText()
		moveCursorTo = None

		def c(cursor):
			nonlocal moveCursorTo
			moveCursorTo = cursor.position()

		def ensurenl(cursor):
			if not cursor.atBlockStart():
				cursor.insertText('\n\n')

		toinsert = {
			'header': (ensurenl, '# ', text),
			'italic': ('*', text, c, '*'),
			'bold': ('**', text, c, '**'),
			'underline': ('<u>', text, c, '</u>'),
			'numbering': (ensurenl, ' 1. ', text),
			'bullets': (ensurenl, '  * ', text),
			'image': ('![', text or self.tr('Alt text'), c, '](', self.tr('URL'), ')'),
			'link': ('[', text or self.tr('Link text'), c, '](', self.tr('URL'), ')'),
			'inline code': ('`', text, c, '`'),
			'code block': (ensurenl, '    ', text),
			'blockquote': (ensurenl, '> ', text),
		}

		if formatting not in toinsert:
			return

		cursor.beginEditBlock()
		for token in toinsert[formatting]:
			if callable(token):
				token(cursor)
			else:
				cursor.insertText(token)
		cursor.endEditBlock()

		self.formattingBox.setCurrentIndex(0)
		# Bring back the focus on the editor
		self.currentTab.editBox.setFocus(Qt.OtherFocusReason)

		if moveCursorTo:
			cursor.setPosition(moveCursorTo)
			self.currentTab.editBox.setTextCursor(cursor)

	def insertSymbol(self, num):
		if num:
			self.currentTab.editBox.insertPlainText('&'+self.usefulChars[num-1]+';')
		self.symbolBox.setCurrentIndex(0)

	def fileChanged(self, fileName):
		tab = None
		for testtab in self.iterateTabs():
			if testtab.fileName == fileName:
				tab = testtab
		if tab is None:
			self.fileSystemWatcher.removePath(fileName)
			return
		if not QFile.exists(fileName):
			self.tabWidget.setCurrentWidget(tab)
			tab.editBox.document().setModified(True)
			QMessageBox.warning(self, '', self.tr(
				'This file has been deleted by other application.\n'
				'Please make sure you save the file before exit.'))
		elif not tab.editBox.document().isModified():
			# File was not modified in ReText, reload silently
			tab.readTextFromFile()
		else:
			self.tabWidget.setCurrentWidget(tab)
			text = self.tr(
				'This document has been modified by other application.\n'
				'Do you want to reload the file (this will discard all '
				'your changes)?\n')
			if self.autoSaveEnabled:
				text += self.tr(
					'If you choose to not reload the file, auto save mode will '
					'be disabled for this session to prevent data loss.')
			messageBox = QMessageBox(QMessageBox.Warning, '', text)
			reloadButton = messageBox.addButton(self.tr('Reload'), QMessageBox.YesRole)
			messageBox.addButton(QMessageBox.Cancel)
			messageBox.exec()
			if messageBox.clickedButton() is reloadButton:
				tab.readTextFromFile()
			else:
				self.autoSaveEnabled = False
				tab.editBox.document().setModified(True)
		if fileName not in self.fileSystemWatcher.files():
			# https://github.com/retext-project/retext/issues/137
			self.fileSystemWatcher.addPath(fileName)

	def maybeSave(self, ind):
		tab = self.tabWidget.widget(ind)
		if self.autoSaveActive(tab):
			tab.saveTextToFile()
			return True
		if not tab.editBox.document().isModified():
			return True
		self.tabWidget.setCurrentIndex(ind)
		ret = QMessageBox.warning(self, '',
			self.tr("The document has been modified.\nDo you want to save your changes?"),
			QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
		if ret == QMessageBox.Save:
			return self.saveFile(False)
		elif ret == QMessageBox.Cancel:
			return False
		return True

	def closeEvent(self, closeevent):
		for ind in range(self.tabWidget.count()):
			if not self.maybeSave(ind):
				return closeevent.ignore()
		if globalSettings.saveWindowGeometry:
			globalSettings.windowGeometry = self.saveGeometry()
		if globalSettings.openLastFilesOnStartup:
			files = [tab.fileName for tab in self.iterateTabs()]
			writeListToSettings("lastFileList", files)
			globalSettings.lastTabIndex = self.tabWidget.currentIndex()
		closeevent.accept()

	def viewHtml(self):
		htmlDlg = HtmlDialog(self)
		try:
			_, htmltext, _ = self.currentTab.getDocumentForExport(includeStyleSheet=False)
		except Exception:
			return self.printError()
		winTitle = self.currentTab.getBaseName()
		htmlDlg.setWindowTitle(winTitle+" ("+self.tr("HTML code")+")")
		htmlDlg.textEdit.setPlainText(htmltext.rstrip())
		htmlDlg.hl.rehighlight()
		htmlDlg.show()
		htmlDlg.raise_()
		htmlDlg.activateWindow()

	def insertImages(self):
		supportedExtensions = ['.png', '.jpg', '.jpeg', '.gif', '.bmp']
		fileFilter = ' (%s);;' % ' '.join('*' + ext for ext in supportedExtensions)
		fileNames, _selectedFilter = QFileDialog.getOpenFileNames(self,
			self.tr("Select one or several images to open"), QDir.currentPath(),
			self.tr("Supported files") + fileFilter + self.tr("All files (*)"))

		cursor = self.currentTab.editBox.textCursor()

		imagesMarkup = '\n'.join(
			self.currentTab.editBox.getImageMarkup(fileName)
			for fileName in fileNames)
		cursor.insertText(imagesMarkup)

		self.formattingBox.setCurrentIndex(0)
		self.currentTab.editBox.setFocus(Qt.OtherFocusReason)

	def openHelp(self):
		QDesktopServices.openUrl(QUrl('https://github.com/retext-project/retext/wiki'))

	def aboutDialog(self):
		QMessageBox.about(self, self.aboutWindowTitle,
		'<p><b>' + (self.tr('ReText %s (using PyMarkups %s)') % (app_version, markups.__version__))
		+'</b></p>' + self.tr('Simple but powerful editor'
		' for Markdown and reStructuredText')
		+'</p><p>'+self.tr('Author: Dmitry Shachnev, 2011').replace('2011', '2011–2020')
		+'<br><a href="https://github.com/retext-project/retext">'+self.tr('Website')
		+'</a> | <a href="http://daringfireball.net/projects/markdown/syntax">'
		+self.tr('Markdown syntax')
		+'</a> | <a href="http://docutils.sourceforge.net/docs/user/rst/quickref.html">'
		+self.tr('reStructuredText syntax')+'</a></p>')

	def setDefaultMarkup(self, markupClass):
		globalSettings.defaultMarkup = markupClass.name
		for tab in self.iterateTabs():
			if not tab.fileName:
				tab.updateActiveMarkupClass()
Exemplo n.º 33
0
    def createDockWindows(self):
        dock = QDockWidget("Folders", self)
        dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        #Code to Create FileView Colums and FolderTree
        self.FileView = QtWidgets.QColumnView()
        self.FileView.setGeometry(QtCore.QRect(240, 10, 291, 281))
        self.FolderTree = QtWidgets.QTreeView()
        self.FolderTree.setGeometry(QtCore.QRect(10, 10, 221, 281))
        FolderTree = self.FolderTree
        #FolderTree.hidecolumn(1),... ?? to show only name column

        #include FolderTree to a Dock at the left side
        dock.setWidget(FolderTree)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)
        #set the model and rootpath for filling the FolderTree from self.ui
        dirmodel = QFileSystemModel()
        #set filter to show only folders
        dirmodel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)
        dirmodel.setRootPath(rootpath)
        #filemodel and filter for only files on right side
        filemodel = QFileSystemModel()
        filemodel.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        filemodel.setRootPath(rootpath)
        FolderView = self.FolderTree
        FolderView.setModel(dirmodel)
        FolderView.setRootIndex(dirmodel.index(rootpath))
        FileView = self.FileView
        FileView.setModel(filemodel)
        dock = QDockWidget("Files", self)
        dock.setWidget(FileView)
        self.addDockWidget(Qt.RightDockWidgetArea, dock)

        #important lines for the connection, which does not work
        self.FolderTree.clicked['QModelIndex'].connect(self.setpathonclick)
Exemplo n.º 34
0
class Win(QMainWindow):
	def __init__(self, options):
		super(Win, self).__init__()

		self.db = dbtag.Db()
		self.db.open(options.db)
		self.db.create_tables()
		self.rootPath = options.filespath

		self._init_widgets()
		self._init_more()

	def _init_widgets(self):
		bigsplitter = QSplitter(Qt.Horizontal, self)
		self.setCentralWidget(bigsplitter)

		leftsplitter = QSplitter(Qt.Vertical, self)

		self.tabWidget = QTabWidget(self)

		self.tagChooser = TagChooser(self.db)
		self.dirChooser = QTreeView(self)

		self.tabWidget.addTab(self.dirChooser, 'Dir')
		self.tabWidget.addTab(self.tagChooser, 'Tags')

		self.tagEditor = TagEditor(self.db)
		self.imageList = ImageList()

		leftsplitter.addWidget(self.tabWidget)
		leftsplitter.addWidget(self.tagEditor)

		bigsplitter.addWidget(leftsplitter)
		bigsplitter.addWidget(self.imageList)

		self.viewer = ImageViewer(self.db)

	def _init_more(self):
		self.setWindowTitle('Tags4')

		self.dirModel = QFileSystemModel()
		self.dirModel.setFilter(QDir.AllDirs | QDir.Drives | QDir.Hidden | QDir.NoDotAndDotDot)
		qidx = self.dirModel.setRootPath(self.rootPath)
		self.dirChooser.setModel(self.dirModel)
		self.dirChooser.setRootIndex(qidx)

		self.dirChooser.clicked.connect(self.browseSelectedDir)
		self.imageList.itemSelectionChanged.connect(self._editTagsItems)
		self.imageList.itemDoubleClicked.connect(self._spawnViewerItem)
		self.imageList.setSelectionMode(QAbstractItemView.ExtendedSelection)

		self.tabWidget.currentChanged.connect(self._tabSelected)
		self.tagChooser.changed.connect(self.browseSelectedTags)

	def editTags(self, path):
		self.tagEditor.setFile(path)

	def editTagsItems(self, paths):
		self.tagEditor.setFiles(paths)

	def spawnViewer(self, files, currentFile):
		self.viewer.spawn(files, currentFile)

	@Slot()
	def _editTagsItems(self):
		self.editTagsItems([qitem.getPath() for qitem in self.imageList.selectedItems()])

	@Slot(QListWidgetItem)
	def _spawnViewerItem(self, qitem):
		self.spawnViewer(self.imageList.getFiles(), qitem.getPath())

	@Slot()
	def browseSelectedDir(self):
		path = self.dirModel.filePath(self.dirChooser.currentIndex())
		if not path:
			return
		files = [os.path.join(path, f) for f in os.listdir(path)]
		files = filter(os.path.isfile, files)
		files.sort()
		self.imageList.setFiles(files)

	@Slot()
	def browseSelectedTags(self):
		self.imageList.setFiles(self.tagChooser.matchingFiles())

	@Slot(int)
	def _tabSelected(self, idx):
		if idx == 0:
			self.browseSelectedDir()
		else:
			self.browseSelectedTags()

	def browsePath(self, path):
		self.imageList.setFiles(os.path.join(path, f) for f in os.listdir(path))
Exemplo n.º 35
0
    def load_tree(self, project):
        """Load the tree view on the right based on the project selected."""
        qfsm = QFileSystemModel()
        qfsm.setRootPath(project.path)
        load_index = qfsm.index(qfsm.rootPath())
        qfsm.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot)
        qfsm.setNameFilterDisables(False)
        pext = ["*{0}".format(x) for x in project.extensions]
        qfsm.setNameFilters(pext)

        self._tree.setModel(qfsm)
        self._tree.setRootIndex(load_index)

        t_header = self._tree.header()
        t_header.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
        t_header.setSectionResizeMode(0, QHeaderView.Stretch)
        t_header.setStretchLastSection(False)
        t_header.setSectionsClickable(True)

        self._tree.hideColumn(1)  # Size
        self._tree.hideColumn(2)  # Type
        self._tree.hideColumn(3)  # Modification date
Exemplo n.º 36
0
    def setup_ui(self):
        self.ui.setupUi(self)
        settings = QSettings()

        self.ui.splitter.setSizes([600, 1000])
        self.ui.splitter.setChildrenCollapsible(False)

        # Set up folder view

        lastDir = settings.value("mainwindow/workingDirectory",
                                 QDir.homePath())
        log.debug('Current directory: {currentDir}'.format(currentDir=lastDir))

        self.fileModel = QFileSystemModel(self)
        self.fileModel.setFilter(QDir.AllDirs | QDir.Dirs | QDir.Drives
                                 | QDir.NoDotAndDotDot | QDir.Readable
                                 | QDir.Executable | QDir.Writable)
        self.fileModel.iconProvider().setOptions(
            QFileIconProvider.DontUseCustomDirectoryIcons)
        self.fileModel.setRootPath(QDir.rootPath())
        self.fileModel.directoryLoaded.connect(self.onFileModelDirectoryLoaded)

        self.proxyFileModel = QSortFilterProxyModel(self)
        self.proxyFileModel.setSortRole(Qt.DisplayRole)
        self.proxyFileModel.setSourceModel(self.fileModel)
        self.proxyFileModel.sort(0, Qt.AscendingOrder)
        self.proxyFileModel.setSortCaseSensitivity(Qt.CaseInsensitive)
        self.ui.folderView.setModel(self.proxyFileModel)

        self.ui.folderView.setHeaderHidden(True)
        self.ui.folderView.hideColumn(3)
        self.ui.folderView.hideColumn(2)
        self.ui.folderView.hideColumn(1)

        index = self.fileModel.index(lastDir)
        proxyIndex = self.proxyFileModel.mapFromSource(index)
        self.ui.folderView.scrollTo(proxyIndex)

        self.ui.folderView.expanded.connect(self.onFolderViewExpanded)
        self.ui.folderView.clicked.connect(self.onFolderTreeClicked)
        self.ui.buttonFind.clicked.connect(self.onButtonFind)
        self.ui.buttonRefresh.clicked.connect(self.onButtonRefresh)

        # Set up introduction
        self.showInstructions()

        # Set up video view
        self.ui.filterLanguageForVideo.set_unknown_text(_('All languages'))
        self.ui.filterLanguageForVideo.selected_language_changed.connect(
            self.on_language_combobox_filter_change)
        # self.ui.filterLanguageForVideo.selected_language_changed.connect(self.onFilterLanguageVideo)

        self.videoModel = VideoModel(self)
        self.ui.videoView.setHeaderHidden(True)
        self.ui.videoView.setModel(self.videoModel)
        self.ui.videoView.activated.connect(self.onClickVideoTreeView)
        self.ui.videoView.clicked.connect(self.onClickVideoTreeView)
        self.ui.videoView.customContextMenuRequested.connect(self.onContext)
        self.videoModel.dataChanged.connect(self.subtitlesCheckedChanged)
        self.language_filter_change.connect(
            self.videoModel.on_filter_languages_change)

        self.ui.buttonSearchSelectVideos.clicked.connect(
            self.onButtonSearchSelectVideos)
        self.ui.buttonSearchSelectFolder.clicked.connect(
            self.onButtonSearchSelectFolder)
        self.ui.buttonDownload.clicked.connect(self.onButtonDownload)
        self.ui.buttonPlay.clicked.connect(self.onButtonPlay)
        self.ui.buttonIMDB.clicked.connect(self.onViewOnlineInfo)
        self.ui.videoView.setContextMenuPolicy(Qt.CustomContextMenu)

        # Drag and Drop files to the videoView enabled
        self.ui.videoView.__class__.dragEnterEvent = self.dragEnterEvent
        self.ui.videoView.__class__.dragMoveEvent = self.dragEnterEvent
        self.ui.videoView.__class__.dropEvent = self.dropEvent
        self.ui.videoView.setAcceptDrops(1)

        # FIXME: ok to drop this connect?
        # self.ui.videoView.clicked.connect(self.onClickMovieTreeView)

        self.retranslate()
Exemplo n.º 37
0
class Script(QWidget, form_class):
    def __init__(self, parent=None):
        super(Script, self).__init__(parent)
        self.setupUi(self)

        # private variable
        self.__currentpath = ""
        self.__modfiedstate = False
        self._PyQtSignalConnect = console.PyQtSignalConnect()

        # treeView Size
        self.splitter.setSizes([
            Config().getint('SIZE', 'QtScriptFileExplorer'),
            (self.size().width()) -
            Config().getint('SIZE', 'QtScriptFileExplorer')
        ])

        # treeView model create
        self.model = QFileSystemModel()
        self.model.setNameFilters(["*.py"])

        # treeView setting
        self.treeView.setModel(self.model)
        self.treeView.setRootIndex(self.model.setRootPath('./'))
        self.treeView.setAnimated(True)
        self.treeView.setSortingEnabled(False)
        [self.treeView.hideColumn(ii) for ii in range(1, 5)]
        self.treeView.header().setStretchLastSection(False)
        self.treeView.header().setSectionResizeMode(0, QHeaderView.Stretch)

        # signal connect
        self.treeView.activated.connect(lambda e : \
                        self._open_script(self.model.filePath(e)))
        self.btnSave.clicked.connect(lambda: self._save_script())
        self.btnNew.clicked.connect(lambda: self._new_script())
        self.btnRun.clicked.connect(lambda: self._run_script())
        self.btnOpen.clicked.connect(lambda: self._btnOpen_clicked())

        self.fontComboBox.currentFontChanged.connect(
            lambda x: self.plainTextEdit.setFont(x))
        self.plainTextEdit.keyPressEvent = self._plainTextEdit_keyPressEvent
        self.plainTextEdit.wheelEvent = self._plainTextEdit_wheelEvent
        self.plainTextEdit.setAcceptDrops(True)
        self.plainTextEdit.dropEvent = lambda e: self._open_script(e.mimeData(
        ).urls()[0].toLocalFile())
        self.plainTextEdit.modificationChanged.connect(
            lambda x: self._change_modified_state(x))
        self._PyQtSignalConnect.script_run.connect(
            lambda: self.btnRun.animateClick())

    def getstate(self):
        return self.__modfiedstate

    def _change_modified_state(self, param):
        self.__modfiedstate = param

    def _btnOpen_clicked(self):
        options = QFileDialog.Options()
        fileName, _ = QFileDialog.getOpenFileName(
            self,
            "QFileDialog.getOpenFileName()",
            "",
            "All Files (*);;Python Files (*.py)",
            options=options)
        if (os.path.isfile(fileName) == True):
            self._open_script(fileName)
        else:
            pass

    @ismodified
    def _new_script(self):
        self.plainTextEdit.clear()
        self._change_modified_state(False)

    def _save_script(self):
        options = QFileDialog.Options()
        fileName, _ = QFileDialog.getSaveFileName(
            self,
            "QFileDialog.getSaveFileName()",
            self.__currentpath,
            "Python Files (*.py)",
            options=options)
        if fileName == "":
            pass
        else:
            with open(fileName, "w") as f:
                f.write(self.plainTextEdit.toPlainText())
                self.__currentpath = fileName  # when re save occurs, it will be used in default path
            self._change_modified_state(False)
        return fileName

    @ismodified
    def _open_script(self, path):
        try:
            with open(path) as f:
                self.__currentpath = path
                self.plainTextEdit.clear()
                self.plainTextEdit.setPlainText(f.read())
        except UnicodeDecodeError as e:
            pass
        except PermissionError as e:
            pass

    def _change_root(self):
        text = self.lineEdit.displayText()
        self.treeView.setRootIndex(self.model.setRootPath(text))
        self.lineEdit.clear()

    def _plainTextEdit_keyPressEvent(self, event):
        # this is monkey.......
        # how to change tab to 4 space ?
        if (event.key() == Qt.Key_Tab):
            self.plainTextEdit.insertPlainText(" " * 4)
        else:
            QPlainTextEdit.keyPressEvent(self.plainTextEdit, event)

    def _plainTextEdit_wheelEvent(self, event):
        if (event.modifiers() & Qt.ControlModifier):
            self._plainTextEdit_zoom(event.angleDelta().y())
        else:
            QPlainTextEdit.wheelEvent(self.plainTextEdit, event)

    def _plainTextEdit_zoom(self, delta):
        if delta < 0:
            self.plainTextEdit.zoomOut(2)
        elif delta > 0:
            self.plainTextEdit.zoomIn(2)

    def _run_script(self):
        self.btnRun.setEnabled(False)
        console.cexec(self.plainTextEdit.toPlainText(), isfile=True)
        self.btnRun.setEnabled(True)
Exemplo n.º 38
0
class Ui(QtWidgets.QMainWindow):

    # this safely gets a widget reference
    def getUI(self, type, name):
        x = self.findChild(type, name)
        if x is None:
            raise Exception('cannot find widget ' + name)
        return x

    def clear(self):
        if not self.capturing:
            self.canvas.clear()
        self.stage = 0
        self.data = None
        self.done = True  # we've not done anything yet

    # set image for input to processing
    # input: numpy w x h x 3 image, RGB 0-255
    def setImage(self, img):
        # cv is bgr, qt (and sensible things) are rgb
        img = cv.cvtColor(img, cv.COLOR_BGR2RGB)

        # crop to ROI and resize
        #        img = cropSquare(img,340,430,100)
        img = cv.resize(img, dsize=(600, 600), interpolation=cv.INTER_CUBIC)
        self.img = img
        self.clear()
        self.canvas.display(0, self.img)
        self.done = False

    # input: filename
    # output: numpy w x h x 3 image, RGB 0-255

    def loadFile(self, fname):
        img = cv.imread(fname)
        print("Image read")
        if img is None:
            raise Exception('cannot read image')
        self.setImage(img)

    # open file, get ROI and convert to grey
    def openFileAction(self):
        fname, _ = QFileDialog.getOpenFileName(self, 'Open file', '.',
                                               "Image files (*.jpg *.gif)")
        if fname is None or fname == '':
            return
        self.loadFile(fname)

    def nextStage(self):
        if self.done:
            return
        print("Stage {0}, image {1} ".format(self.stage, self.img.shape))
        start = time.perf_counter()
        # perform the next stage - the type of the image depends on the stage.
        # At input it's a 24-bit image.
        self.img, self.data, self.done, text = ellipse_blob.stage(
            self.stage, (self.img, self.data))
        self.stage = self.stage + 1
        self.canvas.display(self.stage, self.img)
        print("Time taken {0} ".format(time.perf_counter() - start))
        if isinstance(text, tuple):
            text, status = text
            st = self.getUI(QtWidgets.QPlainTextEdit, 'status')
            st.appendPlainText(status)
        self.canvas.text(self.stage, text)

    def findEllipsesAction(self):
        while True:
            print("Stage ", self.done, self.stage)
            self.nextStage()
            if self.done:
                break

    def liveCaptureAction(self):
        self.capturing = not self.capturing
        b = self.getUI(QtWidgets.QPushButton, 'liveCaptureButton')
        if self.capturing:
            s = "End live"
            b.setStyleSheet('QPushButton {background-color:#ff8080;}')
        else:
            s = "Begin live"
            b.setStyleSheet('QPushButton {}')
        b.setText(s)

    def fileClickedAction(self, idx):
        if not self.dirModel.isDir(idx):
            item = self.dirModel.filePath(idx)
            self.loadFile(item)

    # confirm a quit menu action
    def confirmQuitAction(self):
        #        reply = QMessageBox.question(self,
        #            'Confirm',
        #            'Really quit?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        #        if reply == QMessageBox.Yes:
        #            app.quit()
        app.quit()

    def tick(self):
        if self.capturing:
            if self.done:
                if self.cam is None:
                    self.cam = cv.VideoCapture(self.camNo)
                    self.cam.set(cv.CAP_PROP_FRAME_WIDTH, 640)
                    self.cam.set(cv.CAP_PROP_FRAME_HEIGHT, 480)
                    self.cam.set(cv.CAP_PROP_BUFFERSIZE, 1)
                ret, img = self.cam.read()
                if not ret:
                    # no cam, should turn off button and capturing
                    self.liveCaptureAction()
                else:
                    self.setImage(img)
                    self.done = False
            else:
                self.nextStage()

    def __init__(self, *args, **kwargs):
        super(Ui, self).__init__(
            *args, **kwargs)  # Call the inherited classes __init__ method
        uic.loadUi('test.ui', self)  # Load the .ui file

        # now we get references to the widgets we want and connect
        # things up. Brackets here to make the line break work.
        (self.getUI(QtWidgets.QAction,
                    'actionQuit').triggered.connect(self.confirmQuitAction))
        (self.getUI(QtWidgets.QAction,
                    'actionOpen').triggered.connect(self.openFileAction))
        (self.getUI(QtWidgets.QAction,
                    'actionLive').triggered.connect(self.liveCaptureAction))

        (self.getUI(QtWidgets.QPushButton,
                    'findEllipsesButton').clicked.connect(
                        self.findEllipsesAction))
        (self.getUI(QtWidgets.QPushButton,
                    'liveCaptureButton').clicked.connect(
                        self.liveCaptureAction))

        # set up the file tree
        self.dirModel = QFileSystemModel()
        self.dirModel.setRootPath(QDir.currentPath())
        self.dirModel.setNameFilters(["*.jpg", "*.png"])
        tree = self.getUI(QtWidgets.QTreeView, 'treeView')
        tree.setModel(self.dirModel)
        tree.setRootIndex(self.dirModel.index(QDir.currentPath()))
        tree.setIndentation(10)
        tree.setSortingEnabled(True)
        tree.setColumnWidth(0, tree.width() / 1.5)
        tree.setColumnHidden(1, True)
        tree.setColumnHidden(2, True)
        tree.doubleClicked.connect(self.fileClickedAction)
        self.treeView = tree

        # set up the live camera system (to null)
        self.capturing = False
        self.cam = None

        # set up the drawing area and the timer which updates it
        self.canvas = self.getUI(QtWidgets.QWidget, 'view')
        self.timer = QTimer()
        self.timer.timeout.connect(self.tick)
        self.timer.start(100)

        self.clear()  # set up internal state
        self.show()  # Show the GUI
Exemplo n.º 39
0
class FilenamePrompt(_BasePrompt):
    """A prompt for a filename."""
    def __init__(self, question, parent=None):
        super().__init__(question, parent)
        self._init_texts(question)
        self._init_key_label()

        self._lineedit = LineEdit(self)
        if question.default:
            self._lineedit.setText(question.default)
        self._lineedit.textEdited.connect(self._set_fileview_root)
        self._vbox.addWidget(self._lineedit)

        self.setFocusProxy(self._lineedit)

        self._init_fileview()
        self._set_fileview_root(question.default)

        if config.val.prompt.filebrowser:
            self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)

        self._to_complete = ''

    @pyqtSlot(str)
    def _set_fileview_root(self, path, *, tabbed=False):
        """Set the root path for the file display."""
        separators = os.sep
        if os.altsep is not None:
            separators += os.altsep

        dirname = os.path.dirname(path)
        basename = os.path.basename(path)
        if not tabbed:
            self._to_complete = ''

        try:
            if not path:
                pass
            elif path in separators and os.path.isdir(path):
                # Input "/" -> don't strip anything
                pass
            elif path[-1] in separators and os.path.isdir(path):
                # Input like /foo/bar/ -> show /foo/bar/ contents
                path = path.rstrip(separators)
            elif os.path.isdir(dirname) and not tabbed:
                # Input like /foo/ba -> show /foo contents
                path = dirname
                self._to_complete = basename
            else:
                return
        except OSError:
            log.prompt.exception("Failed to get directory information")
            return

        root = self._file_model.setRootPath(path)
        self._file_view.setRootIndex(root)

    @pyqtSlot(QModelIndex)
    def _insert_path(self, index, *, clicked=True):
        """Handle an element selection.

        Args:
            index: The QModelIndex of the selected element.
            clicked: Whether the element was clicked.
        """
        if index == QModelIndex():
            path = os.path.join(self._file_model.rootPath(), self._to_complete)
        else:
            path = os.path.normpath(self._file_model.filePath(index))

        if clicked:
            path += os.sep
        else:
            # On Windows, when we have C:\foo and tab over .., we get C:\
            path = path.rstrip(os.sep)

        log.prompt.debug('Inserting path {}'.format(path))
        self._lineedit.setText(path)
        self._lineedit.setFocus()
        self._set_fileview_root(path, tabbed=True)
        if clicked:
            # Avoid having a ..-subtree highlighted
            self._file_view.setCurrentIndex(QModelIndex())

    def _init_fileview(self):
        self._file_view = QTreeView(self)
        self._file_model = QFileSystemModel(self)
        self._file_view.setModel(self._file_model)
        self._file_view.clicked.connect(self._insert_path)

        if config.val.prompt.filebrowser:
            self._vbox.addWidget(self._file_view)
        else:
            self._file_view.hide()

        # Only show name
        self._file_view.setHeaderHidden(True)
        for col in range(1, 4):
            self._file_view.setColumnHidden(col, True)
        # Nothing selected initially
        self._file_view.setCurrentIndex(QModelIndex())
        # The model needs to be sorted so we get the correct first/last index
        self._file_model.directoryLoaded.connect(
            lambda: self._file_model.sort(0))

    def accept(self, value=None):
        text = value if value is not None else self._lineedit.text()
        text = downloads.transform_path(text)
        if text is None:
            message.error("Invalid filename")
            return False
        self.question.answer = text
        return True

    def item_focus(self, which):
        # This duplicates some completion code, but I don't see a nicer way...
        assert which in ['prev', 'next'], which
        selmodel = self._file_view.selectionModel()

        parent = self._file_view.rootIndex()
        first_index = self._file_model.index(0, 0, parent)
        row = self._file_model.rowCount(parent) - 1
        last_index = self._file_model.index(row, 0, parent)

        if not first_index.isValid():
            # No entries
            return

        assert last_index.isValid()

        idx = selmodel.currentIndex()

        if not idx.isValid():
            # No item selected yet
            idx = last_index if which == 'prev' else first_index
        elif which == 'prev':
            idx = self._file_view.indexAbove(idx)
        else:
            assert which == 'next', which
            idx = self._file_view.indexBelow(idx)

        # wrap around if we arrived at beginning/end
        if not idx.isValid():
            idx = last_index if which == 'prev' else first_index

        idx = self._do_completion(idx, which)

        selmodel.setCurrentIndex(
            idx, QItemSelectionModel.ClearAndSelect | QItemSelectionModel.Rows)
        self._insert_path(idx, clicked=False)

    def _do_completion(self, idx, which):
        filename = self._file_model.fileName(idx)
        while not filename.startswith(self._to_complete) and idx.isValid():
            if which == 'prev':
                idx = self._file_view.indexAbove(idx)
            else:
                assert which == 'next', which
                idx = self._file_view.indexBelow(idx)
            filename = self._file_model.fileName(idx)

        return idx

    def _allowed_commands(self):
        return [('prompt-accept', 'Accept'), ('leave-mode', 'Abort')]
Exemplo n.º 40
0
Arquivo: gui.py Projeto: minkione/pbtk
    def __init__(self):
        super().__init__(argv)
        signal(SIGINT, SIG_DFL)

        views = dirname(realpath(__file__)) + '/views/'

        self.welcome = loadUi(views + 'welcome.ui')
        self.choose_extractor = loadUi(views + 'choose_extractor.ui')
        self.choose_proto = loadUi(views + 'choose_proto.ui')
        self.create_endpoint = loadUi(views + 'create_endpoint.ui')
        self.choose_endpoint = loadUi(views + 'choose_endpoint.ui')
        self.fuzzer = loadUi(views + 'fuzzer.ui')

        self.welcome.step1.clicked.connect(self.load_extractors)
        self.choose_extractor.rejected.connect(
            partial(self.set_view, self.welcome))
        self.choose_extractor.extractors.itemClicked.connect(
            self.prompt_extractor)

        self.welcome.step2.clicked.connect(self.load_protos)
        self.proto_fs = QFileSystemModel()
        self.choose_proto.protos.setModel(self.proto_fs)
        self.proto_fs.directoryLoaded.connect(
            self.choose_proto.protos.expandAll)

        for i in range(1, self.proto_fs.columnCount()):
            self.choose_proto.protos.hideColumn(i)
        self.choose_proto.protos.setRootIndex(
            self.proto_fs.index(str(BASE_PATH / 'protos')))
        self.choose_proto.rejected.connect(partial(self.set_view,
                                                   self.welcome))
        self.choose_proto.protos.clicked.connect(self.new_endpoint)

        self.create_endpoint.transports.itemClicked.connect(
            self.pick_transport)
        self.create_endpoint.loadRespPbBtn.clicked.connect(
            self.load_another_pb)
        self.create_endpoint.rejected.connect(
            partial(self.set_view, self.choose_proto))
        self.create_endpoint.buttonBox.accepted.connect(self.write_endpoint)

        self.welcome.step3.clicked.connect(self.load_endpoints)
        self.choose_endpoint.rejected.connect(
            partial(self.set_view, self.welcome))
        self.choose_endpoint.endpoints.itemClicked.connect(self.launch_fuzzer)

        self.fuzzer.rejected.connect(
            partial(self.set_view, self.choose_endpoint))
        self.fuzzer.fuzzFields.clicked.connect(self.fuzz_endpoint)
        self.fuzzer.deleteThis.clicked.connect(self.delete_endpoint)
        self.fuzzer.comboBox.activated.connect(self.launch_fuzzer)

        self.fuzzer.urlField.setWordWrapMode(QTextOption.WrapAnywhere)

        for tree in (self.fuzzer.pbTree, self.fuzzer.getTree):
            tree.itemEntered.connect(lambda item, _: item.edit()
                                     if hasattr(item, 'edit') else None)
            tree.itemClicked.connect(
                lambda item, col: item.update_check(col=col))
            tree.header().setSectionResizeMode(QHeaderView.ResizeToContents)

        self.welcome.mydirLabel.setText(self.welcome.mydirLabel.text() %
                                        BASE_PATH)
        self.welcome.mydirBtn.clicked.connect(
            partial(QDesktopServices.openUrl,
                    QUrl.fromLocalFile(str(BASE_PATH))))

        self.set_view(self.welcome)
        self.exec_()
Exemplo n.º 41
0
class MainWindow(QMainWindow, form_class):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        self.image = None
        self.set_tree_view()
        self.set_radio_button()

    def set_tree_view(self):
        self.root_path = '../'

        self.file_system_model = QFileSystemModel()
        self.tree_view.setModel(self.file_system_model)
        self.file_system_model.setRootPath(self.root_path)
        self.tree_view.setRootIndex(
            self.file_system_model.index(self.root_path))
        self.tree_view.setColumnWidth(0, 200)

        self.tree_view.setColumnHidden(1, True)
        self.tree_view.setColumnHidden(2, True)
        self.tree_view.setColumnHidden(3, True)

        self.tree_view.doubleClicked.connect(self.tree_view_double_clicked)

    def tree_view_double_clicked(self, index):
        if self.file_system_model.isDir(index):
            # print('Directory')
            pass
        else:
            path = self.file_system_model.filePath(index)
            self.image = cv2.imread(path)
            self.image_processing()

    def set_radio_button(self):
        self.radio_rgb.clicked.connect(self.image_processing)
        self.radio_gray.clicked.connect(self.image_processing)
        self.radio_bin.clicked.connect(self.image_processing)

    def image_processing(self):
        if self.image is None:
            return

        if self.radio_rgb.isChecked():
            processed = self.image
        elif self.radio_gray.isChecked():
            processed = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
        else:
            gray = cv2.cvtColor(self.image, cv2.COLOR_BGR2GRAY)
            processed = (gray > 128).astype(np.uint8) * 255

        if len(processed.shape) == 2:
            show_image = QtGui.QImage(processed, processed.shape[1],
                                      processed.shape[0], processed.shape[1],
                                      QtGui.QImage.Format_Grayscale8)
        else:
            show_image = QtGui.QImage(processed, processed.shape[1],
                                      processed.shape[0],
                                      processed.shape[1] * 3,
                                      QtGui.QImage.Format_BGR888)
        self.label_image.setPixmap(QtGui.QPixmap(show_image))
Exemplo n.º 42
0
class FileTree(QWidget):

    def __init__(self, filter=['*.czi'], defaultfolder=r'c:\Zen_Output'):
        super(QWidget, self).__init__()

        # define filter to allowed file extensions
        #filter = ['*.czi', '*.ome.tiff', '*ome.tif' '*.tiff' '*.tif']

        # define the style for the FileTree via s style sheet
        self.setStyleSheet("""
                     QTreeView:: item {
                         background - color: rgb(38, 41, 48)
                         font - weight: bold
                     }

                     QTreeView:: item: : selected {
                         background - color: rgb(38, 41, 48)
                         color: rgb(0, 255, 0)
                     }

                     QTreeView QHeaderView: section {
                         background - color: rgb(38, 41, 48)
                         color: rgb(255, 255, 255)
                     }
                     """)

        self.model = QFileSystemModel()
        self.model.setRootPath(defaultfolder)
        self.model.setFilter(QtCore.QDir.AllDirs | QDir.Files | QtCore.QDir.NoDotAndDotDot)
        self.model.setNameFilterDisables(False)
        self.model.setNameFilters(filter)

        self.tree = QTreeView()
        self.tree.setModel(self.model)
        self.tree.setRootIndex(self.model.index(defaultfolder))
        self.tree.setAnimated(True)
        self.tree.setIndentation(20)
        self.tree.setSortingEnabled(False)
        header = self.tree.header()
        header.setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)

        windowLayout = QVBoxLayout()
        windowLayout.addWidget(self.tree)
        self.setLayout(windowLayout)

        self.tree.clicked.connect(self.on_treeView_clicked)

    def on_treeView_clicked(self, index):
        indexItem = self.model.index(index.row(), 0, index.parent())
        filename = self.model.fileName(indexItem)
        filepath = self.model.filePath(indexItem)

        # open the file when clicked
        print('Opening ImageFile : ', filepath)
        open_image_stack(filepath)
class App(QMainWindow, QWidget):  # 창의 대부분의 기능
    def __init__(self):  # 창 기본 세팅 설정
        super().__init__()

        # Window options!
        self.title = 'HexQT'
        self.left = 0
        self.top = 0
        self.width = 1280
        self.height = 840

        self.rowSpacing = 4  # How many bytes before a double space.
        self.rowLength = 16  # 헥사 창에 얼마나 많은 byte 가 들어갈 것인지
        self.byteWidth = 4  # How many bits to include in a byte.
        self.mode = Mode.READ

        self.initUI()

    def openFile(self):
        fileSelect = FileSelector()
        fileName = fileSelect.fileName

        self.readFile(fileName)

    # readFile ... Reads file data from a file in the form of bytes and generates the text for the hex-editor.
    def readFile(self, fileName):
        fileData = ''
        if fileName:
            with open(fileName, 'rb') as fileObj:
                fileData = fileObj.read()
                self.generateView(fileData)
        # saveFile ... Method for saving the edited hex file.

    def saveFile(self):
        print('Saved!')

    # generateView ... Generates text view for hexdump likedness.
    def generateView(self, text):
        space = ' '
        bigSpace = ' ' * 4

        rowSpacing = self.rowSpacing
        rowLength = self.rowLength

        offset = 0

        offsetText = ''
        mainText = ''
        asciiText = ''

        for chars in range(1, len(text) + 1):
            byte = text[chars - 1]
            char = chr(text[chars - 1])

            # Asciitext 는 오른쪽 출력부
            if char is ' ':
                asciiText += '.'

            elif char is '\n':
                asciiText += '!'

            else:
                asciiText += char
            # main text 가 중앙에 있는것
            mainText += format(byte, '0' + str(self.byteWidth) + 'x')

            if chars % rowLength is 0:
                offsetText += format(offset, '08x') + '\n'
                mainText += '\n'
                asciiText += '\n'

            elif chars % rowSpacing is 0:
                mainText += space * 2

            else:
                mainText += space

            offset += len(char)

        self.offsetTextArea.setText(offsetText)
        self.mainTextArea.setText(mainText)
        self.asciiTextArea.setText(asciiText)

    # openFile ... Opens a file directory and returns the filename.

    # highlightMain ... Bi-directional highlighting from main.
    def highlightMain(self):
        # Create and get cursors for getting and setting selections.
        highlightCursor = QTextCursor(self.asciiTextArea.document())
        # asciitextArea의 처음을 가르치는 커서를 구성
        cursor = self.mainTextArea.textCursor()
        # 커서의 위치의 사본을 따서 복사 함
        # Clear any current selections and reset text color.
        highlightCursor.select(QTextCursor.Document)
        highlightCursor.setCharFormat(QTextCharFormat())
        highlightCursor.clearSelection()

        # Information about where selections and rows start.
        selectedText = cursor.selectedText()  # The actual text selected.
        selectionStart = cursor.selectionStart()
        selectionEnd = cursor.selectionEnd()

        mainText = self.mainTextArea.toPlainText().replace('\n', 'A')
        #mainText = self.mainTextArea.toPlainText()

        totalBytes = 0

        for char in mainText[selectionStart:selectionEnd]:
            if char is not ' ':
                totalBytes += len(char)

        asciiStart = 0

        for char in mainText[:selectionStart]:
            if char is not ' ':
                asciiStart += len(char)

        totalBytes = round(totalBytes / self.byteWidth)
        asciiStart = round(asciiStart / self.byteWidth)
        asciiEnd = asciiStart + totalBytes

        asciiText = self.asciiTextArea.toPlainText()

        # Select text and highlight it.
        highlightCursor.setPosition(asciiStart, QTextCursor.MoveAnchor)
        highlightCursor.setPosition(asciiEnd, QTextCursor.KeepAnchor)

        highlight = QTextCharFormat()
        highlight.setBackground(Qt.darkCyan)
        highlightCursor.setCharFormat(highlight)
        highlightCursor.clearSelection()

    # highlightAscii ... Bi-directional highlighting from ascii.
    def highlightAscii(self):
        selectedText = self.asciiTextArea.textCursor().selectedText()

    # offsetJump ... Creates a dialogue and gets the offset to jump to and then jumps to that offset.

    def offsetJump(self):  # input dialog 를 활용 하여 jump to ofsset 을 만듭니다.
        jumpText = InputDialogue('Jump to Offset', 'Offset').dialogueReponse
        jumpOffset = 0xF

        mainText = self.mainTextArea.toPlainText()
        mainText = mainText.strip().replace('  ', ' ')

        textCursor = self.mainTextArea.textCursor()

    # createMainView ... Creates the primary view and look of the application (3-text areas.)

    def createMainView(self):
        qhBox = QHBoxLayout()
        qhBox2 = QHBoxLayout()
        qvBox = QVBoxLayout()

        self.dirModel = QFileSystemModel()
        self.dirModel.setRootPath('')
        self.fileModel = QFileSystemModel()
        self.tree = QTreeView()
        self.list = QListView()
        self.tree.setModel(self.dirModel)
        self.list.setModel(self.fileModel)

        self.tree.clicked.connect(self.tree_on_clicked)
        self.list.clicked.connect(self.list_on_clicked)

        self.mainTextArea = QTextEdit()
        self.offsetTextArea = QTextEdit()
        self.asciiTextArea = QTextEdit()

        # Initialize them all to read only.
        self.mainTextArea.setReadOnly(True)
        self.asciiTextArea.setReadOnly(True)
        self.offsetTextArea.setReadOnly(True)

        # Create the fonts and styles to be used and then apply them.
        font = QFont("DejaVu Sans Mono", 11, QFont.Normal, True)

        self.mainTextArea.setFont(font)
        self.asciiTextArea.setFont(font)
        self.offsetTextArea.setFont(font)

        #self.offsetTextArea.setTextColor(Qt.red)

        # Syncing scrolls.
        syncScrolls(self.mainTextArea, self.asciiTextArea, self.offsetTextArea)

        # Highlight linking. BUG-GY
        self.mainTextArea.selectionChanged.connect(self.highlightMain)
        self.asciiTextArea.selectionChanged.connect(self.highlightAscii)

        qhBox.addWidget(self.offsetTextArea, 1)
        qhBox.addWidget(self.mainTextArea, 6)
        qhBox.addWidget(self.asciiTextArea, 2)
        qhBox2.addWidget(self.tree)
        qhBox2.addWidget(self.list)
        qvBox.addLayout(qhBox2)
        qvBox.addLayout(qhBox)
        return qvBox

    def tree_on_clicked(self, index):
        path = self.dirModel.fileInfo(index).absoluteFilePath()
        self.list.setRootIndex(self.fileModel.setRootPath(path))

    def list_on_clicked(self, index):
        path = self.fileModel.fileInfo(index).absoluteFilePath()
        #self.openbyList(self,path)
        self.readFile(path)

    # initUI ... Initializes the min look of the application.
    def initUI(self):
        # Initialize basic window options.
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        # Center the window.
        qtRectangle = self.frameGeometry()
        centerPoint = QDesktopWidget().availableGeometry().center()
        qtRectangle.moveCenter(centerPoint)
        self.move(qtRectangle.topLeft())

        # Creates a menu bar, (file, edit, options, etc...)
        mainMenu = self.menuBar()

        # Menus for window.
        fileMenu = mainMenu.addMenu('File')
        editMenu = mainMenu.addMenu('Edit')
        viewMenu = mainMenu.addMenu('View')
        helpMenu = mainMenu.addMenu('Help')

        # FILE MENU ---------------------------------------

        # Open button.
        openButton = QAction(QIcon(), 'Open', self)
        openButton.setShortcut('Ctrl+O')
        openButton.setStatusTip('Open file')
        openButton.triggered.connect(self.openFile)

        # Save button.
        saveButton = QAction(QIcon(), 'Save', self)
        saveButton.setShortcut('Ctrl+S')
        saveButton.setStatusTip('Open file')
        saveButton.triggered.connect(self.saveFile)

        # Optional exit stuff.
        exitButton = QAction(QIcon(), 'Exit', self)
        exitButton.setShortcut('Ctrl+Q')
        exitButton.setStatusTip('Exit application')
        exitButton.triggered.connect(self.close)

        fileMenu.addAction(openButton)
        fileMenu.addAction(saveButton)
        fileMenu.addAction(exitButton)

        # EDIT MENU ---------------------------------------

        # Jump to Offset
        offsetButton = QAction(QIcon(), 'Jump to Offset', self)
        offsetButton.setShortcut('Ctrl+J')
        offsetButton.setStatusTip('Jump to Offset')
        offsetButton.triggered.connect(self.offsetJump)

        editMenu.addAction(offsetButton)

        # Creating a widget for the central widget thingy.
        centralWidget = QWidget()
        centralWidget.setLayout(self.createMainView())

        self.setCentralWidget(centralWidget)

        # Show our masterpiece.
        self.show()
Exemplo n.º 44
0
    def load_tree(self, project):
        """Load the tree view on the right based on the project selected."""
        qfsm = QFileSystemModel()
        qfsm.setRootPath(project.path)
        load_index = qfsm.index(qfsm.rootPath())
        qfsm.setFilter(QDir.AllDirs | QDir.NoDotAndDotDot)
        qfsm.setNameFilterDisables(False)
        pext = ["*{0}".format(x) for x in project.extensions]
        qfsm.setNameFilters(pext)

        self._tree.setModel(qfsm)
        self._tree.setRootIndex(load_index)

        t_header = self._tree.header()
        t_header.setHorizontalScrollMode(QAbstractItemView.ScrollPerPixel)
        t_header.setSectionResizeMode(0, QHeaderView.Stretch)
        t_header.setStretchLastSection(False)
        t_header.setClickable(True)

        self._tree.hideColumn(1)  # Size
        self._tree.hideColumn(2)  # Type
        self._tree.hideColumn(3)  # Modification date
Exemplo n.º 45
0
    def __init__(self, parent):
        QWidget.__init__(self)
        self.parent = parent
        self.name = 'File Manager'
        self.port = '9080'
        self.server = None

        drives = win32api.GetLogicalDriveStrings().split('\\\000')[:-1]
        self.logical_drives = drives + [d+'/' for d in drives]
        # create file manager tab
        self.file_manager_layout = QGridLayout(self)

        # create left manager (PC)
        self.left_up_btn = QPushButton()
        self.left_up_btn.setIcon(QIcon('images/up_btn.png'))
        self.left_up_btn.setFixedWidth(25)
        self.file_manager_layout.addWidget(self.left_up_btn, 0, 0, 1, 1)

        self.left_dir_path = QLineEdit(self.parent.expanduser_dir)
        self.file_manager_layout.addWidget(self.left_dir_path, 0, 1, 1, 8)

        self.left_go_to_btn = QPushButton()
        self.left_go_to_btn.setIcon(QIcon('images/right_btn.png'))
        self.left_go_to_btn.setFixedWidth(25)
        self.file_manager_layout.addWidget(self.left_go_to_btn, 0, 9, 1, 1)

        self.lefttableview = QTableView()
        self.lefttableview.setSelectionBehavior(QTableView.SelectRows)
        self.lefttableview.verticalHeader().hide()
        self.lefttableview.setShowGrid(False)
        self.lefttableview.contextMenuEvent = lambda event: self.left_context(event)

        self.left_file_model = QFileSystemModel()
        self.left_file_model.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.left_file_model.setRootPath(self.parent.expanduser_dir)
        self.left_file_model_path = self.parent.expanduser_dir
        self.lefttableview.setModel(self.left_file_model)
        self.lefttableview.setColumnWidth(0, 150)
        self.lefttableview.setRootIndex(self.left_file_model.index(self.parent.expanduser_dir))
        self.file_manager_layout.addWidget(self.lefttableview, 1, 0, 5, 10)

        # central buttons
        self.download_file_from_device_btn = QPushButton()
        self.download_file_from_device_btn.setIcon(QIcon('images/left_btn.png'))
        self.download_file_from_device_btn.setFixedWidth(30)
        self.download_file_from_device_btn.setEnabled(False)
        self.upload_file_to_device_btn = QPushButton()
        self.upload_file_to_device_btn.setIcon(QIcon('images/right_btn.png'))
        self.upload_file_to_device_btn.setFixedWidth(30)
        self.upload_file_to_device_btn.setEnabled(False)
        self.delete_file_btn = QPushButton()
        self.delete_file_btn.setIcon(QIcon('images/delete_btn.png'))
        self.delete_file_btn.setFixedWidth(30)
        self.file_manager_layout.addWidget(self.download_file_from_device_btn, 3, 10, 1, 1)
        self.file_manager_layout.addWidget(self.delete_file_btn, 4, 10, 1, 1)

        # create right manager (Device)
        self.right_up_btn = QPushButton()
        self.right_up_btn.setIcon(QIcon('images/up_btn.png'))
        self.right_up_btn.setFixedWidth(25)
        self.right_up_btn.setEnabled(False)
        self.file_manager_layout.addWidget(self.right_up_btn, 0, 11, 1, 1)

        self.add_folder_btn = QPushButton()
        self.add_folder_btn.setIcon(QIcon('images/folder_add.png'))
        self.add_folder_btn.setFixedWidth(25)
        self.add_folder_btn.setToolTip(_('Add new folder'))
        self.add_folder_btn.setEnabled(False)
        self.file_manager_layout.addWidget(self.add_folder_btn, 0, 12, 1, 1)

        self.right_dir_path = QLineEdit()
        self.file_manager_layout.addWidget(self.right_dir_path, 0, 13, 1, 7)

        self.right_update_btn = QPushButton()
        self.right_update_btn.setIcon(QIcon('images/update.png'))
        self.right_update_btn.setFixedWidth(25)
        self.file_manager_layout.addWidget(self.right_update_btn, 0, 20, 1, 1)

        self.righttableview = QTableView()
        self.righttableview.setSelectionBehavior(QTableView.SelectRows)
        self.righttableview.contextMenuEvent = lambda event: self.right_context(event)
        self.righttableview.verticalHeader().hide()
        self.righttableview.setShowGrid(False)
        self.right_file_model = QStandardItemModel()
        self.right_file_model_path = []
        self.right_active_dir = None
        self.righttableview.setModel(self.right_file_model)
        self.file_manager_layout.addWidget(self.righttableview, 1, 11, 5, 10)

        # auto sync
        self.timer = QTimer()
        self.timer.setInterval(10000)
        self.file_models_auto_sync = QCheckBox(_('Auto sync'))
        self.left_file_model_auto_sync_label = QLineEdit()
        self.left_file_model_auto_sync_label.setReadOnly(True)
        self.right_file_model_auto_sync_label = QLineEdit()
        self.right_file_model_auto_sync_label.setReadOnly(True)
        self.file_manager_layout.addWidget(self.file_models_auto_sync, 6, 9, 1, 3, alignment=Qt.AlignCenter)
        self.file_manager_layout.addWidget(self.left_file_model_auto_sync_label, 6, 0, 1, 9)
        self.file_manager_layout.addWidget(self.right_file_model_auto_sync_label, 6, 12, 1, 9)

        self.timer.timeout.connect(lambda: self.check_device_sync())
        self.lefttableview.clicked.connect(lambda idx: self.left_file_model_clicked(idx))
        self.lefttableview.doubleClicked.connect(lambda idx: self.left_file_model_doubleclicked(idx))
        self.left_up_btn.clicked.connect(lambda: self.left_file_model_up(self.left_file_model.index(self.left_dir_path.text())))
        self.left_go_to_btn.clicked.connect(lambda: self.left_file_model_go_to_dir())

        self.right_update_btn.clicked.connect(lambda: self.right_file_model_update())
        self.righttableview.doubleClicked.connect(lambda idx: self.right_file_model_doubleclicked(idx))
        self.right_up_btn.clicked.connect(lambda: self.right_file_model_up())
        self.add_folder_btn.clicked.connect(lambda: self.right_file_model_add_folder())
        self.righttableview.clicked.connect(lambda idx: self.right_file_model_clicked(idx))
        self.download_file_from_device_btn.clicked.connect(lambda: self.download_file_from_device())
        self.upload_file_to_device_btn.clicked.connect(lambda: self.upload_file_to_device())
        self.delete_file_btn.clicked.connect(lambda: self.delete_file_from_file_model())

        self.parent.settings_widget.signal_ip_changed.connect(lambda ip: self.change_ip(ip))

        self.parent.signal_language_changed.connect(lambda: self.retranslate())
Exemplo n.º 46
0
class FileManager(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(FileManager, self).__init__(parent)
        self.title = 'PyQt5 file system view - pythonspot.com'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self.default_path = (os.path.join(os.path.expanduser('~'),
                                          'linuxcnc/nc_files/examples'))
        self.user_path = (os.path.join('/media'))
        self.currentPath = None
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files)
        self.model.setNameFilterDisables(False)
        self.model.setNameFilters(["*.ngc", '*.py'])

        self.list = QListView()
        self.list.setModel(self.model)
        self.updateDirectoryView(self.default_path)
        self.list.setWindowTitle("Dir View")
        self.list.resize(640, 480)
        self.list.clicked[QModelIndex].connect(self.clicked)
        self.list.activated.connect(self.load)
        self.list.setAlternatingRowColors(True)

        self.cb = QComboBox()
        self.cb.currentTextChanged.connect(self.filterChanged)
        self.cb.addItems(sorted({'*.ngc', '*.py', '*'}))
        #self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))

        self.button = QPushButton()
        self.button.setText('Media')
        self.button.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button.setToolTip('Jump to Media directory')
        self.button.clicked.connect(self.onMediaClicked)

        self.button2 = QPushButton()
        self.button2.setText('User')
        self.button2.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button2.setToolTip('Jump to linuxcnc directory')
        self.button2.clicked.connect(self.onUserClicked)

        hbox = QHBoxLayout()
        hbox.addWidget(self.button)
        hbox.addWidget(self.button2)
        hbox.addWidget(self.cb)

        windowLayout = QVBoxLayout()
        windowLayout.addWidget(self.list)
        windowLayout.addLayout(hbox)
        self.setLayout(windowLayout)
        self.show()

    def updateDirectoryView(self, path):
        self.list.setRootIndex(self.model.setRootPath(path))

    def filterChanged(self, text):
        self.model.setNameFilters([text])

    def clicked(self, index):
        # the signal passes the index of the clicked item
        dir_path = self.model.filePath(index)
        if self.model.fileInfo(index).isFile():
            self.currentPath = dir_path
            return
        root_index = self.model.setRootPath(dir_path)
        self.list.setRootIndex(root_index)

    def onMediaClicked(self):
        self.updateDirectoryView(self.user_path)

    def onUserClicked(self):
        self.updateDirectoryView(self.default_path)

    def select_row(self, style):
        style = style.lower()
        selectionModel = self.list.selectionModel()
        row = selectionModel.currentIndex().row()
        self.rows = self.model.rowCount(self.list.rootIndex())

        if style == 'last':
            row = self.rows
        elif style == 'up':
            if row > 0:
                row -= 1
            else:
                row = 0
        elif style == 'down':
            if row < self.rows:
                row += 1
            else:
                row = self.rows
        else:
            return
        top = self.model.index(row, 0, self.list.rootIndex())
        selectionModel.setCurrentIndex(
            top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    def _hal_init(self):
        if self.PREFS_:
            last_path = self.PREFS_.getpref('last_loaded_directory',
                                            self.default_path, str,
                                            'BOOK_KEEPING')
            self.updateDirectoryView(last_path)
            LOG.debug("lAST FILE PATH: {}".format(last_path))
        else:
            LOG.debug("lAST FILE PATH: {}".format(self.default_path))
            self.updateDirectoryView(self.default_path)

    # get current selection and update the path
    # then if the path is good load it into linuxcnc
    # record it in the preference file if available
    def load(self):
        row = self.list.selectionModel().currentIndex()
        self.clicked(row)

        fname = self.currentPath
        if fname is None:
            return
        if fname:
            if self.PREFS_:
                self.PREFS_.putpref('last_loaded_directory',
                                    self.model.rootPath(), str, 'BOOK_KEEPING')
                self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING')
            ACTION.OPEN_PROGRAM(fname)
            STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME')

    def up(self):
        self.select_row('up')

    def down(self):
        self.select_row('down')
Exemplo n.º 47
0
class FileChooser(QWidget):
    fileOpened = pyqtSignal(str)

    def __init__(self, parent=None):
        super().__init__(parent)
        # TODO: migrate to FolderComboBox?
        self.folderBox = QComboBox(self)
        self.explorerTree = FileTreeView(self)
        self.explorerTree.doubleClickCallback = self._fileOpened
        self.explorerModel = QFileSystemModel(self)
        self.explorerModel.setFilter(
            QDir.AllDirs | QDir.Files | QDir.NoDotAndDotDot)
        self.explorerModel.setNameFilters(["*.py"])
        self.explorerModel.setNameFilterDisables(False)
        self.explorerTree.setModel(self.explorerModel)
        for index in range(1, self.explorerModel.columnCount()):
            self.explorerTree.hideColumn(index)
        self.setCurrentFolder()
        self.folderBox.currentIndexChanged[int].connect(
            self.updateCurrentFolder)

        layout = QVBoxLayout(self)
        layout.addWidget(self.folderBox)
        layout.addWidget(self.explorerTree)
        layout.setContentsMargins(5, 5, 0, 0)

    def _fileOpened(self, modelIndex):
        path = self.explorerModel.filePath(modelIndex)
        if os.path.isfile(path):
            self.fileOpened.emit(path)

    def currentFolder(self):
        return self.explorerModel.rootPath()

    def setCurrentFolder(self, path=None):
        if path is None:
            app = QApplication.instance()
            path = app.getScriptsDirectory()
        else:
            assert os.path.isdir(path)
        self.explorerModel.setRootPath(path)
        self.explorerTree.setRootIndex(self.explorerModel.index(path))
        self.folderBox.blockSignals(True)
        self.folderBox.clear()
        style = self.style()
        dirIcon = style.standardIcon(style.SP_DirIcon)
        self.folderBox.addItem(dirIcon, os.path.basename(path))
        self.folderBox.insertSeparator(1)
        self.folderBox.addItem(self.tr("Browse…"))
        self.folderBox.setCurrentIndex(0)
        self.folderBox.blockSignals(False)

    def updateCurrentFolder(self, index):
        if index < self.folderBox.count() - 1:
            return
        path = QFileDialog.getExistingDirectory(
            self, self.tr("Choose Directory"), self.currentFolder(),
            QFileDialog.ShowDirsOnly)
        if path:
            QSettings().setValue("scripting/path", path)
            self.setCurrentFolder(path)
Exemplo n.º 48
0
class AssetBrowser(QMainWindow, Ui_MainWindow):
    asset_clicked = pyqtSignal(str, str, name='assetClicked')

    def __init__(self):
        super(AssetBrowser, self).__init__()
        self.setupUi(self)

        self.dir_model = QFileSystemModel()
        self.dir_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)
        self.dir_model.setReadOnly(False)

        self.dir_view.setModel(self.dir_model)
        self.dir_view.hideColumn(1)
        self.dir_view.hideColumn(2)
        self.dir_view.hideColumn(3)

        self.file_model = QFileSystemModel()
        self.file_model.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.file_model.setReadOnly(False)

        self.file_view.setModel(self.file_model)

    def open_project(self, project_dir):
        path = os.path.join(project_dir)

        self.dir_model.setRootPath(path)
        self.file_model.setRootPath(path)

        self.dir_view.setRootIndex(self.dir_model.index(path))
        self.file_view.setRootIndex(self.file_model.index(path))

    def dir_clicked(self, idx):
        path = self.dir_model.fileInfo(idx).absoluteFilePath()

        self.file_view.setRootIndex(self.file_model.setRootPath(path))

    def file_doubleclicked(self, idx):
        fileinfo = self.file_model.fileInfo(idx)

        path = fileinfo.absoluteFilePath()
        ext = fileinfo.suffix()

        self.asset_clicked.emit(path, ext)
Exemplo n.º 49
0
class FileManager(QWidget):
    def __init__(self, parent):
        QWidget.__init__(self)
        self.parent = parent
        self.name = 'File Manager'
        self.port = '9080'
        self.server = None

        drives = win32api.GetLogicalDriveStrings().split('\\\000')[:-1]
        self.logical_drives = drives + [d+'/' for d in drives]
        # create file manager tab
        self.file_manager_layout = QGridLayout(self)

        # create left manager (PC)
        self.left_up_btn = QPushButton()
        self.left_up_btn.setIcon(QIcon('images/up_btn.png'))
        self.left_up_btn.setFixedWidth(25)
        self.file_manager_layout.addWidget(self.left_up_btn, 0, 0, 1, 1)

        self.left_dir_path = QLineEdit(self.parent.expanduser_dir)
        self.file_manager_layout.addWidget(self.left_dir_path, 0, 1, 1, 8)

        self.left_go_to_btn = QPushButton()
        self.left_go_to_btn.setIcon(QIcon('images/right_btn.png'))
        self.left_go_to_btn.setFixedWidth(25)
        self.file_manager_layout.addWidget(self.left_go_to_btn, 0, 9, 1, 1)

        self.lefttableview = QTableView()
        self.lefttableview.setSelectionBehavior(QTableView.SelectRows)
        self.lefttableview.verticalHeader().hide()
        self.lefttableview.setShowGrid(False)
        self.lefttableview.contextMenuEvent = lambda event: self.left_context(event)

        self.left_file_model = QFileSystemModel()
        self.left_file_model.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
        self.left_file_model.setRootPath(self.parent.expanduser_dir)
        self.left_file_model_path = self.parent.expanduser_dir
        self.lefttableview.setModel(self.left_file_model)
        self.lefttableview.setColumnWidth(0, 150)
        self.lefttableview.setRootIndex(self.left_file_model.index(self.parent.expanduser_dir))
        self.file_manager_layout.addWidget(self.lefttableview, 1, 0, 5, 10)

        # central buttons
        self.download_file_from_device_btn = QPushButton()
        self.download_file_from_device_btn.setIcon(QIcon('images/left_btn.png'))
        self.download_file_from_device_btn.setFixedWidth(30)
        self.download_file_from_device_btn.setEnabled(False)
        self.upload_file_to_device_btn = QPushButton()
        self.upload_file_to_device_btn.setIcon(QIcon('images/right_btn.png'))
        self.upload_file_to_device_btn.setFixedWidth(30)
        self.upload_file_to_device_btn.setEnabled(False)
        self.delete_file_btn = QPushButton()
        self.delete_file_btn.setIcon(QIcon('images/delete_btn.png'))
        self.delete_file_btn.setFixedWidth(30)
        self.file_manager_layout.addWidget(self.download_file_from_device_btn, 3, 10, 1, 1)
        self.file_manager_layout.addWidget(self.delete_file_btn, 4, 10, 1, 1)

        # create right manager (Device)
        self.right_up_btn = QPushButton()
        self.right_up_btn.setIcon(QIcon('images/up_btn.png'))
        self.right_up_btn.setFixedWidth(25)
        self.right_up_btn.setEnabled(False)
        self.file_manager_layout.addWidget(self.right_up_btn, 0, 11, 1, 1)

        self.add_folder_btn = QPushButton()
        self.add_folder_btn.setIcon(QIcon('images/folder_add.png'))
        self.add_folder_btn.setFixedWidth(25)
        self.add_folder_btn.setToolTip(_('Add new folder'))
        self.add_folder_btn.setEnabled(False)
        self.file_manager_layout.addWidget(self.add_folder_btn, 0, 12, 1, 1)

        self.right_dir_path = QLineEdit()
        self.file_manager_layout.addWidget(self.right_dir_path, 0, 13, 1, 7)

        self.right_update_btn = QPushButton()
        self.right_update_btn.setIcon(QIcon('images/update.png'))
        self.right_update_btn.setFixedWidth(25)
        self.file_manager_layout.addWidget(self.right_update_btn, 0, 20, 1, 1)

        self.righttableview = QTableView()
        self.righttableview.setSelectionBehavior(QTableView.SelectRows)
        self.righttableview.contextMenuEvent = lambda event: self.right_context(event)
        self.righttableview.verticalHeader().hide()
        self.righttableview.setShowGrid(False)
        self.right_file_model = QStandardItemModel()
        self.right_file_model_path = []
        self.right_active_dir = None
        self.righttableview.setModel(self.right_file_model)
        self.file_manager_layout.addWidget(self.righttableview, 1, 11, 5, 10)

        # auto sync
        self.timer = QTimer()
        self.timer.setInterval(10000)
        self.file_models_auto_sync = QCheckBox(_('Auto sync'))
        self.left_file_model_auto_sync_label = QLineEdit()
        self.left_file_model_auto_sync_label.setReadOnly(True)
        self.right_file_model_auto_sync_label = QLineEdit()
        self.right_file_model_auto_sync_label.setReadOnly(True)
        self.file_manager_layout.addWidget(self.file_models_auto_sync, 6, 9, 1, 3, alignment=Qt.AlignCenter)
        self.file_manager_layout.addWidget(self.left_file_model_auto_sync_label, 6, 0, 1, 9)
        self.file_manager_layout.addWidget(self.right_file_model_auto_sync_label, 6, 12, 1, 9)

        self.timer.timeout.connect(lambda: self.check_device_sync())
        self.lefttableview.clicked.connect(lambda idx: self.left_file_model_clicked(idx))
        self.lefttableview.doubleClicked.connect(lambda idx: self.left_file_model_doubleclicked(idx))
        self.left_up_btn.clicked.connect(lambda: self.left_file_model_up(self.left_file_model.index(self.left_dir_path.text())))
        self.left_go_to_btn.clicked.connect(lambda: self.left_file_model_go_to_dir())

        self.right_update_btn.clicked.connect(lambda: self.right_file_model_update())
        self.righttableview.doubleClicked.connect(lambda idx: self.right_file_model_doubleclicked(idx))
        self.right_up_btn.clicked.connect(lambda: self.right_file_model_up())
        self.add_folder_btn.clicked.connect(lambda: self.right_file_model_add_folder())
        self.righttableview.clicked.connect(lambda idx: self.right_file_model_clicked(idx))
        self.download_file_from_device_btn.clicked.connect(lambda: self.download_file_from_device())
        self.upload_file_to_device_btn.clicked.connect(lambda: self.upload_file_to_device())
        self.delete_file_btn.clicked.connect(lambda: self.delete_file_from_file_model())

        self.parent.settings_widget.signal_ip_changed.connect(lambda ip: self.change_ip(ip))

        self.parent.signal_language_changed.connect(lambda: self.retranslate())

    def retranslate(self):
        self.file_models_auto_sync.setText(_('Auto sync'))
        self.right_file_model.setHorizontalHeaderLabels([_('Name'), _('Size'), _('Changed date')])

    def change_ip(self, ip):
        self.server = ':'.join([ip, self.port])
        self.right_file_model_path = []
        self.right_file_model.clear()

    def left_file_model_clicked(self, idx):
        if os.path.isfile(self.left_file_model.filePath(idx)) and self.parent.geoshark_widget.device_on_connect:
            self.upload_file_to_device_btn.setEnabled(True)
        else:
            self.upload_file_to_device_btn.setEnabled(False)

    def left_file_model_doubleclicked(self, idx):
        self.left_up_btn.setEnabled(True)
        fileinfo = self.left_file_model.fileInfo(idx)
        if fileinfo.isDir():
            self.lefttableview.setRootIndex(idx)
            self.left_dir_path.setText(self.left_file_model.filePath(idx))
            self.left_file_model_path = self.left_file_model.filePath(idx)

    def left_file_model_up(self, idx):
        self.upload_file_to_device_btn.setEnabled(False)
        if self.left_dir_path.text() in self.logical_drives:
            self.left_file_model = QFileSystemModel()
            self.left_file_model.setFilter(QDir.AllEntries | QDir.NoDotAndDotDot)
            self.left_file_model.setRootPath('')
            self.lefttableview.setModel(self.left_file_model)
            self.left_dir_path.setText('My computer')
            self.left_up_btn.setEnabled(False)
        else:
            fileinfo = self.left_file_model.fileInfo(idx)
            dir = fileinfo.dir()
            self.left_dir_path.setText(dir.path())
            self.left_file_model_path = dir.path()
            self.lefttableview.setRootIndex(self.left_file_model.index(dir.absolutePath()))

    def left_file_model_go_to_dir(self):
        if os.path.isdir(self.left_dir_path.text()):
            self.left_file_model_path = self.left_dir_path.text()
            self.left_up_btn.setEnabled(True)
            self.upload_file_to_device_btn.setEnabled(False)
            self.left_file_model.setRootPath(self.left_dir_path.text())
            self.lefttableview.setRootIndex(self.left_file_model.index(self.left_dir_path.text()))

    def right_file_model_update(self):
        if not self.parent.geoshark_widget.device_on_connect:
            return
        url = 'http://{}/active_dir'.format(self.server)
        try:
            res = requests.get(url, timeout=5)
            if res.ok:
                self.right_active_dir = res.text
        except requests.exceptions.RequestException:
            pass

        file_list = self.get_folder_list()
        if file_list is None:
            return
        self.fill_right_file_model(file_list)
        self.download_file_from_device_btn.setEnabled(False)

    def get_folder_list(self, folder_path=None):
        if self.server is None:
            return
        if folder_path is None:
            folder_path = '/'.join(self.right_file_model_path)
        url = 'http://{}/data/{}'.format(self.server, folder_path)
        try:
            res = requests.get(url, timeout=1)
        except requests.exceptions.RequestException:
            show_error(_('GeoShark error'), _('GeoShark is not responding.'))
            return
        if res.ok:
            res = res.json()
            return res
        else:
            return None

    def check_device_sync(self):
        pc_path = self.left_file_model_auto_sync_label.text()
        device_path = self.right_file_model_auto_sync_label.text()
        if self.file_models_auto_sync.isChecked() and pc_path != '' and device_path != '':
            file_list = self.get_folder_list(self.right_file_model_auto_sync_label.text())
            left_list_of_files = os.listdir(self.left_file_model_auto_sync_label.text())
            for f in file_list:
                if f['name'] not in left_list_of_files or os.path.getsize('{}/{}'.format(pc_path, f['name'])) != f['size']:
                    self.download_file_from_device(device_path='{}/{}'.format(device_path, f['name']),
                                                   pc_path=pc_path)

    def fill_right_file_model(self, directory):
        self.add_folder_btn.setEnabled(True)
        if len(self.right_file_model_path) < 1:
            self.right_up_btn.setEnabled(False)
        else:
            self.right_up_btn.setEnabled(True)
            self.add_folder_btn.setEnabled(False)
        self.right_file_model.removeRows(0, self.right_file_model.rowCount())
        self.right_dir_path.setText('/'.join(self.right_file_model_path))
        self.right_file_model.setHorizontalHeaderLabels([_('Name'), _('Size'), _('Changed date')])
        for row, instance in enumerate(directory):
            if instance['name'] == self.right_active_dir:
                image = QIcon('images/directory_active.png')
            else:
                image = QIcon('images/{}.png'.format(instance['type']))
            item = QStandardItem(image, instance['name'])
            item.setData(instance['type'], 5)
            item.setEditable(False)
            self.right_file_model.setItem(row, 0, item)
            item = QStandardItem(str(instance['size']))
            item.setEditable(False)
            self.right_file_model.setItem(row, 1, item)
            item = QStandardItem(str(datetime.datetime.fromtimestamp(instance['changed']).strftime('%d.%m.%Y %H:%M')))
            item.setEditable(False)
            self.right_file_model.setItem(row, 2, item)

        self.righttableview.setColumnWidth(0, max(150, self.righttableview.columnWidth(0)))

    def left_context(self, event):
        context_menu = {}
        index = self.lefttableview.indexAt(event.pos())
        if index.row() == -1:
            return
        context_menu[_('Set active directory')] = lambda: self.set_pc_active_directory(self.left_file_model.filePath(index))
        context_menu[_('Remove element')] = lambda: self.delete_file_from_file_model(index)

        if not self.left_file_model.isDir(index):
            del context_menu[_('Set active directory')]

        menu = QMenu()

        actions = [QAction(a) for a in context_menu.keys()]
        menu.addActions(actions)
        action = menu.exec_(event.globalPos())
        if action:
            context_menu[action.text()]()

    def set_pc_active_directory(self, path):
        self.left_file_model_auto_sync_label.setText(path)
        self.parent.settings_widget.left_folder_tracked.setText(path)

    def right_context(self, event):
        context_menu = {}

        index = self.righttableview.indexAt(event.pos())
        if index.row() == -1:
            return
        item = self.right_file_model.itemFromIndex(index)
        item_row = item.row()

        context_menu[_('Set active directory')] = lambda: self.set_active_directory(item)
        context_menu[_('Remove element')] = lambda: self.delete_file_from_file_model(index)

        if self.right_file_model.item(item_row, 0).data(5) != 'directory':
            del context_menu[_('Set active directory')]

        menu = QMenu()

        actions = [QAction(a) for a in context_menu.keys()]
        menu.addActions(actions)
        action = menu.exec_(event.globalPos())
        if action:
            context_menu[action.text()]()

    def set_active_directory(self, item):
        if not self.parent.geoshark_widget.device_on_connect:
            return
        dirname = item.text()
        url = 'http://{}/active_dir'.format(self.server)
        try:
            res = requests.post(url=url, data=dirname, timeout=5)
        except requests.exceptions.RequestException:
            show_error(_('GeoShark error'), _('Can not set active directory.\nGeoShark is not responding.'))
            return
        if res.ok:
            self.right_file_model_update()
            self.set_active_path(dirname)
        elif res.status_code == 400:
            show_error(_('GeoShark error'), _('Request declined - request body specifies invalid path.'))
            return
        elif res.status_code == 409:
            show_error(_('GeoShark error'), _('Request declined - switching active directory is forbidden during active session.'))
            return
        else:
            print(res.status_code)
            return

    def set_active_path(self, dirname):
        path = '/'.join(self.right_file_model_path + [dirname])
        self.parent.settings_widget.right_folder_tracked.setText(path)
        self.right_file_model_auto_sync_label.setText(path)

    def right_file_model_clicked(self, idx):
        if not self.parent.geoshark_widget.device_on_connect:
            return
        if self.right_file_model.item(idx.row(), 0).data(5) == 'file':
            self.download_file_from_device_btn.setEnabled(True)
        else:
            self.download_file_from_device_btn.setEnabled(False)

    def right_file_model_doubleclicked(self, idx):
        if not self.parent.geoshark_widget.device_on_connect:
            return
        model_path = '/'.join(self.right_file_model_path)
        idx_name = self.right_file_model.item(idx.row(), 0).text()
        if model_path != '':
            dir = '{}/{}'.format(model_path, idx_name)
        else:
            dir = '{}'.format(idx_name)

        file_list = self.get_folder_list(dir)
        if file_list is None:
            return
        self.right_file_model_path = dir.split('/')
        self.fill_right_file_model(file_list)

    def right_file_model_up(self):
        if not self.parent.geoshark_widget.device_on_connect:
            return
        self.download_file_from_device_btn.setEnabled(False)
        up_dir = '/'.join(self.right_file_model_path[:-1])

        file_list = self.get_folder_list(up_dir)
        if file_list is None:
            return
        if up_dir == '':
            self.right_file_model_path = []
        else:
            self.right_file_model_path = up_dir.split('/')
        self.fill_right_file_model(file_list)

    def right_file_model_add_folder(self):
        if not self.parent.geoshark_widget.device_on_connect:
            return
        row = self.right_file_model.rowCount()
        item = QStandardItem(QIcon('images/folder.png'), 'New Directory')
        item.setData('directory', 5)
        item.setEditable(True)
        self.right_file_model.setItem(row, 0, item)
        item = QStandardItem(str(0.0))
        item.setEditable(False)
        self.right_file_model.setItem(row, 1, item)
        item = QStandardItem(str(datetime.datetime.today().strftime('%d.%m.%Y %H:%M')))
        item.setEditable(False)
        self.right_file_model.setItem(row, 2, item)

    def download_file_from_device(self, device_path=None, pc_path=None):
        if not self.parent.geoshark_widget.device_on_connect or self.server is None:
            return

        if not device_path:
            fileName = self.find_selected_idx()
            if fileName:
                fileName = fileName.data()
                device_path = '/'.join(self.right_file_model_path + [fileName])
            else:
                return

        right_file_model_filename = device_path.split('/')[-1]
        save_to_file = '{}/{}'.format(self.left_file_model_path, right_file_model_filename) \
            if not pc_path else '{}/{}'.format(pc_path, right_file_model_filename)
        if os.path.isfile(save_to_file):
            answer = show_warning_yes_no(_('File warning'), _('There is a file with the same name in PC.\n'
                                         'Do you want to rewrite <b>{}</b>?'.format(right_file_model_filename)))
            if answer == QMessageBox.No:
                return
        url = 'http://{}/data/{}'.format(self.server, device_path)
        try:
            b = bytearray()
            res = requests.get(url, timeout=5, stream=True)
            if res.ok:
                progress = QProgressBar()
                progress.setFormat(right_file_model_filename)
                self.file_manager_layout.addWidget(progress, 6, 12, 1, 9)
                total_length = int(res.headers.get('content-length'))
                len_b = 0
                for chunk in tee_to_bytearray(res, b):
                    len_b += len(chunk)
                    progress.setValue((len_b/total_length)*99)
                    QApplication.processEvents()
            else:
                return
        except:
            self.file_manager_layout.addWidget(self.right_file_model_auto_sync_label, 6, 12, 1, 9)
            show_error(_('GeoShark error'), _('GeoShark is not responding.'))
            return

        if res.ok:
            progress.setValue(100)

            with open(save_to_file, 'wb') as file:
                file.write(b)
        for i in reversed(range(self.file_manager_layout.count())):
            if isinstance(self.file_manager_layout.itemAt(i).widget(), QProgressBar):
                self.file_manager_layout.itemAt(i).widget().setParent(None)
        self.file_manager_layout.addWidget(self.right_file_model_auto_sync_label, 6, 12, 1, 9)

    def upload_file_to_device(self):
        if not self.parent.geoshark_widget.device_on_connect or self.server is None:
            return
        file = self.left_file_model.filePath(self.lefttableview.currentIndex())
        filename = file.split('/')[-1]
        url = 'http://{}/data/{}'.format(self.server, '/'.join(self.right_file_model_path))
        filesize = os.path.getsize(file)
        if filesize == 0:
            show_error(_('File error'), _('File size must be non zero.'))
            return
        progress = ProgressBar(text=_('Upload File Into GeoShark'), window_title=_('Upload file to GeoShark'))
        encoder = MultipartEncoder(
            fields={'upload_file': (filename, open(file, 'rb'))}  # added mime-type here
        )
        data = MultipartEncoderMonitor(encoder, lambda monitor: progress.update((monitor.bytes_read/filesize)*99))

        try:
            res = requests.post(url, data=data, headers={'Content-Type': encoder.content_type}, timeout=5)
        except requests.exceptions.RequestException:
            progress.close()
            show_error(_('GeoShark error'), _('GeoShark is not responding.'))
            return
        if res.ok:
            progress.update(100)
            self.right_file_model_update()

    def delete_file_from_file_model(self, index=None):
        selected = self.find_selected_idx()
        if index is None and selected is None:
            return
        if index is None:
            index = selected
        model = index.model()
        index_row = index.row()
        path = model.filePath(index) if hasattr(model, 'filePath') else model.index(index_row, 0).data()
        answer = show_warning_yes_no(_('Remove File warning'),
                                     _('Do you really want to remove:\n{}').format(path))
        if answer == QMessageBox.No:
            return

        if isinstance(model, QFileSystemModel):
            model.remove(index)

        elif isinstance(model, QStandardItemModel):
            if not self.parent.geoshark_widget.device_on_connect or self.server is None:
                return
            filename = self.right_file_model.item(index.row(), 0).text()
            path = '/'.join(self.right_file_model_path + [filename])

            url = 'http://{}/data/{}'.format(self.server, path)
            try:
                res = requests.delete(url)
            except requests.exceptions.RequestException:
                show_error(_('GeoShark error'), _('GeoShark is not responding.'))
                return
            if res.ok:
                self.right_file_model_update()
            elif res.status_code == 400:
                self.right_file_model.removeRow(index.row())
            elif res.status_code == 409:
                show_error(_('GeoShark error'),
                           _('Request declined - directory is the part of active session working directory.'))
                return

    def find_selected_idx(self):
        left_indexes = self.lefttableview.selectedIndexes()
        right_indexes = self.righttableview.selectedIndexes()
        if len(left_indexes) == 0 and len(right_indexes) == 0:
            return None
        index = left_indexes[0] if len(left_indexes) > len(right_indexes) else right_indexes[0]
        return index

    def save_file_models_folder(self):
        self.left_file_model_auto_sync_label.setText(self.parent.settings_widget.left_folder_tracked.text())
        self.right_file_model_auto_sync_label.setText(self.parent.settings_widget.right_folder_tracked.text())
Exemplo n.º 50
0
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        MainWindow.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.MRATcentralwidget = QtWidgets.QWidget(MainWindow)
        self.MRATcentralwidget.setObjectName("MRATcentralwidget")
        self.widget = QtWidgets.QWidget(self.MRATcentralwidget)
        self.widget.setGeometry(QtCore.QRect(10, 0, 201, 480))
        #test = PThresholdTempSourceTTest.Results
        #if PThresholdTempSourceTTest.Results != "":
        data = {'col1':['0','0','0'], 'col2':['0','0','0'], 'col3':['7','8','9']}

        self.table = MyTable(data, 5, 3)
        #self.table.show()
        #self.table.show()







        #tree.resize(340, 480)
        #tree.show()
        MainWindow.setCentralWidget(self.MRATcentralwidget)
        self.dockWidget = QtWidgets.QDockWidget(MainWindow)
        self.dockWidget.setObjectName("dockWidget")
        self.dockWidget= QDockWidget("MRAT work space", self)
        self.dockWidgetContents = QtWidgets.QWidget()
        self.dockWidgetContents.setObjectName("dockWidgetContents")
        self.dockWidget.setWidget(self.dockWidgetContents)
        MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(1), self.dockWidget)
        self.dockWidget.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)

        self.table = QTableWidget()
        #self.widget.setObjectName("widget")
        self.treeView = QtWidgets.QTreeView(self.dockWidget)
        self.treeView.setGeometry(QtCore.QRect(10, 20, 191, 480))
        self.treeView.sizeAdjustPolicy = "AdjustToContents"
        self.treeView.setObjectName("treeView")
        self.model = QFileSystemModel()
        self.rootPath = ''
        self.model.setRootPath(self.rootPath)

        self.treeView.setModel(self.model)

        self.treeView.setAnimated(True)
        self.treeView.setIndentation(5)
        self.treeView.setSortingEnabled(True)

        self.treeView.setWindowTitle("MRAT workspace")


        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
        self.menubar.setMinimumSize(QtCore.QSize(10, 10))
        self.menubar.setDefaultUp(False)
        self.menubar.setNativeMenuBar(False)
        self.menubar.setObjectName("menubar")
        self.menuFile = QtWidgets.QMenu(self.menubar)
        self.menuFile.setObjectName("menuFile")
        self.menuEdit = QtWidgets.QMenu(self.menubar)
        self.menuEdit.setObjectName("menuEdit")
        self.menuData = QtWidgets.QMenu(self.menubar)
        self.menuData.setObjectName("menuData")
        self.menuGraphics = QtWidgets.QMenu(self.menubar)
        self.menuGraphics.setObjectName("menuGraphics")
        self.menuStatistics = QtWidgets.QMenu(self.menubar)
        self.menuStatistics.setObjectName("menuStatistics")
        self.menuT_TESTS = QtWidgets.QMenu(self.menuStatistics)
        self.menuT_TESTS.setObjectName("menuT_TESTS")
        self.menuTemporal = QtWidgets.QMenu(self.menuT_TESTS)
        self.menuTemporal.setObjectName("menuTemporal")
        self.menuResults = QtWidgets.QMenu(self.menubar)
        self.menuResults.setObjectName("menuResults")
        self.menuHelp = QtWidgets.QMenu(self.menubar)
        self.menuHelp.setObjectName("menuHelp")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.toolBar = QtWidgets.QToolBar(MainWindow)
        self.toolBar.setObjectName("toolBar")
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.actionSpatio_Temporal = QtWidgets.QAction(MainWindow)
        self.actionSpatio_Temporal.setObjectName("actionSpatio_Temporal")
        self.actionSpatio_Temporal_2 = QtWidgets.QAction(MainWindow)
        self.actionSpatio_Temporal_2.setObjectName("actionSpatio_Temporal_2")
        self.actionNew_Analysis = QtWidgets.QAction(MainWindow)
        self.actionNew_Analysis.setObjectName("actionNew_Analysis")
        self.actionOpen_Analysis = QtWidgets.QAction(MainWindow)
        self.actionOpen_Analysis.setObjectName("actionOpen_Analysis")
        self.actionPTHreshold = QtWidgets.QAction(MainWindow)
        self.actionPTHreshold.setObjectName("actionPTHreshold")
        self.actionTFCE = QtWidgets.QAction(MainWindow)
        self.actionTFCE.setObjectName("actionTFCE")
        self.actionWindow = QtWidgets.QAction(MainWindow)
        self.actionWindow.setObjectName("actionWindow")
        self.actionImport_File = QtWidgets.QAction(MainWindow)
        self.actionImport_File.setObjectName("actionImport_File")
        self.actionExport_File = QtWidgets.QAction(MainWindow)
        self.actionExport_File.setObjectName("actionExport_File")
        self.actionQuit = QtWidgets.QAction(MainWindow)
        self.actionQuit.setObjectName("actionQuit")
        self.menuFile.addAction(self.actionNew_Analysis)
        self.menuFile.addAction(self.actionOpen_Analysis)
        self.menuFile.addAction(self.actionImport_File)
        self.menuFile.addAction(self.actionExport_File)
        self.menuFile.addAction(self.actionQuit)
        self.menuTemporal.addSeparator()
        self.menuTemporal.addAction(self.actionPTHreshold)
        self.menuTemporal.addAction(self.actionTFCE)
        self.menuTemporal.addAction(self.actionWindow)
        self.menuT_TESTS.addSeparator()
        self.menuT_TESTS.addAction(self.menuTemporal.menuAction())
        self.menuT_TESTS.addAction(self.actionSpatio_Temporal_2)
        self.menuStatistics.addAction(self.actionSpatio_Temporal)
        self.menuStatistics.addAction(self.menuT_TESTS.menuAction())
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuEdit.menuAction())
        self.menubar.addAction(self.menuData.menuAction())
        self.menubar.addAction(self.menuGraphics.menuAction())
        self.menubar.addAction(self.menuStatistics.menuAction())
        self.menubar.addAction(self.menuResults.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())

        self.retranslateUi(MainWindow)
        self.actionQuit.triggered.connect(MainWindow.close)
        self.form1 = ttestwindow()



        #self.Filedial = QtWidgets.QFileDialog.getExistingDirectory(self, "Find Files",
         #       QtCore.QDir.currentPath())
        self.actionPTHreshold.triggered.connect(self.form1.show)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
Exemplo n.º 51
0
class ProjectWidget(QWidget):
    """
    A widget for displaying & editing properties of objects etc.

    Also see the properties this likes to display:
    also see: supertux/property.py
    """
    def __init__(self, parent):
        super().__init__(parent)
        self.items = []
        self.addon = None

        self.vbox = QVBoxLayout()
        self.vbox.setSpacing(0)
        self.vbox.setContentsMargins(0, 0, 0, 0)

        self.heading_label = QLabel("No project")
        self.label = QLabel(
            "Create a project by selecting File > New > Project...")
        self.vbox.addWidget(self.heading_label)
        self.vbox.addWidget(self.label)
        self.setLayout(self.vbox)

    def init_gui(self):
        # Clear from previous:
        self.heading_label.setVisible(False)
        self.label.setVisible(False)

        self.toolbar = QToolBar()
        self.toolbar.setStyleSheet('QToolBar{spacing:0px;}')
        package_icon = QIcon("data/images/icons16/addon_package-16.png")
        add_icon = QIcon("data/images/supertux/plus.png")
        self.toolbar.addAction(package_icon, 'Package add-on...',
                               self.package_addon)
        self.toolbar.addAction(add_icon, "Add content...", self.add_content)

        self.tree_view = QTreeView()
        self.vbox.addWidget(self.toolbar)
        self.model = QFileSystemModel()
        # self.data = [
        #      ("SuperTux addon", [
        #          ("levels", []),
        #          ("images", []),
        #          ("sounds", []),
        #          ("music", []),
        #          ("scripts", []),
        #          ("metadata", [])
        #      ])]
        # self.model = QStandardItemModel()
        # self.add_items(self.model, self.data)
        self.tree_view.setModel(self.model)
        self.tree_view.doubleClicked.connect(self.on_tree_view_double_click)
        self.tree_view.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree_view.customContextMenuRequested.connect(self.on_context_menu)
        self.vbox.addWidget(self.tree_view)

        self.layout = QFormLayout()
        self.vbox.addLayout(self.layout)

        self.setLayout(self.vbox)
        self.setMinimumWidth(300)

        # Called in many cases. This should have functions connected
        # which cause the changes in the widget to be applied
        # Called by hitting "Apply", "Ok" or "Finish"
        self.call_signal = Signal()

        self.call_signal.connect(self.call_callbacks)

    def call_callbacks(self, *args):
        for item in self.items:
            if item.callback is not None:
                item.callback(item.get_value())

    def add_callback(self, callback):
        """Adds a callback to the callback signal"""
        self.call_signal.connect(callback)

    def add_items(self, parent, elements):
        for text, children in elements:
            item = QStandardItem(text)
            parent.appendRow(item)
            if children:
                self.add_items(item, children)

    def call(self):
        self.call_signal(*self.get_values())

    def on_tree_view_double_click(self, item):
        print("double-clicked!")

    def on_context_menu(self, position):

        menu = QMenu()
        menu.addAction(self.tr("Add image..."))
        menu.addAction(self.tr("Add sound..."))
        menu.addAction(self.tr("Add level..."))
        menu.addAction(self.tr("Add script..."))

        menu.exec_(self.tree_view.viewport().mapToGlobal(position))

    def set_project_directory(self, project_dir):
        self.tree_view.setRootIndex(self.model.setRootPath(project_dir))

    def set_addon(self, addon):
        self.addon = addon
        # We now have an add-on set, initialize the GUI
        self.init_gui()

    def package_addon(self):
        print("Package add-on!")

    def add_content(self):
        print("Add content to add-on!")
Exemplo n.º 52
0
class SearchFileWidget(QWidget):

    language_filter_change = pyqtSignal(list)

    def __init__(self):
        QWidget.__init__(self)

        self._refreshing = False

        self.fileModel = None
        self.proxyFileModel = None
        self.videoModel = None

        self._state = None

        self.timeLastSearch = QTime.currentTime()

        self.ui = Ui_SearchFileWidget()
        self.setup_ui()

    def set_state(self, state):
        self._state = state
        self._state.login_status_changed.connect(self.on_login_state_changed)
        self._state.interface_language_changed.connect(
            self.on_interface_language_changed)

    def get_state(self):
        return self._state

    def setup_ui(self):
        self.ui.setupUi(self)
        settings = QSettings()

        self.ui.splitter.setSizes([600, 1000])
        self.ui.splitter.setChildrenCollapsible(False)

        # Set up folder view

        lastDir = settings.value("mainwindow/workingDirectory",
                                 QDir.homePath())
        log.debug('Current directory: {currentDir}'.format(currentDir=lastDir))

        self.fileModel = QFileSystemModel(self)
        self.fileModel.setFilter(QDir.AllDirs | QDir.Dirs | QDir.Drives
                                 | QDir.NoDotAndDotDot | QDir.Readable
                                 | QDir.Executable | QDir.Writable)
        self.fileModel.iconProvider().setOptions(
            QFileIconProvider.DontUseCustomDirectoryIcons)
        self.fileModel.setRootPath(QDir.rootPath())
        self.fileModel.directoryLoaded.connect(self.onFileModelDirectoryLoaded)

        self.proxyFileModel = QSortFilterProxyModel(self)
        self.proxyFileModel.setSortRole(Qt.DisplayRole)
        self.proxyFileModel.setSourceModel(self.fileModel)
        self.proxyFileModel.sort(0, Qt.AscendingOrder)
        self.proxyFileModel.setSortCaseSensitivity(Qt.CaseInsensitive)
        self.ui.folderView.setModel(self.proxyFileModel)

        self.ui.folderView.setHeaderHidden(True)
        self.ui.folderView.hideColumn(3)
        self.ui.folderView.hideColumn(2)
        self.ui.folderView.hideColumn(1)

        index = self.fileModel.index(lastDir)
        proxyIndex = self.proxyFileModel.mapFromSource(index)
        self.ui.folderView.scrollTo(proxyIndex)

        self.ui.folderView.expanded.connect(self.onFolderViewExpanded)
        self.ui.folderView.clicked.connect(self.onFolderTreeClicked)
        self.ui.buttonFind.clicked.connect(self.onButtonFind)
        self.ui.buttonRefresh.clicked.connect(self.onButtonRefresh)

        # Set up introduction
        self.showInstructions()

        # Set up video view
        self.ui.filterLanguageForVideo.set_unknown_text(_('All languages'))
        self.ui.filterLanguageForVideo.selected_language_changed.connect(
            self.on_language_combobox_filter_change)
        # self.ui.filterLanguageForVideo.selected_language_changed.connect(self.onFilterLanguageVideo)

        self.videoModel = VideoModel(self)
        self.ui.videoView.setHeaderHidden(True)
        self.ui.videoView.setModel(self.videoModel)
        self.ui.videoView.activated.connect(self.onClickVideoTreeView)
        self.ui.videoView.clicked.connect(self.onClickVideoTreeView)
        self.ui.videoView.customContextMenuRequested.connect(self.onContext)
        self.videoModel.dataChanged.connect(self.subtitlesCheckedChanged)
        self.language_filter_change.connect(
            self.videoModel.on_filter_languages_change)

        self.ui.buttonSearchSelectVideos.clicked.connect(
            self.onButtonSearchSelectVideos)
        self.ui.buttonSearchSelectFolder.clicked.connect(
            self.onButtonSearchSelectFolder)
        self.ui.buttonDownload.clicked.connect(self.onButtonDownload)
        self.ui.buttonPlay.clicked.connect(self.onButtonPlay)
        self.ui.buttonIMDB.clicked.connect(self.onViewOnlineInfo)
        self.ui.videoView.setContextMenuPolicy(Qt.CustomContextMenu)

        # Drag and Drop files to the videoView enabled
        self.ui.videoView.__class__.dragEnterEvent = self.dragEnterEvent
        self.ui.videoView.__class__.dragMoveEvent = self.dragEnterEvent
        self.ui.videoView.__class__.dropEvent = self.dropEvent
        self.ui.videoView.setAcceptDrops(1)

        # FIXME: ok to drop this connect?
        # self.ui.videoView.clicked.connect(self.onClickMovieTreeView)

        self.retranslate()

    def retranslate(self):
        introduction = '<p align="center"><h2>{title}</h2></p>' \
            '<p><b>{tab1header}</b><br/>{tab1content}</p>' \
            '<p><b>{tab2header}</b><br/>{tab2content}</p>'\
            '<p><b>{tab3header}</b><br/>{tab3content}</p>'.format(
                title=_('How To Use {title}').format(title=PROJECT_TITLE),
                tab1header=_('1st Tab:'),
                tab2header=_('2nd Tab:'),
                tab3header=_('3rd Tab:'),
                tab1content=_('Select, from the Folder Tree on the left, the folder which contains the videos '
                              'that need subtitles. {project} will then try to automatically find available '
                              'subtitles.').format(project=PROJECT_TITLE),
                tab2content=_('If you don\'t have the videos in your machine, you can search subtitles by '
                              'introducing the title/name of the video.').format(project=PROJECT_TITLE),
                tab3content=_('If you have found some subtitle somewhere else that is not in {project}\'s database, '
                              'please upload those subtitles so next users will be able to '
                              'find them more easily.').format(project=PROJECT_TITLE))
        self.ui.introductionHelp.setHtml(introduction)

    @pyqtSlot(Language)
    def on_interface_language_changed(self, language):
        self.ui.retranslateUi(self)
        self.retranslate()

    @pyqtSlot(str)
    def onFileModelDirectoryLoaded(self, path):
        settings = QSettings()
        lastDir = settings.value('mainwindow/workingDirectory',
                                 QDir.homePath())
        qDirLastDir = QDir(lastDir)
        qDirLastDir.cdUp()
        if qDirLastDir.path() == path:
            index = self.fileModel.index(lastDir)
            proxyIndex = self.proxyFileModel.mapFromSource(index)
            self.ui.folderView.scrollTo(proxyIndex)
            self.ui.folderView.setCurrentIndex(proxyIndex)

    @pyqtSlot(int, str)
    def on_login_state_changed(self, state, message):
        log.debug(
            'on_login_state_changed(state={state}, message={message}'.format(
                state=state, message=message))
        if state in (State.LOGIN_STATUS_LOGGED_OUT, State.LOGIN_STATUS_BUSY):
            self.ui.buttonSearchSelectFolder.setEnabled(False)
            self.ui.buttonSearchSelectVideos.setEnabled(False)
            self.ui.buttonFind.setEnabled(False)
        elif state == State.LOGIN_STATUS_LOGGED_IN:
            self.ui.buttonSearchSelectFolder.setEnabled(True)
            self.ui.buttonSearchSelectVideos.setEnabled(True)
            self.ui.buttonFind.setEnabled(
                self.get_current_selected_folder() is not None)
        else:
            log.warning('unknown state')

    @pyqtSlot(Language)
    def on_language_combobox_filter_change(self, language):
        if language.is_generic():
            self.language_filter_change.emit(
                self.get_state().get_permanent_language_filter())
        else:
            self.language_filter_change.emit([language])

    def on_permanent_language_filter_change(self, languages):
        selected_language = self.ui.filterLanguageForVideo.get_selected_language(
        )
        if selected_language.is_generic():
            self.language_filter_change.emit(languages)

    @pyqtSlot()
    def subtitlesCheckedChanged(self):
        subs = self.videoModel.get_checked_subtitles()
        if subs:
            self.ui.buttonDownload.setEnabled(True)
        else:
            self.ui.buttonDownload.setEnabled(False)

    def showInstructions(self):
        self.ui.stackedSearchResult.setCurrentWidget(self.ui.pageIntroduction)

    def hideInstructions(self):
        self.ui.stackedSearchResult.setCurrentWidget(self.ui.pageSearchResult)

    @pyqtSlot(QModelIndex)
    def onFolderTreeClicked(self, proxyIndex):
        """What to do when a Folder in the tree is clicked"""
        if not proxyIndex.isValid():
            return

        index = self.proxyFileModel.mapToSource(proxyIndex)
        settings = QSettings()
        folder_path = self.fileModel.filePath(index)
        settings.setValue('mainwindow/workingDirectory', folder_path)
        # self.ui.buttonFind.setEnabled(self.get_state().)

    def get_current_selected_folder(self):
        proxyIndex = self.ui.folderView.currentIndex()
        index = self.proxyFileModel.mapToSource(proxyIndex)
        folder_path = self.fileModel.filePath(index)
        if not folder_path:
            return None
        return folder_path

    def get_current_selected_item_videomodel(self):
        current_index = self.ui.videoView.currentIndex()
        return self.videoModel.getSelectedItem(current_index)

    @pyqtSlot()
    def onButtonFind(self):
        now = QTime.currentTime()
        if now < self.timeLastSearch.addMSecs(500):
            return
        folder_path = self.get_current_selected_folder()

        settings = QSettings()
        settings.setValue('mainwindow/workingDirectory', folder_path)
        self.search_videos([folder_path])

        self.timeLastSearch = QTime.currentTime()

    @pyqtSlot()
    def onButtonRefresh(self):
        currentPath = self.get_current_selected_folder()
        if not currentPath:
            settings = QSettings()
            currentPath = settings.value('mainwindow/workingDirectory',
                                         QDir.homePath())

        self._refreshing = True

        self.ui.folderView.collapseAll()

        currentPath = self.get_current_selected_folder()
        if not currentPath:
            settings = QSettings()
            currentPath = settings.value('mainwindow/workingDirectory',
                                         QDir.homePath())

        index = self.fileModel.index(currentPath)

        self.ui.folderView.scrollTo(self.proxyFileModel.mapFromSource(index))

    @pyqtSlot(QModelIndex)
    def onFolderViewExpanded(self, proxyIndex):
        if self._refreshing:
            expandedPath = self.fileModel.filePath(
                self.proxyFileModel.mapToSource(proxyIndex))
            if expandedPath == QDir.rootPath():
                currentPath = self.get_current_selected_folder()
                if not currentPath:
                    settings = QSettings()
                    currentPath = settings.value('mainwindow/workingDirectory',
                                                 QDir.homePath())

                index = self.fileModel.index(currentPath)

                self.ui.folderView.scrollTo(
                    self.proxyFileModel.mapFromSource(index))
                self._refreshing = False

    @pyqtSlot()
    def onButtonSearchSelectFolder(self):
        settings = QSettings()
        path = settings.value('mainwindow/workingDirectory', QDir.homePath())
        folder_path = QFileDialog.getExistingDirectory(
            self, _('Select the directory that contains your videos'), path)
        if folder_path:
            settings.setValue('mainwindow/workingDirectory', folder_path)
            self.search_videos([folder_path])

    @pyqtSlot()
    def onButtonSearchSelectVideos(self):
        settings = QSettings()
        currentDir = settings.value('mainwindow/workingDirectory',
                                    QDir.homePath())
        fileNames, t = QFileDialog.getOpenFileNames(
            self, _('Select the video(s) that need subtitles'), currentDir,
            SELECT_VIDEOS)
        if fileNames:
            settings.setValue('mainwindow/workingDirectory',
                              QFileInfo(fileNames[0]).absolutePath())
            self.search_videos(fileNames)

    def search_videos(self, paths):
        if not self.get_state().connected():
            QMessageBox.about(
                self, _("Error"),
                _('You are not connected to the server. Please reconnect first.'
                  ))
            return
        self.ui.buttonFind.setEnabled(False)
        self._search_videos_raw(paths)
        self.ui.buttonFind.setEnabled(True)

    def _search_videos_raw(self, paths):
        # FIXME: must pass mainwindow as argument to ProgressCallbackWidget
        callback = ProgressCallbackWidget(self)
        callback.set_title_text(_("Scanning..."))
        callback.set_label_text(_("Scanning files"))
        callback.set_finished_text(_("Scanning finished"))
        callback.set_block(True)

        try:
            local_videos, local_subs = scan_videopaths(paths,
                                                       callback=callback,
                                                       recursive=True)
        except OSError:
            callback.cancel()
            QMessageBox.warning(self, _('Error'),
                                _('Some directories are not accessible.'))

        if callback.canceled():
            return

        callback.finish()

        log.debug("Videos found: %s" % local_videos)
        log.debug("Subtitles found: %s" % local_subs)
        self.hideInstructions()

        QCoreApplication.processEvents()

        if not local_videos:
            QMessageBox.about(self, _("Scan Results"),
                              _("No video has been found!"))
            return

        total = len(local_videos)

        # FIXME: must pass mainwindow as argument to ProgressCallbackWidget
        # callback = ProgressCallbackWidget(self)
        # callback.set_title_text(_("Asking Server..."))
        # callback.set_label_text(_("Searching subtitles..."))
        # callback.set_updated_text(_("Searching subtitles ( %d / %d )"))
        # callback.set_finished_text(_("Search finished"))
        callback.set_block(True)
        callback.set_range(0, total)

        callback.show()

        callback.set_range(0, 2)

        download_callback = callback.get_child_progress(0, 1)
        # videoSearchResults = self.get_state().get_OSDBServer().SearchSubtitles("", videos_piece)
        remote_subs = self.get_state().get_OSDBServer().search_videos(
            videos=local_videos, callback=download_callback)

        self.videoModel.set_videos(local_videos)
        # self.onFilterLanguageVideo(self.ui.filterLanguageForVideo.get_selected_language())

        if remote_subs is None:
            QMessageBox.about(
                self, _("Error"),
                _("Error contacting the server. Please try again later"))
        callback.finish()

        # TODO: CHECK if our local subtitles are already in the server, otherwise suggest to upload
        # self.OSDBServer.CheckSubHash(sub_hashes)

    @pyqtSlot()
    def onButtonPlay(self):
        settings = QSettings()
        programPath = settings.value('options/VideoPlayerPath', '')
        parameters = settings.value('options/VideoPlayerParameters', '')
        if programPath == '':
            QMessageBox.about(
                self, _('Error'),
                _('No default video player has been defined in Settings.'))
            return

        selected_subtitle = self.get_current_selected_item_videomodel()
        if isinstance(selected_subtitle, SubtitleFileNetwork):
            selected_subtitle = selected_subtitle.get_subtitles()[0]

        if isinstance(selected_subtitle, LocalSubtitleFile):
            subtitle_file_path = selected_subtitle.get_filepath()
        elif isinstance(selected_subtitle, RemoteSubtitleFile):
            subtitle_file_path = QDir.temp().absoluteFilePath(
                'subdownloader.tmp.srt')
            log.debug(
                'Temporary subtitle will be downloaded into: {temp_path}'.
                format(temp_path=subtitle_file_path))
            # FIXME: must pass mainwindow as argument to ProgressCallbackWidget
            callback = ProgressCallbackWidget(self)
            callback.set_title_text(_('Playing video + sub'))
            callback.set_label_text(_('Downloading files...'))
            callback.set_finished_text(_('Downloading finished'))
            callback.set_block(True)
            callback.set_range(0, 100)
            callback.show()
            try:
                subtitle_stream = selected_subtitle.download(
                    self.get_state().get_OSDBServer(), callback=callback)
            except ProviderConnectionError:
                log.debug('Unable to download subtitle "{}"'.format(
                    selected_subtitle.get_filename()),
                          exc_info=True)
                QMessageBox.about(
                    self, _('Error'),
                    _('Unable to download subtitle "{subtitle}"').format(
                        subtitle=selected_subtitle.get_filename()))
                callback.finish()
                return
            callback.finish()
            write_stream(subtitle_stream, subtitle_file_path)

        video = selected_subtitle.get_parent().get_parent().get_parent()

        def windows_escape(text):
            return '"{text}"'.format(text=text.replace('"', '\\"'))

        params = [windows_escape(programPath)]

        for param in parameters.split(' '):
            param = param.format(video.get_filepath(), subtitle_file_path)
            if platform.system() in ('Windows', 'Microsoft'):
                param = windows_escape(param)
            params.append(param)

        pid = None
        log.info('Running this command: {params}'.format(params=params))
        try:
            log.debug('Trying os.spawnvpe ...')
            pid = os.spawnvpe(os.P_NOWAIT, programPath, params, os.environ)
            log.debug('... SUCCESS. pid={pid}'.format(pid=pid))
        except AttributeError:
            log.debug('... FAILED', exc_info=True)
        except Exception as e:
            log.debug('... FAILED', exc_info=True)
        if pid is None:
            try:
                log.debug('Trying os.fork ...')
                pid = os.fork()
                if not pid:
                    log.debug('... SUCCESS. pid={pid}'.format(pid=pid))
                    os.execvpe(os.P_NOWAIT, programPath, params, os.environ)
            except:
                log.debug('... FAIL', exc_info=True)
        if pid is None:
            QMessageBox.about(self, _('Error'),
                              _('Unable to launch videoplayer'))

    @pyqtSlot(QModelIndex)
    def onClickVideoTreeView(self, index):
        data_item = self.videoModel.getSelectedItem(index)

        if isinstance(data_item, SubtitleFile):
            self.ui.buttonPlay.setEnabled(True)
        else:
            self.ui.buttonPlay.setEnabled(False)

        if isinstance(data_item, VideoFile):
            video = data_item
            if True:  # video.getMovieInfo():
                self.ui.buttonIMDB.setEnabled(True)
                self.ui.buttonIMDB.setIcon(QIcon(':/images/info.png'))
                self.ui.buttonIMDB.setText(_('Movie Info'))
        elif isinstance(data_item, RemoteSubtitleFile):
            self.ui.buttonIMDB.setEnabled(True)
            self.ui.buttonIMDB.setIcon(
                QIcon(':/images/sites/opensubtitles.png'))
            self.ui.buttonIMDB.setText(_('Subtitle Info'))
        else:
            self.ui.buttonIMDB.setEnabled(False)

    def onContext(self, point):
        # FIXME: code duplication with Main.onContext and/or SearchNameWidget and/or SearchFileWidget
        menu = QMenu('Menu', self)

        listview = self.ui.videoView

        index = listview.currentIndex()
        data_item = listview.model().getSelectedItem(index)
        if data_item is not None:
            if isinstance(data_item, VideoFile):
                video = data_item
                movie_info = video.getMovieInfo()
                if movie_info:
                    subWebsiteAction = QAction(QIcon(":/images/info.png"),
                                               _("View IMDB info"), self)
                    subWebsiteAction.triggered.connect(self.onViewOnlineInfo)
                else:
                    subWebsiteAction = QAction(QIcon(":/images/info.png"),
                                               _("Set IMDB info..."), self)
                    subWebsiteAction.triggered.connect(self.onSetIMDBInfo)
                menu.addAction(subWebsiteAction)
            elif isinstance(data_item, SubtitleFile):
                downloadAction = QAction(QIcon(":/images/download.png"),
                                         _("Download"), self)
                # Video tab, TODO:Replace me with a enum

                downloadAction.triggered.connect(self.onButtonDownload)
                playAction = QAction(QIcon(":/images/play.png"),
                                     _("Play video + subtitle"), self)
                playAction.triggered.connect(self.onButtonPlay)
                menu.addAction(playAction)

                subWebsiteAction = QAction(
                    QIcon(":/images/sites/opensubtitles.png"),
                    _("View online info"), self)

                menu.addAction(downloadAction)
                subWebsiteAction.triggered.connect(self.onViewOnlineInfo)
                menu.addAction(subWebsiteAction)
            elif isinstance(data_item, Movie):
                subWebsiteAction = QAction(QIcon(":/images/info.png"),
                                           _("View IMDB info"), self)
                subWebsiteAction.triggered.connect(self.onViewOnlineInfo)
                menu.addAction(subWebsiteAction)

        # Show the context menu.
        menu.exec_(listview.mapToGlobal(point))

    def onButtonDownload(self):
        # We download the subtitle in the same folder than the video
        subs = self.videoModel.get_checked_subtitles()
        replace_all = False
        skip_all = False
        if not subs:
            QMessageBox.about(self, _("Error"),
                              _("No subtitles selected to be downloaded"))
            return
        total_subs = len(subs)
        answer = None
        success_downloaded = 0

        # FIXME: must pass mainwindow as argument to ProgressCallbackWidget
        callback = ProgressCallbackWidget(self)
        callback.set_title_text(_("Downloading..."))
        callback.set_label_text(_("Downloading files..."))
        callback.set_updated_text(_("Downloading subtitle {0} ({1}/{2})"))
        callback.set_finished_text(
            _("{0} from {1} subtitles downloaded successfully"))
        callback.set_block(True)
        callback.set_range(0, total_subs)

        callback.show()

        for i, sub in enumerate(subs):
            if callback.canceled():
                break
            destinationPath = self.get_state().getDownloadPath(self, sub)
            if not destinationPath:
                break
            log.debug("Trying to download subtitle '%s'" % destinationPath)
            callback.update(i,
                            QFileInfo(destinationPath).fileName(), i + 1,
                            total_subs)

            # Check if we have write permissions, otherwise show warning window
            while True:
                # If the file and the folder don't have write access.
                if not QFileInfo(
                        destinationPath).isWritable() and not QFileInfo(
                            QFileInfo(destinationPath).absoluteDir().path()
                        ).isWritable():
                    warningBox = QMessageBox(
                        _("Error write permission"),
                        _("%s cannot be saved.\nCheck that the folder exists and you have write-access permissions."
                          ) % destinationPath, QMessageBox.Warning,
                        QMessageBox.Retry | QMessageBox.Default,
                        QMessageBox.Discard | QMessageBox.Escape,
                        QMessageBox.NoButton, self)

                    saveAsButton = warningBox.addButton(
                        _("Save as..."), QMessageBox.ActionRole)
                    answer = warningBox.exec_()
                    if answer == QMessageBox.Retry:
                        continue
                    elif answer == QMessageBox.Discard:
                        break  # Let's get out from the While true
                    # If we choose the SAVE AS
                    elif answer == QMessageBox.NoButton:
                        fileName, t = QFileDialog.getSaveFileName(
                            self, _("Save subtitle as..."), destinationPath,
                            'All (*.*)')
                        if fileName:
                            destinationPath = fileName
                else:  # If we have write access we leave the while loop.
                    break

            # If we have chosen Discard subtitle button.
            if answer == QMessageBox.Discard:
                continue  # Continue the next subtitle

            optionWhereToDownload = QSettings().value(
                "options/whereToDownload", "SAME_FOLDER")
            # Check if doesn't exists already, otherwise show fileExistsBox
            # dialog
            if QFileInfo(destinationPath).exists(
            ) and not replace_all and not skip_all and optionWhereToDownload != "ASK_FOLDER":
                # The "remote filename" below is actually not the real filename. Real name could be confusing
                # since we always rename downloaded sub to match movie
                # filename.
                fileExistsBox = QMessageBox(
                    QMessageBox.Warning, _("File already exists"),
                    _("Local: {local}\n\nRemote: {remote}\n\nHow would you like to proceed?"
                      ).format(local=destinationPath,
                               remote=QFileInfo(destinationPath).fileName()),
                    QMessageBox.NoButton, self)
                skipButton = fileExistsBox.addButton(_("Skip"),
                                                     QMessageBox.ActionRole)
                #                    skipAllButton = fileExistsBox.addButton(_("Skip all"), QMessageBox.ActionRole)
                replaceButton = fileExistsBox.addButton(
                    _("Replace"), QMessageBox.ActionRole)
                replaceAllButton = fileExistsBox.addButton(
                    _("Replace all"), QMessageBox.ActionRole)
                saveAsButton = fileExistsBox.addButton(_("Save as..."),
                                                       QMessageBox.ActionRole)
                cancelButton = fileExistsBox.addButton(_("Cancel"),
                                                       QMessageBox.ActionRole)
                fileExistsBox.exec_()
                answer = fileExistsBox.clickedButton()
                if answer == replaceAllButton:
                    # Don't ask us again (for this batch of files)
                    replace_all = True
                elif answer == saveAsButton:
                    # We will find a uniqiue filename and suggest this to user.
                    # add .<lang> to (inside) the filename. If that is not enough, start adding numbers.
                    # There should also be a preferences setting "Autorename
                    # files" or similar ( =never ask) FIXME
                    suggBaseName, suggFileExt = os.path.splitext(
                        destinationPath)
                    fNameCtr = 0  # Counter used to generate a unique filename
                    suggestedFileName = suggBaseName + '.' + \
                        sub.get_language().xxx() + suggFileExt
                    while (os.path.exists(suggestedFileName)):
                        fNameCtr += 1
                        suggestedFileName = suggBaseName + '.' + \
                            sub.get_language().xxx() + '-' + \
                            str(fNameCtr) + suggFileExt
                    fileName, t = QFileDialog.getSaveFileName(
                        None, _("Save subtitle as..."), suggestedFileName,
                        'All (*.*)')
                    if fileName:
                        destinationPath = fileName
                    else:
                        # Skip this particular file if no filename chosen
                        continue
                elif answer == skipButton:
                    continue  # Skip this particular file
#                    elif answer == skipAllButton:
#                        count += percentage
#                        skip_all = True # Skip all files already downloaded
#                        continue
                elif answer == cancelButton:
                    break  # Break out of DL loop - cancel was pushed
            QCoreApplication.processEvents()
            # FIXME: redundant update?
            callback.update(i,
                            QFileInfo(destinationPath).fileName(), i + 1,
                            total_subs)
            try:
                if not skip_all:
                    log.debug("Downloading subtitle '%s'" % destinationPath)
                    download_callback = ProgressCallback()  # FIXME
                    data_stream = sub.download(
                        provider_instance=self.get_state().get_OSDBServer(),
                        callback=download_callback,
                    )
                    write_stream(data_stream, destinationPath)
            except Exception as e:
                log.exception('Unable to Download subtitle {}'.format(
                    sub.get_filename()))
                QMessageBox.about(
                    self, _("Error"),
                    _("Unable to download subtitle %s") % sub.get_filename())
        callback.finish(success_downloaded, total_subs)

    def onViewOnlineInfo(self):
        # FIXME: code duplication with Main.onContext and/or SearchNameWidget and/or SearchFileWidget
        # Tab for SearchByHash TODO:replace this 0 by an ENUM value
        listview = self.ui.videoView
        index = listview.currentIndex()
        data_item = self.videoModel.getSelectedItem(index)

        if isinstance(data_item, VideoFile):
            video = data_item
            movie_info = video.getMovieInfo()
            if movie_info:
                imdb = movie_info["IDMovieImdb"]
                if imdb:
                    webbrowser.open("http://www.imdb.com/title/tt%s" % imdb,
                                    new=2,
                                    autoraise=1)

        elif isinstance(data_item, RemoteSubtitleFile):
            sub = data_item
            webbrowser.open(sub.get_link(), new=2, autoraise=1)

        elif isinstance(data_item, Movie):
            movie = data_item
            imdb = movie.IMDBId
            if imdb:
                webbrowser.open("http://www.imdb.com/title/tt%s" % imdb,
                                new=2,
                                autoraise=1)

    @pyqtSlot()
    def onSetIMDBInfo(self):
        #FIXME: DUPLICATED WITH SEARCHNAMEWIDGET
        QMessageBox.about(self, _("Info"), "Not implemented yet. Sorry...")
Exemplo n.º 53
0
class MainWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.left = 10
        self.top = 10
        self.width = 400
        self.height = 500
        self.leftPanelWidth = 250
        self.processed_image: Segmented_image = None
        self.initUI()

    def initUI(self):
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.model = QFileSystemModel()
        self.model.setRootPath(
            r'C:\Users\kkozi\Documents\WORKSPACE\pomwj_projekt\data ')
        self.model.setReadOnly(True)
        tmpIdx = self.model.index(
            r'C:\Users\kkozi\Documents\WORKSPACE\pomwj_projekt\data')

        self.tree = QTreeView()
        self.tree.setModel(self.model)
        self.tree.doubleClicked.connect(self.SetProcessedImage)
        self.tree.setRootIndex(tmpIdx)

        self.img = QPixmap(
            r'C:\Users\kkozi\Documents\WORKSPACE\pomwj_projekt\data\no_image.jpg'
        )
        self.imgLabel = QLabel()
        self.imgLabel.setAlignment(Qt.AlignCenter)
        self.imgLabel.setContentsMargins(30, 0, 0, 30)
        self.imgLabel.setStyleSheet("text-align: right; color: white;")
        self.imgLabel.setPixmap(self.img)

        splitter = QSplitter(Qt.Horizontal)
        splitter.addWidget(self.tree)
        splitter.addWidget(self.imgLabel)

        self.processing_wdg = Processing_data_widget()
        self.processing_wdg.process_btn.clicked.connect(self.MakeSegmentation)

        downLayout = QHBoxLayout()
        downLayout.addWidget(splitter)
        downLayout.addWidget(self.processing_wdg)

        mainLayout = QVBoxLayout(self)
        mainLayout.addLayout(downLayout)

    def SetProcessedImage(self, index):
        try:
            path = self.model.filePath(index)
            self.processed_image = Segmented_image()
            self.processed_image.SetImage(path)
            self.processing_wdg.SetFileParams(
                path, self.processed_image.GetColorType())
            if self.ImgIsRGB():
                self.processing_wdg.SetConvertBtnActive()
                self.processing_wdg.convert_btn.clicked.connect(
                    self.ConvertToHSV)
            else:
                self.processing_wdg.SetConvertBtnDisactive()
            self.processing_wdg.process_btn.setDisabled(False)
            self.ShowSelectedImage()

            if not self.processed_image.IsSetImage():
                QMessageBox.information(self, "Segmented_image Viewer",
                                        "Cannot load %s." % 'image')

        except FileFormatError as ex:
            QMessageBox.information(self, 'Format no supported',
                                    '{0}'.format(str(ex.message)),
                                    QMessageBox.Ok)

    def ShowSelectedImage(self):
        self.img = QPixmap.fromImage(self.processed_image.GetQImageFromImage())
        self.img = self.img.scaled(self.imgLabel.width() * 0.9,
                                   self.imgLabel.height() * 0.9,
                                   Qt.KeepAspectRatio)
        self.imgLabel.setPixmap(self.img)
        self.imgLabel.resize(self.width * 0.95, self.height * 0.95)

    def MakeSegmentation(self):
        progress_dialog = QProgressDialog()
        segmentation = Segmentation(self.processed_image)
        progress_dialog.setValue(10)
        seg_img = segmentation.makeSegment(self.processing_wdg.GetMinObjSize(),
                                           self.processing_wdg.GetThrDown(),
                                           self.processing_wdg.GetThrUp())
        progress_dialog.setValue(30)
        self.processed_image = Segmented_image.FromSITKImage(seg_img)
        progress_dialog.setValue(50)
        self.processing_wdg.SetCellsNumResult(segmentation.GetCellsNum())
        progress_dialog.setValue(80)
        self.ShowSelectedImage()
        progress_dialog.setValue(100)
        progress_dialog.close()

    def resizeEvent(self, event):
        self.img = self.img.scaled(self.imgLabel.width() * 0.9,
                                   self.imgLabel.height() * 0.9,
                                   Qt.KeepAspectRatio)
        self.imgLabel.setPixmap(self.img)
        self.imgLabel.resize(self.width * 0.95, self.height * 0.95)

    def ImgIsRGB(self):
        if self.processed_image.colorType == 'RGB':
            return True
        else:
            return False

    def ConvertToHSV(self):
        progress_dialog = QProgressDialog()
        self.processing_wdg.SetConvertBtnDisactive()
        image = self.processed_image.ConvertToHSV()
        self.processed_image = Segmented_image.FromSITKImage(image)
        self.ShowSelectedImage()
        progress_dialog.close()
Exemplo n.º 54
0
parser = QCommandLineParser()
parser.setApplicationDescription("Qt Dir View Example")
parser.addHelpOption()
parser.addVersionOption()

dontUseCustomDirectoryIconsOption = QCommandLineOption('c',
        "Set QFileIconProvider.DontUseCustomDirectoryIcons")
parser.addOption(dontUseCustomDirectoryIconsOption)
parser.addPositionalArgument('directory', "The directory to start in.")
parser.process(app)
try:
    rootPath = parser.positionalArguments().pop(0)
except IndexError:
    rootPath = None

model = QFileSystemModel()
model.setRootPath('')
if parser.isSet(dontUseCustomDirectoryIconsOption):
    model.iconProvider().setOptions(
            QFileIconProvider.DontUseCustomDirectoryIcons)
tree = QTreeView()
tree.setModel(model)
if rootPath is not None:
    rootIndex = model.index(QDir.cleanPath(rootPath))
    if rootIndex.isValid():
        tree.setRootIndex(rootIndex)

# Demonstrating look and feel features.
tree.setAnimated(False)
tree.setIndentation(20)
tree.setSortingEnabled(True)
Exemplo n.º 55
0
    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        pasteBox = QHBoxLayout()
        self.textLine = QLineEdit()
        self.textLine.setToolTip('Current Director/selected File')
        self.pasteButton = QToolButton()
        self.pasteButton.setEnabled(False)
        self.pasteButton.setText('Paste')
        self.pasteButton.setToolTip(
            'Copy file from copy path to current directory/file')
        self.pasteButton.clicked.connect(self.paste)
        self.pasteButton.hide()
        pasteBox.addWidget(self.textLine)
        pasteBox.addWidget(self.pasteButton)

        self.copyBox = QFrame()
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        self.copyLine = QLineEdit()
        self.copyLine.setToolTip('File path to copy from, when pasting')
        self.copyButton = QToolButton()
        self.copyButton.setText('Copy')
        self.copyButton.setToolTip('Record current file as copy path')
        self.copyButton.clicked.connect(self.recordCopyPath)
        hbox.addWidget(self.copyButton)
        hbox.addWidget(self.copyLine)
        self.copyBox.setLayout(hbox)
        self.copyBox.hide()

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files)
        self.model.setNameFilterDisables(False)
        self.model.rootPathChanged.connect(self.folderChanged)

        self.list = QListView()
        self.list.setModel(self.model)
        self.list.resize(640, 480)
        self.list.clicked[QModelIndex].connect(self.listClicked)
        self.list.activated.connect(self._getPathActivated)
        self.list.setAlternatingRowColors(True)
        self.list.hide()

        self.table = QTableView()
        self.table.setModel(self.model)
        self.table.resize(640, 480)
        self.table.clicked[QModelIndex].connect(self.listClicked)
        self.table.activated.connect(self._getPathActivated)
        self.table.setAlternatingRowColors(True)

        header = self.table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        header.swapSections(1, 3)
        header.setSortIndicator(1, Qt.AscendingOrder)
        self.table.setSortingEnabled(True)
        self.table.setColumnHidden(2, True)  # type
        self.table.verticalHeader().setVisible(False)  # row count header

        self.cb = QComboBox()
        self.cb.currentIndexChanged.connect(self.filterChanged)
        self.fillCombobox(INFO.PROGRAM_FILTERS_EXTENSIONS)
        self.cb.setMinimumHeight(30)
        self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,
                                          QSizePolicy.Fixed))

        self.button2 = QToolButton()
        self.button2.setText('User')
        self.button2.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button2.setMinimumSize(60, 30)
        self.button2.setToolTip(
            'Jump to User directory.\nLong press for Options.')
        self.button2.clicked.connect(self.onJumpClicked)

        self.button3 = QToolButton()
        self.button3.setText('Add Jump')
        self.button3.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button3.setMinimumSize(60, 30)
        self.button3.setToolTip('Add current directory to jump button list')
        self.button3.clicked.connect(self.onActionClicked)

        self.settingMenu = QMenu(self)
        self.button2.setMenu(self.settingMenu)

        hbox = QHBoxLayout()
        hbox.addWidget(self.button2)
        hbox.addWidget(self.button3)
        hbox.insertStretch(2, stretch=0)
        hbox.addWidget(self.cb)

        windowLayout = QVBoxLayout()
        windowLayout.addLayout(pasteBox)
        windowLayout.addWidget(self.copyBox)
        windowLayout.addWidget(self.list)
        windowLayout.addWidget(self.table)
        windowLayout.addLayout(hbox)
        self.setLayout(windowLayout)
        self.show()
Exemplo n.º 56
0
class AssetBrowser(QMainWindow, Ui_MainWindow, PlaygroundModule):
    Name = "asset_browser"

    def __init__(self, module_manager):
        super(AssetBrowser, self).__init__()
        self.setupUi(self)

        self.init_module(module_manager)

        self.dir_model = QFileSystemModel()
        self.dir_model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)
        self.dir_model.setReadOnly(False)

        self.dir_view.setModel(self.dir_model)
        self.dir_view.hideColumn(1)
        self.dir_view.hideColumn(2)
        self.dir_view.hideColumn(3)

        self.file_model = QFileSystemModel()
        self.file_model.setFilter(QDir.NoDotAndDotDot | QDir.Files)
        self.file_model.setReadOnly(False)

        self.file_view.setModel(self.file_model)

        self.dock = self.modules_manager.new_docked(self, self.Name, "Asset browser",
                                                    Qt.BottomDockWidgetArea)

        self.modules_manager.main_window.splitDockWidget(self.dock,
                                                         self.modules_manager["asset_view"].dock, Qt.Horizontal)

    def on_open_project(self, project):
        project_dir = project.project_dir
        path = os.path.join(project_dir)

        self.dir_model.setRootPath(path)
        self.file_model.setRootPath(path)

        self.dir_view.setRootIndex(self.dir_model.index(path))
        self.file_view.setRootIndex(self.file_model.index(path))

    def dir_clicked(self, idx):
        path = self.dir_model.fileInfo(idx).absoluteFilePath()

        self.file_view.setRootIndex(self.file_model.setRootPath(path))

    def file_doubleclicked(self, idx):
        fileinfo = self.file_model.fileInfo(idx)

        path = fileinfo.absoluteFilePath()
        ext = fileinfo.suffix()
        asset_name = path.replace(self.project_manager.project_dir, '').replace('/src/', '').split('.')[0]

        self.modules_manager.open_asset(path, asset_name, ext)

    def file_clicked(self, idx):
        fileinfo = self.file_model.fileInfo(idx)

        path = fileinfo.absoluteFilePath()
        ext = fileinfo.suffix()
        asset_name = path.replace(self.project_manager.project_dir, '').replace('/src/', '').split('.')[0]

        self.modules_manager.show_asset(path, asset_name, ext)
Exemplo n.º 57
0
    def __init__(self, parent=None):
        super().__init__(parent)

        self.setupUi(self)

        QtAds.CDockManager.setConfigFlag(
            QtAds.CDockManager.OpaqueSplitterResize, True)
        QtAds.CDockManager.setConfigFlag(
            QtAds.CDockManager.XmlCompressionEnabled, False)
        QtAds.CDockManager.setConfigFlag(QtAds.CDockManager.FocusHighlighting,
                                         True)
        self.dock_manager = QtAds.CDockManager(self)

        # Set central widget
        text_edit = QPlainTextEdit()
        text_edit.setPlaceholderText(
            "This is the central editor. Enter your text here.")
        central_dock_widget = QtAds.CDockWidget("CentralWidget")
        central_dock_widget.setWidget(text_edit)
        central_dock_area = self.dock_manager.setCentralWidget(
            central_dock_widget)
        central_dock_area.setAllowedAreas(QtAds.DockWidgetArea.OuterDockAreas)

        # create other dock widgets
        file_tree = QTreeView()
        file_tree.setFrameShape(QFrame.NoFrame)
        file_model = QFileSystemModel(file_tree)
        file_model.setRootPath(QDir.currentPath())
        file_tree.setModel(file_model)
        data_dock_widget = QtAds.CDockWidget("File system")
        data_dock_widget.setWidget(file_tree)
        data_dock_widget.resize(150, 250)
        data_dock_widget.setMinimumSize(100, 250)
        file_area = self.dock_manager.addDockWidget(
            QtAds.DockWidgetArea.LeftDockWidgetArea, data_dock_widget,
            central_dock_area)
        self.menuView.addAction(data_dock_widget.toggleViewAction())

        table = QTableWidget()
        table.setColumnCount(3)
        table.setRowCount(10)
        table_dock_widget = QtAds.CDockWidget("Table")
        table_dock_widget.setWidget(table)
        table_dock_widget.setMinimumSizeHintMode(
            QtAds.CDockWidget.MinimumSizeHintFromDockWidget)
        table_dock_widget.resize(250, 150)
        table_dock_widget.setMinimumSize(200, 150)
        self.dock_manager.addDockWidget(
            QtAds.DockWidgetArea.BottomDockWidgetArea, table_dock_widget,
            file_area)
        self.menuView.addAction(table_dock_widget.toggleViewAction())

        properties_table = QTableWidget()
        properties_table.setColumnCount(3)
        properties_table.setRowCount(10)
        properties_dock_widget = QtAds.CDockWidget("Properties")
        properties_dock_widget.setWidget(properties_table)
        properties_dock_widget.setMinimumSizeHintMode(
            QtAds.CDockWidget.MinimumSizeHintFromDockWidget)
        properties_dock_widget.resize(250, 150)
        properties_dock_widget.setMinimumSize(200, 150)
        self.dock_manager.addDockWidget(
            QtAds.DockWidgetArea.RightDockWidgetArea, properties_dock_widget,
            central_dock_area)
        self.menuView.addAction(properties_dock_widget.toggleViewAction())

        self.create_perspective_ui()
Exemplo n.º 58
0
class FileManager(QWidget, _HalWidgetBase):
    def __init__(self, parent=None):
        super(FileManager, self).__init__(parent)
        self.title = 'Qtvcp File System View'
        self.left = 10
        self.top = 10
        self.width = 640
        self.height = 480
        self._last = 0

        if INFO.PROGRAM_PREFIX is not None:
            self.user_path = os.path.expanduser(INFO.PROGRAM_PREFIX)
        else:
            self.user_path = (os.path.join(os.path.expanduser('~'),
                                           'linuxcnc/nc_files'))
        user = os.path.split(os.path.expanduser('~'))[-1]
        self.media_path = (os.path.join('/media', user))
        temp = [('User', self.user_path), ('Media', self.media_path)]
        self._jumpList = OrderedDict(temp)
        self.currentPath = None
        self.currentFolder = None
        self.PREFS_ = None
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        pasteBox = QHBoxLayout()
        self.textLine = QLineEdit()
        self.textLine.setToolTip('Current Director/selected File')
        self.pasteButton = QToolButton()
        self.pasteButton.setEnabled(False)
        self.pasteButton.setText('Paste')
        self.pasteButton.setToolTip(
            'Copy file from copy path to current directory/file')
        self.pasteButton.clicked.connect(self.paste)
        self.pasteButton.hide()
        pasteBox.addWidget(self.textLine)
        pasteBox.addWidget(self.pasteButton)

        self.copyBox = QFrame()
        hbox = QHBoxLayout()
        hbox.setContentsMargins(0, 0, 0, 0)
        self.copyLine = QLineEdit()
        self.copyLine.setToolTip('File path to copy from, when pasting')
        self.copyButton = QToolButton()
        self.copyButton.setText('Copy')
        self.copyButton.setToolTip('Record current file as copy path')
        self.copyButton.clicked.connect(self.recordCopyPath)
        hbox.addWidget(self.copyButton)
        hbox.addWidget(self.copyLine)
        self.copyBox.setLayout(hbox)
        self.copyBox.hide()

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.currentPath())
        self.model.setFilter(QDir.AllDirs | QDir.NoDot | QDir.Files)
        self.model.setNameFilterDisables(False)
        self.model.rootPathChanged.connect(self.folderChanged)

        self.list = QListView()
        self.list.setModel(self.model)
        self.list.resize(640, 480)
        self.list.clicked[QModelIndex].connect(self.listClicked)
        self.list.activated.connect(self._getPathActivated)
        self.list.setAlternatingRowColors(True)
        self.list.hide()

        self.table = QTableView()
        self.table.setModel(self.model)
        self.table.resize(640, 480)
        self.table.clicked[QModelIndex].connect(self.listClicked)
        self.table.activated.connect(self._getPathActivated)
        self.table.setAlternatingRowColors(True)

        header = self.table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.Stretch)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        header.swapSections(1, 3)
        header.setSortIndicator(1, Qt.AscendingOrder)
        self.table.setSortingEnabled(True)
        self.table.setColumnHidden(2, True)  # type
        self.table.verticalHeader().setVisible(False)  # row count header

        self.cb = QComboBox()
        self.cb.currentIndexChanged.connect(self.filterChanged)
        self.fillCombobox(INFO.PROGRAM_FILTERS_EXTENSIONS)
        self.cb.setMinimumHeight(30)
        self.cb.setSizePolicy(QSizePolicy(QSizePolicy.Fixed,
                                          QSizePolicy.Fixed))

        self.button2 = QToolButton()
        self.button2.setText('User')
        self.button2.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button2.setMinimumSize(60, 30)
        self.button2.setToolTip(
            'Jump to User directory.\nLong press for Options.')
        self.button2.clicked.connect(self.onJumpClicked)

        self.button3 = QToolButton()
        self.button3.setText('Add Jump')
        self.button3.setSizePolicy(
            QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed))
        self.button3.setMinimumSize(60, 30)
        self.button3.setToolTip('Add current directory to jump button list')
        self.button3.clicked.connect(self.onActionClicked)

        self.settingMenu = QMenu(self)
        self.button2.setMenu(self.settingMenu)

        hbox = QHBoxLayout()
        hbox.addWidget(self.button2)
        hbox.addWidget(self.button3)
        hbox.insertStretch(2, stretch=0)
        hbox.addWidget(self.cb)

        windowLayout = QVBoxLayout()
        windowLayout.addLayout(pasteBox)
        windowLayout.addWidget(self.copyBox)
        windowLayout.addWidget(self.list)
        windowLayout.addWidget(self.table)
        windowLayout.addLayout(hbox)
        self.setLayout(windowLayout)
        self.show()

    def _hal_init(self):
        if self.PREFS_:
            last_path = self.PREFS_.getpref('last_loaded_directory',
                                            self.user_path, str,
                                            'BOOK_KEEPING')
            self.updateDirectoryView(last_path)
            LOG.debug("lAST FILE PATH: {}".format(last_path))

            # get all the saved jumplist paths
            temp = self.PREFS_.getall('FILEMANAGER_JUMPLIST')
            self._jumpList.update(temp)

        else:
            LOG.debug("lAST FILE PATH: {}".format(self.user_path))
            self.updateDirectoryView(self.user_path)

        # install jump paths into toolbutton menu
        for i in self._jumpList:
            axisButton = QAction(QIcon.fromTheme('user-home'), i, self)
            # weird lambda i=i to work around 'function closure'
            axisButton.triggered.connect(
                lambda state, i=i: self.jumpTriggered(i))
            self.settingMenu.addAction(axisButton)

    #########################
    # callbacks
    #########################

    # add shown text and hidden filter data from the INI
    def fillCombobox(self, data):
        for i in data:
            self.cb.addItem(i[0], i[1])

    def folderChanged(self, data):
        data = os.path.normpath(data)
        self.currentFolder = data
        self.textLine.setText(data)

    def updateDirectoryView(self, path, quiet=False):
        if os.path.exists(path):
            self.list.setRootIndex(self.model.setRootPath(path))
            self.table.setRootIndex(self.model.setRootPath(path))
        else:
            LOG.debug(
                "Set directory view error - no such path {}".format(path))
            if not quiet:
                STATUS.emit(
                    'error', LOW_ERROR,
                    "File Manager error - No such path: {}".format(path))

    # retrieve selected filter (it's held as QT.userData)
    def filterChanged(self, index):
        userdata = self.cb.itemData(index)
        self.model.setNameFilters(userdata)

    def listClicked(self, index):
        # the signal passes the index of the clicked item
        dir_path = os.path.normpath(self.model.filePath(index))
        if self.model.fileInfo(index).isFile():
            self.currentPath = dir_path
            self.textLine.setText(self.currentPath)
            return
        root_index = self.model.setRootPath(dir_path)
        self.list.setRootIndex(root_index)
        self.table.setRootIndex(root_index)

    def onUserClicked(self):
        self.showUserDir()

    def onMediaClicked(self):
        self.showMediaDir()

    # jump directly to a saved path shown on the button
    def onJumpClicked(self):
        data = self.button2.text()
        if data.upper() == 'MEDIA':
            self.showMediaDir()
        elif data.upper() == 'USER':
            self.showUserDir()
        else:
            temp = self._jumpList.get(data)
            if temp is not None:
                self.updateDirectoryView(temp)
            else:
                STATUS.emit('error', linuxcnc.OPERATOR_ERROR,
                            'file jumopath: {} not valid'.format(data))
                log.debug('file jumopath: {} not valid'.format(data))

    # jump directly to a saved path from the menu
    def jumpTriggered(self, data):
        if data.upper() == 'MEDIA':
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip(
                'Jump to Media directory.\nLong press for Options.')
            self.showMediaDir()
        elif data.upper() == 'USER':
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip(
                'Jump to User directory.\nLong press for Options.')
            self.showUserDir()
        else:
            self.button2.setText('{}'.format(data))
            self.button2.setToolTip('Jump to directory:\n{}'.format(
                self._jumpList.get(data)))
            self.updateDirectoryView(self._jumpList.get(data))

    # add a jump list path
    def onActionClicked(self):
        i = self.currentFolder
        try:
            self._jumpList[i] = i
        except Exception as e:
            print(e)
        button = QAction(QIcon.fromTheme('user-home'), i, self)
        # weird lambda i=i to work around 'function closure'
        button.triggered.connect(lambda state, i=i: self.jumpTriggered(i))
        self.settingMenu.addAction(button)

    # get current selection and update the path
    # then if the path is good load it into linuxcnc
    # record it in the preference file if available
    def _getPathActivated(self):
        if self.list.isVisible():
            row = self.list.selectionModel().currentIndex()
        else:
            row = self.table.selectionModel().currentIndex()
            self.listClicked(row)

        fname = self.currentPath
        if fname is None:
            return
        if fname:
            self.load(fname)

    def recordCopyPath(self):
        data, isFile = self.getCurrentSelected()
        if isFile:
            self.copyLine.setText(os.path.normpath(data))
            self.pasteButton.setEnabled(True)
        else:
            self.copyLine.setText('')
            self.pasteButton.setEnabled(False)
            STATUS.emit('error', OPERATOR_ERROR,
                        'Can only copy a file, not a folder')

    def paste(self):
        res = self.copyFile(self.copyLine.text(), self.textLine.text())
        if res:
            self.copyLine.setText('')
            self.pasteButton.setEnabled(False)

    ########################
    # helper functions
    ########################

    def showList(self, state=True):
        if state:
            self.table.hide()
            self.list.show()
        else:
            self.table.show()
            self.list.hide()

    def showTable(self, state=True):
        self.showList(not state)

    def showCopyControls(self, state):
        if state:
            self.copyBox.show()
            self.pasteButton.show()
        else:
            self.copyBox.hide()
            self.pasteButton.hide()

    def showMediaDir(self, quiet=False):
        self.updateDirectoryView(self.media_path, quiet)

    def showUserDir(self, quiet=False):
        self.updateDirectoryView(self.user_path, quiet)

    def copyFile(self, s, d):
        try:
            shutil.copy(s, d)
            return True
        except Exception as e:
            LOG.error("Copy file error: {}".format(e))
            STATUS.emit('error', OPERATOR_ERROR,
                        "Copy file error: {}".format(e))
            return False

    @pyqtSlot(float)
    @pyqtSlot(int)
    def scroll(self, data):
        if data > self._last:
            self.up()
        elif data < self._last:
            self.down()
        self._last = data

    # moves the selection up
    # used with MPG scrolling
    def up(self):
        self.select_row('up')

    # moves the selection down
    # used with MPG scrolling
    def down(self):
        self.select_row('down')

    def select_row(self, style='down'):
        style = style.lower()
        if self.list.isVisible():
            i = self.list.rootIndex()
            selectionModel = self.list.selectionModel()
        else:
            i = self.table.rootIndex()
            selectionModel = self.table.selectionModel()

        row = selectionModel.currentIndex().row()
        self.rows = self.model.rowCount(i)

        if style == 'last':
            row = self.rows
        elif style == 'up':
            if row > 0:
                row -= 1
            else:
                row = 0
        elif style == 'down':
            if row < self.rows - 1:
                row += 1
            else:
                row = self.rows - 1
        else:
            return
        top = self.model.index(row, 0, i)
        selectionModel.setCurrentIndex(
            top, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        selection = QItemSelection(top, top)
        selectionModel.clearSelection()
        selectionModel.select(selection, QItemSelectionModel.Select)

    # returns the current highlighted (selected) path as well as
    # whether it's a file or not.
    def getCurrentSelected(self):
        if self.list.isVisible():
            selectionModel = self.list.selectionModel()
        else:
            selectionModel = self.table.selectionModel()
        index = selectionModel.currentIndex()
        dir_path = self.model.filePath(index)
        if self.model.fileInfo(index).isFile():
            return (dir_path, True)
        else:
            return (dir_path, False)

    # This can be class patched to do something else
    def load(self, fname=None):
        try:
            if fname is None:
                self._getPathActivated()
                return
            self.recordBookKeeping()
            ACTION.OPEN_PROGRAM(fname)
            STATUS.emit('update-machine-log', 'Loaded: ' + fname, 'TIME')
        except Exception as e:
            LOG.error("Load file error: {}".format(e))
            STATUS.emit('error', NML_ERROR, "Load file error: {}".format(e))

    # This can be class patched to do something else
    def recordBookKeeping(self):
        fname = self.currentPath
        if fname is None:
            return
        if self.PREFS_:
            self.PREFS_.putpref('last_loaded_directory', self.model.rootPath(),
                                str, 'BOOK_KEEPING')
            self.PREFS_.putpref('RecentPath_0', fname, str, 'BOOK_KEEPING')

    # when qtvcp closes this gets called
    # record jump list paths
    def closing_cleanup__(self):
        if self.PREFS_:
            for i, key in enumerate(self._jumpList):
                if i in (0, 1):
                    continue
                self.PREFS_.putpref(key, self._jumpList.get(key), str,
                                    'FILEMANAGER_JUMPLIST')
Exemplo n.º 59
0
class Directory(QTreeView):
    def __init__(self, callback, app=None, palette=None):
        super().__init__()
        directoryFont = QFont()
        self.app = app
        self.palette = palette
        directoryFont.setFamily(editor["directoryFont"])
        directoryFont.setPointSize(editor["directoryFontSize"])
        self.open_callback = callback
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.openMenu)
        self.setFont(directoryFont)
        self.layout = QHBoxLayout()
        self.model = QFileSystemModel()
        self.setModel(self.model)
        self.model.setRootPath(QDir.rootPath())
        self.setMaximumWidth(300)
        self.setIndentation(10)
        self.setAnimated(True)
        self.newFile()
        self.setSortingEnabled(True)
        self.setWindowTitle("Dir View")
        self.hideColumn(1)
        self.resize(200, 600)
        self.hideColumn(2)
        self.confirmation = MessageBox()
        self.hideColumn(3)
        # self.layout.addWidget(self)
        self.doubleClicked.connect(self.openFile)

    def newFile(self):
        self.newAct = QAction('New')
        self.newAct.setStatusTip('Create a new file')
        self.newAct.triggered.connect(lambda: print("new file created lol"))

    def openMenu(self, position):

        indexes = self.selectedIndexes()
        if len(indexes) > 0:
            level = 0
            index = indexes[0]
            while index.parent().isValid():
                index = index.parent()
                level += 1

        menu = QMenu()
        menu.addAction(
            self.newAct
        )  # TODO: Add more context menu stuff and make them functional
        menu.exec_(self.viewport().mapToGlobal(position))

    def focusInEvent(self, event):
        # If we are focused then we change the selected item highlighting color
        self.focused = True
        self.palette.setColor(QPalette.Highlight,
                              QColor(editor["HighlightColor"]).lighter())

        self.app.setPalette(self.palette)

    def focusOutEvent(self, event):
        # If we un focus from the QTreeView then we make the highlighted item color white
        self.palette.setColor(
            QPalette.Highlight,
            QColor(editor["UnfocusedHighlightColor"]).lighter())
        # self.clearSelection() Uncomment this if you want to remove all highlighting when unfocused
        self.app.setPalette(self.palette)

    def openDirectory(self, path):
        self.setRootIndex(self.model.index(path))

    def openFile(self, signal):
        file_path = self.model.filePath(signal)
        self.open_callback(file_path)
        return file_path

    def keyPressEvent(self, event):
        key = event.key()
        if key == Qt.Key_Delete:

            try:
                self.fileObject = self.selectedIndexes()[0]
                fileName = self.model.filePath(self.fileObject)
                self.confirmation.run("Are you sure you want to delete ",
                                      str(fileName))

            except IndexError:
                print("No file selected")
Exemplo n.º 60
-1
class LocalPathView(QTreeView):
    def __init__ (self):
        super(LocalPathView, self).__init__()
        self._model = QFileSystemModel()
        self._model.setFilter(QDir.Dirs | QDir.Drives | QDir.NoDotAndDotDot | QDir.AllDirs)
        self._model.setRootPath('')
        self.setModel(self._model )

        self.hideColumn(1); # removing Size Column
        self.hideColumn(2); # removing Type Column
        self.setAnimated(False)
        self.setSortingEnabled(True)
        self.header().setSortIndicator(0, Qt.AscendingOrder)

        width = self.size().width() >> 1
        self.setColumnWidth(0, width*0.7)
        self.setColumnWidth(1, width*0.3)

        index = self._model.index(QDir.currentPath())
        self.selectionModel().setCurrentIndex(index, QItemSelectionModel.Select | QItemSelectionModel.Rows)
        self.expand(index)
        self.scrollTo(index)

    @property
    def selectedDir(self):
        return self._model.filePath(self.selectionModel().selectedIndexes()[0])