コード例 #1
0
ファイル: mainwindow.py プロジェクト: rgfernandes/qtdesktop
 def __init__(self):
     QtGui.QMainWindow.__init__(self)
     self.setupUi(self)
     self.__addressStack = list()  # current folder stack (ids)
     self.__exts = ""
     self.__mime2helper = dict()
     self.__magic = magic.open(magic.MIME)
     self.__magic.load()
     self.__init_helpers()
     self.__file = None
     self.__helper = None
     self.treeView = ArchItemView(self.centralwidget)
     self.verticalLayout.addWidget(self.treeView)
     self.__setSlots()
コード例 #2
0
ファイル: mainwindow.py プロジェクト: rgfernandes/qtdesktop
class MainWindow(QtGui.QMainWindow, Ui_Main):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.setupUi(self)
        self.__addressStack = list()  # current folder stack (ids)
        self.__exts = ""
        self.__mime2helper = dict()
        self.__magic = magic.open(magic.MIME)
        self.__magic.load()
        self.__init_helpers()
        self.__file = None
        self.__helper = None
        self.treeView = ArchItemView(self.centralwidget)
        self.verticalLayout.addWidget(self.treeView)
        self.__setSlots()

    def __init_helpers(self):
        # exec "from helper import %s" % ','.join(test1('helper'))
        from helper import arj, lzma, zip, rar, tar  # , arj, tar

        a = locals()
        for i in a:
            if i != "self":
                self.__exts += " *." + " *.".join(a[i].exts)
                for j in a[i].mimes:
                    self.__mime2helper[j] = a[i].mainclass
                    # Sprint a[i].mainclass
        self.__exts = self.__exts.lstrip(" ")

    def __init_db(self, db):
        q = QtSql.QSqlQuery()
        if not q.exec_("DELETE FROM arch"):
            db_err(q)

    def setModel(self, db):
        self.__init_db(db)
        self.__model = ArchTableModel(self, db)
        self.__model.setTable("arch")
        self.__model.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
        self.__setFilter()
        self.treeView.setModel(self.__model)
        self.treeView.setModelColumn(2)

    def __setSlots(self):
        self.connect(self.treeView, QtCore.SIGNAL("activated(const QModelIndex &)"), self.__onActionActivated)
        self.connect(
            self.treeView,
            QtCore.SIGNAL("selectionChanged(const QItemSelection &, const QItemSelection &)"),
            self.__onActionSelected,
        )
        self.connect(self.action_Up, QtCore.SIGNAL("triggered()"), self.__onActionUp)
        self.connect(self.action_FileOpen, QtCore.SIGNAL("triggered()"), self.__onActionFileOpen)
        self.connect(self.action_AddFile, QtCore.SIGNAL("triggered()"), self.__onActionAddFiles)
        self.connect(self.action_AddDirectory, QtCore.SIGNAL("triggered()"), self.__onActionAddFolder)
        self.connect(self.action_Extract, QtCore.SIGNAL("triggered()"), self.__onActionExtract)
        self.connect(self.action_Delete, QtCore.SIGNAL("triggered()"), self.__onActionDelete)
        self.connect(self.action_HelpAboutQt, QtCore.SIGNAL("triggered()"), QtGui.QApplication.aboutQt)

    def __setFilter(self):
        """
		Set current file filter by addressStack
		"""
        if len(self.__addressStack):
            self.__model.setFilter(
                "parent_id = %d ORDER BY isdir DESC, name ASC" % self.__addressStack[len(self.__addressStack) - 1]
            )
        else:
            self.__model.setFilter("parent_id IS NULL ORDER BY isdir DESC, name ASC")  # nice hack
        self.__model.select()
        # self.address.setText(item.getFullPath() if item else "")

    def __onActionActivated(self, index):
        """
		Dive into [sub]folder
		"""
        isdir = index.sibling(index.row(), 3).data().toBool()
        if isdir:
            # print index.sibling(index.row(), 0).data().toUInt()
            self.__addressStack.append(self.__model.get_id(index))  # FIXME: check success convert
            self.__setFilter()

    def __onActionUp(self):
        """
		Dive out from [sub]folder
		"""
        if len(self.__addressStack):
            self.__addressStack.pop()
            self.__setFilter()

    def __onActionSelected(self, selected, deselected):
        """
		Highlighting entry => handle statusbar
		"""
        # print "ok"
        indexes = selected.indexes()
        if indexes.count() != 1:
            self.statusBar().clearMessage()
        else:
            item = indexes[0].internalPointer()  # ArchItem*
            if not item.isDir():
                self.statusBar().showMessage(item.getFullPath())

    def __onActionFileOpen(self):
        """
		Open (== load) archive
		filter " (*.7z *.arj *.rar *.zip *.tar *.tar.gz *.tgz *.tar.bz *.tar.bz2 *.tbz *.tbz2  *.tbz *.tar.7z *.tar.lzma *.tlzma *.tar.xz *.txz)")
		"""
        fileName = QtGui.QFileDialog.getOpenFileName(
            caption=self.tr("Open file"), filter=self.tr("Archive") + " (%s)" % self.__exts
        )
        if not fileName.isEmpty():
            self._file_open(fileName)

    def __onActionAddFiles(self):
        """
		Add files to archive
		"""
        fileNames = QtGui.QFileDialog.getOpenFileNames(
            caption=self.tr("Add file"), filter=self.tr("Any file") + " (*.*)"
        )
        if not fileNames.isEmpty():
            self.__add_entries(fileNames)

    def __onActionAddFolder(self):
        """
		Add a folder to archive
		"""
        folderName = QtGui.QFileDialog.getExistingDirectory(caption=self.tr("Add folder"))
        if not folderName.isEmpty():
            self.__add_entries([folderName])  # FIXME: to QStringList

    def __onActionExtract(self):
        """
		Extract entries from archive
		If 1 - select file
		else: select folder
		"""
        entries = self.__getSelectedIDs()
        if entries:
            dest = QtGui.QFileDialog.getExistingDirectory(caption=self.tr("Extract to folder"))
            # dest = QtCore.QString("/home/eugene/Version/SVN/qtdesktop/trunk/pyqtarc/tmp")
            if not dest.isEmpty():
                # get current path
                if len(self.__addressStack):
                    q = QtSql.QSqlQuery("SELECT fullpath FROM arch WHERE id=%d" % self.__addressStack[-1:][0])
                    if q.next():
                        srcdir = q.value(0).toString()
                else:
                    srcdir = QtCore.QString()
                self.__extract_entries(srcdir, dest, entries)

    def __onActionDelete(self):
        """
		Delete entries in archive.
		"""
        pathlist = QtCore.QStringList()
        idlist = list()
        for index in self.treeView.selectedIndexes():
            # print index.column()
            if index.column() == 7:
                pathlist.append(index.data().toString())
                idlist.append(self.__model.get_id(index))
        if len(idlist):
            # print "Something to delete"
            errcode, out, err = self.__helper.delete(self.__file, pathlist)
            if errcode or err:
                print "Err:", out
            else:
                # print "DELETE FROM arch WHERE id IN (%s)" % ",".join(map(str, idlist))
                QtSql.QSqlQuery("DELETE FROM main.arch WHERE id IN (%s)" % ",".join(map(str, idlist))).exec_()
                self.__model.select()
                # self.treeView.model().reset()

    def __getSelectedIDs(self):
        """
		"""
        retvalue = dict()
        for index in self.treeView.selectedIndexes():
            id = self.__model.get_id(index)
            retvalue[self.__model.get_id(index)] = True
        return retvalue.keys()

    def __getSelectedPaths(self):
        """
		Called from __onActionExtract
		@return: [ArchItem*,]
		"""
        retvalue = list()
        for index in self.treeView.selectedIndexes():
            if index.column() == 7:  # 1, 2, 3, 5, 7
                retvalue.append(index.data().toString())
        return retvalue

    def __reload(self):
        errcode, result = self.__helper.get_list(self.__file)
        if errcode:
            return
        load_arch(result)
        # self.__model.setFilter("parent_id=NULL")
        self.__model.select()

    def _file_open(self, fileName):
        self.__file = QtCore.QFileInfo(fileName).canonicalFilePath()
        mime = self.__magic.file(str(self.__file)).split(";")[0]  # FIXME
        self.__helper = self.__mime2helper[mime]()
        self.__reload()

    def __add_entries(self, entrynames):
        """
		@param entrynames:QStringList - absolute paths of entries to add
		"""
        # 1. list src
        load_fs(entrynames)  # FIXME: false now
        # 2. check folders<>files
        # 3. check on exists
        q = QtSql.QSqlQuery("SELECT fullpath FROM fs WHERE alive=1")
        result = QtCore.QString()
        while q.next():
            result += q.value(0).toString() + "\n"
        if result.isEmpty():
            action = 0
        else:
            msg = QtGui.QMessageBox(
                QtGui.QMessageBox.Question,
                self.tr("John, I need help"),
                self.tr("Some folders and/or files to add exist in archive"),
                QtGui.QMessageBox.Yes | QtGui.QMessageBox.No | QtGui.QMessageBox.Cancel,
            )
            msg.setInformativeText(self.tr("Do you want to replace them?"))
            msg.setDetailedText(result)
            responce = msg.exec_()
            action = {QtGui.QMessageBox.Yes: 1, QtGui.QMessageBox.No: 2, QtGui.QMessageBox.Cancel: 3}[responce]
            # 4. add to archive
            # here we have: 0 (simply add => add selected), 1 (replace => add selected), 2 (skip => add custom list (endpoints)), 3 (break => return)
        if action == 3:
            return
        absprefix = QtCore.QFileInfo(entrynames[0]).absolutePath()
        relpaths = QtCore.QStringList()
        if action < 2:
            for i in entrynames:
                relpaths << QtCore.QFileInfo(i).fileName()
        else:
            q = QtSql.QSqlQuery("SELECT fullpath FROM fs WHERE alive=0 and endpoint=1")
            while q.next():
                relpaths << q.value(0).toString()
        errcode, out, err = self.__helper.add(self.__file, absprefix, relpaths)
        if (errcode) or (err):
            print "error:", err
        else:
            self.__reload()  # FIXME:

    def __extract_entries(self, src, dest, idlist):
        """
		@param dest:QString - absolute path extract to
		@param entrynames:list[int,] - full paths of entries to extract
		"""
        # 0. prepare
        # QtSql.QSqlDatabase.database().transaction()
        QtSql.QSqlQuery("DELETE FROM fs").exec_()
        # basearchname = entrynames[0].
        # 1. prepare db
        # - insert selected into
        QtSql.QSqlQuery(
            "INSERT INTO fs (fullpath, isdir, endpoint, alive) SELECT fullpath, isdir, endpoint, 0 FROM arch WHERE arch.id IN (%s)"
            % ",".join(map(str, idlist))
        ).exec_()
        # - insert children
        QtSql.QSqlQuery(
            "INSERT INTO fs (fullpath, isdir, endpoint, alive) SELECT arch.fullpath, arch.isdir, arch.endpoint, 0 FROM arch JOIN fs ON (arch.fullpath LIKE fs.fullpath||'/%') WHERE arch.endpoint=1"
        ).exec_()
        # - remove not endpoint
        QtSql.QSqlQuery("DELETE FROM fs WHERE endpoint=0").exec_()
        # 2. check exists
        q = QtSql.QSqlQuery("SELECT arch.id, fs.fullpath FROM fs JOIN arch ON (fs.fullpath = arch.fullpath)")
        toskip = list()
        toextract = list()
        ask = QtCore.QString()
        tocut = src.length() + 1 if src.length() else 0
        while q.next():
            id = q.value(0).toUInt()[0]
            s = q.value(1).toString()
            f = QtCore.QFileInfo(dest + "/" + s.mid(tocut))
            if f.exists():
                toskip.append(id)
                ask += s + "\n"
            else:
                toextract.append(id)
                # 3. ask
        if ask.length():
            msg = QtGui.QMessageBox(
                QtGui.QMessageBox.Question,
                self.tr("John, I need help"),
                self.tr("Some folders and/or files to extract exist in filesystem"),
                QtGui.QMessageBox.Yes | QtGui.QMessageBox.No | QtGui.QMessageBox.Cancel,
            )
            msg.setInformativeText(self.tr("Do you want to replace them?"))
            msg.setDetailedText(ask)
            responce = msg.exec_()
            action = {QtGui.QMessageBox.Yes: 1, QtGui.QMessageBox.No: 2, QtGui.QMessageBox.Cancel: 3}[responce]
        else:
            action = 0
            # 4. go
        if action == 3:
            return
        if action == 1:  # replace
            toextract.extend(toskip)
        fpaths = list()
        q = QtSql.QSqlQuery("SELECT fullpath FROM arch WHERE id IN (%s)" % ",".join(map(str, toextract)))
        while q.next():
            fpaths.append(q.value(0).toString())
        errcode, out, err = self.__helper.extract(self.__file, src, dest, fpaths, False)