class ButtomWindow(QTabWidget):
    def __init__(self, parent=None):
        super(ButtomWindow, self).__init__(parent)
        self.initUi()


    def initUi(self):
        self.tabBar = QTabBar()
        self.consoleView = ConsoleWindow()
        self.tabBar.tabBarClicked.connect(self.status)
        self.tabBar.setExpanding(False)
        self.setTabBar(self.tabBar)
        self.addTab(self.consoleView,IconTool.buildQIcon('logcat.png'), "Logcat")
        self.consoleView.setVisible(False)
        self.setFixedHeight(Utils.getItemHeight())
        self.setTabPosition(QTabWidget.South)
        self.setStyleSheet("QTabBar::tab {border: none; height: "+str(Utils.getItemHeight())+"px; width:100px;color:black;}"
                            "QTabBar::tab:selected { border: none;background: lightgray; } ")

    def status(self):
      if self.tabBar.tabText(self.tabBar.currentIndex()) == 'Logcat':
        if self.consoleView.isVisible():
          self.consoleView.setVisible(False)
          self.preHeight = self.width()
          self.setFixedHeight(Utils.getItemHeight())
        else:
          self.consoleView.setVisible(True)
          self.setMaximumHeight(Utils.getWindowHeight())
Exemple #2
0
class MainWindow(QMainWindow):
    def __init__(self, doc):
        QMainWindow.__init__(self, None)
        self.doc = doc
        self.app = doc.app

        self._setupUi()

        # Create base elements
        self.model = MainWindowModel(document=doc.model)
        self.model2view = {}
        self.alookup = Lookup(self, model=self.model.account_lookup)
        self.clookup = Lookup(self, model=self.model.completion_lookup)
        self.drsel = DateRangeSelector(mainwindow=self, view=self.dateRangeSelectorView)
        self.sfield = SearchField(model=self.model.search_field, view=self.searchLineEdit)
        self.importWindow = ImportWindow(self)
        self.csvOptionsWindow = CSVOptionsWindow(self)
        self.recentDocuments = Recent(self.app, 'recentDocuments')
        self.recentDocuments.addMenu(self.menuOpenRecent)

        self.model.view = self
        self.model.connect()

        self._updateUndoActions()
        self._bindSignals()

    def _setupUi(self): # has to take place *before* base elements creation
        self.setWindowTitle("moneyGuru")
        self.resize(700, 580)
        self.centralwidget = QWidget(self)
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.topBar = QWidget(self.centralwidget)
        self.horizontalLayout_2 = QHBoxLayout(self.topBar)
        self.horizontalLayout_2.setContentsMargins(2, 0, 2, 0)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem)
        self.dateRangeSelectorView = DateRangeSelectorView(self.topBar)
        self.dateRangeSelectorView.setMinimumSize(QSize(220, 0))
        self.horizontalLayout_2.addWidget(self.dateRangeSelectorView)
        spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem1)
        self.searchLineEdit = SearchEdit(self.topBar)
        self.searchLineEdit.setMaximumSize(QSize(240, 16777215))
        self.horizontalLayout_2.addWidget(self.searchLineEdit)
        self.verticalLayout.addWidget(self.topBar)
        self.tabBar = QTabBar(self.centralwidget)
        self.tabBar.setMinimumSize(QSize(0, 20))
        self.verticalLayout.addWidget(self.tabBar)
        self.mainView = QStackedWidget(self.centralwidget)
        self.verticalLayout.addWidget(self.mainView)

        # Bottom buttons & status label
        self.bottomBar = QWidget(self.centralwidget)
        self.horizontalLayout = QHBoxLayout(self.bottomBar)
        self.horizontalLayout.setContentsMargins(2, 2, 2, 2)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.newItemButton = QPushButton(self.bottomBar)
        buttonSizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
        buttonSizePolicy.setHorizontalStretch(0)
        buttonSizePolicy.setVerticalStretch(0)
        buttonSizePolicy.setHeightForWidth(self.newItemButton.sizePolicy().hasHeightForWidth())
        self.newItemButton.setSizePolicy(buttonSizePolicy)
        self.newItemButton.setIcon(QIcon(QPixmap(':/plus_8')))
        self.horizontalLayout.addWidget(self.newItemButton)
        self.deleteItemButton = QPushButton(self.bottomBar)
        self.deleteItemButton.setSizePolicy(buttonSizePolicy)
        self.deleteItemButton.setIcon(QIcon(QPixmap(':/minus_8')))
        self.horizontalLayout.addWidget(self.deleteItemButton)
        self.editItemButton = QPushButton(self.bottomBar)
        self.editItemButton.setSizePolicy(buttonSizePolicy)
        self.editItemButton.setIcon(QIcon(QPixmap(':/info_gray_12')))
        self.horizontalLayout.addWidget(self.editItemButton)
        self.horizontalLayout.addItem(horizontalSpacer(size=20))
        self.graphVisibilityButton = QPushButton()
        self.graphVisibilityButton.setSizePolicy(buttonSizePolicy)
        self.graphVisibilityButton.setIcon(QIcon(QPixmap(':/graph_visibility_on_16')))
        self.horizontalLayout.addWidget(self.graphVisibilityButton)
        self.piechartVisibilityButton = QPushButton()
        self.piechartVisibilityButton.setSizePolicy(buttonSizePolicy)
        self.piechartVisibilityButton.setIcon(QIcon(QPixmap(':/piechart_visibility_on_16')))
        self.horizontalLayout.addWidget(self.piechartVisibilityButton)
        self.columnsVisibilityButton = QPushButton()
        self.columnsVisibilityButton.setSizePolicy(buttonSizePolicy)
        self.columnsVisibilityButton.setIcon(QIcon(QPixmap(':/columns_16')))
        self.horizontalLayout.addWidget(self.columnsVisibilityButton)

        self.statusLabel = QLabel(tr("Status"))
        self.statusLabel.setAlignment(Qt.AlignCenter)
        self.horizontalLayout.addWidget(self.statusLabel)
        self.verticalLayout.addWidget(self.bottomBar)


        self.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QRect(0, 0, 700, 20))
        self.menuFile = QMenu(tr("File"))
        self.menuOpenRecent = QMenu(tr("Open Recent"))
        self.menuView = QMenu(tr("View"))
        self.menuDateRange = QMenu(tr("Date Range"))
        self.menuEdit = QMenu(tr("Edit"))
        self.menuHelp = QMenu(tr("Help"))
        self.setMenuBar(self.menubar)
        self.actionOpenDocument = QAction(tr("Open..."), self)
        self.actionOpenDocument.setShortcut("Ctrl+O")
        self.actionShowNetWorth = QAction(tr("Net Worth"), self)
        self.actionShowNetWorth.setShortcut("Ctrl+1")
        self.actionShowNetWorth.setIcon(QIcon(QPixmap(':/balance_sheet_48')))
        self.actionShowProfitLoss = QAction(escapeamp(tr("Profit & Loss")), self)
        self.actionShowProfitLoss.setShortcut("Ctrl+2")
        self.actionShowProfitLoss.setIcon(QIcon(QPixmap(':/income_statement_48')))
        self.actionShowTransactions = QAction(tr("Transactions"), self)
        self.actionShowTransactions.setShortcut("Ctrl+3")
        self.actionShowTransactions.setIcon(QIcon(QPixmap(':/transaction_table_48')))
        self.actionShowSelectedAccount = QAction(tr("Show Account"), self)
        self.actionShowSelectedAccount.setShortcut("Ctrl+]")
        self.actionNewItem = QAction(tr("New Item"), self)
        self.actionNewItem.setShortcut("Ctrl+N")
        self.actionDeleteItem = QAction(tr("Remove Selected"), self)
        self.actionEditItem = QAction(tr("Show Info"), self)
        self.actionEditItem.setShortcut("Ctrl+I")
        self.actionToggleGraph = QAction(tr("Toggle Graph"), self)
        self.actionToggleGraph.setShortcut("Ctrl+Alt+G")
        self.actionTogglePieChart = QAction(tr("Toggle Pie Chart"), self)
        self.actionTogglePieChart.setShortcut("Ctrl+Alt+P")
        self.actionMoveUp = QAction(tr("Move Up"), self)
        self.actionMoveUp.setShortcut("Ctrl++")
        self.actionMoveDown = QAction(tr("Move Down"), self)
        self.actionMoveDown.setShortcut("Ctrl+-")
        self.actionNavigateBack = QAction(tr("Go Back"), self)
        self.actionNavigateBack.setShortcut("Ctrl+[")
        self.actionNewAccountGroup = QAction(tr("New Account Group"), self)
        self.actionNewAccountGroup.setShortcut("Ctrl+Shift+N")
        self.actionShowNextView = QAction(tr("Next View"), self)
        self.actionShowNextView.setShortcut("Ctrl+Shift+]")
        self.actionShowPreviousView = QAction(tr("Previous View"), self)
        self.actionShowPreviousView.setShortcut("Ctrl+Shift+[")
        self.actionNewDocument = QAction(tr("New Document"), self)
        self.actionOpenExampleDocument = QAction(tr("Open Example Document"), self)
        self.actionOpenPluginFolder = QAction(tr("Open Plugin Folder"), self)
        self.actionImport = QAction(tr("Import..."), self)
        self.actionImport.setShortcut("Ctrl+Alt+I")
        self.actionExport = QAction(tr("Export..."), self)
        self.actionExport.setShortcut("Ctrl+Alt+E")
        self.actionSave = QAction(tr("Save"), self)
        self.actionSave.setShortcut("Ctrl+S")
        self.actionSaveAs = QAction(tr("Save As..."), self)
        self.actionSaveAs.setShortcut("Ctrl+Shift+S")
        self.actionAbout = QAction(tr("About moneyGuru"), self)
        self.actionToggleReconciliationMode = QAction(tr("Toggle Reconciliation Mode"), self)
        self.actionToggleReconciliationMode.setShortcut("Ctrl+Shift+R")
        self.actionToggleAccountExclusion = QAction(tr("Toggle Exclusion Status of Account"), self)
        self.actionToggleAccountExclusion.setShortcut("Ctrl+Shift+X")
        self.actionShowSchedules = QAction(tr("Schedules"), self)
        self.actionShowSchedules.setShortcut("Ctrl+4")
        self.actionShowSchedules.setIcon(QIcon(QPixmap(':/schedules_48')))
        self.actionShowBudgets = QAction(tr("Budgets"), self)
        self.actionShowBudgets.setShortcut("Ctrl+5")
        self.actionShowBudgets.setIcon(QIcon(QPixmap(':/budget_48')))
        self.actionReconcileSelected = QAction(tr("Reconcile Selection"), self)
        self.actionReconcileSelected.setShortcut("Ctrl+R")
        self.actionMakeScheduleFromSelected = QAction(tr("Make Schedule from Selected"), self)
        self.actionMakeScheduleFromSelected.setShortcut("Ctrl+M")
        self.actionShowPreferences = QAction(tr("Preferences..."), self)
        self.actionPrint = QAction(tr("Print..."), self)
        self.actionPrint.setShortcut("Ctrl+P")
        self.actionQuit = QAction(tr("Quit moneyGuru"), self)
        self.actionQuit.setShortcut("Ctrl+Q")
        self.actionUndo = QAction(tr("Undo"), self)
        self.actionUndo.setShortcut("Ctrl+Z")
        self.actionRedo = QAction(tr("Redo"), self)
        self.actionRedo.setShortcut("Ctrl+Y")
        self.actionShowHelp = QAction(tr("moneyGuru Help"), self)
        self.actionShowHelp.setShortcut("F1")
        self.actionCheckForUpdate = QAction(tr("Check for update"), self)
        self.actionOpenDebugLog = QAction(tr("Open Debug Log"), self)
        self.actionDuplicateTransaction = QAction(tr("Duplicate Transaction"), self)
        self.actionDuplicateTransaction.setShortcut("Ctrl+D")
        self.actionJumpToAccount = QAction(tr("Jump to Account..."), self)
        self.actionJumpToAccount.setShortcut("Ctrl+Shift+A")
        self.actionNewTab = QAction(tr("New Tab"), self)
        self.actionNewTab.setShortcut("Ctrl+T")
        self.actionCloseTab = QAction(tr("Close Tab"), self)
        self.actionCloseTab.setShortcut("Ctrl+W")

        self.menuFile.addAction(self.actionNewDocument)
        self.menuFile.addAction(self.actionNewTab)
        self.menuFile.addAction(self.actionOpenDocument)
        self.menuFile.addAction(self.menuOpenRecent.menuAction())
        self.menuFile.addAction(self.actionOpenExampleDocument)
        self.menuFile.addAction(self.actionOpenPluginFolder)
        self.menuFile.addAction(self.actionImport)
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionCloseTab)
        self.menuFile.addAction(self.actionSave)
        self.menuFile.addAction(self.actionSaveAs)
        self.menuFile.addAction(self.actionExport)
        self.menuFile.addAction(self.actionPrint)
        self.menuFile.addAction(self.actionQuit)
        self.menuView.addAction(self.actionShowNetWorth)
        self.menuView.addAction(self.actionShowProfitLoss)
        self.menuView.addAction(self.actionShowTransactions)
        self.menuView.addAction(self.actionShowSchedules)
        self.menuView.addAction(self.actionShowBudgets)
        self.menuView.addAction(self.actionShowPreviousView)
        self.menuView.addAction(self.actionShowNextView)
        self.menuView.addAction(self.menuDateRange.menuAction())
        self.menuView.addAction(self.actionShowPreferences)
        self.menuView.addAction(self.actionToggleGraph)
        self.menuView.addAction(self.actionTogglePieChart)
        self.menuEdit.addAction(self.actionNewItem)
        self.menuEdit.addAction(self.actionNewAccountGroup)
        self.menuEdit.addAction(self.actionDeleteItem)
        self.menuEdit.addAction(self.actionEditItem)
        self.menuEdit.addSeparator()
        self.menuEdit.addAction(self.actionMoveUp)
        self.menuEdit.addAction(self.actionMoveDown)
        self.menuEdit.addAction(self.actionDuplicateTransaction)
        self.menuEdit.addAction(self.actionMakeScheduleFromSelected)
        self.menuEdit.addAction(self.actionReconcileSelected)
        self.menuEdit.addAction(self.actionToggleReconciliationMode)
        self.menuEdit.addAction(self.actionToggleAccountExclusion)
        self.menuEdit.addSeparator()
        self.menuEdit.addAction(self.actionShowSelectedAccount)
        self.menuEdit.addAction(self.actionNavigateBack)
        self.menuEdit.addAction(self.actionJumpToAccount)
        self.menuEdit.addSeparator()
        self.menuEdit.addAction(self.actionUndo)
        self.menuEdit.addAction(self.actionRedo)
        self.menuHelp.addAction(self.actionShowHelp)
        self.menuHelp.addAction(self.actionCheckForUpdate)
        self.menuHelp.addAction(self.actionOpenDebugLog)
        self.menuHelp.addAction(self.actionAbout)
        mainmenus = [self.menuFile, self.menuEdit, self.menuView, self.menuHelp]
        for menu in mainmenus:
            self.menubar.addAction(menu.menuAction())
            setAccelKeys(menu)
        setAccelKeys(self.menubar)
        self.tabBar.setMovable(True)
        self.tabBar.setTabsClosable(True)
        self.tabBar.setExpanding(False)

        seq = QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_Right)
        self._shortcutNextTab = QShortcut(seq, self)
        seq = QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_Left)
        self._shortcutPrevTab = QShortcut(seq, self)

        # Linux setup
        if ISLINUX:
            self.actionCheckForUpdate.setVisible(False) # This only works on Windows

    def _bindSignals(self):
        self.newItemButton.clicked.connect(self.actionNewItem.trigger)
        self.deleteItemButton.clicked.connect(self.actionDeleteItem.trigger)
        self.editItemButton.clicked.connect(self.actionEditItem.trigger)
        self.graphVisibilityButton.clicked.connect(self.actionToggleGraph.trigger)
        self.piechartVisibilityButton.clicked.connect(self.actionTogglePieChart.trigger)
        self.columnsVisibilityButton.clicked.connect(self.columnsVisibilityButtonClicked)
        self.recentDocuments.mustOpenItem.connect(self.doc.open)
        self.doc.documentOpened.connect(self.recentDocuments.insertItem)
        self.doc.documentSavedAs.connect(self.recentDocuments.insertItem)
        self.doc.documentPathChanged.connect(self.documentPathChanged)
        self.tabBar.currentChanged.connect(self.currentTabChanged)
        self.tabBar.tabCloseRequested.connect(self.tabCloseRequested)
        self.tabBar.tabMoved.connect(self.tabMoved)

        # Views
        self.actionShowNetWorth.triggered.connect(self.showNetWorthTriggered)
        self.actionShowProfitLoss.triggered.connect(self.showProfitLossTriggered)
        self.actionShowTransactions.triggered.connect(self.showTransactionsTriggered)
        self.actionShowSchedules.triggered.connect(self.showSchedulesTriggered)
        self.actionShowBudgets.triggered.connect(self.showBudgetsTriggered)
        self.actionShowPreviousView.triggered.connect(self.showPreviousViewTriggered)
        self.actionShowNextView.triggered.connect(self.showNextViewTriggered)
        self.actionShowPreferences.triggered.connect(self.app.showPreferences)
        self.actionToggleGraph.triggered.connect(self.toggleGraphTriggered)
        self.actionTogglePieChart.triggered.connect(self.togglePieChartTriggered)

        # Document Edition
        self.actionNewItem.triggered.connect(self.newItemTriggered)
        self.actionNewAccountGroup.triggered.connect(self.newAccountGroupTriggered)
        self.actionDeleteItem.triggered.connect(self.deleteItemTriggered)
        self.actionEditItem.triggered.connect(self.editItemTriggered)
        self.actionMoveUp.triggered.connect(self.moveUpTriggered)
        self.actionMoveDown.triggered.connect(self.moveDownTriggered)
        self.actionDuplicateTransaction.triggered.connect(self.model.duplicate_item)
        self.actionUndo.triggered.connect(self.doc.model.undo)
        self.actionRedo.triggered.connect(self.doc.model.redo)

        # Open / Save / Import / Export / New
        self.actionNewDocument.triggered.connect(self.doc.new)
        self.actionOpenDocument.triggered.connect(self.doc.openDocument)
        self.actionOpenExampleDocument.triggered.connect(self.doc.openExampleDocument)
        self.actionOpenPluginFolder.triggered.connect(self.model.app.open_plugin_folder)
        self.actionImport.triggered.connect(self.importDocument)
        self.actionSave.triggered.connect(self.doc.save)
        self.actionSaveAs.triggered.connect(self.doc.saveAs)
        self.actionExport.triggered.connect(self.model.export)

        # Misc
        self.actionNewTab.triggered.connect(self.model.new_tab)
        self.actionCloseTab.triggered.connect(self.closeTabTriggered)
        self.actionShowSelectedAccount.triggered.connect(self.model.show_account)
        self.actionNavigateBack.triggered.connect(self.navigateBackTriggered)
        self.actionJumpToAccount.triggered.connect(self.jumpToAccountTriggered)
        self.actionMakeScheduleFromSelected.triggered.connect(self.makeScheduleFromSelectedTriggered)
        self.actionReconcileSelected.triggered.connect(self.reconcileSelectedTriggered)
        self.actionToggleReconciliationMode.triggered.connect(self.toggleReconciliationModeTriggered)
        self.actionToggleAccountExclusion.triggered.connect(self.toggleAccountExclusionTriggered)
        self.actionPrint.triggered.connect(self._print)
        self.actionShowHelp.triggered.connect(self.app.showHelp)
        self.actionCheckForUpdate.triggered.connect(self.checkForUpdateTriggered)
        self.actionAbout.triggered.connect(self.aboutTriggered)
        self.actionOpenDebugLog.triggered.connect(self.openDebugLogTriggered)
        self.actionQuit.triggered.connect(self.close)

        # Extra Shortcuts
        self._shortcutNextTab.activated.connect(self.showNextViewTriggered)
        self._shortcutPrevTab.activated.connect(self.showPreviousViewTriggered)

    # --- QWidget overrides
    def closeEvent(self, event):
        if self.doc.confirmDestructiveAction():
            event.accept()
        else:
            event.ignore()

    # --- Private
    def _print(self):
        dialog = QPrintDialog(self)
        if dialog.exec_() != QPrintDialog.Accepted:
            return
        printer = dialog.printer()
        currentView = self.mainView.currentWidget()
        viewPrinter = ViewPrinter(printer, currentView)
        currentView.fitViewsForPrint(viewPrinter)
        viewPrinter.render()

    def _getViewforPane(self, pane_type, pane_view):
        if pane_view in self.model2view:
            view = self.model2view[pane_view]
        else:
            view = PANETYPE2VIEWCLASS[pane_type](model=pane_view, mainwindow=self)
            self.model2view[pane_view] = view
            self.mainView.addWidget(view)
            view.restoreSubviewsSize()
        return view

    def _setTabIndex(self, index):
        if not self.tabBar.count():
            return
        self.tabBar.setCurrentIndex(index)
        self._updateActionsState()
        pane_type = self.model.pane_type(index)
        pane_view = self.model.pane_view(index)
        view = self._getViewforPane(pane_type, pane_view)
        self.mainView.setCurrentWidget(view)
        view.setFocus()

    def _activeView(self):
        paneIndex = self.model.current_pane_index
        return self.model.pane_view(paneIndex)

    def _updateActionsState(self):
        # Updates enable/disable checked/unchecked state of all actions. These state can change
        # under various conditions: main view change, date range type change and when reconciliation
        # mode is toggled

        # Determine what actions are enabled
        view = self._activeView()
        viewType = view.VIEW_TYPE
        isSheet = viewType in {PaneType.NetWorth, PaneType.Profit}
        isTransactionOrEntryTable = viewType in {PaneType.Transaction, PaneType.Account}
        canToggleReconciliation = viewType == PaneType.Account and view.can_toggle_reconciliation_mode

        newItemLabel = {
            PaneType.NetWorth: tr("New Account"),
            PaneType.Profit: tr("New Account"),
            PaneType.Transaction: tr("New Transaction"),
            PaneType.Account: tr("New Transaction"),
            PaneType.Schedule: tr("New Schedule"),
            PaneType.Budget: tr("New Budget"),
            PaneType.GeneralLedger: tr("New Transaction"),
        }.get(viewType, tr("New Item")) # XXX make "New Item" disabled
        self.actionNewItem.setText(newItemLabel)
        self.actionNewAccountGroup.setEnabled(isSheet)
        self.actionMoveDown.setEnabled(isTransactionOrEntryTable)
        self.actionMoveUp.setEnabled(isTransactionOrEntryTable)
        self.actionDuplicateTransaction.setEnabled(isTransactionOrEntryTable)
        self.actionMakeScheduleFromSelected.setEnabled(isTransactionOrEntryTable)
        self.actionReconcileSelected.setEnabled(viewType == PaneType.Account and view.reconciliation_mode)
        self.actionShowNextView.setEnabled(self.model.current_pane_index < self.model.pane_count-1)
        self.actionShowPreviousView.setEnabled(self.model.current_pane_index > 0)
        self.actionShowSelectedAccount.setEnabled(isSheet or isTransactionOrEntryTable)
        self.actionNavigateBack.setEnabled(viewType == PaneType.Account)
        self.actionToggleReconciliationMode.setEnabled(canToggleReconciliation)
        self.actionToggleAccountExclusion.setEnabled(isSheet)

    def _updateUndoActions(self):
        if self.doc.model.can_undo():
            self.actionUndo.setEnabled(True)
            self.actionUndo.setText(tr("Undo {0}").format(self.doc.model.undo_description()))
        else:
            self.actionUndo.setEnabled(False)
            self.actionUndo.setText(tr("Undo"))
        if self.doc.model.can_redo():
            self.actionRedo.setEnabled(True)
            self.actionRedo.setText(tr("Redo {0}").format(self.doc.model.redo_description()))
        else:
            self.actionRedo.setEnabled(False)
            self.actionRedo.setText(tr("Redo"))

    # --- Actions
    # Views
    def showNetWorthTriggered(self):
        self.model.select_pane_of_type(PaneType.NetWorth)

    def showProfitLossTriggered(self):
        self.model.select_pane_of_type(PaneType.Profit)

    def showTransactionsTriggered(self):
        self.model.select_pane_of_type(PaneType.Transaction)

    def showSchedulesTriggered(self):
        self.model.select_pane_of_type(PaneType.Schedule)

    def showBudgetsTriggered(self):
        self.model.select_pane_of_type(PaneType.Budget)

    def showPreviousViewTriggered(self):
        self.model.select_previous_view()

    def showNextViewTriggered(self):
        self.model.select_next_view()

    # Document Edition
    def newItemTriggered(self):
        self.model.new_item()

    def newAccountGroupTriggered(self):
        self.model.new_group()

    def deleteItemTriggered(self):
        self.model.delete_item()

    def editItemTriggered(self):
        self.model.edit_item()

    def moveUpTriggered(self):
        self.model.move_up()

    def moveDownTriggered(self):
        self.model.move_down()

    # Misc
    def closeTabTriggered(self):
        self.model.close_pane(self.model.current_pane_index)

    def navigateBackTriggered(self):
        self.model.navigate_back()

    def jumpToAccountTriggered(self):
        self.model.jump_to_account()

    def makeScheduleFromSelectedTriggered(self):
        self.model.make_schedule_from_selected()

    def reconcileSelectedTriggered(self):
        self._activeView().etable.toggle_reconciled()

    def toggleReconciliationModeTriggered(self):
        self._activeView().toggle_reconciliation_mode()
        self._updateActionsState()

    def toggleAccountExclusionTriggered(self):
        viewType = self.model.pane_type(self.model.current_pane_index)
        if viewType in {PaneType.NetWorth, PaneType.Profit}:
            self._activeView().sheet.toggle_excluded()

    def toggleGraphTriggered(self):
        self.model.toggle_area_visibility(PaneArea.BottomGraph)

    def togglePieChartTriggered(self):
        self.model.toggle_area_visibility(PaneArea.RightChart)

    def columnsVisibilityButtonClicked(self):
        items = self.model.column_menu_items()
        if not items:
            return
        menu = QMenu()
        for i, (display, marked) in enumerate(items):
            action = menu.addAction(display)
            action.setCheckable(True)
            action.setChecked(marked)
            action.setData(i)
            action.triggered.connect(self.columnsMenuItemWasClicked)
        self._columnMenuHolder = menu # we need to hold a reference to it while it popups
        button = self.columnsVisibilityButton
        menu.popup(button.parentWidget().mapToGlobal(button.geometry().topLeft()))

    def columnsMenuItemWasClicked(self):
        action = self.sender()
        if action is not None:
            index = action.data()
            self.model.toggle_column_menu_item(index)

    def checkForUpdateTriggered(self):
        QProcess.execute('updater.exe', ['/checknow'])

    def aboutTriggered(self):
        self.app.showAboutBox()

    def openDebugLogTriggered(self):
        debugLogPath = op.join(getAppData(), 'debug.log')
        url = QUrl.fromLocalFile(debugLogPath)
        QDesktopServices.openUrl(url)

    def importDocument(self):
        title = tr("Select a document to import")
        filters = tr("Supported files (*.moneyguru *.ofx *.qfx *.qif *.csv *.txt)")
        docpath, filetype = QFileDialog.getOpenFileName(self.app.mainWindow, title, '', filters)
        # There's a strange glitch under GNOME where, right after the dialog is gone, the main
        # window isn't the active window, but it will become active if we give it enough time. If we
        # start showing the import window before that happens, we'll end up with an import window
        # under the main window, which is bad. Therefore, we process events until this happens. We
        # do this in a big forloop instead of a while to avoid a possible infinite loop.
        for i in range(10000):
            if self.app.mainWindow.isActiveWindow():
                break
            QApplication.processEvents()
        if docpath:
            try:
                self.model.parse_file_for_import(docpath)
            except FileFormatError as e:
                QMessageBox.warning(self.app.mainWindow, tr("Cannot import file"), str(e))

    # --- Other Signals
    def currentTabChanged(self, index):
        self.model.current_pane_index = index
        self._setTabIndex(index)

    def documentPathChanged(self):
        if self.doc.documentPath:
            title = "moneyGuru ({})".format(self.doc.documentPath)
        else:
            title = "moneyGuru"
        self.setWindowTitle(title)

    def tabCloseRequested(self, index):
        self.model.close_pane(index)

    def tabMoved(self, fromIndex, toIndex):
        # We don't refresh panes because tabMoved is apparently now called *during* drag operations.
        # If we start a full pane refresh during a drag operation, we segfault.
        self.model.move_pane(fromIndex, toIndex, refresh_panes=False)

    # --- model --> view
    def change_current_pane(self):
        self._setTabIndex(self.model.current_pane_index)

    def get_panel_view(self, model):
        if isinstance(model, CustomDateRangePanelModel):
            return CustomDateRangePanel(model, self)
        else:
            return ExportPanel(model, self)

    def refresh_panes(self):
        # Always remove the "new tab" tab
        if self.tabBar.count() > 0:
            self.tabBar.removeTab(self.tabBar.count()-1)
        while self.tabBar.count() < self.model.pane_count:
            self.tabBar.addTab('')
        for i in range(self.model.pane_count):
            pane_label = self.model.pane_label(i)
            pane_label = escapeamp(pane_label)
            self.tabBar.setTabText(i, pane_label)
            pane_type = self.model.pane_type(i)
            pane_view = self.model.pane_view(i)
            # Ensure that the view's "view" has been created and bound
            self._getViewforPane(pane_type, pane_view)
            iconname = PANETYPE2ICON.get(pane_type)
            icon = QIcon(QPixmap(':/{0}'.format(iconname))) if iconname else QIcon()
            self.tabBar.setTabIcon(i, icon)
        # It's important that we proceed with tab removal *after* we've completed tab initialization.
        # We're walking on eggshells here. refresh_panes() can be called in multiple situations, one
        # of them is during the opening of a document. When that happens when another document was
        # previously opened, all views' model are uninitalized and don't have their "view" attribute
        # set yet. If we proceed with the setCurrentIndex() call below before _getViewforPane()
        # could be called above, we get a crash.
        if self.tabBar.currentIndex() >= self.model.pane_count:
            # Normally, we don't touch the tabBar index here and wait for change_current_pane,
            # but when we remove tabs, it's possible that currentTabChanged end up being called and
            # then the tab selection is bugged. I tried disconnecting/reconnecting the signal, but
            # this is buggy. So when a selected tab is about to be removed and is out of bounds,
            # we change the selection to the last index in the model. We don't use
            # self.model.current_pane_index because in some cases, it's -1 and prevents this crash
            # preventer from preventing its crash.
            self.tabBar.setCurrentIndex(self.model.pane_count - 1)
        while self.tabBar.count() > self.model.pane_count:
            self.tabBar.removeTab(self.tabBar.count()-1)
        self.tabBar.setTabsClosable(self.model.pane_count > 1)
        # Add the "new tab" tab
        last_tab_index = self.tabBar.addTab('')
        self.tabBar.setTabEnabled(last_tab_index, False)
        newTabButton = QToolButton()
        newTabButton.setText("+")
        newTabButton.clicked.connect(self.model.new_tab)
        self.tabBar.setTabButton(last_tab_index, QTabBar.RightSide, newTabButton)

    def refresh_status_line(self):
        self.statusLabel.setText(self.model.status_line)

    def refresh_undo_actions(self):
        self._updateUndoActions()

    def restore_window_frame(self, frame):
        self.setGeometry(*frame)

    def save_window_frame(self):
        r = self.geometry()
        return (r.x(), r.y(), r.width(), r.height())

    def show_message(self, msg):
        title = tr("Warning")
        QMessageBox.warning(self, title, msg)

    def update_area_visibility(self):
        hidden = self.model.hidden_areas
        graphimg = ':/graph_visibility_{}_16'.format('off' if PaneArea.BottomGraph in hidden else 'on')
        pieimg = ':/piechart_visibility_{}_16'.format('off' if PaneArea.RightChart in hidden else 'on')
        self.graphVisibilityButton.setIcon(QIcon(QPixmap(graphimg)))
        self.piechartVisibilityButton.setIcon(QIcon(QPixmap(pieimg)))

    def view_closed(self, index):
        self.tabBar.removeTab(index)
        self.tabBar.setTabsClosable(self.model.pane_count > 1)
class App(QFrame):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Web Browser by RafaelxFernandes")
        self.setBaseSize(1366, 768)
        self.create_app()

    def create_app(self):
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        # Create tabs
        self.tab_bar = QTabBar(movable=True, tabsClosable=True)
        self.tab_bar.tabCloseRequested.connect(self.close_tab)
        self.tab_bar.tabBarClicked.connect(self.switch_tab)
        self.tab_bar.setDrawBase(False)

        # Keep track of tabs
        self.tab_count = 0
        self.tabs = []

        # Set toolbar buttons
        # Back
        self.back_button = QPushButton("<")
        self.back_button.clicked.connect(self.go_back)

        # Forward
        self.forward_button = QPushButton(">")
        self.forward_button.clicked.connect(self.go_forward)

        # Reload
        self.reload_button = QPushButton("⟲")
        self.reload_button.clicked.connect(self.reload)

        # Create address bar
        self.tool_bar = QWidget()
        self.tool_bar.setObjectName("Toolbar")
        self.tool_bar_layout = QHBoxLayout()
        self.tool_bar.setLayout(self.tool_bar_layout)
        self.address_bar = AddressBar()
        self.address_bar.returnPressed.connect(self.browse_to)

        # New tab button
        self.add_tab_button = QPushButton("+")
        self.add_tab_button.clicked.connect(self.add_tab)

        # Build tool bar
        self.tool_bar_layout.addWidget(self.back_button)
        self.tool_bar_layout.addWidget(self.forward_button)
        self.tool_bar_layout.addWidget(self.reload_button)
        self.tool_bar_layout.addWidget(self.address_bar)
        self.tool_bar_layout.addWidget(self.add_tab_button)

        # Set main view
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        self.layout.addWidget(self.tab_bar)
        self.layout.addWidget(self.tool_bar)
        self.layout.addWidget(self.container)

        # Shortcuts
        # New tab
        self.shortcut_new_tab = QShortcut(QKeySequence("Ctrl+T"), self)
        self.shortcut_new_tab.activated.connect(self.add_tab)

        # Reload
        self.shortcut_reload = QShortcut(QKeySequence("Ctrl+R"), self)
        self.shortcut_reload.activated.connect(self.reload)

        self.setLayout(self.layout)

        self.add_tab()

        self.show()

    def close_tab(self, index):
        # print(index)
        self.tab_bar.removeTab(index)

    def add_tab(self):
        index = self.tab_count

        # Set self.tabs<#> = QWidget
        self.tabs.append(QWidget())
        self.tabs[index].layout = QVBoxLayout()
        self.tabs[index].layout.setContentsMargins(0, 0, 0, 0)

        # For tab switching
        self.tabs[index].setObjectName("Tab" + str(index))

        # Create webview within the tabs top level widget
        self.tabs[index].content = QWebEngineView()
        self.tabs[index].content.load(QUrl.fromUserInput("http://google.com"))

        self.tabs[index].content.titleChanged.connect(
            lambda: self.set_tab_content(index, "title"))
        self.tabs[index].content.iconChanged.connect(
            lambda: self.set_tab_content(index, "icon"))
        self.tabs[index].content.urlChanged.connect(
            lambda: self.set_tab_content(index, "url"))

        # Add webview to tab.layout
        self.tabs[index].layout.addWidget(self.tabs[index].content)

        # Set tab_layout to layout
        self.tabs[index].setLayout(self.tabs[index].layout)

        # Add and set new tabs content to stack widget
        self.container.layout.addWidget(self.tabs[index])
        self.container.layout.setCurrentWidget(self.tabs[index])

        # Create tab on tab_bar, representing this tab,
        # Set tab_data to tab<#> so it knows what self.tabs[#] it needs to control
        self.tab_bar.addTab("New Tab")
        self.tab_bar.setTabData(index, {
            "object": "Tab" + str(index),
            "initial": index
        })
        self.tab_bar.setCurrentIndex(index)

        self.tab_count += 1

    def switch_tab(self, index):
        if (self.tab_bar.tabData(index)):
            tab_data = self.tab_bar.tabData(index)["object"]
            # print("Tab: " + str(tab_data))
            tab_widget = self.findChild(QWidget, tab_data)

            self.container.layout.setCurrentWidget(tab_widget)

            new_url = tab_widget.content.url().toString()
            self.address_bar.setText(new_url)

    def browse_to(self):
        text = self.address_bar.text()

        index = self.tab_bar.currentIndex()
        tab = self.tab_bar.tabData(index)["object"]
        window_view = self.findChild(QWidget, tab).content

        if ("http" not in text):
            if ("." not in text):
                url = "https://www.google.com/search?q=" + text
            else:
                url = "http://" + text
        else:
            url = text

        window_view.load(QUrl.fromUserInput(url))

    def set_tab_content(self, index, type):
        tab_object_name = self.tabs[index].objectName()

        count = 0
        running = True

        current_tab = self.tab_bar.tabData(
            self.tab_bar.currentIndex())["object"]

        if (current_tab == tab_object_name and type == "url"):
            new_url = self.findChild(QWidget,
                                     tab_object_name).content.url().toString()
            self.address_bar.setText(new_url)
            return False

        while running:
            tab_data_name = self.tab_bar.tabData(count)

            if (count >= 99):
                running = False

            if (tab_object_name == tab_data_name["object"]):
                if (type == "title"):
                    new_title = self.findChild(
                        QWidget, tab_object_name).content.title()
                    self.tab_bar.setTabText(count, new_title)
                elif (type == "icon"):
                    new_icon = self.findChild(QWidget,
                                              tab_object_name).content.icon()
                    self.tab_bar.setTabIcon(count, new_icon)

                running = False
            else:
                count += 1

    def go_back(self):
        activate_index = self.tab_bar.currentIndex()
        tab_name = self.tab_bar.tabData(activate_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.back()

    def go_forward(self):
        activate_index = self.tab_bar.currentIndex()
        tab_name = self.tab_bar.tabData(activate_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.forward()

    def reload(self):
        activate_index = self.tab_bar.currentIndex()
        tab_name = self.tab_bar.tabData(activate_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.reload()
class WebBrowser(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('Web Browser')
        self.setBaseSize(1366, 768)
        self.setMinimumSize(1366, 768)
        self.createApp()
        self.setWindowIcon(QIcon('logo.png'))

    def createApp(self):
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        #  TabBar
        self.tabBar = QTabBar(movable=True, tabsClosable=True)
        self.tabBar.tabCloseRequested.connect(self.closeTab)
        self.tabBar.tabBarClicked.connect(self.switchTab)

        # self.tabBar.addTab('Tab 1')
        # self.tabBar.addTab('Tab 2')
        # self.tabBar = QTabWidget()
        # self.tabBar.addTab(QPushButton('Tab 1'), 'First Tab')
        # self.tabBar.addTab(QPushButton('Tab 2'), 'Second Tab')

        self.tabBar.setCurrentIndex(0)  # Which Tab in the row of tabs is active
        self.tabBar.setDrawBase(False)
        self.tabBar.setLayoutDirection(Qt.LeftToRight)
        self.tabBar.setElideMode(Qt.ElideLeft)

        # Create Key shortcuts
        self.shortcutNewTab = QShortcut(QKeySequence('Ctrl+T'), self)
        self.shortcutNewTab.activated.connect(self.addTab)

        self.shortcutReload = QShortcut(QKeySequence('Ctrl+R'), self)
        self.shortcutReload.activated.connect(self.reload)

        # Keep track of tabs
        self.tabCount = 0
        self.tabs = []

        # Create address bar
        self.toolBar = QWidget()
        self.toolBar.setObjectName('toolBar')
        self.toolBarLayout = QHBoxLayout()
        self.addressBar = AddressBar()
        self.addressBar.returnPressed.connect(self.browseToFromAddressBar)

        # New Tab Button
        self.addTabButton = QPushButton('+')
        self.addTabButton.clicked.connect(self.addTab)

        # Set Toolbar Buttons like Back button, Reload etc.
        self.bwdButton = QPushButton('<')
        self.bwdButton.clicked.connect(self.navigateBwd)

        self.fwdButton = QPushButton('>')
        self.fwdButton.clicked.connect(self.navigateFwd)

        self.rldButton = QPushButton('R')
        self.rldButton.clicked.connect(self.reload)

        # Build Toolbar
        self.toolBar.setLayout(self.toolBarLayout)
        self.toolBarLayout.addWidget(self.bwdButton)
        self.toolBarLayout.addWidget(self.fwdButton)
        self.toolBarLayout.addWidget(self.rldButton)
        self.toolBarLayout.addWidget(self.addressBar)
        self.toolBarLayout.addWidget(self.addTabButton)

        #  Set Main View
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        self.layout.addWidget(self.tabBar)
        self.layout.addWidget(self.toolBar)
        self.layout.addWidget(self.container)

        self.setLayout(self.layout)
        self.show()

    def closeTab(self, i):
        self.tabBar.removeTab(i)

    def addTab(self):
        i = self.tabCount

        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setContentMargins(0, 0, 0, 0)

        self.tabs[i].setObjectName('tab' + str(i))

        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput('http://google.com'))

        #  Update the title of the Tab when the URL changes
        self.tabs[i].content.titleChanged.connect(lambda : self.setTabContent(i, 'Title'))
        self.tabs[i].content.iconChanged.connect(lambda : self.setTabContent(i, 'Icon'))
        self.tabs[i].content.urlChanged.connect(lambda: self.setTabContent(i, 'Url'))

        #  Add webview to tabs layout
        self.tabs[i].splitview = QSplitter()
        self.tabs[i].splitview.setOrientation(Qt.Vertical)
        self.tabs[i].layout.addWidget(self.tabs[i].splitview)

        self.tabs[i].splitview.addWidget(self.tabs[i].content)

        #  Set top level tab in list to Layout
        self.tabs.setLayout(self.tabs[i].layout)

        # Add tab to top level stacked widget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        # Set the tab at the top of the screen
        self.tabBar.addTab('New Tab')
        self.tabBar.setTabData(i, {'object': 'tab' + str(i), 'initial': i})
        self.tabBar.setCurrentIndex(i)

        self.tabCount += 1

    def switchTab(self, i):
        if self.tabBar.tabData(i):
            tabData = self.tabBar.tabData(i)
            tab_widget = self.findChild(QWidget, tabData)
            self.container.layout.setCurrentWidget(tab_widget)

            new_url = tab_widget.url().toString()
            self.addressBar.setText(new_url)

    def browseToFromAddressBar(self):
        txtLine = self.addressBar.text()

        i = self.tabBar.currentIndex()
        tabData = self.tabBar.tabData(i)
        tab_content = self.findChild(QWidget, tabData).content

        if 'http' not in txtLine:
            if '.' not in txtLine:
                url = 'https://www.google.com/search?q=' + str(txtLine)
            else:
                url = 'http://' + str(txtLine)
        else:
            url = txtLine
        tab_content.load(QUrl.fromUserInput(url))

    def setTabContent(self, i, type):
        tab_name = self.tabs[i].objectName()
        count = 0
        running = True
        current_tab = self.tabBar.tabData(self.tabBar.currentIndex())['object']

        if current_tab == tab_name and type == 'Url':
            new_url = self.findChild(QWidget, tab_name).content.url().toString()
            self.addressBar.setText(new_url)
            return False

        while running:
            tab_data_name = self.tabBar.tabData(count)

            if count > 99:
                running = False

            if tab_name == tab_data_name['object']:
                if type == 'Title':
                    newTitle = self.findChild(QWidget, tab_name).content.title()
                    self.tabBar.setTabText(count, newTitle)
                elif type == 'Icon':
                    newIcon = self.findChild(QWidget, tab_name).content.icon()
                    self.tabBar.setTabIcon(count, newIcon)

                running = False
            else:
                count += 1

    def navigateBwd(self):
        activeIndex = self.tabBar.currentIndex()
        tab_name = self.tabBar.tabData(activeIndex)['object']
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.back()

    def navigateFwd(self):
        activeIndex = self.tabBar.currentIndex()
        tab_name = self.tabBar.tabData(activeIndex)['object']
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.forward()

    def reload(self):
        activeIndex = self.tabBar.currentIndex()
        tab_name = self.tabBar.tabData(activeIndex)['object']
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.reload()
Exemple #5
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Web Browser")
        self.CreateApp()
        self.setMaximumSize(1366, 768)

    def CreateApp(self):
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        # Create Tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.CloseTab)
        self.tabbar.tabBarClicked.connect(self.SwitchTab)

        # self.tabbar.addTab("Tab 1")
        # self.tabbar.addTab("Tab 2")

        self.tabbar.setCurrentIndex(0)

        # Keep Track Of Tabs
        self.tabCount = 0
        self.tabs = []

        # Create Address Bar
        self.Toolbar = QWidget()
        self.ToolbarLayout = QHBoxLayout()
        self.addressbar = AddressBar()

        self.Toolbar.setLayout(self.ToolbarLayout)
        self.ToolbarLayout.addWidget(self.addressbar)

        self.AddTabButton = QPushButton("+")
        self.addressbar.returnPressed.connect(self.BrowseTo)
        self.AddTabButton.clicked.connect(self.AddTab)

        self.ToolbarLayout.addWidget(self.AddTabButton)

        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.Toolbar)
        self.layout.addWidget(self.container)

        self.setLayout(self.layout)

        self.AddTab()

        self.show()

    def CloseTab(self, i):
        self.tabbar.removeTab(i)

    def AddTab(self):
        i = self.tabCount

        # set self.tabs<#> = Qwidget
        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setContentsMargins(0, 0, 0, 0)

        # For Tab Switching
        self.tabs[i].setObjectName("tab" + str(i))

        # Create  WebView within the tabs top level widget
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("https://google.com"))

        self.tabs[i].content.titleChanged.connect(
            lambda: self.setTabContent(i, "title"))
        self.tabs[i].content.iconChanged.connect(
            lambda: self.setTabContent(i, "icon"))

        # add widget to tab.layout
        self.tabs[i].layout.addWidget(self.tabs[i].content)

        # Add tabLayout to .layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        # Add and Set new Tabs content to the stack widget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        # create tab on tabbar, repreasenting this tab
        # set tabData to tab<#> So it knows what self.tabs[#] it needs  to control
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {object: "tab" + str(i), "initial": i})
        self.tabbar.setCurrentIndex(i)

        self.tabCount += 1

    def SwitchTab(self, i):
        tab_data = self.tabbar.tabData(i)

        tab_content = self.findChild(QWidget, tab_data)
        self.container.layout.setCurrentWidget(tab_content)

    def BrowseTo(self):
        text = self.addressbar.text()
        i = self.tabbar.currentIndex()
        tab = self.tabbar.tabData(i)
        wv = self.findChild(QWidget, tab).content

        if "http" not in text:
            if "." not in text:
                url = "https://google.com/?q=" + text
            else:
                url = "https://" + text
        else:
            url = text

        wv.load(QUrl.fromUserInput(url))

    def SetTabContent(self, i, type):
        tab_Name = self.tabs[i].objectName()

        count = 0
        running = True

        while running:
            tab_data_name = self.tabbar.tabData(count)

            if count >= 99:
                running = False

            if tab_Name == tab_data_name["object"]:
                if type == "title":
                    newTitle = self.findChild(QWidget,
                                              tab_Name).content.title()
                    self.tabbar.setTabText(count, newTitle)
                elif type == "icon":
                    newIcon = self.findChild(QWidget, tab_Name).content.icon()
                    self.tabbar.setTabIcon(count, newIcon)

                running = False
            else:
                count += 1
Exemple #6
0
class App(QFrame):

    def __init__(self):
        super().__init__()
        self.setWindowTitle("Web Browser")
        self.setMinimumSize(1366, 768)
        self.CreateApp()

    def CreateApp(self):
        #Create the Main Layout and Spacing
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        #Create the Tab Bar
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.CloseTab)
        self.tabbar.tabBarClicked.connect(self.SwitchTab)
        self.tabbar.setCurrentIndex(0)
        self.tabbar.setDrawBase(False)
        self.tabbar.setLayoutDirection(Qt.LeftToRight)
        self.tabbar.setElideMode(Qt.ElideLeft)

        # Keyboard shortcuts
        self.shortcutNewTab = QShortcut(QKeySequence("Ctrl+T"), self)
        self.shortcutNewTab.activated.connect(self.AddTab)

        self.shortcutReload = QShortcut(QKeySequence("Ctrl+R"), self)
        self.shortcutReload.activated.connect(self.ReloadPage)

        #Keep track of tabs
        self.tabCount = 0
        self.tabs = []

        #Creating the Address Bar for the Browswer
        self.Toolbar = QWidget()
        self.Toolbar.setObjectName("Toolbar")
        self.ToolbarLayout = QHBoxLayout()
        self.addressbar = AddressBar()
        self.AddTabButton = QPushButton("+")

        #Connect AddressBar with Button Signals
        self.addressbar.returnPressed.connect(self.BrowseTo)
        self.AddTabButton.clicked.connect(self.AddTab)

        #Set Toolbar Buttons
        self.BackButton = QPushButton("<")
        self.BackButton.clicked.connect(self.GoBack)

        self.ForwardButton = QPushButton(">")
        self.ForwardButton.clicked.connect(self.GoForward)

        self.ReloadButton = QPushButton("⟲")
        self.ReloadButton.clicked.connect(self.ReloadPage)

        #Build the TOolbar
        self.Toolbar.setLayout(self.ToolbarLayout)
        self.ToolbarLayout.addWidget(self.BackButton)
        self.ToolbarLayout.addWidget(self.ForwardButton)
        self.ToolbarLayout.addWidget(self.ReloadButton)
        self.ToolbarLayout.addWidget(self.addressbar)
        self.ToolbarLayout.addWidget(self.AddTabButton)

        #Set Main View
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        #Add Widgets to the Layout
        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.Toolbar)
        self.layout.addWidget(self.container)
        self.setLayout(self.layout)

        self.AddTab()
        self.show()

    def CloseTab(self, i):
        self.tabbar.removeTab(i)

    def AddTab(self):
        i = self.tabCount

        # Set self.tabs = QWidget
        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setContentsMargins(0, 0, 0, 0)

        # For Tab Switching
        self.tabs[i].setObjectName("tab" + str(i))

        # Open Webview
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("http://www.google.com"))

        self.tabs[i].content.titleChanged.connect(lambda: self.SetTabContent(i, "title"))
        self.tabs[i].content.iconChanged.connect(lambda: self.SetTabContent(i, "icon"))
        self.tabs[i].content.urlChanged.connect(lambda: self.SetTabContent(i, "url"))

        # Add Widget to Tabs Layout
        self.tabs[i].layout.addWidget(self.tabs[i].content)

        #Set Top Level Tab from [] to Layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        #Add tab to Top Level Stack Widgets
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        #Set the Tab at the Top of the Screen
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {"object": "tab" + str(i), "initial": i})
        self.tabbar.setCurrentIndex(i)

        #Increase the Tab Count
        self.tabCount += 1

    def SwitchTab(self, i):
        if self.tabbar.tabData(i):
            tab_data = self.tabbar.tabData(i)["object"]
            tab_content = self.findChild(QWidget, tab_data)
            self.container.layout.setCurrentWidget(tab_content)
            new_url = tab_content.content.url().toString()
            self.addressbar.setText(new_url)

    def BrowseTo(self):
        text = self.addressbar.text()
        i = self.tabbar.currentIndex()
        tab = self.tabbar.tabData(i)["object"]
        webview = self.findChild(QWidget, tab).content

        if "http" not in text:
            if "." not in text:
                url = "https://www.google.com/search?q=" + text
            else:
                url = "http://" + text
        else:
            url = text

        webview.load(QUrl.fromUserInput(url))

    def SetTabContent(self, i, type):
        tab_name = self.tabs[i].objectName()

        count = 0
        running = True

        current_tab = self.tabbar.tabData(self.tabbar.currentIndex())["object"]

        if current_tab == tab_name and type == "url":
            new_url = self.findChild(QWidget, tab_name).content.url().toString()
            self.addressbar.setText(new_url)
            return False

        while running:
            tab_data_name = self.tabbar.tabData(count)

            if count >= 99:
                running = False

            if tab_name == tab_data_name["object"]:
                if type == "title":
                    newTitle = self.findChild(QWidget, tab_name).content.title()
                    self.tabbar.setTabText(count, newTitle)
                elif type == "icon":
                    newIcon = self.findChild(QWidget, tab_name).content.icon()
                    self.tabbar.setTabIcon(count, newIcon)
                running = False
            else:
                count += 1

    def GoBack(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.back()

    def GoForward(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.forward()


    def ReloadPage(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.reload()
Exemple #7
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.title = "Eden Browser"
        self.CreateWindow()

        # Set some default properties for the window
        self.setWindowTitle(self.title)
        self.setBaseSize(1366, 768)
        self.setMinimumSize(1366, 768)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setWindowIcon(QIcon('resources/icons/icon.png'))

        # AddressBar searches go through:
        self.SearchProvider = "https://www.google.ca/?gfe_rd=cr&ei=rnd_WPvfEqnM8AeSk4Ng#q="

        self.center()
        QWebEngineSettings.LocalContentCanAccessFileUrls = True

    def CreateWindow(self):
        # Load javascripts:
        file = QFile()
        file.setFileName("resources/scripts/jquery.min.js")
        file.open(QIODevice.ReadOnly)
        self.jquery = file.readAll()
        self.jquery.append("\nvar qt = { 'jQuery': jQuery.noConflict(true) };")
        file.close()

        file = QFile()
        file.setFileName("resources/scripts/inspector.js")
        file.open(QIODevice.ReadOnly)
        self.inspector = file.readAll()
        file.close()

        # Main window layout
        self.layout = QVBoxLayout()
        self.setObjectName("BrowserWindow")

        # No margins around our main content
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0,0,0,0)

        # Shortcuts
        # NEw tab
        self.shortcutNewTab = QShortcut(QKeySequence("Ctrl+T"), self)
        self.shortcutNewTab.activated.connect(self.AddTab)

        # Refresh
        self.shortcutRefresh = QShortcut(QKeySequence("Ctrl+R"), self)
        self.shortcutRefresh.activated.connect(self.refresh)
        self.shortcutRefresh2 = QShortcut(QKeySequence("F5"), self)
        self.shortcutRefresh2.activated.connect(self.refresh)
        self.shortcutRefresh3 = QShortcut(QKeySequence("Ctrl+F5"), self)
        self.shortcutRefresh3.activated.connect(self.refreshNoCache)

        # Open Devtools
        self.shortcutDevTools = QShortcut(QKeySequence("Ctrl+Shift+I"), self)
        self.shortcutDevTools.activated.connect(self.openDevTools)

        # Tabcount
        self.tabCount = 0

        # Create New Tab
        self.AddTabButton = QPushButton()
        self.AddTabButton.setIcon(QIcon("resources/icons/ic_add_black_24px.svg"))
        self.AddTabButton.clicked.connect(self.AddTab)

        # Create TabBar, movable and closable
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.setObjectName("TabBar")
        self.tabbar.setExpanding(False)
        self.tabbar.setDrawBase(False)
        self.tabbar.setElideMode(Qt.ElideLeft)

        # Create custom WindowBorder
        self.windowBorder = QWidget()
        self.windowBorderLayout = QHBoxLayout()
        self.windowBorder.setLayout(self.windowBorderLayout)

        # Close button
        self.CloseBrowserButton = QPushButton()
        self.CloseBrowserButton.setIcon(QIcon('resources/icons/ic_clear_black_24px.svg'))
        self.CloseBrowserButton.setFixedWidth(48)

        # Maximize Button
        self.MaximizeBrowserButton = QPushButton()
        self.MaximizeBrowserButton.setIcon(QIcon('resources/icons/ic_aspect_ratio_black_24px.svg'))
        self.MaximizeBrowserButton.setFixedWidth(48)

        # Minimize button
        self.MinimizeBrowserButton = QPushButton()
        self.MinimizeBrowserButton.setIcon(QIcon('resources/icons/ic_remove_black_24px.svg'))
        self.MinimizeBrowserButton.setFixedWidth(48)

        # WindowControl buttons signal->slot()
        self.MinimizeBrowserButton.clicked.connect(self.min)
        self.MaximizeBrowserButton.clicked.connect(self.maximize)
        self.CloseBrowserButton.clicked.connect(self.quit)

        # Add TabBar to top of Window
        self.windowBorderLayout.addWidget(self.tabbar)

        # So that we can drag the window on non-tab areas
        self.windowBorderLayout.addStretch()

        # Add Window controls
        self.windowBorderLayout.addWidget(self.MinimizeBrowserButton)
        self.windowBorderLayout.addWidget(self.MaximizeBrowserButton)
        self.windowBorderLayout.addWidget(self.CloseBrowserButton)
        self.windowBorderLayout.setSpacing(0)
        self.windowBorderLayout.setContentsMargins(0, 0, 0, 0)

        # Hook into essential events
        self.tabbar.tabBarClicked.connect(self.SwitchTabs)
        self.tabbar.tabCloseRequested.connect(self.CloseTab)

        # Create list to house each tabs widget in
        self.tabs = []



        # Add Back Button
        self.BackButton = QPushButton()
        self.back = QIcon("resources/icons/ic_keyboard_arrow_left_black_24px.svg")
        self.BackButton.setIcon(self.back)
        self.BackButton.setEnabled(False)
        self.BackButton.clicked.connect(self.goBack)

        # Add Forward Button
        self.ForwardButton = QPushButton()
        self.forward = QIcon("resources/icons/ic_keyboard_arrow_right_black_24px.svg")
        self.ForwardButton.setIcon(self.forward)
        self.ForwardButton.setEnabled(False)
        self.ForwardButton.clicked.connect(self.goForward)

        # Add Refresh Button
        self.RefreshButton = QPushButton()
        self.refreshIcon = QIcon("resources/icons/ic_refresh_black_24px.svg")
        self.RefreshButton.setIcon(self.refreshIcon)
        self.RefreshButton.clicked.connect(self.refresh)

        # Add Menu Button
        self.MenuButton = QPushButton()
        self.MenuButton.setIcon(QIcon("resources/icons/ic_more_vert_black_24px.svg"))

        # Create address bar.  Rig it to BrowseTo so we can actually load the sites
        self.AddressBar = AddressBar()
        self.AddressBar.returnPressed.connect(self.BrowseTo)

        # This is teh main control bar
        self.tabControlWidget = QWidget()
        self.tabControls = QHBoxLayout()
        self.tabControlWidget.setObjectName("toolbar")

        # Fill the control bar
        self.tabControls.addWidget(self.BackButton)
        self.tabControls.addWidget(self.ForwardButton)
        self.tabControls.addWidget(self.RefreshButton)
        self.tabControls.addWidget(self.AddressBar)
        self.tabControls.addWidget(self.AddTabButton)
        self.tabControls.addWidget(self.MenuButton)
        self.tabControlWidget.setLayout(self.tabControls)
        self.tabControlWidget.setObjectName("TabControls")

        # Create container that will hold the webviews:
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        # Set the main window structure
        self.layout.addWidget(self.windowBorder)
        self.layout.addWidget(self.tabControlWidget)
        self.layout.addWidget(self.container)

        # Set main windows layout = our top level QVBOX
        self.setLayout(self.layout)

        # Open one tab by default
        self.AddTab()

    def CloseTab(self, i):
        # Remove tab from tab bar, also delete [tab<i>]
        self.tabbar.removeTab(i)
        del self.tabs[i]
        if len(self.tabs) == 0:
            self.AddTab()


    def AddTab(self):
        # If there aren't tabs, keep at 0, otherwise increase by 1
        if len(self.tabs):
            self.tabCount += 1
        i = self.tabCount

        # Add our tab object to self.tabs which is []
        self.tabs.append(QWidget())
        self.tabs[i].count = self.tabCount

        # Set the tabs VBOx layout
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setObjectName("TabView")

        # Create webview of our tab
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].page = self.tabs[i].content.page()
        self.tabs[i].content.setAccessibleName("tab")
        self.tabs[i].content.setObjectName("tab1")

        # On tab creation load google
        #url = QUrl("eden://")
        url = os.getcwd() + r'\resources\pages' + '\\new-tab.html'
        self.tabs[i].content.load(QUrl.fromUserInput(url))


        self.tabs[i].splitView = QSplitter()
        self.tabs[i].splitView.setOrientation(Qt.Vertical)
        self.tabs[i].splitView.addWidget(self.tabs[i].content)


        # Add VBox layout to our tab object, and add content into the tabs layout (VBOX)
        self.tabs[i].layout.addWidget(self.tabs[i].splitView)
        self.tabs[i].setLayout(self.tabs[i].layout)
        self.container.layout.addWidget(self.tabs[i])

        # When the URL changes, set the address bar accordingly
        self.tabs[i].content.urlChanged.connect(lambda: self.SetAddressBar(i))
        self.tabs[i].content.titleChanged.connect(lambda: self.setTabTitle(i))
        self.tabs[i].content.iconChanged.connect(lambda: self.setTabIcon(i))

        self.tabs[i].connected = True
        self.tabs[i].history = []

        # Remove outer margins
        self.tabs[i].layout.setContentsMargins(0,0,0,0)

        # Add the tab to the top tab bar
        self.tabbar.addTab(self.tabs[i].content.title())
        self.tabbar.setTabData(i, "tab"+str(i))
        self.tabs[i].setObjectName("tab"+str(i))

        # On load finished, set the tabs title
        self.tabs[i].content.loadFinished.connect(lambda: self.setTabTitle(i))
        self.tabs[i].content.loadFinished.connect(lambda: self.RunScripts(i))

        # Make this new tab the current (active) one
        self.tabbar.setCurrentIndex(i)
        self.container.layout.setCurrentWidget(self.tabs[i])
        #print("back?", self.tabs[i].content.canGoBack)

        self.AddressBar.selectAll()

    def SwitchTabs(self, i):
        # Set the current tab to the container stacked widget.
        # container = current tab (from our tab list) []
        tab = self.tabbar.tabData(i)
        self.container.layout.setCurrentWidget(self.findChild(QWidget, tab))
        self.SetAddressBar(i)
        print(self.tabs[i].content.nativeParentWidget())

    def goBack(self):
        # Go back in history
        i = self.tabbar.currentIndex()
        self.tabs[i].content.back()
        self.ForwardButton.setEnabled(True)

    def goForward(self):
        # Go forward in history if possible
        i = self.tabbar.currentIndex()
        self.tabs[i].content.forward()

    def refresh(self):
        # Reload current webview
        i = self.tabbar.currentIndex()
        self.tabs[i].content.reload()

    def refreshNoCache(self):
        i = self.tabbar.currentIndex()
        self.tabs[i].content.reloadAndBypassCache()

    def getDevToolsList(self, data):
        dev = data
        dev_list = json.loads(dev)


        count = 0
        name = self.tabbar.tabData(self.tabbar.currentIndex())

        for item in reversed(dev_list):
            print(self.findChild(QWidget, name).page.url().toString())
            if item["url"] == self.findChild(QWidget, name).page.url().toString():
                print("yes")
                devUrl = item["devtoolsFrontendUrl"]
                self.findChild(QWidget, name).devtools.load(QUrl.fromUserInput("http://localhost:667" + devUrl))



    def printHtml(self, result):
        result.toPlainText(self.getDevToolsList)

    def openDevTools(self):
        i = self.tabbar.currentIndex()
        name = self.tabbar.tabData(self.tabbar.currentIndex())
        self.findChild(QWidget, name).devtoolsContainer = QWidget()
        self.findChild(QWidget, name).devtoolsLayout = QVBoxLayout()
        self.findChild(QWidget, name).devtools = QWebEngineView()
        self.findChild(QWidget, name).devtools.load(QUrl.fromUserInput("http://localhost:667"))
        self.findChild(QWidget, name).devtoolsQuit = QPushButton()
        self.findChild(QWidget, name).devtoolsQuit.setIcon(QIcon('resources/icons/ic_clear_black_24px.svg'))
        self.findChild(QWidget, name).devtoolsQuit.setFixedWidth(24)
        self.findChild(QWidget, name).devtoolsQuit.setFixedHeight(24)


        current_page = QWebEngineView()
        current_page.load(QUrl.fromUserInput("http://localhost:667/json/list"))
        current_page.loadFinished.connect(lambda: self.printHtml(current_page.page()))


        self.findChild(QWidget, name).devtoolsLayout.setContentsMargins(0,0,0,0)
        self.findChild(QWidget, name).content.page().runJavaScript(str(self.jquery))
        title = self.findChild(QWidget, name).content.page().title()
        durl = self.findChild(QWidget, name).content.page().url().toString()


        self.findChild(QWidget, name).devtoolsQuit.clicked.connect(self.quitDevtools)

        self.findChild(QWidget, name).devtoolsContainer.setLayout(self.findChild(QWidget, name).devtoolsLayout)
        self.findChild(QWidget, name).devtoolsLayout.addWidget(self.findChild(QWidget, name).devtoolsQuit)
        self.findChild(QWidget, name).devtoolsLayout.addWidget(self.findChild(QWidget, name).devtools)
        self.findChild(QWidget, name).splitView.addWidget(self.findChild(QWidget, name).devtoolsContainer)

    def quitDevtools(self):
        i = self.tabbar.currentIndex()
        activeTab = self.findChild(QWidget, self.tabbar.tabData(i))
        activeTab.devtoolsContainer.setParent(None)
        activeTab.devtoolsContainer.destroy()


    def SetAddressBar(self, i):
        # Get the current tabs index, and set the address bar to its title.toString()
        tab = self.tabbar.tabData(i)
        if self.findChild(QWidget, tab).connected == True:
            url = QUrl(self.findChild(QWidget, tab).content.url()).toString()
            self.AddressBar.setText(url)


        if len(self.tabs[i].history):
            self.BackButton.setEnabled(True)
        self.tabs[i].history.append(url)

    def setTabIcon(self, i):
        tab = self.tabbar.tabData(i)
        icon = self.findChild(QWidget, tab).content.page().icon()
        self.tabbar.setTabIcon(i, icon)

    def BrowseTo(self):
        # Get url from address bar
        url = self.AddressBar.text()
        name = self.tabbar.tabData(self.tabbar.currentIndex())
        activeTab = self.findChild(QWidget, name)
        currentTab = self.tabbar.currentIndex()

        if "eden://" in url:
            pages = "pages"
            page = url.split("://")[1]

            url = os.getcwd() + r'\resources\pages' + '\\' + page + ".html"

            file = QFile(url)
            local_page = file.open(QIODevice.ReadOnly)
            page_content = QTextStream(file)
            activeTab.connected = False

            activeTab.content.urlChanged.disconnect()
            activeTab.content.load(QUrl.fromUserInput(url))

        elif " " in url:
            url = QUrl.fromUserInput(self.SearchProvider + url)

            # Format correctly because were all lazy
            if activeTab.connected == False:
                activeTab.content.urlChanged.connect(lambda: self.SetAddressBar(currentTab))
        elif "http" not in url or "file://" not in url:
            FormattedUrl = "http://"
            OldUrl = url
            url = QUrl.fromUserInput(FormattedUrl + OldUrl)
            if activeTab.connected == False:
                activeTab.content.urlChanged.connect(lambda: self.SetAddressBar(currentTab))
            try:
                activeTab.content.load(url)
            except:
                print("Unexpected error:", sys.exc_info()[0])
                raise

    def RunScripts(self, i):
        addFB = "$('head').prepend('<script type=\"text/javascript\" \
            src=\"https://getfirebug.com/firebug-lite.js\"> \
            {overrideConsole: false,\
            startInNewWindow: true,\
            startOpened: true}\
            </script>');"
        self.tabs[i].content.page().runJavaScript(str(self.jquery))
        self.tabs[i].content.page().runJavaScript(addFB)


    def setTabTitle(self, i):
        # Get current tabs webviews title, and set the actual tab item
        # on the tabbar to the correct title


        tab = self.tabbar.tabData(i)
        icon = self.findChild(QWidget, tab).content.page().title()
        self.tabbar.setTabText(i, icon)

    def getFavicon(self, i):
        url = self.tabs[i].content.url().toString()
        faviconUrl = "http://www.google.com/s2/favicons?domain=" + url
        return faviconUrl

        # center

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def mousePressEvent(self, event):
        self.oldPos = event.globalPos()

    def mouseMoveEvent(self, event):
        delta = QPoint(event.globalPos() - self.oldPos)
        self.move(self.x() + delta.x(), self.y() + delta.y())
        self.oldPos = event.globalPos()

    def quit(self):
        self.destroy()

    def maximize(self):
        if self.isMaximized():
            self.showNormal()
        else:
            self.showMaximized()

    def min(self):
        self.showMinimized()
Exemple #8
0
class ImportWindow(QWidget):
    def __init__(self, mainwindow):
        QWidget.__init__(self, mainwindow, Qt.Window)
        self._setupUi()
        self.doc = mainwindow.doc
        self.model = mainwindow.model.import_window
        self.swapOptionsComboBox = ComboboxModel(model=self.model.swap_type_list, view=self.swapOptionsComboBoxView)
        self.table = ImportTable(model=self.model.import_table, view=self.tableView)
        self.model.view = self
        self._setupColumns() # Can only be done after the model has been connected

        self.tabView.tabCloseRequested.connect(self.tabCloseRequested)
        self.tabView.currentChanged.connect(self.currentTabChanged)
        self.targetAccountComboBox.currentIndexChanged.connect(self.targetAccountChanged)
        self.importButton.clicked.connect(self.importClicked)
        self.swapButton.clicked.connect(self.swapClicked)

    def _setupUi(self):
        self.setWindowTitle(tr("Import"))
        self.resize(557, 407)
        self.verticalLayout = QVBoxLayout(self)
        self.tabView = QTabBar(self)
        self.tabView.setMinimumSize(QtCore.QSize(0, 20))
        self.verticalLayout.addWidget(self.tabView)
        self.targetAccountLayout = QHBoxLayout()
        self.targetAccountLabel = QLabel(tr("Target Account:"))
        self.targetAccountLayout.addWidget(self.targetAccountLabel)
        self.targetAccountComboBox = QComboBox(self)
        self.targetAccountComboBox.setMinimumSize(QtCore.QSize(150, 0))
        self.targetAccountLayout.addWidget(self.targetAccountComboBox)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.targetAccountLayout.addItem(spacerItem)
        self.groupBox = QGroupBox(tr("Are some fields wrong? Fix them!"))
        self.gridLayout = QGridLayout(self.groupBox)
        self.swapOptionsComboBoxView = QComboBox(self.groupBox)
        self.gridLayout.addWidget(self.swapOptionsComboBoxView, 0, 0, 1, 2)
        self.applyToAllCheckBox = QCheckBox(tr("Apply to all accounts"))
        self.gridLayout.addWidget(self.applyToAllCheckBox, 1, 0, 1, 1)
        self.swapButton = QPushButton(tr("Fix"))
        self.gridLayout.addWidget(self.swapButton, 1, 1, 1, 1)
        self.targetAccountLayout.addWidget(self.groupBox)
        self.verticalLayout.addLayout(self.targetAccountLayout)
        self.tableView = TableView(self)
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableView.setDragEnabled(True)
        self.tableView.setDragDropMode(QAbstractItemView.InternalMove)
        self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.horizontalHeader().setHighlightSections(False)
        self.tableView.horizontalHeader().setMinimumSectionSize(18)
        self.tableView.verticalHeader().setVisible(False)
        self.tableView.verticalHeader().setDefaultSectionSize(18)
        self.verticalLayout.addWidget(self.tableView)
        self.horizontalLayout = QHBoxLayout()
        spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)
        self.importButton = QPushButton(tr("Import"))
        self.horizontalLayout.addWidget(self.importButton)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.tabView.setTabsClosable(True)
        self.tabView.setDrawBase(False)
        self.tabView.setDocumentMode(True)
        self.tabView.setUsesScrollButtons(True)

    def _setupColumns(self):
        # Can't set widget alignment in a layout in the Designer
        l = self.targetAccountLayout
        l.setAlignment(self.targetAccountLabel, Qt.AlignTop)
        l.setAlignment(self.targetAccountComboBox, Qt.AlignTop)

    # --- Event Handlers
    def currentTabChanged(self, index):
        self.model.selected_pane_index = index

    def importClicked(self):
        self.model.import_selected_pane()

    def swapClicked(self):
        applyToAll = self.applyToAllCheckBox.isChecked()
        apply = ActionSelectionOptions.ApplyToAll if applyToAll else ActionSelectionOptions.ApplyToPane
        self.model.perform_swap(apply=apply)

    def tabCloseRequested(self, index):
        self.model.close_pane(index)
        self.tabView.removeTab(index)

    def targetAccountChanged(self, index):
        self.model.selected_target_account_index = index
        self.table.updateColumnsVisibility()

    # --- model --> view
    def close(self):
        self.hide()

    def close_selected_tab(self):
        self.tabView.removeTab(self.tabView.currentIndex())

    def refresh_target_accounts(self):
        # We disconnect the combobox because we don't want the clear() call to set the selected
        # target index in the model.
        self.targetAccountComboBox.currentIndexChanged.disconnect(self.targetAccountChanged)
        self.targetAccountComboBox.clear()
        self.targetAccountComboBox.addItems(self.model.target_account_names)
        self.targetAccountComboBox.currentIndexChanged.connect(self.targetAccountChanged)

    def refresh_tabs(self):
        while self.tabView.count():
            self.tabView.removeTab(0)
        for pane in self.model.panes:
            self.tabView.addTab(pane.name)

    def set_swap_button_enabled(self, enabled):
        self.swapButton.setEnabled(enabled)

    def show(self):
        # For non-modal dialogs, show() is not enough to bring the window at the forefront, we have
        # to call raise() as well
        QWidget.showNormal(self)
        QWidget.raise_(self)
        QWidget.activateWindow(self)

    def update_selected_pane(self):
        index = self.model.selected_pane_index
        if index != self.tabView.currentIndex(): # this prevents infinite loops
            self.tabView.setCurrentIndex(index)
        self.targetAccountComboBox.setCurrentIndex(self.model.selected_target_account_index)
        self.table.updateColumnsVisibility()
Exemple #9
0
class App(QFrame):
    def __init__(self):
        super().__init__()  # Initializing the parent class
        self.setWindowTitle('Web Browser')  # Setting Window Title
        self.setBaseSize(1366, 768)
        self.setWindowIcon(QIcon("download.png"))
        self.setMinimumSize(1366, 768)
        self.CreateApp()  # calling the createApp function from initialization

    def CreateApp(self):

        self.layout = QVBoxLayout()  # using vertical Box layout
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(
            0, 0, 0, 0)  #To set margins equal to zero from all side

        # Create Tabs

        self.tabbar = QTabBar(movable=True, tabsClosable=True)  # adding TabBar
        #  movable means we can move the tab
        # tabsClosable means the tabs should close if the cross button is pressed
        self.tabbar.tabCloseRequested.connect(
            self.closeTab
        )  #It passes the argument of index number of the tab of which close button is been clicked.
        self.tabbar.tabBarClicked.connect(self.switchtab)
        # The basic difference between QTabWidget and QTabBar
        # QtabWidget associates a QWidget to # Here we style all the buttons each tab of QTabBar, So widget management when switching from one
        # tab to another is already done by the QtabWidget Class.

        #QtabBar is only a tab bar. You can do everything you want when switching from one tab to another

        # The best advantage is that QTabWidget combines QTabBar and QstackedWidget behaviours.

        self.tabbar.setCurrentIndex(0)
        self.tabbar.setDrawBase(False)
        self.tabbar.setLayoutDirection(Qt.LeftToRight)
        self.tabbar.setElideMode(Qt.ElideLeft)

        #Keep track of tabs

        self.tabcount = 0
        self.tabs = []
        self.deletedtabslist = []

        # Create AddressBar
        self.Toolbar = QWidget()
        self.Toolbar.setObjectName("Toobar")
        self.ToolbarLayout = QHBoxLayout()
        self.addressbar = AddressBar()

        self.AddTabButton = QPushButton("+")
        self.AddTabButton.setMaximumWidth(30)

        self.addressbar.returnPressed.connect(self.BrowseTo)
        self.AddTabButton.clicked.connect(self.AddTab)

        # Set Toolbar Buttons

        self.BackButton = QPushButton("<")
        self.BackButton.clicked.connect(self.GoBack)
        self.BackButton.setMaximumWidth(30)
        self.ForwardButton = QPushButton(">")
        self.ForwardButton.clicked.connect(self.GoForward)
        self.ForwardButton.setMaximumWidth(30)
        self.ReloadButton = QPushButton("↺")
        self.ReloadButton.clicked.connect(self.Reload)
        self.ReloadButton.setMaximumWidth(30)

        self.shortcutNewTab = QShortcut(QKeySequence(Qt.CTRL + Qt.Key_T), self)
        self.shortcutNewTab.activated.connect(self.AddTab)

        # Refresh
        self.shortcutRefresh = QShortcut(QKeySequence("Ctrl+R"), self)
        self.shortcutRefresh.activated.connect(self.Reload)
        self.shortcutRefresh2 = QShortcut(QKeySequence("F5"), self)
        self.shortcutRefresh2.activated.connect(self.Reload)

        # Toolbar options
        self.Toolbar.setLayout(self.ToolbarLayout)
        self.ToolbarLayout.addWidget(self.BackButton)
        self.ToolbarLayout.addWidget(self.ForwardButton)
        self.ToolbarLayout.addWidget(self.ReloadButton)
        self.ToolbarLayout.addWidget(self.addressbar)
        self.ToolbarLayout.addWidget(self.AddTabButton)

        # set main view
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.Toolbar)
        self.layout.addWidget(self.container)

        self.setLayout(self.layout)

        self.AddTab()

        self.show()

    def closeTab(self, i):
        self.tabbar.removeTab(i)
        self.deletedtabslist.append(i)
        self.deletedtabslist.sort()
        m = i - 1
        if m == -1:
            self.AddTab()
            return
        while m >= 0:
            if m not in self.deletedtabslist:
                self.switchtab(m)
                return
            else:
                m -= 1

    def AddTab(self):
        i = self.tabcount

        # setting self.tabs[#] = QWidget
        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setContentsMargins(0, 0, 0, 0)

        # For Tab Switching
        self.tabs[i].setObjectName("tab" + str(i))

        # Open Web View
        self.tabs[i].content = QWebView()
        self.tabs[i].content.load(QUrl("https://www.google.com/"))
        self.addressbar.setText("https://www.google.com/")

        self.tabs[i].content.titleChanged.connect(
            lambda: self.setTabContent(i, "title"))
        self.tabs[i].content.iconChanged.connect(
            lambda: self.setTabContent(i, "icon"))
        self.tabs[i].content.urlChanged.connect(
            lambda: self.setTabContent(i, "url"))

        # Add webview to tabs layout
        self.tabs[i].layout.addWidget(self.tabs[i].content)

        # Set top level tab from [] to layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        # Add tab to top level of stackWidget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        #set the tab at the top of screen
        # Set tabData to tab<#> So it knows what self.tabs[#] it needs to control

        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {"object": "tab" + str(i), "initial": i})

        self.tabbar.setCurrentIndex(i)

        self.tabcount += 1

    def switchtab(self, i):

        # Switch to tab get current tabs TabData ("tab0") and find object with name
        if self.tabbar.tabData(i):
            tab_data = self.tabbar.tabData(i)["object"]

            tab_content = self.findChild(QWidget, tab_data)
            self.container.layout.setCurrentWidget(tab_content)

            new_url = tab_content.content.url().toString()

            self.addressbar.setText(new_url)

    def BrowseTo(self):
        i = self.tabbar.currentIndex()
        if self.tabbar.tabData(i):
            text = self.addressbar.text()

            # To get the tab data

            tab = self.tabbar.tabData(i)["object"]
            web_view = self.findChild(QWidget, tab).content

            if "http" not in text:
                if "." not in text:
                    url = "https://www.google.ca/#q=" + text
                else:
                    url = "http://" + text
            else:
                url = text

            web_view.load(QUrl(url))

    def setTabContent(self, i, type):
        if self.tabbar.tabData(i):
            tab_name = self.tabs[i].objectName()

            count = 0

            running = True

            current_tab = self.tabbar.tabData(
                (self.tabbar.currentIndex()))["object"]

            if current_tab == tab_name == tab_name and type == 'url':
                new_url = self.findChild(QWidget,
                                         tab_name).content.url().toString()
                self.addressbar.setText(new_url)
                return False

            while running:
                tab_data_name = self.tabbar.tabData(count)

                if count >= 99:
                    running = False

                if tab_name == tab_data_name["object"]:
                    if type == "title":
                        newTitle = self.findChild(QWidget,
                                                  tab_name).content.title()
                        self.tabbar.setTabText(count, newTitle)
                    elif type == "icon":
                        print(12)
                        newIcon = self.findChild(QWidget,
                                                 tab_name).content.icon()
                        self.tabbar.setTabIcon(count, newIcon)

                    running = False
                else:
                    count += 1

    def GoBack(self):
        active_index = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(active_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.back()

    def GoForward(self):
        active_index = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(active_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.forward()

    def Reload(self):
        active_index = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(active_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.reload()
Exemple #10
0
class CMWMainTabs(QWidget):
    """GUI for tabs and associated widgets
    """
    tab_names = ['CDB', 'Configuration', 't-converter', 'Mon-A', 'Mon-B']

    def __init__(self, parent=None, app=None):

        QWidget.__init__(self, parent)

        cp.cmwmaintabs = self

        self.box_layout = QHBoxLayout()

        self.gui_win = None
        self.make_tab_bar()
        self.gui_selector(cp.main_tab_name.value())  # USES self.box_layout

        #self.whbox = QWidget(self)
        #self.whbox.setLayout(self.box_layout)

        #self.vspl = QSplitter(Qt.Vertical)
        #self.vspl.addWidget(self.tab_bar)
        #self.vspl.addWidget(self.whbox)

        self.box = QVBoxLayout(self)
        self.box.addWidget(self.tab_bar)
        self.box.addLayout(self.box_layout)
        #self.box.addStretch(1)
        #self.box.addWidget(self.vspl)

        self.setLayout(self.box)

        self.show_tool_tips()
        self.set_style()
        #gu.printStyleInfo(self)

        #self.move(10,25)

        #logger.debug('End of init')
        #self.set_tabs_visible(False)

    #--------------------------

    def show_tool_tips(self):
        self.setToolTip('Main tab window')

    def set_style(self):

        from psana.graphqt.Styles import style
        from psana.graphqt.QWIcons import icon
        icon.set_icons()

        #self.tab_bar.setContentsMargins(-9,-9,-9,-9) # QMargins(-5,-5,-5,-5)

        self.setWindowIcon(icon.icon_monitor)
        self.setStyleSheet(style.styleBkgd)
        self.setContentsMargins(-9, -9, -9, -9)  # QMargins(-5,-5,-5,-5)

        #self.palette = QPalette()
        #self.resetColorIsSet = False

        #self.butELog    .setIcon(icon.icon_mail_forward)
        #self.butFile    .setIcon(icon.icon_save)
        #self.butExit    .setIcon(icon.icon_exit)
        #self.butLogger  .setIcon(icon.icon_logger)
        #self.butFBrowser.setIcon(icon.icon_browser)
        #self.butSave    .setIcon(icon.icon_save_cfg)
        #self.butStop    .setIcon(icon.icon_stop)

        #self.setMinimumHeight(250)
        #self.setMinimumWidth(550)

        #self.adjustSize()
        #self.        setStyleSheet(style.styleBkgd)
        #self.butSave.setStyleSheet(style.styleButton)
        #self.butFBrowser.setVisible(False)
        #self.butExit.setText('')
        #self.butExit.setFlat(True)
        #self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    #-------------------

    def make_tab_bar(self):
        self.tab_bar = QTabBar()

        #len(self.tab_names)
        for tab_name in self.tab_names:
            tab_ind = self.tab_bar.addTab(tab_name)
            self.tab_bar.setTabTextColor(tab_ind,
                                         QColor('blue'))  #gray, red, grayblue

        #self.tab_bar.setTabsClosable(True)
        #self.tab_bar.setMovable(True)
        self.tab_bar.setShape(QTabBar.RoundedNorth)

        tab_index = self.tab_names.index(cp.main_tab_name.value())
        self.tab_bar.setCurrentIndex(tab_index)
        logger.debug('make_tab_bar - set tab index: %d' % tab_index)

        self.tab_bar.currentChanged['int'].connect(self.on_tab_bar)
        self.tab_bar.tabCloseRequested.connect(self.on_tab_close_request)
        self.tab_bar.tabMoved[int, int].connect(self.on_tab_moved)

    #--------------------------

    def gui_selector(self, tab_name):

        if self.gui_win is not None:
            #self.box_layout.removeWidget(self.gui_win)
            #self.gui_win.setVisible(False)
            self.gui_win.close()
            del self.gui_win

        w_height = 200

        if tab_name == 'CDB':
            self.gui_win = CMWDBMain()
            w_height = 500

        elif tab_name == 'Configuration':
            self.gui_win = CMWConfig()

        elif tab_name == 't-converter':
            self.gui_win = QWDateTimeSec()
            self.gui_win.setMaximumWidth(500)
            w_height = 80
            #self.gui_win.setMaximumHeight(w_height)

        else:
            self.gui_win = QTextEdit('Default window for tab %s' % tab_name)

        #self.gui_win.setFixedHeight(w_height)
        self.gui_win.setMinimumHeight(w_height)
        self.gui_win.setVisible(True)
        self.box_layout.addWidget(self.gui_win)

        #self.setStatus(0, s_msg)

    #-------------------

    def current_tab_index_and_name(self):
        tab_ind = self.tab_bar.currentIndex()
        tab_name = str(self.tab_bar.tabText(tab_ind))
        return tab_ind, tab_name

    #-------------------

    def on_tab_bar(self, ind):
        tab_ind, tab_name = self.current_tab_index_and_name()
        logger.info('Selected tab "%s"' % tab_name)
        cp.main_tab_name.setValue(tab_name)
        self.gui_selector(tab_name)

    #-------------------

    def on_tab_close_request(self, ind):
        logger.debug('on_tab_close_request ind:%d' % ind)
        #self.tab_bar.removeTab(ind)
        #logger.debug('on_tab_close_request tab index:%d' % (itab))

    #-------------------

    def on_tab_moved(self, inew, iold):
        logger.debug('on_tab_close_request tab index begin:%d -> end:%d' %
                     (iold, inew))

    #-------------------

    #def resizeEvent(self, e):
    #pass
    #self.frame.setGeometry(self.rect())
    #logger.debug('resizeEvent')
    #logger.debug('CMWMainTabs resizeEvent: %s' % str(self.size()))

    #def moveEvent(self, e):
    #logger.debug('moveEvent')
    #self.position = self.mapToGlobal(self.pos())
    #self.position = self.pos()
    #logger.debug('moveEvent - pos:' + str(self.position))
    #pass

    def closeEvent(self, e):
        logger.debug('closeEvent')

        #try    : self.gui_win.close()
        #except : pass

        #try    : del self.gui_win
        #except : pass

        if self.gui_win is not None:
            self.gui_win.close()

        QWidget.closeEvent(self, e)

    def onExit(self):
        logger.debug('onExit')
        self.close()

    def set_tabs_visible(self, is_visible):
        logger.debug('set_tabs_visible: is_visible %s' % is_visible)
        self.tab_bar.setVisible(is_visible)

    def tab_bar_is_visible(self):
        return self.tab_bar.isVisible()

    def view_hide_tabs(self):
        self.tab_bar.setVisible(not self.tab_bar.isVisible())

    def key_usage(self):
        return 'Keys:'\
               '\n  V - view/hide tabs'\
               '\n'

    if __name__ == "__main__":

        def keyPressEvent(self, e):
            #logger.debug('keyPressEvent, key=%s' % e.key())
            if e.key() == Qt.Key_Escape:
                self.close()

            elif e.key() == Qt.Key_V:
                self.view_hide_tabs()

            else:
                logger.debug(self.key_usage())
Exemple #11
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Web Browser")
        self.setGeometry(0, 0, 1000, 1000)
        self.CreateApp()
        self.setWindowIcon(QIcon("logo.png"))

    def CreateApp(self):
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        # Create Tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.CloseTab)
        self.tabbar.tabBarClicked.connect(self.SwitchTab)
        self.tabbar.setDrawBase(False)
        self.tabbar.setCurrentIndex(0)

        self.shortCutNewTab = QShortcut(QKeySequence("Ctrl+T"), self)
        self.shortCutNewTab.activated.connect(self.AddTab)

        self.shortReload = QShortcut(QKeySequence("Ctrl+R"), self)
        self.shortReload.activated.connect(self.ReloadPage)

        # keep Track of Tabs
        self.tabCount = 0
        self.tabs = []

        # Setup tool Bar
        self.addressBar = AddressBar()
        self.addressBar.returnPressed.connect(self.BrowseTo)

        self.addTabButton = QPushButton("+")
        self.addTabButton.clicked.connect(self.AddTab)

        self.backButton = QPushButton("<")
        self.backButton.clicked.connect(self.GoBack)

        self.forwardButton = QPushButton(">")
        self.forwardButton.clicked.connect(self.GoFoward)

        self.reloadButton = QPushButton("~")
        self.reloadButton.clicked.connect(self.ReloadPage)

        self.toolBar = QWidget()
        self.toolBar.setObjectName("ToolBar")
        self.toolBarLayout = QHBoxLayout()
        self.toolBar.setLayout(self.toolBarLayout)

        self.toolBarLayout.addWidget(self.backButton)
        self.toolBarLayout.addWidget(self.forwardButton)
        self.toolBarLayout.addWidget(self.reloadButton)
        self.toolBarLayout.addWidget(self.addressBar)
        self.toolBarLayout.addWidget(self.addTabButton)

        #set main view
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        #Add Tabs to layout and show
        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.toolBar)
        self.layout.addWidget(self.container)

        self.setLayout(self.layout)

        self.AddTab()

        self.show()

    def CloseTab(self, i):
        self.tabbar.removeTab(i)

    def AddTab(self):
        i = self.tabCount
        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setContentsMargins(0, 0, 0, 0)
        self.tabs[i].setObjectName("tab " + str(i))

        # open webview
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("http://google.com"))

        self.tabs[i].content.titleChanged.connect(
            lambda: self.SetTabContent(i, "title"))
        self.tabs[i].content.iconChanged.connect(
            lambda: self.SetTabContent(i, "icon"))
        self.tabs[i].content.urlChanged.connect(
            lambda: self.SetTabContent(i, "url"))

        # add webview to tabs layout
        self.tabs[i].splitview = QSplitter()
        self.tabs[i].layout.addWidget(self.tabs[i].splitview)
        self.tabs[i].splitview.addWidget(self.tabs[i].content)

        # set top level tap from [] to layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        # add tab tp top level stacked widget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        # set the tab at top of screen
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {"object": "tab " + str(i), "initial": i})
        self.tabbar.setCurrentIndex(i)

        self.tabCount += 1

    def SetTabContent(self, i, type):
        tab_name = self.tabs[i].objectName()

        count = 0
        running = True

        current_tab = self.tabbar.tabData(self.tabbar.currentIndex())["object"]

        if current_tab == tab_name and type == "url":
            new_url = self.findChild(QWidget,
                                     tab_name).content.url().toString()
            self.addressBar.setText(new_url)
            return False

        while running:
            tab_data_name = self.tabbar.tabData(count)

            if count >= 99:
                running = False

            if tab_name == tab_data_name["object"]:
                if type == "title":
                    new_title = self.findChild(QWidget,
                                               tab_name).content.title()
                    self.tabbar.setTabText(count, new_title)
                elif type == "icon":
                    newIcon = self.findChild(QWidget, tab_name).content.icon()
                    self.tabbar.setTabIcon(count, newIcon)

                running = False
            else:
                count += 1

    def SwitchTab(self, i):
        if self.tabbar.tabData(i):
            tab_data = self.tabbar.tabData(i)["object"]

            tab_content = self.findChild(QWidget, tab_data)
            self.container.layout.setCurrentWidget(tab_content)

            new_url = tab_content.content.url().toString()
            self.addressBar.setText(new_url)

    def BrowseTo(self):
        text = self.addressBar.text()

        i = self.tabbar.currentIndex()
        tab = self.tabbar.tabData(i)["object"]
        webview = self.findChild(QWidget, tab).content

        if "http" not in text:
            if "." not in text:
                url = "https://google.com/#q=" + text
            else:
                url = "http://" + text
        else:
            url = text

        webview.load(QUrl.fromUserInput(url))

    def GoBack(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.back()

    def GoFoward(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.forward()

    def ReloadPage(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.reload()
Exemple #12
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.AppSettings()
        self.CreateApplication()

    def AppSettings(self):
        self.setWindowTitle('Web Browser')
        self.setMinimumSize(840, 620)

    def CreateApplication(self):
        # Main Layout
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0,0,0,0)

        # Variables
        self.tab_count = 0
        self.tabs = []

        self.tabbar = QTabBar(tabsClosable=True, movable=True)
        self.tabbar.tabCloseRequested.connect(self.CloseTab)
        self.tabbar.tabBarClicked.connect(self.SwitchTab)

        self.tabbar.setElideMode(Qt.ElideLeft)
        self.tabbar.setExpanding(False)

        # ToolBar
        self.ToolBar = QWidget()
        self.toolbar_layout = QHBoxLayout()
        
        # Tools
        self.btnAddTab = QPushButton('+')
        self.btnAddTab.clicked.connect(self.AddTab)

        self.address_bar =  AddressBar()
        self.address_bar.returnPressed.connect(self.BrowseTo)

        self.btn_back = QPushButton('<')
        self.btn_back.clicked.connect(self.Back)

        self.btn_forward = QPushButton('>')
        self.btn_forward.clicked.connect(self.Forward)

        self.btn_refresh = QPushButton('F5')
        self.btn_refresh.clicked.connect(self.Refresh)

        # Add Tools to ToolBar layout
        self.toolbar_layout.addWidget(self.btn_back)
        self.toolbar_layout.addWidget(self.btn_forward)
        self.toolbar_layout.addWidget(self.btn_refresh)
        self.toolbar_layout.addWidget(self.address_bar)
        self.toolbar_layout.addWidget(self.btnAddTab)


        # Container
        self.container = QWidget()
        self.container_layout = QStackedLayout()
        self.container.setLayout(self.container_layout)

        # addLayout to toolbar
        self.ToolBar.setLayout(self.toolbar_layout)

        
        # Adding Widgets to Main Layout
        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.ToolBar)
        self.layout.addWidget(self.container)

        self.AddTab()

        self.setLayout(self.layout)
        self.show()


    def CloseTab(self, i):
        self.tabbar.removeTab(i)

    def AddTab(self):
        if len(self.tabs):
            self.tab_count += 1
        i = self.tab_count

        self.tabs.append(QWidget())
        self.tabs[i].layout  = QHBoxLayout()
        self.tabs[i].setObjectName('tab'+str(i))


        self.tabs[i].layout.setContentsMargins(0,0,0,0)

        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.titleChanged.connect(lambda: self.setTabTitle(i))
        self.tabs[i].content.iconChanged.connect(lambda: self.setTabIcon(i))
        self.tabs[i].content.urlChanged.connect(lambda: self.setAddressBar(i))


        self.tabs[i].content.load(QUrl.fromUserInput('http://www.google.com'))

        self.tabs[i].layout.addWidget(self.tabs[i].content)
        
        self.container_layout.addWidget(self.tabs[i])
        self.tabs[i].setLayout(self.tabs[i].layout)

        self.tabbar.addTab('New Tab')
        self.tabbar.setTabData(i, 'tab'+str(i))
        self.tabbar.setCurrentIndex(i)
        self.container_layout.setCurrentWidget(self.tabs[i])

        self.address_bar.selectAll()
        self.address_bar.setFocus()

    
    def SwitchTab(self, i):

        if self.tabs[i]:
            self.tabbar.currentIndex()
            tabName = self.tabbar.tabData(i)
            tabObj = self.findChild(QWidget, tabName)
            self.container_layout.setCurrentWidget(tabObj)

            url = tabObj.content.url().toString()
            self.address_bar.setText(url)

    def BrowseTo(self):
        text = self.address_bar.text()
        url = ""
        if 'http' not in text:
            if '.' not in text:
                if 'localhost' in text:
                    url = 'http://'+text
                else:
                    url = 'http://google.com/search?q='+text
            else:
                url = 'http://'+text
        else:
            url = text

        i = self.tabbar.currentIndex()
        self.object = self.findChild(QWidget, self.tabbar.tabData(i))
        self.object.content.load(QUrl.fromUserInput(url))
        

    def setTabTitle(self, i):
        tabName = self.tabbar.tabData(i)
        TabObj = self.findChild(QWidget, tabName)
        self.tabbar.setTabText(i, TabObj.content.title())

    def setAddressBar(self, i):
        tabName = self.tabbar.tabData(i)
        url = self.findChild(QWidget, tabName).content.url().toString()

        self.address_bar.setText(url)

    def setTabIcon(self, i):
        tabName = self.tabbar.tabData(i)
        icon = self.findChild(QWidget, tabName).content.icon()
        self.tabbar.setTabIcon(i, icon)

    def Back(self):
        i = self.tabbar.currentIndex()
        self.tabs[i].content.back()

    def Forward(self):
        i = self.tabbar.currentIndex()
        self.tabs[i].content.forward()

    def Refresh(self):
        i = self.tabbar.currentIndex()
        self.tabs[i].content.reload()
Exemple #13
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Web Browser")
        self.setMinimumSize(800, 600)
        self.create_app()
        self.setWindowIcon(QIcon('./logo.png'))

    def create_app(self):
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        # Create Tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.closeTab)
        self.tabbar.tabBarClicked.connect(self.switchTab)

        self.tabbar.setCurrentIndex(0)

        # Shortcut Key
        self.shortcutNewTab = QShortcut(QKeySequence("Ctrl+T"), self)
        self.shortcutNewTab.activated.connect(self.addTab)

        self.shortcutReload = QShortcut(QKeySequence("Ctrl+R"), self)
        self.shortcutReload.activated.connect(self.reloadPage)

        # Keep track of the tabs
        self.tabCount = 0
        self.tabs = []

        # Create Address Bar
        self.toolBar = QWidget()
        self.toolBarLayout = QHBoxLayout()

        self.addressbar = AddressBar()
        self.addressbar.returnPressed.connect(self.browseTo)

        # new tab button
        self.newTabButton = QPushButton("+")
        self.newTabButton.clicked.connect(self.addTab)

        # Set toolbar button
        self.BackButton = QPushButton("<<")
        self.ForwardButton = QPushButton(">>")
        self.BackButton.clicked.connect(self.goBackward)
        self.ForwardButton.clicked.connect(self.goForward)

        self.ReloadButton = QPushButton("Reload")
        self.ReloadButton.clicked.connect(self.reloadPage)

        # Build Toolbar
        self.toolBar.setObjectName("Toolbar")
        self.toolBar.setLayout(self.toolBarLayout)
        self.toolBarLayout.addWidget(self.BackButton)
        self.toolBarLayout.addWidget(self.ForwardButton)
        self.toolBarLayout.addWidget(self.ReloadButton)
        self.toolBarLayout.addWidget(self.addressbar)
        self.toolBarLayout.addWidget(self.newTabButton)

        # set main view
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        # Add Widgets
        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.toolBar)
        self.layout.addWidget(self.container)

        self.setLayout(self.layout)
        self.addTab()

        self.show()

    # The connection will sent the index of the tab that is clicked
    def closeTab(self, ind):
        self.tabbar.removeTab(ind)

    def addTab(self):
        ind = self.tabCount
        self.tabs.append(QWidget())
        self.tabs[ind].layout = QVBoxLayout()
        self.tabs[ind].layout.setContentsMargins(0, 0, 0, 0)

        # For tab switching
        self.tabs[ind].setObjectName("tab" + str(ind))

        self.tabs[ind].content = QWebEngineView()
        self.tabs[ind].content.load(QUrl.fromUserInput("http://google.com"))

        self.tabs[ind].content.titleChanged.connect(
            lambda: self.set_tab_content(ind, 'title'))
        self.tabs[ind].content.iconChanged.connect(
            lambda: self.set_tab_content(ind, 'icon'))
        self.tabs[ind].content.urlChanged.connect(
            lambda: self.set_tab_content(ind, "url"))

        # Add webview to tabs layout
        self.tabs[ind].layout.addWidget(self.tabs[ind].content)

        # set top level tab from list to layout
        self.tabs[ind].setLayout(self.tabs[ind].layout)

        # Add tab to top level
        self.container.layout.addWidget(self.tabs[ind])
        self.container.layout.setCurrentWidget(self.tabs[ind])

        # Set the tab at top of the screen
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(ind, {
            "object": "tab" + str(ind),
            "initial": ind
        })
        self.tabbar.setCurrentIndex(ind)

        self.tabCount += 1

    def switchTab(self, i):
        tab_data = self.tabbar.tabData(i)['object']
        tab_content = self.findChild(QWidget, tab_data)
        self.container.layout.setCurrentWidget(tab_content)

        newUrl = tab_content.content.url().toString()
        self.addressbar.setText(newUrl)

    def browseTo(self):
        text = self.addressbar.text()

        # Get the index number of the current tab
        i = self.tabbar.currentIndex()
        # Get the name of the current tab
        tab = self.tabbar.tabData(i)['object']
        # Get the webview
        wv = self.findChild(QWidget, tab).content
        if "http" not in text:
            if "." not in text:
                url = "https://www.google.com/#q=" + text
            else:
                url = "https://" + text
        else:
            url = text
        wv.load(QUrl.fromUserInput(url))

    def set_tab_content(self, i, type):
        """
            self.tabs[i].objectName => tab1
            self.tabs[i].tabData(i)['object'] => tab1
        """

        tab_objectName = self.tabs[i].objectName()

        current_tab = self.tabbar.tabData(self.tabbar.currentIndex())['object']

        if current_tab == tab_objectName and type == "url":
            newUrl = self.findChild(QWidget,
                                    tab_objectName).content.url().toString()
            self.addressbar.setText(newUrl)
            return False

        count = 0
        running = True

        while running:
            tab_data_name = self.tabbar.tabData(count)

            if count >= 99:
                running = False

            if tab_objectName == tab_data_name['object']:
                if type == 'title':
                    new_title = self.findChild(QWidget,
                                               tab_objectName).content.title()
                    self.tabbar.setTabText(count, new_title)
                elif type == 'icon':
                    newIcon = self.findChild(QWidget,
                                             tab_objectName).content.icon()
                    self.tabbar.setTabIcon(count, newIcon)

                running = False
            else:
                count += 1

    def goBackward(self):
        activeTabIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeTabIndex)['object']
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.back()

    def goForward(self):
        activeTabIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeTabIndex)['object']
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.forward()

    def reloadPage(self):
        activeTabIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeTabIndex)['object']
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.reload()
Exemple #14
0
class Application(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Web Browser")
        self.create_app()
        self.setBaseSize(1024, 768)
        self.setMinimumSize(1024, 768)
        self.setWindowIcon(QIcon("logo.png"))

    def create_app(self):

        self.layout = QVBoxLayout()
        self.toolbar = QWidget()
        self.toolbar.setObjectName("toolbar")
        self.toolbar_layout = QHBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        self.shortcutNewTab = QShortcut(QKeySequence("Ctrl+T"), self)
        self.shortcutNewTab.activated.connect(self.add_tab)

        self.shortcutReload = QShortcut(QKeySequence("Ctrl+R"), self)
        self.shortcutReload.activated.connect(self.reload_page)

        # Create Tabs
        self.tab_bar = QTabBar(movable=True, tabsClosable=True)
        self.tab_bar.tabCloseRequested.connect(self.close_tab)
        self.tab_bar.tabBarClicked.connect(self.switch_tab)
        self.tab_bar.setCurrentIndex(0)
        self.tab_bar.setDrawBase(False)

        # Keep track of tabs
        self.tab_count = 0
        self.tabs = []

        # Add Tab Button
        self.AddTabButton = QPushButton("+")
        self.AddTabButton.clicked.connect(self.add_tab)

        # Create address bar
        self.address_bar = Address_Bar()
        self.address_bar.returnPressed.connect(self.browse_to)

        # Set Toolbar Buttons
        self.back_button = QPushButton("<")
        self.back_button.clicked.connect(self.go_back)

        self.forward_button = QPushButton(">")
        self.forward_button.clicked.connect(self.go_forward)

        self.reload_button = QPushButton("R")
        self.reload_button.clicked.connect(self.reload_page)

        #Build Toolbar
        self.toolbar.setLayout(self.toolbar_layout)
        self.toolbar_layout.addWidget(self.back_button)
        self.toolbar_layout.addWidget(self.forward_button)
        self.toolbar_layout.addWidget(self.reload_button)
        self.toolbar_layout.addWidget(self.address_bar)
        self.toolbar_layout.addWidget(self.AddTabButton)

        # Set Main View
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        self.layout.addWidget(self.tab_bar)
        self.layout.addWidget(self.toolbar)
        self.layout.addWidget(self.container)
        self.setLayout(self.layout)

        self.add_tab()

        self.show()

    def close_tab(self, i):
        self.tab_bar.removeTab(i)

    def add_tab(self):
        i = self.tab_count

        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setContentsMargins(0, 0, 0, 0)
        self.tabs[i].setObjectName("tab" + str(i))

        # Open Webview
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("http://google.com"))

        self.tabs[i].content.titleChanged.connect(
            lambda: self.set_tab_content(i, "title"))
        self.tabs[i].content.iconChanged.connect(
            lambda: self.set_tab_content(i, "icon"))
        self.tabs[i].content.urlChanged.connect(
            lambda: self.set_tab_content(i, "url"))

        # Add webview to tabs layout
        # self.tabs[i].splitview = QSplitter()
        self.tabs[i].layout.addWidget(self.tabs[i].content)

        # self.tabs[i].splitview.addWidget(self.tabs[i].content)

        # Set top level tab from [] to layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        # Add tab to top level stacked widget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        # Create tab on tab bar,
        # Set tabData to tab<#> So it knows what self.tabs[#] it needs to control
        self.tab_bar.addTab("New Tab")
        self.tab_bar.setTabData(i, {"object": "tab" + str(i), "initial": i})
        self.tab_bar.setCurrentIndex(i)

        self.tab_count += 1

    def switch_tab(self, i):
        tab_data = self.tab_bar.tabData(i)["object"]
        tab_content = self.findChild(QWidget, tab_data)
        self.container.layout.setCurrentWidget(tab_content)
        new_url = tab_content.content.url().toString()
        self.address_bar.setText(new_url)

    def browse_to(self):
        text = self.address_bar.text()

        i = self.tab_bar.currentIndex()
        tab = self.tab_bar.tabData(i)["object"]
        web_view = self.findChild(QWidget, tab).content

        if "http" not in text:
            if "." not in text:
                url = "https://www.google.com/search?q=" + text
            else:
                url = "http://" + text
        else:
            url = text

        web_view.load(QUrl.fromUserInput(url))

    def set_tab_content(self, i, type):
        tab_name = self.tabs[i].objectName()
        count = 0
        running = True

        current_tab = self.tab_bar.tabData(
            self.tab_bar.currentIndex())["object"]

        if current_tab == tab_name and type == "url":
            new_url = self.findChild(QWidget,
                                     tab_name).content.url().toString()
            self.address_bar.setText(new_url)
            return False

        while running:
            tab_data_name = self.tab_bar.tabData(count)

            if count >= 99:
                running = False

            if tab_name == tab_data_name["object"]:
                if type == "title":
                    new_title = self.findChild(QWidget,
                                               tab_name).content.title()
                    self.tab_bar.setTabText(count, new_title)
                elif type == "icon":
                    new_icon = self.findChild(QWidget, tab_name).content.icon()
                    self.tab_bar.setTabIcon(count, new_icon)
                running = False
            else:
                count += 1

    def go_back(self):
        activeIndex = self.tab_bar.currentIndex()
        tab_name = self.tab_bar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.back()

    def go_forward(self):
        activeIndex = self.tab_bar.currentIndex()
        tab_name = self.tab_bar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.forward()

    def reload_page(self):
        activeIndex = self.tab_bar.currentIndex()
        tab_name = self.tab_bar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.reload()
Exemple #15
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Web Browser")
        self.h = 1366
        self.w = 768
        self.CreateApp()
        self.setBaseSize(self.h, self.w)

    def CreateApp(self):
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        #Create Tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.CloseTab)
        self.tabbar.tabBarClicked.connect(self.SwitchTab)

        self.tabbar.setCurrentIndex(0)
        self.tabbar.setDrawBase(False)

        #Keeping track of Tabs
        self.tabCount = 0
        self.tabs = []

        #Create Address Bar
        self.Toolbar = QWidget()
        self.ToolbarLayout = QHBoxLayout()
        self.addressbar = AddressBar()
        self.AddTabButton = QPushButton("+")

        self.addressbar.returnPressed.connect(self.BrowseTo)

        self.AddTabButton.clicked.connect(self.AddTab)

        self.BackButton = QPushButton("<-")
        self.BackButton.clicked.connect(self.GoBack)

        self.ForwardButton = QPushButton("->")
        self.ForwardButton.clicked.connect(self.GoForward)

        self.ReloadButton = QPushButton("R")
        self.ReloadButton.clicked.connect(self.ReloadPage)

        self.Toolbar.setLayout(self.ToolbarLayout)
        self.ToolbarLayout.addWidget(self.BackButton)
        self.ToolbarLayout.addWidget(self.ForwardButton)
        self.ToolbarLayout.addWidget(self.ReloadButton)
        self.ToolbarLayout.addWidget(self.addressbar)
        self.ToolbarLayout.addWidget(self.AddTabButton)

        #Set Main View
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.Toolbar)
        self.layout.addWidget(self.container)

        self.setLayout(self.layout)

        self.AddTab()

        self.show()

    def CloseTab(self, i):
        self.tabbar.removeTab(i)

    def AddTab(self):
        i = self.tabCount

        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].setObjectName("tab" + str(i))

        #Open Webview
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("http://google.com"))

        #Set Tab names
        self.tabs[i].content.titleChanged.connect(
            lambda: self.SetTabContent(i, "title"))
        self.tabs[i].content.iconChanged.connect(
            lambda: self.SetTabContent(i, "icon"))

        #add webview to tabs layout
        self.tabs[i].layout.addWidget(self.tabs[i].content)

        #set top level tab from [] to layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        #Add tab to stacked
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        #set Tab at top
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {"object": "tab" + str(i), "initial": i})

        self.tabbar.setCurrentIndex(i)

        self.tabCount += 1

    def SwitchTab(self, i):
        tab_data = self.tabbar.tabData(i)["object"]
        tab_content = self.findChild(QWidget, tab_data)
        self.container.layout.setCurrentWidget(tab_content)

    def BrowseTo(self):
        text = self.addressbar.text()

        i = self.tabbar.currentIndex()
        tab = self.tabbar.tabData(i)["object"]
        wv = self.findChild(QWidget, tab).content

        if "http" not in text:
            if "." not in text:
                url = "https://www.google.com/#q=" + text
            else:
                url = "http://" + text
        else:
            url = text

        wv.load(QUrl.fromUserInput(url))

    def SetTabContent(self, i, type):
        '''
            self.tabs[i].objectName = tab1
            self.tabbar.tabData(i)["object"] = tab1
        '''
        tab_name = self.tabs[i].objectName()
        #tab1

        count = 0
        running = True

        while running:
            tab_data_name = self.tabbar.tabData(count)

            if count >= 99:
                running = False

            if tab_name == tab_data_name["object"]:
                if type == "title":
                    new_title = self.findChild(QWidget,
                                               tab_name).content.title()
                    self.tabbar.setTabText(count, new_title)
                elif type == "icon":
                    newIcon = self.findChild(QWidget, tab_name).content.icon()
                    self.tabbar.setTabIcon(count, newIcon)
                running = False
            else:
                count += 1

    def GoBack(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.back()

    def GoForward(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.forward()

    def ReloadPage(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.reload()
Exemple #16
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Browser")

        self.setBaseSize(1366, 768)
        self.setMinimumSize(1366, 768)
        self.create_app()
        self.setWindowIcon(QIcon("logo.png"))

    # noinspection PyAttributeOutsideInit
    def create_app(self):
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        # Create Tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.close_tab)
        self.tabbar.tabBarClicked.connect(self.switch_tab)
        self.tabbar.setCurrentIndex(0)
        self.tabbar.setDrawBase(False)
        self.tabbar.setLayoutDirection(Qt.LeftToRight)
        self.tabbar.setElideMode(Qt.ElideLeft)

        self.shortcut_new_tab = QShortcut(QKeySequence("Ctrl+T"), self)
        self.shortcut_new_tab.activated.connect(self.add_tab)

        self.shortcut_reload = QShortcut(QKeySequence("Ctrl+R"), self)
        self.shortcut_reload.activated.connect(self.reload_page)

        # Keep track of tabs
        self.tab_count = 0
        self.tabs = []

        # Create Address Bar
        self.toolbar = QWidget()
        self.toolbar.setObjectName("toolbar")
        self.toolbar_layout = QHBoxLayout()
        self.addressbar = AddressBar()
        self.add_tab_button = QPushButton("+")

        # Connect AdressBar + button Signals
        self.addressbar.returnPressed.connect(self.browse_to)
        self.add_tab_button.clicked.connect(self.add_tab)

        # Set toolbar buttons
        self.back_button = QPushButton("<")
        self.back_button.clicked.connect(self.go_back)

        self.forward_button = QPushButton(">")
        self.forward_button.clicked.connect(self.go_forward)

        self.reload_button = QPushButton("R")
        self.reload_button.clicked.connect(self.reload_page)

        # Build toolbar
        self.toolbar.setLayout(self.toolbar_layout)
        self.toolbar_layout.addWidget(self.back_button)
        self.toolbar_layout.addWidget(self.reload_button)
        self.toolbar_layout.addWidget(self.forward_button)
        self.toolbar_layout.addWidget(self.addressbar)
        self.toolbar_layout.addWidget(self.add_tab_button)

        # Set main view
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.toolbar)
        self.layout.addWidget(self.container)

        self.setLayout(self.layout)

        self.add_tab()

        self.show()

    def close_tab(self, i):
        self.tabbar.removeTab(i)

    # noinspection PyCallByClass
    def add_tab(self):
        i = self.tab_count

        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].setObjectName("tab" + str(i))
        self.tabs[i].layout.setContentsMargins(0, 0, 0, 0)

        # Open webView
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("http://google.com"))

        self.tabs[i].content.titleChanged.connect(lambda: self.set_tab_content(i, "title"))
        self.tabs[i].content.iconChanged.connect(lambda: self.set_tab_content(i, "icon"))
        self.tabs[i].content.urlChanged.connect(lambda: self.set_tab_content(i, "url"))

        # Add webView to tabs layout
        self.tabs[i].layout.addWidget(self.tabs[i].content)

        # Set top level tab from [] to layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        # Add tab to top level stackedWidget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        # Create tab on tabbar, representing this tab,
        # set tabData to tab# so it knows what self.tabs# it needs to control
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {"object": "tab" + str(i), "initial": i})

        '''
            self.tabs[i].objectName = tab1
            self.tabbar.tabData(i)["object"] = tab1
        '''

        self.tabbar.setCurrentIndex(i)

        # +=1
        self.tab_count += 1

    def switch_tab(self, i):
        if self.tabbar.tabData(i):
            tab_data = self.tabbar.tabData(i)["object"]
            tab_content = self.findChild(QWidget, tab_data)
            self.container.layout.setCurrentWidget(tab_content)
            new_url = tab_content.content.url().toString()
            self.addressbar.setText(new_url)

    def browse_to(self):
        text = self.addressbar.text()

        i = self.tabbar.currentIndex()
        tab = self.tabbar.tabData(i)["object"]
        wv = self.findChild(QWidget, tab).content

        if "http" not in text:
            if "." not in text:
                url = "https://www.google.com/#q=" + text
            else:
                url = "https://" + text
        else:
            url = text

        wv.load(QUrl.fromUserInput(url))

    def set_tab_content(self, i, type):
        tab_name = self.tabs[i].objectName()

        count = 0
        running = True

        current_tab = self.tabbar.tabData(self.tabbar.currentIndex())["object"]

        if current_tab == tab_name and type == "url":
            new_url = self.findChild(QWidget, tab_name).content.url().toString()
            self.addressbar.setText(new_url)
            return False

        while running:
            tab_data_name = self.tabbar.tabData(count)

            if count >= 99:
                running = False

            if tab_name == tab_data_name["object"]:
                if type == "title":
                    new_title = self.findChild(QWidget, tab_name).content.title()
                    self.tabbar.setTabText(count, new_title)
                    running = False
                elif type == "icon":
                    new_icon = self.findChild(QWidget, tab_name).content.icon()
                    self.tabbar.setTabIcon(count, new_icon)
                    running = False
            else:
                count += 1

    def go_back(self):
        active_index = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(active_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.back()

    def go_forward(self):
        active_index = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(active_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.forward()

    def reload_page(self):
        active_index = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(active_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.reload()
Exemple #17
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Web Browser")
        # to open at a specific size
        self.setBaseSize(1366, 768)
        self.setMinimumSize(1366, 768)
        self.CreateApp()
        self.setWindowIcon(QIcon("logo.png"))

    def CreateApp(self):
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        # Create Tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.CloseTab)
        self.tabbar.tabBarClicked.connect(self.SwitchTab)

        self.tabbar.setCurrentIndex(0)
        self.tabbar.setDrawBase(False)
        self.tabbar.setLayoutDirection(Qt.LeftToRight)
        self.tabbar.setElideMode(Qt.ElideLeft)
        self.shortcutNewTab = QShortcut(QKeySequence("Ctrl+T"), self)
        self.shortcutNewTab.activated.connect(self.AddTab)

        self.shortcutReload = QShortcut(QKeySequence("Ctrl+R"), self)
        self.shortcutReload.activated.connect(self.ReloadPage)

        # Keep track of tabs
        self.tabCount = 0

        # contains every widget in the tab
        self.tabs = []

        # Set up all Buttons with their methods
        self.Toolbar = QWidget()
        self.Toolbar.setObjectName("Toolbar")
        self.ToolbarLayout = QHBoxLayout()
        self.addressbar = AddressBar()
        self.AddTabButton = QPushButton("+")
        self.BackButton = QPushButton("<")

        self.BackButton.clicked.connect(self.GoBack)

        self.ForwardButton = QPushButton(">")
        self.ReloadButton = QPushButton("R")
        self.ReloadButton.clicked.connect(self.ReloadPage)
        self.ForwardButton.clicked.connect(self.GoForward)
        self.addressbar.returnPressed.connect(self.BrowseTo)
        self.AddTabButton.clicked.connect(self.AddTab)

        # Build Toolbars
        self.Toolbar.setLayout(self.ToolbarLayout)
        self.ToolbarLayout.addWidget(self.BackButton)
        self.ToolbarLayout.addWidget(self.ForwardButton)
        self.ToolbarLayout.addWidget(self.ReloadButton)
        self.ToolbarLayout.addWidget(self.addressbar)
        self.ToolbarLayout.addWidget(self.AddTabButton)

        # Set main view
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.Toolbar)
        self.layout.addWidget(self.container)
        self.setLayout(self.layout)

        self.AddTab()

        self.show()

    def CloseTab(self, i):
        self.tabbar.removeTab(i)

    def AddTab(self):
        i = self.tabCount

        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setContentsMargins(0, 0, 0, 0)

        self.tabs[i].setObjectName("tab " + str(i))

        # Open webview
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("http://google.com"))

        self.tabs[i].content1 = QWebEngineView()
        self.tabs[i].content1.load(QUrl.fromUserInput("http://google.com"))

        self.tabs[i].content.titleChanged.connect(
            lambda: self.SetTabContent(i, "title"))
        self.tabs[i].content.iconChanged.connect(
            lambda: self.SetTabContent(i, "icon"))
        self.tabs[i].content.urlChanged.connect(
            lambda: self.SetTabContent(i, "url"))

        # Add webview to tabs layout
        self.tabs[i].splitview = QSplitter()
        self.tabs[i].layout.addWidget(self.tabs[i].splitview)

        self.tabs[i].splitview.addWidget(self.tabs[i].content)
        self.tabs[i].splitview.addWidget(self.tabs[i].content1)

        # set top level tab from [] to layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        # add tab to top level stackedwidget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        # Set the tab at top of screen
        # Set tabData to tab<#> So it knows what self.tabs(#) it needs to control
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {"object": "tab " + str(i), "initial": i})
        '''
            self.tabs[i].objectName = tab1
            self.tabbar.tabData(i)["object"] = tab1
        '''

        self.tabbar.setCurrentIndex(i)
        self.tabCount += 1

    def SwitchTab(self, i):
        if self.tabbar.tabData(i):
            tab_data = self.tabbar.tabData(i)
            print(tab_data)
            tab_content = self.tabs[i]
            print(tab_content)
            self.container.layout.setCurrentWidget(tab_content)
            new_url = tab_content.content.url().toString()
            self.addressbar.setText(new_url)

    def BrowseTo(self):
        text = self.addressbar.text()
        print(text)
        i = self.tabbar.currentIndex()
        print(i)
        tab = self.tabbar.tabData(i)
        print(tab)
        # wv = self.findChild(QWidget, tab).content
        if "http" not in text:
            if "." not in text:
                url = "https://google.com/#q=" + text
            else:
                url = "http://" + text
        else:
            url = text
        self.tabs[i].content.load(QUrl.fromUserInput(url))

    def SetTabContent(self, i, type):
        print("im here")
        tab_name = self.tabs[i].objectName()
        print(tab_name)
        count = 0
        running = True

        current_tab = self.tabbar.tabData(self.tabbar.currentIndex())["object"]

        if current_tab == tab_name and type == "url":
            new_url = self.tabs[i].content.url().toString()
            self.addressbar.setText(new_url)
            return False

        while running:
            tab_data_name = self.tabbar.tabData(count)
            print(tab_data_name)

            if count >= 99:
                running = False

            if tab_name == tab_data_name["object"]:
                if type == "title":
                    print("im in here")
                    newTitle = self.tabs[i].content.title()
                    self.tabbar.setTabText(count, newTitle)
                    running = False
                elif type == "icon":
                    newIcon = self.tabs[i].content.icon()
                    self.tabbar.setTabIcon(count, newIcon)
                    running = False

            else:
                count += 1

    def GoBack(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.tabs[activeIndex].content
        tab_content.back()
        pass

    def GoForward(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.tabs[activeIndex].content
        tab_content.forward()
        pass

    def ReloadPage(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.tabs[activeIndex].content
        tab_content.reload()
Exemple #18
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Qt-browser")
        self.setMinimumSize(1366, 768)
        self.CreateApp()

    def CreateApp(self):
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        # create tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.CloseTab)
        self.tabbar.tabBarClicked.connect(self.SwitchTab)

        self.tabbar.setCurrentIndex(0)

        # keep track of all tabs
        self.tabCount = 0
        self.tabs = []

        # create address bar
        self.Toolbar = QWidget()
        self.ToolbarLayout = QHBoxLayout()
        self.AddressBar = AddressBar()
        self.AddressBar.returnPressed.connect(self.BrowseTo)

        # create new tab button
        self.AddTabButton = QPushButton("+")
        self.AddTabButton.clicked.connect(self.AddTab)

        # create functional buttons - back, forward and reload
        self.BackButton = QPushButton("<")
        self.BackButton.clicked.connect(self.GoBack)

        self.ForwardButton = QPushButton(">")
        self.ForwardButton.clicked.connect(self.GoForward)

        self.ReloadButton = QPushButton("R")
        self.ReloadButton.clicked.connect(self.ReloadPage)

        # append toolbar and buttons
        self.Toolbar.setLayout(self.ToolbarLayout)
        self.ToolbarLayout.addWidget(self.BackButton)
        self.ToolbarLayout.addWidget(self.ForwardButton)
        self.ToolbarLayout.addWidget(self.ReloadButton)
        self.ToolbarLayout.addWidget(self.AddressBar)
        self.ToolbarLayout.addWidget(self.AddTabButton)


        # set main view
        self.Container = QWidget()
        self.Container.Layout = QStackedLayout()
        self.Container.setLayout(self.Container.Layout)

        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.Toolbar)
        self.layout.addWidget(self.Container)

        self.setLayout(self.layout)

        self.show()

    def CloseTab(self, i):
        self.tabbar.removeTab(i)
        self.tabCount -= 1

    def AddTab(self):
        i = self.tabCount

        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setContentsMargins(0,0,0,0)

        # tab switching
        self.tabs[i].setObjectName("tab" + str(self.tabCount))

        # open web view
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("http://google.com"))

        self.tabs[i].content.titleChanged.connect(lambda: self.SetTabContent(i, "title"))
        self.tabs[i].content.iconChanged.connect(lambda: self.SetTabContent(i, "icon"))
        self.tabs[i].content.urlChanged.connect(lambda: self.SetTabContent(i, "url"))

        # add web view to tabs layout
        self.tabs[i].layout.addWidget(self.tabs[i].content)

        # set top level tab from [] to layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        # add tab to top level stackedwidget
        self.Container.Layout.addWidget(self.tabs[i])
        self.Container.Layout.setCurrentWidget(self.tabs[i])

        # set the tab at the top of screen
        self.tabbar.addTab("new tab")
        self.tabbar.setTabData(i, {"object": "tab" + str(i), "initial": i})

        self.tabbar.setCurrentIndex(i)
        self.tabCount += 1

    def SwitchTab(self, i):
        tab_data = self.tabbar.tabData(i)["object"]
        tab_widget = self.findChild(QWidget, tab_data)
        self.Container.Layout.setCurrentWidget(tab_widget)

        new_url = tab_widget.content.url().toString()
        self.AddressBar.setText(new_url)

    def BrowseTo(self):
        address_text = self.AddressBar.text()

        i = self.tabbar.currentIndex()
        print(i)
        #TODO - better check if any tab exists before accessing it
        if i < 0:
            self.AddTab()
            i = 0
        else:
            pass

        print(i)
        tab = self.tabbar.tabData(i)["object"]
        web_view = self.findChild(QWidget, tab).content

        #TODO - find a better way to filter string passed in address bar
        if "http" not in address_text:
            if "." not in address_text:
                url = "https://www.google.pl/#q=" + address_text
            else:
                url = "http://" + address_text
        else:
            url = address_text
        print(url)
        web_view.load(QUrl.fromUserInput(url))

    def SetTabContent(self, i, type):
        tab_name = self.tabs[i].objectName()
        count = 0
        running = True

        current_tab = self.tabbar.tabData(self.tabbar.currentIndex())["object"]

        if current_tab == tab_name and type == "url":
            new_url = self.findChild(QWidget, tab_name).content.url().toString()
            self.AddressBar.setText(new_url)

        while running:
            tab_data_name = self.tabbar.tabData(count)

            if count >= 99:
                running = False

            if tab_name == tab_data_name["object"]:
                if type == "title":
                    new_title = self.findChild(QWidget, tab_name).content.title()
                    self.tabbar.setTabText(count, new_title)
                elif type == "icon":
                    new_icon = self.findChild(QWidget, tab_name).content.icon()
                    self.tabbar.setTabIcon(count, new_icon)

                running = False
            else:
                count += 1

    def GoBack(self):
        active_index = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(active_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.back()

    def GoForward(self):
        active_index = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(active_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.forward()

    def ReloadPage(self):
        active_index = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(active_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.reload()
Exemple #19
0
class Application(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowIcon(QIcon("Logo.png"))
        self.setWindowTitle("Balongi")
        self.setBaseSize(1400, 720)
        self.setMinimumSize(1400, 720)
        self.CreateApplication()

    def CreateApplication(self):
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)
        #Create Tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.CloseTab)
        self.tabbar.tabBarClicked.connect(self.SwitchTab)
        self.tabbar.setCurrentIndex(0)
        self.tabbar.setDrawBase(False)
        self.tabbar.setLayoutDirection(Qt.LeftToRight)
        self.tabbar.setElideMode(Qt.ElideLeft)
        # Keep Track at Tabs
        self.tabCount = 0
        self.tabs = []
        #Create AddressBar
        self.Toolbar = QWidget()
        self.Toolbar.setObjectName("Toolbar")
        self.Toolbarlayout = QHBoxLayout()
        self.addressb = AdressB()
        self.AddTabButton = QPushButton("🞢")
        #Connect addressbar + button signals
        self.addressb.returnPressed.connect(self.Browse)
        self.AddTabButton.clicked.connect(self.AddTab)
        #Set toolbar buttons
        self.BackButton = QPushButton("🠜")
        self.BackButton.clicked.connect(self.GoBack)
        self.ForwardButton = QPushButton("🠞")
        self.ForwardButton.clicked.connect(self.GoForward)
        self.ReloadButton = QPushButton("â­®")
        self.ReloadButton.clicked.connect(self.ReloadPage)
        #Build a toolbar
        self.Toolbar.setLayout(self.Toolbarlayout)
        self.Toolbarlayout.addWidget(self.BackButton)
        self.Toolbarlayout.addWidget(self.ForwardButton)
        self.Toolbarlayout.addWidget(self.ReloadButton)
        self.Toolbarlayout.addWidget(self.addressb)
        self.Toolbarlayout.addWidget(self.AddTabButton)
        # Set Main View
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.Toolbar)
        self.layout.addWidget(self.container)
        self.setLayout(self.layout)
        self.AddTab()
        self.show()

    def CloseTab(self, i):
        self.tabbar.removeTab(i)

    def AddTab(self):
        i = self.tabCount
        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setContentsMargins(0, 0, 0, 0)
        #For tab switching
        self.tabs[i].setObjectName("tab" + str(i))
        #Open webview
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("http://google.com"))
        self.tabs[i].content.titleChanged.connect(
            lambda: self.SetTabContent(i, "title"))
        self.tabs[i].content.iconChanged.connect(
            lambda: self.SetTabContent(i, "icon"))
        self.tabs[i].content.urlChanged.connect(
            lambda: self.SetTabContent(i, "url"))
        #Add web view to tabs layout
        self.tabs[i].layout.addWidget(self.tabs[i].content)
        # Set Top Level Tab from list to layout
        self.tabs[i].setLayout(self.tabs[i].layout)
        #Add tab to top level stackwidget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])
        #Set the tabs at the top of the screen
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {"object": "tab" + str(i), "initial": i})
        print("tabData: ", self.tabbar.tabData(i)["object"])
        self.tabbar.setCurrentIndex(i)
        self.tabCount += 1

    def SwitchTab(self, i):
        tab_data = self.tabbar.tabData(i)["object"]
        tab_content = self.findChild(QWidget, tab_data)
        self.container.layout.setCurrentWidget(tab_content)
        new_url = tab_content.content.url().toString()
        self.addressb.setText(new_url)

    def Browse(self):
        text = self.addressb.text()
        print(text)

        i = self.tabbar.currentIndex()
        tab = self.tabbar.tabData(i)["object"]
        web_view = self.findChild(QWidget, tab).content
        if "http" not in text:
            if "." not in text:
                url = "https://www.google.com/#q=" + text
            else:
                url = "http://" + text
        else:
            url = text
        web_view.load(QUrl.fromUserInput(url))

    def SetTabContent(self, i, type):
        '''
        self.tabs[i].objectName = tab1
        self.tabbar.tabDat[i]["object"] = tab1
        '''
        tab_name = self.tabs[i].objectName()
        # tab1
        count = 0
        running = True
        currentTab = self.tabbar.tabData(self.tabbar.currentIndex())["object"]
        if currentTab == tab_name and type == "url":
            new_url = self.findChild(QWidget,
                                     tab_name).content.url().toString()
            self.addressb.setText(new_url)
        else:
            while running:
                tab_data_name = self.tabbar.tabData(count)
                if count >= 99:
                    running = False
                if tab_name == tab_data_name["object"]:
                    if type == "title":
                        newTitle = self.findChild(QWidget,
                                                  tab_name).content.title()
                        self.tabbar.setTabText(count, newTitle)
                    elif type == "icon":
                        newIcon = self.findChild(QWidget,
                                                 tab_name).content.icon()
                        self.tabbar.setTabIcon(count, newIcon)
                    running = False
                else:
                    count += 1

    def GoBack(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.back()

    def GoForward(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.forward()

    def ReloadPage(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.reload()
Exemple #20
0
class FMWTabs(QWidget):
    """GUI for tabs and associated widgets
    """
    tab_names = ['LCLS1', 'LCLS1->LCLS2']
    tool_tips = [\
      'LCLS1 - easy access to calibration constants\nin the <experiment>/calib directory',
      'Upploader of LCLS calibratiuon constants\nto LCLS2 calibration DB',\
    ]

    def __init__(self, parent=None, app=None):

        QWidget.__init__(self, parent)

        cp.fmwtabs = self

        self.box_layout = QHBoxLayout()

        start_tab_name = cp.fmwtab_tab_name.value()
        self.gui_win = None
        self.make_tab_bar(start_tab_name)
        self.gui_selector(start_tab_name)

        self.box = QVBoxLayout(self)
        self.box.addWidget(self.tab_bar)
        self.box.addLayout(self.box_layout)

        self.setLayout(self.box)

        self.set_tool_tips()
        self.set_style()

    def set_tool_tips(self):
        for t, s in zip(self.tab_names, self.tool_tips):
            self.tab_bar.setTabToolTip(self.tab_names.index(t), s)
        #self.setToolTip('Main tab window')

    def set_style(self):
        from psana.graphqt.Styles import style
        from psana.graphqt.QWIcons import icon
        icon.set_icons()
        self.setWindowIcon(icon.icon_monitor)
        self.setStyleSheet(style.styleBkgd)
        self.layout().setContentsMargins(0, 0, 0, 0)

    def make_tab_bar(self, start_tab_name):
        self.tab_bar = QTabBar()

        for tab_name in self.tab_names:
            tab_ind = self.tab_bar.addTab(tab_name)
            self.tab_bar.setTabTextColor(tab_ind,
                                         QColor('blue'))  #gray, red, grayblue

        self.tab_bar.setShape(QTabBar.RoundedNorth)

        tab_index = self.tab_names.index(start_tab_name)
        self.tab_bar.setCurrentIndex(tab_index)
        logger.debug('make_tab_bar - set tab index: %d' % tab_index)

        self.tab_bar.currentChanged['int'].connect(self.on_tab_bar)
        self.tab_bar.tabCloseRequested.connect(self.on_tab_close_request)
        self.tab_bar.tabMoved[int, int].connect(self.on_tab_moved)

    def gui_selector(self, tab_name):

        if self.gui_win is not None:
            self.gui_win.close()
            del self.gui_win

        w_height = 200
        #if cp.cmwmain is not None: cp.cmwmain.wlog.setVisible(True)

        if tab_name == 'LCLS1->LCLS2':
            self.gui_win = QTextEdit('Selected tab "%s"' % tab_name)
            w_height = 400

        elif tab_name == 'LCLS1':
            from psana.graphqt.FMW1Main import FMW1Main
            self.gui_win = FMW1Main()

        elif tab_name == 'LCLS2':
            self.gui_win = QTextEdit('Selected tab "%s"' % tab_name)

        else:
            self.gui_win = QTextEdit('Selected tab "%s"' % tab_name)

        #self.gui_win.setMinimumHeight(w_height)
        self.gui_win.setVisible(True)
        self.box_layout.addWidget(self.gui_win)

    def current_tab_index_and_name(self):
        tab_ind = self.tab_bar.currentIndex()
        tab_name = str(self.tab_bar.tabText(tab_ind))
        return tab_ind, tab_name

    def on_tab_bar(self, ind):
        tab_ind, tab_name = self.current_tab_index_and_name()
        logger.info('Selected tab "%s"' % tab_name)
        cp.fmwtab_tab_name.setValue(tab_name)
        self.gui_selector(tab_name)

    def on_tab_close_request(self, ind):
        logger.debug('on_tab_close_request ind:%d' % ind)
        #self.tab_bar.removeTab(ind)
        #logger.debug('on_tab_close_request tab index:%d' % (itab))

    def on_tab_moved(self, inew, iold):
        logger.debug('on_tab_close_request tab index begin:%d -> end:%d' %
                     (iold, inew))

    def closeEvent(self, e):
        logger.debug('closeEvent')

        if self.gui_win is not None:
            self.gui_win.close()

        QWidget.closeEvent(self, e)

        cp.fmwtabs = None

    def onExit(self):
        logger.debug('onExit')
        self.close()

    def set_tabs_visible(self, is_visible):
        logger.debug('set_tabs_visible: is_visible %s' % is_visible)
        self.tab_bar.setVisible(is_visible)

    def tab_bar_is_visible(self):
        return self.tab_bar.isVisible()

    def view_hide_tabs(self):
        self.tab_bar.setVisible(not self.tab_bar.isVisible())

    if __name__ == "__main__":

        def keyPressEvent(self, e):
            logger.debug('keyPressEvent, key=%s' % e.key())
            if e.key() == Qt.Key_Escape:
                self.close()

            elif e.key() == Qt.Key_V:
                self.view_hide_tabs()

            else:
                logger.debug('Keys:'\
                   '\n  V - view/hide tabs'\
                   '\n')
Exemple #21
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Web Browser")
        self.CreateApp()
        self.setBaseSize(1366, 786)

    def CreateApp(self):

        #Keep track of tabs
        self.tabCount = 0
        self.tabs = []

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

        #Creating tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.CloseTab)
        self.tabbar.tabBarClicked.connect(self.SwitchTab)

        self.tabbar.setCurrentIndex(0)

        #create addressbar
        self.Toolbar = QWidget()
        self.ToolbarLayout = QHBoxLayout()
        self.addressbar = AddressBar()
        #new tab button
        self.AddTabButton = QPushButton("+")
        #connect address bar and button signals
        self.AddTabButton.clicked.connect(self.AddTab)
        self.addressbar.returnPressed.connect(self.BrowseTo)
        #set toolbar buttons
        self.BackButton = QPushButton("<")
        self.ForwardButton = QPushButton(">")
        self.RelaodButton = QPushButton("R")
        #connect toolbar buttons
        self.BackButton.clicked.connect(self.GoBack)
        self.ForwardButton.clicked.connect(self.GoForward)
        self.RelaodButton.clicked.connect(self.Reload)
        #build toolbar
        self.Toolbar.setLayout(self.ToolbarLayout)
        self.ToolbarLayout.addWidget(self.BackButton)
        self.ToolbarLayout.addWidget(self.ForwardButton)
        self.ToolbarLayout.addWidget(self.RelaodButton)
        self.ToolbarLayout.addWidget(self.addressbar)
        self.ToolbarLayout.addWidget(self.AddTabButton)
        #set main view
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.Toolbar)
        self.layout.addWidget(self.container)
        self.setLayout(self.layout)

        self.AddTab()
        self.show()

    def CloseTab(self, i):
        self.tabbar.removeTab(i)

    def AddTab(self):
        i = self.tabCount

        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        #giving id to tabs
        self.tabs[i].setObjectName("tab" + str(i))

        #create and open web view
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("http://google.com"))

        self.tabs[i].content.titleChanged.connect(
            lambda: self.SetTabContent(i, "title"))
        self.tabs[i].content.iconChanged.connect(
            lambda: self.SetTabContent(i, "icon"))
        self.tabs[i].content.urlChanged.connect(
            lambda: self.SetTabContent(i, "url"))
        #add web view to tabs layout
        self.tabs[i].layout.addWidget(self.tabs[i].content)
        #set top level tab from list to layout
        self.tabs[i].setLayout(self.tabs[i].layout)
        #add tab to top level stacked widget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])
        #set tab at the top of the screen
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {"object": "tab{}".format(i), "initial": i})
        self.tabbar.setCurrentIndex(i)

        self.tabCount += 1

    def SwitchTab(self, i):
        if self.tabbar.tabData(i):
            td = self.tabbar.tabData(i)['object']
            tabContent = self.findChild(QWidget, td)
            self.container.layout.setCurrentWidget(tabContent)
            new_url = tabContent.url().toString()
            self.addressbar.setText(new_url)

    def BrowseTo(self):
        text = self.addressbar.text()
        i = self.tabbar.currentIndex()
        td = self.tabbar.tabData(i)['object']
        wv = self.findChild(QWidget, td).content

        if 'http' not in text:
            if "." not in text:
                url = "https://www.google.ca/#q={}".format(text)
            else:
                url = "http://{}".format(text)
        else:
            url = text

        wv.load(QUrl.fromUserInput(url))

    def SetTabContent(self, i, type):
        tab_name = self.tabs[i].objectName()
        count = 0
        running = True
        curr_tab = self.tabbar.tabData(self.tabbar.currentIndex())['object']

        if curr_tab == tab_name and type == 'url':
            new_url = self.findChild(QWidget,
                                     tab_name).content.url().toString()
            self.addressbar.setText(new_url)
            return False

        while running:
            tab_data_name = self.tabbar.tabData(count)

            if count >= 99:
                running = False
            if tab_name == tab_data_name['object']:
                if type == 'title':
                    newTitle = self.findChild(QWidget,
                                              tab_name).content.title()
                    self.tabbar.setTabText(count, newTitle)
                elif type == 'icon':
                    newIcon = self.findChild(QWidget, tab_name).content.icon()
                    self.tabbar.setTabIcon(count, newIcon)
                running = False
            else:
                count += 1

    def GoForward(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)['object']
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.forward()

    def GoBack(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)['object']
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.back()

    def Reload(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)['object']
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.reload()
Exemple #22
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Python QT Web Browser")

        self.setMinimumSize(1920, 1200)
        self.CreateApp()
        self.setWindowIcon(QIcon("resources/icons/PyQt.jpg"))

    def CreateApp(self):
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        # Create Tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.CloseTab)
        self.tabbar.tabBarClicked.connect(self.SwitchTab)
        self.tabbar.setCurrentIndex(0)
        self.tabbar.setDrawBase(False)
        self.tabbar.setLayoutDirection(Qt.LeftToRight)
        self.tabbar.setElideMode(Qt.ElideLeft)

        self.shortcutNewTab = QShortcut(QKeySequence("Ctrl+T"), self)
        self.shortcutNewTab.activated.connect(self.AddTab)

        self.shortcutReload = QShortcut(QKeySequence("Ctrl+R"), self)
        self.shortcutReload.activated.connect(self.ReloadPage)

        # Keep track of the tabs
        self.tabCount = 0
        self.tabs = []

        # Create AddressBar
        self.Toolbar = QWidget()
        self.Toolbar.setObjectName("Toolbar")
        self.ToolbarLayout = QHBoxLayout()
        self.addressbar = AddressBar()
        self.AddTabButton = QPushButton("+")

        # Connect AddressBar + button Signals
        self.addressbar.returnPressed.connect(self.BrowseTo)
        self.AddTabButton.clicked.connect(self.AddTab)

        # Set Toolbar Buttons
        self.BackButton = QPushButton("<")
        self.BackButton.clicked.connect(self.GoBack)

        self.ForwardButton = QPushButton(">")
        self.ForwardButton.clicked.connect(self.GoForward)

        self.ReloadButton = QPushButton("R")
        self.ReloadButton.clicked.connect(self.ReloadPage)

        # Build toolbar
        self.Toolbar.setLayout(self.ToolbarLayout)
        self.ToolbarLayout.addWidget(self.BackButton)
        self.ToolbarLayout.addWidget(self.ForwardButton)
        self.ToolbarLayout.addWidget(self.ReloadButton)
        self.ToolbarLayout.addWidget(self.addressbar)
        self.ToolbarLayout.addWidget(self.AddTabButton)

        # Set main view
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        # Construct main view from top level elements
        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.Toolbar)
        self.layout.addWidget(self.container)

        self.setLayout(self.layout)

        self.AddTab()

        self.show()

    def CloseTab(self, i):
        self.tabbar.removeTab(i)

    def AddTab(self):
        i = self.tabCount

        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setContentsMargins(0, 0, 0, 0)

        # For tab switching
        self.tabs[i].setObjectName("tab" + str(i))

        # Create webview within the tabs top level widget
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("https://www.google.ie/"))

        # Add widget to tab.layout.
        self.tabs[i].content.titleChanged.connect(
            lambda: self.SetTabContent(i, "title"))
        self.tabs[i].content.iconChanged.connect(
            lambda: self.SetTabContent(i, "icon"))
        self.tabs[i].content.urlChanged.connect(
            lambda: self.SetTabContent(i, "url"))

        # Add webview to tabs layout
        self.tabs[i].splitview = QSplitter()
        self.tabs[i].layout.addWidget(self.tabs[i].splitview)

        self.tabs[i].splitview.addWidget(self.tabs[i].content)

        # set top level tab from [] to layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        # Add tabe to top level stackedwidget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        # Set the tab at the top of the screen
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {"object": "tab" + str(i), "initial": i})

        self.tabbar.setCurrentIndex(i)

        self.tabCount += 1

    def SwitchTab(self, i):
        # Switch to tab
        if self.tabbar.tabData(i):
            tab_data = self.tabbar.tabData(i)["object"]
            tab_content = self.findChild(QWidget, tab_data)
            self.container.layout.setCurrentWidget(tab_content)
            new_url = tab_content.content.url().toString()
            self.addressbar.setText(new_url)

    def BrowseTo(self):
        text = self.addressbar.text()
        print(text)

        i = self.tabbar.currentIndex()
        tab = self.tabbar.tabData(i)["object"]
        wv = self.findChild(QWidget, tab).content

        if "http" not in text:
            if "." not in text:
                url = "https://www.google.ie/#q=" + text
            else:
                url = "http://" + text
        else:
            url = text

        wv.load(QUrl.fromUserInput(url))

    def SetTabContent(self, i, type):
        tab_name = self.tabs[i].objectName()
        # tab1

        count = 0
        running = True

        current_tab = self.tabbar.tabData(self.tabbar.currentIndex())["object"]

        if current_tab == tab_name and type == "url":
            new_url = self.findChild(QWidget,
                                     tab_name).content.url().toString()
            self.addressbar.setText(new_url)
            return False

        while running:
            tab_data_name = self.tabbar.tabData(count)

            if count >= 99:
                running = False

            if tab_name == tab_data_name["object"]:
                if type == "title":
                    newTitle = self.findChild(QWidget,
                                              tab_name).content.title()
                    self.tabbar.setTabText(count, newTitle)
                elif type == "icon":
                    newIcon = self.findChild(QWidget, tab_name).content.icon()
                    self.tabbar.setTabIcon(count, newIcon)

                running = False
            else:
                count += 1

    def GoBack(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.back()

    def GoForward(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.forward()

    def ReloadPage(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.reload()
Exemple #23
0
class CMWConfig(QWidget):
    """CMWConfig is a QWidget with tabs for configuration management"""
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        #self.lab_title  = QLabel     ('Configuration settings')
        #self.lab_status = QLabel     ('Status: ')
        self.but_close = QPushButton('&Close')
        self.but_save = QPushButton('&Save')
        self.but_show = QPushButton('Show &Image')

        self.hboxW = QHBoxLayout()
        self.hboxB = QHBoxLayout()
        #self.hboxB.addWidget(self.lab_status)
        self.hboxB.addStretch(1)
        self.hboxB.addWidget(self.but_close)
        self.hboxB.addWidget(self.but_save)
        self.hboxB.addWidget(self.but_show)

        self.tab_names = ['Parameters', 'Configuration File']

        self.gui_win = None

        self.make_tab_bar()
        self.gui_selector(cp.current_config_tab.value())

        self.vbox = QVBoxLayout()
        self.vbox.addWidget(self.tab_bar)
        self.vbox.addLayout(self.hboxW)
        self.vbox.addStretch(1)
        self.vbox.addLayout(self.hboxB)
        self.setLayout(self.vbox)

        self.but_close.clicked.connect(self.on_close)
        self.but_save.clicked.connect(self.on_save)
        self.but_show.clicked.connect(self.on_show)

        self.set_tool_tips()
        self.set_style()

    def set_tool_tips(self):
        #msg = 'Edit field'
        self.but_close.setToolTip('Close this window.')
        self.but_save.setToolTip('Save all current configuration parameters.')
        self.but_show.setToolTip('Show ...')

    def set_style(self):
        self.setStyleSheet(style.styleBkgd)
        self.but_close.setStyleSheet(style.styleButton)
        self.but_save.setStyleSheet(style.styleButton)
        self.but_show.setStyleSheet(style.styleButton)

        self.setMinimumSize(600, 360)

        is_visible = False
        #self.lab_status.setVisible(False)
        self.but_close.setVisible(is_visible)
        self.but_save.setVisible(is_visible)
        self.but_show.setVisible(is_visible)

    def make_tab_bar(self):
        self.tab_bar = QTabBar()

        #Uses self.tab_names
        self.ind_tab_0 = self.tab_bar.addTab(self.tab_names[0])
        self.ind_tab_1 = self.tab_bar.addTab(self.tab_names[1])

        self.tab_bar.setTabTextColor(self.ind_tab_0, QColor('magenta'))
        self.tab_bar.setTabTextColor(self.ind_tab_1, QColor('magenta'))
        self.tab_bar.setShape(QTabBar.RoundedNorth)

        #self.tab_bar.setTabsClosable(True)
        #self.tab_bar.setMovable(True)

        #self.tab_bar.setTabEnabled(1, False)
        #self.tab_bar.setTabEnabled(2, False)

        tab_index = self.tab_names.index(cp.current_config_tab.value())
        #try :
        #    tab_index = self.tab_names.index(cp.current_config_tab.value())
        #except :
        #    tab_index = 1
        #    cp.current_config_tab.setValue(self.tab_names[tab_index])

        self.tab_bar.setCurrentIndex(tab_index)

        logger.debug(' make_tab_bar - set tab: ' +
                     cp.current_config_tab.value())

        #self.connect(self.tab_bar, QtCore.SIGNAL('currentChanged(int)'), self.on_tab_bar)
        self.tab_bar.currentChanged[int].connect(self.on_tab_bar)

    def gui_selector(self, tab_name):

        #try    : self.gui_win.close()
        #except : pass

        #try    : del self.gui_win
        #except : pass

        if self.gui_win is not None:
            self.gui_win.close()
            del self.gui_win

        w_height = 120

        if tab_name == self.tab_names[0]:
            self.gui_win = CMWConfigPars(self)

        elif tab_name == self.tab_names[1]:
            self.gui_win = CMWConfigFile(self)
            w_height = 170

        else:
            logger.warning('Unknown tab name "%s"' % tab_name)

        #self.set_status(0, 'Set configuration file')
        self.gui_win.setFixedHeight(w_height)
        self.hboxW.addWidget(self.gui_win)
        self.gui_win.setVisible(True)

    def current_tab_index_and_name(self):
        tab_ind = self.tab_bar.currentIndex()
        tab_name = str(self.tab_bar.tabText(tab_ind))
        return tab_ind, tab_name

    def on_tab_bar(self):
        tab_ind, tab_name = self.current_tab_index_and_name()
        logger.info('Selected tab "%s"' % tab_name)
        cp.current_config_tab.setValue(tab_name)
        self.gui_selector(tab_name)

    def set_parent(self, parent):
        self.parent = parent

    #def resizeEvent(self, e):
    #logger.debug('resizeEvent')
    #print self._name + ' config: self.size():', self.size()
    #self.setMinimumSize( self.size().width(), self.size().height()-40 )
    #pass

    #def moveEvent(self, e):
    #logger.debug('moveEvent')
    #self.position = self.mapToGlobal(self.pos())
    #self.position = self.pos()
    #logger.debug('moveEvent: new pos:' + str(self.position))
    #pass

    def closeEvent(self, e):
        logger.debug('closeEvent')

        self.tab_bar.close()
        if self.gui_win is not None: self.gui_win.close()

        QWidget.close(self)

    def on_close(self):
        logger.debug('on_close')
        self.close()

    def on_save(self):
        logger.debug('on_save')
        cp.saveParametersInFile(cp.fname_cp.value())

    def on_show(self):
        logger.debug('on_show - is not implemented yet...')
Exemple #24
0
class SubTabWidget(QWidget):
    _tabChanged = pyqtSignal(int, name = "tabChanged")

    def __init__(self, subtitleData, videoWidget, parent = None):
        super(SubTabWidget, self).__init__(parent)
        self._subtitleData = subtitleData
        self.__initTabWidget(videoWidget)

    def __initTabWidget(self, videoWidget):
        settings = SubSettings()

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

        #TabBar
        self.tabBar = QTabBar(self)

        # Splitter (bookmarks + pages)
        self.splitter = QSplitter(self)
        self.splitter.setObjectName("sidebar_splitter")

        self._toolbox = ToolBox(self._subtitleData, self)
        self._toolbox.setObjectName("sidebar")
        self._toolbox.setMinimumWidth(100)

        self._toolbox.addTool(Details(self._subtitleData, self))
        self._toolbox.addTool(Synchronizer(videoWidget, self._subtitleData, self))
        self._toolbox.addTool(History(self))

        self.rightWidget = QWidget()
        rightLayout = QGridLayout()
        rightLayout.setContentsMargins(0, 0, 0, 0)
        self.rightWidget.setLayout(rightLayout)

        self._mainTab = FileList(_("Subtitles"), self._subtitleData, self)

        self.pages = QStackedWidget(self)
        rightLayout.addWidget(self.pages, 0, 0)

        self.tabBar.addTab(self._mainTab.name)
        self.pages.addWidget(self._mainTab)

        self.splitter.addWidget(self._toolbox)
        self.splitter.addWidget(self.rightWidget)
        self.__drawSplitterHandle(1)

        # Setting widgets
        mainLayout.addWidget(self.tabBar)
        mainLayout.addWidget(self.splitter)

        # Widgets settings
        self.tabBar.setMovable(True)
        self.tabBar.setTabsClosable(True)
        self.tabBar.setExpanding(False)

        # Don't resize left panel if it's not needed
        leftWidgetIndex = self.splitter.indexOf(self._toolbox)
        rightWidgetIndex = self.splitter.indexOf(self.rightWidget)

        self.splitter.setStretchFactor(leftWidgetIndex, 0)
        self.splitter.setStretchFactor(rightWidgetIndex, 1)
        self.splitter.setCollapsible(leftWidgetIndex, False)
        self.splitter.setSizes([250])

        # Some signals
        self.tabBar.currentChanged.connect(self.showTab)
        self.tabBar.tabCloseRequested.connect(self.closeTab)
        self.tabBar.tabMoved.connect(self.moveTab)
        self._mainTab.requestOpen.connect(self.openTab)
        self._mainTab.requestRemove.connect(self.removeFile)

        self.tabChanged.connect(lambda i: self._toolbox.setContentFor(self.tab(i)))

        self.setLayout(mainLayout)

    def __addTab(self, filePath):
        """Returns existing tab index. Creates a new one if it isn't opened and returns its index
        otherwise."""
        for i in range(self.tabBar.count()):
            widget = self.pages.widget(i)
            if not widget.isStatic and filePath == widget.filePath:
                return i
        tab = SubtitleEditor(filePath, self._subtitleData, self)
        newIndex = self.tabBar.addTab(self._createTabName(tab.name, tab.history.isClean()))
        tab.history.cleanChanged.connect(
            lambda clean: self._cleanStateForFileChanged(filePath, clean))
        self.pages.addWidget(tab)
        return newIndex

    def __drawSplitterHandle(self, index):
        splitterHandle = self.splitter.handle(index)

        splitterLayout = QVBoxLayout(splitterHandle)
        splitterLayout.setSpacing(0)
        splitterLayout.setContentsMargins(0, 0, 0, 0)

        line = QFrame(splitterHandle)
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        splitterLayout.addWidget(line)
        splitterHandle.setLayout(splitterLayout)

    def _createTabName(self, name, cleanState):
        if cleanState is True:
            return name
        else:
            return "%s +" % name

    def _cleanStateForFileChanged(self, filePath, cleanState):
        page = self.tabByPath(filePath)
        if page is not None:
            for i in range(self.tabBar.count()):
                if self.tabBar.tabText(i)[:len(page.name)] == page.name:
                    self.tabBar.setTabText(i, self._createTabName(page.name, cleanState))
                    return

    def saveWidgetState(self, settings):
        settings.setState(self.splitter, self.splitter.saveState())
        settings.setHidden(self._toolbox, self._toolbox.isHidden())

    def restoreWidgetState(self, settings):
        self.showPanel(not settings.getHidden(self._toolbox))

        splitterState = settings.getState(self.splitter)
        if not splitterState.isEmpty():
            self.splitter.restoreState(settings.getState(self.splitter))

    @pyqtSlot(str, bool)
    def openTab(self, filePath, background=False):
        if self._subtitleData.fileExists(filePath):
            tabIndex = self.__addTab(filePath)
            if background is False:
                self.showTab(tabIndex)
        else:
            log.error(_("SubtitleEditor not created for %s!" % filePath))

    @pyqtSlot(str)
    def removeFile(self, filePath):
        tab = self.tabByPath(filePath)
        command = RemoveFile(filePath)
        if tab is not None:
            index = self.pages.indexOf(tab)
            if self.closeTab(index):
                self._subtitleData.execute(command)
        else:
            self._subtitleData.execute(command)


    @pyqtSlot(int)
    def closeTab(self, index):
        tab = self.tab(index)
        if tab.canClose():
            widgetToRemove = self.pages.widget(index)
            self.tabBar.removeTab(index)
            self.pages.removeWidget(widgetToRemove)
            widgetToRemove.deleteLater()
            return True
        return False


    def count(self):
        return self.tabBar.count()

    def currentIndex(self):
        return self.tabBar.currentIndex()

    def currentPage(self):
        return self.pages.currentWidget()

    @pyqtSlot(int, int)
    def moveTab(self, fromIndex, toIndex):
        fromWidget = self.pages.widget(fromIndex)
        toWidget = self.pages.widget(toIndex)
        if fromWidget.isStatic or toWidget.isStatic:
            self.tabBar.blockSignals(True) # signals would cause infinite recursion
            self.tabBar.moveTab(toIndex, fromIndex)
            self.tabBar.blockSignals(False)
            return
        else:
            self.pages.removeWidget(fromWidget)
            self.pages.removeWidget(toWidget)

            if fromIndex < toIndex:
                self.pages.insertWidget(fromIndex, toWidget)
                self.pages.insertWidget(toIndex, fromWidget)
            else:
                self.pages.insertWidget(toIndex, fromWidget)
                self.pages.insertWidget(fromIndex, toWidget)

            # Hack
            # Qt changes tabs during mouse drag and dropping. The next line is added
            # to prevent it.
            self.showTab(self.tabBar.currentIndex())

    @pyqtSlot(int)
    def showTab(self, index):
        showWidget = self.pages.widget(index)
        if showWidget:
            self.pages.setCurrentWidget(showWidget)
            self.tabBar.blockSignals(True)
            self.tabBar.setCurrentIndex(index)
            self.tabBar.blockSignals(False)

            # Try to update current tab.
            showWidget.updateTab()

            self._tabChanged.emit(index)

    def showPanel(self, val):
        if val is True:
            self._toolbox.show()
        else:
            self._toolbox.hide()

    def togglePanel(self):
        if self._toolbox.isHidden():
            self._toolbox.show()
        else:
            self._toolbox.hide()

    def tab(self, index):
        return self.pages.widget(index)

    def tabByPath(self, path):
        for i in range(self.pages.count()):
            page = self.tab(i)
            if not page.isStatic and page.filePath == path:
                return page
        return None

    @property
    def fileList(self):
        return self._mainTab
Exemple #25
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Web Browser")

        self.create_app()
        self.setMinimumSize(1366, 768)
        self.setBaseSize(1366, 786)
        self.setWindowIcon(QIcon("TA logo BLK.png"))

    def create_app(self):
        # Setting main window layout
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0, 0, 0, 0)

        # Create keyboard shortcut --> new tab, reload
        self.shortcut_newtab = QShortcut(QKeySequence("Ctrl+t"), self)
        self.shortcut_newtab.activated.connect(self.add_tab)

        self.shortcut_reload = QShortcut(QKeySequence("Ctrl+r"), self)
        self.shortcut_reload.activated.connect(self.reload_page)

        # Create tabs --> Set tab bar, add tabs, close tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.close_tab)
        # Switch tab bar when clicked
        self.tabbar.tabBarClicked.connect(self.switch_tab)
        # Set index, tell which tab active
        self.tabbar.setCurrentIndex(0)
        self.tabbar.setDrawBase(False)

        # Keep track of tabs and content
        self.tab_count = 0
        self.tabs = []

        # Create address bar
        self.toolbar = QWidget()
        self.toolbar.setObjectName("Toolbar")
        self.toolbar_layout = QHBoxLayout()
        self.addressbar = AddressBar()

        # Connect address bar, button signal --> new tab, back, forward
        self.addressbar.returnPressed.connect(self.browse_to)

        self.add_tab_button = QPushButton("+")
        self.add_tab_button.clicked.connect(self.add_tab)

        self.back_button = QPushButton("<-")
        self.back_button.clicked.connect(self.go_back)

        self.forward_button = QPushButton("->")
        self.forward_button.clicked.connect(self.go_forward)

        self.reload_button = QPushButton("R")
        self.reload_button.clicked.connect(self.reload_page)

        # Create toolbar widget, add item
        self.toolbar.setLayout(self.toolbar_layout)
        self.toolbar_layout.addWidget(self.back_button)
        self.toolbar_layout.addWidget(self.forward_button)
        self.toolbar_layout.addWidget(self.reload_button)
        self.toolbar_layout.addWidget(self.addressbar)
        self.toolbar_layout.addWidget(self.add_tab_button)

        # Set main view, stacked layout
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        # Put elements in widget, set layout to widget
        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.toolbar)
        self.layout.addWidget(self.container)

        self.setLayout(self.layout)
        self.add_tab()
        self.show()

    # Close tab, pass index
    def close_tab(self, i):
        self.tabbar.removeTab(i)

    # Add tabs
    def add_tab(self):
        i = self.tab_count

        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setContentsMargins(0, 0, 0, 0)

        # Set object name, for switching tabs
        self.tabs[i].setObjectName("tab" + str(i))

        # Web engine view --> object page loads into
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("http://wwww.bing.com"))
        """
        # Add to code for second window of splitview
        self.tabs[i].content1 = QWebEngineView()
        self.tabs[i].content1.load(QUrl.fromUserInput("http://wwww.bing.com"))
        """

        # Update title text, icon, address bar
        self.tabs[i].content.titleChanged.connect(
            lambda: self.set_tab_content(i, "title"))
        self.tabs[i].content.iconChanged.connect(
            lambda: self.set_tab_content(i, "icon"))
        self.tabs[i].content.urlChanged.connect(
            lambda: self.set_tab_content(i, "url"))

        # Add webview content to layout (good for developer tools)
        self.tabs[i].splitview = QSplitter()
        self.tabs[i].splitview.setOrientation(Qt.Vertical)
        self.tabs[i].layout.addWidget(self.tabs[i].splitview)
        """
        # Add content to split view
        self.tabs[i].splitview.addWidget(self.tabs[i].content)
        self.tabs[i].splitview.addWidget(self.tabs[i].content1)
        """

        # Set top level tab from list to layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        # Add tab to top level stacked Widget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        # Show tab at top of screen, set tab data to website of tab
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {"object": "tab" + str(i), "initial": i})

        self.tabbar.setCurrentIndex(i)

        # Add to tab count
        self.tab_count += 1

    def switch_tab(self, i):
        # Get tab data, return object name want to switch to
        tab_data = self.tabbar.tabData(i)["object"]

        # If tab data exists, can click on tabs
        if self.tabbar.tabData(i):
            # Make tab index static
            tab_widget = self.findChild(QWidget, tab_data)
            self.container.layout.setCurrentWidget(tab_widget)

            # Change url in address bar with tab change
            new_url = tab_widget.content.url().toString()
            self.addressbar.setText(new_url)

    def browse_to(self):
        # Get text in address bar
        text = self.addressbar.text()

        # Get index # of current tab, get tab name, get webview associate with name
        i = self.tabbar.currentIndex()
        tab = self.tabbar.tabData(i)["object"]
        web_view = self.findChild(QWidget, tab).content

        # Check if address or search term
        if "http" not in text:
            if "." not in text:
                url = "https://www.bing.com/search?q=" + text
            else:
                url = "http://" + text
        else:
            url = text

        web_view.load(QUrl.fromUserInput(url))

    def set_tab_content(self, i, type):
        """
        self.tabs[i].objectName = tab1
        self.tabbar.tabData(i)["object"] = tab1
        """
        tab_name = self.tabs[i].objectName()

        count = 0
        running = True

        current_tab = self.tabbar.tabData(self.tabbar.currentIndex())["object"]

        if current_tab == tab_name and type == "url":
            new_url = self.findChild(QWidget,
                                     tab_name).content.url().toString()
            self.addressbar.setText(new_url)
            return False

        while running:
            # Get tab data
            tab_data_name = self.tabbar.tabData(count)

            if count >= 99:
                running = False

            if tab_name == tab_data_name["object"]:
                if type == "title":
                    new_title = self.findChild(QWidget,
                                               tab_name).content.title()
                    self.tabbar.setTabText(count, new_title)
                elif type == "icon":
                    new_icon = self.findChild(QWidget, tab_name).content.icon()
                    self.tabbar.setTabIcon(count, new_icon)
                running = False
            else:
                count += 1

    def go_back(self):
        active_index = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(active_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.back()

    def go_forward(self):
        active_index = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(active_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.forward()

    def reload_page(self):
        active_index = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(active_index)["object"]
        tab_content = self.findChild(QWidget, tab_name).content

        tab_content.reload()
Exemple #26
0
class ImportWindow(QDialog):
    def __init__(self, model, mainwindow, prefs):
        QDialog.__init__(self, mainwindow, Qt.Window)
        self.prefs = prefs
        self._setupUi()
        self.prefs.restoreGeometry('importWindowGeometry', self)
        self.doc = mainwindow.doc
        self.model = model
        self.swapOptionsComboBox = ComboboxModel(
            model=self.model.swap_type_list, view=self.swapOptionsComboBoxView)
        self.table = ImportTable(model=self.model.import_table,
                                 view=self.tableView)
        self._setupColumns(
        )  # Can only be done after the model has been connected

        self.targetAccountComboBox.addItems(self.model.target_account_names)
        for pane in self.model.panes:
            self.tabView.addTab(pane.name)

        self.tabView.tabCloseRequested.connect(self.tabCloseRequested)
        self.tabView.currentChanged.connect(self.currentTabChanged)
        self.targetAccountComboBox.currentIndexChanged.connect(
            self.targetAccountChanged)
        self.closeButton.clicked.connect(self.close)
        self.importButton.clicked.connect(self.importClicked)
        self.matchButton.clicked.connect(self.matchClicked)
        self.swapButton.clicked.connect(self.swapClicked)

    def _setupUi(self):
        self.setWindowTitle(tr("Import"))
        self.resize(557, 407)
        self.setModal(True)
        self.verticalLayout = QVBoxLayout(self)
        self.tabView = QTabBar(self)
        self.tabView.setMinimumHeight(20)
        self.verticalLayout.addWidget(self.tabView)
        self.targetAccountLayout = QHBoxLayout()
        self.targetAccountLabel = QLabel(tr("Target Account:"))
        self.targetAccountLayout.addWidget(self.targetAccountLabel)
        self.targetAccountComboBox = QComboBox(self)
        self.targetAccountComboBox.setMinimumWidth(150)
        self.targetAccountLayout.addWidget(self.targetAccountComboBox)
        self.targetAccountLayout.addItem(horizontalSpacer())

        self.matchBox = QGroupBox(tr("Match entries by date/amount"))
        self.matchBox.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
        matchLayout = QVBoxLayout(self.matchBox)
        self.matchThreshold = QSpinBox()
        label = QLabel(tr("maximum day(s)"))
        matchLayout.addLayout(horizontalWrap([self.matchThreshold, label]))
        self.matchButton = QPushButton(tr("Match"))
        self.matchButton.setSizePolicy(QSizePolicy.Maximum,
                                       QSizePolicy.Preferred)
        matchLayout.addLayout(horizontalWrap([None, self.matchButton]))

        self.targetAccountLayout.addWidget(self.matchBox)
        self.swapBox = QGroupBox(tr("Are some fields wrong? Fix them!"))
        swapLayout = QVBoxLayout(self.swapBox)
        self.swapOptionsComboBoxView = QComboBox(self.swapBox)
        swapLayout.addWidget(self.swapOptionsComboBoxView)
        self.applyToAllCheckBox = QCheckBox(tr("Apply to all accounts"))
        self.swapButton = QPushButton(tr("Fix"))
        swapLayout.addLayout(
            horizontalWrap([self.applyToAllCheckBox, self.swapButton]))
        self.targetAccountLayout.addWidget(self.swapBox)

        self.verticalLayout.addLayout(self.targetAccountLayout)
        self.tableView = TableView(self)
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableView.setDragEnabled(True)
        self.tableView.setDragDropMode(QAbstractItemView.InternalMove)
        self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.horizontalHeader().setHighlightSections(False)
        self.tableView.horizontalHeader().setMinimumSectionSize(18)
        self.tableView.verticalHeader().setVisible(False)
        self.tableView.verticalHeader().setDefaultSectionSize(18)
        self.verticalLayout.addWidget(self.tableView)
        self.horizontalLayout = QHBoxLayout()
        spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                  QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)
        self.closeButton = QPushButton(tr("Close"))
        self.horizontalLayout.addWidget(self.closeButton)
        self.importButton = QPushButton(tr("Import"))
        self.horizontalLayout.addWidget(self.importButton)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.tabView.setTabsClosable(True)
        self.tabView.setDrawBase(False)
        self.tabView.setDocumentMode(True)
        self.tabView.setUsesScrollButtons(True)

    def _setupColumns(self):
        # Can't set widget alignment in a layout in the Designer
        l = self.targetAccountLayout
        l.setAlignment(self.targetAccountLabel, Qt.AlignTop)
        l.setAlignment(self.targetAccountComboBox, Qt.AlignTop)

    # --- Event Handlers
    def close(self):
        self.prefs.saveGeometry('importWindowGeometry', self)
        super().close()

    def currentTabChanged(self, index):
        self.model.selected_pane_index = index

    def importClicked(self):
        self.model.import_selected_pane()

    def matchClicked(self):
        threshold = self.matchThreshold.value()
        self.model.match_entries_by_date_and_amount(threshold)

    def swapClicked(self):
        applyToAll = self.applyToAllCheckBox.isChecked()
        self.model.perform_swap(apply_to_all=applyToAll)

    def tabCloseRequested(self, index):
        self.model.close_pane(index)
        self.tabView.removeTab(index)

    def targetAccountChanged(self, index):
        self.model.selected_target_account_index = index
        self.table.updateColumnsVisibility()

    # --- model --> view
    def close_selected_tab(self):
        self.tabView.removeTab(self.tabView.currentIndex())

    def set_swap_button_enabled(self, enabled):
        self.swapButton.setEnabled(enabled)

    def update_selected_pane(self):
        index = self.model.selected_pane_index
        if index != self.tabView.currentIndex(
        ):  # this prevents infinite loops
            self.tabView.setCurrentIndex(index)
        self.targetAccountComboBox.setCurrentIndex(
            self.model.selected_target_account_index)
        self.table.updateColumnsVisibility()
Exemple #27
0
class TilesetDock(QDockWidget):
    ##
    # Emitted when the current tile changed.
    ##
    currentTileChanged = pyqtSignal(list)
    ##
    # Emitted when the currently selected tiles changed.
    ##
    stampCaptured = pyqtSignal(TileStamp)
    ##
    # Emitted when files are dropped at the tileset dock.
    ##
    tilesetsDropped = pyqtSignal(QStringList)
    newTileset = pyqtSignal()

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

        # Shared tileset references because the dock wants to add new tiles
        self.mTilesets = QVector()
        self.mCurrentTilesets = QMap()
        self.mMapDocument = None
        self.mTabBar = QTabBar()
        self.mViewStack = QStackedWidget()
        self.mToolBar = QToolBar()
        self.mCurrentTile = None
        self.mCurrentTiles = None
        self.mNewTileset = QAction(self)
        self.mImportTileset = QAction(self)
        self.mExportTileset = QAction(self)
        self.mPropertiesTileset = QAction(self)
        self.mDeleteTileset = QAction(self)
        self.mEditTerrain = QAction(self)
        self.mAddTiles = QAction(self)
        self.mRemoveTiles = QAction(self)
        self.mTilesetMenuButton = TilesetMenuButton(self)
        self.mTilesetMenu = QMenu(self)  # opens on click of mTilesetMenu
        self.mTilesetActionGroup = QActionGroup(self)
        self.mTilesetMenuMapper = None  # needed due to dynamic content
        self.mEmittingStampCaptured = False
        self.mSynchronizingSelection = False

        self.setObjectName("TilesetDock")
        self.mTabBar.setMovable(True)
        self.mTabBar.setUsesScrollButtons(True)
        self.mTabBar.currentChanged.connect(self.updateActions)
        self.mTabBar.tabMoved.connect(self.moveTileset)
        w = QWidget(self)
        horizontal = QHBoxLayout()
        horizontal.setSpacing(0)
        horizontal.addWidget(self.mTabBar)
        horizontal.addWidget(self.mTilesetMenuButton)
        vertical = QVBoxLayout(w)
        vertical.setSpacing(0)
        vertical.setContentsMargins(5, 5, 5, 5)
        vertical.addLayout(horizontal)
        vertical.addWidget(self.mViewStack)
        horizontal = QHBoxLayout()
        horizontal.setSpacing(0)
        horizontal.addWidget(self.mToolBar, 1)
        vertical.addLayout(horizontal)
        self.mNewTileset.setIcon(QIcon(":images/16x16/document-new.png"))
        self.mImportTileset.setIcon(QIcon(":images/16x16/document-import.png"))
        self.mExportTileset.setIcon(QIcon(":images/16x16/document-export.png"))
        self.mPropertiesTileset.setIcon(
            QIcon(":images/16x16/document-properties.png"))
        self.mDeleteTileset.setIcon(QIcon(":images/16x16/edit-delete.png"))
        self.mEditTerrain.setIcon(QIcon(":images/16x16/terrain.png"))
        self.mAddTiles.setIcon(QIcon(":images/16x16/add.png"))
        self.mRemoveTiles.setIcon(QIcon(":images/16x16/remove.png"))
        Utils.setThemeIcon(self.mNewTileset, "document-new")
        Utils.setThemeIcon(self.mImportTileset, "document-import")
        Utils.setThemeIcon(self.mExportTileset, "document-export")
        Utils.setThemeIcon(self.mPropertiesTileset, "document-properties")
        Utils.setThemeIcon(self.mDeleteTileset, "edit-delete")
        Utils.setThemeIcon(self.mAddTiles, "add")
        Utils.setThemeIcon(self.mRemoveTiles, "remove")
        self.mNewTileset.triggered.connect(self.newTileset)
        self.mImportTileset.triggered.connect(self.importTileset)
        self.mExportTileset.triggered.connect(self.exportTileset)
        self.mPropertiesTileset.triggered.connect(self.editTilesetProperties)
        self.mDeleteTileset.triggered.connect(self.removeTileset)
        self.mEditTerrain.triggered.connect(self.editTerrain)
        self.mAddTiles.triggered.connect(self.addTiles)
        self.mRemoveTiles.triggered.connect(self.removeTiles)
        self.mToolBar.addAction(self.mNewTileset)
        self.mToolBar.setIconSize(QSize(16, 16))
        self.mToolBar.addAction(self.mImportTileset)
        self.mToolBar.addAction(self.mExportTileset)
        self.mToolBar.addAction(self.mPropertiesTileset)
        self.mToolBar.addAction(self.mDeleteTileset)
        self.mToolBar.addAction(self.mEditTerrain)
        self.mToolBar.addAction(self.mAddTiles)
        self.mToolBar.addAction(self.mRemoveTiles)
        self.mZoomable = Zoomable(self)
        self.mZoomComboBox = QComboBox()
        self.mZoomable.connectToComboBox(self.mZoomComboBox)
        horizontal.addWidget(self.mZoomComboBox)
        self.mViewStack.currentChanged.connect(self.updateCurrentTiles)
        TilesetManager.instance().tilesetChanged.connect(self.tilesetChanged)
        DocumentManager.instance().documentAboutToClose.connect(
            self.documentAboutToClose)
        self.mTilesetMenuButton.setMenu(self.mTilesetMenu)
        self.mTilesetMenu.aboutToShow.connect(self.refreshTilesetMenu)
        self.setWidget(w)
        self.retranslateUi()
        self.setAcceptDrops(True)
        self.updateActions()

    def __del__(self):
        del self.mCurrentTiles

    ##
    # Sets the map for which the tilesets should be displayed.
    ##
    def setMapDocument(self, mapDocument):
        if (self.mMapDocument == mapDocument):
            return
        # Hide while we update the tab bar, to avoid repeated layouting
        if sys.platform != 'darwin':
            self.widget().hide()

        self.setCurrentTiles(None)
        self.setCurrentTile(None)

        if (self.mMapDocument):
            # Remember the last visible tileset for this map
            tilesetName = self.mTabBar.tabText(self.mTabBar.currentIndex())
            self.mCurrentTilesets.insert(self.mMapDocument, tilesetName)

        # Clear previous content
        while (self.mTabBar.count()):
            self.mTabBar.removeTab(0)
        while (self.mViewStack.count()):
            self.mViewStack.removeWidget(self.mViewStack.widget(0))
        #self.mTilesets.clear()
        # Clear all connections to the previous document
        if (self.mMapDocument):
            self.mMapDocument.disconnect()
        self.mMapDocument = mapDocument
        if (self.mMapDocument):
            self.mTilesets = self.mMapDocument.map().tilesets()
            for tileset in self.mTilesets:
                view = TilesetView()
                view.setMapDocument(self.mMapDocument)
                view.setZoomable(self.mZoomable)
                self.mTabBar.addTab(tileset.name())
                self.mViewStack.addWidget(view)

            self.mMapDocument.tilesetAdded.connect(self.tilesetAdded)
            self.mMapDocument.tilesetRemoved.connect(self.tilesetRemoved)
            self.mMapDocument.tilesetMoved.connect(self.tilesetMoved)
            self.mMapDocument.tilesetNameChanged.connect(
                self.tilesetNameChanged)
            self.mMapDocument.tilesetFileNameChanged.connect(
                self.updateActions)
            self.mMapDocument.tilesetChanged.connect(self.tilesetChanged)
            self.mMapDocument.tileAnimationChanged.connect(
                self.tileAnimationChanged)
            cacheName = self.mCurrentTilesets.take(self.mMapDocument)
            for i in range(self.mTabBar.count()):
                if (self.mTabBar.tabText(i) == cacheName):
                    self.mTabBar.setCurrentIndex(i)
                    break

            object = self.mMapDocument.currentObject()
            if object:
                if object.typeId() == Object.TileType:
                    self.setCurrentTile(object)

        self.updateActions()
        if sys.platform != 'darwin':
            self.widget().show()

    ##
    # Synchronizes the selection with the given stamp. Ignored when the stamp is
    # changing because of a selection change in the TilesetDock.
    ##
    def selectTilesInStamp(self, stamp):
        if self.mEmittingStampCaptured:
            return
        processed = QSet()
        selections = QMap()
        for variation in stamp.variations():
            tileLayer = variation.tileLayer()
            for cell in tileLayer:
                tile = cell.tile
                if tile:
                    if (processed.contains(tile)):
                        continue
                    processed.insert(tile)  # avoid spending time on duplicates
                    tileset = tile.tileset()
                    tilesetIndex = self.mTilesets.indexOf(
                        tileset.sharedPointer())
                    if (tilesetIndex != -1):
                        view = self.tilesetViewAt(tilesetIndex)
                        if (not view.model()):  # Lazily set up the model
                            self.setupTilesetModel(view, tileset)
                        model = view.tilesetModel()
                        modelIndex = model.tileIndex(tile)
                        selectionModel = view.selectionModel()

                        _x = QItemSelection()
                        _x.select(modelIndex, modelIndex)
                        selections[selectionModel] = _x

        if (not selections.isEmpty()):
            self.mSynchronizingSelection = True
            # Mark captured tiles as selected
            for i in selections:
                selectionModel = i[0]
                selection = i[1]
                selectionModel.select(selection,
                                      QItemSelectionModel.SelectCurrent)

            # Show/edit properties of all captured tiles
            self.mMapDocument.setSelectedTiles(processed.toList())
            # Update the current tile (useful for animation and collision editors)
            first = selections.first()
            selectionModel = first[0]
            selection = first[1]
            currentIndex = QModelIndex(selection.first().topLeft())
            if (selectionModel.currentIndex() != currentIndex):
                selectionModel.setCurrentIndex(currentIndex,
                                               QItemSelectionModel.NoUpdate)
            else:
                self.currentChanged(currentIndex)
            self.mSynchronizingSelection = False

    def currentTilesetChanged(self):
        view = self.currentTilesetView()
        if view:
            s = view.selectionModel()
            if s:
                self.setCurrentTile(view.tilesetModel().tileAt(
                    s.currentIndex()))

    ##
    # Returns the currently selected tile.
    ##
    def currentTile(self):
        return self.mCurrentTile

    def changeEvent(self, e):
        super().changeEvent(e)
        x = e.type()
        if x == QEvent.LanguageChange:
            self.retranslateUi()
        else:
            pass

    def dragEnterEvent(self, e):
        urls = e.mimeData().urls()
        if (not urls.isEmpty() and not urls.at(0).toLocalFile().isEmpty()):
            e.accept()

    def dropEvent(self, e):
        paths = QStringList()
        for url in e.mimeData().urls():
            localFile = url.toLocalFile()
            if (not localFile.isEmpty()):
                paths.append(localFile)

        if (not paths.isEmpty()):
            self.tilesetsDropped.emit(paths)
            e.accept()

    def selectionChanged(self):
        self.updateActions()
        if not self.mSynchronizingSelection:
            self.updateCurrentTiles()

    def currentChanged(self, index):
        if (not index.isValid()):
            return
        model = index.model()
        self.setCurrentTile(model.tileAt(index))

    def updateActions(self):
        external = False
        hasImageSource = False
        hasSelection = False
        view = None
        index = self.mTabBar.currentIndex()
        if (index > -1):
            view = self.tilesetViewAt(index)
            if (view):
                tileset = self.mTilesets.at(index)
                if (not view.model()):  # Lazily set up the model
                    self.setupTilesetModel(view, tileset)

                self.mViewStack.setCurrentIndex(index)
                external = tileset.isExternal()
                hasImageSource = tileset.imageSource() != ''
                hasSelection = view.selectionModel().hasSelection()

        tilesetIsDisplayed = view != None
        mapIsDisplayed = self.mMapDocument != None
        self.mNewTileset.setEnabled(mapIsDisplayed)
        self.mImportTileset.setEnabled(tilesetIsDisplayed and external)
        self.mExportTileset.setEnabled(tilesetIsDisplayed and not external)
        self.mPropertiesTileset.setEnabled(tilesetIsDisplayed and not external)
        self.mDeleteTileset.setEnabled(tilesetIsDisplayed)
        self.mEditTerrain.setEnabled(tilesetIsDisplayed and not external)
        self.mAddTiles.setEnabled(tilesetIsDisplayed and not hasImageSource
                                  and not external)
        self.mRemoveTiles.setEnabled(tilesetIsDisplayed and not hasImageSource
                                     and hasSelection and not external)

    def updateCurrentTiles(self):
        view = self.currentTilesetView()
        if (not view):
            return
        s = view.selectionModel()
        if (not s):
            return
        indexes = s.selection().indexes()
        if len(indexes) == 0:
            return
        first = indexes[0]
        minX = first.column()
        maxX = first.column()
        minY = first.row()
        maxY = first.row()
        for index in indexes:
            if minX > index.column():
                minX = index.column()
            if maxX < index.column():
                maxX = index.column()
            if minY > index.row():
                minY = index.row()
            if maxY < index.row():
                maxY = index.row()

        # Create a tile layer from the current selection
        tileLayer = TileLayer(QString(), 0, 0, maxX - minX + 1,
                              maxY - minY + 1)
        model = view.tilesetModel()
        for index in indexes:
            tileLayer.setCell(index.column() - minX,
                              index.row() - minY, Cell(model.tileAt(index)))

        self.setCurrentTiles(tileLayer)

    def indexPressed(self, index):
        view = self.currentTilesetView()
        tile = view.tilesetModel().tileAt(index)
        if tile:
            self.mMapDocument.setCurrentObject(tile)

    def tilesetAdded(self, index, tileset):
        view = TilesetView()
        view.setMapDocument(self.mMapDocument)
        view.setZoomable(self.mZoomable)
        self.mTilesets.insert(index, tileset.sharedPointer())
        self.mTabBar.insertTab(index, tileset.name())
        self.mViewStack.insertWidget(index, view)
        self.updateActions()

    def tilesetChanged(self, tileset):
        # Update the affected tileset model, if it exists
        index = indexOf(self.mTilesets, tileset)
        if (index < 0):
            return
        model = self.tilesetViewAt(index).tilesetModel()
        if model:
            model.tilesetChanged()

    def tilesetRemoved(self, tileset):
        # Delete the related tileset view
        index = indexOf(self.mTilesets, tileset)
        self.mTilesets.removeAt(index)
        self.mTabBar.removeTab(index)
        self.tilesetViewAt(index).close()

        # Make sure we don't reference this tileset anymore
        if (self.mCurrentTiles):
            # TODO: Don't clean unnecessarily (but first the concept of
            #       "current brush" would need to be introduced)
            cleaned = self.mCurrentTiles.clone()
            cleaned.removeReferencesToTileset(tileset)
            self.setCurrentTiles(cleaned)

        if (self.mCurrentTile and self.mCurrentTile.tileset() == tileset):
            self.setCurrentTile(None)
        self.updateActions()

    def tilesetMoved(self, _from, to):
        self.mTilesets.insert(to, self.mTilesets.takeAt(_from))
        # Move the related tileset views
        widget = self.mViewStack.widget(_from)
        self.mViewStack.removeWidget(widget)
        self.mViewStack.insertWidget(to, widget)
        self.mViewStack.setCurrentIndex(self.mTabBar.currentIndex())
        # Update the titles of the affected tabs
        start = min(_from, to)
        end = max(_from, to)
        for i in range(start, end + 1):
            tileset = self.mTilesets.at(i)
            if (self.mTabBar.tabText(i) != tileset.name()):
                self.mTabBar.setTabText(i, tileset.name())

    def tilesetNameChanged(self, tileset):
        index = indexOf(self.mTilesets, tileset)
        self.mTabBar.setTabText(index, tileset.name())

    def tileAnimationChanged(self, tile):
        view = self.currentTilesetView()
        if view:
            model = view.tilesetModel()
            if model:
                model.tileChanged(tile)

    ##
    # Removes the currently selected tileset.
    ##
    def removeTileset(self, *args):
        l = len(args)
        if l == 0:
            currentIndex = self.mViewStack.currentIndex()
            if (currentIndex != -1):
                self.removeTileset(self.mViewStack.currentIndex())
        elif l == 1:
            ##
            # Removes the tileset at the given index. Prompting the user when the tileset
            # is in use by the map.
            ##
            index = args[0]
            tileset = self.mTilesets.at(index).data()
            inUse = self.mMapDocument.map().isTilesetUsed(tileset)
            # If the tileset is in use, warn the user and confirm removal
            if (inUse):
                warning = QMessageBox(
                    QMessageBox.Warning, self.tr("Remove Tileset"),
                    self.tr("The tileset \"%s\" is still in use by the map!" %
                            tileset.name()), QMessageBox.Yes | QMessageBox.No,
                    self)
                warning.setDefaultButton(QMessageBox.Yes)
                warning.setInformativeText(
                    self.tr("Remove this tileset and all references "
                            "to the tiles in this tileset?"))
                if (warning.exec() != QMessageBox.Yes):
                    return

            remove = RemoveTileset(self.mMapDocument, index, tileset)
            undoStack = self.mMapDocument.undoStack()
            if (inUse):
                # Remove references to tiles in this tileset from the current map
                def referencesTileset(cell):
                    tile = cell.tile
                    if tile:
                        return tile.tileset() == tileset
                    return False

                undoStack.beginMacro(remove.text())
                removeTileReferences(self.mMapDocument, referencesTileset)

            undoStack.push(remove)
            if (inUse):
                undoStack.endMacro()

    def moveTileset(self, _from, to):
        command = MoveTileset(self.mMapDocument, _from, to)
        self.mMapDocument.undoStack().push(command)

    def editTilesetProperties(self):
        tileset = self.currentTileset()
        if (not tileset):
            return
        self.mMapDocument.setCurrentObject(tileset)
        self.mMapDocument.emitEditCurrentObject()

    def importTileset(self):
        tileset = self.currentTileset()
        if (not tileset):
            return
        command = SetTilesetFileName(self.mMapDocument, tileset, QString())
        self.mMapDocument.undoStack().push(command)

    def exportTileset(self):
        tileset = self.currentTileset()
        if (not tileset):
            return

        tsxFilter = self.tr("Tiled tileset files (*.tsx)")
        helper = FormatHelper(FileFormat.ReadWrite, tsxFilter)

        prefs = preferences.Preferences.instance()

        suggestedFileName = prefs.lastPath(
            preferences.Preferences.ExternalTileset)
        suggestedFileName += '/'
        suggestedFileName += tileset.name()

        extension = ".tsx"

        if (not suggestedFileName.endswith(extension)):
            suggestedFileName += extension

        selectedFilter = tsxFilter
        fileName, _ = QFileDialog.getSaveFileName(self,
                                                  self.tr("Export Tileset"),
                                                  suggestedFileName,
                                                  helper.filter(),
                                                  selectedFilter)
        if fileName == '':
            return
        prefs.setLastPath(preferences.Preferences.ExternalTileset,
                          QFileInfo(fileName).path())

        tsxFormat = TsxTilesetFormat()
        format = helper.formatByNameFilter(selectedFilter)
        if not format:
            format = tsxFormat

        if format.write(tileset, fileName):
            command = SetTilesetFileName(self.mMapDocument, tileset, fileName)
            self.mMapDocument.undoStack().push(command)
        else:
            error = format.errorString()
            QMessageBox.critical(self.window(), self.tr("Export Tileset"),
                                 self.tr("Error saving tileset: %s" % error))

    def editTerrain(self):
        tileset = self.currentTileset()
        if (not tileset):
            return
        editTerrainDialog = EditTerrainDialog(self.mMapDocument, tileset, self)
        editTerrainDialog.exec()

    def addTiles(self):
        tileset = self.currentTileset()
        if (not tileset):
            return
        prefs = preferences.Preferences.instance()
        startLocation = QFileInfo(
            prefs.lastPath(preferences.Preferences.ImageFile)).absolutePath()
        filter = Utils.readableImageFormatsFilter()
        files = QFileDialog.getOpenFileNames(self.window(),
                                             self.tr("Add Tiles"),
                                             startLocation, filter)
        tiles = QList()
        id = tileset.tileCount()
        for file in files:
            image = QPixmap(file)
            if (not image.isNull()):
                tiles.append(Tile(image, file, id, tileset))
                id += 1
            else:
                warning = QMessageBox(QMessageBox.Warning,
                                      self.tr("Add Tiles"),
                                      self.tr("Could not load \"%s\"!" % file),
                                      QMessageBox.Ignore | QMessageBox.Cancel,
                                      self.window())
                warning.setDefaultButton(QMessageBox.Ignore)
                if (warning.exec() != QMessageBox.Ignore):
                    tiles.clear()
                    return

        if (tiles.isEmpty()):
            return
        prefs.setLastPath(preferences.Preferences.ImageFile, files.last())
        self.mMapDocument.undoStack().push(
            AddTiles(self.mMapDocument, tileset, tiles))

    def removeTiles(self):
        view = self.currentTilesetView()
        if (not view):
            return
        if (not view.selectionModel().hasSelection()):
            return
        indexes = view.selectionModel().selectedIndexes()
        model = view.tilesetModel()
        tileIds = RangeSet()
        tiles = QList()
        for index in indexes:
            tile = model.tileAt(index)
            if tile:
                tileIds.insert(tile.id())
                tiles.append(tile)

        def matchesAnyTile(cell):
            tile = cell.tile
            if tile:
                return tiles.contains(tile)
            return False

        inUse = self.hasTileReferences(self.mMapDocument, matchesAnyTile)
        # If the tileset is in use, warn the user and confirm removal
        if (inUse):
            warning = QMessageBox(
                QMessageBox.Warning, self.tr("Remove Tiles"),
                self.tr("One or more of the tiles to be removed are "
                        "still in use by the map!"),
                QMessageBox.Yes | QMessageBox.No, self)
            warning.setDefaultButton(QMessageBox.Yes)
            warning.setInformativeText(
                self.tr("Remove all references to these tiles?"))
            if (warning.exec() != QMessageBox.Yes):
                return

        undoStack = self.mMapDocument.undoStack()
        undoStack.beginMacro(self.tr("Remove Tiles"))
        removeTileReferences(self.mMapDocument, matchesAnyTile)
        # Iterate backwards over the ranges in order to keep the indexes valid
        firstRange = tileIds.begin()
        it = tileIds.end()
        if (it == firstRange):  # no range
            return
        tileset = view.tilesetModel().tileset()
        while (it != firstRange):
            it -= 1
            item = tileIds.item(it)
            length = item[1] - item[0] + 1
            undoStack.push(
                RemoveTiles(self.mMapDocument, tileset, item[0], length))

        undoStack.endMacro()
        # Clear the current tiles, will be referencing the removed tiles
        self.setCurrentTiles(None)
        self.setCurrentTile(None)

    def documentAboutToClose(self, mapDocument):
        self.mCurrentTilesets.remove(mapDocument)

    def refreshTilesetMenu(self):
        self.mTilesetMenu.clear()
        if (self.mTilesetMenuMapper):
            self.mTabBar.disconnect(self.mTilesetMenuMapper)
            del self.mTilesetMenuMapper

        self.mTilesetMenuMapper = QSignalMapper(self)
        self.mTilesetMenuMapper.mapped.connect(self.mTabBar.setCurrentIndex)
        currentIndex = self.mTabBar.currentIndex()
        for i in range(self.mTabBar.count()):
            action = QAction(self.mTabBar.tabText(i), self)
            action.setCheckable(True)
            self.mTilesetActionGroup.addAction(action)
            if (i == currentIndex):
                action.setChecked(True)
            self.mTilesetMenu.addAction(action)
            action.triggered.connect(self.mTilesetMenuMapper.map)
            self.mTilesetMenuMapper.setMapping(action, i)

    def setCurrentTile(self, tile):
        if (self.mCurrentTile == tile):
            return
        self.mCurrentTile = tile
        self.currentTileChanged.emit([tile])
        if (tile):
            self.mMapDocument.setCurrentObject(tile)

    def setCurrentTiles(self, tiles):
        if (self.mCurrentTiles == tiles):
            return
        del self.mCurrentTiles
        self.mCurrentTiles = tiles
        # Set the selected tiles on the map document
        if (tiles):
            selectedTiles = QList()
            for y in range(tiles.height()):
                for x in range(tiles.width()):
                    cell = tiles.cellAt(x, y)
                    if (not cell.isEmpty()):
                        selectedTiles.append(cell.tile)

            self.mMapDocument.setSelectedTiles(selectedTiles)

            # Create a tile stamp with these tiles
            map = self.mMapDocument.map()
            stamp = Map(map.orientation(), tiles.width(), tiles.height(),
                        map.tileWidth(), map.tileHeight())
            stamp.addLayer(tiles.clone())
            stamp.addTilesets(tiles.usedTilesets())

            self.mEmittingStampCaptured = True
            self.stampCaptured.emit(TileStamp(stamp))
            self.mEmittingStampCaptured = False

    def retranslateUi(self):
        self.setWindowTitle(self.tr("Tilesets"))
        self.mNewTileset.setText(self.tr("New Tileset"))
        self.mImportTileset.setText(self.tr("Import Tileset"))
        self.mExportTileset.setText(self.tr("Export Tileset As..."))
        self.mPropertiesTileset.setText(self.tr("Tileset Properties"))
        self.mDeleteTileset.setText(self.tr("Remove Tileset"))
        self.mEditTerrain.setText(self.tr("Edit Terrain Information"))
        self.mAddTiles.setText(self.tr("Add Tiles"))
        self.mRemoveTiles.setText(self.tr("Remove Tiles"))

    def currentTileset(self):
        index = self.mTabBar.currentIndex()
        if (index == -1):
            return None
        return self.mTilesets.at(index)

    def currentTilesetView(self):
        return self.mViewStack.currentWidget()

    def tilesetViewAt(self, index):
        return self.mViewStack.widget(index)

    def setupTilesetModel(self, view, tileset):
        view.setModel(TilesetModel(tileset, view))

        s = view.selectionModel()
        s.selectionChanged.connect(self.selectionChanged)
        s.currentChanged.connect(self.currentChanged)
        view.pressed.connect(self.indexPressed)
Exemple #28
0
class E5SideBar(QWidget):
    """
    Class implementing a sidebar with a widget area, that is hidden or shown,
    if the current tab is clicked again.
    """
    Version = 1

    North = 0
    East = 1
    South = 2
    West = 3

    def __init__(self, orientation=None, delay=200, parent=None):
        """
        Constructor
        
        @param orientation orientation of the sidebar widget (North, East,
            South, West)
        @param delay value for the expand/shrink delay in milliseconds
            (integer)
        @param parent parent widget (QWidget)
        """
        super(E5SideBar, self).__init__(parent)

        self.__tabBar = QTabBar()
        self.__tabBar.setDrawBase(True)
        self.__tabBar.setShape(QTabBar.RoundedNorth)
        self.__tabBar.setUsesScrollButtons(True)
        self.__tabBar.setDrawBase(False)
        self.__stackedWidget = QStackedWidget(self)
        self.__stackedWidget.setContentsMargins(0, 0, 0, 0)
        self.__autoHideButton = QToolButton()
        self.__autoHideButton.setCheckable(True)
        self.__autoHideButton.setIcon(
            UI.PixmapCache.getIcon("autoHideOff.png"))
        self.__autoHideButton.setChecked(True)
        self.__autoHideButton.setToolTip(
            self.tr("Deselect to activate automatic collapsing"))
        self.barLayout = QBoxLayout(QBoxLayout.LeftToRight)
        self.barLayout.setContentsMargins(0, 0, 0, 0)
        self.layout = QBoxLayout(QBoxLayout.TopToBottom)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)
        self.barLayout.addWidget(self.__autoHideButton)
        self.barLayout.addWidget(self.__tabBar)
        self.layout.addLayout(self.barLayout)
        self.layout.addWidget(self.__stackedWidget)
        self.setLayout(self.layout)

        # initialize the delay timer
        self.__actionMethod = None
        self.__delayTimer = QTimer(self)
        self.__delayTimer.setSingleShot(True)
        self.__delayTimer.setInterval(delay)
        self.__delayTimer.timeout.connect(self.__delayedAction)

        self.__minimized = False
        self.__minSize = 0
        self.__maxSize = 0
        self.__bigSize = QSize()

        self.splitter = None
        self.splitterSizes = []

        self.__hasFocus = False
        # flag storing if this widget or any child has the focus
        self.__autoHide = False

        self.__tabBar.installEventFilter(self)

        self.__orientation = E5SideBar.North
        if orientation is None:
            orientation = E5SideBar.North
        self.setOrientation(orientation)

        self.__tabBar.currentChanged[int].connect(
            self.__stackedWidget.setCurrentIndex)
        e5App().focusChanged.connect(self.__appFocusChanged)
        self.__autoHideButton.toggled[bool].connect(self.__autoHideToggled)

    def setSplitter(self, splitter):
        """
        Public method to set the splitter managing the sidebar.
        
        @param splitter reference to the splitter (QSplitter)
        """
        self.splitter = splitter
        self.splitter.splitterMoved.connect(self.__splitterMoved)
        self.splitter.setChildrenCollapsible(False)
        index = self.splitter.indexOf(self)
        self.splitter.setCollapsible(index, False)

    def __splitterMoved(self, pos, index):
        """
        Private slot to react on splitter moves.
        
        @param pos new position of the splitter handle (integer)
        @param index index of the splitter handle (integer)
        """
        if self.splitter:
            self.splitterSizes = self.splitter.sizes()

    def __delayedAction(self):
        """
        Private slot to handle the firing of the delay timer.
        """
        if self.__actionMethod is not None:
            self.__actionMethod()

    def setDelay(self, delay):
        """
        Public method to set the delay value for the expand/shrink delay in
        milliseconds.
        
        @param delay value for the expand/shrink delay in milliseconds
            (integer)
        """
        self.__delayTimer.setInterval(delay)

    def delay(self):
        """
        Public method to get the delay value for the expand/shrink delay in
        milliseconds.
        
        @return value for the expand/shrink delay in milliseconds (integer)
        """
        return self.__delayTimer.interval()

    def __cancelDelayTimer(self):
        """
        Private method to cancel the current delay timer.
        """
        self.__delayTimer.stop()
        self.__actionMethod = None

    def shrink(self):
        """
        Public method to record a shrink request.
        """
        self.__delayTimer.stop()
        self.__actionMethod = self.__shrinkIt
        self.__delayTimer.start()

    def __shrinkIt(self):
        """
        Private method to shrink the sidebar.
        """
        self.__minimized = True
        self.__bigSize = self.size()
        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            self.__minSize = self.minimumSizeHint().height()
            self.__maxSize = self.maximumHeight()
        else:
            self.__minSize = self.minimumSizeHint().width()
            self.__maxSize = self.maximumWidth()
        if self.splitter:
            self.splitterSizes = self.splitter.sizes()

        self.__stackedWidget.hide()

        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            self.setFixedHeight(self.__tabBar.minimumSizeHint().height())
        else:
            self.setFixedWidth(self.__tabBar.minimumSizeHint().width())

        self.__actionMethod = None

    def expand(self):
        """
        Public method to record a expand request.
        """
        self.__delayTimer.stop()
        self.__actionMethod = self.__expandIt
        self.__delayTimer.start()

    def __expandIt(self):
        """
        Private method to expand the sidebar.
        """
        self.__minimized = False
        self.__stackedWidget.show()
        self.resize(self.__bigSize)
        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            minSize = max(self.__minSize, self.minimumSizeHint().height())
            self.setMinimumHeight(minSize)
            self.setMaximumHeight(self.__maxSize)
        else:
            minSize = max(self.__minSize, self.minimumSizeHint().width())
            self.setMinimumWidth(minSize)
            self.setMaximumWidth(self.__maxSize)
        if self.splitter:
            self.splitter.setSizes(self.splitterSizes)

        self.__actionMethod = None

    def isMinimized(self):
        """
        Public method to check the minimized state.
        
        @return flag indicating the minimized state (boolean)
        """
        return self.__minimized

    def isAutoHiding(self):
        """
        Public method to check, if the auto hide function is active.
        
        @return flag indicating the state of auto hiding (boolean)
        """
        return self.__autoHide

    def eventFilter(self, obj, evt):
        """
        Public method to handle some events for the tabbar.
        
        @param obj reference to the object (QObject)
        @param evt reference to the event object (QEvent)
        @return flag indicating, if the event was handled (boolean)
        """
        if obj == self.__tabBar:
            if evt.type() == QEvent.MouseButtonPress:
                pos = evt.pos()
                for i in range(self.__tabBar.count()):
                    if self.__tabBar.tabRect(i).contains(pos):
                        break

                if i == self.__tabBar.currentIndex():
                    if self.isMinimized():
                        self.expand()
                    else:
                        self.shrink()
                    return True
                elif self.isMinimized():
                    self.expand()
            elif evt.type() == QEvent.Wheel:
                if qVersion() >= "5.0.0":
                    delta = evt.angleDelta().y()
                else:
                    delta = evt.delta()
                if delta > 0:
                    self.prevTab()
                else:
                    self.nextTab()
                return True

        return QWidget.eventFilter(self, obj, evt)

    def addTab(self, widget, iconOrLabel, label=None):
        """
        Public method to add a tab to the sidebar.
        
        @param widget reference to the widget to add (QWidget)
        @param iconOrLabel reference to the icon or the label text of the tab
            (QIcon, string)
        @param label the labeltext of the tab (string) (only to be
            used, if the second parameter is a QIcon)
        """
        if label:
            index = self.__tabBar.addTab(iconOrLabel, label)
            self.__tabBar.setTabToolTip(index, label)
        else:
            index = self.__tabBar.addTab(iconOrLabel)
            self.__tabBar.setTabToolTip(index, iconOrLabel)
        self.__stackedWidget.addWidget(widget)
        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            self.__minSize = self.minimumSizeHint().height()
        else:
            self.__minSize = self.minimumSizeHint().width()

    def insertTab(self, index, widget, iconOrLabel, label=None):
        """
        Public method to insert a tab into the sidebar.
        
        @param index the index to insert the tab at (integer)
        @param widget reference to the widget to insert (QWidget)
        @param iconOrLabel reference to the icon or the labeltext of the tab
            (QIcon, string)
        @param label the labeltext of the tab (string) (only to be
            used, if the second parameter is a QIcon)
        """
        if label:
            index = self.__tabBar.insertTab(index, iconOrLabel, label)
            self.__tabBar.setTabToolTip(index, label)
        else:
            index = self.__tabBar.insertTab(index, iconOrLabel)
            self.__tabBar.setTabToolTip(index, iconOrLabel)
        self.__stackedWidget.insertWidget(index, widget)
        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            self.__minSize = self.minimumSizeHint().height()
        else:
            self.__minSize = self.minimumSizeHint().width()

    def removeTab(self, index):
        """
        Public method to remove a tab.
        
        @param index the index of the tab to remove (integer)
        """
        self.__stackedWidget.removeWidget(self.__stackedWidget.widget(index))
        self.__tabBar.removeTab(index)
        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            self.__minSize = self.minimumSizeHint().height()
        else:
            self.__minSize = self.minimumSizeHint().width()

    def clear(self):
        """
        Public method to remove all tabs.
        """
        while self.count() > 0:
            self.removeTab(0)

    def prevTab(self):
        """
        Public slot used to show the previous tab.
        """
        ind = self.currentIndex() - 1
        if ind == -1:
            ind = self.count() - 1

        self.setCurrentIndex(ind)
        self.currentWidget().setFocus()

    def nextTab(self):
        """
        Public slot used to show the next tab.
        """
        ind = self.currentIndex() + 1
        if ind == self.count():
            ind = 0

        self.setCurrentIndex(ind)
        self.currentWidget().setFocus()

    def count(self):
        """
        Public method to get the number of tabs.
        
        @return number of tabs in the sidebar (integer)
        """
        return self.__tabBar.count()

    def currentIndex(self):
        """
        Public method to get the index of the current tab.
        
        @return index of the current tab (integer)
        """
        return self.__stackedWidget.currentIndex()

    def setCurrentIndex(self, index):
        """
        Public slot to set the current index.
        
        @param index the index to set as the current index (integer)
        """
        self.__tabBar.setCurrentIndex(index)
        self.__stackedWidget.setCurrentIndex(index)
        if self.isMinimized():
            self.expand()

    def currentWidget(self):
        """
        Public method to get a reference to the current widget.
        
        @return reference to the current widget (QWidget)
        """
        return self.__stackedWidget.currentWidget()

    def setCurrentWidget(self, widget):
        """
        Public slot to set the current widget.
        
        @param widget reference to the widget to become the current widget
            (QWidget)
        """
        self.__stackedWidget.setCurrentWidget(widget)
        self.__tabBar.setCurrentIndex(self.__stackedWidget.currentIndex())
        if self.isMinimized():
            self.expand()

    def indexOf(self, widget):
        """
        Public method to get the index of the given widget.
        
        @param widget reference to the widget to get the index of (QWidget)
        @return index of the given widget (integer)
        """
        return self.__stackedWidget.indexOf(widget)

    def isTabEnabled(self, index):
        """
        Public method to check, if a tab is enabled.
        
        @param index index of the tab to check (integer)
        @return flag indicating the enabled state (boolean)
        """
        return self.__tabBar.isTabEnabled(index)

    def setTabEnabled(self, index, enabled):
        """
        Public method to set the enabled state of a tab.
        
        @param index index of the tab to set (integer)
        @param enabled enabled state to set (boolean)
        """
        self.__tabBar.setTabEnabled(index, enabled)

    def orientation(self):
        """
        Public method to get the orientation of the sidebar.
        
        @return orientation of the sidebar (North, East, South, West)
        """
        return self.__orientation

    def setOrientation(self, orient):
        """
        Public method to set the orientation of the sidebar.

        @param orient orientation of the sidebar (North, East, South, West)
        """
        if orient == E5SideBar.North:
            self.__tabBar.setShape(QTabBar.RoundedNorth)
            self.__tabBar.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Preferred)
            self.barLayout.setDirection(QBoxLayout.LeftToRight)
            self.layout.setDirection(QBoxLayout.TopToBottom)
            self.layout.setAlignment(self.barLayout, Qt.AlignLeft)
        elif orient == E5SideBar.East:
            self.__tabBar.setShape(QTabBar.RoundedEast)
            self.__tabBar.setSizePolicy(QSizePolicy.Preferred,
                                        QSizePolicy.Expanding)
            self.barLayout.setDirection(QBoxLayout.TopToBottom)
            self.layout.setDirection(QBoxLayout.RightToLeft)
            self.layout.setAlignment(self.barLayout, Qt.AlignTop)
        elif orient == E5SideBar.South:
            self.__tabBar.setShape(QTabBar.RoundedSouth)
            self.__tabBar.setSizePolicy(QSizePolicy.Expanding,
                                        QSizePolicy.Preferred)
            self.barLayout.setDirection(QBoxLayout.LeftToRight)
            self.layout.setDirection(QBoxLayout.BottomToTop)
            self.layout.setAlignment(self.barLayout, Qt.AlignLeft)
        elif orient == E5SideBar.West:
            self.__tabBar.setShape(QTabBar.RoundedWest)
            self.__tabBar.setSizePolicy(QSizePolicy.Preferred,
                                        QSizePolicy.Expanding)
            self.barLayout.setDirection(QBoxLayout.TopToBottom)
            self.layout.setDirection(QBoxLayout.LeftToRight)
            self.layout.setAlignment(self.barLayout, Qt.AlignTop)
        self.__orientation = orient

    def tabIcon(self, index):
        """
        Public method to get the icon of a tab.
        
        @param index index of the tab (integer)
        @return icon of the tab (QIcon)
        """
        return self.__tabBar.tabIcon(index)

    def setTabIcon(self, index, icon):
        """
        Public method to set the icon of a tab.
        
        @param index index of the tab (integer)
        @param icon icon to be set (QIcon)
        """
        self.__tabBar.setTabIcon(index, icon)

    def tabText(self, index):
        """
        Public method to get the text of a tab.
        
        @param index index of the tab (integer)
        @return text of the tab (string)
        """
        return self.__tabBar.tabText(index)

    def setTabText(self, index, text):
        """
        Public method to set the text of a tab.
        
        @param index index of the tab (integer)
        @param text text to set (string)
        """
        self.__tabBar.setTabText(index, text)

    def tabToolTip(self, index):
        """
        Public method to get the tooltip text of a tab.
        
        @param index index of the tab (integer)
        @return tooltip text of the tab (string)
        """
        return self.__tabBar.tabToolTip(index)

    def setTabToolTip(self, index, tip):
        """
        Public method to set the tooltip text of a tab.
        
        @param index index of the tab (integer)
        @param tip tooltip text to set (string)
        """
        self.__tabBar.setTabToolTip(index, tip)

    def tabWhatsThis(self, index):
        """
        Public method to get the WhatsThis text of a tab.
        
        @param index index of the tab (integer)
        @return WhatsThis text of the tab (string)
        """
        return self.__tabBar.tabWhatsThis(index)

    def setTabWhatsThis(self, index, text):
        """
        Public method to set the WhatsThis text of a tab.
        
        @param index index of the tab (integer)
        @param text WhatsThis text to set (string)
        """
        self.__tabBar.setTabWhatsThis(index, text)

    def widget(self, index):
        """
        Public method to get a reference to the widget associated with a tab.
        
        @param index index of the tab (integer)
        @return reference to the widget (QWidget)
        """
        return self.__stackedWidget.widget(index)

    def saveState(self):
        """
        Public method to save the state of the sidebar.
        
        @return saved state as a byte array (QByteArray)
        """
        if len(self.splitterSizes) == 0:
            if self.splitter:
                self.splitterSizes = self.splitter.sizes()
            self.__bigSize = self.size()
            if self.__orientation in [E5SideBar.North, E5SideBar.South]:
                self.__minSize = self.minimumSizeHint().height()
                self.__maxSize = self.maximumHeight()
            else:
                self.__minSize = self.minimumSizeHint().width()
                self.__maxSize = self.maximumWidth()

        data = QByteArray()
        stream = QDataStream(data, QIODevice.WriteOnly)
        stream.setVersion(QDataStream.Qt_4_6)

        stream.writeUInt16(self.Version)
        stream.writeBool(self.__minimized)
        stream << self.__bigSize
        stream.writeUInt16(self.__minSize)
        stream.writeUInt16(self.__maxSize)
        stream.writeUInt16(len(self.splitterSizes))
        for size in self.splitterSizes:
            stream.writeUInt16(size)
        stream.writeBool(self.__autoHide)

        return data

    def restoreState(self, state):
        """
        Public method to restore the state of the sidebar.
        
        @param state byte array containing the saved state (QByteArray)
        @return flag indicating success (boolean)
        """
        if state.isEmpty():
            return False

        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            minSize = self.layout.minimumSize().height()
            maxSize = self.maximumHeight()
        else:
            minSize = self.layout.minimumSize().width()
            maxSize = self.maximumWidth()

        data = QByteArray(state)
        stream = QDataStream(data, QIODevice.ReadOnly)
        stream.setVersion(QDataStream.Qt_4_6)
        stream.readUInt16()  # version
        minimized = stream.readBool()

        if minimized and not self.__minimized:
            self.shrink()

        stream >> self.__bigSize
        self.__minSize = max(stream.readUInt16(), minSize)
        self.__maxSize = max(stream.readUInt16(), maxSize)
        count = stream.readUInt16()
        self.splitterSizes = []
        for i in range(count):
            self.splitterSizes.append(stream.readUInt16())

        self.__autoHide = stream.readBool()
        self.__autoHideButton.setChecked(not self.__autoHide)

        if not minimized:
            self.expand()

        return True

    #######################################################################
    ## methods below implement the autohide functionality
    #######################################################################

    def __autoHideToggled(self, checked):
        """
        Private slot to handle the toggling of the autohide button.
        
        @param checked flag indicating the checked state of the button
            (boolean)
        """
        self.__autoHide = not checked
        if self.__autoHide:
            self.__autoHideButton.setIcon(
                UI.PixmapCache.getIcon("autoHideOn.png"))
        else:
            self.__autoHideButton.setIcon(
                UI.PixmapCache.getIcon("autoHideOff.png"))

    def __appFocusChanged(self, old, now):
        """
        Private slot to handle a change of the focus.
        
        @param old reference to the widget, that lost focus (QWidget or None)
        @param now reference to the widget having the focus (QWidget or None)
        """
        self.__hasFocus = self.isAncestorOf(now)
        if self.__autoHide and not self.__hasFocus and not self.isMinimized():
            self.shrink()
        elif self.__autoHide and self.__hasFocus and self.isMinimized():
            self.expand()

    def enterEvent(self, event):
        """
        Protected method to handle the mouse entering this widget.
        
        @param event reference to the event (QEvent)
        """
        if self.__autoHide and self.isMinimized():
            self.expand()
        else:
            self.__cancelDelayTimer()

    def leaveEvent(self, event):
        """
        Protected method to handle the mouse leaving this widget.
        
        @param event reference to the event (QEvent)
        """
        if self.__autoHide and not self.__hasFocus and not self.isMinimized():
            self.shrink()
        else:
            self.__cancelDelayTimer()

    def shutdown(self):
        """
        Public method to shut down the object.
        
        This method does some preparations so the object can be deleted
        properly. It disconnects from the focusChanged signal in order to
        avoid trouble later on.
        """
        e5App().focusChanged.disconnect(self.__appFocusChanged)
Exemple #29
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Web Browser")

        print("call init")
        self.create_app()
        self.setBaseSize(1366, 768)

    def create_app(self):
        print("create app")
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0,0,0,0)

        # Create Tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.close_tab)
        self.tabbar.tabBarClicked.connect(self.SwitchTab)

        self.tabbar.setCurrentIndex(0)

        # Keep track of tabs
        self.tabCount = 0
        self.tabs =[]


        # Create AddressBar
        self.Toolbar = QWidget()
        self.ToolbarLayout = QHBoxLayout()
        self.addressbar = AddressBar()
        self.AddTabButton = QPushButton("+")

        self.addressbar.returnPressed.connect(self.BrowseTo)
        self.AddTabButton.clicked.connect(self.AddTab)

        self.Toolbar.setLayout(self.ToolbarLayout)
        self.ToolbarLayout.addWidget(self.addressbar)
        self.ToolbarLayout.addWidget(self.AddTabButton)

        # set main view
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)


        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.Toolbar)
        self.layout.addWidget(self.container)
        self.setLayout(self.layout)

        print("run show")

        self.AddTab()
        self.show()

    def close_tab(self, i):
        self.tabbar.removeTab(i)


    def AddTab(self):
        i = self.tabCount
        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].setObjectName("tab" + str(i))

        # open webview
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("http://google.com"))

        self.tabs[i].content.titleChanged.connect(lambda: self.SetTabText(i))

        # Add webview to tabs layout
        self.tabs[i].layout.addWidget(self.tabs[i].content)

        # set top level tab from [] to layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        # add tab to the top level stacked widget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        # set the tab at top of screen
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {"object": 'tab' + str(i), "initial": i})


        self.tabbar.setCurrentIndex(i)

        self.tabCount += 1

    def SwitchTab(self, i):
        tab_data = self.tabbar.tabData(i)
        print("tab: ", tab_data)
        tab_content = self.findChild(QWidget, tab_data)
        self.container.layout.setCurrentWidget(tab_content)

    def BrowseTo(self):
        text = self.addressbar.text()
        print("text")
        i = self.tabbar.currentIndex()
        tab = self.tabbar.tabData(i)["object"]
        wv = self.findChild(QWidget, tab).content

        if "http" not in text:
            if "." not in text:
                url = "https://www.google.com/search?q=" + text
            else:
                url ="http://" + text
        else:
            url = text
        wv.load(QUrl.fromUserInput(url))

    def SetTabText(self, i):
        '''
            self.tabs[i].objectName = tab1
            self.tabbar.tabData(i)["object"] = tab1
        '''
        tab_name = self.tabs[i].objectName()
        # tab1
        count = 0
        running = True

        while running:
            tab_data_name = self.tabbar.tabData(count)
            if count > 99:
                running = False
            if tab_name == tab_data_name["object"]:
                newTitle = self.findChild(QWidget, tab_name).content.title()
                self.tabbar.setTabText(count, newTitle)
                running = False
            else:
                count +=1
Exemple #30
0
class CGWMainTabs(QWidget):
    """GUI for tabs and associated widgets
    """
    tab_names = ['User', 'Expert']
    tab_ind_user = 0
    tab_ind_expert = 1

    def __init__(self, **kwargs):

        self.kwargs = kwargs

        parent = kwargs.get('parent', None)
        QWidget.__init__(self, parent)

        self.box_layout = QHBoxLayout()

        self.gui_win = None
        self.make_tab_bar()
        self.gui_selector(self.tab_names[1])

        self.box = QVBoxLayout(self)
        self.box.addWidget(self.tab_bar)
        self.box.addLayout(self.box_layout)
        #self.box.addStretch(1)
        self.setLayout(self.box)

        self.show_tool_tips()
        self.set_style()

    #--------------------------

    def show_tool_tips(self):
        self.setToolTip('Main tab window')

    #-------------------

    def sizeHint(self):
        height = 400 if self.tab_bar.currentIndex(
        ) == self.tab_ind_expert else 50
        return QSize(300, height)

    #-------------------

    def set_style(self):

        from psdaq.control_gui.Styles import style
        from psdaq.control_gui.QWIcons import icon
        icon.set_icons()

        self.setWindowIcon(icon.icon_monitor)
        self.setStyleSheet(style.styleBkgd)
        self.layout().setContentsMargins(0, 0, 0, 0)

        self.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)

        #self.setMinimumSize(300,300)

        #self.palette = QPalette()
        #self.resetColorIsSet = False

        #self.butELog    .setIcon(icon.icon_mail_forward)
        #self.butFile    .setIcon(icon.icon_save)
        #self.butExit    .setIcon(icon.icon_exit)
        #self.butLogger  .setIcon(icon.icon_logger)
        #self.butFBrowser.setIcon(icon.icon_browser)
        #self.butSave    .setIcon(icon.icon_save_cfg)
        #self.butStop    .setIcon(icon.icon_stop)

        #self.setMinimumHeight(250)
        #self.setMinimumWidth(550)

        #self.adjustSize()
        #self.        setStyleSheet(style.styleBkgd)
        #self.butSave.setStyleSheet(style.styleButton)
        #self.butFBrowser.setVisible(False)
        #self.butExit.setText('')
        #self.butExit.setFlat(True)

    #-------------------

    def make_tab_bar(self):
        self.tab_bar = QTabBar()

        #len(self.tab_names)
        for tab_name in self.tab_names:
            tab_ind = self.tab_bar.addTab(tab_name)
            self.tab_bar.setTabTextColor(tab_ind,
                                         QColor('blue'))  #gray, red, grayblue

        #self.tab_bar.setTabsClosable(True)
        #self.tab_bar.setMovable(True)
        self.tab_bar.setShape(QTabBar.RoundedNorth)

        tab_index = self.tab_ind_expert  # self.tab_names.index(self.tab_names[self.tab_ind_expert])
        self.tab_bar.setCurrentIndex(tab_index)
        logger.debug('make_tab_bar - set tab index: %d' % tab_index)

        self.tab_bar.currentChanged['int'].connect(self.on_tab_bar)
        self.tab_bar.tabCloseRequested.connect(self.on_tab_close_request)
        self.tab_bar.tabMoved[int, int].connect(self.on_tab_moved)

    #--------------------------

    def gui_selector(self, tab_name):

        if self.gui_win is not None:
            #self.box_layout.removeWidget(self.gui_win)
            #self.gui_win.setVisible(False)
            self.gui_win.close()
            del self.gui_win

        w_height = 100

        if tab_name == self.tab_names[1]:
            self.gui_win = CGWMainTabExpert(**self.kwargs)
            self.setMinimumHeight(400)
            w_height = 350

        elif tab_name == self.tab_names[0]:
            self.gui_win = CGWMainTabUser(**self.kwargs)
            #self.gui_win = QTextEdit(tab_name)
            self.setFixedHeight(110)
            #self.setMinimumHeight(100)
            #self.gui_win.setFixedHeight(100)
            w_height = 70

        else:
            self.gui_win = QTextEdit('Default window for tab %s' % tab_name)

        #self.gui_win.setMaximumHeight(w_height)
        #self.gui_win.setMaximumWidth(500)
        #self.gui_win.setFixedHeight(w_height)
        self.gui_win.setMinimumHeight(w_height)
        self.gui_win.setVisible(True)
        self.box_layout.addWidget(self.gui_win)

        #self.setStatus(0, s_msg)

    #-------------------

    def current_tab_index_and_name(self):
        tab_ind = self.tab_bar.currentIndex()
        tab_name = str(self.tab_bar.tabText(tab_ind))
        return tab_ind, tab_name

    #-------------------

    def on_tab_bar(self, ind):
        tab_ind, tab_name = self.current_tab_index_and_name()
        logger.info('Selected tab "%s"' % tab_name)
        #cp.main_tab_name.setValue(tab_name)
        self.gui_selector(tab_name)

    #-------------------

    def on_tab_close_request(self, ind):
        logger.debug('on_tab_close_request ind:%d' % ind)
        #self.tab_bar.removeTab(ind)
        #logger.debug('on_tab_close_request tab index:%d' % (itab))

    #-------------------

    def on_tab_moved(self, inew, iold):
        logger.debug('on_tab_close_request tab index begin:%d -> end:%d' %
                     (iold, inew))

    #-------------------

    #def resizeEvent(self, e):
    #pass
    #self.frame.setGeometry(self.rect())
    #logger.debug('resizeEvent')
    #logger.debug('CGWMainTabs resizeEvent: %s' % str(self.size()))

    #def moveEvent(self, e):
    #logger.debug('moveEvent')
    #self.position = self.mapToGlobal(self.pos())
    #self.position = self.pos()
    #logger.debug('moveEvent - pos:' + str(self.position))
    #pass

    def closeEvent(self, e):
        logger.debug('CGWMainTabs.closeEvent')

        #try    : self.gui_win.close()
        #except : pass

        #try    : del self.gui_win
        #except : pass

        self.tab_bar.close()

        if self.gui_win is not None:
            self.gui_win.close()

        QWidget.closeEvent(self, e)

    def onExit(self):
        logger.debug('onExit')
        self.close()

    def set_tabs_visible(self, is_visible):
        logger.debug('set_tabs_visible: is_visible %s' % is_visible)
        self.tab_bar.setVisible(is_visible)

    def tab_bar_is_visible(self):
        return self.tab_bar.isVisible()

    def view_hide_tabs(self):
        self.tab_bar.setVisible(not self.tab_bar.isVisible())

    def key_usage(self):
        return 'Keys:'\
               '\n  V - view/hide tabs'\
               '\n'

    if __name__ == "__main__":

        def keyPressEvent(self, e):
            #logger.debug('keyPressEvent, key=%s' % e.key())
            if e.key() == Qt.Key_Escape:
                self.close()

            elif e.key() == Qt.Key_V:
                self.view_hide_tab()

            else:
                logger.debug(self.key_usage())
Exemple #31
0
class MainWindow(QMainWindow):
    def __init__(self, doc):
        QMainWindow.__init__(self, None)
        self.doc = doc
        self.app = doc.app

        self._setupUi()

        # Create base elements
        self.model = MainWindowModel(document=doc.model)
        self.model2view = {}
        self.alookup = Lookup(self, model=self.model.account_lookup)
        self.clookup = Lookup(self, model=self.model.completion_lookup)
        self.drsel = DateRangeSelector(mainwindow=self, view=self.dateRangeSelectorView)
        self.sfield = SearchField(model=self.model.search_field, view=self.searchLineEdit)
        self.importWindow = ImportWindow(self)
        self.csvOptionsWindow = CSVOptionsWindow(self)
        self.recentDocuments = Recent(self.app, 'recentDocuments')
        self.recentDocuments.addMenu(self.menuOpenRecent)

        self.model.view = self
        self.model.connect()

        self._updateUndoActions()
        self._bindSignals()

    def _setupUi(self): # has to take place *before* base elements creation
        self.setWindowTitle("moneyGuru")
        self.resize(700, 580)
        self.centralwidget = QWidget(self)
        self.verticalLayout = QVBoxLayout(self.centralwidget)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.topBar = QWidget(self.centralwidget)
        self.horizontalLayout_2 = QHBoxLayout(self.topBar)
        self.horizontalLayout_2.setContentsMargins(2, 0, 2, 0)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem)
        self.dateRangeSelectorView = DateRangeSelectorView(self.topBar)
        self.dateRangeSelectorView.setMinimumSize(QSize(220, 0))
        self.horizontalLayout_2.addWidget(self.dateRangeSelectorView)
        spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout_2.addItem(spacerItem1)
        self.searchLineEdit = SearchEdit(self.topBar)
        self.searchLineEdit.setMaximumSize(QSize(240, 16777215))
        self.horizontalLayout_2.addWidget(self.searchLineEdit)
        self.verticalLayout.addWidget(self.topBar)
        self.tabBar = QTabBar(self.centralwidget)
        self.tabBar.setMinimumSize(QSize(0, 20))
        self.verticalLayout.addWidget(self.tabBar)
        self.mainView = QStackedWidget(self.centralwidget)
        self.verticalLayout.addWidget(self.mainView)

        # Bottom buttons & status label
        self.bottomBar = QWidget(self.centralwidget)
        self.horizontalLayout = QHBoxLayout(self.bottomBar)
        self.horizontalLayout.setContentsMargins(2, 2, 2, 2)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.newItemButton = QPushButton(self.bottomBar)
        buttonSizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Fixed)
        buttonSizePolicy.setHorizontalStretch(0)
        buttonSizePolicy.setVerticalStretch(0)
        buttonSizePolicy.setHeightForWidth(self.newItemButton.sizePolicy().hasHeightForWidth())
        self.newItemButton.setSizePolicy(buttonSizePolicy)
        self.newItemButton.setIcon(QIcon(QPixmap(':/plus_8')))
        self.horizontalLayout.addWidget(self.newItemButton)
        self.deleteItemButton = QPushButton(self.bottomBar)
        self.deleteItemButton.setSizePolicy(buttonSizePolicy)
        self.deleteItemButton.setIcon(QIcon(QPixmap(':/minus_8')))
        self.horizontalLayout.addWidget(self.deleteItemButton)
        self.editItemButton = QPushButton(self.bottomBar)
        self.editItemButton.setSizePolicy(buttonSizePolicy)
        self.editItemButton.setIcon(QIcon(QPixmap(':/info_gray_12')))
        self.horizontalLayout.addWidget(self.editItemButton)
        self.horizontalLayout.addItem(horizontalSpacer(size=20))
        self.graphVisibilityButton = QPushButton()
        self.graphVisibilityButton.setSizePolicy(buttonSizePolicy)
        self.graphVisibilityButton.setIcon(QIcon(QPixmap(':/graph_visibility_on_16')))
        self.horizontalLayout.addWidget(self.graphVisibilityButton)
        self.piechartVisibilityButton = QPushButton()
        self.piechartVisibilityButton.setSizePolicy(buttonSizePolicy)
        self.piechartVisibilityButton.setIcon(QIcon(QPixmap(':/piechart_visibility_on_16')))
        self.horizontalLayout.addWidget(self.piechartVisibilityButton)
        self.columnsVisibilityButton = QPushButton()
        self.columnsVisibilityButton.setSizePolicy(buttonSizePolicy)
        self.columnsVisibilityButton.setIcon(QIcon(QPixmap(':/columns_16')))
        self.horizontalLayout.addWidget(self.columnsVisibilityButton)

        self.statusLabel = QLabel(tr("Status"))
        self.statusLabel.setAlignment(Qt.AlignCenter)
        self.horizontalLayout.addWidget(self.statusLabel)
        self.verticalLayout.addWidget(self.bottomBar)


        self.setCentralWidget(self.centralwidget)
        self.menubar = QMenuBar(self)
        self.menubar.setGeometry(QRect(0, 0, 700, 20))
        self.menuFile = QMenu(tr("File"))
        self.menuOpenRecent = QMenu(tr("Open Recent"))
        self.menuView = QMenu(tr("View"))
        self.menuDateRange = QMenu(tr("Date Range"))
        self.menuEdit = QMenu(tr("Edit"))
        self.menuHelp = QMenu(tr("Help"))
        self.setMenuBar(self.menubar)
        self.actionOpenDocument = QAction(tr("Open..."), self)
        self.actionOpenDocument.setShortcut("Ctrl+O")
        self.actionShowNetWorth = QAction(tr("Net Worth"), self)
        self.actionShowNetWorth.setShortcut("Ctrl+1")
        self.actionShowNetWorth.setIcon(QIcon(QPixmap(':/balance_sheet_48')))
        self.actionShowProfitLoss = QAction(escapeamp(tr("Profit & Loss")), self)
        self.actionShowProfitLoss.setShortcut("Ctrl+2")
        self.actionShowProfitLoss.setIcon(QIcon(QPixmap(':/income_statement_48')))
        self.actionShowTransactions = QAction(tr("Transactions"), self)
        self.actionShowTransactions.setShortcut("Ctrl+3")
        self.actionShowTransactions.setIcon(QIcon(QPixmap(':/transaction_table_48')))
        self.actionShowSelectedAccount = QAction(tr("Show Account"), self)
        self.actionShowSelectedAccount.setShortcut("Ctrl+]")
        self.actionNewItem = QAction(tr("New Item"), self)
        self.actionNewItem.setShortcut("Ctrl+N")
        self.actionDeleteItem = QAction(tr("Remove Selected"), self)
        self.actionEditItem = QAction(tr("Show Info"), self)
        self.actionEditItem.setShortcut("Ctrl+I")
        self.actionToggleGraph = QAction(tr("Toggle Graph"), self)
        self.actionToggleGraph.setShortcut("Ctrl+Alt+G")
        self.actionTogglePieChart = QAction(tr("Toggle Pie Chart"), self)
        self.actionTogglePieChart.setShortcut("Ctrl+Alt+P")
        self.actionMoveUp = QAction(tr("Move Up"), self)
        self.actionMoveUp.setShortcut("Ctrl++")
        self.actionMoveDown = QAction(tr("Move Down"), self)
        self.actionMoveDown.setShortcut("Ctrl+-")
        self.actionNavigateBack = QAction(tr("Go Back"), self)
        self.actionNavigateBack.setShortcut("Ctrl+[")
        self.actionNewAccountGroup = QAction(tr("New Account Group"), self)
        self.actionNewAccountGroup.setShortcut("Ctrl+Shift+N")
        self.actionShowNextView = QAction(tr("Next View"), self)
        self.actionShowNextView.setShortcut("Ctrl+Shift+]")
        self.actionShowPreviousView = QAction(tr("Previous View"), self)
        self.actionShowPreviousView.setShortcut("Ctrl+Shift+[")
        self.actionNewDocument = QAction(tr("New Document"), self)
        self.actionOpenExampleDocument = QAction(tr("Open Example Document"), self)
        self.actionOpenPluginFolder = QAction(tr("Open Plugin Folder"), self)
        self.actionImport = QAction(tr("Import..."), self)
        self.actionImport.setShortcut("Ctrl+Alt+I")
        self.actionExport = QAction(tr("Export..."), self)
        self.actionExport.setShortcut("Ctrl+Alt+E")
        self.actionSave = QAction(tr("Save"), self)
        self.actionSave.setShortcut("Ctrl+S")
        self.actionSaveAs = QAction(tr("Save As..."), self)
        self.actionSaveAs.setShortcut("Ctrl+Shift+S")
        self.actionAbout = QAction(tr("About moneyGuru"), self)
        self.actionToggleReconciliationMode = QAction(tr("Toggle Reconciliation Mode"), self)
        self.actionToggleReconciliationMode.setShortcut("Ctrl+Shift+R")
        self.actionToggleAccountExclusion = QAction(tr("Toggle Exclusion Status of Account"), self)
        self.actionToggleAccountExclusion.setShortcut("Ctrl+Shift+X")
        self.actionShowSchedules = QAction(tr("Schedules"), self)
        self.actionShowSchedules.setShortcut("Ctrl+4")
        self.actionShowSchedules.setIcon(QIcon(QPixmap(':/schedules_48')))
        self.actionShowBudgets = QAction(tr("Budgets"), self)
        self.actionShowBudgets.setShortcut("Ctrl+5")
        self.actionShowBudgets.setIcon(QIcon(QPixmap(':/budget_48')))
        self.actionReconcileSelected = QAction(tr("Reconcile Selection"), self)
        self.actionReconcileSelected.setShortcut("Ctrl+R")
        self.actionMakeScheduleFromSelected = QAction(tr("Make Schedule from Selected"), self)
        self.actionMakeScheduleFromSelected.setShortcut("Ctrl+M")
        self.actionShowPreferences = QAction(tr("Preferences..."), self)
        self.actionPrint = QAction(tr("Print..."), self)
        self.actionPrint.setShortcut("Ctrl+P")
        self.actionQuit = QAction(tr("Quit moneyGuru"), self)
        self.actionQuit.setShortcut("Ctrl+Q")
        self.actionUndo = QAction(tr("Undo"), self)
        self.actionUndo.setShortcut("Ctrl+Z")
        self.actionRedo = QAction(tr("Redo"), self)
        self.actionRedo.setShortcut("Ctrl+Y")
        self.actionShowHelp = QAction(tr("moneyGuru Help"), self)
        self.actionShowHelp.setShortcut("F1")
        self.actionCheckForUpdate = QAction(tr("Check for update"), self)
        self.actionOpenDebugLog = QAction(tr("Open Debug Log"), self)
        self.actionDuplicateTransaction = QAction(tr("Duplicate Transaction"), self)
        self.actionDuplicateTransaction.setShortcut("Ctrl+D")
        self.actionJumpToAccount = QAction(tr("Jump to Account..."), self)
        self.actionJumpToAccount.setShortcut("Ctrl+Shift+A")
        self.actionNewTab = QAction(tr("New Tab"), self)
        self.actionNewTab.setShortcut("Ctrl+T")
        self.actionCloseTab = QAction(tr("Close Tab"), self)
        self.actionCloseTab.setShortcut("Ctrl+W")

        self.menuFile.addAction(self.actionNewDocument)
        self.menuFile.addAction(self.actionNewTab)
        self.menuFile.addAction(self.actionOpenDocument)
        self.menuFile.addAction(self.menuOpenRecent.menuAction())
        self.menuFile.addAction(self.actionOpenExampleDocument)
        self.menuFile.addAction(self.actionOpenPluginFolder)
        self.menuFile.addAction(self.actionImport)
        self.menuFile.addSeparator()
        self.menuFile.addAction(self.actionCloseTab)
        self.menuFile.addAction(self.actionSave)
        self.menuFile.addAction(self.actionSaveAs)
        self.menuFile.addAction(self.actionExport)
        self.menuFile.addAction(self.actionPrint)
        self.menuFile.addAction(self.actionQuit)
        self.menuView.addAction(self.actionShowNetWorth)
        self.menuView.addAction(self.actionShowProfitLoss)
        self.menuView.addAction(self.actionShowTransactions)
        self.menuView.addAction(self.actionShowSchedules)
        self.menuView.addAction(self.actionShowBudgets)
        self.menuView.addAction(self.actionShowPreviousView)
        self.menuView.addAction(self.actionShowNextView)
        self.menuView.addAction(self.menuDateRange.menuAction())
        self.menuView.addAction(self.actionShowPreferences)
        self.menuView.addAction(self.actionToggleGraph)
        self.menuView.addAction(self.actionTogglePieChart)
        self.menuEdit.addAction(self.actionNewItem)
        self.menuEdit.addAction(self.actionNewAccountGroup)
        self.menuEdit.addAction(self.actionDeleteItem)
        self.menuEdit.addAction(self.actionEditItem)
        self.menuEdit.addSeparator()
        self.menuEdit.addAction(self.actionMoveUp)
        self.menuEdit.addAction(self.actionMoveDown)
        self.menuEdit.addAction(self.actionDuplicateTransaction)
        self.menuEdit.addAction(self.actionMakeScheduleFromSelected)
        self.menuEdit.addAction(self.actionReconcileSelected)
        self.menuEdit.addAction(self.actionToggleReconciliationMode)
        self.menuEdit.addAction(self.actionToggleAccountExclusion)
        self.menuEdit.addSeparator()
        self.menuEdit.addAction(self.actionShowSelectedAccount)
        self.menuEdit.addAction(self.actionNavigateBack)
        self.menuEdit.addAction(self.actionJumpToAccount)
        self.menuEdit.addSeparator()
        self.menuEdit.addAction(self.actionUndo)
        self.menuEdit.addAction(self.actionRedo)
        self.menuHelp.addAction(self.actionShowHelp)
        self.menuHelp.addAction(self.actionCheckForUpdate)
        self.menuHelp.addAction(self.actionOpenDebugLog)
        self.menuHelp.addAction(self.actionAbout)
        mainmenus = [self.menuFile, self.menuEdit, self.menuView, self.menuHelp]
        for menu in mainmenus:
            self.menubar.addAction(menu.menuAction())
            setAccelKeys(menu)
        setAccelKeys(self.menubar)
        self.tabBar.setMovable(True)
        self.tabBar.setTabsClosable(True)
        self.tabBar.setExpanding(False)

        seq = QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_Right)
        self._shortcutNextTab = QShortcut(seq, self)
        seq = QKeySequence(Qt.CTRL + Qt.SHIFT + Qt.Key_Left)
        self._shortcutPrevTab = QShortcut(seq, self)

        # Linux setup
        if ISLINUX:
            self.actionCheckForUpdate.setVisible(False) # This only works on Windows

    def _bindSignals(self):
        self.newItemButton.clicked.connect(self.actionNewItem.trigger)
        self.deleteItemButton.clicked.connect(self.actionDeleteItem.trigger)
        self.editItemButton.clicked.connect(self.actionEditItem.trigger)
        self.graphVisibilityButton.clicked.connect(self.actionToggleGraph.trigger)
        self.piechartVisibilityButton.clicked.connect(self.actionTogglePieChart.trigger)
        self.columnsVisibilityButton.clicked.connect(self.columnsVisibilityButtonClicked)
        self.recentDocuments.mustOpenItem.connect(self.doc.open)
        self.doc.documentOpened.connect(self.recentDocuments.insertItem)
        self.doc.documentSavedAs.connect(self.recentDocuments.insertItem)
        self.doc.documentPathChanged.connect(self.documentPathChanged)
        self.tabBar.currentChanged.connect(self.currentTabChanged)
        self.tabBar.tabCloseRequested.connect(self.tabCloseRequested)
        self.tabBar.tabMoved.connect(self.tabMoved)

        # Views
        self.actionShowNetWorth.triggered.connect(self.showNetWorthTriggered)
        self.actionShowProfitLoss.triggered.connect(self.showProfitLossTriggered)
        self.actionShowTransactions.triggered.connect(self.showTransactionsTriggered)
        self.actionShowSchedules.triggered.connect(self.showSchedulesTriggered)
        self.actionShowBudgets.triggered.connect(self.showBudgetsTriggered)
        self.actionShowPreviousView.triggered.connect(self.showPreviousViewTriggered)
        self.actionShowNextView.triggered.connect(self.showNextViewTriggered)
        self.actionShowPreferences.triggered.connect(self.app.showPreferences)
        self.actionToggleGraph.triggered.connect(self.toggleGraphTriggered)
        self.actionTogglePieChart.triggered.connect(self.togglePieChartTriggered)

        # Document Edition
        self.actionNewItem.triggered.connect(self.newItemTriggered)
        self.actionNewAccountGroup.triggered.connect(self.newAccountGroupTriggered)
        self.actionDeleteItem.triggered.connect(self.deleteItemTriggered)
        self.actionEditItem.triggered.connect(self.editItemTriggered)
        self.actionMoveUp.triggered.connect(self.moveUpTriggered)
        self.actionMoveDown.triggered.connect(self.moveDownTriggered)
        self.actionDuplicateTransaction.triggered.connect(self.model.duplicate_item)
        self.actionUndo.triggered.connect(self.doc.model.undo)
        self.actionRedo.triggered.connect(self.doc.model.redo)

        # Open / Save / Import / Export / New
        self.actionNewDocument.triggered.connect(self.doc.new)
        self.actionOpenDocument.triggered.connect(self.doc.openDocument)
        self.actionOpenExampleDocument.triggered.connect(self.doc.openExampleDocument)
        self.actionOpenPluginFolder.triggered.connect(self.model.app.open_plugin_folder)
        self.actionImport.triggered.connect(self.importDocument)
        self.actionSave.triggered.connect(self.doc.save)
        self.actionSaveAs.triggered.connect(self.doc.saveAs)
        self.actionExport.triggered.connect(self.model.export)

        # Misc
        self.actionNewTab.triggered.connect(self.model.new_tab)
        self.actionCloseTab.triggered.connect(self.closeTabTriggered)
        self.actionShowSelectedAccount.triggered.connect(self.model.show_account)
        self.actionNavigateBack.triggered.connect(self.navigateBackTriggered)
        self.actionJumpToAccount.triggered.connect(self.jumpToAccountTriggered)
        self.actionMakeScheduleFromSelected.triggered.connect(self.makeScheduleFromSelectedTriggered)
        self.actionReconcileSelected.triggered.connect(self.reconcileSelectedTriggered)
        self.actionToggleReconciliationMode.triggered.connect(self.toggleReconciliationModeTriggered)
        self.actionToggleAccountExclusion.triggered.connect(self.toggleAccountExclusionTriggered)
        self.actionPrint.triggered.connect(self._print)
        self.actionShowHelp.triggered.connect(self.app.showHelp)
        self.actionCheckForUpdate.triggered.connect(self.checkForUpdateTriggered)
        self.actionAbout.triggered.connect(self.aboutTriggered)
        self.actionOpenDebugLog.triggered.connect(self.openDebugLogTriggered)
        self.actionQuit.triggered.connect(self.close)

        # Extra Shortcuts
        self._shortcutNextTab.activated.connect(self.showNextViewTriggered)
        self._shortcutPrevTab.activated.connect(self.showPreviousViewTriggered)

    # --- QWidget overrides
    def closeEvent(self, event):
        if self.doc.confirmDestructiveAction():
            event.accept()
        else:
            event.ignore()

    # --- Private
    def _print(self):
        dialog = QPrintDialog(self)
        if dialog.exec_() != QPrintDialog.Accepted:
            return
        printer = dialog.printer()
        currentView = self.mainView.currentWidget()
        viewPrinter = ViewPrinter(printer, currentView)
        currentView.fitViewsForPrint(viewPrinter)
        viewPrinter.render()

    def _getViewforPane(self, pane_type, pane_view):
        if pane_view in self.model2view:
            view = self.model2view[pane_view]
        else:
            view = PANETYPE2VIEWCLASS[pane_type](model=pane_view, mainwindow=self)
            self.model2view[pane_view] = view
            self.mainView.addWidget(view)
            view.restoreSubviewsSize()
        return view

    def _setTabIndex(self, index):
        if not self.tabBar.count():
            return
        self.tabBar.setCurrentIndex(index)
        self._updateActionsState()
        pane_type = self.model.pane_type(index)
        pane_view = self.model.pane_view(index)
        view = self._getViewforPane(pane_type, pane_view)
        self.mainView.setCurrentWidget(view)
        view.setFocus()

    def _activeView(self):
        paneIndex = self.model.current_pane_index
        return self.model.pane_view(paneIndex)

    def _updateActionsState(self):
        # Updates enable/disable checked/unchecked state of all actions. These state can change
        # under various conditions: main view change, date range type change and when reconciliation
        # mode is toggled

        # Determine what actions are enabled
        view = self._activeView()
        viewType = view.VIEW_TYPE
        isSheet = viewType in {PaneType.NetWorth, PaneType.Profit}
        isTransactionOrEntryTable = viewType in {PaneType.Transaction, PaneType.Account}
        canToggleReconciliation = viewType == PaneType.Account and view.can_toggle_reconciliation_mode

        newItemLabel = {
            PaneType.NetWorth: tr("New Account"),
            PaneType.Profit: tr("New Account"),
            PaneType.Transaction: tr("New Transaction"),
            PaneType.Account: tr("New Transaction"),
            PaneType.Schedule: tr("New Schedule"),
            PaneType.Budget: tr("New Budget"),
            PaneType.GeneralLedger: tr("New Transaction"),
        }.get(viewType, tr("New Item")) # XXX make "New Item" disabled
        self.actionNewItem.setText(newItemLabel)
        self.actionNewAccountGroup.setEnabled(isSheet)
        self.actionMoveDown.setEnabled(isTransactionOrEntryTable)
        self.actionMoveUp.setEnabled(isTransactionOrEntryTable)
        self.actionDuplicateTransaction.setEnabled(isTransactionOrEntryTable)
        self.actionMakeScheduleFromSelected.setEnabled(isTransactionOrEntryTable)
        self.actionReconcileSelected.setEnabled(viewType == PaneType.Account and view.reconciliation_mode)
        self.actionShowNextView.setEnabled(self.model.current_pane_index < self.model.pane_count-1)
        self.actionShowPreviousView.setEnabled(self.model.current_pane_index > 0)
        self.actionShowSelectedAccount.setEnabled(isSheet or isTransactionOrEntryTable)
        self.actionNavigateBack.setEnabled(viewType == PaneType.Account)
        self.actionToggleReconciliationMode.setEnabled(canToggleReconciliation)
        self.actionToggleAccountExclusion.setEnabled(isSheet)

    def _updateUndoActions(self):
        if self.doc.model.can_undo():
            self.actionUndo.setEnabled(True)
            self.actionUndo.setText(tr("Undo {0}").format(self.doc.model.undo_description()))
        else:
            self.actionUndo.setEnabled(False)
            self.actionUndo.setText(tr("Undo"))
        if self.doc.model.can_redo():
            self.actionRedo.setEnabled(True)
            self.actionRedo.setText(tr("Redo {0}").format(self.doc.model.redo_description()))
        else:
            self.actionRedo.setEnabled(False)
            self.actionRedo.setText(tr("Redo"))

    # --- Actions
    # Views
    def showNetWorthTriggered(self):
        self.model.select_pane_of_type(PaneType.NetWorth)

    def showProfitLossTriggered(self):
        self.model.select_pane_of_type(PaneType.Profit)

    def showTransactionsTriggered(self):
        self.model.select_pane_of_type(PaneType.Transaction)

    def showSchedulesTriggered(self):
        self.model.select_pane_of_type(PaneType.Schedule)

    def showBudgetsTriggered(self):
        self.model.select_pane_of_type(PaneType.Budget)

    def showPreviousViewTriggered(self):
        self.model.select_previous_view()

    def showNextViewTriggered(self):
        self.model.select_next_view()

    # Document Edition
    def newItemTriggered(self):
        self.model.new_item()

    def newAccountGroupTriggered(self):
        self.model.new_group()

    def deleteItemTriggered(self):
        self.model.delete_item()

    def editItemTriggered(self):
        self.model.edit_item()

    def moveUpTriggered(self):
        self.model.move_up()

    def moveDownTriggered(self):
        self.model.move_down()

    # Misc
    def closeTabTriggered(self):
        self.model.close_pane(self.model.current_pane_index)

    def navigateBackTriggered(self):
        self.model.navigate_back()

    def jumpToAccountTriggered(self):
        self.model.jump_to_account()

    def makeScheduleFromSelectedTriggered(self):
        self.model.make_schedule_from_selected()

    def reconcileSelectedTriggered(self):
        self._activeView().etable.toggle_reconciled()

    def toggleReconciliationModeTriggered(self):
        self._activeView().toggle_reconciliation_mode()
        self._updateActionsState()

    def toggleAccountExclusionTriggered(self):
        viewType = self.model.pane_type(self.model.current_pane_index)
        if viewType in {PaneType.NetWorth, PaneType.Profit}:
            self._activeView().sheet.toggle_excluded()

    def toggleGraphTriggered(self):
        self.model.toggle_area_visibility(PaneArea.BottomGraph)

    def togglePieChartTriggered(self):
        self.model.toggle_area_visibility(PaneArea.RightChart)

    def columnsVisibilityButtonClicked(self):
        items = self.model.column_menu_items()
        if not items:
            return
        menu = QMenu()
        for i, (display, marked) in enumerate(items):
            action = menu.addAction(display)
            action.setCheckable(True)
            action.setChecked(marked)
            action.setData(i)
            action.triggered.connect(self.columnsMenuItemWasClicked)
        self._columnMenuHolder = menu # we need to hold a reference to it while it popups
        button = self.columnsVisibilityButton
        menu.popup(button.parentWidget().mapToGlobal(button.geometry().topLeft()))

    def columnsMenuItemWasClicked(self):
        action = self.sender()
        if action is not None:
            index = action.data()
            self.model.toggle_column_menu_item(index)

    def checkForUpdateTriggered(self):
        QProcess.execute('updater.exe', ['/checknow'])

    def aboutTriggered(self):
        self.app.showAboutBox()

    def openDebugLogTriggered(self):
        debugLogPath = op.join(getAppData(), 'debug.log')
        url = QUrl.fromLocalFile(debugLogPath)
        QDesktopServices.openUrl(url)

    def importDocument(self):
        title = tr("Select a document to import")
        filters = tr("Supported files (*.moneyguru *.ofx *.qfx *.qif *.csv *.txt)")
        docpath, filetype = QFileDialog.getOpenFileName(self.app.mainWindow, title, '', filters)
        # There's a strange glitch under GNOME where, right after the dialog is gone, the main
        # window isn't the active window, but it will become active if we give it enough time. If we
        # start showing the import window before that happens, we'll end up with an import window
        # under the main window, which is bad. Therefore, we process events until this happens. We
        # do this in a big forloop instead of a while to avoid a possible infinite loop.
        for i in range(10000):
            if self.app.mainWindow.isActiveWindow():
                break
            QApplication.processEvents()
        if docpath:
            try:
                self.model.parse_file_for_import(docpath)
            except FileFormatError as e:
                QMessageBox.warning(self.app.mainWindow, tr("Cannot import file"), str(e))

    # --- Other Signals
    def currentTabChanged(self, index):
        self.model.current_pane_index = index
        self._setTabIndex(index)

    def documentPathChanged(self):
        if self.doc.documentPath:
            title = "moneyGuru ({})".format(self.doc.documentPath)
        else:
            title = "moneyGuru"
        self.setWindowTitle(title)

    def tabCloseRequested(self, index):
        self.model.close_pane(index)

    def tabMoved(self, fromIndex, toIndex):
        self.model.move_pane(fromIndex, toIndex)

    # --- model --> view
    def change_current_pane(self):
        self._setTabIndex(self.model.current_pane_index)

    def get_panel_view(self, model):
        if isinstance(model, CustomDateRangePanelModel):
            return CustomDateRangePanel(model, self)
        else:
            return ExportPanel(model, self)

    def refresh_panes(self):
        # Always remove the "new tab" tab
        if self.tabBar.count() > 0:
            self.tabBar.removeTab(self.tabBar.count()-1)
        while self.tabBar.count() < self.model.pane_count:
            self.tabBar.addTab('')
        for i in range(self.model.pane_count):
            pane_label = self.model.pane_label(i)
            pane_label = escapeamp(pane_label)
            self.tabBar.setTabText(i, pane_label)
            pane_type = self.model.pane_type(i)
            pane_view = self.model.pane_view(i)
            # Ensure that the view's "view" has been created and bound
            self._getViewforPane(pane_type, pane_view)
            iconname = PANETYPE2ICON.get(pane_type)
            icon = QIcon(QPixmap(':/{0}'.format(iconname))) if iconname else QIcon()
            self.tabBar.setTabIcon(i, icon)
        # It's important that we proceed with tab removal *after* we've completed tab initialization.
        # We're walking on eggshells here. refresh_panes() can be called in multiple situations, one
        # of them is during the opening of a document. When that happens when another document was
        # previously opened, all views' model are uninitalized and don't have their "view" attribute
        # set yet. If we proceed with the setCurrentIndex() call below before _getViewforPane()
        # could be called above, we get a crash.
        if self.tabBar.currentIndex() >= self.model.pane_count:
            # Normally, we don't touch the tabBar index here and wait for change_current_pane,
            # but when we remove tabs, it's possible that currentTabChanged end up being called and
            # then the tab selection is bugged. I tried disconnecting/reconnecting the signal, but
            # this is buggy. So when a selected tab is about to be removed and is out of bounds,
            # we change the selection to the last index in the model. We don't use
            # self.model.current_pane_index because in some cases, it's -1 and prevents this crash
            # preventer from preventing its crash.
            self.tabBar.setCurrentIndex(self.model.pane_count - 1)
        while self.tabBar.count() > self.model.pane_count:
            self.tabBar.removeTab(self.tabBar.count()-1)
        self.tabBar.setTabsClosable(self.model.pane_count > 1)
        # Add the "new tab" tab
        last_tab_index = self.tabBar.addTab('')
        self.tabBar.setTabEnabled(last_tab_index, False)
        newTabButton = QToolButton()
        newTabButton.setText("+")
        newTabButton.clicked.connect(self.model.new_tab)
        self.tabBar.setTabButton(last_tab_index, QTabBar.RightSide, newTabButton)

    def refresh_status_line(self):
        self.statusLabel.setText(self.model.status_line)

    def refresh_undo_actions(self):
        self._updateUndoActions()

    def restore_window_frame(self, frame):
        self.setGeometry(*frame)

    def save_window_frame(self):
        r = self.geometry()
        return (r.x(), r.y(), r.width(), r.height())

    def show_message(self, msg):
        title = tr("Warning")
        QMessageBox.warning(self, title, msg)

    def update_area_visibility(self):
        hidden = self.model.hidden_areas
        graphimg = ':/graph_visibility_{}_16'.format('off' if PaneArea.BottomGraph in hidden else 'on')
        pieimg = ':/piechart_visibility_{}_16'.format('off' if PaneArea.RightChart in hidden else 'on')
        self.graphVisibilityButton.setIcon(QIcon(QPixmap(graphimg)))
        self.piechartVisibilityButton.setIcon(QIcon(QPixmap(pieimg)))

    def view_closed(self, index):
        self.tabBar.removeTab(index)
        self.tabBar.setTabsClosable(self.model.pane_count > 1)
Exemple #32
0
class CMWMainTabs(QWidget):
    """GUI for tabs and associated widgets
    """
    tab_names = [
        'CDB', 'Image', 'Text', 'Calib', 'HDF5', 'XTC', 't-converter',
        'Configuration', 'Mask'
    ]

    tool_tips = [\
      'Calibration Data Base\nviewer/manager',\
      'Image Viewer for ndarrays',\
      'Text Browser for text-like calibration constants',\
      'File Manager for easy access calibration constants\nunder experimental calib directory',\
      'HDF5 file browser',\
      'XTC data viewer',\
      'Time converter between Date&Time <-> POSIX <-> LCLS2',\
      'Configuration manager for this app',\
      'Mask Editor for images',\
    ]

    def __init__(self, parent=None, app=None):

        QWidget.__init__(self, parent)

        cp.cmwmaintabs = self

        self.box_layout = QHBoxLayout()

        start_tab_name = cp.main_tab_name.value()
        self.gui_win = None
        self.make_tab_bar(start_tab_name)
        self.gui_selector(start_tab_name)

        self.box = QVBoxLayout(self)
        self.box.addWidget(self.tab_bar)
        self.box.addLayout(self.box_layout)

        self.setLayout(self.box)

        self.set_tool_tips()
        self.set_style()

    def set_tool_tips(self):
        for t, s in zip(self.tab_names, self.tool_tips):
            self.tab_bar.setTabToolTip(self.tab_names.index(t), s)

    def set_style(self):
        from psana.graphqt.Styles import style
        from psana.graphqt.QWIcons import icon
        icon.set_icons()
        self.setWindowIcon(icon.icon_monitor)
        self.setStyleSheet(style.styleBkgd)
        self.layout().setContentsMargins(0, 0, 0, 0)

    def make_tab_bar(self, start_tab_name):
        self.tab_bar = QTabBar()

        for tab_name in self.tab_names:
            tab_ind = self.tab_bar.addTab(tab_name)
            self.tab_bar.setTabTextColor(tab_ind,
                                         QColor('blue'))  #gray, red, grayblue

        self.tab_bar.setShape(QTabBar.RoundedNorth)

        tab_index = self.tab_names.index(start_tab_name)
        self.tab_bar.setCurrentIndex(tab_index)
        logger.debug('make_tab_bar - set tab index: %d' % tab_index)

        self.tab_bar.currentChanged['int'].connect(self.on_tab_bar)
        self.tab_bar.tabCloseRequested.connect(self.on_tab_close_request)
        self.tab_bar.tabMoved[int, int].connect(self.on_tab_moved)

    def gui_selector(self, tab_name):

        if self.gui_win is not None:
            self.gui_win.close()
            del self.gui_win

        w_height = 200
        if cp.cmwmain is not None: cp.cmwmain.wlog.setVisible(True)

        if tab_name == 'CDB':
            from psana.graphqt.CMWDBMain import CMWDBMain
            self.gui_win = CMWDBMain()
            w_height = 500

        elif tab_name == 'Configuration':
            from psana.graphqt.CMWConfig import CMWConfig
            self.gui_win = CMWConfig()
            w_height = 500

        elif tab_name == 't-converter':
            from psana.graphqt.QWDateTimeSec import QWDateTimeSec
            self.gui_win = QWDateTimeSec()
            self.gui_win.setMaximumWidth(400)
            w_height = 80

        elif tab_name == 'HDF5':
            from psana.graphqt.H5VMain import H5VMain
            #if cp.cmwmain is not None: cp.cmwmain.wlog.setVisible(False)
            self.gui_win = H5VMain()

        elif tab_name == 'Calib':
            from psana.graphqt.FMW1Main import FMW1Main
            self.gui_win = FMW1Main()
            #from psana.graphqt.FMWTabs import FMWTabs
            #self.gui_win = FMWTabs()

        elif tab_name == 'Image':
            from psana.graphqt.IVMain import IVMain
            #if cp.cmwmain is not None: cp.cmwmain.wlog.setVisible(False)
            self.gui_win = IVMain()

        elif tab_name == 'Text':
            from psana.graphqt.QWTextBrowser import QWTextBrowser
            self.gui_win = QWTextBrowser()

        elif tab_name == 'XTC':
            from psana.graphqt.DMQWMain import DMQWMain
            self.gui_win = DMQWMain()

        elif tab_name == 'Mask':
            self.gui_win = QTextEdit('Selected tab "%s"' % tab_name)

        else:
            self.gui_win = QTextEdit('Selected tab "%s"' % tab_name)

        #self.gui_win.setMinimumHeight(w_height)
        self.gui_win.setVisible(True)
        self.box_layout.addWidget(self.gui_win)

    def current_tab_index_and_name(self):
        tab_ind = self.tab_bar.currentIndex()
        tab_name = str(self.tab_bar.tabText(tab_ind))
        return tab_ind, tab_name

    def on_tab_bar(self, ind):
        tab_ind, tab_name = self.current_tab_index_and_name()
        logger.info('Selected tab "%s"' % tab_name)
        cp.main_tab_name.setValue(tab_name)
        self.gui_selector(tab_name)

    def on_tab_close_request(self, ind):
        logger.debug('on_tab_close_request ind:%d' % ind)
        #self.tab_bar.removeTab(ind)

    def on_tab_moved(self, inew, iold):
        logger.debug('on_tab_close_request tab index begin:%d -> end:%d' %
                     (iold, inew))

    def closeEvent(self, e):
        logger.debug('closeEvent')

        if self.gui_win is not None:
            self.gui_win.close()

        QWidget.closeEvent(self, e)

        cp.cmwmaintabs = None

    def onExit(self):
        logger.debug('onExit')
        self.close()

    def set_tabs_visible(self, is_visible):
        logger.debug('set_tabs_visible: is_visible %s' % is_visible)
        self.tab_bar.setVisible(is_visible)

    def tab_bar_is_visible(self):
        return self.tab_bar.isVisible()

    def view_hide_tabs(self):
        self.tab_bar.setVisible(not self.tab_bar.isVisible())

    def view_data(self, data=None, fname=None):
        from psana.pyalgos.generic.NDArrUtils import info_ndarr, np
        cp.last_selected_data = data
        cp.last_selected_fname.setValue(fname)
        if data is None and fname is None:
            logger.debug('data and fname are None - do not switch to viewer')
        elif data is None:
            tabname = 'Text' if 'geometry' in fname or 'common_mode' in fname else 'Image'
            self.set_tab(tabname)
        elif isinstance(data, np.ndarray):
            logger.info(
                info_ndarr(data, 'switch to Image Viewer to view data:'))
            self.set_tab(tabname='Image')
        elif isinstance(data, str):
            logger.info(info_ndarr(data,
                                   'switch to Text Viewer to view data:'))
            self.set_tab(tabname='Text')
        elif isinstance(data, dict):
            from psana.pscalib.calib.MDBConvertUtils import info_dict
            logger.info(
                'data is dict switch to Text Viewer to view data as info_dict')
            cp.last_selected_data = info_dict(
                data, offset='  ', s='')  #str(cp.last_selected_data)
            self.set_tab(tabname='Text')
        else:
            logger.debug(
                'data of the selected document is not numpy array - do not switch to Image Viewer'
            )
            cp.last_selected_data = None

    def set_tab(self, tabname='Image'):
        logger.debug('switch tab to %s' % str(tabname))
        self.tab_bar.setCurrentIndex(self.tab_names.index(tabname))

    def key_usage(self):
        return 'Keys:'\
               '\n  V - view/hide tabs'\
               '\n'

    if __name__ == "__main__":

        def keyPressEvent(self, e):
            #logger.debug('keyPressEvent, key=%s' % e.key())
            if e.key() == Qt.Key_Escape:
                self.close()

            elif e.key() == Qt.Key_V:
                self.view_hide_tabs()

            else:
                logger.debug(self.key_usage())
Exemple #33
0
class E5SideBar(QWidget):
    """
    Class implementing a sidebar with a widget area, that is hidden or shown,
    if the current tab is clicked again.
    """
    Version = 1
    
    North = 0
    East = 1
    South = 2
    West = 3
    
    def __init__(self, orientation=None, delay=200, parent=None):
        """
        Constructor
        
        @param orientation orientation of the sidebar widget (North, East,
            South, West)
        @param delay value for the expand/shrink delay in milliseconds
            (integer)
        @param parent parent widget (QWidget)
        """
        super(E5SideBar, self).__init__(parent)
        
        self.__tabBar = QTabBar()
        self.__tabBar.setDrawBase(True)
        self.__tabBar.setShape(QTabBar.RoundedNorth)
        self.__tabBar.setUsesScrollButtons(True)
        self.__tabBar.setDrawBase(False)
        self.__stackedWidget = QStackedWidget(self)
        self.__stackedWidget.setContentsMargins(0, 0, 0, 0)
        self.__autoHideButton = QToolButton()
        self.__autoHideButton.setCheckable(True)
        self.__autoHideButton.setIcon(
            UI.PixmapCache.getIcon("autoHideOff.png"))
        self.__autoHideButton.setChecked(True)
        self.__autoHideButton.setToolTip(
            self.tr("Deselect to activate automatic collapsing"))
        self.barLayout = QBoxLayout(QBoxLayout.LeftToRight)
        self.barLayout.setContentsMargins(0, 0, 0, 0)
        self.layout = QBoxLayout(QBoxLayout.TopToBottom)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)
        self.barLayout.addWidget(self.__autoHideButton)
        self.barLayout.addWidget(self.__tabBar)
        self.layout.addLayout(self.barLayout)
        self.layout.addWidget(self.__stackedWidget)
        self.setLayout(self.layout)
        
        # initialize the delay timer
        self.__actionMethod = None
        self.__delayTimer = QTimer(self)
        self.__delayTimer.setSingleShot(True)
        self.__delayTimer.setInterval(delay)
        self.__delayTimer.timeout.connect(self.__delayedAction)
        
        self.__minimized = False
        self.__minSize = 0
        self.__maxSize = 0
        self.__bigSize = QSize()
        
        self.splitter = None
        self.splitterSizes = []
        
        self.__hasFocus = False
        # flag storing if this widget or any child has the focus
        self.__autoHide = False
        
        self.__tabBar.installEventFilter(self)
        
        self.__orientation = E5SideBar.North
        if orientation is None:
            orientation = E5SideBar.North
        self.setOrientation(orientation)
        
        self.__tabBar.currentChanged[int].connect(
            self.__stackedWidget.setCurrentIndex)
        e5App().focusChanged[QWidget, QWidget].connect(self.__appFocusChanged)
        self.__autoHideButton.toggled[bool].connect(self.__autoHideToggled)
    
    def setSplitter(self, splitter):
        """
        Public method to set the splitter managing the sidebar.
        
        @param splitter reference to the splitter (QSplitter)
        """
        self.splitter = splitter
        self.splitter.splitterMoved.connect(self.__splitterMoved)
        self.splitter.setChildrenCollapsible(False)
        index = self.splitter.indexOf(self)
        self.splitter.setCollapsible(index, False)
    
    def __splitterMoved(self, pos, index):
        """
        Private slot to react on splitter moves.
        
        @param pos new position of the splitter handle (integer)
        @param index index of the splitter handle (integer)
        """
        if self.splitter:
            self.splitterSizes = self.splitter.sizes()
    
    def __delayedAction(self):
        """
        Private slot to handle the firing of the delay timer.
        """
        if self.__actionMethod is not None:
            self.__actionMethod()
    
    def setDelay(self, delay):
        """
        Public method to set the delay value for the expand/shrink delay in
        milliseconds.
        
        @param delay value for the expand/shrink delay in milliseconds
            (integer)
        """
        self.__delayTimer.setInterval(delay)
    
    def delay(self):
        """
        Public method to get the delay value for the expand/shrink delay in
        milliseconds.
        
        @return value for the expand/shrink delay in milliseconds (integer)
        """
        return self.__delayTimer.interval()
    
    def __cancelDelayTimer(self):
        """
        Private method to cancel the current delay timer.
        """
        self.__delayTimer.stop()
        self.__actionMethod = None
    
    def shrink(self):
        """
        Public method to record a shrink request.
        """
        self.__delayTimer.stop()
        self.__actionMethod = self.__shrinkIt
        self.__delayTimer.start()
   
    def __shrinkIt(self):
        """
        Private method to shrink the sidebar.
        """
        self.__minimized = True
        self.__bigSize = self.size()
        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            self.__minSize = self.minimumSizeHint().height()
            self.__maxSize = self.maximumHeight()
        else:
            self.__minSize = self.minimumSizeHint().width()
            self.__maxSize = self.maximumWidth()
        if self.splitter:
            self.splitterSizes = self.splitter.sizes()
        
        self.__stackedWidget.hide()
        
        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            self.setFixedHeight(self.__tabBar.minimumSizeHint().height())
        else:
            self.setFixedWidth(self.__tabBar.minimumSizeHint().width())
        
        self.__actionMethod = None
    
    def expand(self):
        """
        Public method to record a expand request.
        """
        self.__delayTimer.stop()
        self.__actionMethod = self.__expandIt
        self.__delayTimer.start()
    
    def __expandIt(self):
        """
        Private method to expand the sidebar.
        """
        self.__minimized = False
        self.__stackedWidget.show()
        self.resize(self.__bigSize)
        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            minSize = max(self.__minSize, self.minimumSizeHint().height())
            self.setMinimumHeight(minSize)
            self.setMaximumHeight(self.__maxSize)
        else:
            minSize = max(self.__minSize, self.minimumSizeHint().width())
            self.setMinimumWidth(minSize)
            self.setMaximumWidth(self.__maxSize)
        if self.splitter:
            self.splitter.setSizes(self.splitterSizes)
        
        self.__actionMethod = None
    
    def isMinimized(self):
        """
        Public method to check the minimized state.
        
        @return flag indicating the minimized state (boolean)
        """
        return self.__minimized
    
    def isAutoHiding(self):
        """
        Public method to check, if the auto hide function is active.
        
        @return flag indicating the state of auto hiding (boolean)
        """
        return self.__autoHide
    
    def eventFilter(self, obj, evt):
        """
        Public method to handle some events for the tabbar.
        
        @param obj reference to the object (QObject)
        @param evt reference to the event object (QEvent)
        @return flag indicating, if the event was handled (boolean)
        """
        if obj == self.__tabBar:
            if evt.type() == QEvent.MouseButtonPress:
                pos = evt.pos()
                for i in range(self.__tabBar.count()):
                    if self.__tabBar.tabRect(i).contains(pos):
                        break
                
                if i == self.__tabBar.currentIndex():
                    if self.isMinimized():
                        self.expand()
                    else:
                        self.shrink()
                    return True
                elif self.isMinimized():
                    self.expand()
            elif evt.type() == QEvent.Wheel:
                if qVersion() >= "5.0.0":
                    delta = evt.angleDelta().y()
                else:
                    delta = evt.delta()
                if delta > 0:
                    self.prevTab()
                else:
                    self.nextTab()
                return True
        
        return QWidget.eventFilter(self, obj, evt)
    
    def addTab(self, widget, iconOrLabel, label=None):
        """
        Public method to add a tab to the sidebar.
        
        @param widget reference to the widget to add (QWidget)
        @param iconOrLabel reference to the icon or the label text of the tab
            (QIcon, string)
        @param label the labeltext of the tab (string) (only to be
            used, if the second parameter is a QIcon)
        """
        if label:
            index = self.__tabBar.addTab(iconOrLabel, label)
            self.__tabBar.setTabToolTip(index, label)
        else:
            index = self.__tabBar.addTab(iconOrLabel)
            self.__tabBar.setTabToolTip(index, iconOrLabel)
        self.__stackedWidget.addWidget(widget)
        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            self.__minSize = self.minimumSizeHint().height()
        else:
            self.__minSize = self.minimumSizeHint().width()
    
    def insertTab(self, index, widget, iconOrLabel, label=None):
        """
        Public method to insert a tab into the sidebar.
        
        @param index the index to insert the tab at (integer)
        @param widget reference to the widget to insert (QWidget)
        @param iconOrLabel reference to the icon or the labeltext of the tab
            (QIcon, string)
        @param label the labeltext of the tab (string) (only to be
            used, if the second parameter is a QIcon)
        """
        if label:
            index = self.__tabBar.insertTab(index, iconOrLabel, label)
            self.__tabBar.setTabToolTip(index, label)
        else:
            index = self.__tabBar.insertTab(index, iconOrLabel)
            self.__tabBar.setTabToolTip(index, iconOrLabel)
        self.__stackedWidget.insertWidget(index, widget)
        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            self.__minSize = self.minimumSizeHint().height()
        else:
            self.__minSize = self.minimumSizeHint().width()
    
    def removeTab(self, index):
        """
        Public method to remove a tab.
        
        @param index the index of the tab to remove (integer)
        """
        self.__stackedWidget.removeWidget(self.__stackedWidget.widget(index))
        self.__tabBar.removeTab(index)
        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            self.__minSize = self.minimumSizeHint().height()
        else:
            self.__minSize = self.minimumSizeHint().width()
    
    def clear(self):
        """
        Public method to remove all tabs.
        """
        while self.count() > 0:
            self.removeTab(0)
    
    def prevTab(self):
        """
        Public slot used to show the previous tab.
        """
        ind = self.currentIndex() - 1
        if ind == -1:
            ind = self.count() - 1
            
        self.setCurrentIndex(ind)
        self.currentWidget().setFocus()
    
    def nextTab(self):
        """
        Public slot used to show the next tab.
        """
        ind = self.currentIndex() + 1
        if ind == self.count():
            ind = 0
            
        self.setCurrentIndex(ind)
        self.currentWidget().setFocus()
    
    def count(self):
        """
        Public method to get the number of tabs.
        
        @return number of tabs in the sidebar (integer)
        """
        return self.__tabBar.count()
    
    def currentIndex(self):
        """
        Public method to get the index of the current tab.
        
        @return index of the current tab (integer)
        """
        return self.__stackedWidget.currentIndex()
    
    def setCurrentIndex(self, index):
        """
        Public slot to set the current index.
        
        @param index the index to set as the current index (integer)
        """
        self.__tabBar.setCurrentIndex(index)
        self.__stackedWidget.setCurrentIndex(index)
        if self.isMinimized():
            self.expand()
    
    def currentWidget(self):
        """
        Public method to get a reference to the current widget.
        
        @return reference to the current widget (QWidget)
        """
        return self.__stackedWidget.currentWidget()
    
    def setCurrentWidget(self, widget):
        """
        Public slot to set the current widget.
        
        @param widget reference to the widget to become the current widget
            (QWidget)
        """
        self.__stackedWidget.setCurrentWidget(widget)
        self.__tabBar.setCurrentIndex(self.__stackedWidget.currentIndex())
        if self.isMinimized():
            self.expand()
    
    def indexOf(self, widget):
        """
        Public method to get the index of the given widget.
        
        @param widget reference to the widget to get the index of (QWidget)
        @return index of the given widget (integer)
        """
        return self.__stackedWidget.indexOf(widget)
    
    def isTabEnabled(self, index):
        """
        Public method to check, if a tab is enabled.
        
        @param index index of the tab to check (integer)
        @return flag indicating the enabled state (boolean)
        """
        return self.__tabBar.isTabEnabled(index)
    
    def setTabEnabled(self, index, enabled):
        """
        Public method to set the enabled state of a tab.
        
        @param index index of the tab to set (integer)
        @param enabled enabled state to set (boolean)
        """
        self.__tabBar.setTabEnabled(index, enabled)
    
    def orientation(self):
        """
        Public method to get the orientation of the sidebar.
        
        @return orientation of the sidebar (North, East, South, West)
        """
        return self.__orientation
    
    def setOrientation(self, orient):
        """
        Public method to set the orientation of the sidebar.

        @param orient orientation of the sidebar (North, East, South, West)
        """
        if orient == E5SideBar.North:
            self.__tabBar.setShape(QTabBar.RoundedNorth)
            self.__tabBar.setSizePolicy(
                QSizePolicy.Expanding, QSizePolicy.Preferred)
            self.barLayout.setDirection(QBoxLayout.LeftToRight)
            self.layout.setDirection(QBoxLayout.TopToBottom)
            self.layout.setAlignment(self.barLayout, Qt.AlignLeft)
        elif orient == E5SideBar.East:
            self.__tabBar.setShape(QTabBar.RoundedEast)
            self.__tabBar.setSizePolicy(
                QSizePolicy.Preferred, QSizePolicy.Expanding)
            self.barLayout.setDirection(QBoxLayout.TopToBottom)
            self.layout.setDirection(QBoxLayout.RightToLeft)
            self.layout.setAlignment(self.barLayout, Qt.AlignTop)
        elif orient == E5SideBar.South:
            self.__tabBar.setShape(QTabBar.RoundedSouth)
            self.__tabBar.setSizePolicy(
                QSizePolicy.Expanding, QSizePolicy.Preferred)
            self.barLayout.setDirection(QBoxLayout.LeftToRight)
            self.layout.setDirection(QBoxLayout.BottomToTop)
            self.layout.setAlignment(self.barLayout, Qt.AlignLeft)
        elif orient == E5SideBar.West:
            self.__tabBar.setShape(QTabBar.RoundedWest)
            self.__tabBar.setSizePolicy(
                QSizePolicy.Preferred, QSizePolicy.Expanding)
            self.barLayout.setDirection(QBoxLayout.TopToBottom)
            self.layout.setDirection(QBoxLayout.LeftToRight)
            self.layout.setAlignment(self.barLayout, Qt.AlignTop)
        self.__orientation = orient
    
    def tabIcon(self, index):
        """
        Public method to get the icon of a tab.
        
        @param index index of the tab (integer)
        @return icon of the tab (QIcon)
        """
        return self.__tabBar.tabIcon(index)
    
    def setTabIcon(self, index, icon):
        """
        Public method to set the icon of a tab.
        
        @param index index of the tab (integer)
        @param icon icon to be set (QIcon)
        """
        self.__tabBar.setTabIcon(index, icon)
    
    def tabText(self, index):
        """
        Public method to get the text of a tab.
        
        @param index index of the tab (integer)
        @return text of the tab (string)
        """
        return self.__tabBar.tabText(index)
    
    def setTabText(self, index, text):
        """
        Public method to set the text of a tab.
        
        @param index index of the tab (integer)
        @param text text to set (string)
        """
        self.__tabBar.setTabText(index, text)
    
    def tabToolTip(self, index):
        """
        Public method to get the tooltip text of a tab.
        
        @param index index of the tab (integer)
        @return tooltip text of the tab (string)
        """
        return self.__tabBar.tabToolTip(index)
    
    def setTabToolTip(self, index, tip):
        """
        Public method to set the tooltip text of a tab.
        
        @param index index of the tab (integer)
        @param tip tooltip text to set (string)
        """
        self.__tabBar.setTabToolTip(index, tip)
    
    def tabWhatsThis(self, index):
        """
        Public method to get the WhatsThis text of a tab.
        
        @param index index of the tab (integer)
        @return WhatsThis text of the tab (string)
        """
        return self.__tabBar.tabWhatsThis(index)
    
    def setTabWhatsThis(self, index, text):
        """
        Public method to set the WhatsThis text of a tab.
        
        @param index index of the tab (integer)
        @param text WhatsThis text to set (string)
        """
        self.__tabBar.setTabWhatsThis(index, text)
    
    def widget(self, index):
        """
        Public method to get a reference to the widget associated with a tab.
        
        @param index index of the tab (integer)
        @return reference to the widget (QWidget)
        """
        return self.__stackedWidget.widget(index)
    
    def saveState(self):
        """
        Public method to save the state of the sidebar.
        
        @return saved state as a byte array (QByteArray)
        """
        if len(self.splitterSizes) == 0:
            if self.splitter:
                self.splitterSizes = self.splitter.sizes()
            self.__bigSize = self.size()
            if self.__orientation in [E5SideBar.North, E5SideBar.South]:
                self.__minSize = self.minimumSizeHint().height()
                self.__maxSize = self.maximumHeight()
            else:
                self.__minSize = self.minimumSizeHint().width()
                self.__maxSize = self.maximumWidth()
        
        data = QByteArray()
        stream = QDataStream(data, QIODevice.WriteOnly)
        stream.setVersion(QDataStream.Qt_4_6)
        
        stream.writeUInt16(self.Version)
        stream.writeBool(self.__minimized)
        stream << self.__bigSize
        stream.writeUInt16(self.__minSize)
        stream.writeUInt16(self.__maxSize)
        stream.writeUInt16(len(self.splitterSizes))
        for size in self.splitterSizes:
            stream.writeUInt16(size)
        stream.writeBool(self.__autoHide)
        
        return data
    
    def restoreState(self, state):
        """
        Public method to restore the state of the sidebar.
        
        @param state byte array containing the saved state (QByteArray)
        @return flag indicating success (boolean)
        """
        if state.isEmpty():
            return False
        
        if self.__orientation in [E5SideBar.North, E5SideBar.South]:
            minSize = self.layout.minimumSize().height()
            maxSize = self.maximumHeight()
        else:
            minSize = self.layout.minimumSize().width()
            maxSize = self.maximumWidth()
        
        data = QByteArray(state)
        stream = QDataStream(data, QIODevice.ReadOnly)
        stream.setVersion(QDataStream.Qt_4_6)
        stream.readUInt16()  # version
        minimized = stream.readBool()
        
        if minimized and not self.__minimized:
            self.shrink()
        
        stream >> self.__bigSize
        self.__minSize = max(stream.readUInt16(), minSize)
        self.__maxSize = max(stream.readUInt16(), maxSize)
        count = stream.readUInt16()
        self.splitterSizes = []
        for i in range(count):
            self.splitterSizes.append(stream.readUInt16())
        
        self.__autoHide = stream.readBool()
        self.__autoHideButton.setChecked(not self.__autoHide)
        
        if not minimized:
            self.expand()
        
        return True
    
    #######################################################################
    ## methods below implement the autohide functionality
    #######################################################################
    
    def __autoHideToggled(self, checked):
        """
        Private slot to handle the toggling of the autohide button.
        
        @param checked flag indicating the checked state of the button
            (boolean)
        """
        self.__autoHide = not checked
        if self.__autoHide:
            self.__autoHideButton.setIcon(
                UI.PixmapCache.getIcon("autoHideOn.png"))
        else:
            self.__autoHideButton.setIcon(
                UI.PixmapCache.getIcon("autoHideOff.png"))
    
    def __appFocusChanged(self, old, now):
        """
        Private slot to handle a change of the focus.
        
        @param old reference to the widget, that lost focus (QWidget or None)
        @param now reference to the widget having the focus (QWidget or None)
        """
        self.__hasFocus = self.isAncestorOf(now)
        if self.__autoHide and not self.__hasFocus and not self.isMinimized():
            self.shrink()
        elif self.__autoHide and self.__hasFocus and self.isMinimized():
            self.expand()
    
    def enterEvent(self, event):
        """
        Protected method to handle the mouse entering this widget.
        
        @param event reference to the event (QEvent)
        """
        if self.__autoHide and self.isMinimized():
            self.expand()
        else:
            self.__cancelDelayTimer()
    
    def leaveEvent(self, event):
        """
        Protected method to handle the mouse leaving this widget.
        
        @param event reference to the event (QEvent)
        """
        if self.__autoHide and not self.__hasFocus and not self.isMinimized():
            self.shrink()
        else:
            self.__cancelDelayTimer()
    
    def shutdown(self):
        """
        Public method to shut down the object.
        
        This method does some preparations so the object can be deleted
        properly. It disconnects from the focusChanged signal in order to
        avoid trouble later on.
        """
        e5App().focusChanged[QWidget, QWidget].disconnect(
            self.__appFocusChanged)
Exemple #34
0
class App(QFrame):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Web Browser")
        self.setBaseSize(1366, 768)
        self.setMinimumSize(1366, 768)
        self.setWindowIcon(QIcon("logo.png"))
        self.CreateApp()

    def CreateApp(self):
        self.layout = QVBoxLayout()
        self.layout.setSpacing(0)
        self.layout.setContentsMargins(0,0,0,0)

        # Create Tabs
        self.tabbar = QTabBar(movable=True, tabsClosable=True)
        self.tabbar.tabCloseRequested.connect(self.CloseTab)
        self.tabbar.tabBarClicked.connect(self.SwitchTab)
        self.tabbar.setCurrentIndex(0)
        self.tabbar.setDrawBase(False)

        # Create a shortcut key for a new tab
        self.shortcutNewTab = QShortcut(QKeySequence("Ctrl+T"), self)
        self.shortcutNewTab.activated.connect(self.AddTab)

        # keep track of tabs
        self.tabCount = 0
        self.tabs = []

        # Create Addressbar
        self.Toolbar = QWidget()
        self.Toolbar.setObjectName("Toolbar")
        self.ToolbarLayout = QHBoxLayout()
        self.addressbar = AddressBar()
        self.AddTabButton = QPushButton("+")

        # Connect Addressbar + button signals
        self.addressbar.returnPressed.connect(self.BrowseTo)
        self.AddTabButton.clicked.connect(self.AddTab)

        # set toolbar buttons and signals
        self.BackButton = QPushButton("<")
        self.BackButton.clicked.connect(self.GoBack)
        self.ForwardButton = QPushButton(">")
        self.ForwardButton.clicked.connect(self.GoForward)
        self.ReloadButton = QPushButton("↻")
        self.ReloadButton.clicked.connect(self.GoReload)

        # Build toolbar
        self.Toolbar.setLayout(self.ToolbarLayout)
        self.ToolbarLayout.addWidget(self.BackButton)
        self.ToolbarLayout.addWidget(self.ForwardButton)
        self.ToolbarLayout.addWidget(self.ReloadButton)
        self.ToolbarLayout.addWidget(self.addressbar)
        self.ToolbarLayout.addWidget(self.AddTabButton)

        # set main view
        self.container = QWidget()
        self.container.layout = QStackedLayout()
        self.container.setLayout(self.container.layout)

        # construct main view
        self.layout.addWidget(self.tabbar)
        self.layout.addWidget(self.Toolbar)
        self.layout.addWidget(self.container)

        self.setLayout(self.layout)
        self.AddTab()
        self.show()

    def CloseTab(self, i):
        self.tabbar.removeTab(i)

    def AddTab(self):
        i = self.tabCount

        # set self.tabs<#> = QWidget
        self.tabs.append(QWidget())
        self.tabs[i].layout = QVBoxLayout()
        self.tabs[i].layout.setContentsMargins(0,0,0,0)

        # For tab switching
        self.tabs[i].setObjectName("tab" + str(i))

        # create the web engine view
        self.tabs[i].content = QWebEngineView()
        self.tabs[i].content.load(QUrl.fromUserInput("http://bing.com"))

        self.tabs[i].content.titleChanged.connect(lambda: self.SetTabContent(i, "title"))
        self.tabs[i].content.iconChanged.connect(lambda: self.SetTabContent(i, "icon"))
        self.tabs[i].content.urlChanged.connect(lambda: self.SetTabContent(i, "url"))


        # add widget to tabs layout
        self.tabs[i].layout.addWidget(self.tabs[i].content)

        # set top level tab from list to layout
        self.tabs[i].setLayout(self.tabs[i].layout)

        # add tab to top level stacked widget
        self.container.layout.addWidget(self.tabs[i])
        self.container.layout.setCurrentWidget(self.tabs[i])

        # create tab on tabbar, representing this tab
        # set tabData to tab<#> so it knows what self.tabs[#] it needs to control
        self.tabbar.addTab("New Tab")
        self.tabbar.setTabData(i, {"object": "tab" + str(i), "initial": i})

        self.tabbar.setCurrentIndex(i)

        self.tabCount += 1
        print(self.tabCount)

    def SwitchTab(self, i):
        if self.tabbar.tabData(i):
            tab_data = self.tabbar.tabData(i)["object"]
            print(tab_data)
            tab_content = self.findChild(QWidget, tab_data)
            self.container.layout.setCurrentWidget(tab_content)
            new_url = tab_content.content.url().toString()
            self.addressbar.setText(new_url)

    def BrowseTo(self):
        text = self.addressbar.text()
        i = self.tabbar.currentIndex()
        tab = self.tabbar.tabData(i)["object"]
        wv = self.findChild(QWidget, tab).content

        if "http" not in text:
            if "." not in text:
                url = "https://www.bing.com/search?q=" + text
            else:
                url = "http://" + text
        else:
            url = text

        wv.load(QUrl.fromUserInput(url))

    def SetTabContent(self, i, type):
        '''
            self.tabs[i].objectName = tab1
            self.tabbar.tabData(i)["object"] = tab1
        '''
        tab_name = self.tabs[i].objectName()

        count = 0
        running = True

        current_tab = self.tabbar.tabData(self.tabbar.currentIndex())["object"]
        if current_tab == tab_name and type == "url":
            new_url = self.findChild(QWidget, tab_name).content.url().toString()
            self.addressbar.setText(new_url)
            return False

        while running:
            tab_data_name = self.tabbar.tabData(count)
            if count >= 99:
                running = False
            if tab_name == tab_data_name["object"]:
                if type == "title":
                    newTitle = self.findChild(QWidget, tab_name).content.title()
                    self.tabbar.setTabText(count, newTitle)
                elif type == "icon":
                    newIcon = self.findChild(QWidget, tab_name).content.icon()
                    self.tabbar.setTabIcon(count, newIcon)
                running = False
            else:
                count += 1

    def GoBack(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.back()

    def GoForward(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.forward()

    def GoReload(self):
        activeIndex = self.tabbar.currentIndex()
        tab_name = self.tabbar.tabData(activeIndex)["object"]
        tab_content = self.findChild(QWidget, tab_name).content
        tab_content.reload()
Exemple #35
0
class ImportWindow(QDialog):
    def __init__(self, model, mainwindow, prefs):
        QDialog.__init__(self, mainwindow, Qt.Window)
        self.prefs = prefs
        self._setupUi()
        self.prefs.restoreGeometry('importWindowGeometry', self)
        self.doc = mainwindow.doc
        self.model = model
        self.swapOptionsComboBox = ComboboxModel(model=self.model.swap_type_list, view=self.swapOptionsComboBoxView)
        self.table = ImportTable(model=self.model.import_table, view=self.tableView)
        self._setupColumns() # Can only be done after the model has been connected

        self.targetAccountComboBox.addItems(self.model.target_account_names)
        for pane in self.model.panes:
            self.tabView.addTab(pane.name)

        self.tabView.tabCloseRequested.connect(self.tabCloseRequested)
        self.tabView.currentChanged.connect(self.currentTabChanged)
        self.targetAccountComboBox.currentIndexChanged.connect(self.targetAccountChanged)
        self.closeButton.clicked.connect(self.close)
        self.importButton.clicked.connect(self.importClicked)
        self.matchButton.clicked.connect(self.matchClicked)
        self.swapButton.clicked.connect(self.swapClicked)

    def _setupUi(self):
        self.setWindowTitle(tr("Import"))
        self.resize(557, 407)
        self.setModal(True)
        self.verticalLayout = QVBoxLayout(self)
        self.tabView = QTabBar(self)
        self.tabView.setMinimumHeight(20)
        self.verticalLayout.addWidget(self.tabView)
        self.targetAccountLayout = QHBoxLayout()
        self.targetAccountLabel = QLabel(tr("Target Account:"))
        self.targetAccountLayout.addWidget(self.targetAccountLabel)
        self.targetAccountComboBox = QComboBox(self)
        self.targetAccountComboBox.setMinimumWidth(150)
        self.targetAccountLayout.addWidget(self.targetAccountComboBox)
        self.targetAccountLayout.addItem(horizontalSpacer())

        self.matchBox = QGroupBox(tr("Match entries by date/amount"))
        self.matchBox.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
        matchLayout = QVBoxLayout(self.matchBox)
        self.matchThreshold = QSpinBox()
        label = QLabel(tr("maximum day(s)"))
        matchLayout.addLayout(horizontalWrap([self.matchThreshold, label]))
        self.matchButton = QPushButton(tr("Match"))
        self.matchButton.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred)
        matchLayout.addLayout(horizontalWrap([None, self.matchButton]))

        self.targetAccountLayout.addWidget(self.matchBox)
        self.swapBox = QGroupBox(tr("Are some fields wrong? Fix them!"))
        swapLayout = QVBoxLayout(self.swapBox)
        self.swapOptionsComboBoxView = QComboBox(self.swapBox)
        swapLayout.addWidget(self.swapOptionsComboBoxView)
        self.applyToAllCheckBox = QCheckBox(tr("Apply to all accounts"))
        self.swapButton = QPushButton(tr("Fix"))
        swapLayout.addLayout(horizontalWrap([self.applyToAllCheckBox, self.swapButton]))
        self.targetAccountLayout.addWidget(self.swapBox)

        self.verticalLayout.addLayout(self.targetAccountLayout)
        self.tableView = TableView(self)
        self.tableView.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.tableView.setDragEnabled(True)
        self.tableView.setDragDropMode(QAbstractItemView.InternalMove)
        self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.tableView.horizontalHeader().setHighlightSections(False)
        self.tableView.horizontalHeader().setMinimumSectionSize(18)
        self.tableView.verticalHeader().setVisible(False)
        self.tableView.verticalHeader().setDefaultSectionSize(18)
        self.verticalLayout.addWidget(self.tableView)
        self.horizontalLayout = QHBoxLayout()
        spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
        self.horizontalLayout.addItem(spacerItem1)
        self.closeButton = QPushButton(tr("Close"))
        self.horizontalLayout.addWidget(self.closeButton)
        self.importButton = QPushButton(tr("Import"))
        self.horizontalLayout.addWidget(self.importButton)
        self.verticalLayout.addLayout(self.horizontalLayout)
        self.tabView.setTabsClosable(True)
        self.tabView.setDrawBase(False)
        self.tabView.setDocumentMode(True)
        self.tabView.setUsesScrollButtons(True)

    def _setupColumns(self):
        # Can't set widget alignment in a layout in the Designer
        l = self.targetAccountLayout
        l.setAlignment(self.targetAccountLabel, Qt.AlignTop)
        l.setAlignment(self.targetAccountComboBox, Qt.AlignTop)

    # --- Event Handlers
    def close(self):
        self.prefs.saveGeometry('importWindowGeometry', self)
        super().close()

    def currentTabChanged(self, index):
        self.model.selected_pane_index = index

    def importClicked(self):
        self.model.import_selected_pane()

    def matchClicked(self):
        threshold = self.matchThreshold.value()
        self.model.match_entries_by_date_and_amount(threshold)

    def swapClicked(self):
        applyToAll = self.applyToAllCheckBox.isChecked()
        self.model.perform_swap(apply_to_all=applyToAll)

    def tabCloseRequested(self, index):
        self.model.close_pane(index)
        self.tabView.removeTab(index)

    def targetAccountChanged(self, index):
        self.model.selected_target_account_index = index
        self.table.updateColumnsVisibility()

    # --- model --> view
    def close_selected_tab(self):
        self.tabView.removeTab(self.tabView.currentIndex())

    def set_swap_button_enabled(self, enabled):
        self.swapButton.setEnabled(enabled)

    def update_selected_pane(self):
        index = self.model.selected_pane_index
        if index != self.tabView.currentIndex(): # this prevents infinite loops
            self.tabView.setCurrentIndex(index)
        self.targetAccountComboBox.setCurrentIndex(self.model.selected_target_account_index)
        self.table.updateColumnsVisibility()