Пример #1
0
    def _create_tool_bar(self):
        tools_toolbar = QToolBar('Tools')
        tools_toolbar.addAction(self.file_open)
        tools_toolbar.setFloatable(False)
        tools_toolbar.setMovable(False)

        self.addToolBar(tools_toolbar)
Пример #2
0
    def setup(self):
        # icons
        self.homeIcon = Icon('home.svg', '#0A0').getIcon()
        self.csvIcon = Icon('file-csv.svg', '#D50').getIcon()
        self.dbIcon = Icon('database.svg', '#666').getIcon()

        # Setup ToolBar
        toolBar = QToolBar('Left Menu', self)
        toolBar.setFloatable(False)
        toolBar.setMovable(False)
        toolBar.setIconSize(QSize(64, 64))
        toolBar.setStyleSheet('background-color: #004; color: #FFF;')

        # Tabs Properties
        self.TabContainer.setTabsClosable(True)
        self.TabContainer.tabCloseRequested.connect(self.closeTab)

        # Home
        home = QAction(self.homeIcon, 'Home', self)
        home.triggered.connect(self.onHome)
        self.TabContainer.addTab(self.home, self.homeIcon, 'Home')

        # CSV
        loadCSV = QAction(self.csvIcon, 'Load CSV', self)
        loadCSV.triggered.connect(self.onLoadCSV)

        # DB
        loadDB = QAction(self.dbIcon, 'Load From DataBase', self)
        loadDB.triggered.connect(self.onLoadDB)

        # Add to ToolBar
        toolBar.addAction(home)
        toolBar.addAction(loadCSV)
        toolBar.addAction(loadDB)
        self.addToolBar(Qt.LeftToolBarArea, toolBar)
Пример #3
0
    def __init__(self, parentWidget, settings):
        QWidget.__init__(self, parentWidget)
        self.settings = settings

        toolbar = QToolBar(self)
        toolbar.setFloatable(False)
        toolbar.setMovable(False)

        addAction = QAction("+", toolbar)
        addAction.triggered.connect(self.addNotepad)
        toolbar.addAction(addAction)

        removeAction = QAction("-", toolbar)
        removeAction.triggered.connect(self.removeNotepad)
        toolbar.addAction(removeAction)

        self.browserView = TreeWidget(self)

        hLayout = QVBoxLayout(self)
        hLayout.setContentsMargins(0, 0, 0, 1)
        hLayout.addWidget(toolbar)
        hLayout.addWidget(self.browserView)

        self.currentItem = None
        self.browserView.itemSelectionChanged.connect(self.handleItemSelected)
Пример #4
0
    def __init__(self, parent=None):
        super().__init__(parent)
        self.mTile = None
        self.mMapDocument = None
        self.mMapScene = MapScene(self)
        self.mMapView = MapView(self, MapViewMode.NoStaticContents)
        self.mToolManager = ToolManager(self)
        self.mApplyingChanges = False
        self.mSynchronizing = False

        self.setObjectName("TileCollisionEditor")
        widget = QWidget(self)
        layout = QVBoxLayout(widget)
        layout.setSpacing(0)
        layout.setContentsMargins(5, 5, 5, 5)
        self.mMapView.setScene(self.mMapScene)
        self.mMapView.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.mMapView.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        rectangleObjectsTool = CreateRectangleObjectTool(self)
        ellipseObjectsTool = CreateEllipseObjectTool(self)
        polygonObjectsTool = CreatePolygonObjectTool(self)
        polylineObjectsTool = CreatePolylineObjectTool(self)
        toolBar = QToolBar(self)
        toolBar.setMovable(False)
        toolBar.setFloatable(False)
        toolBar.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.mToolManager = ToolManager(self)
        toolBar.addAction(
            self.mToolManager.registerTool(ObjectSelectionTool(self)))
        toolBar.addAction(self.mToolManager.registerTool(
            EditPolygonTool(self)))
        toolBar.addAction(self.mToolManager.registerTool(rectangleObjectsTool))
        toolBar.addAction(self.mToolManager.registerTool(ellipseObjectsTool))
        toolBar.addAction(self.mToolManager.registerTool(polygonObjectsTool))
        toolBar.addAction(self.mToolManager.registerTool(polylineObjectsTool))
        self.setCentralWidget(self.mMapView)
        self.addToolBar(toolBar)
        self.mMapScene.setSelectedTool(self.mToolManager.selectedTool())
        self.mToolManager.selectedToolChanged.connect(self.setSelectedTool)
        zoomComboBox = QComboBox()
        self.statusBar().addPermanentWidget(zoomComboBox)
        zoomable = self.mMapView.zoomable()
        zoomable.connectToComboBox(zoomComboBox)
        undoShortcut = QShortcut(QKeySequence.Undo, self)
        redoShortcut = QShortcut(QKeySequence.Redo, self)
        cutShortcut = QShortcut(QKeySequence.Cut, self)
        copyShortcut = QShortcut(QKeySequence.Copy, self)
        pasteShortcut = QShortcut(QKeySequence.Paste, self)
        deleteShortcut = QShortcut(QKeySequence.Delete, self)
        deleteShortcut2 = QShortcut(QKeySequence.Back, self)
        undoShortcut.activated.connect(self.undo)
        redoShortcut.activated.connect(self.redo)
        cutShortcut.activated.connect(self.cut)
        copyShortcut.activated.connect(self.copy)
        pasteShortcut.activated.connect(self.paste)
        deleteShortcut.activated.connect(self.delete_)
        deleteShortcut2.activated.connect(self.delete_)
        self.retranslateUi()
        self.resize(300, 300)
        Utils.restoreGeometry(self)
Пример #5
0
    def _createToolBar(self):
        tools = QToolBar()
        tools.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

        tools.addAction(QIcon('Images/magnifier.png'), 'Search View', self.defaultView)
        tools.addAction(QIcon('Images/money-bag-dollar.png'), 'Bidding View', self.biddingView)
        tools.addAction(QIcon('Images/users.png'), 'Team View', self.teamView)

        tools.setFloatable(False)

        tools.setStyleSheet("""
            QToolBar{
                background-color: rgb(70, 72, 74);
                color: rgb(242, 243, 244);
            }
            QToolButton {
                background-color: rgb(80, 81, 82);
                color: rgb(242, 243, 244);
                border-width: 2px;
                spacing: 5px;
                padding: 3px;
                border-radius: 3px;
            }
        """)

        self.addToolBar(tools)
Пример #6
0
    def __init__(self, parent):
        TitledToolbar.__init__(self, parent, 'Actions')

        toolbar = QToolBar(self)
        toolbar.setFloatable(False)
        toolbar.setMovable(False)

        self.saveAction = QAction(QIcon(":/icons/file-save.png"),
                                  "Save (Ctrl-S)", toolbar)
        self.saveAction.setShortcut(Qt.CTRL + Qt.Key_S)
        self.saveAction.triggered.connect(parent.save)
        toolbar.addAction(self.saveAction)

        self.nonprintableAction = QAction(
            QIcon(":/icons/view-nonprintable.png"), "View nonprintable chars",
            toolbar)
        self.nonprintableAction.setCheckable(True)
        self.nonprintableAction.triggered.connect(parent.toggleNonprintable)
        toolbar.addAction(self.nonprintableAction)

        self.undoAction = QAction(QIcon(":/icons/edit-undo.png"),
                                  "Undo (Ctrl-Z)", toolbar)
        # saveAction.setShortcut(Qt.CTRL + Qt.Key_Z);
        self.undoAction.triggered.connect(parent.undo)
        toolbar.addAction(self.undoAction)

        self.redoAction = QAction(QIcon(":/icons/edit-redo.png"),
                                  "Redo (Ctrl-Y)", toolbar)
        # saveAction.setShortcut(Qt.CTRL + Qt.Key_Y);
        self.redoAction.triggered.connect(parent.redo)
        toolbar.addAction(self.redoAction)

        self.backAction = QAction(QIcon(":/icons/view-back.png"), "Back",
                                  toolbar)
        self.backAction.setEnabled(False)
        self.backAction.triggered.connect(parent.navigateBack)
        toolbar.addAction(self.backAction)

        self.forwardAction = QAction(QIcon(":/icons/view-forward.png"),
                                     "Forward", toolbar)
        self.forwardAction.setEnabled(False)
        self.forwardAction.triggered.connect(parent.navigateForward)
        toolbar.addAction(self.forwardAction)

        insertImageAction = QAction(QIcon(":/icons/edit-insert-image.png"),
                                    "Insert Image", toolbar)
        insertImageAction.triggered.connect(parent.insertImage)
        toolbar.addAction(insertImageAction)

        insertFormulaAction = QAction("f(x)", toolbar)
        insertFormulaAction.triggered.connect(parent.insertFormula)
        toolbar.addAction(insertFormulaAction)

        findInPageAction = QAction(QIcon(":/icons/edit-find.png"),
                                   "Find in page (CTRL-F)", toolbar)
        findInPageAction.setShortcut(Qt.CTRL + Qt.Key_F)
        findInPageAction.triggered.connect(parent.findInPage)
        toolbar.addAction(findInPageAction)

        self.addWidget(toolbar)
Пример #7
0
    def __init__(self, parentWidget, settings):
        QWidget.__init__(self, parentWidget)
        self.settings = settings

        toolbar = QToolBar(self)
        toolbar.setFloatable(False)
        toolbar.setMovable(False)

        addAction = QAction("+", toolbar)
        addAction.triggered.connect(self.addNotepad)
        toolbar.addAction(addAction)

        removeAction = QAction("-", toolbar)
        removeAction.triggered.connect(self.removeNotepad)
        toolbar.addAction(removeAction)

        self.browserView = TreeWidget(self)

        hLayout = QVBoxLayout(self)
        hLayout.setContentsMargins(0, 0, 0, 1)
        hLayout.addWidget(toolbar)
        hLayout.addWidget(self.browserView)

        self.currentItem = None
        self.browserView.itemSelectionChanged.connect(self.handleItemSelected)
Пример #8
0
    def __init__(self, parent = None):
        super().__init__(parent)
        self.mTile = None
        self.mMapDocument = None
        self.mMapScene = MapScene(self)
        self.mMapView = MapView(self, MapViewMode.NoStaticContents)
        self.mToolManager = ToolManager(self)
        self.mApplyingChanges = False
        self.mSynchronizing = False

        self.setObjectName("TileCollisionEditor")
        widget = QWidget(self)
        layout = QVBoxLayout(widget)
        layout.setSpacing(0)
        layout.setContentsMargins(5, 5, 5, 5)
        self.mMapView.setScene(self.mMapScene)
        self.mMapView.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.mMapView.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        rectangleObjectsTool = CreateRectangleObjectTool(self)
        ellipseObjectsTool = CreateEllipseObjectTool(self)
        polygonObjectsTool = CreatePolygonObjectTool(self)
        polylineObjectsTool = CreatePolylineObjectTool(self)
        toolBar = QToolBar(self)
        toolBar.setMovable(False)
        toolBar.setFloatable(False)
        toolBar.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.mToolManager = ToolManager(self)
        toolBar.addAction(self.mToolManager.registerTool(ObjectSelectionTool(self)))
        toolBar.addAction(self.mToolManager.registerTool(EditPolygonTool(self)))
        toolBar.addAction(self.mToolManager.registerTool(rectangleObjectsTool))
        toolBar.addAction(self.mToolManager.registerTool(ellipseObjectsTool))
        toolBar.addAction(self.mToolManager.registerTool(polygonObjectsTool))
        toolBar.addAction(self.mToolManager.registerTool(polylineObjectsTool))
        self.setCentralWidget(self.mMapView)
        self.addToolBar(toolBar)
        self.mMapScene.setSelectedTool(self.mToolManager.selectedTool())
        self.mToolManager.selectedToolChanged.connect(self.setSelectedTool)
        zoomComboBox = QComboBox()
        self.statusBar().addPermanentWidget(zoomComboBox)
        zoomable = self.mMapView.zoomable()
        zoomable.connectToComboBox(zoomComboBox)
        undoShortcut = QShortcut(QKeySequence.Undo, self)
        redoShortcut = QShortcut(QKeySequence.Redo, self)
        cutShortcut = QShortcut(QKeySequence.Cut, self)
        copyShortcut = QShortcut(QKeySequence.Copy, self)
        pasteShortcut = QShortcut(QKeySequence.Paste, self)
        deleteShortcut = QShortcut(QKeySequence.Delete, self)
        deleteShortcut2 = QShortcut(QKeySequence.Back, self)
        undoShortcut.activated.connect(self.undo)
        redoShortcut.activated.connect(self.redo)
        cutShortcut.activated.connect(self.cut)
        copyShortcut.activated.connect(self.copy)
        pasteShortcut.activated.connect(self.paste)
        deleteShortcut.activated.connect(self.delete_)
        deleteShortcut2.activated.connect(self.delete_)
        self.retranslateUi()
        self.resize(300, 300)
        Utils.restoreGeometry(self)
Пример #9
0
    def __init__(self, toolbar):
        TitledToolbar.__init__(self, toolbar, 'Text style')
        self.currentStyle = None

        toolbar = QToolBar(self)
        toolbar.setFloatable(False)
        toolbar.setMovable(False)

        self.styleToAction = {}

        textKeywordAction = QAction(QIcon(':/icons/format-keyword.png'),
                                    'Notepad link', toolbar)
        textKeywordAction.setCheckable(True)
        selector = ('olink', None, None)
        textKeywordAction.setProperty('style', selector)
        self.styleToAction[selector] = textKeywordAction
        textKeywordAction.triggered.connect(self.styleSelected)
        toolbar.addAction(textKeywordAction)

        textLinkAction = QAction(QIcon(':/icons/format-link.png'),
                                 'Internet link', toolbar)
        textLinkAction.setCheckable(True)
        selector = ('link', None, None)
        textLinkAction.setProperty('style', selector)
        self.styleToAction[selector] = textLinkAction
        textLinkAction.triggered.connect(self.styleSelected)
        toolbar.addAction(textLinkAction)

        textBoldAction = QAction(QIcon(':/icons/format-text-emphasized.png'),
                                 'Emphasize', toolbar)
        textBoldAction.setCheckable(True)
        selector = ('emphasis', None, None)
        textBoldAction.setProperty('style', selector)
        self.styleToAction[selector] = textBoldAction
        textBoldAction.triggered.connect(self.styleSelected)
        toolbar.addAction(textBoldAction)

        textHighlightAction = QAction(
            QIcon(':/icons/format-text-highlight.png'), 'Highlight', toolbar)
        textHighlightAction.setCheckable(True)
        selector = ('emphasis', 'role', 'highlight')
        textHighlightAction.setProperty('style', selector)
        self.styleToAction[selector] = textHighlightAction
        textHighlightAction.triggered.connect(self.styleSelected)
        toolbar.addAction(textHighlightAction)

        textCodeAction = QAction(QIcon(':/icons/format-text-code.png'), 'Code',
                                 toolbar)
        textCodeAction.setCheckable(True)
        selector = ('code', None, None)
        textCodeAction.setProperty('style', selector)
        self.styleToAction[selector] = textCodeAction
        textCodeAction.triggered.connect(self.styleSelected)
        toolbar.addAction(textCodeAction)

        self.addWidget(toolbar)
Пример #10
0
    def _create_toolbar(self, color_maps):
        toolbar = QToolBar()
        toolbar.setFloatable(False)
        toolbar.setMovable(False)

        self._layout_combo = LayoutCombo()
        self._layout_combo_action = QWidgetAction(self._layout_combo)
        self._layout_combo_action.setDefaultWidget(self._layout_combo)
        toolbar.addAction(self._layout_combo_action)
        self._layout_combo.layout_changed.connect(
            self._slice_view_widget.set_plot_layout)

        # self._colormap_combo = ColormapCombo(['seismic', 'spectral', 'RdGy', 'hot', 'jet', 'gray'])
        self._colormap_combo = ColormapCombo(color_maps)
        self._colormap_combo.currentIndexChanged[int].connect(
            self._colormap_changed)
        toolbar.addWidget(self._colormap_combo)

        self._save_button = QToolButton()
        self._save_button.setToolTip("Save as image")
        self._save_button.setIcon(resource_icon("table_export.png"))
        self._save_button.clicked.connect(self._save_figure)
        toolbar.addWidget(self._save_button)

        self._settings_button = QToolButton()
        self._settings_button.setToolTip("Toggle settings visibility")
        self._settings_button.setIcon(resource_icon("cog.png"))
        self._settings_button.setCheckable(True)
        self._settings_button.toggled.connect(self._show_settings)
        toolbar.addWidget(self._settings_button)

        self._help_button = QToolButton()
        self._help_button.setToolTip("View help")
        self._help_button.setIcon(resource_icon("help.png"))
        self._help_button.setCheckable(True)
        self._help_button.toggled.connect(self._show_help)
        toolbar.addWidget(self._help_button)

        def toggle_on_close(event):
            self._settings_button.setChecked(False)
            event.accept()

        def toggle_on_close_help(event):
            self._help_button.setChecked(False)
            event.accept()

        self._settings_window.closeEvent = toggle_on_close
        self._help_window.closeEvent = toggle_on_close_help

        self._colormap_combo.setCurrentIndex(45)
        self.set_default_layout()

        return toolbar
Пример #11
0
    def __init__(self, parent = None):
        super().__init__(parent)
        self.mOpacityLabel = QLabel()
        self.mOpacitySlider = QSlider(Qt.Horizontal)
        self.mLayerView = LayerView()
        self.mMapDocument = None
        self.mUpdatingSlider = False
        self.mChangingLayerOpacity = False
        self.mUpdatingSlider = False

        self.setObjectName("layerDock")
        widget = QWidget(self)
        layout = QVBoxLayout(widget)
        layout.setContentsMargins(5, 5, 5, 5)
        opacityLayout = QHBoxLayout()
        self.mOpacitySlider.setRange(0, 100)
        self.mOpacitySlider.setEnabled(False)
        opacityLayout.addWidget(self.mOpacityLabel)
        opacityLayout.addWidget(self.mOpacitySlider)
        self.mOpacityLabel.setBuddy(self.mOpacitySlider)
        handler = MapDocumentActionHandler.instance()
        newLayerMenu = QMenu(self)
        newLayerMenu.addAction(handler.actionAddTileLayer())
        newLayerMenu.addAction(handler.actionAddObjectGroup())
        newLayerMenu.addAction(handler.actionAddImageLayer())
        newIcon = QIcon(":/images/16x16/document-new.png")
        newLayerButton = QToolButton()
        newLayerButton.setPopupMode(QToolButton.InstantPopup)
        newLayerButton.setMenu(newLayerMenu)
        newLayerButton.setIcon(newIcon)
        Utils.setThemeIcon(newLayerButton, "document-new")
        buttonContainer = QToolBar()
        buttonContainer.setFloatable(False)
        buttonContainer.setMovable(False)
        buttonContainer.setIconSize(QSize(16, 16))
        buttonContainer.addWidget(newLayerButton)
        buttonContainer.addAction(handler.actionMoveLayerUp())
        buttonContainer.addAction(handler.actionMoveLayerDown())
        buttonContainer.addAction(handler.actionDuplicateLayer())
        buttonContainer.addAction(handler.actionRemoveLayer())
        buttonContainer.addSeparator()
        buttonContainer.addAction(handler.actionToggleOtherLayers())
        listAndToolBar = QVBoxLayout()
        listAndToolBar.setSpacing(0)
        listAndToolBar.addWidget(self.mLayerView)
        listAndToolBar.addWidget(buttonContainer)
        layout.addLayout(opacityLayout)
        layout.addLayout(listAndToolBar)
        self.setWidget(widget)
        self.retranslateUi()
        self.mOpacitySlider.valueChanged.connect(self.sliderValueChanged)
        self.updateOpacitySlider()
Пример #12
0
    def __init__(self, parent=None):
        super().__init__(parent)
        self.mOpacityLabel = QLabel()
        self.mOpacitySlider = QSlider(Qt.Horizontal)
        self.mLayerView = LayerView()
        self.mMapDocument = None
        self.mUpdatingSlider = False
        self.mChangingLayerOpacity = False
        self.mUpdatingSlider = False

        self.setObjectName("layerDock")
        widget = QWidget(self)
        layout = QVBoxLayout(widget)
        layout.setContentsMargins(5, 5, 5, 5)
        opacityLayout = QHBoxLayout()
        self.mOpacitySlider.setRange(0, 100)
        self.mOpacitySlider.setEnabled(False)
        opacityLayout.addWidget(self.mOpacityLabel)
        opacityLayout.addWidget(self.mOpacitySlider)
        self.mOpacityLabel.setBuddy(self.mOpacitySlider)
        handler = MapDocumentActionHandler.instance()
        newLayerMenu = QMenu(self)
        newLayerMenu.addAction(handler.actionAddTileLayer())
        newLayerMenu.addAction(handler.actionAddObjectGroup())
        newLayerMenu.addAction(handler.actionAddImageLayer())
        newIcon = QIcon(":/images/16x16/document-new.png")
        newLayerButton = QToolButton()
        newLayerButton.setPopupMode(QToolButton.InstantPopup)
        newLayerButton.setMenu(newLayerMenu)
        newLayerButton.setIcon(newIcon)
        Utils.setThemeIcon(newLayerButton, "document-new")
        buttonContainer = QToolBar()
        buttonContainer.setFloatable(False)
        buttonContainer.setMovable(False)
        buttonContainer.setIconSize(QSize(16, 16))
        buttonContainer.addWidget(newLayerButton)
        buttonContainer.addAction(handler.actionMoveLayerUp())
        buttonContainer.addAction(handler.actionMoveLayerDown())
        buttonContainer.addAction(handler.actionDuplicateLayer())
        buttonContainer.addAction(handler.actionRemoveLayer())
        buttonContainer.addSeparator()
        buttonContainer.addAction(handler.actionToggleOtherLayers())
        listAndToolBar = QVBoxLayout()
        listAndToolBar.setSpacing(0)
        listAndToolBar.addWidget(self.mLayerView)
        listAndToolBar.addWidget(buttonContainer)
        layout.addLayout(opacityLayout)
        layout.addLayout(listAndToolBar)
        self.setWidget(widget)
        self.retranslateUi()
        self.mOpacitySlider.valueChanged.connect(self.sliderValueChanged)
        self.updateOpacitySlider()
Пример #13
0
    def __init__(self, toolbar):
        TitledToolbar.__init__(self, toolbar, 'Text style')
        self.currentStyle = None

        toolbar = QToolBar(self)
        toolbar.setFloatable(False)
        toolbar.setMovable(False)

        self.styleToAction = {}

        textKeywordAction = QAction(QIcon(':/icons/format-keyword.png'), 'Notepad link', toolbar)
        textKeywordAction.setCheckable(True);
        selector = ('olink', None, None)
        textKeywordAction.setProperty('style', selector)
        self.styleToAction[selector] = textKeywordAction
        textKeywordAction.triggered.connect(self.styleSelected)
        toolbar.addAction(textKeywordAction)

        textLinkAction = QAction(QIcon(':/icons/format-link.png'), 'Internet link', toolbar)
        textLinkAction.setCheckable(True);
        selector = ('link', None, None)
        textLinkAction.setProperty('style', selector)
        self.styleToAction[selector] = textLinkAction 
        textLinkAction.triggered.connect(self.styleSelected)
        toolbar.addAction(textLinkAction)

        textBoldAction = QAction(QIcon(':/icons/format-text-emphasized.png'), 'Emphasize', toolbar)
        textBoldAction.setCheckable(True);
        selector = ('emphasis', None, None)
        textBoldAction.setProperty('style', selector)
        self.styleToAction[selector] = textBoldAction
        textBoldAction.triggered.connect(self.styleSelected)
        toolbar.addAction(textBoldAction)

        textHighlightAction = QAction(QIcon(':/icons/format-text-highlight.png'), 'Highlight', toolbar)
        textHighlightAction.setCheckable(True);
        selector = ('emphasis', 'role', 'highlight')
        textHighlightAction.setProperty('style', selector)
        self.styleToAction[selector] = textHighlightAction
        textHighlightAction.triggered.connect(self.styleSelected)
        toolbar.addAction(textHighlightAction)
 
        textCodeAction = QAction(QIcon(':/icons/format-text-code.png'), 'Code', toolbar)
        textCodeAction.setCheckable(True);
        selector = ('code', None, None)
        textCodeAction.setProperty('style', selector)
        self.styleToAction[selector] = textCodeAction
        textCodeAction.triggered.connect(self.styleSelected)
        toolbar.addAction(textCodeAction)

        self.addWidget(toolbar)
Пример #14
0
    def __init__(self, parent):
        TitledToolbar.__init__(self, parent, 'Actions')
 
        toolbar = QToolBar(self)
        toolbar.setFloatable(False)
        toolbar.setMovable(False)

        self.saveAction = QAction(QIcon(":/icons/file-save.png"), "Save (Ctrl-S)", toolbar)
        self.saveAction.setShortcut(Qt.CTRL + Qt.Key_S);
        self.saveAction.triggered.connect(parent.save)
        toolbar.addAction(self.saveAction)

        self.nonprintableAction = QAction(QIcon(":/icons/view-nonprintable.png"), "View nonprintable chars", toolbar)
        self.nonprintableAction.setCheckable(True);
        self.nonprintableAction.triggered.connect(parent.toggleNonprintable)
        toolbar.addAction(self.nonprintableAction)

        self.undoAction = QAction(QIcon(":/icons/edit-undo.png"), "Undo (Ctrl-Z)", toolbar)
        # saveAction.setShortcut(Qt.CTRL + Qt.Key_Z);
        self.undoAction.triggered.connect(parent.undo)
        toolbar.addAction(self.undoAction)

        self.redoAction = QAction(QIcon(":/icons/edit-redo.png"), "Redo (Ctrl-Y)", toolbar)
        # saveAction.setShortcut(Qt.CTRL + Qt.Key_Y);
        self.redoAction.triggered.connect(parent.redo)
        toolbar.addAction(self.redoAction)

        self.backAction = QAction(QIcon(":/icons/view-back.png"), "Back", toolbar)
        self.backAction.setEnabled(False)
        self.backAction.triggered.connect(parent.navigateBack)
        toolbar.addAction(self.backAction)

        self.forwardAction = QAction(QIcon(":/icons/view-forward.png"), "Forward", toolbar)
        self.forwardAction.setEnabled(False)
        self.forwardAction.triggered.connect(parent.navigateForward)
        toolbar.addAction(self.forwardAction)

        insertImageAction = QAction(QIcon(":/icons/edit-insert-image.png"), "Insert Image", toolbar)
        insertImageAction.triggered.connect(parent.insertImage)
        toolbar.addAction(insertImageAction)

        insertFormulaAction = QAction("f(x)", toolbar)
        insertFormulaAction.triggered.connect(parent.insertFormula)
        toolbar.addAction(insertFormulaAction)

        findInPageAction = QAction(QIcon(":/icons/edit-find.png"), "Find in page (CTRL-F)", toolbar)
        findInPageAction.setShortcut(Qt.CTRL + Qt.Key_F);
        findInPageAction.triggered.connect(parent.findInPage)
        toolbar.addAction(findInPageAction)

        self.addWidget(toolbar)
Пример #15
0
    def _createContractionToolbar(self):
        toolbar = QToolBar(parent=self)
        toolbar.setFloatable(True)
        toolbar.setMovable(True)
        toolbar.hide()

        action = toolbar.addAction('next')
        action.triggered.connect(self.next_hg)
        action = toolbar.addAction('previous')
        action.triggered.connect(self.previous_hg)
        action = toolbar.addAction('stop')
        action.triggered.connect(self.stopContractionPlayerSlot)

        self.contraction_toolbar = toolbar
Пример #16
0
    def add_toolbar(self, title=None, toolbar=None):
        """Creates, adds and returns a QToolBar
        """
        if 1 != bool(toolbar) + bool(title):
            raise ValueError('Just one of toolbar or title should be given')
        if not toolbar:
            toolbar = QToolBar(title)
        toolbar.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum)
        self.addTab(toolbar, toolbar.windowTitle())

        # This style applies to QToolButtons that are immediate children
        # of the toolbar - it does not apply to QToolButtons that are
        # contained within QWidgets added to toolbar.
        toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
        toolbar.setMovable(False)
        toolbar.setFloatable(False)
        return toolbar
Пример #17
0
    def add_toolbar(self,
                    name: str,
                    toolbar: QToolBar,
                    text: str = 'untitled toolbar'):

        b = self.top_toolbar_tab.add_button(text)
        toolbar.tab_button = b
        b.clicked.connect(lambda: self.switch_toolbar(name))

        self.addToolBarBreak(Qt.TopToolBarArea)
        self.addToolBar(toolbar)
        toolbar.setObjectName(name)
        self.toolbars[name] = toolbar
        toolbar.setMovable(False)
        toolbar.setFloatable(False)

        if self._current_toolbar_name != '':
            self.refresh_toolbar_appearance()
Пример #18
0
    def __init__(self, parent=None):
        super().__init__(parent)
        self.mMapDocument = None
        self.mPropertyBrowser = PropertyBrowser()

        self.setObjectName("propertiesDock")
        self.mActionAddProperty = QAction(self)
        self.mActionAddProperty.setEnabled(False)
        self.mActionAddProperty.setIcon(QIcon(":/images/16x16/add.png"))
        self.mActionAddProperty.triggered.connect(self.addProperty)
        self.mActionRemoveProperty = QAction(self)
        self.mActionRemoveProperty.setEnabled(False)
        self.mActionRemoveProperty.setIcon(QIcon(":/images/16x16/remove.png"))
        self.mActionRemoveProperty.triggered.connect(self.removeProperty)
        self.mActionRenameProperty = QAction(self)
        self.mActionRenameProperty.setEnabled(False)
        self.mActionRenameProperty.setIcon(QIcon(":/images/16x16/rename.png"))
        self.mActionRenameProperty.triggered.connect(self.renameProperty)
        Utils.setThemeIcon(self.mActionAddProperty, "add")
        Utils.setThemeIcon(self.mActionRemoveProperty, "remove")
        Utils.setThemeIcon(self.mActionRenameProperty, "rename")
        toolBar = QToolBar()
        toolBar.setFloatable(False)
        toolBar.setMovable(False)
        toolBar.setIconSize(QSize(16, 16))
        toolBar.addAction(self.mActionAddProperty)
        toolBar.addAction(self.mActionRemoveProperty)
        toolBar.addAction(self.mActionRenameProperty)
        widget = QWidget(self)
        layout = QVBoxLayout(widget)
        layout.setContentsMargins(5, 5, 5, 5)
        layout.setSpacing(0)
        layout.addWidget(self.mPropertyBrowser)
        layout.addWidget(toolBar)
        widget.setLayout(layout)
        self.setWidget(widget)
        manager = DocumentManager.instance()
        manager.currentDocumentChanged.connect(self.mapDocumentChanged)
        self.mPropertyBrowser.currentItemChangedSignal.connect(
            self.currentItemChanged)
        self.retranslateUi()
Пример #19
0
    def __init__(self, parent = None):
        super().__init__(parent)
        self.mExpandedGroups = QMapList()
        self.mObjectsView = ObjectsView()
        self.mMapDocument = None

        self.setObjectName("ObjectsDock")
        self.mActionObjectProperties = QAction(self)
        self.mActionObjectProperties.setIcon(QIcon(":/images/16x16/document-properties.png"))
        Utils.setThemeIcon(self.mActionObjectProperties, "document-properties")
        self.mActionObjectProperties.triggered.connect(self.objectProperties)
        handler = MapDocumentActionHandler.instance()
        widget = QWidget(self)
        layout = QVBoxLayout(widget)
        layout.setContentsMargins(5, 5, 5, 5)
        layout.setSpacing(0)
        layout.addWidget(self.mObjectsView)
        self.mActionNewLayer = QAction(self)
        self.mActionNewLayer.setIcon(QIcon(":/images/16x16/document-new.png"))
        self.mActionNewLayer.triggered.connect(handler.actionAddObjectGroup().triggered)
        self.mActionMoveToGroup = QAction(self)
        self.mActionMoveToGroup.setIcon(QIcon(":/images/16x16/layer-object.png"))
        toolBar = QToolBar()
        toolBar.setFloatable(False)
        toolBar.setMovable(False)
        toolBar.setIconSize(QSize(16, 16))
        toolBar.addAction(self.mActionNewLayer)
        toolBar.addAction(handler.actionDuplicateObjects())
        toolBar.addAction(handler.actionRemoveObjects())
        toolBar.addAction(self.mActionMoveToGroup)
        button = toolBar.widgetForAction(self.mActionMoveToGroup)
        self.mMoveToMenu = QMenu(self)
        button.setPopupMode(QToolButton.InstantPopup)
        button.setMenu(self.mMoveToMenu)
        self.mMoveToMenu.aboutToShow.connect(self.aboutToShowMoveToMenu)
        self.mMoveToMenu.triggered.connect(self.triggeredMoveToMenu)
        toolBar.addAction(self.mActionObjectProperties)
        layout.addWidget(toolBar)
        self.setWidget(widget)
        self.retranslateUi()
        DocumentManager.instance().documentAboutToClose.connect(self.documentAboutToClose)
Пример #20
0
    def __init__(self, parent = None):
        super().__init__(parent)
        self.mMapDocument = None
        self.mPropertyBrowser = PropertyBrowser()

        self.setObjectName("propertiesDock")
        self.mActionAddProperty = QAction(self)
        self.mActionAddProperty.setEnabled(False)
        self.mActionAddProperty.setIcon(QIcon(":/images/16x16/add.png"))
        self.mActionAddProperty.triggered.connect(self.addProperty)
        self.mActionRemoveProperty = QAction(self)
        self.mActionRemoveProperty.setEnabled(False)
        self.mActionRemoveProperty.setIcon(QIcon(":/images/16x16/remove.png"))
        self.mActionRemoveProperty.triggered.connect(self.removeProperty)
        self.mActionRenameProperty = QAction(self)
        self.mActionRenameProperty.setEnabled(False)
        self.mActionRenameProperty.setIcon(QIcon(":/images/16x16/rename.png"))
        self.mActionRenameProperty.triggered.connect(self.renameProperty)
        Utils.setThemeIcon(self.mActionAddProperty, "add")
        Utils.setThemeIcon(self.mActionRemoveProperty, "remove")
        Utils.setThemeIcon(self.mActionRenameProperty, "rename")
        toolBar = QToolBar()
        toolBar.setFloatable(False)
        toolBar.setMovable(False)
        toolBar.setIconSize(QSize(16, 16))
        toolBar.addAction(self.mActionAddProperty)
        toolBar.addAction(self.mActionRemoveProperty)
        toolBar.addAction(self.mActionRenameProperty)
        widget = QWidget(self)
        layout = QVBoxLayout(widget)
        layout.setContentsMargins(5, 5, 5, 5)
        layout.setSpacing(0)
        layout.addWidget(self.mPropertyBrowser)
        layout.addWidget(toolBar)
        widget.setLayout(layout)
        self.setWidget(widget)
        manager = DocumentManager.instance()
        manager.currentDocumentChanged.connect(self.mapDocumentChanged)
        self.mPropertyBrowser.currentItemChangedSignal.connect(self.currentItemChanged)
        self.retranslateUi()
Пример #21
0
    def add_toolbar(self, name: str, toolbar: QToolBar,
                    text: str = 'untitled toolbar'):
        """
        添加一个工具栏。
        """
        b = self.top_toolbar_tab.add_button(text)
        toolbar.tab_button = b
        b.clicked.connect(lambda: self.on_toolbar_switch_button_clicked(name))

        if hasattr(self, 'toolbar_path'):
            self.insertToolBar(self.toolbar_path, toolbar)
            self.insertToolBarBreak(self.toolbar_path)
        else:
            self.addToolBarBreak(Qt.TopToolBarArea)
            self.addToolBar(toolbar)
        toolbar.setObjectName(name)
        self.toolbars[name] = toolbar
        toolbar.setMovable(False)
        toolbar.setFloatable(False)

        if self._current_toolbar_name != '':
            self.refresh_toolbar_appearance()
Пример #22
0
    def __init__(self, style='default'):
        super(QRibbonWindow, self).__init__()
        self.style = style
        self.setObjectName('QRibbonWindow')

        self.tabs = []
        self.groups = []

        # 设置样式
        self.default = default
        if self.style == 'default':
            _default = default.replace("{{margin}}", str(self.margin))
            self.setStyleSheet(_default + '\n' + self.styleSheet())
        # 去除右键菜单
        self.setContextMenuPolicy(Qt.NoContextMenu)
        # 添加工具栏
        toolBar = QToolBar(self)
        toolBar.setMouseTracking(True)
        self.ribbonWidget = QRibbonWidget(toolBar)
        toolBar.addWidget(self.ribbonWidget)
        toolBar.setAllowedAreas(Qt.NoToolBarArea)
        toolBar.setMovable(False)
        toolBar.setFloatable(False)
        self.addToolBar(toolBar)
        # 添加中心控件
        self.centralWidget = QWidget(self)
        self.centralWidget.setMouseTracking(True)
        self.centralWidget.setObjectName("centralWidget")
        self.setCentralWidget(self.centralWidget)
        # 安装时间过滤器
        self.installEventFilter(self)
        self.ribbonWidget.tabPanel.installEventFilter(self)
        self.minButton.installEventFilter(self)
        self.maxButton.installEventFilter(self)
        self.closeButton.installEventFilter(self)
        # 最小化、最大化、关闭按钮事件
        self.minButton.clicked.connect(self.showMinimized)
        self.maxButton.clicked.connect(self.toggle_max)
        self.closeButton.clicked.connect(self.close)
Пример #23
0
class Record(object):
	def __init__(self):
		r = Record()
		r.foo = 'oof'
		setattr(r, 'bar', 'rab')
		r.foo
		'oof'
		r.bar
		'rab'
		names = 'id description price'.split()
		values = [666, 'duct tape', 3.45]
		s = Record()
		for name, value in zip(names, values):
			setattr(s, name, value)
		s.__dict__ # If you are suffering from dict withdrawal symptoms
		{'price': 3.45, 'id': 666, 'description': 'duct tape'}
		return self
	def appToolBar(self, QToolBar, cfg):
		'Create a Toolbar from configurations file'
		pxcfg = here+'z-data_/desktop.yaml'
		self.config = config.instruct(pxcfg).select(
								'docAddToolBar').override(cfg)#	||
		self.createToolBar()
		for button, cfg in self.config['buttons'].items():
			self.createButton(button, cfg)
	def createToolBar(self):
		self.toolbar = QToolBar()
		self.toolbar.setMovable(True)
		self.toolbar.setFloatable(True)
		self.toolbar.setOrientation(Qt.Vertical)
		return self
	def createButton(self, button, cfg):
		''
		toolbutton = QToolButton()
		toolbutton.setText(cfg['DisplayName'])
		toolbutton.setCheckable(cfg['checkable'])
		toolbutton.setAutoExclusive(cfg['setAutoExclusive'])
		self.toolbar.addWidget(toolbutton)
		return self
Пример #24
0
    def _create_toolbar(self):
        toolbar = QToolBar()
        toolbar.setFloatable(False)
        toolbar.setMovable(False)

        self.layout_combo = LayoutCombo()
        toolbar.addWidget(self.layout_combo)
        self.layout_combo.layout_changed.connect(self._plot_layout_changed)

        self._settings_button = QToolButton()
        self._settings_button.setToolTip("Toggle settings visibility")
        self._settings_button.setIcon(resource_icon("cog.png"))
        self._settings_button.setCheckable(True)
        self._settings_button.toggled.connect(self._show_settings)
        toolbar.addWidget(self._settings_button)

        def toggle_on_close(event):
            self._settings_button.setChecked(False)
            event.accept()

        self._settings_window.closeEvent = toggle_on_close

        return toolbar
Пример #25
0
class MainWindow_Ui(QMainWindow):
    def __init__(self, persepolis_setting):
        super().__init__()
        # MainWindow
        self.persepolis_setting = persepolis_setting

        icons = ':/' + \
            str(self.persepolis_setting.value('settings/icons')) + '/'

        self.setWindowTitle("Persepolis Download Manager")
        self.setWindowIcon(
            QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg')))

        self.centralwidget = QWidget(self)
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        # enable drag and drop
        self.setAcceptDrops(True)
        # frame
        self.frame = QFrame(self.centralwidget)

        # download_table_horizontalLayout
        download_table_horizontalLayout = QHBoxLayout()
        tabels_splitter = QSplitter(Qt.Horizontal)
        # category_tree
        self.category_tree_qwidget = QWidget(self)
        category_tree_verticalLayout = QVBoxLayout()
        self.category_tree = CategoryTreeView(self)
        category_tree_verticalLayout.addWidget(self.category_tree)

        self.category_tree_model = QStandardItemModel()
        self.category_tree.setModel(self.category_tree_model)
        category_table_header = ['Category']
        self.category_tree_model.setHorizontalHeaderLabels(
            category_table_header)
        self.category_tree.header().setStretchLastSection(True)

        # queue_panel
        self.queue_panel_widget = QWidget(self)

        queue_panel_verticalLayout_main = QVBoxLayout(self.queue_panel_widget)
        # queue_panel_show_button
        self.queue_panel_show_button = QPushButton(self)

        queue_panel_verticalLayout_main.addWidget(self.queue_panel_show_button)
        # queue_panel_widget_frame
        self.queue_panel_widget_frame = QFrame(self)
        self.queue_panel_widget_frame.setFrameShape(QFrame.StyledPanel)
        self.queue_panel_widget_frame.setFrameShadow(QFrame.Raised)

        queue_panel_verticalLayout_main.addWidget(
            self.queue_panel_widget_frame)

        queue_panel_verticalLayout = QVBoxLayout(self.queue_panel_widget_frame)
        queue_panel_verticalLayout_main.setContentsMargins(50, -1, 50, -1)

        # start_end_frame
        self.start_end_frame = QFrame(self)

        # start time
        start_verticalLayout = QVBoxLayout(self.start_end_frame)
        self.start_checkBox = QCheckBox(self)
        start_verticalLayout.addWidget(self.start_checkBox)

        self.start_frame = QFrame(self)
        self.start_frame.setFrameShape(QFrame.StyledPanel)
        self.start_frame.setFrameShadow(QFrame.Raised)

        start_frame_verticalLayout = QVBoxLayout(self.start_frame)

        self.start_time_qDataTimeEdit = QDateTimeEdit(self.start_frame)
        self.start_time_qDataTimeEdit.setDisplayFormat('H:mm')
        start_frame_verticalLayout.addWidget(self.start_time_qDataTimeEdit)

        start_verticalLayout.addWidget(self.start_frame)
        # end time

        self.end_checkBox = QCheckBox(self)
        start_verticalLayout.addWidget(self.end_checkBox)

        self.end_frame = QFrame(self)
        self.end_frame.setFrameShape(QFrame.StyledPanel)
        self.end_frame.setFrameShadow(QFrame.Raised)

        end_frame_verticalLayout = QVBoxLayout(self.end_frame)

        self.end_time_qDateTimeEdit = QDateTimeEdit(self.end_frame)
        self.end_time_qDateTimeEdit.setDisplayFormat('H:mm')
        end_frame_verticalLayout.addWidget(self.end_time_qDateTimeEdit)

        start_verticalLayout.addWidget(self.end_frame)

        self.reverse_checkBox = QCheckBox(self)
        start_verticalLayout.addWidget(self.reverse_checkBox)

        queue_panel_verticalLayout.addWidget(self.start_end_frame)

        # limit_after_frame
        self.limit_after_frame = QFrame(self)
        # limit_checkBox
        limit_verticalLayout = QVBoxLayout(self.limit_after_frame)
        self.limit_checkBox = QCheckBox(self)
        limit_verticalLayout.addWidget(self.limit_checkBox)
        # limit_frame
        self.limit_frame = QFrame(self)
        self.limit_frame.setFrameShape(QFrame.StyledPanel)
        self.limit_frame.setFrameShadow(QFrame.Raised)
        limit_verticalLayout.addWidget(self.limit_frame)

        limit_frame_verticalLayout = QVBoxLayout(self.limit_frame)
        # limit_spinBox
        limit_frame_horizontalLayout = QHBoxLayout()
        self.limit_spinBox = QDoubleSpinBox(self)
        self.limit_spinBox.setMinimum(1)
        self.limit_spinBox.setMaximum(1023)
        limit_frame_horizontalLayout.addWidget(self.limit_spinBox)
        # limit_comboBox
        self.limit_comboBox = QComboBox(self)
        self.limit_comboBox.addItem("")
        self.limit_comboBox.addItem("")
        limit_frame_horizontalLayout.addWidget(self.limit_comboBox)
        limit_frame_verticalLayout.addLayout(limit_frame_horizontalLayout)
        # limit_pushButton
        self.limit_pushButton = QPushButton(self)
        limit_frame_verticalLayout.addWidget(self.limit_pushButton)

        # after_checkBox
        self.after_checkBox = QtWidgets.QCheckBox(self)
        limit_verticalLayout.addWidget(self.after_checkBox)
        # after_frame
        self.after_frame = QtWidgets.QFrame(self)
        self.after_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.after_frame.setFrameShadow(QtWidgets.QFrame.Raised)
        limit_verticalLayout.addWidget(self.after_frame)

        after_frame_verticalLayout = QVBoxLayout(self.after_frame)
        # after_comboBox
        self.after_comboBox = QComboBox(self)
        self.after_comboBox.addItem("")

        after_frame_verticalLayout.addWidget(self.after_comboBox)
        # after_pushButton
        self.after_pushButton = QPushButton(self)
        after_frame_verticalLayout.addWidget(self.after_pushButton)

        queue_panel_verticalLayout.addWidget(self.limit_after_frame)
        category_tree_verticalLayout.addWidget(self.queue_panel_widget)

        # keep_awake_checkBox
        self.keep_awake_checkBox = QCheckBox(self)
        queue_panel_verticalLayout.addWidget(self.keep_awake_checkBox)

        self.category_tree_qwidget.setLayout(category_tree_verticalLayout)
        tabels_splitter.addWidget(self.category_tree_qwidget)

        # download table widget
        self.download_table_content_widget = QWidget(self)
        download_table_content_widget_verticalLayout = QVBoxLayout(
            self.download_table_content_widget)

        self.download_table = DownloadTableWidget(self)
        download_table_content_widget_verticalLayout.addWidget(
            self.download_table)
        tabels_splitter.addWidget(self.download_table_content_widget)

        self.download_table.setColumnCount(13)
        self.download_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.download_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.download_table.verticalHeader().hide()

        # hide gid and download dictioanry section
        self.download_table.setColumnHidden(8, True)
        self.download_table.setColumnHidden(9, True)

        download_table_header = [
            'File Name', 'Status', 'Size', 'Downloaded', 'Percentage',
            'Connections', 'Transfer rate', 'Estimate time left', 'Gid',
            'Link', 'First try date', 'Last try date', 'Category'
        ]
        self.download_table.setHorizontalHeaderLabels(download_table_header)

        # fixing the size of download_table when window is Maximized!
        self.download_table.horizontalHeader().setSectionResizeMode(0)
        self.download_table.horizontalHeader().setStretchLastSection(True)

        tabels_splitter.setStretchFactor(0, 3)  # category_tree width
        tabels_splitter.setStretchFactor(1, 10)  # ratio of tables's width
        download_table_horizontalLayout.addWidget(tabels_splitter)
        self.frame.setLayout(download_table_horizontalLayout)
        self.verticalLayout.addWidget(self.frame)
        self.setCentralWidget(self.centralwidget)

        # menubar
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QRect(0, 0, 600, 24))
        self.setMenuBar(self.menubar)
        fileMenu = self.menubar.addMenu('&File')
        editMenu = self.menubar.addMenu('&Edit')
        viewMenu = self.menubar.addMenu('&View')
        downloadMenu = self.menubar.addMenu('&Download')
        queueMenu = self.menubar.addMenu('&Queue')
        helpMenu = self.menubar.addMenu('&Help')

        # viewMenu submenus
        sortMenu = viewMenu.addMenu('Sort by')
        # statusbar
        self.statusbar = QStatusBar(self)
        self.setStatusBar(self.statusbar)
        self.statusbar.showMessage("Persepolis Download Manager")
        # toolBar
        self.toolBar2 = QToolBar(self)
        self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar2)
        self.toolBar2.setWindowTitle('Menu')
        self.toolBar2.setIconSize(QSize(32, 32))
        self.toolBar2.setFloatable(False)
        self.toolBar2.setMovable(False)

        self.toolBar = QToolBar(self)
        self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.toolBar.setWindowTitle('Toolbar')
        self.toolBar.setIconSize(QSize(32, 32))
        self.toolBar.setFloatable(False)
        self.toolBar.setMovable(False)

        #toolBar and menubar and actions
        self.stopAllAction = QAction(QIcon(icons + 'stop_all'),
                                     'Stop all active downloads',
                                     self,
                                     statusTip='Stop all active downloads',
                                     triggered=self.stopAllDownloads)
        downloadMenu.addAction(self.stopAllAction)

        self.sort_file_name_Action = QAction('File name',
                                             self,
                                             triggered=self.sortByName)
        sortMenu.addAction(self.sort_file_name_Action)

        self.sort_file_size_Action = QAction('File size',
                                             self,
                                             triggered=self.sortBySize)
        sortMenu.addAction(self.sort_file_size_Action)

        self.sort_first_try_date_Action = QAction(
            'First try date', self, triggered=self.sortByFirstTry)
        sortMenu.addAction(self.sort_first_try_date_Action)

        self.sort_last_try_date_Action = QAction('Last try date',
                                                 self,
                                                 triggered=self.sortByLastTry)
        sortMenu.addAction(self.sort_last_try_date_Action)

        self.sort_download_status_Action = QAction('Download status',
                                                   self,
                                                   triggered=self.sortByStatus)
        sortMenu.addAction(self.sort_download_status_Action)

        self.trayAction = QAction('Show system tray icon',
                                  self,
                                  statusTip="Show/Hide system tray icon",
                                  triggered=self.showTray)
        self.trayAction.setCheckable(True)
        viewMenu.addAction(self.trayAction)

        self.showMenuBarAction = QAction('Show menubar',
                                         self,
                                         statusTip='Show menubar',
                                         triggered=self.showMenuBar)
        self.showMenuBarAction.setCheckable(True)
        viewMenu.addAction(self.showMenuBarAction)

        self.showSidePanelAction = QAction('Show side panel',
                                           self,
                                           statusTip='Show side panel',
                                           triggered=self.showSidePanel)
        self.showSidePanelAction.setCheckable(True)
        viewMenu.addAction(self.showSidePanelAction)

        self.minimizeAction = QAction(QIcon(icons + 'minimize'),
                                      'Minimize to system tray',
                                      self,
                                      shortcut="Ctrl+W",
                                      statusTip="Minimize to system tray",
                                      triggered=self.minMaxTray)
        viewMenu.addAction(self.minimizeAction)

        self.addlinkAction = QAction(QIcon(icons + 'add'),
                                     'Add New Download Link',
                                     self,
                                     shortcut="Ctrl+N",
                                     statusTip="Add New Download Link",
                                     triggered=self.addLinkButtonPressed)
        fileMenu.addAction(self.addlinkAction)

        self.addtextfileAction = QAction(
            QIcon(icons + 'file'),
            'Import links from text file',
            self,
            statusTip='Create a Text file and put links in it.line by line!',
            triggered=self.importText)
        fileMenu.addAction(self.addtextfileAction)

        self.resumeAction = QAction(QIcon(icons + 'play'),
                                    'Resume Download',
                                    self,
                                    shortcut="Ctrl+R",
                                    statusTip="Resume Download",
                                    triggered=self.resumeButtonPressed)
        downloadMenu.addAction(self.resumeAction)

        self.pauseAction = QAction(QIcon(icons + 'pause'),
                                   'Pause Download',
                                   self,
                                   shortcut="Ctrl+C",
                                   statusTip="Pause Download",
                                   triggered=self.pauseButtonPressed)
        downloadMenu.addAction(self.pauseAction)

        self.stopAction = QAction(QIcon(icons + 'stop'),
                                  'Stop Download',
                                  self,
                                  shortcut="Ctrl+S",
                                  statusTip="Stop/Cancel Download",
                                  triggered=self.stopButtonPressed)
        downloadMenu.addAction(self.stopAction)

        self.removeAction = QAction(QIcon(icons + 'remove'),
                                    'Remove Download',
                                    self,
                                    shortcut="Ctrl+D",
                                    statusTip="Remove Download",
                                    triggered=self.removeButtonPressed)
        downloadMenu.addAction(self.removeAction)

        self.propertiesAction = QAction(QIcon(icons + 'setting'),
                                        'Properties',
                                        self,
                                        shortcut="Ctrl+P",
                                        statusTip="Properties",
                                        triggered=self.propertiesButtonPressed)
        downloadMenu.addAction(self.propertiesAction)

        self.progressAction = QAction(QIcon(icons + 'window'),
                                      'Progress',
                                      self,
                                      shortcut="Ctrl+Z",
                                      statusTip="Progress",
                                      triggered=self.progressButtonPressed)
        downloadMenu.addAction(self.progressAction)

        self.openFileAction = QAction(QIcon(icons + 'file'),
                                      'Open file',
                                      self,
                                      statusTip='Open file',
                                      triggered=self.openFile)
        fileMenu.addAction(self.openFileAction)

        self.openDownloadFolderAction = QAction(
            QIcon(icons + 'folder'),
            'Open download folder',
            self,
            statusTip='Open download folder',
            triggered=self.openDownloadFolder)
        fileMenu.addAction(self.openDownloadFolderAction)

        self.deleteFileAction = QAction(QIcon(icons + 'trash'),
                                        'Delete file',
                                        self,
                                        statusTip='Delete file',
                                        triggered=self.deleteFile)
        fileMenu.addAction(self.deleteFileAction)

        self.openDefaultDownloadFolderAction = QAction(
            QIcon(icons + 'folder'),
            'Open default download folder',
            self,
            statusTip='Open default download folder',
            triggered=self.openDefaultDownloadFolder)
        fileMenu.addAction(self.openDefaultDownloadFolderAction)

        self.exitAction = QAction(QIcon(icons + 'exit'),
                                  'Exit',
                                  self,
                                  shortcut="Ctrl+Q",
                                  statusTip="Exit",
                                  triggered=self.closeEvent)
        fileMenu.addAction(self.exitAction)

        self.selectAction = QAction('Select multiple items ',
                                    self,
                                    statusTip='Select multiple items',
                                    triggered=self.selectDownloads)
        self.selectAction.setCheckable(True)
        editMenu.addAction(self.selectAction)

        self.selectAllAction = QAction(QIcon(icons + 'select_all'),
                                       'Select All',
                                       self,
                                       statusTip='Select All',
                                       triggered=self.selectAll)
        editMenu.addAction(self.selectAllAction)
        self.selectAllAction.setEnabled(False)

        self.removeSelectedAction = QAction(
            QIcon(icons + 'multi_remove'),
            'Remove selected downloads form list',
            self,
            statusTip='Remove selected downloads form list',
            triggered=self.removeSelected)
        editMenu.addAction(self.removeSelectedAction)
        self.removeSelectedAction.setEnabled(False)

        self.deleteSelectedAction = QAction(
            QIcon(icons + 'multi_trash'),
            'Delete selected download files',
            self,
            statusTip='Delete selected download files',
            triggered=self.deleteSelected)
        editMenu.addAction(self.deleteSelectedAction)
        self.deleteSelectedAction.setEnabled(False)

        self.createQueueAction = QAction(QIcon(icons + 'add_queue'),
                                         'Create new queue',
                                         self,
                                         statusTip='Create new download queue',
                                         triggered=self.createQueue)
        queueMenu.addAction(self.createQueueAction)

        self.removeQueueAction = QAction(QIcon(icons + 'remove_queue'),
                                         'Remove this queue',
                                         self,
                                         statusTip='Remove this queue',
                                         triggered=self.removeQueue)
        queueMenu.addAction(self.removeQueueAction)

        self.startQueueAction = QAction(QIcon(icons + 'start_queue'),
                                        'Start this queue',
                                        self,
                                        statusTip='Start this queue',
                                        triggered=self.startQueue)
        queueMenu.addAction(self.startQueueAction)

        self.stopQueueAction = QAction(QIcon(icons + 'stop_queue'),
                                       'Stop this queue',
                                       self,
                                       statusTip='Stop this queue',
                                       triggered=self.stopQueue)
        queueMenu.addAction(self.stopQueueAction)

        self.moveUpAction = QAction(
            QIcon(icons + 'up'),
            'Move up this item',
            self,
            statusTip='Move currently selected item up by one row',
            triggered=self.moveUp)
        queueMenu.addAction(self.moveUpAction)

        self.moveDownAction = QAction(
            QIcon(icons + 'down'),
            'Move down this item',
            self,
            statusTip='Move currently selected item down by one row',
            triggered=self.moveDown)
        queueMenu.addAction(self.moveDownAction)

        self.moveUpSelectedAction = QAction(
            QIcon(icons + 'multi_up'),
            'Move up selected items',
            self,
            statusTip='Move currently selected items up by one row',
            triggered=self.moveUpSelected)
        queueMenu.addAction(self.moveUpSelectedAction)

        self.moveDownSelectedAction = QAction(
            QIcon(icons + 'multi_down'),
            'Move down selected items',
            self,
            statusTip='Move currently selected items down by one row',
            triggered=self.moveDownSelected)
        queueMenu.addAction(self.moveDownSelectedAction)

        self.preferencesAction = QAction(QIcon(icons + 'preferences'),
                                         'Preferences',
                                         self,
                                         statusTip='Preferences',
                                         triggered=self.openPreferences,
                                         menuRole=5)
        editMenu.addAction(self.preferencesAction)

        self.aboutAction = QAction(QIcon(icons + 'about'),
                                   'About',
                                   self,
                                   statusTip='About',
                                   triggered=self.openAbout,
                                   menuRole=4)
        helpMenu.addAction(self.aboutAction)

        self.issueAction = QAction(QIcon(icons + 'about'),
                                   'Report an issue',
                                   self,
                                   statusTip='Report an issue',
                                   triggered=self.reportIssue)
        helpMenu.addAction(self.issueAction)

        self.updateAction = QAction(QIcon(icons + 'about'),
                                    'Check for newer version',
                                    self,
                                    statusTip='Check for newer release',
                                    triggered=self.newUpdate)
        helpMenu.addAction(self.updateAction)

        self.logAction = QAction(QIcon(icons + 'about'),
                                 'Show log file',
                                 self,
                                 statusTip='Help',
                                 triggered=self.showLog)
        helpMenu.addAction(self.logAction)

        self.helpAction = QAction(QIcon(icons + 'about'),
                                  'Help',
                                  self,
                                  statusTip='Help',
                                  triggered=self.persepolisHelp)
        helpMenu.addAction(self.helpAction)

        self.qmenu = MenuWidget(self)

        self.toolBar2.addWidget(self.qmenu)

        # labels
        self.queue_panel_show_button.setText("Hide options")
        self.start_checkBox.setText("Start Time")

        self.end_checkBox.setText("End Time")

        self.reverse_checkBox.setText("Download bottom of\n the list first")

        self.limit_checkBox.setText("Limit Speed")
        self.limit_comboBox.setItemText(0, "KB/S")
        self.limit_comboBox.setItemText(1, "MB/S")
        self.limit_pushButton.setText("Apply")

        self.after_checkBox.setText("After download")
        self.after_comboBox.setItemText(0, "Shut Down")

        self.keep_awake_checkBox.setText("Keep system awake!")
        self.keep_awake_checkBox.setToolTip(
            "<html><head/><body><p>This option is preventing system from going to sleep.\
            This is necessary if your power manager is suspending system automatically. </p></body></html>"
        )

        self.after_pushButton.setText("Apply")

    def changeIcon(self, icons):
        icons = ':/' + str(icons) + '/'

        action_icon_dict = {
            self.stopAllAction: 'stop_all',
            self.minimizeAction: 'minimize',
            self.addlinkAction: 'add',
            self.addtextfileAction: 'file',
            self.resumeAction: 'play',
            self.pauseAction: 'pause',
            self.stopAction: 'stop',
            self.removeAction: 'remove',
            self.propertiesAction: 'setting',
            self.progressAction: 'window',
            self.openFileAction: 'file',
            self.openDownloadFolderAction: 'folder',
            self.deleteFileAction: 'trash',
            self.openDefaultDownloadFolderAction: 'folder',
            self.exitAction: 'exit',
            self.selectAllAction: 'select_all',
            self.removeSelectedAction: 'multi_remove',
            self.deleteSelectedAction: 'multi_trash',
            self.createQueueAction: 'add_queue',
            self.removeQueueAction: 'remove_queue',
            self.startQueueAction: 'start_queue',
            self.stopQueueAction: 'stop_queue',
            self.moveUpAction: 'up',
            self.moveDownAction: 'down',
            self.preferencesAction: 'preferences',
            self.aboutAction: 'about',
            self.issueAction: 'about',
            self.updateAction: 'about',
            self.qmenu: 'menu'
        }
        for key in action_icon_dict.keys():
            key.setIcon(QIcon(icons + str(action_icon_dict[key])))
Пример #26
0
class MainWindow(QMainWindow):
    """This is the main application window class

    it defines the GUI window for the browser
    """
    def parse_config(self, file_config, options):
        self.config = {}
        options = vars(options)
        for key, metadata in CONFIG_OPTIONS.items():
            options_val = options.get(key)
            file_val = file_config.get(key)
            env_val = os.environ.get(metadata.get("env", ''))
            default_val = metadata.get("default")
            vals = metadata.get("values")
            debug("key: {}, default: {}, file: {}, options: {}".format(
                key, default_val, file_val, options_val))
            if vals:
                options_val = (options_val in vals and options_val) or None
                file_val = (file_val in vals and file_val) or None
                env_val = (env_val in vals and env_val) or None
            if metadata.get("is_file"):
                filename = options_val or env_val
                if not filename:
                    self.config[key] = default_val
                else:
                    try:
                        with open(filename, 'r') as fh:
                            self.config[key] = fh.read()
                    except IOError:
                        debug("Could not open file {} for reading.".format(
                            filename))
                        self.config[key] = default_val
            else:
                set_values = [
                    val for val in (options_val, env_val, file_val)
                    if val is not None
                ]
                if len(set_values) > 0:
                    self.config[key] = set_values[0]
                else:
                    self.config[key] = default_val
            if metadata.get("type") and self.config[key]:
                debug("{} cast to {}".format(key, metadata.get("type")))
                self.config[key] = metadata.get("type")(self.config[key])
        debug(repr(self.config))

    def createAction(self,
                     text,
                     slot=None,
                     shortcut=None,
                     icon=None,
                     tip=None,
                     checkable=False,
                     signal="triggered"):
        """Return a QAction given a number of common QAction attributes

        Just a shortcut function Originally borrowed from
        'Rapid GUI Development with PyQT' by Mark Summerset
        """
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(
                QIcon.fromTheme(icon, QIcon(":/{}.png".format(icon))))
        if shortcut is not None and not shortcut.isEmpty():
            action.setShortcut(shortcut)
            tip += " ({})".format(shortcut.toString())
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            action.__getattr__(signal).connect(slot)
        if checkable:
            action.setCheckable()
        return action

    def __init__(self, options, parent=None):
        """Construct a MainWindow Object."""
        super(MainWindow, self).__init__(parent)
        # Load config file
        self.setWindowTitle("Browser")
        debug("loading configuration from '{}'".format(options.config_file))
        configfile = {}
        if options.config_file:
            configfile = yaml.safe_load(open(options.config_file, 'r'))
        self.parse_config(configfile, options)
        # self.popup will hold a reference to the popup window
        # if it gets opened
        self.popup = None

        # Stylesheet support
        if self.config.get("stylesheet"):
            try:
                with open(self.config.get("stylesheet")) as ss:
                    self.setStyleSheet(ss.read())
            except:
                debug(('Problem loading stylesheet file "{}", '
                       'using default style.').format(
                           self.config.get("stylesheet")))
        self.setObjectName("global")

        # Set proxy server environment variable before creating web views
        if self.config.get("proxy_server"):
            os.environ["http_proxy"] = self.config.get("proxy_server")
            os.environ["https_proxy"] = self.config.get("proxy_server")

        # If the whitelist is activated, add the bookmarks and start_url
        if self.config.get("whitelist"):
            # we can just specify whitelist = True,
            # which should whitelist just the start_url and bookmark urls.
            if type(self.config.get("whitelist")) is not list:
                self.whitelist = []
            self.whitelist.append(
                str(QUrl(self.config.get("start_url")).host()))
            bookmarks = self.config.get("bookmarks")
            if bookmarks:
                self.whitelist += [
                    str(QUrl(b.get("url")).host())
                    for k, b in bookmarks.items()
                ]
                self.whitelist = set(self.whitelist)  # uniquify and optimize
            debug("Generated whitelist: " + str(self.whitelist))

        # create the web engine profile
        self.create_webprofile()

        # Now construct the UI
        self.build_ui()

    # ## END OF CONSTRUCTOR ## #

    def create_webprofile(self):
        """Create a webengineprofile to use in all views."""
        if self.config.get("privacy_mode"):
            webprofile = QWebEngineProfile()
        else:
            webprofile = QWebEngineProfile.defaultProfile()
        debug("Browser session is private: {}".format(
            webprofile.isOffTheRecord()))
        if self.config.get("user_agent"):
            webprofile.setHttpUserAgent(self.config["user_agent"])
            debug('Set user agent to "{}"'.format(webprofile.httpUserAgent()))
        self.webprofile = webprofile

    def build_ui(self):
        """Set up the user interface for the main window.

        Unlike the constructor, this method is re-run
        whenever the browser is "reset" by the user.
        """

        debug("build_ui")
        inactivity_timeout = self.config.get("timeout")
        quit_button_tooltip = ("Click here to quit"
                               if self.config.get('quit_button_mode')
                               == 'close' else "Click here when you are done"
                               "\nIt will clear your browsing history"
                               " and return you to the start page.")
        qb_mode_callbacks = {'close': self.close, 'reset': self.reset_browser}
        to_mode_callbacks = {
            'close': self.close,
            'reset': self.reset_browser,
            'screensaver': self.screensaver
        }
        self.screensaver_active = False

        # ##Start GUI configuration## #
        self.browser_window = AdmWebView(self.config,
                                         webprofile=self.webprofile)
        self.browser_window.setObjectName("web_content")
        self.setCentralWidget(self.browser_window)

        # Icon theme setting
        QIcon.setThemeName(self.config.get("icon_theme"))

        self.setCentralWidget(self.browser_window)
        debug("loading {}".format(self.config.get("start_url")))
        self.browser_window.setUrl(QUrl(self.config.get("start_url")))

        # Window size settings
        window_size = self.config.get("window_size", '').lower()
        if window_size == 'full':
            self.showFullScreen()
        elif window_size == 'max':
            self.showMaximized()
        elif window_size:
            size = re.match(r"(\d+)x(\d+)", window_size)
            if size:
                width, height = size.groups()
                self.setFixedSize(int(width), int(height))
            else:
                debug('Ignoring invalid window size "{}"'.format(window_size))

        # Set up the top navigation bar if it's configured to exist
        if self.config.get("navigation"):
            self.navigation_bar = QToolBar("Navigation")
            self.navigation_bar.setObjectName("navigation")
            self.addToolBar(Qt.TopToolBarArea, self.navigation_bar)
            self.navigation_bar.setMovable(False)
            self.navigation_bar.setFloatable(False)

            #  Standard navigation tools
            self.nav_items = {
                "back":
                self.browser_window.pageAction(AdmWebPage.Back),
                "forward":
                self.browser_window.pageAction(AdmWebPage.Forward),
                "refresh":
                self.browser_window.pageAction(AdmWebPage.Reload),
                "stop":
                self.browser_window.pageAction(AdmWebPage.Stop),
                "quit":
                self.createAction(
                    self.config.get("quit_button_text"),
                    qb_mode_callbacks.get(self.config.get("quit_button_mode"),
                                          self.reset_browser),
                    QKeySequence("Alt+F"), None, quit_button_tooltip),
                "zoom_in":
                self.createAction(
                    "Zoom In", self.zoom_in, QKeySequence("Alt++"), "zoom-in",
                    "Increase the size of the text and images on the page"),
                "zoom_out":
                self.createAction(
                    "Zoom Out", self.zoom_out, QKeySequence("Alt+-"),
                    "zoom-out",
                    "Decrease the size of text and images on the page")
            }
            if self.config.get("allow_printing"):
                self.nav_items["print"] = self.createAction(
                    "Print", self.browser_window.print_webpage,
                    QKeySequence("Ctrl+p"), "document-print",
                    "Print this page")

            # Add all the actions to the navigation bar.
            for item in self.config.get("navigation_layout"):
                if item == "separator":
                    self.navigation_bar.addSeparator()
                elif item == "spacer":
                    # an expanding spacer.
                    spacer = QWidget()
                    spacer.setSizePolicy(QSizePolicy.Expanding,
                                         QSizePolicy.Preferred)
                    self.navigation_bar.addWidget(spacer)
                elif item == "bookmarks":
                    # Insert bookmarks buttons here.
                    self.bookmark_buttons = []
                    for bookmark in self.config.get("bookmarks", {}).items():
                        debug("Bookmark:\n" + bookmark.__str__())
                        # bookmark name will use the "name" attribute,
                        # if present, or else just the key:
                        bookmark_name = bookmark[1].get("name") or bookmark[0]
                        # Create a button for the bookmark as a QAction,
                        # which we'll add to the toolbar
                        button = self.createAction(
                            bookmark_name, (lambda url=bookmark[1].get(
                                "url"): self.browser_window.load(QUrl(url))),
                            QKeySequence.mnemonic(bookmark_name), None,
                            bookmark[1].get("description"))
                        self.navigation_bar.addAction(button)
                        (self.navigation_bar.widgetForAction(
                            button).setObjectName("navigation_button"))
                else:
                    action = self.nav_items.get(item, None)
                    if action:
                        self.navigation_bar.addAction(action)
                        (self.navigation_bar.widgetForAction(
                            action).setObjectName("navigation_button"))

            # This removes the ability to toggle off the navigation bar:
            self.nav_toggle = self.navigation_bar.toggleViewAction()
            self.nav_toggle.setVisible(False)
            # End "if show_navigation is True" block

        # set hidden quit action
        # For reasons I haven't adequately ascertained,
        # this shortcut fails now and then claiming
        # "Ambiguous shortcut overload".
        # No idea why, as it isn't consistent.
        self.really_quit = self.createAction("", self.close,
                                             QKeySequence("Ctrl+Alt+Q"), None,
                                             "")
        self.addAction(self.really_quit)

        # Call a reset function after timeout
        if inactivity_timeout != 0:
            self.event_filter = InactivityFilter(inactivity_timeout)
            QCoreApplication.instance().installEventFilter(self.event_filter)
            self.browser_window.page().installEventFilter(self.event_filter)
            self.event_filter.timeout.connect(
                to_mode_callbacks.get(self.config.get("timeout_mode"),
                                      self.reset_browser))
        else:
            self.event_filter = None

        # ##END OF UI SETUP## #

    def screensaver(self):
        """Enter "screensaver" mode

        This method puts the browser in screensaver mode, where a URL
        is displayed while the browser is idle.  Activity causes the browser to
        return to the home screen.
        """
        debug("screensaver started")
        self.screensaver_active = True
        if self.popup:
            self.popup.close()
        if self.config.get("navigation"):
            self.navigation_bar.hide()
        self.browser_window.setZoomFactor(self.config.get("zoom_factor"))
        self.browser_window.load(QUrl(self.config.get("screensaver_url")))
        self.event_filter.timeout.disconnect()
        self.event_filter.activity.connect(self.reset_browser)

    def reset_browser(self):
        """Clear the history and reset the UI.

        Called whenever the inactivity filter times out,
        or when the user clicks the "finished" button in
        'reset' mode.
        """
        # Clear out the memory cache
        #QWebEngineSettings.clearMemoryCaches()
        self.browser_window.history().clear()
        # self.navigation_bar.clear() doesn't do its job,
        # so remove the toolbar first, then rebuild the UI.
        debug("RESET BROWSER")
        if self.event_filter:
            self.event_filter.blockSignals(True)
        if self.screensaver_active is True:
            self.screensaver_active = False
            self.event_filter.activity.disconnect()
        if self.event_filter:
            self.event_filter.blockSignals(False)
        if hasattr(self, "navigation_bar"):
            self.removeToolBar(self.navigation_bar)
        self.build_ui()

    def zoom_in(self):
        """Zoom in action callback.

        Note that we cap zooming in at a factor of 3x.
        """
        if self.browser_window.zoomFactor() < 3.0:
            self.browser_window.setZoomFactor(
                self.browser_window.zoomFactor() + 0.1)
            self.nav_items["zoom_out"].setEnabled(True)
        else:
            self.nav_items["zoom_in"].setEnabled(False)

    def zoom_out(self):
        """Zoom out action callback.

        Note that we cap zooming out at 0.1x.
        """
        if self.browser_window.zoomFactor() > 0.1:
            self.browser_window.setZoomFactor(
                self.browser_window.zoomFactor() - 0.1)
            self.nav_items["zoom_in"].setEnabled(True)
        else:
            self.nav_items["zoom_out"].setEnabled(False)
Пример #27
0
class AppWindow(QMainWindow):
	"The application's main window"
	move_listener = pyqtSignal()
	db_activity_checker = pyqtSignal()
	graphics_blur = QGraphicsBlurEffect()
	def __init__(self):
		super().__init__()
		app_constants.GENERAL_THREAD = QThread(self)
		app_constants.GENERAL_THREAD.finished.connect(app_constants.GENERAL_THREAD.deleteLater)
		app_constants.GENERAL_THREAD.start()
		self.setAcceptDrops(True)
		self.initUI()
		self.start_up()
		QTimer.singleShot(3000, self._check_update)
		self.setFocusPolicy(Qt.NoFocus)
		self.set_shortcuts()
		self.graphics_blur.setParent(self)
		#ex = settings.ExProperties()
		#d = pewnet.ExHenManager(ex.ipb_id, ex.ipb_pass)
		#item = d.from_gallery_url('http://exhentai.org/g/861957/02741dc584/')
		#def a(): print(item.file)
		#if not item.file:
		#	item.file_rdy.connect(a)
		#else:
		#	a()

	def set_shortcuts(self):
		quit = QShortcut(QKeySequence('Ctrl+Q'), self, self.close)

	def init_watchers(self):

		def remove_gallery(g):
			index = self.manga_list_view.find_index(g.id, True)
			if index:
				self.manga_list_view.remove_gallery([index])

		def create_gallery(path):
			g_dia = gallerydialog.GalleryDialog(self, path)
			g_dia.SERIES.connect(self.manga_list_view.gallery_model.addRows)
			g_dia.show()

		def update_gallery(g):
			index = self.manga_list_view.find_index(g.id)
			if index:
				self.manga_list_view.replace_edit_gallery([g], index.row())
			else:
				log_e('Could not find gallery to update from watcher')

		def created(path):
			c_popup = io_misc.CreatedPopup(path, self)
			c_popup.ADD_SIGNAL.connect(create_gallery)
		def modified(path, gallery):
			mod_popup = io_misc.ModifiedPopup(path, gallery, self)
		def deleted(path, gallery):
			d_popup = io_misc.DeletedPopup(path, gallery, self)
			d_popup.UPDATE_SIGNAL.connect(update_gallery)
			d_popup.REMOVE_SIGNAL.connect(remove_gallery)
		def moved(new_path, gallery):
			mov_popup = io_misc.MovedPopup(new_path, gallery, self)
			mov_popup.UPDATE_SIGNAL.connect(update_gallery)

		self.watchers = io_misc.Watchers()
		self.watchers.gallery_handler.CREATE_SIGNAL.connect(created)
		self.watchers.gallery_handler.MODIFIED_SIGNAL.connect(modified)
		self.watchers.gallery_handler.MOVED_SIGNAL.connect(moved)
		self.watchers.gallery_handler.DELETED_SIGNAL.connect(deleted)

	admin_db_method_invoker = pyqtSignal(str)
	def start_up(self):
		hello = ["Hello!", "Hi!", "Onii-chan!", "Senpai!", "Hisashiburi!", "Welcome!", "Okaerinasai!", "Welcome back!", "Hajimemashite!"]
		self.notification_bar.add_text("{} Please don't hesitate to report any bugs you find.".format(hello[random.randint(0, len(hello)-1)])+
								 " Go to Settings -> About -> Bug Reporting for more info!")
		level = 5
		def normalize_first_time():
			settings.set(level, 'Application', 'first time level')
			settings.save()

		def done(status=True):
			gallerydb.DatabaseEmitter.RUN = True
			if app_constants.FIRST_TIME_LEVEL != level:
				normalize_first_time()
			if app_constants.ENABLE_MONITOR and\
				app_constants.MONITOR_PATHS and all(app_constants.MONITOR_PATHS):
				self.init_watchers()
				if app_constants.LOOK_NEW_GALLERY_STARTUP:
					if self.manga_list_view.gallery_model.db_emitter.count == app_constants.GALLERY_DATA:
						self.scan_for_new_galleries()
					else:
						self.manga_list_view.gallery_model.db_emitter.DONE.connect(self.scan_for_new_galleries)
			self.download_manager = pewnet.Downloader()
			app_constants.DOWNLOAD_MANAGER = self.download_manager
			self.download_manager.start_manager(4)

		if app_constants.FIRST_TIME_LEVEL < 4:
			log_i('Invoking first time level {}'.format(4))
			settings.set([], 'Application', 'monitor paths')
			settings.set([], 'Application', 'ignore paths')
			app_constants.MONITOR_PATHS = []
			app_constants.IGNORE_PATHS = []
			settings.save()
			done()
		elif app_constants.FIRST_TIME_LEVEL < 5:
			log_i('Invoking first time level {}'.format(5))
			app_widget = misc.ApplicationPopup(self)
			app_widget.note_info.setText("<font color='red'>IMPORTANT:</font> Application restart is required when done")
			app_widget.restart_info.hide()
			self.admin_db = gallerydb.AdminDB()
			self.admin_db.moveToThread(app_constants.GENERAL_THREAD)
			self.admin_db.DONE.connect(done)
			self.admin_db.DONE.connect(lambda: app_constants.NOTIF_BAR.add_text("Application requires a restart"))
			self.admin_db.DONE.connect(self.admin_db.deleteLater)
			self.admin_db.DATA_COUNT.connect(app_widget.prog.setMaximum)
			self.admin_db.PROGRESS.connect(app_widget.prog.setValue)
			self.admin_db_method_invoker.connect(self.admin_db.rebuild_db)
			self.admin_db_method_invoker.connect(app_widget.show)
			app_widget.adjustSize()
			db_p = os.path.join(os.path.split(database.db_constants.DB_PATH)[0], 'sadpanda.db')
			self.admin_db_method_invoker.emit(db_p)
		else:
			done()

	def initUI(self):
		self.center = QWidget()
		self.display = QStackedLayout()
		self._main_layout = QVBoxLayout()
		self._main_layout.setSpacing(0)
		self._main_layout.setContentsMargins(0,0,0,0)
		self._main_layout.addLayout(self.display)
		self.center.setLayout(self._main_layout)
		# init the manga view variables
		self.manga_display()
		log_d('Create manga display: OK')
		# init the chapter view variables
		#self.chapter_display()
		self.m_l_view_index = self.display.addWidget(self.manga_list_view)
		self.m_t_view_index = self.display.addWidget(self.manga_table_view)
		self.download_window = io_misc.GalleryDownloader(self)
		self.download_window.hide()
		# init toolbar
		self.init_toolbar()
		log_d('Create toolbar: OK')
		# init status bar
		self.init_stat_bar()
		log_d('Create statusbar: OK')

		self.tags_treeview = None
		if app_constants.TAGS_TREEVIEW_ON_START:
			def tags_tree_none(): self.tags_treeview = None
			self.tags_treeview = misc_db.DBOverview(self, True)
			self.tags_treeview.about_to_close.connect(tags_tree_none)
			self.tags_treeview.show()

		self.system_tray = misc.SystemTray(QIcon(app_constants.APP_ICO_PATH), self)
		app_constants.SYSTEM_TRAY = self.system_tray
		tray_menu = QMenu(self)
		self.system_tray.setContextMenu(tray_menu)
		self.system_tray.setToolTip('Happypanda {}'.format(app_constants.vs))
		tray_quit = QAction('Quit', tray_menu)
		tray_update = tray_menu.addAction('Check for update')
		tray_update.triggered.connect(self._check_update)
		tray_menu.addAction(tray_quit)
		tray_quit.triggered.connect(self.close)
		self.system_tray.show()
		def tray_activate(r=None):
			if not r or r == QSystemTrayIcon.Trigger:
				self.showNormal()
				self.activateWindow()
		self.system_tray.messageClicked.connect(tray_activate)
		self.system_tray.activated.connect(tray_activate)
		log_d('Create system tray: OK')
		#self.display.addWidget(self.chapter_main)

		self.setCentralWidget(self.center)
		self.setWindowIcon(QIcon(app_constants.APP_ICO_PATH))


		props = settings.win_read(self, 'AppWindow')
		if props.resize:
			x, y = props.resize
			self.resize(x, y)
		else:
			self.resize(app_constants.MAIN_W, app_constants.MAIN_H)
		posx, posy = props.pos
		self.move(posx, posy)
		self.init_spinners()
		self.show()
		log_d('Show window: OK')

		self.notification_bar = misc.NotificationOverlay(self)
		p = self.toolbar.pos()
		self.notification_bar.move(p.x(), p.y()+self.toolbar.height())
		self.notification_bar.resize(self.width())
		app_constants.NOTIF_BAR = self.notification_bar
		log_d('Create notificationbar: OK')

		log_d('Window Create: OK')

	def _check_update(self):
		class upd_chk(QObject):
			UPDATE_CHECK = pyqtSignal(str)
			def __init__(self, **kwargs):
				super().__init__(**kwargs)
			def fetch_vs(self):
				import requests
				import time
				log_d('Checking Update')
				time.sleep(1.5)
				try:
					if os.path.exists('cacert.pem'):
						r = requests.get("https://raw.githubusercontent.com/Pewpews/happypanda/master/VS.txt",
							  verify='cacert.pem')
					else:
						r = requests.get("https://raw.githubusercontent.com/Pewpews/happypanda/master/VS.txt")
					a = r.text
					vs = a.strip()
					self.UPDATE_CHECK.emit(vs)
				except:
					log.exception('Checking Update: FAIL')
					self.UPDATE_CHECK.emit('this is a very long text which is sure to be over limit')

		def check_update(vs):
			log_i('Received version: {}\nCurrent version: {}'.format(vs, app_constants.vs))
			if vs != app_constants.vs:
				if len(vs) < 10:
					self.notification_bar.begin_show()
					self.notification_bar.add_text("Version {} of Happypanda is".format(vs)+
									   " available. Click here to update!", False)
					self.notification_bar.clicked.connect(lambda: utils.open_web_link(
						'https://github.com/Pewpews/happypanda/releases'))
					self.notification_bar.set_clickable(True)
				else:
					self.notification_bar.add_text("An error occurred while checking for new version")

		self.update_instance = upd_chk()
		thread = QThread(self)
		self.update_instance.moveToThread(thread)
		thread.started.connect(self.update_instance.fetch_vs)
		self.update_instance.UPDATE_CHECK.connect(check_update)
		self.update_instance.UPDATE_CHECK.connect(self.update_instance.deleteLater)
		thread.finished.connect(thread.deleteLater)
		thread.start()

	def _web_metadata_picker(self, gallery, title_url_list, queue, parent=None):
		if not parent:
			parent = self
		text = "Which gallery do you want to extract metadata from?"
		s_gallery_popup = misc.SingleGalleryChoices(gallery, title_url_list,
											  text, parent)
		s_gallery_popup.USER_CHOICE.connect(queue.put)

	def get_metadata(self, gal=None):
		metadata_spinner = misc.Spinner(self)
		def move_md_spinner():
			metadata_spinner.update_move(
			QPoint(
				self.pos().x()+self.width()-65,
				self.pos().y()+self.toolbar.height()+55))
		metadata_spinner.set_text("Metadata")
		metadata_spinner.set_size(55)
		metadata_spinner.move(QPoint(self.pos().x()+self.width()-65,
							   self.pos().y()+self.toolbar.height()+55))
		self.move_listener.connect(move_md_spinner)
		thread = QThread(self)
		thread.setObjectName('App.get_metadata')
		fetch_instance = fetch.Fetch()
		if gal:
			if not isinstance(gal, list):
				galleries = [gal]
			else:
				galleries = gal
		else:
			if app_constants.CONTINUE_AUTO_METADATA_FETCHER:
				galleries = [g for g in self.manga_list_view.gallery_model._data if not g.exed]
			else:
				galleries = self.manga_list_view.gallery_model._data
			if not galleries:
				self.notification_bar.add_text('Looks like we\'ve already gone through all galleries!')
				return None
		fetch_instance.galleries = galleries

		self.notification_bar.begin_show()
		fetch_instance.moveToThread(thread)

		def done(status):
			self.notification_bar.end_show()
			fetch_instance.deleteLater()
			if not isinstance(status, bool):
				galleries = []
				for tup in status:
					galleries.append(tup[0])

				class GalleryContextMenu(QMenu):
					app_instance = self
					def __init__(self, parent=None):
						super().__init__(parent)
						show_in_library_act = self.addAction('Show in library')
						show_in_library_act.triggered.connect(self.show_in_library)

					def show_in_library(self):
						viewer = self.app_instance.manga_list_view
						index = viewer.find_index(self.gallery_widget.gallery.id, True)
						if index:
							self.app_instance.manga_table_view.scroll_to_index(index)
							self.app_instance.manga_list_view.scroll_to_index(index)

				g_popup = io_misc.GalleryPopup(('Fecthing metadata for these galleries failed.'+
									  ' Check happypanda.log for details.', galleries), self, menu=GalleryContextMenu())
				#errors = {g[0].id: g[1] for g in status}
				#for g_item in g_popup.get_all_items():
				#	g_item.setToolTip(errors[g_item.gallery.id])
				g_popup.graphics_blur.setEnabled(False)
				close_button = g_popup.add_buttons('Close')[0]
				close_button.clicked.connect(g_popup.close)

		fetch_instance.GALLERY_PICKER.connect(self._web_metadata_picker)
		fetch_instance.GALLERY_EMITTER.connect(self.manga_list_view.replace_edit_gallery)
		fetch_instance.AUTO_METADATA_PROGRESS.connect(self.notification_bar.add_text)
		thread.started.connect(fetch_instance.auto_web_metadata)
		fetch_instance.FINISHED.connect(done)
		fetch_instance.FINISHED.connect(metadata_spinner.close)
		fetch_instance.FINISHED.connect(lambda: self.move_listener.disconnect(move_md_spinner))
		thread.finished.connect(thread.deleteLater)
		thread.start()
		metadata_spinner.show()

	def init_stat_bar(self):
		self.status_bar = self.statusBar()
		self.status_bar.setMaximumHeight(20)
		self.status_bar.setSizeGripEnabled(False)
		self.stat_info = QLabel()
		self.stat_info.setIndent(5)
		self.sort_main = QAction("Asc", self)
		sort_menu = QMenu()
		self.sort_main.setMenu(sort_menu)
		s_by_title = QAction("Title", sort_menu)
		s_by_artist = QAction("Artist", sort_menu)
		sort_menu.addAction(s_by_title)
		sort_menu.addAction(s_by_artist)
		self.status_bar.addPermanentWidget(self.stat_info)
		#self.status_bar.addAction(self.sort_main)
		self.temp_msg = QLabel()
		self.temp_timer = QTimer()

		self.manga_list_view.gallery_model.ROWCOUNT_CHANGE.connect(self.stat_row_info)
		self.manga_list_view.gallery_model.db_emitter.COUNT_CHANGE.connect(self.stat_row_info)
		self.manga_list_view.gallery_model.STATUSBAR_MSG.connect(self.stat_temp_msg)
		self.manga_list_view.STATUS_BAR_MSG.connect(self.stat_temp_msg)
		self.manga_table_view.STATUS_BAR_MSG.connect(self.stat_temp_msg)
		self.stat_row_info()
		app_constants.STAT_MSG_METHOD = self.stat_temp_msg

	def stat_temp_msg(self, msg):
		self.temp_timer.stop()
		self.temp_msg.setText(msg)
		self.status_bar.addWidget(self.temp_msg)
		self.temp_timer.timeout.connect(self.temp_msg.clear)
		self.temp_timer.setSingleShot(True)
		self.temp_timer.start(5000)

	def stat_row_info(self):
		r = self.manga_list_view.model().rowCount()
		t = self.manga_list_view.gallery_model.db_emitter.count
		self.stat_info.setText("Loaded {} of {} ".format(r, t))

	def manga_display(self):
		"initiates the manga view and related things"
		#list view
		self.manga_list_view = gallery.MangaView(self)

		#table view

		self.manga_table_view = gallery.MangaTableView(self)
		self.manga_table_view.gallery_model = self.manga_list_view.gallery_model
		self.manga_table_view.sort_model = self.manga_list_view.sort_model
		self.manga_table_view.setModel(self.manga_table_view.sort_model)
		self.manga_table_view.sort_model.change_model(self.manga_table_view.gallery_model)
		self.manga_table_view.setColumnWidth(app_constants.FAV, 20)
		self.manga_table_view.setColumnWidth(app_constants.ARTIST, 200)
		self.manga_table_view.setColumnWidth(app_constants.TITLE, 400)
		self.manga_table_view.setColumnWidth(app_constants.TAGS, 300)
		self.manga_table_view.setColumnWidth(app_constants.TYPE, 60)
		self.manga_table_view.setColumnWidth(app_constants.CHAPTERS, 60)
		self.manga_table_view.setColumnWidth(app_constants.LANGUAGE, 100)
		self.manga_table_view.setColumnWidth(app_constants.LINK, 400)


	def init_spinners(self):
		# fetching spinner
		self.data_fetch_spinner = misc.Spinner(self)
		self.data_fetch_spinner.set_size(60)
		self.move_listener.connect(
			lambda: self.data_fetch_spinner.update_move(
				QPoint(self.pos().x()+self.width()//2, self.pos().y()+self.height()//2)))
		
		self.manga_list_view.gallery_model.ADD_MORE.connect(self.data_fetch_spinner.show)
		self.manga_list_view.gallery_model.db_emitter.START.connect(self.data_fetch_spinner.show)
		self.manga_list_view.gallery_model.ADDED_ROWS.connect(self.data_fetch_spinner.before_hide)
		self.manga_list_view.gallery_model.db_emitter.CANNOT_FETCH_MORE.connect(self.data_fetch_spinner.before_hide)

		## deleting spinner
		#self.gallery_delete_spinner = misc.Spinner(self)
		#self.gallery_delete_spinner.set_size(40,40)
		##self.gallery_delete_spinner.set_text('Removing...')
		#self.manga_list_view.gallery_model.rowsAboutToBeRemoved.connect(self.gallery_delete_spinner.show)
		#self.manga_list_view.gallery_model.rowsRemoved.connect(self.gallery_delete_spinner.before_hide)


	def search(self, srch_string):
		self.search_bar.setText(srch_string)
		self.search_backward.setVisible(True)
		self.manga_list_view.sort_model.init_search(srch_string)
		old_cursor_pos = self._search_cursor_pos[0]
		self.search_bar.end(False)
		if self.search_bar.cursorPosition() != old_cursor_pos+1:
			self.search_bar.setCursorPosition(old_cursor_pos)


	def favourite_display(self):
		"Switches to favourite display"
		self.manga_table_view.sort_model.fav_view()
		self.favourite_btn.selected = True
		self.library_btn.selected = False

	def catalog_display(self):
		"Switches to catalog display"
		self.manga_table_view.sort_model.catalog_view()
		self.library_btn.selected = True
		self.favourite_btn.selected = False

	def settings(self):
		sett = settingsdialog.SettingsDialog(self)
		sett.scroll_speed_changed.connect(self.manga_list_view.updateGeometries)
		#sett.show()

	def init_toolbar(self):
		self.toolbar = QToolBar()
		self.toolbar.setFixedHeight(25)
		self.toolbar.setWindowTitle("Show") # text for the contextmenu
		#self.toolbar.setStyleSheet("QToolBar {border:0px}") # make it user defined?
		self.toolbar.setMovable(False)
		self.toolbar.setFloatable(False)
		#self.toolbar.setIconSize(QSize(20,20))
		self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
		self.toolbar.setIconSize(QSize(20,20))

		spacer_start = QWidget() # aligns the first actions properly
		spacer_start.setFixedSize(QSize(10, 1))
		self.toolbar.addWidget(spacer_start)

		self.favourite_btn = misc.ToolbarButton(self.toolbar, 'Favorites')
		self.toolbar.addWidget(self.favourite_btn)
		self.favourite_btn.clicked.connect(self.favourite_display) #need lambda to pass extra args

		self.library_btn = misc.ToolbarButton(self.toolbar, 'Library')
		self.toolbar.addWidget(self.library_btn)
		self.library_btn.clicked.connect(self.catalog_display) #need lambda to pass extra args
		self.library_btn.selected = True

		self.toolbar.addSeparator()

		gallery_menu = QMenu()
		gallery_action = QToolButton()
		gallery_action.setText('Gallery ')
		gallery_action.setPopupMode(QToolButton.InstantPopup)
		gallery_action.setToolTip('Contains various gallery related features')
		gallery_action.setMenu(gallery_menu)
		add_gallery_icon = QIcon(app_constants.PLUS_PATH)
		gallery_action_add = QAction(add_gallery_icon, "Add single gallery...", self)
		gallery_action_add.triggered.connect(self.manga_list_view.SERIES_DIALOG.emit)
		gallery_action_add.setToolTip('Add a single gallery thoroughly')
		gallery_menu.addAction(gallery_action_add)
		add_more_action = QAction(add_gallery_icon, "Add galleries...", self)
		add_more_action.setStatusTip('Add galleries from different folders')
		add_more_action.triggered.connect(lambda: self.populate(True))
		gallery_menu.addAction(add_more_action)
		populate_action = QAction(add_gallery_icon, "Populate from directory/archive...", self)
		populate_action.setStatusTip('Populates the DB with galleries from a single folder or archive')
		populate_action.triggered.connect(self.populate)
		gallery_menu.addAction(populate_action)
		gallery_menu.addSeparator()
		metadata_action = QAction('Get metadata for all galleries', self)
		metadata_action.triggered.connect(self.get_metadata)
		gallery_menu.addAction(metadata_action)
		scan_galleries_action = QAction('Scan for new galleries', self)
		scan_galleries_action.triggered.connect(self.scan_for_new_galleries)
		scan_galleries_action.setStatusTip('Scan monitored folders for new galleries')
		gallery_menu.addAction(scan_galleries_action)
		gallery_action_random = gallery_menu.addAction("Open random gallery")
		gallery_action_random.triggered.connect(self.manga_list_view.open_random_gallery)
		self.toolbar.addWidget(gallery_action)


		misc_action = QToolButton()
		misc_action.setText('Tools ')
		misc_action_menu = QMenu()
		misc_action.setMenu(misc_action_menu)
		misc_action.setPopupMode(QToolButton.InstantPopup)
		misc_action.setToolTip("Contains misc. features")
		gallery_downloader = QAction("Gallery Downloader", misc_action_menu)
		gallery_downloader.triggered.connect(self.download_window.show)
		misc_action_menu.addAction(gallery_downloader)
		duplicate_check_simple = QAction("Simple Duplicate Finder", misc_action_menu)
		duplicate_check_simple.triggered.connect(lambda: self.manga_list_view.duplicate_check())
		misc_action_menu.addAction(duplicate_check_simple)
		self.toolbar.addWidget(misc_action)

		spacer_middle = QWidget() # aligns buttons to the right
		spacer_middle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
		self.toolbar.addWidget(spacer_middle)


		sort_action = QToolButton()
		sort_action.setIcon(QIcon(app_constants.SORT_PATH))
		sort_action.setMenu(misc.SortMenu(self.toolbar, self.manga_list_view))
		sort_action.setPopupMode(QToolButton.InstantPopup)
		self.toolbar.addWidget(sort_action)
		
		self.grid_toggle_g_icon = QIcon(app_constants.GRID_PATH)
		self.grid_toggle_l_icon = QIcon(app_constants.LIST_PATH)
		self.grid_toggle = QToolButton()
		if self.display.currentIndex() == self.m_l_view_index:
			self.grid_toggle.setIcon(self.grid_toggle_l_icon)
		else:
			self.grid_toggle.setIcon(self.grid_toggle_g_icon)
		self.grid_toggle.setObjectName('gridtoggle')
		self.grid_toggle.clicked.connect(self.toggle_view)
		self.toolbar.addWidget(self.grid_toggle)

		spacer_mid2 = QWidget()
		spacer_mid2.setFixedSize(QSize(5, 1))
		self.toolbar.addWidget(spacer_mid2)

		def set_search_case(b):
			app_constants.GALLERY_SEARCH_CASE = b
			settings.set(b, 'Application', 'gallery search case')
			settings.save()

		def set_search_strict(b):
			app_constants.GALLERY_SEARCH_STRICT = b
			settings.set(b, 'Application', 'gallery search strict')
			settings.save()

		self.search_bar = misc.LineEdit()
		search_options = self.search_bar.addAction(QIcon(app_constants.SEARCH_OPTIONS_PATH), QLineEdit.TrailingPosition)
		search_options_menu = QMenu(self)
		search_options.triggered.connect(lambda: search_options_menu.popup(QCursor.pos()))
		search_options.setMenu(search_options_menu)
		case_search_option = search_options_menu.addAction('Case Sensitive')
		case_search_option.setCheckable(True)
		case_search_option.setChecked(app_constants.GALLERY_SEARCH_CASE)
		case_search_option.toggled.connect(set_search_case)
		strict_search_option = search_options_menu.addAction('Match whole terms')
		strict_search_option.setCheckable(True)
		strict_search_option.setChecked(app_constants.GALLERY_SEARCH_STRICT)
		strict_search_option.toggled.connect(set_search_strict)
		self.search_bar.setObjectName('search_bar')
		self.search_timer = QTimer(self)
		self.search_timer.setSingleShot(True)
		self.search_timer.timeout.connect(lambda: self.search(self.search_bar.text()))
		self._search_cursor_pos = [0, 0]
		def set_cursor_pos(old, new):
			self._search_cursor_pos[0] = old
			self._search_cursor_pos[1] = new
		self.search_bar.cursorPositionChanged.connect(set_cursor_pos)

		if app_constants.SEARCH_AUTOCOMPLETE:
			completer = QCompleter(self)
			completer_view = misc.CompleterPopupView()
			completer.setPopup(completer_view)
			completer_view._setup()
			completer.setModel(self.manga_list_view.gallery_model)
			completer.setCaseSensitivity(Qt.CaseInsensitive)
			completer.setCompletionMode(QCompleter.PopupCompletion)
			completer.setCompletionRole(Qt.DisplayRole)
			completer.setCompletionColumn(app_constants.TITLE)
			completer.setFilterMode(Qt.MatchContains)
			self.search_bar.setCompleter(completer)
			self.search_bar.returnPressed.connect(lambda: self.search(self.search_bar.text()))
		if not app_constants.SEARCH_ON_ENTER:
			self.search_bar.textEdited.connect(lambda: self.search_timer.start(800))
		self.search_bar.setPlaceholderText("Search title, artist, namespace & tags")
		self.search_bar.setMinimumWidth(150)
		self.search_bar.setMaximumWidth(500)
		self.search_bar.setFixedHeight(19)
		self.manga_list_view.sort_model.HISTORY_SEARCH_TERM.connect(lambda a: self.search_bar.setText(a))
		self.toolbar.addWidget(self.search_bar)

		def search_history(_, back=True): # clicked signal passes a bool
			sort_model =  self.manga_list_view.sort_model
			nav = sort_model.PREV if back else sort_model.NEXT
			history_term = sort_model.navigate_history(nav)
			if back:
				self.search_forward.setVisible(True)

		back = QShortcut(QKeySequence(QKeySequence.Back), self, lambda: search_history(None))
		forward = QShortcut(QKeySequence(QKeySequence.Forward), self, lambda: search_history(None, False))

		search_backbutton = QToolButton(self.toolbar)
		search_backbutton.setText(u'\u25C0')
		search_backbutton.setFixedWidth(15)
		search_backbutton.clicked.connect(search_history)
		self.search_backward = self.toolbar.addWidget(search_backbutton)
		self.search_backward.setVisible(False)
		search_forwardbutton = QToolButton(self.toolbar)
		search_forwardbutton.setText(u'\u25B6')
		search_forwardbutton.setFixedWidth(15)
		search_forwardbutton.clicked.connect(lambda: search_history(None, False))
		self.search_forward = self.toolbar.addWidget(search_forwardbutton)
		self.search_forward.setVisible(False)

		spacer_end = QWidget() # aligns settings action properly
		spacer_end.setFixedSize(QSize(10, 1))
		self.toolbar.addWidget(spacer_end)

		settings_act = QToolButton(self.toolbar)
		settings_act.setIcon(QIcon(app_constants.SETTINGS_PATH))
		settings_act.clicked.connect(self.settings)
		self.toolbar.addWidget(settings_act)

		spacer_end2 = QWidget() # aligns About action properly
		spacer_end2.setFixedSize(QSize(5, 1))
		self.toolbar.addWidget(spacer_end2)
		self.addToolBar(self.toolbar)

	def toggle_view(self):
		"""
		Toggles the current display view
		"""
		if self.display.currentIndex() == self.m_l_view_index:
			self.display.setCurrentIndex(self.m_t_view_index)
			self.grid_toggle.setIcon(self.grid_toggle_g_icon)
		else:
			self.display.setCurrentIndex(self.m_l_view_index)
			self.grid_toggle.setIcon(self.grid_toggle_l_icon)

	# TODO: Improve this so that it adds to the gallery dialog,
	# so user can edit data before inserting (make it a choice)
	def populate(self, mixed=None):
		"Populates the database with gallery from local drive'"
		if mixed:
			gallery_view = misc.GalleryListView(self, True)
			gallery_view.SERIES.connect(self.gallery_populate)
			gallery_view.show()
		else:
			msg_box = misc.BasePopup(self)
			l = QVBoxLayout()
			msg_box.main_widget.setLayout(l)
			l.addWidget(QLabel('Directory or Archive?'))
			l.addLayout(msg_box.buttons_layout)

			def from_dir():
				path = QFileDialog.getExistingDirectory(self, "Choose a directory containing your galleries")
				if not path:
					return
				msg_box.close()
				app_constants.OVERRIDE_SUBFOLDER_AS_GALLERY = True
				self.gallery_populate(path, True)
			def from_arch():
				path = QFileDialog.getOpenFileName(self, 'Choose an archive containing your galleries',
									   filter=utils.FILE_FILTER)
				path = [path[0]]
				if not all(path) or not path:
					return
				msg_box.close()
				app_constants.OVERRIDE_SUBFOLDER_AS_GALLERY = True
				self.gallery_populate(path, True)

			buttons = msg_box.add_buttons('Directory', 'Archive', 'Close')
			buttons[2].clicked.connect(msg_box.close)
			buttons[0].clicked.connect(from_dir)
			buttons[1].clicked.connect(from_arch)
			msg_box.adjustSize()
			msg_box.show()

	def gallery_populate(self, path, validate=False):
		"Scans the given path for gallery to add into the DB"
		if len(path) is not 0:
			data_thread = QThread(self)
			data_thread.setObjectName('General gallery populate')
			loading = misc.Loading(self)
			self.g_populate_inst = fetch.Fetch()
			self.g_populate_inst.series_path = path
			loading.show()

			def finished(status):
				def hide_loading():
					loading.hide()
				if status:
					if len(status) != 0:
						def add_gallery(gallery_list):
							def append_to_model(x):
								self.manga_list_view.sort_model.insertRows(x, None, len(x))
								self.manga_list_view.sort_model.init_search(
									self.manga_list_view.sort_model.current_term)

							class A(QObject):
								done = pyqtSignal()
								prog = pyqtSignal(int)
								def __init__(self, obj, parent=None):
									super().__init__(parent)
									self.obj = obj
									self.galleries = []

								def add_to_db(self):
									for y, x in enumerate(self.obj):
										gallerydb.add_method_queue(
											gallerydb.GalleryDB.add_gallery_return, False, x)
										self.galleries.append(x)
										y += 1
										self.prog.emit(y)
									append_to_model(self.galleries)
									self.done.emit()
							loading.progress.setMaximum(len(gallery_list))
							self.a_instance = A(gallery_list)
							thread = QThread(self)
							thread.setObjectName('Database populate')
							def loading_show(numb):
								if loading.isHidden():
									loading.show()
								loading.setText('Populating database ({}/{})\nPlease wait...'.format(
									numb, loading.progress.maximum()))
								loading.progress.setValue(numb)
								loading.show()

							def loading_hide():
								loading.close()
								self.manga_list_view.gallery_model.ROWCOUNT_CHANGE.emit()

							self.a_instance.moveToThread(thread)
							self.a_instance.prog.connect(loading_show)
							thread.started.connect(self.a_instance.add_to_db)
							self.a_instance.done.connect(loading_hide)
							self.a_instance.done.connect(self.a_instance.deleteLater)
							#a_instance.add_to_db()
							thread.finished.connect(thread.deleteLater)
							thread.start()
						#data_thread.quit
						hide_loading()
						log_i('Populating DB from gallery folder: OK')
						if validate:
							gallery_list = misc.GalleryListView(self)
							gallery_list.SERIES.connect(add_gallery)
							for ser in status:
								if ser.is_archive and app_constants.SUBFOLDER_AS_GALLERY:
									p = os.path.split(ser.path)[1]
									if ser.chapters[0].path:
										pt_in_arch = os.path.split(ser.path_in_archive)
										pt_in_arch = pt_in_arch[1] or pt_in_arch[0]
										text = '{}: {}'.format(p, pt_in_arch)
									else:
										text = p
									gallery_list.add_gallery(ser, text)
								else:
									gallery_list.add_gallery(ser, os.path.split(ser.path)[1])
							#self.manga_list_view.gallery_model.populate_data()
							gallery_list.update_count()
							gallery_list.show()
						else:
							add_gallery(status)
					else:
						log_d('No new gallery was found')
						loading.setText("No new gallery found")
						#data_thread.quit

				else:
					log_e('Populating DB from gallery folder: Nothing was added!')
					loading.setText("<font color=red>Nothing was added. Check happypanda_log for details..</font>")
					loading.progress.setStyleSheet("background-color:red;")
					data_thread.quit
					QTimer.singleShot(8000, loading.close)

			def skipped_gs(s_list):
				"Skipped galleries"
				msg_box = QMessageBox(self)
				msg_box.setIcon(QMessageBox.Question)
				msg_box.setText('Do you want to view skipped paths?')
				msg_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
				msg_box.setDefaultButton(QMessageBox.No)
				if msg_box.exec() == QMessageBox.Yes:
					list_wid = QTableWidget(self)
					list_wid.setAttribute(Qt.WA_DeleteOnClose)
					list_wid.setRowCount(len(s_list))
					list_wid.setColumnCount(2)
					list_wid.setAlternatingRowColors(True)
					list_wid.setEditTriggers(list_wid.NoEditTriggers)
					list_wid.setHorizontalHeaderLabels(['Reason', 'Path'])
					list_wid.setSelectionBehavior(list_wid.SelectRows)
					list_wid.setSelectionMode(list_wid.SingleSelection)
					list_wid.setSortingEnabled(True)
					list_wid.verticalHeader().hide()
					list_wid.setAutoScroll(False)
					for x, g in enumerate(s_list):
						list_wid.setItem(x, 0, QTableWidgetItem(g[1]))
						list_wid.setItem(x, 1, QTableWidgetItem(g[0]))
					list_wid.resizeColumnsToContents()
					list_wid.setWindowTitle('{} skipped paths'.format(len(s_list)))
					list_wid.setWindowFlags(Qt.Window)
					list_wid.resize(900,400)

					list_wid.doubleClicked.connect(lambda i: utils.open_path(
						list_wid.item(i.row(), 1).text(), list_wid.item(i.row(), 1).text()))

					list_wid.show()

			def a_progress(prog):
				loading.progress.setValue(prog)
				loading.setText("Preparing galleries...")

			self.g_populate_inst.moveToThread(data_thread)
			self.g_populate_inst.DATA_COUNT.connect(loading.progress.setMaximum)
			self.g_populate_inst.PROGRESS.connect(a_progress)
			self.g_populate_inst.FINISHED.connect(finished)
			self.g_populate_inst.FINISHED.connect(self.g_populate_inst.deleteLater)
			self.g_populate_inst.SKIPPED.connect(skipped_gs)
			data_thread.finished.connect(data_thread.deleteLater)
			data_thread.started.connect(self.g_populate_inst.local)
			data_thread.start()
			#.g_populate_inst.local()
			log_i('Populating DB from directory/archive')

	def scan_for_new_galleries(self):
		available_folders =  app_constants.ENABLE_MONITOR and\
									app_constants.MONITOR_PATHS and all(app_constants.MONITOR_PATHS)
		if available_folders and not app_constants.SCANNING_FOR_GALLERIES:
			app_constants.SCANNING_FOR_GALLERIES = True
			self.notification_bar.add_text("Scanning for new galleries...")
			log_i('Scanning for new galleries...')
			try:
				class ScanDir(QObject):
					final_paths_and_galleries = pyqtSignal(list, list)
					finished = pyqtSignal()
					def __init__(self, parent=None):
						super().__init__(parent)
						self.scanned_data = []
					def scan_dirs(self):
						paths = []
						for p in app_constants.MONITOR_PATHS:
							if os.path.exists(p):
								dir_content = scandir.scandir(p)
								for d in dir_content:
									paths.append(d.path)
							else:
								log_e("Monitored path does not exists: {}".format(p.encode(errors='ignore')))

						fetch_inst = fetch.Fetch(self)
						fetch_inst.series_path = paths
						def set_scanned_d(d):
							self.scanned_data = d
						fetch_inst.FINISHED.connect(set_scanned_d)
						fetch_inst.local()
						#contents = []
						#for g in self.scanned_data:
						#	contents.append(g)

						#paths = sorted(paths)
						#new_galleries = []
						#for x in contents:
						#	y = utils.b_search(paths, os.path.normcase(x.path))
						#	if not y:
						#		new_galleries.append(x)

						galleries = []
						final_paths = []
						if self.scanned_data:
							for g in self.scanned_data:
								try:
									if g.is_archive:
										g.profile = utils.get_gallery_img(g.chapters[0].path, g.path)
									else:
										g.profile = utils.get_gallery_img(g.chapters[0].path)
									if not g.profile:
										raise Exception
								except:
									g.profile = app_constants.NO_IMAGE_PATH
							
								galleries.append(g)
								final_paths.append(g.path)
						self.final_paths_and_galleries.emit(final_paths, galleries)
						self.finished.emit()
						self.deleteLater()
					#if app_constants.LOOK_NEW_GALLERY_AUTOADD:
					#	QTimer.singleShot(10000, self.gallery_populate(final_paths))
					#	return

				def show_new_galleries(final_paths, galleries):
					if final_paths and galleries:
						app_constants.OVERRIDE_MOVE_IMPORTED_IN_FETCH = True
						if app_constants.LOOK_NEW_GALLERY_AUTOADD:
							self.gallery_populate(final_paths)
						else:

							class NewGalleryMenu(QMenu):

								def __init__(self, parent=None):
									super().__init__(parent)

									ignore_act = self.addAction('Add to ignore list')
									ignore_act.triggered.connect(self.add_to_ignore)

								def add_to_ignore(self):
									gallery = self.gallery_widget.gallery
									app_constants.IGNORE_PATHS.append(gallery.path)
									settings.set(app_constants.IGNORE_PATHS, 'Application', 'ignore paths')
									if self.gallery_widget.parent_widget.gallery_layout.count() == 1:
										self.gallery_widget.parent_widget.close()
									else:
										self.gallery_widget.close()

							if len(galleries) == 1:
								self.notification_bar.add_text("{} new gallery was discovered in one of your monitored directories".format(len(galleries)))
							else:
								self.notification_bar.add_text("{} new galleries were discovered in one of your monitored directories".format(len(galleries)))
							text = "These new galleries were discovered! Do you want to add them?"\
								if len(galleries) > 1 else "This new gallery was discovered! Do you want to add it?"
							g_popup = io_misc.GalleryPopup((text, galleries), self, NewGalleryMenu())
							buttons = g_popup.add_buttons('Add', 'Close')

							def populate_n_close():
								g_popup.close()
								self.gallery_populate(final_paths)
							buttons[0].clicked.connect(populate_n_close)
							buttons[1].clicked.connect(g_popup.close)

				def finished(): app_constants.SCANNING_FOR_GALLERIES = False

				thread = QThread(self)
				self.scan_inst = ScanDir()
				self.scan_inst.moveToThread(thread)
				self.scan_inst.final_paths_and_galleries.connect(show_new_galleries)
				self.scan_inst.finished.connect(finished)
				thread.started.connect(self.scan_inst.scan_dirs)
				#self.scan_inst.scan_dirs()
				thread.finished.connect(thread.deleteLater)
				thread.start()
			except:
				self.notification_bar.add_text('An error occured while attempting to scan for new galleries. Check happypanda.log.')
				log.exception('An error occured while attempting to scan for new galleries.')
				app_constants.SCANNING_FOR_GALLERIES = False

	def dragEnterEvent(self, event):
		if event.mimeData().hasUrls():
			event.acceptProposedAction()
		else:
			self.notification_bar.add_text('File is not supported')

	def dropEvent(self, event):
		acceptable = []
		unaccept = []
		for u in event.mimeData().urls():
			path = u.toLocalFile()
			if os.path.isdir(path) or path.endswith(utils.ARCHIVE_FILES):
				acceptable.append(path)
			else:
				unaccept.append(path)
		log_i('Acceptable dropped items: {}'.format(len(acceptable)))
		log_i('Unacceptable dropped items: {}'.format(len(unaccept)))
		log_d('Dropped items: {}\n{}'.format(acceptable, unaccept).encode(errors='ignore'))
		if acceptable:
			self.notification_bar.add_text('Adding dropped items...')
			log_i('Adding dropped items')
			l = len(acceptable) == 1
			f_item = acceptable[0]
			if f_item.endswith(utils.ARCHIVE_FILES):
				f_item = utils.check_archive(f_item)
			else:
				f_item = utils.recursive_gallery_check(f_item)
			f_item_l = len(f_item) < 2
			subfolder_as_c = not app_constants.SUBFOLDER_AS_GALLERY
			if l and subfolder_as_c or l and f_item_l:
				g_d = gallerydialog.GalleryDialog(self, acceptable[0])
				g_d.SERIES.connect(self.manga_list_view.gallery_model.addRows)
				g_d.show()
			else:
				self.gallery_populate(acceptable, True)
		else:
			text = 'File not supported' if len(unaccept) < 2 else 'Files not supported'
			self.notification_bar.add_text(text)

		if unaccept:
			self.notification_bar.add_text('Some unsupported files did not get added')

	def resizeEvent(self, event):
		try:
			self.notification_bar.resize(event.size().width())
		except AttributeError:
			pass
		self.move_listener.emit()
		return super().resizeEvent(event)

	def moveEvent(self, event):
		self.move_listener.emit()
		return super().moveEvent(event)

	def showEvent(self, event):
		return super().showEvent(event)

	def cleanup_exit(self):
		self.system_tray.hide()
		# watchers
		try:
			self.watchers.stop_all()
		except AttributeError:
			pass

		# settings
		settings.set(self.manga_list_view.current_sort, 'General', 'current sort')
		settings.set(app_constants.IGNORE_PATHS, 'Application', 'ignore paths')
		settings.win_save(self, 'AppWindow')

		# temp dir
		try:
			for root, dirs, files in scandir.walk('temp', topdown=False):
				for name in files:
					os.remove(os.path.join(root, name))
				for name in dirs:
					os.rmdir(os.path.join(root, name))
			log_d('Flush temp on exit: OK')
		except:
			log.exception('Flush temp on exit: FAIL')

		if self.tags_treeview:
			self.tags_treeview.close()
		self.download_window.close()

		# check if there is db activity
		if not gallerydb.method_queue.empty():
			class DBActivityChecker(QObject):
				FINISHED = pyqtSignal()
				def __init__(self, **kwargs):
					super().__init__(**kwargs)

				def check(self):
					gallerydb.method_queue.join()
					self.FINISHED.emit()
					self.deleteLater()

			db_activity = DBActivityChecker()
			db_spinner = misc.Spinner(self)
			self.db_activity_checker.connect(db_activity.check)
			db_activity.moveToThread(app_constants.GENERAL_THREAD)
			db_activity.FINISHED.connect(db_spinner.close)
			db_spinner.set_size(50)
			db_spinner.set_text('Activity')
			db_spinner.move(QPoint(self.pos().x()+self.width()-70, self.pos().y()+self.height()-70))
			self.move_listener.connect(lambda: db_spinner.update_move(QPoint(self.pos().x()+self.width()-70,
																	self.pos().y()+self.height()-70)))
			db_spinner.show()
			self.db_activity_checker.emit()
			msg_box = QMessageBox(self)
			msg_box.setText('Database activity detected!')
			msg_box.setInformativeText("Closing now might result in data loss." +
								 " Do you still want to close?\n(Wait for the activity spinner to hide before closing)")
			msg_box.setIcon(QMessageBox.Critical)
			msg_box.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
			msg_box.setDefaultButton(QMessageBox.No)
			if msg_box.exec() == QMessageBox.Yes:
				return 1
			else:
				return 2
		else:
			return 0

	def closeEvent(self, event):
		r_code = self.cleanup_exit()
		if r_code == 1:
			log_d('Force Exit App: OK')
			super().closeEvent(event)
		elif r_code == 2:
			log_d('Ignore Exit App')
			event.ignore()
		else:
			log_d('Normal Exit App: OK')
			super().closeEvent(event)
Пример #28
0
    def __init__(self, parent):
        TitledToolbar.__init__(self, parent, 'Block style')
        self.currentStyle = None

        toolbar = QToolBar(self)
        toolbar.setFloatable(False)
        toolbar.setMovable(False)

        self.styleToIndex = {}
        self.styleToDropdown = {}

##########################
        d1 = IconDropDown(self, ':/icons/format-text-paragraph.png')
        d1.entrySelected.connect(self.styleSelected)

        selector = ('para', None, None)
        d1.addItem("Standard", selector)
        self.styleToDropdown[selector] = d1
        self.styleToIndex[selector] = 0

        selector = ('tip', None, None)
        d1.addItem('Tip', selector)
        self.styleToDropdown[selector] = d1
        self.styleToIndex[selector] = 1

        selector = ('warning', None, None)
        d1.addItem('Warning', selector)
        self.styleToDropdown[selector] = d1
        self.styleToIndex[selector] = 2

        selector = ('blockquote', None, None)
        d1.addItem('Quotation', selector)
        self.styleToDropdown[selector] = d1
        self.styleToIndex[selector] = 3

##########################
        d2 = IconDropDown(self, ':/icons/format-text-header.png')
        d2.entrySelected.connect(self.styleSelected)

        selector = ('title', 'level', '1')
        d2.addItem('Title 1', selector)
        self.styleToDropdown[selector] = d2
        self.styleToIndex[selector] = 0

        selector = ('title', 'level', '2')
        d2.addItem('Title 2', selector)
        self.styleToDropdown[selector] = d2
        self.styleToIndex[selector] = 1

        selector = ('title', 'level', '3')
        d2.addItem('Title 3', selector)
        self.styleToDropdown[selector] = d2
        self.styleToIndex[selector] = 2

##########################
        d3 = IconDropDown(self, ":/icons/format-list-unordered.png")
        d3.entrySelected.connect(self.styleSelected)

        selector = ('itemizedlist', 'level', '1')
        d3.addItem("Unordered List", selector)
        self.styleToDropdown[selector] = d3
        self.styleToIndex[selector] = 0

        selector = ('orderedlist', 'level', '1')
        d3.addItem("Ordered List", selector)
        self.styleToDropdown[selector] = d3
        self.styleToIndex[selector] = 1

##########################
        d4 = IconDropDown(self, ":/icons/format-text-code.png")
        d4.entrySelected.connect(self.styleSelected)

        selector = ('programlisting', 'language', 'cpp')
        d4.addItem("C++", selector)
        self.styleToDropdown[selector] = d4
        self.styleToIndex[selector] = 0

        selector = ('programlisting', 'language', 'java')
        d4.addItem("Java", selector)
        self.styleToDropdown[selector] = d4
        self.styleToIndex[selector] = 1
        
        selector = ('programlisting', 'language', 'python')
        d4.addItem("Python", selector)
        self.styleToDropdown[selector] = d4
        self.styleToIndex[selector] = 2
        
        selector = ('programlisting', 'language', 'sql')
        d4.addItem("SQL", selector)
        self.styleToDropdown[selector] = d4
        self.styleToIndex[selector] = 3
        
        selector = ('programlisting', 'language', 'xml')
        d4.addItem("XML", selector)
        self.styleToDropdown[selector] = d4
        self.styleToIndex[selector] = 4

        selector = ('programlisting', 'language', 'bash')
        d4.addItem("Bash", selector)
        self.styleToDropdown[selector] = d4
        self.styleToIndex[selector] = 5
        
        selector = ('screen', None, None)
        d4.addItem("Generic", selector)
        self.styleToDropdown[selector] = d4
        self.styleToIndex[selector] = 6

        toolbar.addWidget(d1)
        toolbar.addWidget(d2)
        toolbar.addWidget(d3)
        toolbar.addWidget(d4)

        intendLessAction = QAction(QIcon(":/icons/format-indent-less.png"), "", toolbar) 
        intendLessAction.triggered.connect(self.indentLess)
        toolbar.addAction(intendLessAction)

        intendMoreAction = QAction(QIcon(":/icons/format-indent-more.png"), "", toolbar) 
        intendMoreAction.triggered.connect(self.indentMore)
        toolbar.addAction(intendMoreAction)

        # Can not currently support tables because the QTextTableCell python
        # binding is missing methods to traverse the cell contents
        #insertTableAction = QAction("Table", toolbar) 
        #insertTableAction.triggered.connect(self.insertTable)
        #toolbar.addAction(insertTableAction)

        self.addWidget(toolbar)
Пример #29
0
class MainWindow_Ui(QMainWindow):
    def __init__(self, persepolis_setting):
        super().__init__()
        # MainWindow
        self.persepolis_setting = persepolis_setting

        # add support for other languages
        locale = str(self.persepolis_setting.value('settings/locale'))
        QLocale.setDefault(QLocale(locale))
        self.translator = QTranslator()
        if self.translator.load(':/translations/locales/ui_' + locale, 'ts'):
            QCoreApplication.installTranslator(self.translator)


        # set ui direction
        ui_direction = self.persepolis_setting.value('ui_direction')

        if ui_direction == 'rtl':
            self.setLayoutDirection(Qt.RightToLeft)
        
        elif ui_direction in 'ltr':
            self.setLayoutDirection(Qt.LeftToRight)



        icons = ':/' + \
            str(self.persepolis_setting.value('settings/icons')) + '/'

        self.setWindowTitle(QCoreApplication.translate("mainwindow_ui_tr", "Persepolis Download Manager"))
        self.setWindowIcon(QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg')))

        self.centralwidget = QWidget(self)
        self.verticalLayout = QVBoxLayout(self.centralwidget)

        # enable drag and drop
        self.setAcceptDrops(True)

        # frame
        self.frame = QFrame(self.centralwidget)

        # download_table_horizontalLayout
        download_table_horizontalLayout = QHBoxLayout()
        horizontal_splitter = QSplitter(Qt.Horizontal)

        vertical_splitter = QSplitter(Qt.Vertical)

        # category_tree
        self.category_tree_qwidget = QWidget(self)
        category_tree_verticalLayout = QVBoxLayout()
        self.category_tree = CategoryTreeView(self)
        category_tree_verticalLayout.addWidget(self.category_tree)

        self.category_tree_model = QStandardItemModel()
        self.category_tree.setModel(self.category_tree_model)
        category_table_header = [QCoreApplication.translate("mainwindow_ui_tr", 'Category')]

        self.category_tree_model.setHorizontalHeaderLabels(
            category_table_header)
        self.category_tree.header().setStretchLastSection(True)

        self.category_tree.header().setDefaultAlignment(Qt.AlignCenter)
        
        # queue_panel
        self.queue_panel_widget = QWidget(self)

        queue_panel_verticalLayout_main = QVBoxLayout(self.queue_panel_widget)

        # queue_panel_show_button
        self.queue_panel_show_button = QPushButton(self)

        queue_panel_verticalLayout_main.addWidget(self.queue_panel_show_button)

        # queue_panel_widget_frame
        self.queue_panel_widget_frame = QFrame(self)
        self.queue_panel_widget_frame.setFrameShape(QFrame.StyledPanel)
        self.queue_panel_widget_frame.setFrameShadow(QFrame.Raised)

        queue_panel_verticalLayout_main.addWidget(
            self.queue_panel_widget_frame)

        queue_panel_verticalLayout = QVBoxLayout(self.queue_panel_widget_frame)
        queue_panel_verticalLayout_main.setContentsMargins(50, -1, 50, -1)

        # start_end_frame
        self.start_end_frame = QFrame(self)

        # start time
        start_verticalLayout = QVBoxLayout(self.start_end_frame)
        self.start_checkBox = QCheckBox(self)
        start_verticalLayout.addWidget(self.start_checkBox)

        self.start_frame = QFrame(self)
        self.start_frame.setFrameShape(QFrame.StyledPanel)
        self.start_frame.setFrameShadow(QFrame.Raised)

        start_frame_verticalLayout = QVBoxLayout(self.start_frame)

        self.start_time_qDataTimeEdit = QDateTimeEdit(self.start_frame)
        self.start_time_qDataTimeEdit.setDisplayFormat('H:mm')
        start_frame_verticalLayout.addWidget(self.start_time_qDataTimeEdit)
  
        start_verticalLayout.addWidget(self.start_frame)

        # end time
        self.end_checkBox = QCheckBox(self)
        start_verticalLayout.addWidget(self.end_checkBox)

        self.end_frame = QFrame(self)
        self.end_frame.setFrameShape(QFrame.StyledPanel)
        self.end_frame.setFrameShadow(QFrame.Raised)

        end_frame_verticalLayout = QVBoxLayout(self.end_frame)

        self.end_time_qDateTimeEdit = QDateTimeEdit(self.end_frame)
        self.end_time_qDateTimeEdit.setDisplayFormat('H:mm')
        end_frame_verticalLayout.addWidget(self.end_time_qDateTimeEdit)
 
        start_verticalLayout.addWidget(self.end_frame)

        self.reverse_checkBox = QCheckBox(self)
        start_verticalLayout.addWidget(self.reverse_checkBox)

        queue_panel_verticalLayout.addWidget(self.start_end_frame)

        # limit_after_frame
        self.limit_after_frame = QFrame(self)

        # limit_checkBox
        limit_verticalLayout = QVBoxLayout(self.limit_after_frame)
        self.limit_checkBox = QCheckBox(self)
        limit_verticalLayout.addWidget(self.limit_checkBox)

        # limit_frame
        self.limit_frame = QFrame(self)
        self.limit_frame.setFrameShape(QFrame.StyledPanel)
        self.limit_frame.setFrameShadow(QFrame.Raised)
        limit_verticalLayout.addWidget(self.limit_frame)

        limit_frame_verticalLayout = QVBoxLayout(self.limit_frame)

        # limit_spinBox
        limit_frame_horizontalLayout = QHBoxLayout()
        self.limit_spinBox = QDoubleSpinBox(self)
        self.limit_spinBox.setMinimum(1)
        self.limit_spinBox.setMaximum(1023)
        limit_frame_horizontalLayout.addWidget(self.limit_spinBox)

        # limit_comboBox
        self.limit_comboBox = QComboBox(self)
        self.limit_comboBox.addItem("")
        self.limit_comboBox.addItem("")
        limit_frame_horizontalLayout.addWidget(self.limit_comboBox)
        limit_frame_verticalLayout.addLayout(limit_frame_horizontalLayout)

        # limit_pushButton
        self.limit_pushButton = QPushButton(self)
        limit_frame_verticalLayout.addWidget(self.limit_pushButton)

        # after_checkBox
        self.after_checkBox = QCheckBox(self)
        limit_verticalLayout.addWidget(self.after_checkBox)

        # after_frame
        self.after_frame = QFrame(self)
        self.after_frame.setFrameShape(QFrame.StyledPanel)
        self.after_frame.setFrameShadow(QFrame.Raised)
        limit_verticalLayout.addWidget(self.after_frame)

        after_frame_verticalLayout = QVBoxLayout(self.after_frame)

        # after_comboBox
        self.after_comboBox = QComboBox(self)
        self.after_comboBox.addItem("")

        after_frame_verticalLayout.addWidget(self.after_comboBox)

        # after_pushButton
        self.after_pushButton = QPushButton(self)
        after_frame_verticalLayout.addWidget(self.after_pushButton)

        queue_panel_verticalLayout.addWidget(self.limit_after_frame)
        category_tree_verticalLayout.addWidget(self.queue_panel_widget)

        # keep_awake_checkBox
        self.keep_awake_checkBox = QCheckBox(self)
        queue_panel_verticalLayout.addWidget(self.keep_awake_checkBox)

        self.category_tree_qwidget.setLayout(category_tree_verticalLayout)
        horizontal_splitter.addWidget(self.category_tree_qwidget)

        # download table widget
        self.download_table_content_widget = QWidget(self)
        download_table_content_widget_verticalLayout = QVBoxLayout(
            self.download_table_content_widget)

       
        # download_table
        self.download_table = DownloadTableWidget(self)
        vertical_splitter.addWidget(self.download_table)

        horizontal_splitter.addWidget(self.download_table_content_widget)

        self.download_table.setColumnCount(13)
        self.download_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.download_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.download_table.verticalHeader().hide()

        # hide gid and download dictioanry section
        self.download_table.setColumnHidden(8, True)
        self.download_table.setColumnHidden(9, True)

        download_table_header = [QCoreApplication.translate("mainwindow_ui_tr", 'File Name'), QCoreApplication.translate("mainwindow_ui_tr",'Status'), QCoreApplication.translate("mainwindow_ui_tr", 'Size'), QCoreApplication.translate("mainwindow_ui_tr", 'Downloaded'), QCoreApplication.translate("mainwindow_ui_tr", 'Percentage'), QCoreApplication.translate("mainwindow_ui_tr", 'Connections'),
                                 QCoreApplication.translate("mainwindow_ui_tr", 'Transfer rate'), QCoreApplication.translate("mainwindow_ui_tr",'Estimated time left'), 'Gid', QCoreApplication.translate("mainwindow_ui_tr",'Link'), QCoreApplication.translate("mainwindow_ui_tr", 'First try date'), QCoreApplication.translate("mainwindow_ui_tr", 'Last try date'), QCoreApplication.translate("mainwindow_ui_tr",'Category')]

        self.download_table.setHorizontalHeaderLabels(download_table_header)

        # fixing the size of download_table when window is Maximized!
        self.download_table.horizontalHeader().setSectionResizeMode(0)
        self.download_table.horizontalHeader().setStretchLastSection(True)

        horizontal_splitter.setStretchFactor(0, 3) # category_tree width
        horizontal_splitter.setStretchFactor(1, 10)  # ratio of tables's width


        # video_finder_widget
        self.video_finder_widget = QWidget(self)
        video_finder_horizontalLayout = QHBoxLayout(self.video_finder_widget)

        self.muxing_pushButton = QPushButton(self)
        self.muxing_pushButton.setIcon(QIcon(icons + 'video_finder'))
        video_finder_horizontalLayout.addWidget(self.muxing_pushButton)
        video_finder_horizontalLayout.addSpacing(20)

        video_audio_verticalLayout = QVBoxLayout()

        self.video_label = QLabel(self)
        video_audio_verticalLayout.addWidget(self.video_label)

        self.audio_label = QLabel(self)
        video_audio_verticalLayout.addWidget(self.audio_label)
        video_finder_horizontalLayout.addLayout(video_audio_verticalLayout)

        status_muxing_verticalLayout = QVBoxLayout()

        self.video_finder_status_label = QLabel(self)
        status_muxing_verticalLayout.addWidget(self.video_finder_status_label)

        self.muxing_status_label = QLabel(self)
        status_muxing_verticalLayout.addWidget(self.muxing_status_label)
        video_finder_horizontalLayout.addLayout(status_muxing_verticalLayout)

        vertical_splitter.addWidget(self.video_finder_widget)

        download_table_content_widget_verticalLayout.addWidget(vertical_splitter)


        download_table_horizontalLayout.addWidget(horizontal_splitter)

        self.frame.setLayout(download_table_horizontalLayout)

        self.verticalLayout.addWidget(self.frame)

        self.setCentralWidget(self.centralwidget)

        # menubar
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QRect(0, 0, 600, 24))
        self.setMenuBar(self.menubar)
        fileMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&File'))
        editMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&Edit'))
        viewMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&View'))
        downloadMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&Download'))
        queueMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&Queue'))
        videoFinderMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", 'V&ideo Finder'))
        helpMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&Help'))


        # viewMenu submenus
        sortMenu = viewMenu.addMenu(QCoreApplication.translate("mainwindow_ui_tr", 'Sort by'))

        # statusbar
        self.statusbar = QStatusBar(self)
        self.setStatusBar(self.statusbar)
        self.statusbar.showMessage(QCoreApplication.translate("mainwindow_ui_tr", "Persepolis Download Manager"))

        # toolBar
        self.toolBar2 = QToolBar(self)
        self.addToolBar(Qt.TopToolBarArea, self.toolBar2)
        self.toolBar2.setWindowTitle(QCoreApplication.translate("mainwindow_ui_tr", 'Menu'))
        self.toolBar2.setFloatable(False)
        self.toolBar2.setMovable(False)

        self.toolBar = QToolBar(self)
        self.addToolBar(Qt.TopToolBarArea, self.toolBar)
        self.toolBar.setWindowTitle(QCoreApplication.translate("mainwindow_ui_tr", 'Toolbar'))
        self.toolBar.setFloatable(False)
        self.toolBar.setMovable(False)


        #toolBar and menubar and actions
        self.persepolis_setting.beginGroup('settings/shortcuts')

        # videoFinderAddLinkAction
        self.videoFinderAddLinkAction = QAction(QIcon(icons + 'video_finder'), QCoreApplication.translate("mainwindow_ui_tr", 'Find Video Links'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Download video or audio from Youtube, Vimeo, etc...'),
                                            triggered=self.showVideoFinderAddLinkWindow)

        self.videoFinderAddLinkAction_shortcut = QShortcut(self.persepolis_setting.value('video_finder_shortcut'), self, self.showVideoFinderAddLinkWindow)

        videoFinderMenu.addAction(self.videoFinderAddLinkAction)

        # stopAllAction
        self.stopAllAction = QAction(QIcon(icons + 'stop_all'), QCoreApplication.translate("mainwindow_ui_tr", 'Stop all active downloads'),
                                     self, statusTip='Stop all active downloads', triggered=self.stopAllDownloads)
        downloadMenu.addAction(self.stopAllAction)

        # sort_file_name_Action
        self.sort_file_name_Action = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'File name'), self, triggered=self.sortByName)
        sortMenu.addAction(self.sort_file_name_Action)

        # sort_file_size_Action
        self.sort_file_size_Action = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'File size'), self, triggered=self.sortBySize)
        sortMenu.addAction(self.sort_file_size_Action)

        # sort_first_try_date_Action
        self.sort_first_try_date_Action = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'First try date'), self, triggered=self.sortByFirstTry)
        sortMenu.addAction(self.sort_first_try_date_Action)

        # sort_last_try_date_Action
        self.sort_last_try_date_Action = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'Last try date'), self, triggered=self.sortByLastTry)
        sortMenu.addAction(self.sort_last_try_date_Action)

        # sort_download_status_Action
        self.sort_download_status_Action = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'Download status'), self, triggered=self.sortByStatus)
        sortMenu.addAction(self.sort_download_status_Action)

        # trayAction
        self.trayAction = QAction(QCoreApplication.translate("mainwindow_ui_tr", 'Show system tray icon'), self,
                                  statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Show/Hide system tray icon"), triggered=self.showTray)
        self.trayAction.setCheckable(True)
        viewMenu.addAction(self.trayAction)

        # showMenuBarAction
        self.showMenuBarAction = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'Show menubar'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Show menubar'), triggered=self.showMenuBar)
        self.showMenuBarAction.setCheckable(True)
        viewMenu.addAction(self.showMenuBarAction)

        # showSidePanelAction
        self.showSidePanelAction = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'Show side panel'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Show side panel'), triggered=self.showSidePanel)
        self.showSidePanelAction.setCheckable(True)
        viewMenu.addAction(self.showSidePanelAction)

        # minimizeAction
        self.minimizeAction = QAction(QIcon(icons + 'minimize'), QCoreApplication.translate("mainwindow_ui_tr", 'Minimize to system tray'), self,
                                      statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Minimize to system tray"), triggered=self.minMaxTray)

        self.minimizeAction_shortcut = QShortcut(self.persepolis_setting.value('hide_window_shortcut'), self, self.minMaxTray)
        viewMenu.addAction(self.minimizeAction)

        # addlinkAction
        self.addlinkAction = QAction(QIcon(icons + 'add'), QCoreApplication.translate("mainwindow_ui_tr", 'Add New Download Link'), self,
                                     statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Add New Download Link"), triggered=self.addLinkButtonPressed)

        self.addlinkAction_shortcut = QShortcut(self.persepolis_setting.value('add_new_download_shortcut'), self, self.addLinkButtonPressed)
        fileMenu.addAction(self.addlinkAction)

        # importText
        self.addtextfileAction = QAction(QIcon(icons + 'file'), QCoreApplication.translate("mainwindow_ui_tr", 'Import links from text file'), self,
                                         statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Create a Text file and put links in it.line by line!'), triggered=self.importText)

        self.addtextfileAction_shortcut = QShortcut(self.persepolis_setting.value('import_text_shortcut'), self, self.importText)

        fileMenu.addAction(self.addtextfileAction)

        # resumeAction
        self.resumeAction = QAction(QIcon(icons + 'play'), QCoreApplication.translate("mainwindow_ui_tr", 'Resume Download'), self,
                                    statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Resume Download"), triggered=self.resumeButtonPressed)

        downloadMenu.addAction(self.resumeAction)

        # pauseAction
        self.pauseAction = QAction(QIcon(icons + 'pause'), QCoreApplication.translate("mainwindow_ui_tr", 'Pause Download'), self,
                                   statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Pause Download"), triggered=self.pauseButtonPressed)

        downloadMenu.addAction(self.pauseAction)

        # stopAction
        self.stopAction = QAction(QIcon(icons + 'stop'), QCoreApplication.translate("mainwindow_ui_tr", 'Stop Download'), self,
                                  statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Stop/Cancel Download"), triggered=self.stopButtonPressed)

        downloadMenu.addAction(self.stopAction)

        # propertiesAction
        self.propertiesAction = QAction(QIcon(icons + 'setting'), QCoreApplication.translate("mainwindow_ui_tr", 'Properties'), self,
                                        statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Properties"), triggered=self.propertiesButtonPressed)

        downloadMenu.addAction(self.propertiesAction)

        # progressAction
        self.progressAction = QAction(QIcon(icons + 'window'), QCoreApplication.translate("mainwindow_ui_tr", 'Progress'), self,
                                      statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Progress"), triggered=self.progressButtonPressed)

        downloadMenu.addAction(self.progressAction)

        # openFileAction
        self.openFileAction = QAction(QIcon(
            icons + 'file'), QCoreApplication.translate("mainwindow_ui_tr", 'Open file'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Open file'), triggered=self.openFile)
        fileMenu.addAction(self.openFileAction)

        
        # openDownloadFolderAction
        self.openDownloadFolderAction = QAction(QIcon(
            icons + 'folder'), QCoreApplication.translate("mainwindow_ui_tr", 'Open download folder'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Open download folder'), triggered=self.openDownloadFolder)

        fileMenu.addAction(self.openDownloadFolderAction)

        # openDefaultDownloadFolderAction
        self.openDefaultDownloadFolderAction = QAction(QIcon(
            icons + 'folder'), QCoreApplication.translate("mainwindow_ui_tr", 'Open default download folder'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Open default download folder'), triggered=self.openDefaultDownloadFolder)

        fileMenu.addAction(self.openDefaultDownloadFolderAction)

        # exitAction
        self.exitAction = QAction(QIcon(icons + 'exit'), QCoreApplication.translate("mainwindow_ui_tr", 'Exit'), self,
                                  statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Exit"), triggered=self.closeAction)

        self.exitAction_shortcut = QShortcut(self.persepolis_setting.value('quit_shortcut'), self, self.closeAction)

        fileMenu.addAction(self.exitAction)

        # clearAction
        self.clearAction = QAction(QIcon(icons + 'multi_remove'), QCoreApplication.translate("mainwindow_ui_tr", 'Clear download list'),
                                         self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Clear all items in download list'), triggered=self.clearDownloadList)
        editMenu.addAction(self.clearAction)

        # removeSelectedAction
        self.removeSelectedAction = QAction(QIcon(icons + 'remove'), QCoreApplication.translate("mainwindow_ui_tr", 'Remove selected downloads from list'),
                                            self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Remove selected downloads form list'), triggered=self.removeSelected)

        self.removeSelectedAction_shortcut = QShortcut(self.persepolis_setting.value('remove_shortcut'), self, self.removeSelected)

        editMenu.addAction(self.removeSelectedAction)
        self.removeSelectedAction.setEnabled(False)

        # deleteSelectedAction
        self.deleteSelectedAction = QAction(QIcon(icons + 'trash'), QCoreApplication.translate("mainwindow_ui_tr", 'Delete selected download files'),
                                            self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Delete selected download files'), triggered=self.deleteSelected)

        self.deleteSelectedAction_shortcut = QShortcut(self.persepolis_setting.value('delete_shortcut'), self, self.deleteSelected)

        editMenu.addAction(self.deleteSelectedAction)
        self.deleteSelectedAction.setEnabled(False)

        # moveSelectedDownloadsAction
        self.moveSelectedDownloadsAction = QAction(QIcon(icons + 'folder'), QCoreApplication.translate("mainwindow_ui_tr", 'move selected download files to another destination'),
                                            self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'move selected download files to another destination'), triggered=self.moveSelectedDownloads)

        editMenu.addAction(self.moveSelectedDownloadsAction)
        self.moveSelectedDownloadsAction.setEnabled(False)



        # createQueueAction
        self.createQueueAction = QAction(QIcon(icons + 'add_queue'), QCoreApplication.translate("mainwindow_ui_tr", 'Create new queue'),
                                         self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Create new download queue'), triggered=self.createQueue)
        queueMenu.addAction(self.createQueueAction)

        # removeQueueAction
        self.removeQueueAction = QAction(QIcon(icons + 'remove_queue'), QCoreApplication.translate("mainwindow_ui_tr", 'Remove this queue'),
                                         self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Remove this queue'), triggered=self.removeQueue)
        queueMenu.addAction(self.removeQueueAction)

        # startQueueAction
        self.startQueueAction = QAction(QIcon(
            icons + 'start_queue'), QCoreApplication.translate("mainwindow_ui_tr", 'Start this queue'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Start this queue'), triggered=self.startQueue)

        queueMenu.addAction(self.startQueueAction)

        # stopQueueAction
        self.stopQueueAction = QAction(QIcon(
            icons + 'stop_queue'), QCoreApplication.translate("mainwindow_ui_tr", 'Stop this queue'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Stop this queue'), triggered=self.stopQueue)

        queueMenu.addAction(self.stopQueueAction)

        # moveUpSelectedAction
        self.moveUpSelectedAction = QAction(QIcon(icons + 'multi_up'), QCoreApplication.translate("mainwindow_ui_tr", 'Move up selected items'), self,
                                            statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Move currently selected items up by one row'), triggered=self.moveUpSelected)

        self.moveUpSelectedAction_shortcut = QShortcut(self.persepolis_setting.value('move_up_selection_shortcut'), self, self.moveUpSelected)

        queueMenu.addAction(self.moveUpSelectedAction)

        # moveDownSelectedAction
        self.moveDownSelectedAction = QAction(QIcon(icons + 'multi_down'), QCoreApplication.translate("mainwindow_ui_tr", 'Move down selected items'),
                                              self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Move currently selected items down by one row'), triggered=self.moveDownSelected)
        self.moveDownSelectedAction_shortcut = QShortcut(self.persepolis_setting.value('move_down_selection_shortcut'), self, self.moveDownSelected)

        queueMenu.addAction(self.moveDownSelectedAction)

        # preferencesAction
        self.preferencesAction = QAction(QIcon(icons + 'preferences'), QCoreApplication.translate("mainwindow_ui_tr", 'Preferences'),
                                         self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Preferences'), triggered=self.openPreferences, menuRole=5)
        editMenu.addAction(self.preferencesAction)

        # aboutAction
        self.aboutAction = QAction(QIcon(
            icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'About'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'About'), triggered=self.openAbout, menuRole=4)
        helpMenu.addAction(self.aboutAction)

        # issueAction
        self.issueAction = QAction(QIcon(icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'Report an issue'),
                                   self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Report an issue'), triggered=self.reportIssue)
        helpMenu.addAction(self.issueAction)

        # updateAction
        self.updateAction = QAction(QIcon(icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'Check for newer version'),
                                    self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Check for newer release'), triggered=self.newUpdate)
        helpMenu.addAction(self.updateAction)

        # logAction
        self.logAction = QAction(QIcon(icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'Show log file'),
                                   self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Help'), triggered=self.showLog)
        helpMenu.addAction(self.logAction)

        # helpAction
        self.helpAction = QAction(QIcon(icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'Help'),
                                   self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Help'), triggered=self.persepolisHelp)
        helpMenu.addAction(self.helpAction)

        self.persepolis_setting.endGroup()

        self.qmenu = MenuWidget(self)

        self.toolBar2.addWidget(self.qmenu)


# labels
        self.queue_panel_show_button.setText(QCoreApplication.translate("mainwindow_ui_tr", "Hide options"))
        self.start_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "Start Time"))

        self.end_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "End Time"))

        self.reverse_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "Download bottom of\n the list first"))

        self.limit_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "Limit Speed"))
        self.limit_comboBox.setItemText(0, "KiB/s")
        self.limit_comboBox.setItemText(1, "MiB/s")
        self.limit_pushButton.setText(QCoreApplication.translate("mainwindow_ui_tr", "Apply"))

        self.after_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "After download"))
        self.after_comboBox.setItemText(0, QCoreApplication.translate("mainwindow_ui_tr", "Shut Down"))

        self.keep_awake_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "Keep system awake!"))
        self.keep_awake_checkBox.setToolTip(
            QCoreApplication.translate("mainwindow_ui_tr", "<html><head/><body><p>This option is preventing system from going to sleep.\
            This is necessary if your power manager is suspending system automatically. </p></body></html>"))
 
        self.after_pushButton.setText(QCoreApplication.translate("mainwindow_ui_tr", "Apply"))

        self.muxing_pushButton.setText(QCoreApplication.translate("mainwindow_ui_tr", "start muxing"))

        self.video_label.setText(QCoreApplication.translate("mainwindow_ui_tr", "<b>Video file status: </b>"))
        self.audio_label.setText(QCoreApplication.translate("mainwindow_ui_tr", "<b>Audio file status: </b>"))

        self.video_finder_status_label.setText(QCoreApplication.translate("mainwindow_ui_tr", "<b>Status: </b>"))
        self.muxing_status_label.setText(QCoreApplication.translate("mainwindow_ui_tr", "<b>Muxing status: </b>"))
Пример #30
0
class ToolbarUI(object):
    def __init__(self, main_window: QMainWindow):
        """
        工具导航
        外观模式
        :param main_window:
        """
        self.main_window = main_window
        self.toolbar = QToolBar(self.main_window)

        # 子类
        self.ui_list = []
        self.server_start_ui = ServerStartUI(self.toolbar)  # 服务器开关
        self.file_manager_ui = FileManagerUI(self.toolbar)  # 文件管理
        self.terminal_ui = TerminalUI(self.toolbar)  # 远程终端
        self.remote_control_ui = RemoteControlUI(self.toolbar)  # 远程控制
        self.video_monitor_ui = VideoMonitorUI(self.toolbar)  # 视频监控
        self.voice_monitor_ui = VoiceMonitorUI(self.toolbar)  # 语音监控
        self.keyboard_ui = KeyboardUI(self.toolbar)  # 键盘记录
        self.make_client_ui = MakeClientUI(self.toolbar)  # 创建客户端
        self.service_manager_ui = ServiceManagerUI(self.toolbar)  # 服务管理
        self.exit_ui = ExitUI(self.toolbar, self.main_window)  # 退出程序

        # 子类信号
        self.connect_list = []
        self.server_start_connect = ServerStartConnect(self.server_start_ui)

    def options(self) -> None:
        """
        参数设置
        :return:
        """
        self.toolbar.setObjectName("toolBar")

        # 设置是否可以移动
        self.toolbar.setMovable(True)

        # 设置是否可以悬浮在主窗口
        self.toolbar.setFloatable(True)

        # 设置图标尺寸
        self.toolbar.setIconSize(QSize(25, 25))

        # 字体在右边
        # self.tools_main.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

        # 字体在下面
        if settings.LOAD_EFFECT_ON:
            self.toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
            load_animation.load_animation(self.toolbar)

        # 窗口添加工具导航栏
        self.main_window.addToolBar(Qt.TopToolBarArea, self.toolbar)

    def setup_ui(self) -> None:
        self.options()

        if not settings.TOOLBAR_SHOW:
            self.toolbar.hide()

        self.load_ui()
        self.load_connect()
        self.show_ui()

        # QDockWidget 位置发生变动
        self.toolbar.orientationChanged.connect(self.orientation_changed)

    def orientation_changed(self, event) -> None:
        """
        位置变动事件
        :param event:
        :return:
        """
        if event:
            pass
        if settings.LOAD_EFFECT_ON:
            load_animation.load_animation(self.toolbar)

    # noinspection PyArgumentList
    def retranslate_ui(self) -> None:
        self.toolbar.setWindowTitle(_translate("ToolbarUI", "工具导航"))

    def load_ui(self) -> None:
        """
        加载模块
        :return:
        """
        self.ui_list.append(self.server_start_ui)
        self.ui_list.append(self.file_manager_ui)
        self.ui_list.append(self.terminal_ui)
        self.ui_list.append(self.remote_control_ui)
        self.ui_list.append(self.video_monitor_ui)
        self.ui_list.append(self.voice_monitor_ui)
        self.ui_list.append(self.keyboard_ui)
        self.ui_list.append(self.make_client_ui)
        self.ui_list.append(self.service_manager_ui)
        self.ui_list.append(self.exit_ui)

    def load_connect(self) -> None:
        """
        加载 链接信号
        :return:
        """
        self.connect_list.append(self.server_start_connect)

    def show_ui(self) -> None:
        """
        显示数据
        :return:
        """
        all_list = self.ui_list + self.connect_list
        for item in all_list:
            item.setup_ui()
            item.retranslate_ui()
Пример #31
0
    def __init__(self, stampManager, parent = None):
        super().__init__(parent)
        
        self.mTileStampManager = stampManager
        self.mTileStampModel = stampManager.tileStampModel()
        self.mProxyModel = QSortFilterProxyModel(self.mTileStampModel)
        self.mFilterEdit = QLineEdit(self)
        self.mNewStamp = QAction(self)
        self.mAddVariation = QAction(self)
        self.mDuplicate = QAction(self)
        self.mDelete = QAction(self)
        self.mChooseFolder = QAction(self)

        self.setObjectName("TileStampsDock")
        self.mProxyModel.setSortLocaleAware(True)
        self.mProxyModel.setSortCaseSensitivity(Qt.CaseInsensitive)
        self.mProxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.mProxyModel.setSourceModel(self.mTileStampModel)
        self.mProxyModel.sort(0)
        self.mTileStampView = TileStampView(self)
        self.mTileStampView.setModel(self.mProxyModel)
        self.mTileStampView.setVerticalScrollMode(QAbstractItemView.ScrollPerPixel)
        self.mTileStampView.header().setStretchLastSection(False)
        self.mTileStampView.header().setSectionResizeMode(0, QHeaderView.Stretch)
        self.mTileStampView.header().setSectionResizeMode(1, QHeaderView.ResizeToContents)
        self.mTileStampView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.mTileStampView.customContextMenuRequested.connect(self.showContextMenu)
        self.mNewStamp.setIcon(QIcon(":images/16x16/document-new.png"))
        self.mAddVariation.setIcon(QIcon(":/images/16x16/add.png"))
        self.mDuplicate.setIcon(QIcon(":/images/16x16/stock-duplicate-16.png"))
        self.mDelete.setIcon(QIcon(":images/16x16/edit-delete.png"))
        self.mChooseFolder.setIcon(QIcon(":images/16x16/document-open.png"))
        Utils.setThemeIcon(self.mNewStamp, "document-new")
        Utils.setThemeIcon(self.mAddVariation, "add")
        Utils.setThemeIcon(self.mDelete, "edit-delete")
        Utils.setThemeIcon(self.mChooseFolder, "document-open")

        self.mFilterEdit.setClearButtonEnabled(True)
        self.mFilterEdit.textChanged.connect(self.mProxyModel.setFilterFixedString)
        self.mTileStampModel.stampRenamed.connect(self.ensureStampVisible)
        self.mNewStamp.triggered.connect(self.newStamp)
        self.mAddVariation.triggered.connect(self.addVariation)
        self.mDuplicate.triggered.connect(self.duplicate)
        self.mDelete.triggered.connect(self.delete_)
        self.mChooseFolder.triggered.connect(self.chooseFolder)
        self.mDuplicate.setEnabled(False)
        self.mDelete.setEnabled(False)
        self.mAddVariation.setEnabled(False)
        widget = QWidget(self)
        layout = QVBoxLayout(widget)
        layout.setContentsMargins(5, 5, 5, 5)
        
        buttonContainer = QToolBar()
        buttonContainer.setFloatable(False)
        buttonContainer.setMovable(False)
        buttonContainer.setIconSize(QSize(16, 16))
        buttonContainer.addAction(self.mNewStamp)
        buttonContainer.addAction(self.mAddVariation)
        buttonContainer.addAction(self.mDuplicate)
        buttonContainer.addAction(self.mDelete)
        stretch = QWidget()
        stretch.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        buttonContainer.addWidget(stretch)
        buttonContainer.addAction(self.mChooseFolder)
        listAndToolBar = QVBoxLayout()
        listAndToolBar.setSpacing(0)
        listAndToolBar.addWidget(self.mFilterEdit)
        listAndToolBar.addWidget(self.mTileStampView)
        listAndToolBar.addWidget(buttonContainer)
        layout.addLayout(listAndToolBar)
        selectionModel = self.mTileStampView.selectionModel()
        selectionModel.currentRowChanged.connect(self.currentRowChanged)
        self.setWidget(widget)
        self.retranslateUi()
Пример #32
0
class MainWindow(QMainWindow):
    """

    """
    def __init__(self):
        super(MainWindow, self).__init__()

        self.menu_bar = QMenuBar()

        self.file_menu = QMenu("文件(&F)", self.menu_bar)
        self.open_action = QAction("打开(O)", self.file_menu)
        self.open_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_O))
        self.search_action = QAction("搜索(F)", self.file_menu)
        self.search_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_F))
        self.search_action.triggered.connect(self.show_search_widget)
        self.close_action = QAction("关闭(C)", self.file_menu)
        self.close_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_C))
        self.close_action.triggered.connect(self.answer_close_action_triggered)
        self.quit_action = QAction("退出(Q)", self.file_menu)
        self.quit_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_Q))
        self.quit_action.triggered.connect(lambda: sys.exit())

        self.play_menu = QMenu("播放(&L)", self.menu_bar)
        self.play_action = QAction("播放(P)", self.play_menu)
        self.stop_action = QAction("停止(S)", self.play_menu)
        self.pause_action = QAction("暂停(P)", self.play_menu)
        self.resume_action = QAction("恢复(R)", self.play_menu)
        self.rate_action = QAction("倍速(R)", self.play_menu)
        self.jump_action = QAction("跳转(J)", self.play_menu)
        self.mute_action = QAction("静音(M)", self.play_menu)
        self.volume_up_action = QAction("增大音量(U)", self.play_menu)
        self.volume_down_action = QAction("减小音量(D)", self.play_menu)

        self.enhance_menu = QMenu("增强(&E)", self.menu_bar)
        self.skin_menu = QMenu("换肤", self.enhance_menu)
        self.dark_skin_action = QAction("暗黑模式", self.skin_menu)
        self.dark_skin_action.setCheckable(True)
        self.dark_skin_action.triggered.connect(
            self.answer_dark_skin_action_triggered)
        self.white_skin_action = QAction("纯白模式", self.skin_menu)
        self.white_skin_action.setCheckable(True)
        self.white_skin_action.triggered.connect(
            self.answer_white_skin_action_triggered)
        self.blue_skin_action = QAction("浅蓝模式", self.skin_menu)
        self.blue_skin_action.setCheckable(True)
        self.blue_skin_action.triggered.connect(
            self.answer_blue_skin_action_triggered)
        self.skin_action_group = QActionGroup(self)
        self.skin_action_group.addAction(self.dark_skin_action)
        self.skin_action_group.addAction(self.white_skin_action)
        self.skin_action_group.addAction(self.blue_skin_action)

        self.language_menu = QMenu("语言", self.enhance_menu)
        self.zh_CN_action = QAction("简体中文", self.language_menu)
        self.zh_CN_action.setCheckable(True)
        self.zh_CN_action.triggered.connect(self.answer_zh_CN_action_triggered)
        self.en_action = QAction("English", self.language_menu)
        self.en_action.setCheckable(True)
        self.en_action.triggered.connect(self.answer_en_action_triggered)
        self.language_action_group = QActionGroup(self)
        self.language_action_group.addAction(self.zh_CN_action)
        self.language_action_group.addAction(self.en_action)

        self.font_action = QAction("字体(F)", self.enhance_menu)
        self.font_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_S))
        self.font_action.triggered.connect(self.answer_font_action_triggered)
        self.hide_action = QAction("隐藏(V)", self.enhance_menu)
        self.hide_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_V))
        self.hide_action.setCheckable(True)
        self.hide_action.triggered.connect(self.answer_hide_action_triggered)

        self.tool_menu = QMenu("工具(&T)", self.menu_bar)
        self.screenshot_action = QAction("截图(J)", self.tool_menu)
        self.screenshot_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_J))
        self.screenshot_action.triggered.connect(
            self.answer_screenshot_action_triggered)
        self.gif_action = QAction("动图(G)", self.tool_menu)
        self.gif_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_G))
        self.gif_action.triggered.connect(self.answer_gif_action_triggered)
        self.screen_record_action = QAction("录屏(L)", self.tool_menu)
        self.screen_record_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_L))
        self.screen_record_action.triggered.connect(
            self.answer_screen_record_action_triggered)

        self.help_menu = QMenu("帮助(&H)", self.menu_bar)
        self.help_action = QAction("帮助文档(H)", self.help_menu)
        self.help_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_H))
        self.help_action.triggered.connect(self.answer_help_action_triggered)
        self.change_log_action = QAction("更新日志(U)", self.help_menu)
        self.change_log_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_U))
        self.change_log_action.triggered.connect(
            self.answer_change_log_action_triggered)
        self.check_version_action = QAction("检查版本(C)", self.help_menu)
        self.check_version_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_C))
        self.check_version_action.triggered.connect(
            self.answer_check_version_action_triggered)
        self.about_action = QAction("关于软件(A)", self.help_menu)
        self.about_action.setShortcut(QKeySequence(Qt.CTRL + Qt.Key_A))
        self.about_action.triggered.connect(self.answer_about_action_triggered)

        self.tool_bar = QToolBar()
        self.tool_bar.setFloatable(False)
        self.tool_bar.setMovable(True)
        self.tool_bar.setIconSize(QSize(32, 32))
        # self.tool_bar.setStyleSheet("QToolBar{border: 1px solid #313335; spacing:5px; }")
        self.addToolBar(Qt.TopToolBarArea, self.tool_bar)
        self.search_tool_action = QAction("", self.tool_bar)
        self.search_tool_action.setToolTip("信息搜索")
        self.search_tool_action.setIcon(
            QIcon("./resources/img/[email protected]"))
        self.search_widget = SearchWidget()
        self.search_tool_action.triggered.connect(self.show_search_widget)
        self.search_widget.watch_live_signal.connect(
            self.answer_watch_live_signal)

        self.attention_tool_action = QAction("", self.tool_bar)
        self.attention_tool_action.setToolTip("历史关注")
        self.attention_tool_action.setIcon(
            QIcon("./resources/img/[email protected]"))
        # self.attention_tool_action.triggered.connect(self.show_search_widget)

        self.pure_tool_action = QAction("", self.tool_bar)
        self.pure_tool_action.setToolTip("纯净模式")
        self.pure_tool_action.setIcon(
            QIcon("./resources/img/[email protected]"))
        # self.pure_tool_action.triggered.connect(self.show_search_widget)

        self.nlp_tool_action = QAction("", self.tool_bar)
        self.nlp_tool_action.setToolTip("智能字幕")
        self.nlp_tool_action.setIcon(QIcon("./resources/img/[email protected]"))
        # self.nlp_tool_action.triggered.connect(self.show_search_widget)

        self.note_tool_action = QAction("", self.tool_bar)
        self.note_tool_action.setToolTip("边看边记")
        self.note_tool_action.setIcon(
            QIcon("./resources/img/[email protected]"))
        # self.note_tool_action.triggered.connect(self.show_search_widget)

        self.live_widget = LiveWidget()

        self.init_ui()
        self._init_cfg()

    def init_ui(self):
        """

        :return:
        """
        # 菜单栏
        self.file_menu.addAction(self.open_action)
        self.file_menu.addAction(self.search_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.close_action)
        self.file_menu.addAction(self.quit_action)

        self.play_menu.addAction(self.play_action)
        self.play_menu.addAction(self.stop_action)
        self.play_menu.addAction(self.pause_action)
        self.play_menu.addAction(self.resume_action)
        self.play_menu.addSeparator()
        self.play_menu.addAction(self.rate_action)
        self.play_menu.addAction(self.jump_action)
        self.play_menu.addSeparator()
        self.play_menu.addAction(self.mute_action)
        self.play_menu.addAction(self.volume_up_action)
        self.play_menu.addAction(self.volume_down_action)

        self.enhance_menu.addMenu(self.skin_menu)
        self.skin_menu.addAction(self.dark_skin_action)
        self.skin_menu.addAction(self.white_skin_action)
        self.skin_menu.addAction(self.blue_skin_action)
        self.enhance_menu.addMenu(self.language_menu)
        self.language_menu.addAction(self.zh_CN_action)
        self.language_menu.addAction(self.en_action)
        self.enhance_menu.addAction(self.font_action)
        self.enhance_menu.addSeparator()
        self.enhance_menu.addAction(self.hide_action)

        self.tool_menu.addAction(self.screenshot_action)
        self.tool_menu.addAction(self.gif_action)
        self.tool_menu.addAction(self.screen_record_action)
        self.tool_menu.addSeparator()

        self.help_menu.addAction(self.help_action)
        self.help_menu.addAction(self.change_log_action)
        self.help_menu.addAction(self.check_version_action)
        self.help_menu.addSeparator()
        self.help_menu.addAction(self.about_action)

        self.menu_bar.addMenu(self.file_menu)
        self.menu_bar.addMenu(self.play_menu)
        self.menu_bar.addMenu(self.enhance_menu)
        self.menu_bar.addMenu(self.tool_menu)
        self.menu_bar.addMenu(self.help_menu)

        self.setMenuBar(self.menu_bar)

        # 工具栏
        self.tool_bar.addAction(self.search_tool_action)
        self.tool_bar.addSeparator()
        self.tool_bar.addAction(self.attention_tool_action)
        self.tool_bar.addSeparator()
        self.tool_bar.addAction(self.pure_tool_action)
        self.tool_bar.addSeparator()
        self.tool_bar.addAction(self.nlp_tool_action)
        self.tool_bar.addSeparator()
        self.tool_bar.addAction(self.note_tool_action)
        self.tool_bar.addSeparator()

        # 显示区域
        self.setCentralWidget(self.live_widget)

        self.set_window_info()

    def _init_cfg(self):
        """

        :return:
        """
        # 工具栏可见性
        visible = retrieve_content("preferences", "tool_bar_visible")
        if visible == "True":
            self.hide_action.setChecked(False)
            self.hide_action.triggered.emit(False)
        else:
            self.hide_action.setChecked(True)
            self.hide_action.triggered.emit(True)

        # 工具栏位置
        position = retrieve_content("preferences", "tool_bar_position")

        # 皮肤设置
        skin = retrieve_content("preferences", "skin")
        if skin == "dark":
            self.dark_skin_action.setChecked(True)
            self.dark_skin_action.triggered.emit()
        elif skin == "white":
            self.white_skin_action.setChecked(True)
            self.white_skin_action.triggered.emit()
        else:
            self.blue_skin_action.setChecked(True)
            self.blue_skin_action.triggered.emit()

        # 字体设置
        font_family = retrieve_content("preferences", "font-family")
        font_style = retrieve_content("preferences", "font-style")
        font_size = retrieve_content("preferences", "font-size")
        font = QFont()
        font.setFamily(font_family)
        font.setStyleName(font_style)
        font.setPointSize(int(font_size))
        qApp.setFont(font)
        qApp.processEvents()

    def set_window_info(self):
        """

        :return:
        """
        desktop_widget = QDesktopWidget()
        screen_rect = desktop_widget.screenGeometry()
        self.setGeometry(screen_rect)
        title = retrieve_content("software_info",
                                 "software_name") + " " + retrieve_content(
                                     "software_info", "software_version")
        self.setWindowTitle(title)
        self.setWindowIcon(QIcon('./resources/img/[email protected]'))
        self.showMaximized()

    def show_search_widget(self):
        """

        :return:
        """
        width, height = get_window_center_point(self.search_widget)
        self.search_widget.move(width, height)
        self.search_widget.exec_()

    @staticmethod
    def answer_help_action_triggered():
        """

        :return:
        """
        desktop_services = QDesktopServices()
        desktop_services.openUrl(
            QUrl(
                "https://github.com/parzulpan/real-live/blob/master/resources/Help.md"
            ))

    @staticmethod
    def answer_change_log_action_triggered():
        """

        :return:
        """
        desktop_services = QDesktopServices()
        desktop_services.openUrl(
            QUrl(
                "https://github.com/parzulpan/real-live/blob/master/resources/ChangeLog.md"
            ))

    @staticmethod
    def answer_check_version_action_triggered():
        """

        :return:
        """
        # TODO: 获取GitHub API 进行检查并弹窗
        desktop_services = QDesktopServices()
        desktop_services.openUrl(
            QUrl("https://github.com/parzulpan/real-live/releases"))

    @staticmethod
    def answer_about_action_triggered():
        """

        :return:
        """
        about_widget = AboutWidget()
        width, height = get_window_center_point(about_widget)
        about_widget.move(width, height)
        about_widget.exec_()

    def answer_watch_live_signal(self, url):
        """

        :param url:
        :return:
        """
        # self.live_widget.vlc_widget.get_player()
        self.live_widget.vlc_widget.play_url(url)
        self.live_widget.set_player_widget(True)

    def answer_close_action_triggered(self):
        """

        :return:
        """
        self.live_widget.set_player_widget(False)
        # self.live_widget.vlc_widget.get_player()
        # self.live_widget.vlc_widget.release_player()
        self.live_widget.vlc_widget.stop()

    def answer_hide_action_triggered(self, checked):
        """

        :param checked:
        :return:
        """
        if checked:
            self.tool_bar.hide()
            update_contents("preferences", "tool_bar_visible", "False")
        else:
            self.tool_bar.show()
            update_contents("preferences", "tool_bar_visible", "True")

    def answer_tool_bar_top_level_changed(self, area):
        """

        :return:
        """
        print("top_level_changed")
        print(area)
        if self.tool_bar.allowedAreas() == Qt.LeftToolBarArea:
            print("LeftToolBarArea")
        elif self.tool_bar.allowedAreas() == Qt.RightToolBarArea:
            print("RightToolBarArea")
        elif self.tool_bar.allowedAreas() == Qt.BottomToolBarArea:
            print("BottomToolBarArea")
        elif self.tool_bar.allowedAreas() == Qt.TopToolBarArea:
            print("TopToolBarArea")
        else:
            print("else")

    @staticmethod
    def answer_screenshot_action_triggered():
        """

        :return:
        """
        # dll = windll.LoadLibrary('./bin/OEScreenshot.dll')
        # dll = WinDLL('./bin/OEScreenshot.dll')
        # dll = cdll.LoadLibrary('./bin/OEScreenshot.dll')
        dll = CDLL('./bin/screenshot/OEScreenshot.dll')
        print(dll)

    def answer_gif_action_triggered(self):
        """

        :return:
        """
        pass

    def answer_screen_record_action_triggered(self):
        """

        :return:
        """
        pass

    @staticmethod
    def answer_dark_skin_action_triggered(checked):
        """

        :param checked:
        :return:
        """
        with open("./resources/qss/dark.qss", "r", encoding="utf-8") as f:
            qss = f.read()
            qApp.setStyleSheet(qss)
        update_contents("preferences", "skin", "dark")

    @staticmethod
    def answer_white_skin_action_triggered(checked):
        """

        :param checked:
        :return:
        """
        with open("./resources/qss/white.qss", "r", encoding="utf-8") as f:
            qss = f.read()
            qApp.setStyleSheet(qss)
        update_contents("preferences", "skin", "white")

    @staticmethod
    def answer_blue_skin_action_triggered(checked):
        """

        :param checked:
        :return:
        """
        with open("./resources/qss/blue.qss", "r", encoding="utf-8") as f:
            qss = f.read()
            qApp.setStyleSheet(qss)
        update_contents("preferences", "skin", "blue")

    def answer_font_action_triggered(self, checked):
        """

        :param checked:
        :return:
        """
        font = qApp.font()
        font, changed = QFontDialog().getFont(font, self, caption="字体设置")
        if changed:
            qApp.setFont(font)
            qApp.processEvents()
            update_contents("preferences", "font-family", font.family())
            update_contents("preferences", "font-style", font.styleName())
            update_contents("preferences", "font-size", str(font.pointSize()))

    def answer_zh_CN_action_triggered(self, checked):
        """

        :param checked:
        :return:
        """
        pass

    def answer_en_action_triggered(self, checked):
        """

        :param checked:
        :return:
        """
        pass

    def closeEvent(self, event) -> None:
        """

        :param event:
        :return:
        """
        print("closeEvent")
        self.live_widget.vlc_widget.release_player()
Пример #33
0
class AppWindow(QMainWindow):
    "The application's main window"

    def __init__(self):
        super().__init__()
        self.initUI()
        self.start_up()
        QTimer.singleShot(3000, self._check_update)

    def init_watchers(self):
        def remove_gallery(g):
            index = self.manga_list_view.find_index(g.id)
            if index:
                self.manga_list_view.remove_gallery([index])

        def create_gallery(path):
            g_dia = gallerydialog.GalleryDialog(self, path)
            g_dia.SERIES.connect(self.manga_list_view.gallery_model.addRows)
            g_dia.show()

        def update_gallery(g):
            index = self.manga_list_view.find_index(g.id)
            if index:
                self.manga_list_view.replace_edit_gallery([g], index.row())
            else:
                log_e("Could not find gallery to update from Watcher")

        def created(path):
            c_popup = file_misc.CreatedPopup(path, self)
            c_popup.ADD_SIGNAL.connect(create_gallery)

        def modified(path, gallery):
            mod_popup = file_misc.ModifiedPopup(path, gallery, self)

        def deleted(path, gallery):
            d_popup = file_misc.DeletedPopup(path, gallery, self)
            d_popup.UPDATE_SIGNAL.connect(update_gallery)
            d_popup.REMOVE_SIGNAL.connect(remove_gallery)

        def moved(new_path, gallery):
            mov_popup = file_misc.MovedPopup(new_path, gallery, self)
            mov_popup.UPDATE_SIGNAL.connect(update_gallery)

        self.watchers = file_misc.Watchers()
        self.watchers.gallery_handler.CREATE_SIGNAL.connect(created)
        self.watchers.gallery_handler.MODIFIED_SIGNAL.connect(modified)
        self.watchers.gallery_handler.MOVED_SIGNAL.connect(moved)
        self.watchers.gallery_handler.DELETED_SIGNAL.connect(deleted)

        if gui_constants.LOOK_NEW_GALLERY_STARTUP:
            self.notification_bar.add_text("Looking for new galleries...")
            try:

                class ScanDir(QObject):
                    final_paths_and_galleries = pyqtSignal(list, list)

                    def __init__(self, model_data, parent=None):
                        super().__init__(parent)
                        self.model_data = model_data

                    def scan_dirs(self):
                        db_data = self.model_data
                        paths = []
                        for g in range(len(db_data)):
                            paths.append(os.path.normcase(db_data[g].path))

                        contents = []
                        case_path = []  # needed for tile and artist parsing... e.g to avoid lowercase
                        for m_path in gui_constants.MONITOR_PATHS:
                            for p in os.listdir(m_path):
                                abs_p = os.path.join(m_path, p)
                                if os.path.isdir(abs_p) or p.endswith(utils.ARCHIVE_FILES):
                                    case_path.append(abs_p)
                                    contents.append(os.path.normcase(abs_p))

                        paths = sorted(paths)
                        new_galleries = []
                        for c, x in enumerate(contents):
                            y = utils.b_search(paths, x)
                            if not y:
                                # (path, number for case_path)
                                new_galleries.append((x, c))

                        galleries = []
                        final_paths = []
                        if new_galleries:
                            for g in new_galleries:
                                gallery = gallerydb.Gallery()
                                try:
                                    gallery.profile = utils.get_gallery_img(g[0])
                                except:
                                    gallery.profile = gui_constants.NO_IMAGE_PATH
                                parser_dict = utils.title_parser(os.path.split(case_path[g[1]])[1])
                                gallery.title = parser_dict["title"]
                                gallery.artist = parser_dict["artist"]
                                galleries.append(gallery)
                                final_paths.append(case_path[g[1]])
                        self.final_paths_and_galleries.emit(final_paths, galleries)
                        # if gui_constants.LOOK_NEW_GALLERY_AUTOADD:
                        # 	QTimer.singleShot(10000, self.gallery_populate(final_paths))
                        # 	return

                def show_new_galleries(final_paths, galleries):
                    if final_paths and galleries:
                        if gui_constants.LOOK_NEW_GALLERY_AUTOADD:
                            self.gallery_populate(final_paths)
                        else:
                            if len(galleries) == 1:
                                self.notification_bar.add_text(
                                    "{} new gallery was discovered in one of your monitored directories".format(
                                        len(galleries)
                                    )
                                )
                            else:
                                self.notification_bar.add_text(
                                    "{} new galleries were discovered in one of your monitored directories".format(
                                        len(galleries)
                                    )
                                )
                            text = (
                                "These new galleries were discovered! Do you want to add them?"
                                if len(galleries) > 1
                                else "This new gallery was discovered! Do you want to add it?"
                            )
                            g_popup = file_misc.GalleryPopup((text, galleries), self)
                            buttons = g_popup.add_buttons("Add", "Close")

                            def populate_n_close():
                                self.gallery_populate(final_paths)
                                g_popup.close()

                            buttons[0].clicked.connect(populate_n_close)
                            buttons[1].clicked.connect(g_popup.close)

                thread = QThread(self)
                self.scan_inst = ScanDir(self.manga_list_view.gallery_model._data)
                self.scan_inst.moveToThread(thread)
                self.scan_inst.final_paths_and_galleries.connect(show_new_galleries)
                self.scan_inst.final_paths_and_galleries.connect(lambda a: self.scan_inst.deleteLater())
                thread.started.connect(self.scan_inst.scan_dirs)
                thread.finished.connect(thread.deleteLater)
                thread.start()
            except:
                self.notification_bar.add_text(
                    "An error occured while attempting to scan for new galleries. Check happypanda.log."
                )
                log.exception("An error occured while attempting to scan for new galleries.")

    def start_up(self):
        def normalize_first_time():
            settings.set(2, "Application", "first time level")

        def done():
            self.manga_list_view.gallery_model.init_data()
            if gui_constants.ENABLE_MONITOR and gui_constants.MONITOR_PATHS and all(gui_constants.MONITOR_PATHS):
                self.init_watchers()
            if gui_constants.FIRST_TIME_LEVEL != 2:
                normalize_first_time()

        if gui_constants.FIRST_TIME_LEVEL < 2:

            class FirstTime(file_misc.BasePopup):
                def __init__(self, parent=None):
                    super().__init__(parent)
                    main_layout = QVBoxLayout()
                    info_lbl = QLabel(
                        "Hi there! Some big changes are about to occur!\n"
                        + "Please wait.. This will take at most a few minutes.\n"
                        + "If not then try restarting the application."
                    )
                    info_lbl.setAlignment(Qt.AlignCenter)
                    main_layout.addWidget(info_lbl)
                    prog = QProgressBar(self)
                    prog.setMinimum(0)
                    prog.setMaximum(0)
                    prog.setTextVisible(False)
                    main_layout.addWidget(prog)
                    main_layout.addWidget(QLabel("Note: This popup will close itself when everything is ready"))
                    self.main_widget.setLayout(main_layout)

            ft_widget = FirstTime(self)
            log_i("Invoking first time level 2")
            bridge = gallerydb.Bridge()
            thread = QThread(self)
            thread.setObjectName("Startup")
            bridge.moveToThread(thread)
            thread.started.connect(bridge.rebuild_galleries)
            bridge.DONE.connect(ft_widget.close)
            bridge.DONE.connect(self.setEnabled)
            bridge.DONE.connect(done)
            bridge.DONE.connect(bridge.deleteLater)
            thread.finished.connect(thread.deleteLater)
            thread.start()
            ft_widget.adjustSize()
            ft_widget.show()
            self.setEnabled(False)
        else:
            done()

    def initUI(self):
        self.center = QWidget()
        self.display = QStackedLayout()
        self.center.setLayout(self.display)
        # init the manga view variables
        self.manga_display()
        log_d("Create manga display: OK")
        # init the chapter view variables
        # self.chapter_display()
        self.m_l_view_index = self.display.addWidget(self.manga_list_main)
        self.m_t_view_index = self.display.addWidget(self.manga_table_view)
        # init toolbar
        self.init_toolbar()
        log_d("Create toolbar: OK")
        # init status bar
        self.init_stat_bar()
        log_d("Create statusbar: OK")

        self.system_tray = misc.SystemTray(QIcon(gui_constants.APP_ICO_PATH), self)
        gui_constants.SYSTEM_TRAY = self.system_tray
        tray_menu = QMenu(self)
        self.system_tray.setContextMenu(tray_menu)
        self.system_tray.setToolTip("Happypanda {}".format(gui_constants.vs))
        tray_quit = QAction("Quit", tray_menu)
        tray_menu.addAction(tray_quit)
        tray_quit.triggered.connect(self.close)
        self.system_tray.show()
        log_d("Create system tray: OK")

        # self.display.addWidget(self.chapter_main)

        self.setCentralWidget(self.center)
        self.setWindowTitle("Happypanda")
        self.setWindowIcon(QIcon(gui_constants.APP_ICO_PATH))

        props = settings.win_read(self, "AppWindow")
        if props.resize:
            x, y = props.resize
            self.resize(x, y)
        else:
            self.resize(gui_constants.MAIN_W, gui_constants.MAIN_H)
        posx, posy = props.pos
        self.move(posx, posy)
        self.show()
        log_d("Show window: OK")

        self.notification_bar = misc.NotificationOverlay(self)
        p = self.toolbar.pos()
        self.notification_bar.move(p.x(), p.y() + self.toolbar.height())
        self.notification_bar.resize(self.width())
        gui_constants.NOTIF_BAR = self.notification_bar
        log_d("Create notificationbar: OK")

        log_d("Window Create: OK")

    def _check_update(self):
        class upd_chk(QObject):
            UPDATE_CHECK = pyqtSignal(str)

            def __init__(self, **kwargs):
                super().__init__(**kwargs)

            def fetch_vs(self):
                import requests
                import time

                try:
                    log_d("Checking Update")
                    time.sleep(1.5)
                    r = requests.get(
                        "https://raw.githubusercontent.com/Pewpews/happypanda/master/VS.txt", verify="cacert.pem"
                    )
                    a = r.text
                    vs = a.strip()
                    self.UPDATE_CHECK.emit(vs)
                except:
                    log.exception("Checking Update: FAIL")
                    self.UPDATE_CHECK.emit("this is a very long text which is is sure to be over limit")

        def check_update(vs):
            log_i("Received version: {}\nCurrent version: {}".format(vs, gui_constants.vs))
            if vs != gui_constants.vs:
                if len(vs) < 10:
                    self.notification_bar.add_text(
                        "Version {} of Happypanda is".format(vs) + " available. Click here to update!", False
                    )
                    self.notification_bar.clicked.connect(
                        lambda: utils.open_web_link("https://github.com/Pewpews/happypanda/releases")
                    )
                    self.notification_bar.set_clickable(True)
                else:
                    self.notification_bar.add_text("An error occurred while checking for new version")

        self.update_instance = upd_chk()
        thread = QThread(self)
        self.update_instance.moveToThread(thread)
        thread.started.connect(self.update_instance.fetch_vs)
        self.update_instance.UPDATE_CHECK.connect(check_update)
        self.update_instance.UPDATE_CHECK.connect(self.update_instance.deleteLater)
        thread.finished.connect(thread.deleteLater)
        thread.start()

    def _web_metadata_picker(self, gallery, title_url_list, queue, parent=None):
        if not parent:
            parent = self
        text = "Which gallery do you want to extract metadata from?"
        s_gallery_popup = misc.SingleGalleryChoices(gallery, title_url_list, text, parent)
        s_gallery_popup.USER_CHOICE.connect(queue.put)

    def get_metadata(self, gal=None):
        thread = QThread(self)
        thread.setObjectName("App.get_metadata")
        fetch_instance = fetch.Fetch()
        if gal:
            galleries = [gal]
        else:
            if gui_constants.CONTINUE_AUTO_METADATA_FETCHER:
                galleries = [g for g in self.manga_list_view.gallery_model._data if not g.exed]
            else:
                galleries = self.manga_list_view.gallery_model._data
            if not galleries:
                self.notification_bar.add_text("Looks like we've already gone through all galleries!")
                return None
        fetch_instance.galleries = galleries

        self.notification_bar.begin_show()
        fetch_instance.moveToThread(thread)

        def done(status):
            self.notification_bar.end_show()
            fetch_instance.deleteLater()

        fetch_instance.GALLERY_PICKER.connect(self._web_metadata_picker)
        fetch_instance.GALLERY_EMITTER.connect(self.manga_list_view.replace_edit_gallery)
        fetch_instance.AUTO_METADATA_PROGRESS.connect(self.notification_bar.add_text)
        thread.started.connect(fetch_instance.auto_web_metadata)
        fetch_instance.FINISHED.connect(done)
        thread.finished.connect(thread.deleteLater)
        thread.start()

        # def style_tooltip(self):
        # 	palette = QToolTip.palette()
        # 	palette.setColor()

    def init_stat_bar(self):
        self.status_bar = self.statusBar()
        self.status_bar.setMaximumHeight(20)
        self.status_bar.setSizeGripEnabled(False)
        self.stat_info = QLabel()
        self.stat_info.setIndent(5)
        self.sort_main = QAction("Asc", self)
        sort_menu = QMenu()
        self.sort_main.setMenu(sort_menu)
        s_by_title = QAction("Title", sort_menu)
        s_by_artist = QAction("Artist", sort_menu)
        sort_menu.addAction(s_by_title)
        sort_menu.addAction(s_by_artist)
        self.status_bar.addPermanentWidget(self.stat_info)
        # self.status_bar.addAction(self.sort_main)
        self.temp_msg = QLabel()
        self.temp_timer = QTimer()

        self.manga_list_view.gallery_model.ROWCOUNT_CHANGE.connect(self.stat_row_info)
        self.manga_list_view.gallery_model.STATUSBAR_MSG.connect(self.stat_temp_msg)
        self.manga_list_view.STATUS_BAR_MSG.connect(self.stat_temp_msg)
        self.manga_table_view.STATUS_BAR_MSG.connect(self.stat_temp_msg)
        self.stat_row_info()

    def stat_temp_msg(self, msg):
        self.temp_timer.stop()
        self.temp_msg.setText(msg)
        self.status_bar.addWidget(self.temp_msg)
        self.temp_timer.timeout.connect(self.temp_msg.clear)
        self.temp_timer.setSingleShot(True)
        self.temp_timer.start(5000)

    def stat_row_info(self):
        r = self.manga_list_view.model().rowCount()
        t = self.manga_list_view.gallery_model._data_count
        self.stat_info.setText("Loaded {} of {} ".format(r, t))

    def manga_display(self):
        "initiates the manga view"
        # list view
        self.manga_list_main = QWidget()
        # self.manga_list_main.setContentsMargins(-10, -12, -10, -10)
        self.manga_list_main.setContentsMargins(10, -9, -10, -10)  # x, y, inverted_width, inverted_height
        self.manga_list_layout = QHBoxLayout()
        self.manga_list_main.setLayout(self.manga_list_layout)

        self.manga_list_view = gallery.MangaView(self)
        self.manga_list_view.clicked.connect(self.popup)
        self.manga_list_view.manga_delegate.POPUP.connect(self.popup)
        self.popup_window = self.manga_list_view.manga_delegate.popup_window
        self.manga_list_layout.addWidget(self.manga_list_view)

        # table view
        self.manga_table_main = QWidget()
        self.manga_table_layout = QVBoxLayout()
        self.manga_table_main.setLayout(self.manga_table_layout)

        self.manga_table_view = gallery.MangaTableView(self)
        self.manga_table_view.gallery_model = self.manga_list_view.gallery_model
        self.manga_table_view.sort_model = self.manga_list_view.sort_model
        self.manga_table_view.setModel(self.manga_table_view.sort_model)
        self.manga_table_view.sort_model.change_model(self.manga_table_view.gallery_model)
        self.manga_table_view.setColumnWidth(gui_constants.FAV, 20)
        self.manga_table_view.setColumnWidth(gui_constants.ARTIST, 200)
        self.manga_table_view.setColumnWidth(gui_constants.TITLE, 400)
        self.manga_table_view.setColumnWidth(gui_constants.TAGS, 300)
        self.manga_table_view.setColumnWidth(gui_constants.TYPE, 60)
        self.manga_table_view.setColumnWidth(gui_constants.CHAPTERS, 60)
        self.manga_table_view.setColumnWidth(gui_constants.LANGUAGE, 100)
        self.manga_table_view.setColumnWidth(gui_constants.LINK, 400)
        self.manga_table_layout.addWidget(self.manga_table_view)

    def search(self, srch_string):
        case_ins = srch_string.lower()
        if not gui_constants.ALLOW_SEARCH_REGEX:
            remove = "^$*+?{}\\|()[]"
            for x in remove:
                if x == "[" or x == "]":
                    continue
                else:
                    case_ins = case_ins.replace(x, ".")
        else:
            try:
                re.compile(case_ins)
            except re.error:
                return
        self.manga_list_view.sort_model.search(case_ins)

    def popup(self, index):
        if not self.popup_window.isVisible():
            m_x = QCursor.pos().x()
            m_y = QCursor.pos().y()
            d_w = QDesktopWidget().width()
            d_h = QDesktopWidget().height()
            p_w = gui_constants.POPUP_WIDTH
            p_h = gui_constants.POPUP_HEIGHT

            index_rect = self.manga_list_view.visualRect(index)
            index_point = self.manga_list_view.mapToGlobal(index_rect.topRight())
            # adjust so it doesn't go offscreen
            if d_w - m_x < p_w and d_h - m_y < p_h:  # bottom
                self.popup_window.move(m_x - p_w + 5, m_y - p_h)
            elif d_w - m_x > p_w and d_h - m_y < p_h:
                self.popup_window.move(m_x + 5, m_y - p_h)
            elif d_w - m_x < p_w:
                self.popup_window.move(m_x - p_w + 5, m_y + 5)
            else:
                self.popup_window.move(index_point)

            self.popup_window.set_gallery(index.data(Qt.UserRole + 1))
            self.popup_window.show()

    def favourite_display(self):
        "Switches to favourite display"
        if self.display.currentIndex() == self.m_l_view_index:
            self.manga_list_view.sort_model.fav_view()
        else:
            self.manga_table_view.sort_model.fav_view()

    def catalog_display(self):
        "Switches to catalog display"
        if self.display.currentIndex() == self.m_l_view_index:
            self.manga_list_view.sort_model.catalog_view()
        else:
            self.manga_table_view.sort_model.catalog_view()

    def settings(self):
        sett = settingsdialog.SettingsDialog(self)
        sett.scroll_speed_changed.connect(self.manga_list_view.updateGeometries)
        # sett.show()

    def init_toolbar(self):
        self.toolbar = QToolBar()
        self.toolbar.setFixedHeight(25)
        self.toolbar.setWindowTitle("Show")  # text for the contextmenu
        # self.toolbar.setStyleSheet("QToolBar {border:0px}") # make it user defined?
        self.toolbar.setMovable(False)
        self.toolbar.setFloatable(False)
        # self.toolbar.setIconSize(QSize(20,20))
        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

        spacer_start = QWidget()  # aligns the first actions properly
        spacer_start.setFixedSize(QSize(10, 1))
        self.toolbar.addWidget(spacer_start)

        favourite_view_icon = QIcon(gui_constants.STAR_BTN_PATH)
        favourite_view_action = QAction(favourite_view_icon, "Favorites", self)
        favourite_view_action.setToolTip("Show only favourite galleries")
        favourite_view_action.triggered.connect(self.favourite_display)  # need lambda to pass extra args
        self.toolbar.addAction(favourite_view_action)

        catalog_view_icon = QIcon(gui_constants.HOME_BTN_PATH)
        catalog_view_action = QAction(catalog_view_icon, "Library", self)
        catalog_view_action.setToolTip("Show all your galleries")
        # catalog_view_action.setText("Catalog")
        catalog_view_action.triggered.connect(self.catalog_display)  # need lambda to pass extra args
        self.toolbar.addAction(catalog_view_action)
        self.toolbar.addSeparator()

        gallery_menu = QMenu()
        gallery_action = QToolButton()
        gallery_action.setText("Gallery ")
        gallery_action.setPopupMode(QToolButton.InstantPopup)
        gallery_action.setToolTip("Contains various gallery related features")
        gallery_action.setMenu(gallery_menu)
        add_gallery_icon = QIcon(gui_constants.PLUS_PATH)
        gallery_action_add = QAction(add_gallery_icon, "Add gallery", self)
        gallery_action_add.triggered.connect(self.manga_list_view.SERIES_DIALOG.emit)
        gallery_action_add.setToolTip("Add a single gallery thoroughly")
        gallery_menu.addAction(gallery_action_add)
        add_more_action = QAction(add_gallery_icon, "Add galleries...", self)
        add_more_action.setStatusTip("Add galleries from different folders")
        add_more_action.triggered.connect(lambda: self.populate(True))
        gallery_menu.addAction(add_more_action)
        populate_action = QAction(add_gallery_icon, "Populate from folder...", self)
        populate_action.setStatusTip("Populates the DB with galleries from a single folder")
        populate_action.triggered.connect(self.populate)
        gallery_menu.addAction(populate_action)
        gallery_menu.addSeparator()
        metadata_action = QAction("Get metadata for all galleries", self)
        metadata_action.triggered.connect(self.get_metadata)
        gallery_menu.addAction(metadata_action)
        self.toolbar.addWidget(gallery_action)
        self.toolbar.addSeparator()

        misc_action = QToolButton()
        misc_action.setText("Misc ")
        misc_action_menu = QMenu()
        misc_action.setMenu(misc_action_menu)
        misc_action.setPopupMode(QToolButton.InstantPopup)
        misc_action.setToolTip("Contains misc. features")
        misc_action_random = QAction("Open random gallery", misc_action_menu)
        misc_action_random.triggered.connect(self.manga_list_view.open_random_gallery)
        misc_action_menu.addAction(misc_action_random)
        duplicate_check_simple = QAction("Simple duplicate finder", misc_action_menu)
        duplicate_check_simple.triggered.connect(lambda: self.manga_list_view.duplicate_check())
        misc_action_menu.addAction(duplicate_check_simple)
        self.toolbar.addWidget(misc_action)

        spacer_middle = QWidget()  # aligns buttons to the right
        spacer_middle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.toolbar.addWidget(spacer_middle)

        self.grid_toggle_g_icon = QIcon(gui_constants.GRID_PATH)
        self.grid_toggle_l_icon = QIcon(gui_constants.LIST_PATH)
        self.grid_toggle = QToolButton()
        if self.display.currentIndex() == self.m_l_view_index:
            self.grid_toggle.setIcon(self.grid_toggle_l_icon)
        else:
            self.grid_toggle.setIcon(self.grid_toggle_g_icon)
        self.grid_toggle.setObjectName("gridtoggle")
        self.grid_toggle.clicked.connect(self.toggle_view)
        self.toolbar.addWidget(self.grid_toggle)

        self.search_bar = misc.LineEdit()
        if gui_constants.SEARCH_AUTOCOMPLETE:
            completer = QCompleter(self)
            completer.setModel(self.manga_list_view.gallery_model)
            completer.setCaseSensitivity(Qt.CaseInsensitive)
            completer.setCompletionMode(QCompleter.PopupCompletion)
            completer.setCompletionRole(Qt.DisplayRole)
            completer.setCompletionColumn(gui_constants.TITLE)
            completer.setFilterMode(Qt.MatchContains)
            self.search_bar.setCompleter(completer)
        if gui_constants.SEARCH_ON_ENTER:
            self.search_bar.returnPressed.connect(lambda: self.search(self.search_bar.text()))
        else:
            self.search_bar.textChanged[str].connect(self.search)
        self.search_bar.setPlaceholderText("Search title, artist, namespace & tags")
        self.search_bar.setMinimumWidth(150)
        self.search_bar.setMaximumWidth(500)
        self.toolbar.addWidget(self.search_bar)
        self.toolbar.addSeparator()
        settings_icon = QIcon(gui_constants.SETTINGS_PATH)
        settings_action = QAction("Set&tings", self)
        settings_action.triggered.connect(self.settings)
        self.toolbar.addAction(settings_action)

        spacer_end = QWidget()  # aligns About action properly
        spacer_end.setFixedSize(QSize(10, 1))
        self.toolbar.addWidget(spacer_end)
        self.addToolBar(self.toolbar)

    def toggle_view(self):
        """
		Toggles the current display view
		"""
        if self.display.currentIndex() == self.m_l_view_index:
            self.display.setCurrentIndex(self.m_t_view_index)
            self.grid_toggle.setIcon(self.grid_toggle_g_icon)
        else:
            self.display.setCurrentIndex(self.m_l_view_index)
            self.grid_toggle.setIcon(self.grid_toggle_l_icon)

            # TODO: Improve this so that it adds to the gallery dialog,
            # so user can edit data before inserting (make it a choice)

    def populate(self, mixed=None):
        "Populates the database with gallery from local drive'"
        if mixed:
            gallery_view = misc.GalleryListView(self, True)
            gallery_view.SERIES.connect(self.gallery_populate)
            gallery_view.show()
        else:
            path = QFileDialog.getExistingDirectory(None, "Choose a folder containing your galleries")
            self.gallery_populate(path, True)

    def gallery_populate(self, path, validate=False):
        "Scans the given path for gallery to add into the DB"
        if len(path) is not 0:
            data_thread = QThread(self)
            data_thread.setObjectName("General gallery populate")
            loading = misc.Loading(self)
            if not loading.ON:
                misc.Loading.ON = True
                fetch_instance = fetch.Fetch()
                fetch_instance.series_path = path
                loading.show()

                def finished(status):
                    def hide_loading():
                        loading.hide()

                    if status:
                        if len(status) != 0:

                            def add_gallery(gallery_list):
                                def append_to_model(x):
                                    self.manga_list_view.gallery_model.insertRows(x, None, len(x))

                                class A(QObject):
                                    done = pyqtSignal()
                                    prog = pyqtSignal(int)

                                    def __init__(self, obj, parent=None):
                                        super().__init__(parent)
                                        self.obj = obj
                                        self.galleries = []

                                    def add_to_db(self):
                                        gui_constants.NOTIF_BAR.begin_show()
                                        gui_constants.NOTIF_BAR.add_text("Populating database...")
                                        for y, x in enumerate(self.obj):
                                            gui_constants.NOTIF_BAR.add_text(
                                                "Populating database {}/{}".format(y + 1, len(self.obj))
                                            )
                                            gallerydb.add_method_queue(gallerydb.GalleryDB.add_gallery_return, False, x)
                                            self.galleries.append(x)
                                            y += 1
                                            self.prog.emit(y)
                                        append_to_model(self.galleries)
                                        gui_constants.NOTIF_BAR.end_show()
                                        self.done.emit()

                                loading.progress.setMaximum(len(gallery_list))
                                a_instance = A(gallery_list)
                                thread = QThread(self)
                                thread.setObjectName("Database populate")

                                def loading_show():
                                    loading.setText("Populating database.\nPlease wait...")
                                    loading.show()

                                def loading_hide():
                                    loading.close()
                                    self.manga_list_view.gallery_model.ROWCOUNT_CHANGE.emit()

                                def del_later():
                                    try:
                                        a_instance.deleteLater()
                                    except NameError:
                                        pass

                                a_instance.moveToThread(thread)
                                a_instance.prog.connect(loading.progress.setValue)
                                thread.started.connect(loading_show)
                                thread.started.connect(a_instance.add_to_db)
                                a_instance.done.connect(loading_hide)
                                a_instance.done.connect(del_later)
                                thread.finished.connect(thread.deleteLater)
                                thread.start()

                            data_thread.quit
                            hide_loading()
                            log_i("Populating DB from gallery folder: OK")
                            if validate:
                                gallery_list = misc.GalleryListView(self)
                                gallery_list.SERIES.connect(add_gallery)
                                for ser in status:
                                    gallery_list.add_gallery(ser, os.path.split(ser.path)[1])
                                    # self.manga_list_view.gallery_model.populate_data()
                                gallery_list.show()
                            else:
                                add_gallery(status)
                            misc.Loading.ON = False
                        else:
                            log_d("No new gallery was found")
                            loading.setText("No new gallery found")
                            data_thread.quit
                            misc.Loading.ON = False

                    else:
                        log_e("Populating DB from gallery folder: Nothing was added!")
                        loading.setText("<font color=red>Nothing was added. Check happypanda_log for details..</font>")
                        loading.progress.setStyleSheet("background-color:red;")
                        data_thread.quit
                        QTimer.singleShot(10000, loading.close)

                def fetch_deleteLater():
                    try:
                        fetch_instance.deleteLater
                    except NameError:
                        pass

                def a_progress(prog):
                    loading.progress.setValue(prog)
                    loading.setText("Searching for galleries...")

                fetch_instance.moveToThread(data_thread)
                fetch_instance.DATA_COUNT.connect(loading.progress.setMaximum)
                fetch_instance.PROGRESS.connect(a_progress)
                data_thread.started.connect(fetch_instance.local)
                fetch_instance.FINISHED.connect(finished)
                fetch_instance.FINISHED.connect(fetch_deleteLater)
                data_thread.finished.connect(data_thread.deleteLater)
                data_thread.start()
                log_i("Populating DB from gallery folder")

    def resizeEvent(self, event):
        try:
            self.notification_bar.resize(event.size().width())
        except AttributeError:
            pass
        return super().resizeEvent(event)

    def closeEvent(self, event):
        # watchers
        try:
            self.watchers.stop_all()
        except AttributeError:
            pass

            # settings
        settings.set(self.manga_list_view.current_sort, "General", "current sort")
        settings.win_save(self, "AppWindow")

        # temp dir
        try:
            for root, dirs, files in os.walk("temp", topdown=False):
                for name in files:
                    os.remove(os.path.join(root, name))
                for name in dirs:
                    os.rmdir(os.path.join(root, name))
            log_d("Empty temp on exit: OK")
        except:
            log_d("Empty temp on exit: FAIL")

            # error
        err = sys.exc_info()
        if all(err):
            log_c("Last error before exit:\n{}\n{}\n{}".format(err[0], err[1], err[2]))
        else:
            log_d("Normal Exit App: OK")
        super().closeEvent(event)
        app = QApplication.instance()
        app.quit()
        sys.exit()
Пример #34
0
class MainWindow_Ui(QMainWindow):
    def __init__(self):
        super().__init__()
        #MainWindow
        self.resize(600, 400)
        self.setMinimumSize(QSize(600, 400))
        self.setMaximumSize(QSize(16777215, 16777215))
        self.setWindowTitle("Persepolis Download Manager")
        self.setWindowIcon(QIcon.fromTheme('persepolis', QIcon(':/icon.svg')))

        self.centralwidget = QWidget(self)
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        #enable drag and drop
        self.setAcceptDrops(True)
        #frame
        self.frame = QFrame(self.centralwidget)
        self.frame.setGeometry(QRect(10, 10, 581, 251))
        self.frame.setFrameShape(QFrame.StyledPanel)
        self.frame.setFrameShadow(QFrame.Raised)
        self.gridLayout = QGridLayout(self.frame)

        #tablewidget
        self.download_table = QTableWidget(self.frame)
        self.download_table.setGeometry(QRect(10, 10, 560, 231))
        self.download_table.setSizeIncrement(QSize(0, 0))
        self.download_table.setColumnCount(10)
        self.download_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.download_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.download_table.verticalHeader().hide()
        #hide gid and download dictioanry section
        self.download_table.setColumnHidden(8, True)
        self.download_table.setColumnHidden(9, True)

        self.gridLayout.addWidget(self.download_table, 0, 0, 1, 1)
        self.verticalLayout.addWidget(self.frame)

        self.setCentralWidget(self.centralwidget)

        download_table_header = [
            'File Name', 'Status', 'Size', 'Downloaded', 'Percentage',
            'Connections', 'Transfer rate', 'Estimate time left', 'Gid', 'Info'
        ]
        self.download_table.setHorizontalHeaderLabels(download_table_header)
        #fixing the size of download_table when window is Maximized!
        self.download_table.horizontalHeader().setSectionResizeMode(0)
        self.download_table.horizontalHeader().setStretchLastSection(True)
        #finding number od row that user selected!
        self.download_table.itemSelectionChanged.connect(self.selectedRow)

        #menubar
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QRect(0, 0, 600, 24))
        self.setMenuBar(self.menubar)
        fileMenu = self.menubar.addMenu('File')
        editMenu = self.menubar.addMenu('Edit')
        viewMenu = self.menubar.addMenu('View')
        downloadMenu = self.menubar.addMenu('Download')
        helpMenu = self.menubar.addMenu('Help')

        #statusbar
        self.statusbar = QStatusBar(self)
        self.setStatusBar(self.statusbar)
        self.statusbar.showMessage("Persepolis Download Manager")
        #toolBar
        self.toolBar = QToolBar(self)
        self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.toolBar.setWindowTitle("toolBar")
        self.toolBar.setIconSize(QSize(38, 38))
        self.toolBar.setFloatable(False)
        self.toolBar.setMovable(False)

        #toolBar and menubar and actions
        self.stopAllAction = QAction(QIcon(icons + 'stop_all'),
                                     'Stop all active downloads',
                                     self,
                                     statusTip='Stop all active downloads',
                                     triggered=self.stopAllDownloads)
        downloadMenu.addAction(self.stopAllAction)

        self.pauseAllAction = QAction(QIcon(icons + 'pause_all'),
                                      'Pause all active downloads',
                                      self,
                                      statusTip='Pause all active downloads',
                                      triggered=self.pauseAllDownloads)
        downloadMenu.addAction(self.pauseAllAction)

        self.trayAction = QAction('Show system tray icon',
                                  self,
                                  statusTip="Show/Hide system tray icon",
                                  triggered=self.showTray)
        self.trayAction.setCheckable(True)
        self.trayAction.setChecked(True)
        viewMenu.addAction(self.trayAction)

        self.minimizeAction = QAction(QIcon(icons + 'minimize'),
                                      'Minimize to system tray',
                                      self,
                                      shortcut="Ctrl+W",
                                      statusTip="Minimize to system tray",
                                      triggered=self.minMaxTray)
        viewMenu.addAction(self.minimizeAction)

        self.addlinkAction = QAction(QIcon(icons + 'add'),
                                     'Add New Download Link',
                                     self,
                                     shortcut="Ctrl+N",
                                     statusTip="Add New Download Link",
                                     triggered=self.addLinkButtonPressed)
        fileMenu.addAction(self.addlinkAction)

        self.resumeAction = QAction(QIcon(icons + 'play'),
                                    'Resume Download',
                                    self,
                                    shortcut="Ctrl+R",
                                    statusTip="Resume Download",
                                    triggered=self.resumeButtonPressed)
        downloadMenu.addAction(self.resumeAction)

        self.pauseAction = QAction(QIcon(icons + 'pause'),
                                   'Pause Download',
                                   self,
                                   shortcut="Ctrl+C",
                                   statusTip="Pause Download",
                                   triggered=self.pauseButtonPressed)
        downloadMenu.addAction(self.pauseAction)

        self.stopAction = QAction(QIcon(icons + 'stop'),
                                  'Stop Download',
                                  self,
                                  shortcut="Ctrl+S",
                                  statusTip="Stop/Cancel Download",
                                  triggered=self.stopButtonPressed)
        downloadMenu.addAction(self.stopAction)

        self.removeAction = QAction(QIcon(icons + 'remove'),
                                    'Remove Download',
                                    self,
                                    shortcut="Ctrl+D",
                                    statusTip="Remove Download",
                                    triggered=self.removeButtonPressed)
        downloadMenu.addAction(self.removeAction)

        self.propertiesAction = QAction(QIcon(icons + 'setting'),
                                        'Properties',
                                        self,
                                        shortcut="Ctrl+P",
                                        statusTip="Properties",
                                        triggered=self.propertiesButtonPressed)
        downloadMenu.addAction(self.propertiesAction)

        self.progressAction = QAction(QIcon(icons + 'window'),
                                      'Progress',
                                      self,
                                      shortcut="Ctrl+Z",
                                      statusTip="Progress",
                                      triggered=self.progressButtonPressed)
        downloadMenu.addAction(self.progressAction)

        self.openFileAction = QAction(QIcon(icons + 'file'),
                                      'Open file',
                                      self,
                                      statusTip='Open file',
                                      triggered=self.openFile)
        fileMenu.addAction(self.openFileAction)

        self.openDownloadFolderAction = QAction(
            QIcon(icons + 'folder'),
            'Open download folder',
            self,
            statusTip='Open download folder',
            triggered=self.openDownloadFolder)
        fileMenu.addAction(self.openDownloadFolderAction)

        self.deleteFileAction = QAction(QIcon(icons + 'trash'),
                                        'delete file',
                                        self,
                                        statusTip='delete file',
                                        triggered=self.deleteFile)
        fileMenu.addAction(self.deleteFileAction)

        self.openDefaultDownloadFolderAction = QAction(
            QIcon(icons + 'folder'),
            'Open default download folder',
            self,
            statusTip='Open default download folder',
            triggered=self.openDefaultDownloadFolder)
        fileMenu.addAction(self.openDefaultDownloadFolderAction)

        self.exitAction = QAction(QIcon(icons + 'exit'),
                                  'Exit',
                                  self,
                                  shortcut="Ctrl+Q",
                                  statusTip="Exit",
                                  triggered=self.closeEvent)
        fileMenu.addAction(self.exitAction)

        self.selectAction = QAction('Enable selectection mode',
                                    self,
                                    statusTip='Select Downloads',
                                    triggered=self.selectDownloads)
        self.selectAction.setCheckable(True)
        editMenu.addAction(self.selectAction)

        self.selectAllAction = QAction(QIcon(icons + 'select_all'),
                                       'Select All',
                                       self,
                                       statusTip='Select All',
                                       triggered=self.selectAll)
        editMenu.addAction(self.selectAllAction)
        self.selectAllAction.setEnabled(False)

        self.removeSelectedAction = QAction(
            QIcon(icons + 'multi_remove'),
            'Remove selected downloads form list',
            self,
            statusTip='Remove selected downloads form list',
            triggered=self.removeSelected)
        editMenu.addAction(self.removeSelectedAction)
        self.removeSelectedAction.setEnabled(False)

        self.deleteSelectedAction = QAction(
            QIcon(icons + 'multi_trash'),
            'Delete selected download files',
            self,
            statusTip='Delete selected download files',
            triggered=self.deleteSelected)
        editMenu.addAction(self.deleteSelectedAction)
        self.deleteSelectedAction.setEnabled(False)

        self.preferencesAction = QAction(QIcon(icons + 'preferences'),
                                         'Preferences',
                                         self,
                                         statusTip='Preferences',
                                         triggered=self.openPreferences)
        editMenu.addAction(self.preferencesAction)

        self.aboutAction = QAction(QIcon(icons + 'about'),
                                   'About',
                                   self,
                                   statusTip='About',
                                   triggered=self.openAbout)
        helpMenu.addAction(self.aboutAction)

        for i in self.addlinkAction, self.resumeAction, self.pauseAction, self.stopAction, self.removeAction, self.deleteFileAction, self.propertiesAction, self.progressAction, self.exitAction:
            self.toolBar.addAction(i)

        self.toolBar.insertSeparator(self.addlinkAction)
        self.toolBar.insertSeparator(self.resumeAction)
        self.toolBar.insertSeparator(self.removeAction)
        self.toolBar.insertSeparator(self.exitAction)
        self.toolBar.addSeparator()
Пример #35
0
class MainWindow_Ui(QMainWindow):
    def __init__(self, persepolis_setting):
        super().__init__()
        # MainWindow
        self.persepolis_setting = persepolis_setting

        # add support for other languages
        locale = str(self.persepolis_setting.value('settings/locale'))
        QLocale.setDefault(QLocale(locale))
        self.translator = QTranslator()
        if self.translator.load(':/translations/locales/ui_' + locale, 'ts'):
            QCoreApplication.installTranslator(self.translator)


        # set ui direction
        ui_direction = self.persepolis_setting.value('ui_direction')

        if ui_direction == 'rtl':
            self.setLayoutDirection(Qt.RightToLeft)
        
        elif ui_direction in 'ltr':
            self.setLayoutDirection(Qt.LeftToRight)



        icons = ':/' + \
            str(self.persepolis_setting.value('settings/icons')) + '/'

        self.setWindowTitle(QCoreApplication.translate("mainwindow_ui_tr", "Persepolis Download Manager"))
        self.setWindowIcon(QIcon.fromTheme('persepolis', QIcon(':/persepolis.svg')))

        self.centralwidget = QWidget(self)
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        # enable drag and drop
        self.setAcceptDrops(True)
# frame
        self.frame = QFrame(self.centralwidget)

# download_table_horizontalLayout
        download_table_horizontalLayout = QHBoxLayout()
        tabels_splitter = QSplitter(Qt.Horizontal)
# category_tree
        self.category_tree_qwidget = QWidget(self)
        category_tree_verticalLayout = QVBoxLayout()
        self.category_tree = CategoryTreeView(self)
        category_tree_verticalLayout.addWidget(self.category_tree)

        self.category_tree_model = QStandardItemModel()
        self.category_tree.setModel(self.category_tree_model)
        category_table_header = [QCoreApplication.translate("mainwindow_ui_tr", 'Category')]

        self.category_tree_model.setHorizontalHeaderLabels(
            category_table_header)
        self.category_tree.header().setStretchLastSection(True)

        self.category_tree.header().setDefaultAlignment(Qt.AlignCenter)
        
# queue_panel
        self.queue_panel_widget = QWidget(self)

        queue_panel_verticalLayout_main = QVBoxLayout(self.queue_panel_widget)
# queue_panel_show_button
        self.queue_panel_show_button = QPushButton(self)

        queue_panel_verticalLayout_main.addWidget(self.queue_panel_show_button)
# queue_panel_widget_frame
        self.queue_panel_widget_frame = QFrame(self)
        self.queue_panel_widget_frame.setFrameShape(QFrame.StyledPanel)
        self.queue_panel_widget_frame.setFrameShadow(QFrame.Raised)

        queue_panel_verticalLayout_main.addWidget(
            self.queue_panel_widget_frame)

        queue_panel_verticalLayout = QVBoxLayout(self.queue_panel_widget_frame)
        queue_panel_verticalLayout_main.setContentsMargins(50, -1, 50, -1)

# start_end_frame
        self.start_end_frame = QFrame(self)

# start time
        start_verticalLayout = QVBoxLayout(self.start_end_frame)
        self.start_checkBox = QCheckBox(self)
        start_verticalLayout.addWidget(self.start_checkBox)

        self.start_frame = QFrame(self)
        self.start_frame.setFrameShape(QFrame.StyledPanel)
        self.start_frame.setFrameShadow(QFrame.Raised)

        start_frame_verticalLayout = QVBoxLayout(self.start_frame)

        self.start_time_qDataTimeEdit = QDateTimeEdit(self.start_frame)
        self.start_time_qDataTimeEdit.setDisplayFormat('H:mm')
        start_frame_verticalLayout.addWidget(self.start_time_qDataTimeEdit)
  
        start_verticalLayout.addWidget(self.start_frame)
# end time

        self.end_checkBox = QCheckBox(self)
        start_verticalLayout.addWidget(self.end_checkBox)

        self.end_frame = QFrame(self)
        self.end_frame.setFrameShape(QFrame.StyledPanel)
        self.end_frame.setFrameShadow(QFrame.Raised)

        end_frame_verticalLayout = QVBoxLayout(self.end_frame)

        self.end_time_qDateTimeEdit = QDateTimeEdit(self.end_frame)
        self.end_time_qDateTimeEdit.setDisplayFormat('H:mm')
        end_frame_verticalLayout.addWidget(self.end_time_qDateTimeEdit)
 
        start_verticalLayout.addWidget(self.end_frame)

        self.reverse_checkBox = QCheckBox(self)
        start_verticalLayout.addWidget(self.reverse_checkBox)

        queue_panel_verticalLayout.addWidget(self.start_end_frame)

# limit_after_frame
        self.limit_after_frame = QFrame(self)
# limit_checkBox
        limit_verticalLayout = QVBoxLayout(self.limit_after_frame)
        self.limit_checkBox = QCheckBox(self)
        limit_verticalLayout.addWidget(self.limit_checkBox)
# limit_frame
        self.limit_frame = QFrame(self)
        self.limit_frame.setFrameShape(QFrame.StyledPanel)
        self.limit_frame.setFrameShadow(QFrame.Raised)
        limit_verticalLayout.addWidget(self.limit_frame)

        limit_frame_verticalLayout = QVBoxLayout(self.limit_frame)
# limit_spinBox
        limit_frame_horizontalLayout = QHBoxLayout()
        self.limit_spinBox = QDoubleSpinBox(self)
        self.limit_spinBox.setMinimum(1)
        self.limit_spinBox.setMaximum(1023)
        limit_frame_horizontalLayout.addWidget(self.limit_spinBox)
# limit_comboBox
        self.limit_comboBox = QComboBox(self)
        self.limit_comboBox.addItem("")
        self.limit_comboBox.addItem("")
        limit_frame_horizontalLayout.addWidget(self.limit_comboBox)
        limit_frame_verticalLayout.addLayout(limit_frame_horizontalLayout)
# limit_pushButton
        self.limit_pushButton = QPushButton(self)
        limit_frame_verticalLayout.addWidget(self.limit_pushButton)

# after_checkBox
        self.after_checkBox = QtWidgets.QCheckBox(self)
        limit_verticalLayout.addWidget(self.after_checkBox)
# after_frame
        self.after_frame = QtWidgets.QFrame(self)
        self.after_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.after_frame.setFrameShadow(QtWidgets.QFrame.Raised)
        limit_verticalLayout.addWidget(self.after_frame)

        after_frame_verticalLayout = QVBoxLayout(self.after_frame)
# after_comboBox
        self.after_comboBox = QComboBox(self)
        self.after_comboBox.addItem("")

        after_frame_verticalLayout.addWidget(self.after_comboBox)
# after_pushButton
        self.after_pushButton = QPushButton(self)
        after_frame_verticalLayout.addWidget(self.after_pushButton)

        queue_panel_verticalLayout.addWidget(self.limit_after_frame)
        category_tree_verticalLayout.addWidget(self.queue_panel_widget)

# keep_awake_checkBox
        self.keep_awake_checkBox = QCheckBox(self)
        queue_panel_verticalLayout.addWidget(self.keep_awake_checkBox)

        self.category_tree_qwidget.setLayout(category_tree_verticalLayout)
        tabels_splitter.addWidget(self.category_tree_qwidget)

# download table widget
        self.download_table_content_widget = QWidget(self)
        download_table_content_widget_verticalLayout = QVBoxLayout(
            self.download_table_content_widget)

        self.download_table = DownloadTableWidget(self)
        download_table_content_widget_verticalLayout.addWidget(
            self.download_table)
        tabels_splitter.addWidget(self.download_table_content_widget)

        self.download_table.setColumnCount(13)
        self.download_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.download_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.download_table.verticalHeader().hide()

# hide gid and download dictioanry section
        self.download_table.setColumnHidden(8, True)
        self.download_table.setColumnHidden(9, True)

        download_table_header = [QCoreApplication.translate("mainwindow_ui_tr", 'File Name'), QCoreApplication.translate("mainwindow_ui_tr",'Status'), QCoreApplication.translate("mainwindow_ui_tr", 'Size'), QCoreApplication.translate("mainwindow_ui_tr", 'Downloaded'), QCoreApplication.translate("mainwindow_ui_tr", 'Percentage'), QCoreApplication.translate("mainwindow_ui_tr", 'Connections'),
                                 QCoreApplication.translate("mainwindow_ui_tr", 'Transfer rate'), QCoreApplication.translate("mainwindow_ui_tr",'Estimated time left'), 'Gid', QCoreApplication.translate("mainwindow_ui_tr",'Link'), QCoreApplication.translate("mainwindow_ui_tr", 'First try date'), QCoreApplication.translate("mainwindow_ui_tr", 'Last try date'), QCoreApplication.translate("mainwindow_ui_tr",'Category')]

        self.download_table.setHorizontalHeaderLabels(download_table_header)

# fixing the size of download_table when window is Maximized!
        self.download_table.horizontalHeader().setSectionResizeMode(0)
        self.download_table.horizontalHeader().setStretchLastSection(True)

        tabels_splitter.setStretchFactor(0, 3) # category_tree width
        tabels_splitter.setStretchFactor(1, 10)  # ratio of tables's width
        download_table_horizontalLayout.addWidget(tabels_splitter)
        self.frame.setLayout(download_table_horizontalLayout)
        self.verticalLayout.addWidget(self.frame)
        self.setCentralWidget(self.centralwidget)

# menubar
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QRect(0, 0, 600, 24))
        self.setMenuBar(self.menubar)
        fileMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&File'))
        editMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&Edit'))
        viewMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&View'))
        downloadMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&Download'))
        queueMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&Queue'))
        videoFinderMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", 'V&ideo Finder'))
        helpMenu = self.menubar.addMenu(QCoreApplication.translate("mainwindow_ui_tr", '&Help'))


# viewMenu submenus
        sortMenu = viewMenu.addMenu(QCoreApplication.translate("mainwindow_ui_tr", 'Sort by'))
# statusbar
        self.statusbar = QStatusBar(self)
        self.setStatusBar(self.statusbar)
        self.statusbar.showMessage(QCoreApplication.translate("mainwindow_ui_tr", "Persepolis Download Manager"))
# toolBar
        self.toolBar2 = QToolBar(self)
        self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar2)
        self.toolBar2.setWindowTitle(QCoreApplication.translate("mainwindow_ui_tr", 'Menu'))
        self.toolBar2.setFloatable(False)
        self.toolBar2.setMovable(False)

        self.toolBar = QToolBar(self)
        self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.toolBar.setWindowTitle(QCoreApplication.translate("mainwindow_ui_tr", 'Toolbar'))
        self.toolBar.setFloatable(False)
        self.toolBar.setMovable(False)


#toolBar and menubar and actions
        self.videoFinderAddLinkAction = QAction(QIcon(icons + 'video_finder'), QCoreApplication.translate("mainwindow_ui_tr", 'Find Video Links'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Download video or audio from Youtube, Vimeo, etc...'),
                                            triggered=self.showVideoFinderAddLinkWindow)

        QShortcut(QKeySequence('Ctrl+I'), self, self.showVideoFinderAddLinkWindow)

        videoFinderMenu.addAction(self.videoFinderAddLinkAction)

        self.stopAllAction = QAction(QIcon(icons + 'stop_all'), QCoreApplication.translate("mainwindow_ui_tr", 'Stop all active downloads'),
                                     self, statusTip='Stop all active downloads', triggered=self.stopAllDownloads)
        downloadMenu.addAction(self.stopAllAction)

        self.sort_file_name_Action = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'File name'), self, triggered=self.sortByName)
        sortMenu.addAction(self.sort_file_name_Action)

        self.sort_file_size_Action = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'File size'), self, triggered=self.sortBySize)
        sortMenu.addAction(self.sort_file_size_Action)

        self.sort_first_try_date_Action = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'First try date'), self, triggered=self.sortByFirstTry)
        sortMenu.addAction(self.sort_first_try_date_Action)

        self.sort_last_try_date_Action = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'Last try date'), self, triggered=self.sortByLastTry)
        sortMenu.addAction(self.sort_last_try_date_Action)

        self.sort_download_status_Action = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'Download status'), self, triggered=self.sortByStatus)
        sortMenu.addAction(self.sort_download_status_Action)

        self.trayAction = QAction(QCoreApplication.translate("mainwindow_ui_tr", 'Show system tray icon'), self,
                                  statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Show/Hide system tray icon"), triggered=self.showTray)
        self.trayAction.setCheckable(True)
        viewMenu.addAction(self.trayAction)

        self.showMenuBarAction = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'Show menubar'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Show menubar'), triggered=self.showMenuBar)
        self.showMenuBarAction.setCheckable(True)
        viewMenu.addAction(self.showMenuBarAction)

        self.showSidePanelAction = QAction(
            QCoreApplication.translate("mainwindow_ui_tr", 'Show side panel'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Show side panel'), triggered=self.showSidePanel)
        self.showSidePanelAction.setCheckable(True)
        viewMenu.addAction(self.showSidePanelAction)

        self.minimizeAction = QAction(QIcon(icons + 'minimize'), QCoreApplication.translate("mainwindow_ui_tr", 'Minimize to system tray'), self,
                                      statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Minimize to system tray"), triggered=self.minMaxTray)
        QShortcut(QKeySequence('Ctrl+W'), self, self.minMaxTray)

        viewMenu.addAction(self.minimizeAction)

        self.addlinkAction = QAction(QIcon(icons + 'add'), QCoreApplication.translate("mainwindow_ui_tr", 'Add New Download Link'), self,
                                     statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Add New Download Link"), triggered=self.addLinkButtonPressed)
        QShortcut(QKeySequence('Ctrl+N'), self, self.addLinkButtonPressed)
        fileMenu.addAction(self.addlinkAction)

        self.addtextfileAction = QAction(QIcon(icons + 'file'), QCoreApplication.translate("mainwindow_ui_tr", 'Import links from text file'), self,
                                         statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Create a Text file and put links in it.line by line!'), triggered=self.importText)
        fileMenu.addAction(self.addtextfileAction)

        self.resumeAction = QAction(QIcon(icons + 'play'), QCoreApplication.translate("mainwindow_ui_tr", 'Resume Download'), self,
                                    statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Resume Download"), triggered=self.resumeButtonPressed)
        QShortcut(QKeySequence('Ctrl+R'), self, self.resumeButtonPressed)
        downloadMenu.addAction(self.resumeAction)

        self.pauseAction = QAction(QIcon(icons + 'pause'), QCoreApplication.translate("mainwindow_ui_tr", 'Pause Download'), self,
                                   statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Pause Download"), triggered=self.pauseButtonPressed)
        QShortcut(QKeySequence('Ctrl+C'), self, self.pauseButtonPressed)
        downloadMenu.addAction(self.pauseAction)

        self.stopAction = QAction(QIcon(icons + 'stop'), QCoreApplication.translate("mainwindow_ui_tr", 'Stop Download'), self,
                                  statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Stop/Cancel Download"), triggered=self.stopButtonPressed)
        QShortcut(QKeySequence('Ctrl+S'), self, self.stopButtonPressed)
        downloadMenu.addAction(self.stopAction)

        self.propertiesAction = QAction(QIcon(icons + 'setting'), QCoreApplication.translate("mainwindow_ui_tr", 'Properties'), self,
                                        statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Properties"), triggered=self.propertiesButtonPressed)
        QShortcut(QKeySequence('Ctrl+P'), self, self.propertiesButtonPressed)
        downloadMenu.addAction(self.propertiesAction)

        self.progressAction = QAction(QIcon(icons + 'window'), QCoreApplication.translate("mainwindow_ui_tr", 'Progress'), self,
                                      statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Progress"), triggered=self.progressButtonPressed)
        QShortcut(QKeySequence('Ctrl+Z'), self, self.progressButtonPressed)
        downloadMenu.addAction(self.progressAction)

        self.openFileAction = QAction(QIcon(
            icons + 'file'), QCoreApplication.translate("mainwindow_ui_tr", 'Open file'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Open file'), triggered=self.openFile)
        fileMenu.addAction(self.openFileAction)

        self.openDownloadFolderAction = QAction(QIcon(
            icons + 'folder'), QCoreApplication.translate("mainwindow_ui_tr", 'Open download folder'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Open download folder'), triggered=self.openDownloadFolder)
        fileMenu.addAction(self.openDownloadFolderAction)

        self.openDefaultDownloadFolderAction = QAction(QIcon(
            icons + 'folder'), QCoreApplication.translate("mainwindow_ui_tr", 'Open default download folder'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Open default download folder'), triggered=self.openDefaultDownloadFolder)
        fileMenu.addAction(self.openDefaultDownloadFolderAction)

        self.exitAction = QAction(QIcon(icons + 'exit'), QCoreApplication.translate("mainwindow_ui_tr", 'Exit'), self,
                                  statusTip=QCoreApplication.translate("mainwindow_ui_tr", "Exit"), triggered=self.closeEvent)
        QShortcut(QKeySequence('Ctrl+Q'), self, self.closeEvent)
        fileMenu.addAction(self.exitAction)

        self.clearAction = QAction(QIcon(icons + 'multi_remove'), QCoreApplication.translate("mainwindow_ui_tr", 'Clear download list'),
                                         self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Clear all items in download list'), triggered=self.clearDownloadList)
        editMenu.addAction(self.clearAction)

        self.removeSelectedAction = QAction(QIcon(icons + 'remove'), QCoreApplication.translate("mainwindow_ui_tr", 'Remove selected downloads from list'),
                                            self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Remove selected downloads form list'), triggered=self.removeSelected)
        editMenu.addAction(self.removeSelectedAction)
        self.removeSelectedAction.setEnabled(False)

        self.deleteSelectedAction = QAction(QIcon(icons + 'trash'), QCoreApplication.translate("mainwindow_ui_tr", 'Delete selected download files'),
                                            self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Delete selected download files'), triggered=self.deleteSelected)
        editMenu.addAction(self.deleteSelectedAction)
        self.deleteSelectedAction.setEnabled(False)

        self.createQueueAction = QAction(QIcon(icons + 'add_queue'), QCoreApplication.translate("mainwindow_ui_tr", 'Create new queue'),
                                         self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Create new download queue'), triggered=self.createQueue)
        queueMenu.addAction(self.createQueueAction)

        self.removeQueueAction = QAction(QIcon(icons + 'remove_queue'), QCoreApplication.translate("mainwindow_ui_tr", 'Remove this queue'),
                                         self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Remove this queue'), triggered=self.removeQueue)
        queueMenu.addAction(self.removeQueueAction)

        self.startQueueAction = QAction(QIcon(
            icons + 'start_queue'), QCoreApplication.translate("mainwindow_ui_tr", 'Start this queue'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Start this queue'), triggered=self.startQueue)
        queueMenu.addAction(self.startQueueAction)

        self.stopQueueAction = QAction(QIcon(
            icons + 'stop_queue'), QCoreApplication.translate("mainwindow_ui_tr", 'Stop this queue'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Stop this queue'), triggered=self.stopQueue)
        queueMenu.addAction(self.stopQueueAction)

        self.moveUpSelectedAction = QAction(QIcon(icons + 'multi_up'), QCoreApplication.translate("mainwindow_ui_tr", 'Move up selected items'), self,
                                            statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Move currently selected items up by one row'), triggered=self.moveUpSelected)
        queueMenu.addAction(self.moveUpSelectedAction)

        self.moveDownSelectedAction = QAction(QIcon(icons + 'multi_down'), QCoreApplication.translate("mainwindow_ui_tr", 'Move down selected items'),
                                              self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Move currently selected items down by one row'), triggered=self.moveDownSelected)
        queueMenu.addAction(self.moveDownSelectedAction)

        self.preferencesAction = QAction(QIcon(icons + 'preferences'), QCoreApplication.translate("mainwindow_ui_tr", 'Preferences'),
                                         self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Preferences'), triggered=self.openPreferences, menuRole=5)
        editMenu.addAction(self.preferencesAction)

        self.aboutAction = QAction(QIcon(
            icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'About'), self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'About'), triggered=self.openAbout, menuRole=4)
        helpMenu.addAction(self.aboutAction)

        self.issueAction = QAction(QIcon(icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'Report an issue'),
                                   self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Report an issue'), triggered=self.reportIssue)
        helpMenu.addAction(self.issueAction)

        self.updateAction = QAction(QIcon(icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'Check for newer version'),
                                    self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Check for newer release'), triggered=self.newUpdate)
        helpMenu.addAction(self.updateAction)

        self.logAction = QAction(QIcon(icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'Show log file'),
                                   self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Help'), triggered=self.showLog)
        helpMenu.addAction(self.logAction)

        self.helpAction = QAction(QIcon(icons + 'about'), QCoreApplication.translate("mainwindow_ui_tr", 'Help'),
                                   self, statusTip=QCoreApplication.translate("mainwindow_ui_tr", 'Help'), triggered=self.persepolisHelp)
        helpMenu.addAction(self.helpAction)

        self.qmenu = MenuWidget(self)

        self.toolBar2.addWidget(self.qmenu)

# labels
        self.queue_panel_show_button.setText(QCoreApplication.translate("mainwindow_ui_tr", "Hide options"))
        self.start_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "Start Time"))

        self.end_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "End Time"))

        self.reverse_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "Download bottom of\n the list first"))

        self.limit_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "Limit Speed"))
        self.limit_comboBox.setItemText(0, "KiB/s")
        self.limit_comboBox.setItemText(1, "MiB/s")
        self.limit_pushButton.setText(QCoreApplication.translate("mainwindow_ui_tr", "Apply"))

        self.after_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "After download"))
        self.after_comboBox.setItemText(0, QCoreApplication.translate("mainwindow_ui_tr", "Shut Down"))

        self.keep_awake_checkBox.setText(QCoreApplication.translate("mainwindow_ui_tr", "Keep system awake!"))
        self.keep_awake_checkBox.setToolTip(
            QCoreApplication.translate("mainwindow_ui_tr", "<html><head/><body><p>This option is preventing system from going to sleep.\
            This is necessary if your power manager is suspending system automatically. </p></body></html>"))
 
        self.after_pushButton.setText(QCoreApplication.translate("mainwindow_ui_tr", "Apply"))

    def changeIcon(self, icons):
        icons = ':/' + str(icons) + '/'

        action_icon_dict = {self.stopAllAction: 'stop_all', self.minimizeAction: 'minimize', self.addlinkAction: 'add', self.addtextfileAction: 'file', self.resumeAction: 'play', self.pauseAction: 'pause', self.stopAction: 'stop', self.propertiesAction: 'setting', self.progressAction: 'window', self.openFileAction: 'file', self.openDownloadFolderAction: 'folder', self.openDefaultDownloadFolderAction: 'folder', self.exitAction: 'exit',
                self.removeSelectedAction: 'multi_remove', self.deleteSelectedAction: 'multi_trash', self.createQueueAction: 'add_queue', self.removeQueueAction: 'remove_queue', self.startQueueAction: 'start_queue', self.stopQueueAction: 'stop_queue', self.preferencesAction: 'preferences', self.aboutAction: 'about', self.issueAction: 'about', self.updateAction: 'about', self.videoFinderAddLinkAction: 'video_finder', self.qmenu: 'menu'}
        for key in action_icon_dict.keys():
            key.setIcon(QIcon(icons + str(action_icon_dict[key])))
Пример #36
0
    def __init__(self, stampManager, parent=None):
        super().__init__(parent)

        self.mTileStampManager = stampManager
        self.mTileStampModel = stampManager.tileStampModel()
        self.mProxyModel = QSortFilterProxyModel(self.mTileStampModel)
        self.mFilterEdit = QLineEdit(self)
        self.mNewStamp = QAction(self)
        self.mAddVariation = QAction(self)
        self.mDuplicate = QAction(self)
        self.mDelete = QAction(self)
        self.mChooseFolder = QAction(self)

        self.setObjectName("TileStampsDock")
        self.mProxyModel.setSortLocaleAware(True)
        self.mProxyModel.setSortCaseSensitivity(Qt.CaseInsensitive)
        self.mProxyModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.mProxyModel.setSourceModel(self.mTileStampModel)
        self.mProxyModel.sort(0)
        self.mTileStampView = TileStampView(self)
        self.mTileStampView.setModel(self.mProxyModel)
        self.mTileStampView.setVerticalScrollMode(
            QAbstractItemView.ScrollPerPixel)
        self.mTileStampView.header().setStretchLastSection(False)
        self.mTileStampView.header().setSectionResizeMode(
            0, QHeaderView.Stretch)
        self.mTileStampView.header().setSectionResizeMode(
            1, QHeaderView.ResizeToContents)
        self.mTileStampView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.mTileStampView.customContextMenuRequested.connect(
            self.showContextMenu)
        self.mNewStamp.setIcon(QIcon(":images/16x16/document-new.png"))
        self.mAddVariation.setIcon(QIcon(":/images/16x16/add.png"))
        self.mDuplicate.setIcon(QIcon(":/images/16x16/stock-duplicate-16.png"))
        self.mDelete.setIcon(QIcon(":images/16x16/edit-delete.png"))
        self.mChooseFolder.setIcon(QIcon(":images/16x16/document-open.png"))
        Utils.setThemeIcon(self.mNewStamp, "document-new")
        Utils.setThemeIcon(self.mAddVariation, "add")
        Utils.setThemeIcon(self.mDelete, "edit-delete")
        Utils.setThemeIcon(self.mChooseFolder, "document-open")

        self.mFilterEdit.setClearButtonEnabled(True)
        self.mFilterEdit.textChanged.connect(
            self.mProxyModel.setFilterFixedString)
        self.mTileStampModel.stampRenamed.connect(self.ensureStampVisible)
        self.mNewStamp.triggered.connect(self.newStamp)
        self.mAddVariation.triggered.connect(self.addVariation)
        self.mDuplicate.triggered.connect(self.duplicate)
        self.mDelete.triggered.connect(self.delete_)
        self.mChooseFolder.triggered.connect(self.chooseFolder)
        self.mDuplicate.setEnabled(False)
        self.mDelete.setEnabled(False)
        self.mAddVariation.setEnabled(False)
        widget = QWidget(self)
        layout = QVBoxLayout(widget)
        layout.setContentsMargins(5, 5, 5, 5)

        buttonContainer = QToolBar()
        buttonContainer.setFloatable(False)
        buttonContainer.setMovable(False)
        buttonContainer.setIconSize(QSize(16, 16))
        buttonContainer.addAction(self.mNewStamp)
        buttonContainer.addAction(self.mAddVariation)
        buttonContainer.addAction(self.mDuplicate)
        buttonContainer.addAction(self.mDelete)
        stretch = QWidget()
        stretch.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Minimum)
        buttonContainer.addWidget(stretch)
        buttonContainer.addAction(self.mChooseFolder)
        listAndToolBar = QVBoxLayout()
        listAndToolBar.setSpacing(0)
        listAndToolBar.addWidget(self.mFilterEdit)
        listAndToolBar.addWidget(self.mTileStampView)
        listAndToolBar.addWidget(buttonContainer)
        layout.addLayout(listAndToolBar)
        selectionModel = self.mTileStampView.selectionModel()
        selectionModel.currentRowChanged.connect(self.currentRowChanged)
        self.setWidget(widget)
        self.retranslateUi()
Пример #37
0
class AppWindow(QMainWindow):
	"The application's main window"
	def __init__(self):
		super().__init__()
		self.center = QWidget()
		self.display = QStackedLayout()
		self.center.setLayout(self.display)
		# init the manga view variables
		self.manga_display()
		# init the chapter view variables
		self.chapter_display()
		# init toolbar
		self.init_toolbar()
		# init status bar
		self.init_stat_bar()

		self.display.addWidget(self.manga_main)
		self.display.addWidget(self.chapter_main)

		self.setCentralWidget(self.center)
		self.setWindowTitle("Happypanda")
		self.resize(1029, 650)
		self.show()
	
	def init_stat_bar(self):
		self.status_bar = self.statusBar()
		self.status_bar.setMaximumHeight(20)
		self.status_bar.setSizeGripEnabled(False)
		self.stat_info = QLabel()
		self.stat_info.setIndent(5)
		self.sort_main = QAction("Asc", self)
		sort_menu = QMenu()
		self.sort_main.setMenu(sort_menu)
		s_by_title = QAction("Title", sort_menu)
		s_by_artist = QAction("Artist", sort_menu)
		sort_menu.addAction(s_by_title)
		sort_menu.addAction(s_by_artist)
		self.status_bar.addPermanentWidget(self.stat_info)
		#self.status_bar.addAction(self.sort_main)
		self.temp_msg = QLabel()
		self.temp_timer = QTimer()
		self.manga_list_view.series_model.ROWCOUNT_CHANGE.connect(self.stat_row_info)
		self.manga_list_view.series_model.STATUSBAR_MSG.connect(self.stat_temp_msg)

	def stat_temp_msg(self, msg):
		self.temp_timer.stop()
		self.temp_msg.setText(msg)
		self.status_bar.addWidget(self.temp_msg)
		self.temp_timer.timeout.connect(self.temp_msg.clear)
		self.temp_timer.setSingleShot(True)
		self.temp_timer.start(5000)

	def stat_row_info(self):
		r = self.manga_list_view.series_model.rowCount()
		t = len(self.manga_list_view.series_model._data)
		self.stat_info.setText("<b>Showing {} of {} </b>".format(r, t))

	def manga_display(self):
		"initiates the manga view"
		self.manga_main = QWidget()
		self.manga_main.setContentsMargins(-10, -12, -10, -10)
		self.manga_view = QHBoxLayout()
		self.manga_main.setLayout(self.manga_view)

		manga_delegate = series.CustomDelegate()
		manga_delegate.BUTTON_CLICKED.connect(self.setCurrentIndex)
		self.manga_list_view = series.MangaView()
		self.manga_list_view.setItemDelegate(manga_delegate)
		self.manga_view.addWidget(self.manga_list_view)

	def favourite_display(self):
		"initiates favourite display"
		pass

	def chapter_display(self):
		"Initiates chapter view"
		self.chapter_main = QWidget()
		self.chapter_main.setObjectName("chapter_main") # to allow styling this object
		self.chapter_layout = QHBoxLayout()
		self.chapter_main.setLayout(self.chapter_layout)

		#self.chapter_info.setContentsMargins(-8,-7,-7,-7)
		#self.chapter_info.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding)
		self.chapter_info_view = series.ChapterInfo()
		self.chapter_layout.addWidget(self.chapter_info_view)

		chapter_list_view = series.ChapterView()
		self.chapter_layout.addWidget(chapter_list_view)
		#self.chapter.setCollapsible(0, True)
		#self.chapter.setCollapsible(1, False)

	def init_toolbar(self):
		self.toolbar = QToolBar()
		self.toolbar.setFixedHeight(30)
		self.toolbar.setWindowTitle("Show") # text for the contextmenu
		#self.toolbar.setStyleSheet("QToolBar {border:0px}") # make it user defined?
		self.toolbar.setMovable(False)
		self.toolbar.setFloatable(False)
		#self.toolbar.setIconSize(QSize(20,20))
		self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

		spacer_start = QWidget() # aligns the first actions properly
		spacer_start.setFixedSize(QSize(10, 1))
		self.toolbar.addWidget(spacer_start)

		favourite_view_icon = QIcon(gui_constants.STAR_BTN_PATH)
		favourite_view_action = QAction(favourite_view_icon, "Favourite", self)
		#favourite_view_action.setText("Manga View")
		favourite_view_action.triggered.connect(lambda: self.setCurrentIndex(1)) #need lambda to pass extra args
		self.toolbar.addAction(favourite_view_action)

		catalog_view_icon = QIcon(gui_constants.HOME_BTN_PATH)
		catalog_view_action = QAction(catalog_view_icon, "Library", self)
		#catalog_view_action.setText("Catalog")
		catalog_view_action.triggered.connect(lambda: self.setCurrentIndex(0)) #need lambda to pass extra args
		self.toolbar.addAction(catalog_view_action)
		self.toolbar.addSeparator()

		series_icon = QIcon(gui_constants.PLUS_PATH)
		series_action = QAction(series_icon, "Add series...", self)
		series_action.triggered.connect(self.manga_list_view.SERIES_DIALOG.emit)
		series_menu = QMenu()
		series_menu.addSeparator()
		populate_action = QAction("Populate from folder...", self)
		populate_action.triggered.connect(self.populate)
		series_menu.addAction(populate_action)
		series_action.setMenu(series_menu)
		self.toolbar.addAction(series_action)

		spacer_middle = QWidget() # aligns buttons to the right
		spacer_middle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
		self.toolbar.addWidget(spacer_middle)
		
		self.search_bar = QLineEdit()
		self.search_bar.setPlaceholderText("Search title, artist, genres")
		self.search_bar.setMaximumWidth(200)
		self.toolbar.addWidget(self.search_bar)
		self.toolbar.addSeparator()
		settings_icon = QIcon(gui_constants.SETTINGS_PATH)
		settings_action = QAction(settings_icon, "Set&tings", self)
		self.toolbar.addAction(settings_action)
		self.addToolBar(self.toolbar)
		
		spacer_end = QWidget() # aligns About action properly
		spacer_end.setFixedSize(QSize(10, 1))
		self.toolbar.addWidget(spacer_end)

	def setCurrentIndex(self, number, index=None):
		"""Changes the current display view.
		Params:
			number <- int (0 for manga view, 1 for chapter view
		Optional:
			index <- QModelIndex for chapter view
		Note: 0-based indexing
		"""
		if index is not None:
			self.chapter_info_view.display_manga(index)
			self.display.setCurrentIndex(number)
		else:
			self.display.setCurrentIndex(number)

	# TODO: Improve this so that it adds to the series dialog,
	# so user can edit data before inserting (make it a choice)
	def populate(self):
		"Populates the database with series from local drive'"
		msgbox = QMessageBox()
		msgbox.setText("<font color='red'><b>Use with care.</b></font> Choose a folder containing all your series'.")
		msgbox.setInformativeText("Oniichan, are you sure you want to do this?")
		msgbox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
		msgbox.setDefaultButton(QMessageBox.No)
		if msgbox.exec() == QMessageBox.Yes:
			path = QFileDialog.getExistingDirectory(None, "Choose a folder containing your series'")
			if len(path) is not 0:
				data_thread = QThread()
				loading_thread = QThread()
				loading = misc.Loading()

				if not loading.ON:
					misc.Loading.ON = True
					fetch_instance = fetch.Fetch()
					fetch_instance.series_path = path
					loading.show()

					def finished(status):
						if status:
							self.manga_list_view.series_model.populate_data()
							# TODO: make it spawn a dialog instead (from utils.py or misc.py)
							if loading.progress.maximum() == loading.progress.value():
								misc.Loading.ON = False
								loading.hide()
							data_thread.quit
						else:
							loading.setText("<font color=red>An error occured. Try restarting..</font>")
							loading.progress.setStyleSheet("background-color:red")
							data_thread.quit

					def fetch_deleteLater():
						try:
							fetch_instance.deleteLater
						except NameError:
							pass

					def thread_deleteLater(): #NOTE: Isn't this bad?
						data_thread.deleteLater

					def a_progress(prog):
						loading.progress.setValue(prog)
						loading.setText("Searching on local disk...\n(Will take a while on first time)")

					fetch_instance.moveToThread(data_thread)
					fetch_instance.DATA_COUNT.connect(loading.progress.setMaximum)
					fetch_instance.PROGRESS.connect(a_progress)
					data_thread.started.connect(fetch_instance.local)
					fetch_instance.FINISHED.connect(finished)
					fetch_instance.FINISHED.connect(fetch_deleteLater)
					fetch_instance.FINISHED.connect(thread_deleteLater)
					data_thread.start()
Пример #38
0
class GUI(QMainWindow):
    def __init__(self, config, app, splash):
        super().__init__()

        self.config = config
        self.app = app
        self.splash = splash

        log.set_up(logger, verbose=config.VERBOSE, logfile=config.LOG_FILE)

        self.resize(1024, 680)
        self.setWindowTitle(tr("Zuul GUI"))
        icon = QtGui.QIcon('assets/zuul.icns')
        self.setWindowIcon(icon)
        self.app.setWindowIcon(icon)

        def openPreference():
            if self.config.initialize(openDialog=True):
                self.loadPlugins()

        # Add Preferences menu
        mainMenuBar = QMenuBar()
        newAct = QAction(tr("Preferences..."), self)
        newAct.triggered.connect(openPreference)
        fileMenu = mainMenuBar.addMenu(tr("Zuul GUI"))
        fileMenu.addAction(newAct)
        self.setMenuBar(mainMenuBar)

        self.currentBlock = None
        if self.refreshStatus():
            self.loadPlugins()

            timer = QtCore.QTimer(self)
            timer.timeout.connect(self.refreshStatus)
            timer.start(self.config.POLL_INTERVAL)

            self.show()

    # init clientapi
    def initXcpApi(self):
        if hasattr(self, 'zulApi') and isinstance(self.zulApi, ZuuldAPI):
            return True
        else:
            try:
                self.zulApi = ZuuldAPI(self.config)
                return True
            except ConfigurationError as e:
                self.show()
                msgBox = QMessageBox(self)
                msgBox.setText(str(e))
                msgBox.setModal(True)
                msgBox.show()
                return False

    def refreshStatus(self):
        if not self.initXcpApi():
            return False

        try:
            serverInfo = self.zulApi.call(
                {
                    'method': 'get_running_info',
                    'params': []
                }, return_dict=True)

            zuulLastBlock = serverInfo['last_block']['block_index']
            walletLastBlock = self.zulApi.call(
                {
                    'method': 'wallet_last_block',
                    'params': {}
                },
                return_dict=True)

            message = 'Server Last Block: {} | Wallet Last Block: {}'

            self.statusBar().showMessage(
                message.format(zuulLastBlock, walletLastBlock))

            if self.currentBlock is not None and self.currentBlock != zuulLastBlock:
                self.notifyPlugins('new_block', {'block_index': zuulLastBlock})

            self.currentBlock = zuulLastBlock

            return True
        # TODO
        except Exception as e:
            # if application startup then open preference dialog and exit
            if not hasattr(self, 'plugins'):
                if self.splash:
                    self.splash.hide()
                self.config.initialize(openDialog=True)
                exit()
            # else fails silently, error are already shown by `api.ZuuldRPCError`
            # and refreshStatus is executed each self.config.POLL_INTERVAL second
            return False

    def notifyPlugins(self, messageName, messageData):
        logger.debug('Notify plugins `{}`: {}'.format(messageName,
                                                      messageData))
        if hasattr(self, 'plugins'):
            for plugin in self.plugins:
                if hasattr(plugin, 'onMessage'):
                    plugin.onMessage(messageName, messageData)
            self.refreshToolbar()

    def refreshToolbar(self):
        pluginIndex = self.currentMenuItem.property('pluginIndex')
        actionValue = self.currentMenuItem.property('actionValue')
        self.initToolbar(selectedPluginIndex=pluginIndex,
                         selectedActionValue=actionValue)
        self.currentMenuItem.setProperty('active', 'true')
        self.refreshStyleSheet()

    def initPlugins(self):
        # init QML plugin container
        if hasattr(self, 'stackedWidget'):
            del (self.stackedWidget)

        self.stackedWidget = QStackedWidget(self)
        self.plugins = []

        for pluginName in self.config.PLUGINS:
            view = QQuickView()
            view.setFlags(Qt.SubWindow)

            # add clientapi into the plugin context
            context = view.rootContext()

            context.setContextProperty('zulApi', self.zulApi)
            context.setContextProperty('GUI', self)

            # load plugin translations if i18n subfolder exists
            i18nDir = 'plugins/{}/i18n'.format(pluginName)
            if os.path.exists(i18nDir):
                translator = QtCore.QTranslator()
                fileName = 'send_'.format(QtCore.QLocale.system().name())
                #fileName = 'send_fr'
                translator.load(fileName, i18nDir)
                self.app.installTranslator(translator)

            # load QML file
            plugin_index_path = 'plugins/{}/index.qml'.format(pluginName)
            view.setSource(QUrl(plugin_index_path))

            plugin = view.rootObject()
            self.plugins.append(plugin)

            # call plugin init callback
            plugin.init()

            # add the plugin in the container
            container = QWidget.createWindowContainer(view, self)
            self.stackedWidget.addWidget(container)

    def initToolbar(self, selectedPluginIndex=None, selectedActionValue=None):
        # init toolbar
        if hasattr(self, 'toolbar'):
            self.removeToolBar(self.toolbar)
            del (self.toolbar)

        self.toolbar = QToolBar()
        self.toolbar.setAutoFillBackground(True)
        self.toolbar.setObjectName('menu')
        self.toolbar.setMovable(False)
        self.toolbar.setFloatable(False)
        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon
                                        | Qt.AlignLeft)
        self.addToolBar(Qt.LeftToolBarArea, self.toolbar)
        self.currentMenuItem = None

        pluginIndex = 0
        for plugin in self.plugins:
            # generate the left menu
            menu = plugin.property('menu')
            if isinstance(menu, QJSValue):
                menu = menu.toVariant()
            if menu and isinstance(menu,
                                   dict) and 'items' in menu and isinstance(
                                       menu['items'], list):
                # menu title
                if 'groupLabel' in menu:
                    menuGroupLabel = QLabel(menu['groupLabel'])
                    menuGroupLabel.setProperty('isGroupLabel', 'true')
                    self.toolbar.addWidget(menuGroupLabel)
                # menu item
                items = []
                for menuItem in menu['items']:
                    if isinstance(
                            menuItem, dict
                    ) and 'label' in menuItem and 'value' in menuItem:
                        items.append(MenuItem(menuItem['label'], self))
                        items[-1].setProperty('pluginIndex', pluginIndex)
                        items[-1].setProperty('actionValue', menuItem['value'])
                        items[-1].setProperty('isAction', 'true')
                        self.toolbar.addWidget(items[-1])
                        if self.currentMenuItem is None or (
                                selectedPluginIndex == pluginIndex
                                and selectedActionValue == menuItem['value']):
                            self.currentMenuItem = items[-1]

            pluginIndex += 1

        self.currentMenuItem.activate()

    def loadPlugins(self):
        if not self.initXcpApi():
            return

        self.initPlugins()
        self.initToolbar()

        # display the plugin container
        self.refreshStyleSheet()
        self.setCentralWidget(self.stackedWidget)

    def refreshStyleSheet(self):
        self.setStyleSheet('''
            QWidget, QQuickView, QToolBar, QMainWindow { font-size:14pt }
            QToolBar#menu { background-color: #ececec; border: 1px solid #ececec; border-right-color: #000; }
            QToolBar#menu QLabel { width:100%; text-align:left; padding:3px; margin:0; }
            QToolBar#menu QLabel[isAction="true"]:hover { background-color:#CCC; }
            QToolBar#menu QLabel[active="true"] { background-color:#CCC; }
            QToolBar#menu QLabel[isAction="true"] { padding-left: 15px; }
            QToolBar#menu QLabel[isGroupLabel="true"] { color:#888888; text-transform:uppercase; }
        ''')

    # used in QML to display a confirm dialog
    @pyqtSlot(QVariant, QVariant, result=QVariant)
    def confirm(self, title, text):
        result = QMessageBox.question(self, title, text)
        if result == QMessageBox.Yes:
            return True
        else:
            return False

    # used in QML to display a message dialog
    @pyqtSlot(QVariant, QVariant)
    def alert(self, title, text):
        QMessageBox.information(self, title, text)

    @pyqtSlot(QVariant)
    def copyToClipboard(self, text):
        clipboard = QApplication.clipboard()
        clipboard.setText(text)
Пример #39
0
class MainWindow(QMainWindow, ui_window.Ui_Window):
    emulator_found = QtCore.pyqtSignal(dict)
    emulators_loaded = QtCore.pyqtSignal()

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

        self.emulators = { }

        self.settings = QSettings('SanderTheDragon', 'Qtendo')

        self.ui_create()
        self.ui_connect()
        self.settings_load()



    def showEvent(self, ev):
        QMainWindow.showEvent(self, ev)

        self.statusBar.showMsg('Searching for emulators', 1000)
        Thread(target=self.find_emulators, daemon=True).start()


    def closeEvent(self, ev):
        QMainWindow.closeEvent(self, ev)

        self.settings_save()



    def ui_create(self):
        #Add toolbar
        self.toolBar = QToolBar()
        self.toolBar.addAction(self.actionPageEmulation)
        self.toolBar.setFloatable(False)
        self.toolBar.setMovable(False)
        self.toolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.gridLayout.addWidget(self.toolBar, 1, 0)

        #Add a second toolbar on emulation page
        self.toolBarEmulation = QToolBar()
        self.toolBarEmulation.setFloatable(False)
        self.toolBarEmulation.setMovable(False)
        self.toolBarEmulation.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.pageEmulationLayout.addWidget(self.toolBarEmulation, 0, 0)

        #Add progress bar to status bar
        self.taskProgress = QProgressBar()
        self.taskProgress.setVal = lambda x: ( self.taskProgress.setVisible(True), self.taskProgress.setValue(x) )
        self.taskProgress.setVal(0)
        self.taskProgress.setTextVisible(False)
        self.statusBar.addPermanentWidget(self.taskProgress)

        #Also print messages to terminal
        self.statusBar.showMsg = lambda msg, timeout: ( logging.info(msg), self.statusBar.showMessage(msg, timeout) )

        #Styling
        self.setStyleSheet('QToolButton { padding-right: -3px; }')


    def ui_connect(self):
        #Menu actions
        self.actionQuit.triggered.connect(QCoreApplication.quit)
        self.actionSettings.triggered.connect(lambda: settings.SettingsDialog(parent=self).exec_())
        self.actionAbout.triggered.connect(lambda: about.AboutDialog(parent=self).exec_())

        #Toolbar actions
        self.actionPageEmulation.triggered.connect(lambda: self.stackedWidget.setCurrentIndex(0))

        #Other signals
        self.emulator_found.connect(self.add_emulator)
        self.emulators_loaded.connect(self.reset_status)


    def settings_load(self):
        if self.settings.value('qtendo/window/restore', True, type=bool):
            self.restoreGeometry(self.settings.value('qtendo/window/geometry', type=QByteArray))


    def settings_save(self):
        if self.settings.value('qtendo/window/restore', True, type=bool):
            self.settings.setValue('qtendo/window/geometry', self.saveGeometry())



    def change_emulator(self, index):
        current = self.stackedWidgetEmulation.currentIndex()

        if current != index:
            emulator = self.emulators[list(self.emulators.keys())[current]]
            emulator['action'].setIcon(QIcon(emulator['action'].icon().pixmap(QSize(24, 24), QIcon.Disabled)))

            self.stackedWidgetEmulation.setCurrentIndex(index)
            emulator = self.emulators[list(self.emulators.keys())[index]]
            emulator['action'].setIcon(QIcon(':' + emulator['icon']))


    def add_emulator(self, emulator):
        if len(emulator['path']) > 0:
            self.statusBar.showMsg('Found ' + emulator['name'], 1000)
        else:
            self.statusBar.showMsg('Failed to find ' + emulator['name'], 1000)

        self.emulators[emulator['name']] = emulator

        i = self.stackedWidgetEmulation.count()
        emulator['action'] = QAction()

        emulator['action'].setIcon(QIcon(':' + emulator['icon']))
        if i > 0:
            self.toolBarEmulation.addSeparator()
            emulator['action'].setIcon(QIcon(emulator['action'].icon().pixmap(QSize(24, 24), QIcon.Disabled)))

        emulator['action'].setIconText(emulator['name'])
        emulator['action'].triggered.connect(lambda checked, index=i: self.change_emulator(index))

        self.toolBarEmulation.addAction(emulator['action'])
        self.stackedWidgetEmulation.insertWidget(i, emulator['widget'](emulator))

        if len(self.settings.value('emulation/emulator/' + emulator['name'].lower().replace(' ', '_') + '/path', emulator['path'], type=str)) == 0:
            self.toolBarEmulation.widgetForAction(emulator['action']).setStyleSheet('color: ' + QApplication.palette().color(QPalette.Disabled, QPalette.WindowText).name() + ';')

        emulator['reload_settings'] = self.reload_settings

        self.taskProgress.setVal(int((100.0 / float(emulator_count)) * float(i + 1)))


    def reset_status(self):
        self.statusBar.clearMessage()
        self.taskProgress.setValue(0)
        self.taskProgress.setVisible(False)


    def reload_settings(self):
        emulator = self.emulators[list(self.emulators.keys())[self.stackedWidgetEmulation.currentIndex()]]

        if len(self.settings.value('emulation/emulator/' + emulator['name'].lower().replace(' ', '_') + '/path', emulator['path'], type=str)) == 0:
            self.toolBarEmulation.widgetForAction(emulator['action']).setStyleSheet('color: ' + QApplication.palette().color(QPalette.Disabled, QPalette.WindowText).name() + ';')
        else:
            self.toolBarEmulation.widgetForAction(emulator['action']).setStyleSheet('')



    def find_emulators(self):
        #Search for FCEUX
        self.emulator_found.emit(fceux.find(None if not self.settings.contains('emulation/emulator/fceux/path') else self.settings.value('emulation/emulator/fceux/path', type=str)))
        #Search for ZSNES
        self.emulator_found.emit(zsnes.find(None if not self.settings.contains('emulation/emulator/zsnes/path') else self.settings.value('emulation/emulator/zsnes/path', type=str)))
        #Search for Mupen64Plus
        self.emulator_found.emit(mupen64plus.find(None if not self.settings.contains('emulation/emulator/mupen64plus/path') else self.settings.value('emulation/emulator/mupen64plus/path', type=str)))
        #Search for Dolphin Emulator
        self.emulator_found.emit(dolphin.find(None if not self.settings.contains('emulation/emulator/dolphin/path') else self.settings.value('emulation/emulator/dolphin/path', type=str)))
        #Search for Citra
        self.emulator_found.emit(citra.find(None if not self.settings.contains('emulation/emulator/citra/path') else self.settings.value('emulation/emulator/citra/path', type=str)))

        self.emulators_loaded.emit()
Пример #40
0
class MainWindow(QMainWindow):

    """This is the main application window class

    it defines the GUI window for the browser
    """

    def parse_config(self, file_config, options):
        self.config = {}
        options = vars(options)
        for key, metadata in CONFIG_OPTIONS.items():
            options_val = options.get(key)
            file_val = file_config.get(key)
            env_val = os.environ.get(metadata.get("env", ''))
            default_val = metadata.get("default")
            vals = metadata.get("values")
            debug("key: {}, default: {}, file: {}, options: {}".format(
                key, default_val, file_val, options_val
            ))
            if vals:
                options_val = (options_val in vals and options_val) or None
                file_val = (file_val in vals and file_val) or None
                env_val = (env_val in vals and env_val) or None
            if metadata.get("is_file"):
                filename = options_val or env_val
                if not filename:
                    self.config[key] = default_val
                else:
                    try:
                        with open(filename, 'r') as fh:
                            self.config[key] = fh.read()
                    except IOError:
                        debug("Could not open file {} for reading.".format(
                            filename)
                        )
                        self.config[key] = default_val
            else:
                set_values = [
                    val for val in (options_val, env_val, file_val)
                    if val is not None
                ]
                if len(set_values) > 0:
                    self.config[key] = set_values[0]
                else:
                    self.config[key] = default_val
            if metadata.get("type") and self.config[key]:
                debug("{} cast to {}".format(key, metadata.get("type")))
                self.config[key] = metadata.get("type")(self.config[key])
        debug(repr(self.config))

    def createAction(self, text, slot=None, shortcut=None, icon=None, tip=None,
                     checkable=False, signal="triggered"):
        """Return a QAction given a number of common QAction attributes

        Just a shortcut function Originally borrowed from
        'Rapid GUI Development with PyQT' by Mark Summerset
        """
        action = QAction(text, self)
        if icon is not None:
            action.setIcon(QIcon.fromTheme(
                icon, QIcon(":/{}.png".format(icon))
            ))
        if shortcut is not None and not shortcut.isEmpty():
            action.setShortcut(shortcut)
            tip += " ({})".format(shortcut.toString())
        if tip is not None:
            action.setToolTip(tip)
            action.setStatusTip(tip)
        if slot is not None:
            action.__getattr__(signal).connect(slot)
        if checkable:
            action.setCheckable()
        return action

    def __init__(self, options, parent=None):
        """Construct a MainWindow Object."""
        super(MainWindow, self).__init__(parent)
        # Load config file
        self.setWindowTitle("Browser")
        debug("loading configuration from '{}'".format(options.config_file))
        configfile = {}
        if options.config_file:
            configfile = yaml.safe_load(open(options.config_file, 'r'))
        self.parse_config(configfile, options)
        # self.popup will hold a reference to the popup window
        # if it gets opened
        self.popup = None

        # Stylesheet support
        if self.config.get("stylesheet"):
            try:
                with open(self.config.get("stylesheet")) as ss:
                    self.setStyleSheet(ss.read())
            except:
                debug(
                    """Problem loading stylesheet file "{}", """
                    """using default style."""
                    .format(self.config.get("stylesheet"))
                )
        self.setObjectName("global")

        # If the whitelist is activated, add the bookmarks and start_url
        if self.config.get("whitelist"):
            # we can just specify whitelist = True,
            # which should whitelist just the start_url and bookmark urls.
            whitelist = self.config.get("whitelist")
            if type(whitelist) is not list:
                whitelist = []
            whitelist.append(str(QUrl(
                self.config.get("start_url")
            ).host()))
            bookmarks = self.config.get("bookmarks")
            if bookmarks:
                whitelist += [
                    str(QUrl(b.get("url")).host())
                    for k, b in bookmarks.items()
                ]
                self.config["whitelist"] = set(whitelist)  # uniquify and optimize
            debug("Generated whitelist: " + str(whitelist))

        # If diagnostic is enabled, connect CTRL+ALT+? to show some diagnistic info
        if (self.config.get("enable_diagnostic")):
            self.diagnostic_action = self.createAction(
                "Show Diagnostic",
                self.show_diagnostic,
                QKeySequence("Ctrl+Alt+/"),
                tip=''
            )
            self.addAction(self.diagnostic_action)

        self.build_ui()

    # ## END OF CONSTRUCTOR ## #

    def build_ui(self):
        """Set up the user interface for the main window.

        Unlike the constructor, this method is re-run
        whenever the browser is "reset" by the user.
        """

        debug("build_ui")
        inactivity_timeout = self.config.get("timeout")
        quit_button_tooltip = (
            self.config.get("quit_button_mode") == 'close'
            and "Click here to quit the browser."
            or """Click here when you are done.
            It will clear your browsing history"""
            """ and return you to the start page.""")
        qb_mode_callbacks = {'close': self.close, 'reset': self.reset_browser}
        to_mode_callbacks = {'close': self.close,
                             'reset': self.reset_browser,
                             'screensaver': self.screensaver}
        self.screensaver_active = False

        # ##Start GUI configuration## #
        self.browser_window = WcgWebView(self.config)
        self.browser_window.setObjectName("web_content")

        if (
            self.config.get("icon_theme") is not None
            and QT_VERSION_STR > '4.6'
        ):
            QIcon.setThemeName(self.config.get("icon_theme"))
        self.setCentralWidget(self.browser_window)
        debug("loading {}".format(self.config.get("start_url")))
        self.browser_window.setUrl(QUrl(self.config.get("start_url")))
        if self.config.get("fullscreen"):
            self.showFullScreen()
        elif (
            self.config.get("window_size") and
            self.config.get("window_size").lower() == 'max'
        ):
            self.showMaximized()
        elif self.config.get("window_size"):
            size = re.match(r"(\d+)x(\d+)", self.config.get("window_size"))
            if size:
                width, height = size.groups()
                self.setFixedSize(int(width), int(height))
            else:
                debug('Ignoring invalid window size "{}"'.format(
                    self.config.get("window_size")
                ))

        # Set up the top navigation bar if it's configured to exist
        if self.config.get("navigation"):
            self.navigation_bar = QToolBar("Navigation")
            self.navigation_bar.setObjectName("navigation")
            self.addToolBar(Qt.TopToolBarArea, self.navigation_bar)
            self.navigation_bar.setMovable(False)
            self.navigation_bar.setFloatable(False)

            #  Standard navigation tools
            self.nav_items = {}
            self.nav_items["back"] = self.browser_window.pageAction(QWebPage.Back)
            self.nav_items["forward"] = self.browser_window.pageAction(QWebPage.Forward)
            self.nav_items["refresh"] = self.browser_window.pageAction(QWebPage.Reload)
            self.nav_items["stop"] = self.browser_window.pageAction(QWebPage.Stop)
            # The "I'm finished" button.
            self.nav_items["quit"] = self.createAction(
                self.config.get("quit_button_text"),
                qb_mode_callbacks.get(self.config.get("quit_button_mode"), self.reset_browser),
                QKeySequence("Alt+F"),
                None,
                quit_button_tooltip)
            # Zoom buttons
            self.nav_items["zoom_in"] = self.createAction(
                "Zoom In",
                self.zoom_in,
                QKeySequence("Alt++"),
                "zoom-in",
                "Increase the size of the text and images on the page")
            self.nav_items["zoom_out"] = self.createAction(
                "Zoom Out",
                self.zoom_out,
                QKeySequence("Alt+-"),
                "zoom-out",
                "Decrease the size of text and images on the page")
            if self.config.get("allow_printing"):
                self.nav_items["print"] = self.createAction(
                    "Print",
                    self.browser_window.print_webpage,
                    QKeySequence("Ctrl+p"),
                    "document-print",
                    "Print this page")

            # Add all the actions to the navigation bar.
            for item in self.config.get("navigation_layout"):
                if item == "separator":
                    self.navigation_bar.addSeparator()
                elif item == "spacer":
                    # an expanding spacer.
                    spacer = QWidget()
                    spacer.setSizePolicy(
                        QSizePolicy.Expanding, QSizePolicy.Preferred)
                    self.navigation_bar.addWidget(spacer)
                elif item == "bookmarks":
                    # Insert bookmarks buttons here.
                    self.bookmark_buttons = []
                    for bookmark in self.config.get("bookmarks", {}).items():
                        debug("Bookmark:\n" + bookmark.__str__())
                        # bookmark name will use the "name" attribute, if present
                        # or else just the key:
                        bookmark_name = bookmark[1].get("name") or bookmark[0]
                        # Create a button for the bookmark as a QAction,
                        # which we'll add to the toolbar
                        button = self.createAction(
                            bookmark_name,
                            lambda url=bookmark[1].get("url"): self.browser_window.load(QUrl(url)),
                            QKeySequence.mnemonic(bookmark_name),
                            None,
                            bookmark[1].get("description")
                            )
                        self.navigation_bar.addAction(button)
                        self.navigation_bar.widgetForAction(button).setObjectName("navigation_button")
                else:
                    action = self.nav_items.get(item, None)
                    if action:
                        self.navigation_bar.addAction(action)
                        self.navigation_bar.widgetForAction(action).setObjectName("navigation_button")

            # This removes the ability to toggle off the navigation bar:
            self.nav_toggle = self.navigation_bar.toggleViewAction()
            self.nav_toggle.setVisible(False)
            # End "if show_navigation is True" block

        # set hidden quit action
        # For reasons I haven't adequately ascertained,
        # this shortcut fails now and then claiming
        # "Ambiguous shortcut overload".
        # No idea why, as it isn't consistent.
        self.really_quit = self.createAction(
            "", self.close, QKeySequence("Ctrl+Alt+Q"), None, ""
        )
        self.addAction(self.really_quit)

        # Call a reset function after timeout
        if inactivity_timeout != 0:
            self.event_filter = InactivityFilter(inactivity_timeout)
            QCoreApplication.instance().installEventFilter(self.event_filter)
            self.browser_window.page().installEventFilter(self.event_filter)
            self.event_filter.timeout.connect(
                to_mode_callbacks.get(self.config.get("timeout_mode"),
                                      self.reset_browser))
        else:
            self.event_filter = None

        # ##END OF UI SETUP## #

    def screensaver(self):
        """Enter "screensaver" mode

        This method puts the browser in screensaver mode, where a URL
        is displayed while the browser is idle.  Activity causes the browser to
        return to the home screen.
        """
        debug("screensaver started")
        self.screensaver_active = True
        if self.popup:
            self.popup.close()
        if self.config.get("navigation"):
            self.navigation_bar.hide()
        self.browser_window.setZoomFactor(self.config.get("zoom_factor"))
        self.browser_window.load(QUrl(self.config.get("screensaver_url")))
        self.event_filter.timeout.disconnect()
        self.event_filter.activity.connect(self.reset_browser)

    def reset_browser(self):
        """Clear the history and reset the UI.

        Called whenever the inactivity filter times out,
        or when the user clicks the "finished" button in
        'reset' mode.
        """
        # Clear out the memory cache
        QWebSettings.clearMemoryCaches()
        self.browser_window.history().clear()
        # self.navigation_bar.clear() doesn't do its job,
        # so remove the toolbar first, then rebuild the UI.
        debug("RESET BROWSER")
        if self.event_filter:
            self.event_filter.blockSignals(True)
        if self.screensaver_active is True:
            self.screensaver_active = False
            self.event_filter.activity.disconnect()
        if self.event_filter:
            self.event_filter.blockSignals(False)
        if hasattr(self, "navigation_bar"):
            self.removeToolBar(self.navigation_bar)
        self.build_ui()

    def zoom_in(self):
        """Zoom in action callback.

        Note that we cap zooming in at a factor of 3x.
        """
        if self.browser_window.zoomFactor() < 3.0:
            self.browser_window.setZoomFactor(
                self.browser_window.zoomFactor() + 0.1
            )
            self.nav_items["zoom_out"].setEnabled(True)
        else:
            self.nav_items["zoom_in"].setEnabled(False)

    def zoom_out(self):
        """Zoom out action callback.

        Note that we cap zooming out at 0.1x.
        """
        if self.browser_window.zoomFactor() > 0.1:
            self.browser_window.setZoomFactor(
                self.browser_window.zoomFactor() - 0.1
            )
            self.nav_items["zoom_in"].setEnabled(True)
        else:
            self.nav_items["zoom_out"].setEnabled(False)

    def show_diagnostic(self):
        "Display a dialog box with some diagnostic info"
        data = {
            "OS": os.uname(),
            "USER": (os.environ.get("USER")
                     or os.environ.get("USERNAME")),
            "Python": sys.version,
            "Qt": QT_VERSION_STR,
            "Script Date": (
                datetime.datetime.fromtimestamp(
                    os.stat(__file__).st_mtime).isoformat()
            )
        }
        html = "\n".join([
            "<h1>System Information</h1>",
            "<h2>Please click &quot;",
            self.config.get("quit_button_text").replace("&", ''),
            "&quot; when you are finished.</h2>",
            "<ul>",
            "\n".join([
                "<li><b>{}</b>: {}</li>".format(k, v)
                for k, v in data.items()
            ]),
            "</ul>"
        ])
        self.browser_window.setHtml(html)
Пример #41
0
    def initUI(self):
        self.tboard = Board(self)
        self.tboard.setDraught(self)
        self.setCentralWidget(self.tboard)

        mainMenu = self.menuBar()
        gameMenu = mainMenu.addMenu(" Game")

        resetAction = QAction("Reset", self)
        resetAction.setShortcut("Ctrl+R")

        pvp = QAction("Player vs Player", self)
        pvp.setShortcut("Ctrl+P")

        pve = QAction("Player vs Ai", self)
        pve.setShortcut("Ctrl+A")

        gameMenu.addAction(resetAction)
        gameMenu.addAction(pvp)
        gameMenu.addAction(pve)

        resetAction.triggered.connect(self.resetGame)
        pvp.triggered.connect(self.playerGame)
        pve.triggered.connect(self.aiGame)

        self.statusbar = self.statusBar()
        self.tboard.msg2Statusbar[str].connect(self.statusbar.showMessage)

        toolbar = QToolBar()
        toolbar.setAllowedAreas(Qt.RightToolBarArea)
        toolbar.setIconSize(QSize(40, 40))
        toolbar.setFloatable(False)
        toolbar.setMovable(False)

        magicWidget = QWidget()
        self.grid = QGridLayout()

        myFont = QFont()
        myFont.setBold(True)
        myFont.setPixelSize(15)

        self.playerLabel = QLabel("Player")
        self.playerLabel.setFont(myFont)
        self.playerTurn = self.turnLabel()

        self.opponentLabel = QLabel("Opponent")
        self.opponentLabel.setFont(myFont)
        self.opponentLabel.setContentsMargins(0, 30, 0, 0)
        self.opponentTurn = self.turnLabel()
        self.opponentTurn.setContentsMargins(0, 30, 0, 0)

        self.playerPawnLeft = QLabel(str(self.tboard.players[0].pawnLeft))
        self.opponentPawnLeft = QLabel(str(self.tboard.players[1].pawnLeft))

        self.playerPawnKilled = QLabel(str(self.tboard.players[0].pawnKilled))
        self.opponentPawnKilled = QLabel(str(
            self.tboard.players[1].pawnKilled))

        self.grid.addWidget(self.playerLabel, 0, 0)
        self.grid.addWidget(self.playerTurn, 0, 1)
        self.grid.addWidget(self.remainingLabel(), 1, 0)
        self.grid.addWidget(self.playerPawnLeft, 1, 1)
        self.grid.addWidget(self.killedLabel(), 2, 0)
        self.grid.addWidget(self.playerPawnKilled, 2, 1)

        self.grid.addWidget(self.opponentLabel, 3, 0)
        self.grid.addWidget(self.opponentTurn, 3, 1)
        self.grid.addWidget(self.remainingLabel(), 4, 0)
        self.grid.addWidget(self.opponentPawnLeft, 4, 1)
        self.grid.addWidget(self.killedLabel(), 5, 0)
        self.grid.addWidget(self.opponentPawnKilled, 5, 1)

        magicWidget.setLayout(self.grid)

        toolbar.addWidget(magicWidget)

        self.updateTurnLabel()

        self.addToolBar(Qt.RightToolBarArea, toolbar)

        self.resize(550, 400)
        self.center()
        self.setWindowTitle('Draught')
        self.show()
Пример #42
0
class App(QMainWindow):

    @property
    def QSETTINGS(self):
        return QSettings(QSettings.IniFormat, QSettings.UserScope, "mdviewer", "session")

    def __init__(self, parent=None, filename=""):
        QMainWindow.__init__(self, parent)
        self.filename = filename or os.path.join(app_dir, u"README.md")

        # Set environment variables
        self.set_env()

        # Configure Preview window
        self.set_window_title()
        self.resize(self.QSETTINGS.value("size", QSize(800,400)))
        self.move(self.QSETTINGS.value("pos", QPoint(0,0)))

        # Activate WebView
        self.web_view = QWebView()
        self.setCentralWidget(self.web_view)

        self.scroll_pos = {}

        # Configure and start file watcher thread
        self.thread1 = WatcherThread(self.filename)
        self.thread1.update.connect(self.update)
        self.watcher = QFileSystemWatcher([self.filename])
        self.watcher.fileChanged.connect(self.thread1.run)
        self.thread1.run()

        self.web_view.loadFinished.connect(self.after_update)

        # Get style sheet
        self.stylesheet = self.QSETTINGS.value("stylesheet", "default.css")

        # Set GUI menus and toolbars
        self.set_menus()
        self.set_search_bar()

    def set_env(self):
        path, name = os.path.split(os.path.abspath(self.filename))
        ext = os.path.splitext(name)[-1].lower()
        os.environ["MDVIEWER_EXT"] = ext[1:]
        os.environ["MDVIEWER_FILE"] = name
        os.environ["MDVIEWER_ORIGIN"] = path

    def set_window_title(self):
        _path, name = os.path.split(os.path.abspath(self.filename))
        self.setWindowTitle(u"%s – MDviewer" % (name))

    def update(self, text, warn):
        "Update Preview."

        self.web_view.settings().setAttribute(QWebSettings.JavascriptEnabled, True)
        self.web_view.settings().setAttribute(QWebSettings.PluginsEnabled, True)
        self.web_view.settings().setAttribute(QWebSettings.DeveloperExtrasEnabled, True)

        # Configure link behavior
        self.web_view.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
        self.web_view.linkClicked.connect(lambda url: self.handle_link_clicked(url))

        # Save scroll position
        if not self.web_view.page().currentFrame().scrollPosition() == QPoint(0,0):
            self.scroll_pos[self.filename] = self.web_view.page().currentFrame().scrollPosition()

        # Update Preview
        self.web_view.setHtml(text, baseUrl=QUrl.fromLocalFile(os.path.join(os.getcwd(), self.filename)))

        # Load JavaScript and core CSS
        scr = os.path.join(app_dir, "mdviewer.js")
        css = os.path.join(app_dir, "mdviewer.css")
        add_resources = """
        (function() {
            var head = document.querySelector("head");
            var css = document.createElement("link");
            css.rel = "stylesheet";
            css.href = "%s";
            css.id = "coreCSS";
            head.appendChild(css);
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.src = "%s";
            script.id = "coreJS";
            script.setAttribute("defer", "");
            head.appendChild(script);
        })()
        """ % (css, scr)
        self.web_view.page().currentFrame().evaluateJavaScript(add_resources)

        # Display processor warnings
        if warn: QMessageBox.warning(self, "Processor message", warn)

    def after_update(self):
        "Restore scroll position."

        try:
            pos = self.scroll_pos[self.filename]
        except KeyError:
            pass
        else:
            self.web_view.page().currentFrame().evaluateJavaScript("window.scrollTo(%s, %s)" % (pos.x(), pos.y()))

    def open_file(self):
        filename, _filter = QFileDialog.getOpenFileName(self, "Open File", os.path.dirname(self.filename))
        if filename != "":
            self.filename = self.thread1.filename = filename
            self.set_env()
            self.set_window_title()
            self.thread1.run()
        else:
            pass

    def save_html(self):
        filename, _filter = QFileDialog.getSaveFileName(self, "Save File", os.path.dirname(self.filename))
        if filename != "":
            proc = Settings.get("processor_path", "pandoc")
            args = Settings.get("processor_args", "")
            args = ("%s" % (args)).split() + [self.filename]
            caller = QProcess()
            caller.start(proc, args)
            caller.waitForFinished()
            html = str(caller.readAllStandardOutput(), "utf8")
            with io.open(filename, "w", encoding="utf8") as f:
                f.writelines(html)
                f.close()
        else:
            pass

    def find(self, text, btn=""):
        page = self.web_view.page()
        back = page.FindFlags(1) if btn is self.prev else page.FindFlags(0)
        case = page.FindFlags(2) if self.case.isChecked() else page.FindFlags(0)
        wrap = page.FindFlags(4) if self.wrap.isChecked() else page.FindFlags(0)
        page.findText("", page.FindFlags(8))
        page.findText(text, back | wrap | case)

    def set_search_bar(self):
        self.search_bar = QToolBar()
        self.search_bar.setMovable(False)
        self.search_bar.setFloatable(False)
        self.search_bar.setVisible(False)
        self.search_bar.layout().setSpacing(1)
        self.addToolBar(0x8, self.search_bar)

        self.text = QLineEdit(self)
        self.text.setClearButtonEnabled(True)
        self.text.setPlaceholderText(u"Search")
        self.case = QCheckBox(u"Case sensitive", self)
        self.wrap = QCheckBox(u"Wrap", self)
        self.next = QPushButton(u"Next", self)
        self.next.setToolTip(u"Find next")
        self.next.setShortcut(QKeySequence("Return"))
        self.next.setDisabled(True)
        self.prev = QPushButton(u"Previous", self)
        self.prev.setToolTip(u"Find previous")
        self.prev.setShortcut(QKeySequence("Shift+Return"))
        self.prev.setDisabled(True)
        self.done = QPushButton(u"Done", self)
        self.done.setToolTip(u"Hide Search bar")
        self.done.setShortcut(QKeySequence("Esc"))

        def _enable_nav():
            if self.text.text() == "":
                self.next.setDisabled(True)
                self.prev.setDisabled(True)
            else:
                self.next.setDisabled(False)
                self.prev.setDisabled(False)

        def _toggle_btn(btn=""):
            self.text.setFocus()
            self.find(self.text.text(), btn)

        def _hide():
            if self.search_bar.isVisible():
                self.search_bar.hide()

        self.search_bar.addWidget(self.done)
        self.search_bar.addSeparator()
        self.search_bar.addWidget(self.case)
        self.search_bar.addWidget(self.wrap)
        self.search_bar.addWidget(self.text)
        self.search_bar.addSeparator()
        self.search_bar.addWidget(self.next)
        self.search_bar.addWidget(self.prev)
        for btn in (self.prev, self.next):
            btn.pressed[()].connect(lambda btn = btn: _toggle_btn(btn))
        self.done.pressed.connect(_hide)
        self.text.textChanged.connect(self.find)
        self.text.textChanged.connect(_enable_nav)

    def show_search_bar(self):
        self.search_bar.show()
        self.text.setFocus()
        self.text.selectAll()

    def print_doc(self):
        dialog = QPrintPreviewDialog()
        dialog.paintRequested.connect(self.web_view.print_)
        dialog.exec_()

    def quit(self, QCloseEvent):
        self.QSETTINGS.setValue("size", self.size())
        self.QSETTINGS.setValue("pos", self.pos())
        self.QSETTINGS.setValue("stylesheet", self.stylesheet)

        QtWidgets.qApp.quit()

    def zoom_in(self):
        self.web_view.setZoomFactor(self.web_view.zoomFactor()+.1)

    def zoom_out(self):
        self.web_view.setZoomFactor(self.web_view.zoomFactor()-.1)

    def zoom_reset(self):
        self.web_view.setZoomFactor(1)

    def scroll_down(self):
        self.web_view.page().currentFrame().scroll(0, +self.web_view.page().viewportSize().height())

    def scroll_up(self):
        self.web_view.page().currentFrame().scroll(0, -self.web_view.page().viewportSize().height())

    def toggle_toc(self):
        self.web_view.page().currentFrame().evaluateJavaScript("toggleTOC()")

    def handle_link_clicked(self, url):
        if url.isLocalFile():
            if url.toLocalFile() == os.path.abspath(self.filename) and url.hasFragment():
                self.web_view.page().currentFrame().scrollToAnchor(url.fragment())
                return
            else:
                QDesktopServices.openUrl(url)
        else:
            QDesktopServices.openUrl(url)

    @staticmethod
    def set_stylesheet(self, stylesheet="default.css"):
        path = os.path.join(css_dir, stylesheet)
        url = QUrl.fromLocalFile(path)
        self.web_view.settings().setUserStyleSheetUrl(url)
        self.stylesheet = stylesheet

    def about(self):
        msg_about = QMessageBox(0, "About MDviewer", u"MDviewer\n\nVersion: %s" % (VERSION), parent=self)
        msg_about.show()

    def report_issue(self):
        url = QUrl.fromUserInput("https://github.com/saf-dmitry/mdviewer/issues")
        QDesktopServices.openUrl(url)

    def set_menus(self):
        menubar = self.menuBar()

        file_menu = menubar.addMenu("&File")

        for d in (
                {"name": u"&Open...",      "shct": "Ctrl+O", "func": self.open_file},
                {"name": u"&Save HTML...", "shct": "Ctrl+S", "func": self.save_html},
                {"name": u"&Find...",      "shct": "Ctrl+F", "func": self.show_search_bar},
                {"name": u"&Print...",     "shct": "Ctrl+P", "func": self.print_doc},
                {"name": u"&Quit",         "shct": "Ctrl+Q", "func": self.quit}
                 ):
            action = QAction(d["name"], self)
            action.setShortcut(QKeySequence(d["shct"]))
            action.triggered.connect(d["func"])
            file_menu.addAction(action)

        view_menu = menubar.addMenu("&View")

        for d in (
                {"name": u"Zoom &In",     "shct": "Ctrl++", "func": self.zoom_in},
                {"name": u"Zoom &Out",    "shct": "Ctrl+-", "func": self.zoom_out},
                {"name": u"&Actual Size", "shct": "Ctrl+0", "func": self.zoom_reset}
                 ):
            action = QAction(d["name"], self)
            action.setShortcut(QKeySequence(d["shct"]))
            action.triggered.connect(d["func"])
            view_menu.addAction(action)

        style_menu = menubar.addMenu("&Style")
        style_menu.setStyleSheet("menu-scrollable: 1")
        style_menu.setDisabled(True)

        if os.path.exists(css_dir):
            files = sorted(os.listdir(css_dir))
            files = [f for f in files if f.endswith(".css")]
            if len(files) > 0:
                style_menu.setDisabled(False)
                group = QActionGroup(self, exclusive=True)
                for i, f in enumerate(files, start=1):
                    name = os.path.splitext(f)[0].replace("&", "&&")
                    action = group.addAction(QtWidgets.QAction(name, self))
                    action.triggered.connect(
                        lambda x, stylesheet = f: self.set_stylesheet(self, stylesheet))
                    if i < 10: action.setShortcut(QKeySequence("Ctrl+%d" % i))
                    action.setCheckable(True)
                    style_menu.addAction(action)
                    if f == self.stylesheet: action.trigger()

        help_menu = menubar.addMenu("&Help")

        for d in (
                {"name": u"&About...",        "func": self.about},
                {"name": u"&Report an Issue", "func": self.report_issue},
                 ):
            action = QAction(d["name"], self)
            action.triggered.connect(d["func"])
            help_menu.addAction(action)

        # Redefine reload action
        reload_action = self.web_view.page().action(QWebPage.Reload)
        reload_action.setShortcut(QKeySequence.Refresh)
        reload_action.triggered.connect(self.thread1.run)
        self.web_view.addAction(reload_action)

        # Define additional shortcuts
        QShortcut(QKeySequence("j"), self, activated=self.scroll_down)
        QShortcut(QKeySequence("k"), self, activated=self.scroll_up)
        QShortcut(QKeySequence("t"), self, activated=self.toggle_toc)

    def closeEvent(self, event):
        self.quit(event)
        event.accept()
Пример #43
0
class MainWindow_Ui(QMainWindow):
    def __init__(self):
        super().__init__()
#MainWindow
        self.resize(600, 400)
        self.setMinimumSize(QSize(600, 400))
        self.setMaximumSize(QSize(16777215, 16777215))
        self.setWindowTitle("Persepolis Download Manager")
        self.setWindowIcon(QIcon('icon'))
        
        self.centralwidget = QWidget(self)
        self.verticalLayout = QVBoxLayout(self.centralwidget)
#enable drag and drop 
        self.setAcceptDrops(True)
#frame
        self.frame = QFrame(self.centralwidget)
        self.frame.setGeometry(QRect(10, 10, 581, 251))
        self.frame.setFrameShape(QFrame.StyledPanel)
        self.frame.setFrameShadow(QFrame.Raised)
        self.gridLayout = QGridLayout(self.frame)
 

#tablewidget
        self.download_table = QTableWidget(self.frame)
        self.download_table.setGeometry(QRect(10, 10, 560, 231))
        self.download_table.setSizeIncrement(QSize(0, 0))
        self.download_table.setColumnCount(10)
        self.download_table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.download_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.download_table.verticalHeader().hide()
        self.download_table.setColumnHidden(8 , True)
        self.download_table.setColumnHidden(9 , True)

        self.gridLayout.addWidget(self.download_table, 0, 0, 1, 1)
        self.verticalLayout.addWidget(self.frame)
 
        self.setCentralWidget(self.centralwidget)

        download_table_header = ['File Name' , 'Status' , 'Size' , 'Downloaded' , 'Percentage' , 'Connections' , 'Transfer rate' , 'Estimate time left' , 'Gid' , 'Info']
        self.download_table.setHorizontalHeaderLabels(download_table_header)    
#fixing the size of download_table when window is Maximized!
        self.download_table.horizontalHeader().setSectionResizeMode(0)
        self.download_table.horizontalHeader().setStretchLastSection(True)
#finding number od row that user selected!
        self.download_table.itemSelectionChanged.connect(self.selectedRow)
   



#menubar
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QRect(0, 0, 600, 24))
        self.setMenuBar(self.menubar)
        fileMenu = self.menubar.addMenu('File')
        editMenu = self.menubar.addMenu('Edit')
        viewMenu = self.menubar.addMenu('View')
        downloadMenu = self.menubar.addMenu('Download')
        helpMenu = self.menubar.addMenu('Help')


#statusbar
        self.statusbar = QStatusBar(self)
        self.setStatusBar(self.statusbar)
        self.statusbar.showMessage("Persepolis Download Manager")
#toolBar
        self.toolBar = QToolBar(self)
        self.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.toolBar.setWindowTitle("toolBar")
        self.toolBar.setIconSize(QSize(38 , 38))
        self.toolBar.setFloatable(False)
        self.toolBar.setMovable(False)

#toolBar and menubar and actions
        self.stopAllAction = QAction(QIcon(icons + 'stop_all') , 'Stop all active downloads' , self , statusTip = 'Stop all active downloads', triggered = self.stopAllDownloads )
        downloadMenu.addAction(self.stopAllAction)

        self.pauseAllAction = QAction(QIcon(icons + 'pause_all') , 'Pause all active downloads' , self , statusTip = 'Pause all active downloads', triggered = self.pauseAllDownloads )
        downloadMenu.addAction(self.pauseAllAction)


        self.minimizeAction = QAction(QIcon(icons + 'minimize') , 'Minimize to system tray' , self , shortcut = "Ctrl+W" , statusTip = "Minimize to system tray" , triggered = self.minMaxTray) 
        viewMenu.addAction(self.minimizeAction)

    

        self.addlinkAction = QAction(QIcon(icons + 'add') , 'Add New Download Link' , self , shortcut = "Ctrl+N" , statusTip = "Add New Download Link" , triggered = self.addLinkButtonPressed) 
        fileMenu.addAction(self.addlinkAction)


        self.resumeAction = QAction(QIcon(icons + 'play') , 'Resume Download' , self , shortcut = "Ctrl+R" , statusTip = "Resume Download" , triggered = self.resumeButtonPressed)
        downloadMenu.addAction(self.resumeAction)


        self.pauseAction = QAction(QIcon(icons + 'pause') , 'Pause Download' , self , shortcut = "Ctrl+C" , statusTip = "Pause Download" , triggered = self.pauseButtonPressed)
        downloadMenu.addAction(self.pauseAction)

       

        self.stopAction = QAction(QIcon(icons + 'stop') , 'Stop Download' , self , shortcut = "Ctrl+S" , statusTip = "Stop/Cancel Download" , triggered = self.stopButtonPressed)
        downloadMenu.addAction(self.stopAction)

        self.removeAction = QAction(QIcon(icons + 'trash') , 'Remove Download' , self , shortcut = "Ctrl+D" , statusTip = "Remove Download" , triggered = self.removeButtonPressed)
        downloadMenu.addAction(self.removeAction)

        self.propertiesAction = QAction(QIcon(icons + 'setting') , 'Properties' , self , shortcut = "Ctrl+P" , statusTip = "Properties" , triggered = self.propertiesButtonPressed )
        downloadMenu.addAction(self.propertiesAction)

        self.progressAction = QAction(QIcon(icons + 'window') , 'Progress' , self , shortcut = "Ctrl+Z" , statusTip = "Progress" , triggered = self.progressButtonPressed )
        downloadMenu.addAction(self.progressAction)


        self.exitAction = QAction(QIcon(icons + 'exit') , 'Exit' , self , shortcut = "Ctrl+Q" , statusTip = "Exit" , triggered = self.close)
        fileMenu.addAction(self.exitAction)

        self.preferencesAction = QAction(QIcon(icons + 'preferences') , 'Preferences' , self , statusTip = 'Preferences' , triggered = self.openPreferences)
        editMenu.addAction(self.preferencesAction)

        self.aboutAction = QAction(QIcon(icons + 'about') , 'About' , self , statusTip = 'About' , triggered = self.openAbout)
        helpMenu.addAction(self.aboutAction)

        


        for i in self.addlinkAction,self.resumeAction, self.pauseAction , self.stopAction, self.removeAction , self.propertiesAction, self.progressAction , self.exitAction :
            self.toolBar.addAction(i)
         

        self.toolBar.insertSeparator(self.addlinkAction)
        self.toolBar.insertSeparator(self.resumeAction)     
        self.toolBar.insertSeparator(self.removeAction)
        self.toolBar.insertSeparator(self.exitAction)
        self.toolBar.addSeparator()
Пример #44
0
class Ui_MainWindow(object):
    def setupUi(self, main_window):

        main_window.setObjectName("mainWindow")
        main_window.resize(1024, 768)
        main_window.setMinimumSize(QSize(1024, 768))
        main_window.setToolButtonStyle(Qt.ToolButtonIconOnly)

        self.central_widget = QWidget(main_window)
        self.central_widget.setObjectName("central_widget")

        self.horizontalLayout = QHBoxLayout(self.central_widget)
        self.horizontalLayout.setObjectName("horizontalLayout")

        self.topDownSplitter = QSplitter(self.central_widget)
        self.topDownSplitter.setOrientation(Qt.Vertical)
        self.topDownSplitter.setOpaqueResize(True)
        self.topDownSplitter.setHandleWidth(5)
        self.topDownSplitter.setObjectName("topDownSplitter")

        self.leftRightSplitter = QSplitter(self.topDownSplitter)
        self.leftRightSplitter.setOrientation(Qt.Horizontal)
        self.leftRightSplitter.setObjectName("leftRightSplitter")

        self.leftPanel = QFrame(self.leftRightSplitter)

        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.leftPanel.sizePolicy().hasHeightForWidth())

        self.leftPanel.setSizePolicy(sizePolicy)
        self.leftPanel.setMinimumSize(QSize(245, 550))
        self.leftPanel.setMaximumSize(QSize(245, 16777215))
        self.leftPanel.setFrameShape(QFrame.StyledPanel)
        self.leftPanel.setFrameShadow(QFrame.Raised)
        self.leftPanel.setObjectName("leftPanel")

        self.leftPanelVLayout = QVBoxLayout(self.leftPanel)
        self.leftPanelVLayout.setObjectName("leftPanelVLayout")

        self.colorPickerFrame = QFrame(self.leftPanel)
        self.colorPickerFrame.setMinimumSize(QSize(0, 0))
        self.colorPickerFrame.setMaximumSize(QSize(16777215, 16777215))
        self.colorPickerFrame.setFrameShape(QFrame.StyledPanel)
        self.colorPickerFrame.setFrameShadow(QFrame.Raised)
        self.colorPickerFrame.setObjectName("colorPickerFrame")

        self.leftPanelVLayout.addWidget(self.colorPickerFrame)
        self.leftPanelVLayout.setStretch(0, 5)

        self.mainPanel = QFrame(self.leftRightSplitter)

        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.mainPanel.sizePolicy().hasHeightForWidth())

        self.mainPanel.setSizePolicy(sizePolicy)
        self.mainPanel.setMinimumSize(QSize(320, 240))
        self.mainPanel.setAutoFillBackground(False)
        self.mainPanel.setFrameShape(QFrame.StyledPanel)
        self.mainPanel.setFrameShadow(QFrame.Raised)
        self.mainPanel.setObjectName("mainPanel")

        self.verticalLayout = QVBoxLayout(self.mainPanel)
        self.verticalLayout.setObjectName("verticalLayout")

        self.canvasFrame = QFrame(self.mainPanel)

        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.canvasFrame.sizePolicy().hasHeightForWidth())

        self.canvasFrame.setSizePolicy(sizePolicy)
        self.canvasFrame.setMinimumSize(310, 230)
        self.canvasFrame.setFrameShape(QFrame.StyledPanel)
        self.canvasFrame.setFrameShadow(QFrame.Raised)
        self.canvasFrame.setObjectName("canvasFrame")

        self.verticalLayout.addWidget(self.canvasFrame)
        self.verticalLayout.setStretch(0, 12)

        self.rightPanel = QFrame(self.leftRightSplitter)

        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.rightPanel.sizePolicy().hasHeightForWidth())

        self.rightPanel.setSizePolicy(sizePolicy)
        self.rightPanel.setMinimumSize(QSize(245, 550))
        self.rightPanel.setMaximumSize(QSize(340, 16777215))
        self.rightPanel.setFrameShape(QFrame.StyledPanel)
        self.rightPanel.setFrameShadow(QFrame.Raised)
        self.rightPanel.setObjectName("rightPanel")

        self.rightPanelLayout = QVBoxLayout(self.rightPanel)
        self.rightPanelLayout.setObjectName("rightPanelLayout")

        self.previewFrame = QFrame(self.rightPanel)
        self.previewFrame.setMaximumSize(320, 500)
        self.previewFrame.setFrameShape(QFrame.StyledPanel)
        self.previewFrame.setFrameShadow(QFrame.Raised)
        self.previewFrame.setObjectName("previewFrame")

        self.rightPanelLayout.addWidget(self.previewFrame)

        self.layerListFrame = QFrame(self.rightPanel)
        self.layerListFrame.setFrameShape(QFrame.StyledPanel)
        self.layerListFrame.setFrameShadow(QFrame.Raised)
        self.layerListFrame.setObjectName("layerListFrame")

        self.rightPanelLayout.addWidget(self.layerListFrame)

        self.animationBarFrame = QFrame(self.topDownSplitter)

        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.animationBarFrame.sizePolicy().hasHeightForWidth())

        self.animationBarFrame.setSizePolicy(sizePolicy)
        self.animationBarFrame.setMinimumSize(QSize(600, 100))
        self.animationBarFrame.setMaximumSize(QSize(16777215, 100))
        self.animationBarFrame.setFrameShape(QFrame.StyledPanel)
        self.animationBarFrame.setFrameShadow(QFrame.Raised)
        self.animationBarFrame.setObjectName("animationBarFrame")

        self.horizontalLayout.addWidget(self.topDownSplitter)

        main_window.setCentralWidget(self.central_widget)

        self.toolBar = QToolBar(main_window)

        sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.toolBar.sizePolicy().hasHeightForWidth())

        self.toolBar.setSizePolicy(sizePolicy)
        self.toolBar.setMovable(False)
        self.toolBar.setFloatable(False)
        self.toolBar.setObjectName("toolBar")

        main_window.addToolBar(Qt.TopToolBarArea, self.toolBar)

        self.actionNew = QAction(main_window)
        self.actionNew.setObjectName("actionNew")

        self.actionQuit = QAction(main_window)
        self.actionQuit.setObjectName("actionQuit")

        self.actionOpen = QAction(main_window)
        self.actionOpen.setObjectName("actionOpen")

        self.actionSave = QAction(main_window)
        self.actionSave.setObjectName("actionSave")

        self.actionSaveAs = QAction(main_window)
        self.actionSaveAs.setObjectName("actionSaveAs")

        self.actionClose = QAction(main_window)
        self.actionClose.setObjectName("actionClose")

        self.actionExport = QAction(main_window)
        self.actionExport.setObjectName("actionExport")

        self.actionImport = QAction(main_window)
        self.actionImport.setObjectName("actionImport")

        self.toolBar.addAction(self.actionNew)
        self.toolBar.addAction(self.actionOpen)
        self.toolBar.addAction(self.actionImport)
        self.toolBar.addAction(self.actionSave)
        self.toolBar.addAction(self.actionSaveAs)
        self.toolBar.addAction(self.actionExport)
        self.toolBar.addAction(self.actionClose)
        self.toolBar.addAction(self.actionQuit)

        self.retranslateUi(main_window)
        QMetaObject.connectSlotsByName(main_window)

    def retranslateUi(self, main_window):

        _translate = QCoreApplication.translate

        main_window.setWindowTitle(_translate("MainWindow", "SpriteMator"))
        self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))

        self.actionNew.setText(_translate("MainWindow", "New"))
        self.actionNew.setIconText(_translate("MainWindow", "New"))
        self.actionNew.setToolTip(_translate("MainWindow", "New Sprite"))
        self.actionNew.setShortcut(_translate("MainWindow", "Ctrl+N"))

        self.actionQuit.setText(_translate("MainWindow", "Quit"))
        self.actionQuit.setToolTip(
            _translate("MainWindow", "Close Application"))
        self.actionQuit.setShortcut(_translate("MainWindow", "Esc"))

        self.actionOpen.setText(_translate("MainWindow", "Open"))
        self.actionOpen.setToolTip(_translate("MainWindow", "Open Sprite"))
        self.actionOpen.setShortcut(_translate("MainWindow", "Ctrl+O"))

        self.actionSave.setText(_translate("MainWindow", "Save"))
        self.actionSave.setToolTip(_translate("MainWindow", "Save Sprite"))
        self.actionSave.setShortcut(_translate("MainWindow", "Ctrl+S"))

        self.actionSaveAs.setText(_translate("MainWindow", "SaveAs"))
        self.actionSaveAs.setToolTip(
            _translate("MainWindow", "Save Sprite with another name"))
        self.actionSaveAs.setShortcut(_translate("MainWindow", "Ctrl+Shift+S"))

        self.actionClose.setText(_translate("MainWindow", "Close"))
        self.actionClose.setToolTip(_translate("MainWindow", "Close Sprite"))
        self.actionClose.setShortcut(_translate("MainWindow", "Ctrl+Q"))

        self.actionExport.setText(_translate("MainWindow", "Export"))
        self.actionExport.setToolTip(
            _translate(
                "MainWindow",
                "Export Sprite animations : Either as separate images or as a spritesheet"
            ))
        self.actionExport.setShortcut(_translate("MainWindow", "Ctrl+E"))

        self.actionImport.setText(_translate("MainWindow", "Import"))
        self.actionImport.setToolTip(
            _translate("MainWindow",
                       "Create a Sprite from one or more images"))
        self.actionImport.setShortcut(_translate("MainWindow", "Ctrl+I"))