Example #1
0
    def __init__(self, app):
        QMainWindow.__init__(self)

        self.app = app
        self.config = app.config
        self.unserializing = False

        self.setWindowTitle('FileLegend')
        #self.setWindowIcon(QtGui.QIcon('ppv.png'))

        self.backgroundjob_widget = BackgroundJobDisplay(self)

        self.maintab = MainTabWidget(self, path(u'~').expand())

        mainwidget = QWidget(self)
        layout = QVBoxLayout(mainwidget)
        layout.addWidget(self.maintab)
        layout.addWidget(self.backgroundjob_widget)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)

        self.setCentralWidget(mainwidget)

        app.aboutToQuit.connect(thumbdb_factory.stop_all)
        app.focusChanged.connect(self._focus_changed)

        self.maintab.newTabOpened.connect(self._new_maintab)
        self.maintab.currentChanged.connect(self._maintab_changed)

        self.filename_label = QLabel("")
        self.filename_label.setObjectName("filename")
        self.filesize_label = QLabel("")
        self.filesize_label.setObjectName("size")

        statusbar = self.statusBar()
        statusbar.addPermanentWidget(self.filename_label)
        statusbar.addPermanentWidget(self.filesize_label)
        self.setStatusBar(statusbar)

        self.setup_toolbar()

        self.focused_dirtab = None
Example #2
0
class MainWindow(QMainWindow):
    activeWidgetChanged = pyqtSignal(QWidget)
    newFileWidget = pyqtSignal(QWidget)

    def __init__(self, app):
        QMainWindow.__init__(self)

        self.app = app
        self.config = app.config
        self.unserializing = False

        self.setWindowTitle('FileLegend')
        #self.setWindowIcon(QtGui.QIcon('ppv.png'))

        self.backgroundjob_widget = BackgroundJobDisplay(self)

        self.maintab = MainTabWidget(self, path(u'~').expand())

        mainwidget = QWidget(self)
        layout = QVBoxLayout(mainwidget)
        layout.addWidget(self.maintab)
        layout.addWidget(self.backgroundjob_widget)
        layout.setSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)

        self.setCentralWidget(mainwidget)

        app.aboutToQuit.connect(thumbdb_factory.stop_all)
        app.focusChanged.connect(self._focus_changed)

        self.maintab.newTabOpened.connect(self._new_maintab)
        self.maintab.currentChanged.connect(self._maintab_changed)

        self.filename_label = QLabel("")
        self.filename_label.setObjectName("filename")
        self.filesize_label = QLabel("")
        self.filesize_label.setObjectName("size")

        statusbar = self.statusBar()
        statusbar.addPermanentWidget(self.filename_label)
        statusbar.addPermanentWidget(self.filesize_label)
        self.setStatusBar(statusbar)

        self.setup_toolbar()

        self.focused_dirtab = None

    def serialize(self, session_filename='session.dat'):
        tree = (
                self.geometry(),
                self.maintab.serialize()
               )
        return tree

    def unserialize(self, data):
        self.unserializing = True

        geometry, tree = data

        self.setGeometry(geometry)

        self.setUpdatesEnabled(False)
        self.maintab.unserialize(tree)
        self.setUpdatesEnabled(True)

        self.maintab.currentWidget().widgets[0].setFocus()

        self.unserializing = False

    @property
    def active_filewidget(self):
        return self.focused_dirtab.currentWidget().filewidget

    def setup_toolbar(self):
        self.addToolBar(FLToolBar(self))

    def _focus_changed(self, old, new):
        if new is None:
            return

        if isinstance(new, DirTabWidget):
            dirtabwidget = new
        else:
            try:
                dirtabwidget = qpath(new, "^[DirTabWidget]")
            except ObjectNotFound:
                if new.parent() and \
                   new.parent().property('is_panel_wrapper').isValid():
                    print "parent.is_panel_wrapper"
                    dirtabwidget = new.widget
                elif new.property('is_panel_wrapper').toBool():
                    dirtabwidget = new.widget
                else:
                    return

        self._set_active_dirtab(dirtabwidget)

    def _set_active_dirtab(self, dirtabwidget):
        if self.focused_dirtab != dirtabwidget:
            if self.focused_dirtab:
                self.focused_dirtab.set_active(False)

            dirtabwidget.set_active(True)
            self.focused_dirtab = dirtabwidget

            self.activeWidgetChanged.emit(dirtabwidget)

    def _connect_dirtabwidget(self, dirtabwidget):
        def panelwrapper_mouseevent(wrapper, event):
            self._focus_changed(None, wrapper)
            return False

        panelwrapper = dirtabwidget.parent()
        panelwrapper.installEventFilter(
            PyEventFilter(
                self,
                panelwrapper,
                QMouseEvent,
                panelwrapper_mouseevent
            )
        )

        dirtabwidget.newTabOpened.connect(self._new_dirtab)
        dirtabwidget.currentChanged.connect(
            partial(self._dirtab_changed, dirtabwidget)
        )

        if not self.unserializing:
            dirtabwidget.new_tab()

        dirtabwidget.setStyleSheet(self.app.styleSheet())

    def _new_maintab(self, splitter):
        #print splitter
        for dirtabwidget in splitter.widgets:
            self._connect_dirtabwidget(dirtabwidget)

        splitter.newPanelOpened.connect(self._connect_dirtabwidget)

        if not self.unserializing:
            splitter.new_panel()

    def _new_dirtab(self, dirpanel):
        """
        called for every filewidget
        """
        def on_file_activated(filewidget, filename):
            filename = filewidget.directory.path_for(filename)
            try:
                group = self.app.extension2category[filename.ext]
            except KeyError:
                group = filename.ext

            try:
                action = self.config.default_action[group]
            except KeyError:
                self._request_action(filename, filewidget.directory)
            else:
                action.run(self.app)

        def filter_callback(exception):
            self.statusBar().showMessage(
                unicode(exception.orginal), 5000
            )

        dirpanel.filterError.connect(filter_callback)

        multifilewidget = dirpanel.filewidget
        multifilewidget.fileActivated.connect(
            partial(on_file_activated, multifilewidget)
        )

        for widget in multifilewidget.widgets:
            self.connect_filewidget_events(widget)

        multifilewidget.newWidget.connect(self.connect_filewidget_events)

        self.newFileWidget.emit(multifilewidget)

    def connect_filewidget_events(self, widget):
        widget.menuRequested.connect(self._show_filewidget_menu)

        model = widget.model()
        model.prompter = fsopdialogs.PrompWrapper()

        model.copyStarting.connect(self.on_fsop)
        model.moveStarting.connect(self.on_fsop)
        model.deleteStarting.connect(self.on_delete)

        model.icon_mapping.update(self.app.icon_mapping)

        widget.clicked.connect(
            self.filewidget_clicked
        )

        if isinstance(widget.model(), ThumbDirModel):
            self._setup_thumbwidget(widget)

    def filewidget_clicked(self, idx):
        filename = idx.internalPointer()
        if filename.isdir():
            sizetext = "<DIR>"
        else:
            try:
                sizetext = "%.2f%s" % format_size(filename.size)
            except OSError:
                sizetext = "<broken symlink>"

        try:
            res = get_picture_resolution(filename)
        except IOError:
            text = sizetext
        else:
            text = "%sx%s (%s)" % ((res) + (sizetext,))

        self.filesize_label.setText(text)
        self.filename_label.setText(filename.name)

    def on_fsop(self, filenames, dest, thread, refire=True):
        # Ensure status is only shown when necessary
        if refire:
            QTimer.singleShot(100,
                lambda: self.on_fsop(filenames, dest, thread, refire=False)
            )
        else:
            fsop = thread.operation

            if not fsop.done:
                status = self.backgroundjob_widget.add_status(
                    FSOPStatusWidget(self.backgroundjob_widget, fsop)
                )

                # This ensures the update callback will only be executed
                # in the QT-Thread
                thread.connect(
                    thread,
                    SIGNAL("cb"),
                    partial(
                        status.update_fsop,
                        fsop
                    )
                )
                fsop.update = lambda key, value: thread.emit(
                    SIGNAL("cb"),
                    key, value
                )

    def on_delete(self, filenames, thread):
        self.on_fsop(filenames, None, thread)

    def _setup_thumbwidget(self, thumbwidget):
        """
        Creates a backgroundjob-status-widget and connects all necessary events
        """
        self.backgroundjob_widget.add_status(
            ThumbStatusWidget(self.backgroundjob_widget, thumbwidget)
        )

    def _show_filewidget_menu(self, filewidget, position):
        menu = FileWidgetMenu(self, filewidget)
        menu.popup(position)

    def _maintab_changed(self):
        for widget in self.maintab.currentWidget().widgets:
            #print "mtc", widget, widget.is_active()
            if widget.is_active():
                self.focused_dirtab = widget
                break
        else:
            try:
                self._set_active_dirtab(
                    self.maintab.currentWidget().widgets[0]
                )
            except IndexError:
                pass

    def _dirtab_changed(self, dirtabwidget):
        self._focus_changed(None, dirtabwidget)

    def visible_filewidgets(self):
        splitter = self.maintab.currentWidget()
        for dirtab in splitter.widgets:
            yield dirtab.currentWidget().filewidget.currentWidget()

    def _request_action(self, filename, directory):
        groupname = self.app.get_groupname(filename)

        appselect = AppSelector(None, groupname)
        appselect.exec_()

        if appselect.action:
            action = appselect.action

            if appselect.make_default:
                self.config.default_action[groupname] = action
                #self.app.filetypes.set_default_action(action)

            recent_apps = self.config.recent_apps[groupname]
            #recent_apps = self.app.filetypes.get_recent_apps(filename)
            if action not in recent_apps:
                recent_apps.insert(0, appselect.action)
                #if len(recent_apps) > 5:
                    #recent_apps.pop(-1)

            appselect.action.create_qaction(self).trigger() #.run(
                #AttrDict(filename=filename, directory=directory)
            #)

    def run_action(self, action):
        pass