コード例 #1
0
class CalculateVolumeWidget(QWidget):
 
    def __init__(self, parent):
        
        super(QWidget, self).__init__(parent)
        
        self.layout = QVBoxLayout(self)
        self.parent = parent
        
        # Array of indices of tabs with plots (for making updates when switching to them)
        self.tabsWithPlots = [0,1]
        
        # Initialize tab screen
        self.tabs = QTabWidget()
        self.tab1 = DiskMethodWidget(self)
        self.tab2 = DefiniteIntegralWidget(self)
        
        # Add tabs
        self.tabs.addTab(self.tab1,"Método de discos")
        self.tabs.addTab(self.tab2,"Integral definida")
        
        # Function whenever a new tab is clicked
        self.tabs.currentChanged.connect(self.updatePlot)
        
        # Add tabs to widget        
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)
    
    # Update plot subtab
    def updatePlot(self):
        if(self.tabs.currentIndex() in self.tabsWithPlots):
            self.tabs.currentWidget().updatePlot()
コード例 #2
0
class Window(QMainWindow):
    def __init__(self):
        super(Window, self).__init__(flags=Qt.Window)
        self.index_page = 0
        self.valid_players = player_store.players
        self.setWindowTitle("Business FUT")
        self.setWindowIcon(QIcon("img/fut_icon.ico"))
        self.tab_widgets = QTabWidget()
        self.tab_widgets.setStyleSheet(QTabWidget_stylesheet)
        self.tab_widgets.blockSignals(True)
        self.tab_widgets.currentChanged.connect(self.on_tab_changed)
        self.buy_tab = BuyTab()
        self.favorite_tab = FavoriteTab()
        self.sell_tab = SellTab()
        self.tab_widgets.addTab(self.buy_tab, "Achats")
        self.tab_widgets.addTab(self.favorite_tab, "Favoris")
        self.tab_widgets.addTab(self.sell_tab, "Ventes")
        self.setCentralWidget(self.tab_widgets)
        self.tab_widgets.blockSignals(False)

    def on_tab_changed(self):
        self.tab_widgets.currentWidget().update_table()

    def keyPressEvent(self, e):
        if type(e) == QKeyEvent and e.key() == Qt.Key_F1:
            c.ech += 1
            if c.ech > 3:
                c.ech = 1
            from model.database import Database
            db = Database()
            db.update_constant(c.ech)
            self.close()
コード例 #3
0
class QualifyingParams(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.vbox = QVBoxLayout(self)
        self.modetab = QTabWidget()
        self.vbox.addWidget(self.modetab)
        self.complaps = CompLaps()
        self.modetab.addTab(self.complaps, self.tr('Laps'))
        self.comptime = CompTime()
        self.modetab.addTab(self.comptime, self.tr('Time'))
        self.sequential = QCheckBox()
        self.sequential.setText(self.tr('Sequential'))
        self.vbox.addWidget(self.sequential)
        self.setLayout(self.vbox)

    def getCompMode(self):
        if self.modetab.currentWidget() == self.complaps:
            if self.sequential.isChecked():
                return COMP_MODE__QUALIFYING_LAPS_SEQ
            return COMP_MODE__QUALIFYING_LAPS
        if self.modetab.currentWidget() == self.comptime:
            if self.sequential.isChecked():
                return COMP_MODE__QUALIFYING_TIME_SEQ
            return COMP_MODE__QUALIFYING_TIME

    def getDuration(self):
        if self.modetab.currentWidget() == self.complaps:
            return self.complaps.duration.value()
        if self.modetab.currentWidget() == self.comptime:
            return self.comptime.duration.value()
コード例 #4
0
class ViewSourceDialogTabber(QMainWindow):
    def __init__(self, parent=None, title="Source"):
        super(ViewSourceDialogTabber, self).__init__(parent)
        self.setWindowTitle(title)
        self.tabs = QTabWidget(self)
        self.tabs.setElideMode(Qt.ElideRight)
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.removeTab)
        self.setCentralWidget(self.tabs)
        self.tabs.currentChanged.connect(self.updateWindowTitle)
    def sizeHint(self):
        return QSize(640, 480)
    def removeTab(self):
        self.tabs.removeTab(self.tabs.currentIndex())
    def addTab(self, title="New Tab", data=""):
        vsd = ViewSourceDialog(self, str(title))
        vsd.setPlainText(data)
        self.tabs.addTab(vsd, tr("Source of %s") % (title,))
        self.tabs.setCurrentIndex(self.tabs.count()-1)
        self.raise_()
        self.activateWindow()
    def updateWindowTitle(self):
        try: self.setWindowTitle(tr("Source of %s") % (self.tabs.currentWidget().windowTitle(),))
        except: pass
        if self.tabs.count() == 0:
            self.hide()
コード例 #5
0
class ViewSourceDialogTabber(QMainWindow):
    def __init__(self, parent=None, title="Source"):
        super(ViewSourceDialogTabber, self).__init__(parent)
        self.setWindowTitle(title)
        self.tabs = QTabWidget(self)
        self.tabs.setElideMode(Qt.ElideRight)
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.removeTab)
        self.setCentralWidget(self.tabs)
        self.tabs.currentChanged.connect(self.updateWindowTitle)

    def sizeHint(self):
        return QSize(640, 480)

    def removeTab(self):
        self.tabs.removeTab(self.tabs.currentIndex())

    def addTab(self, title="New Tab", data=""):
        vsd = ViewSourceDialog(self, str(title))
        vsd.setPlainText(data)
        self.tabs.addTab(vsd, tr("Source of %s") % (title, ))
        self.tabs.setCurrentIndex(self.tabs.count() - 1)
        self.raise_()
        self.activateWindow()

    def updateWindowTitle(self):
        try:
            self.setWindowTitle(
                tr("Source of %s") %
                (self.tabs.currentWidget().windowTitle(), ))
        except:
            pass
        if self.tabs.count() == 0:
            self.hide()
コード例 #6
0
def main():
    app = QApplication(sys.argv)
    QApplication.setStyle(QStyleFactory.create('Fusion'))

    technics_tab = technics.Widget()
    departments_tab = departments.Widget()
    rooms_tab = rooms.Widget()
    employees_tab = employees.Widget()
    transfers_tab = transfers.Widget()
    technicsView_tab = technicsView.Widget()
    roomsView_tab = roomsView.Widget()
    responsibleView_tab = responsibleView.Widget()
    
    tabs = QTabWidget()
    tabs.addTab(technics_tab, 'Technics')
    tabs.addTab(departments_tab, 'Departments')
    tabs.addTab(rooms_tab, 'Rooms')
    tabs.addTab(employees_tab, 'Employees')
    tabs.addTab(transfers_tab, 'Transers')
    tabs.addTab(technicsView_tab, 'Technics View')
    tabs.addTab(roomsView_tab, 'Rooms View')
    tabs.addTab(responsibleView_tab, 'Responsible View')

    tabs.setFixedWidth(750)
    tabs.setFixedHeight(600)
    tabs.setWindowTitle('Office Equipment')
    tabs.show()
    tabs.currentChanged.connect(lambda x: tabs.currentWidget().refresh())

    sys.exit(app.exec_())
コード例 #7
0
class Window(QMainWindow):
    def __init__(self, dataManager, parent=None):
        super(Window, self).__init__(parent)
        self.setWindowTitle("python-aptly GUI")

        main_widget = QWidget(self)
        layout = QGridLayout()
        self.tabs = QTabWidget()
        self.tabs.addTab(SnapshotTab(dataManager), "Snapshot management")
        self.tabs.addTab(RepositoryTab(dataManager), "Repository management")
        self.tabs.addTab(PackagePromotion(dataManager), "Package Promotion")
        self.tabs.addTab(ComponentPromotion(dataManager),
                         "Component Promotion")

        main_widget.setLayout(layout)
        layout.addWidget(self.tabs)
        self.tabs.currentChanged.connect(self.foo)
        self.setCentralWidget(main_widget)

        menubar = QMenuBar()
        menubar.addMenu('shit')
        menubar.addMenu('shit2')

    def foo(self, item):
        t = self.tabs.currentWidget()
        t.reload_component()
コード例 #8
0
class MainWidget(QWidget):
    def __init__(
        self,
        parent,
    ):
        super(QWidget, self).__init__(parent)
        self.layout = QVBoxLayout(self)

        self.ini = QSettings(SETTINGS_PATH, QSettings.IniFormat)
        self.ini.setIniCodec("utf-8")
        # tabs for application
        self.tabs = QTabWidget()
        self.mainTab = ConnectionPanel(settings=SETTINGS_PATH)
        self.serversTab = ServersTable(settings=SETTINGS_PATH)
        self.tabs.resize(300, 200)
        # Add tabs
        self.tabs.addTab(self.mainTab, "Main")
        self.tabs.addTab(self.serversTab, "Servers")
        self.tabs.currentChanged.connect(self.tab_changed)

        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)

    def tab_changed(self):
        if self.tabs.currentWidget() == self.mainTab:
            if self.serversTab.save_settings_change_tab() == "Value Error":
                self.tabs.setCurrentIndex(2)
            self.mainTab.reload_servers()
コード例 #9
0
class SearchMusic(ScrollArea):
    def __init__(self, parent=None):
        super().__init__(self)
        self.parent = parent
        self.setObjectName("SearchMusic")
        self.searchText = ""

        self.frame.setContentsMargins(0, 0, 0, 0)

        self.tabWidget = QTabWidget()
        self.tabWidget.setObjectName("tabWidget")

        self.mainLayout = QVBoxLayout()
        # self.mainLayout.setSpacing(0)
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.titleLabel = QLabel()
        self.mainLayout.addWidget(self.titleLabel)
        self.mainLayout.addWidget(self.tabWidget)

        self.frame.setLayout(self.mainLayout)

        self.addSearchMusicTabs()

        self.tabWidget.currentChanged.connect(self.tabChanged)

    def addSearchMusicTabs(self):
        tab = SearchMusicNetEase(self.parent)
        self.addTab(tab, "网易云")
        tab = SearchMusicQQ(self.parent)
        self.addTab(tab, "QQ")

    def addTab(self, widget, name=''):
        self.tabWidget.addTab(widget, name)

    def search(self, text):
        self.searchText = text
        self.titleLabel.setText(
            "搜索<font color='#23518F'>“{0}”</font><br>".format(self.searchText))
        tab = self.tabWidget.currentWidget()
        tab.search(self.searchText)

    def tabChanged(self, index):
        if self.searchText:
            tab = self.tabWidget.currentWidget()
            if self.searchText != tab.searchText:
                tab.search(self.searchText)
コード例 #10
0
class PreferencesDialog(QDialog):
    """
    This dialog adjusts preferences
    """
    def __init__(self, *args, **kwargs):
        super(PreferencesDialog, self).__init__(*args, **kwargs)
        self.appctx = self.parent().appctx
        # Setup UI
        self.setup_ui()

    def setup_ui(self):
        # TODO: Add preferences settings
        self.setWindowTitle(f"CLARITE Preferences")
        self.setMinimumWidth(500)
        self.setModal(True)

        layout = QVBoxLayout()

        # Tabs
        self.tabs = QTabWidget(self)
        self.tabs.setTabPosition(QTabWidget.North)
        self.tab_display = DisplayTab(self)
        self.tabs.addTab(self.tab_display, "Display")
        layout.addWidget(self.tabs)

        # Bottom row of buttons
        bottom_layout = QHBoxLayout()
        layout.addLayout(bottom_layout)
        # Reset
        self.default_btn = QPushButton("Default")
        self.default_btn.clicked.connect(self.use_default_settings)
        bottom_layout.addWidget(self.default_btn)
        # Spacer
        bottom_layout.addStretch()
        # Ok/Cancel
        QBtn = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
        self.buttonBox = QDialogButtonBox(QBtn)
        bottom_layout.addWidget(self.buttonBox)
        self.buttonBox.accepted.connect(self.submit)
        self.buttonBox.rejected.connect(self.reject)

        # Set Layout
        self.setLayout(layout)

    def submit(self):
        # Write settings from each tab
        self.tab_display.write_settings()
        # Refresh the display
        self.appctx.data_model.refresh()
        # Close the dialog
        self.accept()

    def use_default_settings(self):
        # Reset the current tab to default settings
        w = self.tabs.currentWidget()
        w.load_default_settings()
        w.refresh_ui()
コード例 #11
0
ファイル: danaquery.py プロジェクト: wllacer/dana-cube
class SesionTab(QWidget):
    def __init__(self, conn, confName, holder=None, parent=None):
        super(SesionTab, self).__init__(parent)
        self.conn = conn
        self.confName = confName
        self.holder = holder
        self.tabQueries = QTabWidget()
        self.tabQueries.setTabShape(QTabWidget.Triangular)
        meatLayout = QVBoxLayout()
        meatLayout.addWidget(self.tabQueries)
        self.setLayout(meatLayout)

        self.addQuery()

    def addQuery(self):
        #self.tabQueries.addTab(QueryTab(self.conn,self.confName,holder=self.holder),"{}:{}".format(self.confName, self.tabQueries.count() +1))
        self.tabQueries.addTab(
            myQueryTab(self.conn, holder=self.holder),
            "{}:{}".format(self.confName,
                           self.tabQueries.count() + 1))
        self.tabQueries.setCurrentIndex(self.tabQueries.count() - 1)

    def openQuery(self):
        #self.tabQueries.addTab(QueryTab(self.conn,self.confName,holder=self.holder),"{}:{}".format(self.confName, #self.tabQueries.count() +1))
        #self.tabQueries.setCurrentIndex(self.tabQueries.count() -1)
        self.tabQueries.currentWidget().readQuery()

    def saveQuery(self):
        self.tabQueries.currentWidget().writeQuery()

    def saveAsQuery(self):
        self.tabQueries.currentWidget().writeQuery(True)

    def closeQuery(self):
        tabId = self.tabQueries.currentIndex()
        self.tabQueries.removeTab(tabId)

    def execute(self):
        self.tabQueries.currentWidget().execute()

    def reformat(self):
        self.tabQueries.currentWidget().reformat()
コード例 #12
0
class solar_spectrum_gen_window(QWidget):

	update = pyqtSignal()

	def __init__(self):
		self.export_file_name="data.dat"#os.path.join(self.path,"spectra.inp")
		super().__init__()
		self.resize(1200,600)
		self.setWindowIcon(icon_get("weather-few-clouds"))

		self.vbox=QVBoxLayout()

		self.ribbon = ribbon_solar()
		self.vbox.addWidget(self.ribbon)
		
		self.ribbon.run.clicked.connect(self.callback_run)

		#self.ribbon.export.triggered.connect(self.callback_export)
		
		self.setWindowTitle(_("Solar Spectrum Generator")+" (https://www.gpvdm.com)")


		self.notebook = QTabWidget()

		self.vbox.addWidget(self.notebook)
		self.spectral2_gui=spectral2_gui()
		self.notebook.addTab(self.spectral2_gui,"SPECTRAL2")
		self.setLayout(self.vbox)


	def callback_run(self):
		tab = self.notebook.currentWidget()
		tab.calculate()


	def save(self):
		self.notebook.currentWidget().save()

	def copy(self):
		self.notebook.currentWidget().copy2clip()
コード例 #13
0
class TabTable(QWidget):
    """
    This is the base widget for tab table
    """
    def __init__(self, parent=None, **kwargs):
        super(TabTable, self).__init__(parent)
        self.layout = QVBoxLayout(self)

        # Initialize tab screen
        self.tabs = QTabWidget()
        self.tabs.resize(300, 200)

        # Add tabs
        for i in kwargs:
            self.tabs.addTab(kwargs[i], i)

        # Add tabs to widget
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)

    def New(self):
        self.tabs.currentWidget().New()
コード例 #14
0
class SessionDetails(QWidget):
    def __init__(self, parent=None):
        super(SessionDetails, self).__init__(parent)
        self.tabs = QTabWidget(self)
        layout = QVBoxLayout(self)
        layout.addWidget(self.tabs)
        self.setMinimumSize(600, 600)
        self.tabs.currentChanged.connect(self.selectInterval)
        self.session = None

    def setSession(self, session):
        self.session = session
        self.tabs.clear()
        self.tabs.addTab(IntervalPage(session, self), str(session.start_time))
        self.selectInterval(0)
        if not session.waypoints():
            self.parent().map_holder.hide_map()
        else:
            self.parent().map_holder.show_map()

    def setTab(self, tab):
        t = self.tabs.currentWidget()
        t.setTab(tab)

    def addInterval(self, interval):
        self.tabs.addTab(IntervalPage(interval, self), str(interval.timestamp))
        if interval.waypoints():
            self.parent().map.draw_segment(interval.timestamp,
                                           interval.duration)

    def selectInterval(self, ix):
        if self.session.waypoints():
            if ix == 0:
                self.parent().map.draw_map(self.session)
                # pass
            elif ix > 0:
                page = self.tabs.currentWidget()
                self.parent().map.draw_segment(page.interval.timestamp,
                                               page.interval.duration)
コード例 #15
0
class RaceParams(QWidget):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.vbox = QVBoxLayout(self)
        self.modetab = QTabWidget()
        self.vbox.addWidget(self.modetab)
        self.complaps = CompLaps()
        self.modetab.addTab(self.complaps, self.tr('Laps'))
        self.comptime = CompTime()
        self.modetab.addTab(self.comptime, self.tr('Time'))
        self.setLayout(self.vbox)

    def getCompMode(self):
        if self.modetab.currentWidget() == self.complaps:
            return COMP_MODE__RACE_LAPS
        if self.modetab.currentWidget() == self.comptime:
            return COMP_MODE__RACE_TIME

    def getDuration(self):
        if self.modetab.currentWidget() == self.complaps:
            return self.complaps.duration.value()
        if self.modetab.currentWidget() == self.comptime:
            return self.comptime.duration.value()
コード例 #16
0
ファイル: __init__.py プロジェクト: nanthony21/pwspy_gui
class AnalysisSettingsDock(AnalysisSettingsCreator, QDockWidget):
    def __init__(self, parent: QWidget, cellSelector: CellSelector, erManager):
        super().__init__("Settings", parent=parent)
        self._erManager = erManager
        self.setStyleSheet(
            "QDockWidget > QWidget { border: 1px solid lightgray; }")
        self._selector = cellSelector
        self.setObjectName(
            'AnalysisSettingsDock')  # needed for restore state to work
        widg = QWidget()
        widg.setLayout(QVBoxLayout())
        self._settingsTabWidget = QTabWidget(self)
        self._PWSSettingsFrame = PWSSettingsFrame(self._erManager,
                                                  cellSelector)
        self._settingsTabWidget.addTab(self._PWSSettingsFrame, "PWS")
        self._DynSettingsFrame = DynamicsSettingsFrame(self._erManager,
                                                       cellSelector)
        self._settingsTabWidget.addTab(self._DynSettingsFrame, "Dynamics")
        widg.layout().addWidget(self._settingsTabWidget)
        self.addAnalysisButton = QPushButton("Add Analysis")
        widg.layout().addWidget(self.addAnalysisButton)

        self._analysesQueue = QueuedAnalysesFrame(self)

        widg.layout().addWidget(self._analysesQueue)
        self._analysesQueue.setFixedHeight(50)
        widg.setMinimumHeight(200)
        widg.setMinimumWidth(self._PWSSettingsFrame.minimumWidth() + 10)

        self.addAnalysisButton.released.connect(self._addAnalysis)
        self.setWidget(widg)

    def _addAnalysis(self):
        settingsWidget: AbstractSettingsFrame = self._settingsTabWidget.currentWidget(
        )
        try:
            settings = settingsWidget.getSettings()
        except Exception as e:
            QMessageBox.information(self, 'Hold on', str(e))
            return
        self._analysesQueue.addAnalysis(settings)

    def getListedAnalyses(
            self) -> typing.List[AbstractRuntimeAnalysisSettings]:
        return self._analysesQueue.analyses
コード例 #17
0
class EvalWindow(QMainWindow):
    def __init__(self):
        super(EvalWindow, self).__init__()
        self.tab_widget = QTabWidget()
        self.tab_widget.setTabsClosable(True)
        self.tab_widget.setTabShape(1)
        self.tab_widget.tabCloseRequested.connect(self.on_close_tab)

        self.tab_widget.currentChanged.connect(self.tab_changed)
        self.setCentralWidget(self.tab_widget)

        self.data_editor_dock = QDockWidget("Data Inspection", self)
        self.data_editor_dock.setAllowedAreas(Qt.LeftDockWidgetArea
                                              | Qt.RightDockWidgetArea
                                              | Qt.BottomDockWidgetArea)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.data_editor_dock)

        self.data_editor = DataEditor()
        self.data_editor_dock.setWidget(self.data_editor)

        self.navigation_dock = QDockWidget("Navigation Stack", self)

        self.navigation_dock.setAllowedAreas(Qt.LeftDockWidgetArea
                                             | Qt.RightDockWidgetArea
                                             | Qt.BottomDockWidgetArea)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.navigation_dock)
        self.last_tab_widget = None

        self.resize(1000, 700)

    def add_eval(self, gui_eval):
        self.show()
        self.activateWindow()

        self.tab_widget.addTab(gui_eval, gui_eval.view.scene.workflow.name)

    def tab_changed(self, index):
        curr_widget = self.tab_widget.currentWidget()
        curr_widget.view.scene.on_selection_changed()
        self.navigation_dock.setWidget(curr_widget.navigation)
        self.last_tab_widget = curr_widget

    def on_close_tab(self, index):
        self.tab_widget.removeTab(index)
コード例 #18
0
class AutoPickerSettingDialog(QDialog):

    applySignal = QtCore.pyqtSignal(object)

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

        

        self.tabWidget = QTabWidget()
        self.tabWidget.addTab(StaLtaTab(self), "STA/LTA")
        #tabWidget.addTab(ArAicTab(), "AR-AIC")

        defaultButton = QPushButton(' Restore Defaults ')
        spacer1 = QSpacerItem(20,20, QSizePolicy.Minimum)
        applyButton = QPushButton('Apply')
       
        buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)

        buttonBox.accepted.connect(self.accept)
        buttonBox.rejected.connect(self.reject)
        applyButton.clicked.connect(self.onApplyClicked)



        hbl = QHBoxLayout()
        hbl.addWidget(defaultButton)
        hbl.addItem(spacer1)
        hbl.addWidget(applyButton)
        hbl.addWidget(buttonBox)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.tabWidget)
        mainLayout.addLayout(hbl)
        self.setLayout(mainLayout)

        self.setWindowTitle("AutoPicker Settings")

    def onApplyClicked(self):

        configDict = self.tabWidget.currentWidget().getConfig()        

        self.applySignal.emit(configDict)
コード例 #19
0
ファイル: telemetry.py プロジェクト: wangyeee/MiniGCS
class ConnectionEditWindow(QWidget):

    MAVLinkConnectedSignal = pyqtSignal(object)
    cancelConnectionSignal = pyqtSignal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.tabs = QTabWidget(self)
        self._createTabs()
        l = QVBoxLayout()
        l.setContentsMargins(0, 0, 0, 0)
        l.addWidget(self.tabs)
        l.addWidget(self.__createActionButtons())
        self.setLayout(l)

    def _createTabs(self):
        self.serialConnTab = SerialConnectionEditTab(parent=self)
        self.logReplayTab = LogFileReplayEditTab(self)
        self.tabs.addTab(self.serialConnTab, 'Serial Link')
        self.tabs.addTab(self.logReplayTab, 'Log File Replay')

    def __createActionButtons(self):
        l = QHBoxLayout()
        l.setContentsMargins(5, 0, 5, 5)
        self.connectButton = QPushButton('Connect')
        self.closeButton = QPushButton('Close')
        self.connectButton.clicked.connect(self._doConnect)
        self.closeButton.clicked.connect(self.close)
        l.addWidget(self.connectButton)
        l.addWidget(self.closeButton)
        self.actionButtonWidget = QWidget()
        self.actionButtonWidget.setLayout(l)
        return self.actionButtonWidget

    def closeEvent(self, event):
        self.cancelConnectionSignal.emit()
        super().closeEvent(event)

    def _doConnect(self):
        currTab = self.tabs.currentWidget()
        if hasattr(currTab, 'doConnect'):
            if currTab.doConnect():
                self.close()
コード例 #20
0
ファイル: pyqt_classes.py プロジェクト: th-truong/tj-chess
class chessTabs(QWidget):
    def __init__(self, parent, chess_db, engines):
        super(QWidget, self).__init__(parent)

        self.tabs = QTabWidget()
        viewer_tab = ViewerTab(self, chess_db)
        player_tab = PlayerTab(self, engines)

        self.tabs.addTab(viewer_tab, "Viewer")
        self.tabs.addTab(player_tab, "Player")

        layout = QGridLayout(self)
        layout.addWidget(self.tabs)
        self.setLayout(layout)

    def wheelEvent(self, event: QWheelEvent):
        tab = self.tabs.currentWidget()
        if event.angleDelta().y() > 0:
            tab.fwd_btn_click()
        elif event.angleDelta().y() < 0:
            tab.back_btn_click()
コード例 #21
0
class MainWindow(QMainWindow):

    connect_to_yadisk_signal = pyqtSignal()
    get_yadisk_listdir = pyqtSignal(str)
    get_local_listdir = pyqtSignal(str)
    get_bublic_listdir = pyqtSignal(str)

    move_file_signal = pyqtSignal(str, str)
    download_from_auth_yadisk = pyqtSignal(str, str, dict)
    download_from_bublic_yadisk = pyqtSignal(str, str, dict)
    upload_to_auth_yadisk = pyqtSignal(str, str, dict)

    open_link_signal = pyqtSignal()

    local_browse_clicked = pyqtSignal(KeyType, SecurityAlgorithm)
    yadisk_browse_clicked = pyqtSignal(KeyType, SecurityAlgorithm)

    local_algorithm_changed = pyqtSignal(SecurityAlgorithm, KeyType)
    yadisk_algorithm_changed = pyqtSignal(SecurityAlgorithm, KeyType)

    set_media_folder = pyqtSignal(str)

    def __init__(self):
        super(MainWindow, self).__init__()
        uic.loadUi("forms/mainwindow.ui", self)
        self.local_files = QTabWidget()  #FileSystem()
        self.add_local_file_system()

        self.yadisk_files = QTabWidget()

        self.h_layout.layout().addWidget(self.local_files)
        self.h_layout.layout().addWidget(self.yadisk_files)

        self.connect_to_actions()
        self.show_status("Not connected")
        self.local_files.show()

        self.icon = QIcon(":/img/images/icon.png")
        self.setWindowIcon(self.icon)

    def connect_to_actions(self):
        self.connect_to_yadisk_action.triggered.connect(self.connect_to_yadisk)
        self.open_link_action.triggered.connect(self.open_link)
        self.yadisk_files.currentChanged.connect(self.yadisk_tab_changed)

    def get_local_system(self):
        return self.local_files.currentWidget()

    def get_yadisk(self):
        return self.yadisk_files.currentWidget()

    def add_local_file_system(self):
        file_system = FileSystem(magic_const.LOCAL_FILE_SYSTEM_LABELS, "local")

        file_system.double_clicked.connect(self.get_local_listdir)
        file_system.move_clicked.connect(self.move_file_from_local)
        file_system.browse_clicked.connect(self.local_browse_clicked)
        file_system.algorithm_changed.connect(self.local_algorithm_changed)

        self.local_files.addTab(file_system, "Local file system")
        file_system.set_load_button_enable(False)

    def add_authorized_yadisk_tab(self):
        file_system = FileSystem(magic_const.YADISK_FILE_SYSTEM_LABELS,
                                 "yadisk_auth")
        file_system.double_clicked.connect(self.get_yadisk_listdir)
        file_system.move_clicked.connect(self.move_file_from_yadisk)
        file_system.browse_clicked.connect(self.yadisk_browse_clicked)
        file_system.algorithm_changed.connect(self.yadisk_algorithm_changed)
        file_system.set_media_folder.connect(self.set_media_folder)

        self.yadisk_files.addTab(file_system, "YaDisk")
        self.yadisk_files.setCurrentWidget(file_system)

    def add_bublic_yadisk_tab(self, name="name"):
        file_system = BublicFileSystem(magic_const.YADISK_FILE_SYSTEM_LABELS,
                                       "bublic")
        file_system.double_clicked.connect(self.get_bublic_listdir)
        file_system.move_clicked.connect(self.move_file_from_bublic_yadisk)
        file_system.algorithm_changed.connect(self.yadisk_algorithm_changed)
        self.yadisk_files.addTab(file_system, name)
        self.yadisk_files.setCurrentWidget(file_system)

    def connect_to_yadisk(self):
        self.connect_to_yadisk_signal.emit()
        #self.yadisk_files.addTab(FileSystem(), "name")
        #self.connect_to_yadisk_signal.emit()

    def open_link(self):
        #self.add_yadisk_tab()
        self.open_link_signal.emit()

    def show_status(self, message):
        self.statusBar().showMessage(message)

    def show_local_listdir(self, listdir, path):
        #print("show local listdir", path)
        self.get_local_system().show_listdir(listdir, path)

    def show_yadisk_listdir(self, listdir, path):
        self.get_yadisk().show_listdir(listdir, path)

    def get_crypto_data(self, file_system):
        result = {
            "algorithm": file_system.get_algorithm(),
            "key_type": file_system.get_key_type(),
            "key": file_system.get_key().encode("utf-8"),
            "media_path": file_system.get_file_path(),
            "take_file_from_yadisk": file_system.take_file_from_yadisk(),
            "media_type": file_system.get_media_type()
        }

        return result

    def move_file_from_yadisk(self):
        local_system = self.get_local_system()
        yadisk_files = self.get_yadisk()
        from_folder = Path(yadisk_files.get_folder_path())
        to_folder = Path(local_system.get_folder_path())

        file_name = yadisk_files.get_file_name()
        from_path = from_folder / file_name
        to_path = to_folder / file_name

        encryption_data = self.get_crypto_data(yadisk_files)
        self.download_from_auth_yadisk.emit(from_path.as_posix(),
                                            to_path.as_posix(),
                                            encryption_data)
        #self.move_file_signal.emit(from_path.as_posix(), to_path.as_posix())

    def move_file_from_local(self):
        # TODO : add algorithm and key type

        local_system = self.get_local_system()
        yadisk_files = self.get_yadisk()

        from_folder = Path(local_system.get_folder_path())
        to_folder = Path(yadisk_files.get_folder_path())

        file_name = local_system.get_file_name()
        from_path = from_folder / file_name
        to_path = to_folder / file_name

        encryption_data = self.get_crypto_data(local_system)
        self.upload_to_auth_yadisk.emit(from_path.as_posix(),
                                        to_path.as_posix(), encryption_data)

    def move_file_from_bublic_yadisk(self):
        local_system = self.get_local_system()
        yadisk_files = self.get_yadisk()

        from_url = yadisk_files.get_folder_path()

        to_folder = Path(local_system.get_folder_path())
        file_name = yadisk_files.get_file_name()

        to_path = to_folder / file_name

        encryption_data = self.get_crypto_data(yadisk_files)
        self.download_from_bublic_yadisk.emit(from_url, to_path.as_posix(),
                                              encryption_data)

    def get_yadisk_folder_name(self):
        return self.yadisk_files.currentWidget().get_folder_path()

    def get_local_folder_name(self):
        return self.local_files.currentWidget().get_folder_path()

    def browse(self, filesystem, result):
        #filesystem.put_key("")
        filesystem.put_file_path("")

        if result["action"] == "get_save_filename":
            path = QFileDialog.getSaveFileName(self, "Create file", "new",
                                               result["limits"])
            filesystem.put_file_path(path[0])

        elif result["action"] == "get_open_filename":
            path = QFileDialog.getOpenFileName(self, "Open file", "",
                                               result["limits"])
            filesystem.put_file_path(path[0])
        else:
            pass

    def local_browse(self, result):
        filesystem = self.get_local_system()
        self.browse(filesystem, result)

    def yadisk_browse(self, result):
        filesystem = self.get_yadisk()
        self.browse(filesystem, result)

    def put_local_key(self, key):
        filesystem = self.get_local_system()
        filesystem.put_key(key)

    def put_yadisk_key(self, key):
        filesystem = self.get_yadisk()
        filesystem.put_key(key)

    def yadisk_tab_changed(self):
        yadisk_filesystem = self.yadisk_files.currentWidget()
        local_filesystem = self.local_files.currentWidget()
        if yadisk_filesystem.system_type == "yadisk_auth":
            local_filesystem.set_load_button_enable(True)
        elif yadisk_filesystem.system_type == "bublic":
            local_filesystem.set_load_button_enable(False)
        else:
            logger.error("In yadisk tab wrong system type")

    def show_progress_dialog(self, message, value=0, minmax=None):

        if minmax == None:
            minmax = (0, 0)
        self.progress = QProgressDialog(self)
        self.progress.setWindowTitle("Please, wait")
        self.progress.setLabelText(message)
        self.progress.setRange(*minmax)
        self.progress.setValue(value)
        self.progress.setCancelButton(None)
        self.progress.show()

        logger.info("Progress bar is opened")

    def close_progress_dialog(self):
        self.progress.close()
        logger.info("Progress bar is closed")
コード例 #22
0
class MainWindow(QMainWindow):
    def __init__(self, filename):
        super().__init__()

        self.setGeometry(20, 20, 1324, 1068)
        self.setWindowTitle('qt-Notepad')
        self.setStyleSheet('font-size: 14pt; font-family: Courier;')

        self.show()
        self.init_ui()
        centralWidget = QWidget()
        self.tabs = QTabWidget(centralWidget)
        self.setCentralWidget(self.tabs)
        self.tabs.setTabsClosable(True)
        self.tabs.setMovable(True)
        self.tabs.tabCloseRequested.connect(self.closeTab)
        if filename:
            f = open(filename, 'r')
            filedata = f.read()
            f.close()
            newfile = QTextEdit()
            newfile.setText(filedata)
            i = self.tabs.addTab(newfile, filename)
            self.tabs.setCurrentIndex(i)
        else:
            self.open_file()

    def init_ui(self):

        new_action = QAction('New File', self)
        new_action.setShortcut('Ctrl+N')
        new_action.setStatusTip('Create new file')
        new_action.triggered.connect(self.new_file)

        open_action = QAction('Open...', self)
        open_action.setShortcut('Ctrl+O')
        open_action.setStatusTip('Open a file')
        open_action.triggered.connect(self.open_file)

        save_action = QAction('Save File', self)
        save_action.setShortcut('Ctrl+S')
        save_action.setStatusTip('Save current file')
        save_action.triggered.connect(self.save_file)

        new_save_action = QAction('Save File As...', self)
        new_save_action.setShortcut('Shift+Ctrl+S')
        new_save_action.setStatusTip('Save current file')
        new_save_action.triggered.connect(self.save_file_as)

        close_action = QAction('Close File', self)
        close_action.setShortcut('Ctrl+W')
        close_action.setStatusTip('Close file and exit tab')
        close_action.triggered.connect(self.close_file)

        exit_action = QAction('Exit qt-Notepad', self)
        exit_action.setShortcut('Ctrl+Q')
        exit_action.setStatusTip('Close Notepad')
        exit_action.triggered.connect(self.close)

        undo_action = QAction('Undo', self)
        undo_action.setShortcut('Ctrl+Z')

        copy_action = QAction('Copy', self)
        copy_action.setShortcut('Ctrl+C')

        cut_action = QAction('Cut', self)
        cut_action.setShortcut('Ctrl+X')

        paste_action = QAction('Paste', self)
        paste_action.setShortcut('Ctrl+V')

        minimize_action = QAction('Minimize', self)
        minimize_action.setShortcut('Ctrl+M')

        view_action = QAction('Show', self)
        view_action.setShortcut('Ctrl+/')

        menubar = self.menuBar()
        file_menu = menubar.addMenu('&File')
        edit_menu = menubar.addMenu('&Edit')
        view_menu = menubar.addMenu('&View')
        window_menu = menubar.addMenu('&Window')

        file_menu.addAction(new_action)
        file_menu.addAction(open_action)
        file_menu.addAction(save_action)
        file_menu.addAction(new_save_action)
        file_menu.addAction(close_action)
        file_menu.addAction(exit_action)

        edit_menu.addAction(undo_action)
        edit_menu.addAction(copy_action)
        edit_menu.addAction(cut_action)
        edit_menu.addAction(paste_action)

        view_menu.addAction(view_action)

        window_menu.addAction(minimize_action)

    def closeTab(self, currentIndex):
        currentQWidget = self.tabs.currentWidget()
        currentQWidget.deleteLater()
        self.tabs.removeTab(currentIndex)

    def new_file(self):
        newfile = QTextEdit()
        i = self.tabs.addTab(newfile, 'New Document')
        self.tabs.setCurrentIndex(i)

    def save_file(self):
        editor = self.tabs.currentWidget()
        filename = self.tabs.tabText(self.tabs.currentIndex())
        if filename != 'New Document':
            f = open(filename, 'w')
            filedata = editor.toPlainText()
            f.write(filedata)
            f.close()
        else:
            self.save_file_as()

    def save_file_as(self):
        filename = QFileDialog.getSaveFileName(self, 'Save File',
                                               os.getenv('HOME'))[0]
        print(filename)
        if filename != ('', ''):
            f = open(filename, 'w')
            filedata = self.text.toPlainText()
            f.write(filedata)
            f.close()

    def open_file(self):
        filename = QFileDialog.getOpenFileName(self, 'Open File',
                                               os.getenv('HOME'))[0]
        f = open(filename, 'r')
        filedata = f.read()
        f.close()
        newfile = QTextEdit()
        newfile.setText(filedata)
        i = self.tabs.addTab(newfile, filename)
        self.tabs.setCurrentIndex(i)

    def close_file(self):
        self.save_file()
        currentIndex = self.tabs.currentIndex()
        self.tabs.removeTab(currentIndex)
コード例 #23
0
ファイル: pulppy.py プロジェクト: bruino/pulppy
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        fileMenu = QMenu("&File", self)
        newAction = fileMenu.addAction("&New...")
        newAction.setShortcut("Ctrl+N")
        self.printAction = fileMenu.addAction("&Print...", self.printFile)
        self.printAction.setShortcut("Ctrl+P")
        self.printAction.setEnabled(False)
        quitAction = fileMenu.addAction("&Exit")
        quitAction.setShortcut("Ctrl+Q")

        helpMenu = QMenu("&Help", self)
        aboutAction = helpMenu.addAction("&About")

        self.menuBar().addMenu(fileMenu)
        self.menuBar().addMenu(helpMenu)

        self.solvers = QTabWidget()
        self.solvers.setTabsClosable(True)
        self.solvers.tabCloseRequested.connect(self.closeTab)

        newAction.triggered.connect(self.openDialog)
        quitAction.triggered.connect(self.close)
        aboutAction.triggered.connect(self.openAbout)

        self.setCentralWidget(self.solvers)
        self.setWindowTitle("Pulppy Software")
    
    def printFile(self):
        editor = self.solvers.currentWidget()
        
        if type(editor) == QTextEdit:
            printer = QPrinter()
            dialog = QPrintDialog(printer, self)
            dialog.setWindowTitle("Print Document")
            if dialog.exec_() != QDialog.Accepted:
                return
            editor.print_(printer)
        else:
            answer = QMessageBox.warning(self, "Not Print Image",
                "Dont print graph.",
                QMessageBox.Ok)
        
    def closeTab (self, currentIndex):
        currentQWidget = self.solvers.widget(currentIndex)
        currentQWidget.deleteLater()
        self.solvers.removeTab(currentIndex)

    def openDialog(self):
        inputProblemDialog = InputProblem(self)
        if inputProblemDialog.exec_() == QDialog.Accepted:
            inputTable = InputTableModel(inputProblemDialog.title
            , inputProblemDialog.numVar, inputProblemDialog.numCons
            , inputProblemDialog.typeVar, inputProblemDialog.objCrit, self)
            if inputTable.exec_() == QDialog.Accepted:
                self.createTabSolver(inputTable.problem)
                if inputTable.numVariables == 2:
                    self.createTabGraph(inputTable.canvas)
                    
    def createTabGraph(self, canvas):
        self.main_widget = QWidget(self)
        vbox = QVBoxLayout(self.main_widget)
        vbox.addWidget(canvas.mpl_toolbar)
        vbox.addWidget(canvas)
        
        tabIndex = self.solvers.addTab(self.main_widget, "Graph - "+canvas.title)
        self.solvers.setCurrentIndex(tabIndex)

    def createTabSolver(self, problem):
        editor = QTextEdit()
        tabIndex = self.solvers.addTab(editor, problem.name)
        self.solvers.setCurrentIndex(tabIndex)

        cursor = editor.textCursor()
        cursor.movePosition(QTextCursor.Start)
        topFrame = cursor.currentFrame()
        topFrameFormat = topFrame.frameFormat()
        topFrameFormat.setPadding(16)
        topFrame.setFrameFormat(topFrameFormat)

        textFormat = QTextCharFormat()
        boldFormat = QTextCharFormat()
        boldFormat.setFontWeight(QFont.Bold)

        referenceFrameFormat = QTextFrameFormat()
        referenceFrameFormat.setBorder(1)
        referenceFrameFormat.setPadding(8)
        referenceFrameFormat.setPosition(QTextFrameFormat.FloatLeft)
        referenceFrameFormat.setWidth(QTextLength(QTextLength.PercentageLength, 100))
        cursor.insertFrame(referenceFrameFormat)

        cursor.insertText("Title Problem: ", boldFormat)
        cursor.insertText(problem.name+"\n", textFormat)
        cursor.insertText("Criterion: ", boldFormat)
        if problem.sense == 1:
            cursor.insertText("Minimize\n",textFormat)
        else:
            cursor.insertText("Maximize\n",textFormat)

        WasNone, dummyVar = problem.fixObjective()
        cursor.insertText("Status: ", boldFormat)
        cursor.insertText(str(LpStatus[problem.status])+"\n", textFormat)
        cursor.insertText("Value Function Objetive: ", boldFormat)
        cursor.insertText(str(value(problem.objective))+"\n", textFormat)
        cursor.insertBlock()
        cursor.insertText("Objective\n", boldFormat)
        cursor.insertText(str(problem.objective)+"\n", textFormat)
        cursor.insertBlock()
        cursor.insertText("Subject To\n", boldFormat)
        ks = list(problem.constraints.keys())
        ks.sort()
        for k in ks:
            constraint = problem.constraints[k]
            print constraint
            if not list(constraint.keys()):
                #empty constraint add the dummyVar
                dummyVar = problem.get_dummyVar()
                constraint += dummyVar
                #set this dummyvar to zero so infeasible problems are not made
                #feasible
                cursor.insertText((dummyVar == 0.0).asCplexLpConstraint("_dummy")
                                    , textFormat)
                cursor.insertBlock()
            cursor.insertText(str(k)+" : ", boldFormat)
            cursor.insertText(str(constraint), textFormat)
            cursor.insertBlock()
        vs = problem.variables()
        cursor.insertBlock()
        # Bounds on non-"positive" variables
        # Note: XPRESS and CPLEX do not interpret integer variables without
        # explicit bounds
        mip=1
        if mip:
            vg=[v for v in vs if not (v.isPositive() and v.cat==LpContinuous) \
                and not v.isBinary()]
        else:
            vg = [v for v in vs if not v.isPositive()]
        if vg:
            cursor.insertText("Bounds\n", boldFormat)
            for v in vg:
                cursor.insertText("%s, " % v.asCplexLpVariable(), textFormat)
        # Integer non-binary variables
        if mip:
            vg = [v for v in vs if v.cat == LpInteger and not v.isBinary()]
            if vg:
                cursor.insertText("Generals\n", boldFormat)
                for v in vg:
                    cursor.insertText("%s, " % v.name, textFormat)
            # Binary variables
            vg = [v for v in vs if v.isBinary()]
            if vg:
                cursor.insertText("Binaries\n",boldFormat)
                for v in vg:
                    cursor.insertText("%s, " % v.name, textFormat)
        cursor.setPosition(topFrame.lastPosition())

        bodyFrameFormat = QTextFrameFormat()
        bodyFrameFormat.setWidth(QTextLength(QTextLength.PercentageLength, 100))
        cursor.insertBlock()
        cursor.insertFrame(bodyFrameFormat)

        cursor.insertBlock()

        orderTableFormat = QTextTableFormat()
        orderTableFormat.setAlignment(Qt.AlignHCenter)
        orderTable = cursor.insertTable(1, 3, orderTableFormat)

        orderFrameFormat = cursor.currentFrame().frameFormat()
        orderFrameFormat.setBorder(1)
        cursor.currentFrame().setFrameFormat(orderFrameFormat)

        cursor = orderTable.cellAt(0, 0).firstCursorPosition()
        cursor.insertText("Variable", boldFormat)
        cursor = orderTable.cellAt(0, 1).firstCursorPosition()
        cursor.insertText("Value", boldFormat)
        cursor = orderTable.cellAt(0, 2).firstCursorPosition()
        cursor.insertText("Reduced Cost", boldFormat)

        for v in problem.variables():
            row = orderTable.rows()
            orderTable.insertRows(row, 1)
            #Name variable
            cursor = orderTable.cellAt(row, 0).firstCursorPosition()
            cursor.insertText(v.name, textFormat)
            #Value variable
            cursor = orderTable.cellAt(row, 1).firstCursorPosition()
            cursor.insertText(str(v.varValue), textFormat)
            #Cost Reduced variable
            cursor = orderTable.cellAt(row, 2).firstCursorPosition()
            cursor.insertText(str(v.dj), textFormat)

        cursor.setPosition(topFrame.lastPosition())
        cursor.insertBlock()

        orderTableFormat = QTextTableFormat()
        orderTableFormat.setAlignment(Qt.AlignHCenter)
        orderTable = cursor.insertTable(1, 3, orderTableFormat)

        orderFrameFormat = cursor.currentFrame().frameFormat()
        orderFrameFormat.setBorder(1)
        cursor.currentFrame().setFrameFormat(orderFrameFormat)

        cursor = orderTable.cellAt(0, 0).firstCursorPosition()
        cursor.insertText("Constraint", boldFormat)
        cursor = orderTable.cellAt(0, 1).firstCursorPosition()
        cursor.insertText("Slack", boldFormat)
        cursor = orderTable.cellAt(0, 2).firstCursorPosition()
        cursor.insertText("Shadow Price", boldFormat)

        for m in range(problem.numConstraints()):
            row = orderTable.rows()
            orderTable.insertRows(row, 1)
            #Name Constraint
            cursor = orderTable.cellAt(row, 0).firstCursorPosition()
            cursor.insertText("C"+ str(m+1), textFormat)
            #Slack Constraint
            cursor = orderTable.cellAt(row, 1).firstCursorPosition()
            cursor.insertText(str(problem.constraints.get("_C"+str(m+1)).slack)
            , textFormat)
            cursor = orderTable.cellAt(row, 2).firstCursorPosition()
            cursor.insertText(str(problem.constraints.get("_C"+str(m+1)).pi)
                                    , textFormat)
            self.printAction.setEnabled(True)

    def openAbout(self):
        about = AboutDialog(self)
        about.show()
コード例 #24
0
class ObserverWindow(QMainWindow):

    messageReceived = pyqtSignal(str, str, str, str, str)
    newFilterSettingsApplied = pyqtSignal(str)
    resetDisplays = pyqtSignal()

    #__________________________________________________________________
    def __init__(self, client, logger):

        super(ObserverWindow, self).__init__()

        self._connectionState = None

        self._countUntitledDisplay = 0
        self._displays = []
        self._session = 'Default session'
        self._host = 'localhost'
        self._port = 1883
        self._rootTopic = ''
        self._logger = logger

        self._logger.info(self.tr("Started"))

        reg = QSettings()

        if "current session" in reg.childKeys() and reg.value(
                "current session", '').strip() and reg.value(
                    "current session", '').strip() in reg.childGroups():
            self._session = reg.value("current session")

        self._logger.info(self.tr("Current session : ") + self._session)

        if self._session not in reg.childGroups():
            reg.beginGroup(self._session)
            reg.setValue("host", self._host)
            reg.setValue("port", self._port)
            reg.setValue("root topic", self._rootTopic)
            reg.endGroup()
        else:
            reg.beginGroup(self._session)
            self._host = reg.value("host", 'localhost')
            try:
                self._port = reg.value("port", 1883, type=int)
            except:
                pass
            self._rootTopic = reg.value("root topic", '')
            reg.endGroup()

        if "current session" in reg.childKeys() and not reg.value(
                "current session", '') in reg.childGroups():
            reg.remove("current session")

        self._mqttSwitchingConnection = False

        self._mqttClient = client
        self._mqttServerHost = self._host
        self._mqttServerPort = self._port
        self._mqttRootTopic = self._rootTopic
        self._mqttSubTopic = '#'

        if self._rootTopic:
            self._mqttSubTopic = self._rootTopic + '/#'

        QApplication.desktop().screenCountChanged.connect(self.restoreWindow)
        QApplication.desktop().resized.connect(self.restoreWindow)

        self.setWindowTitle(self._session)
        self.setWindowIcon(QIcon(':/view-eye.svg'))

        self._tabWidget = QTabWidget()
        self._cloudLabel = QLabel()
        self._connectionStateLabel = QLabel()

        self.builUi()

        reg.beginGroup(self._session)
        inbox = reg.value("param inbox", 'inbox')
        outbox = reg.value("param outbox", 'outbox')
        regexInbox = reg.value("regex inbox",
                               r'^%ROOT%/(?P<correspondent>.+)/%INBOX%$')
        regexOutbox = reg.value("regex outbox",
                                r'^%ROOT%/(?P<correspondent>.+)/%OUTBOX%$')
        regexDefault = reg.value("regex default",
                                 r'.*/(?P<correspondent>[^/]+)/[^/]+$')
        reg.endGroup()

        regexInbox = regexInbox.replace("%ROOT%", self._rootTopic).replace(
            "%INBOX%", inbox)
        regexOutbox = regexOutbox.replace("%ROOT%", self._rootTopic).replace(
            "%OUTBOX%", outbox)

        self._topicRegexInbox = None
        try:
            self._topicRegexInbox = re.compile(regexInbox)
        except Exception as e:
            self._logger.error(self.tr("Failed to compile inbox regex"))
            self._logger.debug(e)

        self._topicRegexOutbox = None
        try:
            self._topicRegexOutbox = re.compile(regexOutbox)
        except Exception as e:
            self._logger.error(self.tr("Failed to compile outbox regex"))
            self._logger.debug(e)

        self._topicRegexDefault = None
        try:
            self._topicRegexDefault = re.compile(regexDefault)
        except Exception as e:
            self._logger.error(
                self.tr("Failed to compile topic default regex"))
            self._logger.debug(e)

        self.addDisplay(self.tr("All messsages"))

        reg.beginGroup(self._session)
        for i in reg.childGroups():
            self.addDisplay(i)
        reg.endGroup()

        self.changeConnectionState(ConnectionState.DISCONNECTED)

        self._logger.info("{0} : {1}".format(self.tr("MQTT server host"),
                                             self._mqttServerHost))
        self._logger.info("{0} : {1}".format(self.tr("MQTT server port"),
                                             self._mqttServerPort))
        self._logger.info("{0} : {1}".format(
            self.tr("MQTT clientid"),
            self._mqttClient._client_id.decode("latin1")))

        Timer(0, self.layoutLoadSettings).start()
        Timer(0, self.start).start()

    #__________________________________________________________________
    @pyqtSlot()
    def addDisplay(self, title=None):

        if not title:
            if self._countUntitledDisplay:
                title = "{0} ({1})".format(self.tr("New observation"),
                                           self._countUntitledDisplay)
            else:
                title = self.tr("New observation")
            self._countUntitledDisplay = self._countUntitledDisplay + 1
            reg = QSettings()
            reg.beginGroup(self._session)
            if title not in reg.childGroups():
                reg.beginGroup(title)
                reg.setValue("display",
                             int(TopicDisplay.EMPHASIZEDCORRESPONDENT))
                reg.endGroup()
            reg.endGroup()
            reg.sync()

        root_observation = not len(self._displays)

        new_display = ObserverDisplayWidget(title,
                                            self._logger,
                                            self._session,
                                            self._mqttServerHost,
                                            self._mqttServerPort,
                                            self._mqttRootTopic,
                                            remove=not root_observation,
                                            filter=not root_observation)

        new_display.addObservation.connect(self.addDisplay)
        new_display.delObservation.connect(self.removeCurrentDisplay)
        self.newFilterSettingsApplied.connect(new_display.applyFilterSettings)

        self._displays.append(new_display)
        self._tabWidget.addTab(new_display, title)

        self.resetDisplays.connect(new_display.reset)
        self.messageReceived.connect(new_display.processMessage)
        new_display.newFilterSettings.connect(self.applyFilterSettings)
        new_display.resetWills.connect(self.applyResetWills)

        self._tabWidget.setCurrentWidget(new_display)

        self._logger.info("{0} : {1}".format(self.tr("Added observation"),
                                             title))

        dspmsg = ''
        for d in self._displays:
            if dspmsg:
                dspmsg += ' | '
            else:
                dspmsg = 'Displays : '
            dspmsg += d.title()
        self._logger.debug(dspmsg)

    #__________________________________________________________________
    @pyqtSlot(dict)
    def applyFilterSettings(self, filter):

        try:
            display = None
            for d in self._displays:
                if d.title() == filter["observation"]:
                    display = d

            if not display:
                self._logger.error(
                    self.tr("Observation not found in displays : ") +
                    filter["observation"])
            else:

                if filter["name"] != filter["observation"]:
                    for d in self._displays:
                        if d.title() == filter["name"]:
                            self._logger.warning(
                                self.tr("Can't rename observation '") +
                                filter["observation"] + self.tr("' : '") +
                                filter["name"] + self.tr("' already exists"))
                            msgbox = QMessageBox()
                            msgbox.setWindowTitle(self.tr("Observer"))
                            msgbox.setWindowIcon(
                                QIcon(':/magnifier-black.svg'))
                            msgbox.setText(
                                self.tr("Ignore apply filter !") +
                                "<br><br><i>" + self.
                                tr("Can't rename observation (name already in use)."
                                   ) + "</i><br>")
                            msgbox.setStandardButtons(QMessageBox.Close)
                            msgbox.setAttribute(Qt.WA_DeleteOnClose)
                            msgbox.setWindowFlags(
                                msgbox.windowFlags()
                                & ~Qt.WindowContextHelpButtonHint)
                            msgbox.button(QMessageBox.Close).setText(
                                self.tr("Close"))
                            msgbox.move(self.pos() + QPoint(40, 40))
                            msgbox.exec()
                            return
                    display.setTitle(filter["name"])
                    self._tabWidget.setTabText(self._tabWidget.currentIndex(),
                                               filter["name"])
                    reg = QSettings()
                    reg.beginGroup(self._session)
                    reg.remove(filter["observation"])
                    reg.endGroup()

                reg = QSettings()
                reg.beginGroup(self._session)
                reg.beginGroup(filter["name"])
                reg.setValue("display", int(filter["display"]))
                reg.setValue("filter 1", filter["filter 1"])
                reg.setValue("filter 2", filter["filter 2"])
                reg.setValue("filter 3", filter["filter 3"])
                reg.setValue("filter 4", filter["filter 4"])
                reg.setValue("buffer size", filter["buffer size"])
                reg.remove("Hidden correspondents")
                reg.beginGroup("Hidden correspondents")
                for p in filter["hidden correspondents"]:
                    reg.setValue(p.replace('/', '\\'), '')
                reg.endGroup()
                reg.remove("Hidden topics")
                reg.beginGroup("Hidden topics")
                for t in filter["hidden topics"]:
                    reg.setValue(t.replace('/', '\\'), '')
                reg.endGroup()
                reg.endGroup()
                reg.endGroup()
                reg.sync()

                self.newFilterSettingsApplied.emit(filter["name"])

        except Exception as e:
            self._logger.error("Failed to apply filter settings")
            self._logger.debug(e)

    #__________________________________________________________________
    @pyqtSlot(list)
    def applyResetWills(self, topics):

        for topic in topics:
            if self._connectionState == ConnectionState.CONNECTED:
                try:
                    (result, mid) = self._mqttClient.publish(topic,
                                                             '',
                                                             qos=0,
                                                             retain=True)
                    self._logger.info("{0} {1} (mid={2})".format(
                        self.tr("MQTT sending '' to clear will for "), topic,
                        mid))
                except Exception as e:
                    self._logger.info("{0} {1} (mid={2})".format(
                        self.tr("MQTT failed to send '' to clear will for "),
                        topic, mid))
                    self._logger.debug(e)
            else:
                self._logger.info("{0} {1}".format(
                    self.tr("MQTT failed to reset will (disconnected) for "),
                    topic))

    #__________________________________________________________________
    def builUi(self):

        mw = QWidget()
        self.setCentralWidget(mw)

        main_layout = QVBoxLayout(mw)
        main_layout.setSpacing(12)

        cloud_image = QLabel()
        cloud_image.setPixmap(QIcon(":/cloud-data.svg").pixmap(QSize(36, 36)))
        cloud_image.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

        cloud = self._mqttServerHost + ':' + str(self._mqttServerPort)

        if self._mqttRootTopic:
            cloud += '/' + self._mqttRootTopic + '/#'
        else:
            cloud += '/#'

        self._cloudLabel.setText(cloud)
        font = self._cloudLabel.font()
        font.setPixelSize(12)
        font.setBold(True)
        self._cloudLabel.setFont(font)

        settings_button = QPushButton()
        settings_button.setIcon(QIcon(":/settings.svg"))
        settings_button.setFlat(True)
        settings_button.setToolTip(self.tr("Settings"))
        settings_button.setIconSize(QSize(16, 16))
        settings_button.setFixedSize(QSize(24, 24))
        settings_button.setStyleSheet("QPushButton { padding-bottom: 4px }")

        self._connectionStateLabel = QLabel()
        self._connectionStateLabel.setPixmap(
            QIcon(":/led-circle-grey.svg").pixmap(QSize(24, 24)))
        self._connectionStateLabel.setSizePolicy(QSizePolicy.Fixed,
                                                 QSizePolicy.Fixed)

        header_layout = QHBoxLayout()
        header_layout.addWidget(cloud_image)
        header_layout.addWidget(self._cloudLabel)
        header_layout.addStretch()
        header_layout.addWidget(settings_button)
        header_layout.addWidget(self._connectionStateLabel)
        main_layout.addLayout(header_layout)

        main_layout.addWidget(self._tabWidget)

        settings_button.pressed.connect(self.settings)

    #__________________________________________________________________
    def changeConnectionState(self, state):

        self._connectionState = state

        if state == ConnectionState.CONNECTED:
            self._connectionStateLabel.setPixmap(
                QIcon(":/led-circle-green.svg").pixmap(QSize(24, 24)))
            self._connectionStateLabel.setToolTip(self.tr("Connected"))
        elif state == ConnectionState.CONNECTING:
            self._connectionStateLabel.setPixmap(
                QIcon(":/led-circle-yellow.svg").pixmap(QSize(24, 24)))
            self._connectionStateLabel.setToolTip(self.tr("Connecting"))
        elif state == ConnectionState.DISCONNECTED:
            self._connectionStateLabel.setPixmap(
                QIcon(":/led-circle-red.svg").pixmap(QSize(24, 24)))
            self._connectionStateLabel.setToolTip(self.tr("Disconnected"))
        else:
            self._connectionStateLabel.setPixmap(
                QIcon(":/led-circle-grey.svg").pixmap(QSize(24, 24)))
            self._connectionStateLabel.setToolTip("")

    #__________________________________________________________________
    def closeEvent(self, event):

        self._logger.info(self.tr("Done"))

    #__________________________________________________________________
    def layoutLoadSettings(self):

        reg = QSettings()
        pos = reg.value("position", QPoint(200, 200))
        size = reg.value("size", QSize(400, 400))

        self.move(pos)
        self.resize(size)

    #__________________________________________________________________
    def layoutSaveSettings(self):

        reg = QSettings()
        reg.setValue("position", self.pos())
        reg.setValue("size", self.size())
        reg.sync()

    #__________________________________________________________________
    def moveEvent(self, event):

        if self.isVisible():
            Timer(0, self.layoutSaveSettings).start()

    #__________________________________________________________________
    def mqttConnect(self):

        self._logger.info(self.tr("May connect to MQTT server..."))

        if self._mqttSwitchingConnection and self._connectionState == ConnectionState.DISCONNECTED:
            self._mqttServerHost = self._host
            self._mqttServerPort = self._port
            self._mqttRootTopic = self._rootTopic

            if self._rootTopic:
                self._mqttSubTopic = self._rootTopic + '/#'
            else:
                self._mqttSubTopic = '#'

            cloud = self._mqttServerHost + ':' + str(self._mqttServerPort)

            if self._mqttRootTopic:
                cloud += '/' + self._mqttRootTopic + '/#'
            else:
                cloud += '/#'

            self._cloudLabel.setText(cloud)

            clientid = "Observer/" + QUuid.createUuid().toString()
            self._logger.debug("MQTT clientid %s", clientid)

            self._mqttClient.reinitialise(client_id=clientid,
                                          clean_session=True,
                                          userdata=None)

            self._logger.info(self.tr("MQTT client reinitialised"))
            self._logger.info("{0} : {1}".format(self.tr("MQTT server host"),
                                                 self._mqttServerHost))
            self._logger.info("{0} : {1}".format(self.tr("MQTT server port"),
                                                 self._mqttServerPort))
            self._logger.info("{0} : {1}".format(
                self.tr("MQTT clientid"),
                self._mqttClient._client_id.decode("latin1")))
            self._mqttClient.on_connect = self.mqttOnConnect
            self._mqttClient.on_disconnect = self.mqttOnDisconnect
            self._mqttClient.on_log = self.mqttOnLog
            self._mqttClient.on_message = self.mqttOnMessage
            self._mqttClient.on_publish = self.mqttOnPublish
            self._mqttClient.on_subscribe = self.mqttOnSubscribe
            self._mqttClient.on_unsubscribe = self.mqttOnUnsubscribe

            self._mqttSwitchingConnection = False
            self._mqttClient.loop_start()

        if self._connectionState == ConnectionState.CONNECTED or self._connectionState == ConnectionState.CONNECTING:
            self._logger.info(
                self.tr("MQTT connect ignored (already ongoing)"))
        else:
            self._logger.info(self.tr("Connect to MQTT server"))
            try:
                self._mqttClient.connect(self._mqttServerHost,
                                         port=self._mqttServerPort,
                                         keepalive=MQTT_KEEPALIVE)
                self.changeConnectionState(ConnectionState.CONNECTING)
                self._logger.info(self.tr("MQTT connecting"))
            except Exception as e:
                self.changeConnectionState(ConnectionState.DISCONNECTED)
                self._logger.warning(
                    self.tr("Failed to connect to MQTT server"))
                self._logger.debug(e)
                Timer(15.000, self.mqttConnect).start()

        self._logger.debug("Connection state = " + str(self._connectionState))

    #__________________________________________________________________
    def mqttDisconnect(self):

        try:
            self._mqttClient.disconnect()
        except Exception as e:
            self._logger.error(self.tr("MQTT disconnection call failed"))
            self._logger.debug(e)

    #__________________________________________________________________
    def mqttOnConnect(self, client, userdata, flags, rc):

        self._logger.debug("Connected to MQTT server with result code: " +
                           str(rc) + " and flags: ", flags)  # flags is dict

        if rc == 0:
            self._logger.info(self.tr("MQTT connected"))
            self.changeConnectionState(ConnectionState.CONNECTED)
            mydata = {
                'host': self._mqttServerHost,
                'port': self._mqttServerPort
            }
            self._mqttClient.user_data_set(str(mydata))
            try:
                (result, mid) = self._mqttClient.subscribe(self._mqttSubTopic)
                self._logger.info("{0} {1} : {2}".format(
                    self.tr("MQTT subscribing to"), mid, self._mqttSubTopic))
            except Exception as e:
                self._logger.error(self.tr("MQTT subscribe call failed"))
                self._logger.debug(e)
        elif rc == 1:
            self._logger.warning(
                self.
                tr("MQTT failed to connect : connection refused - incorrect protocol version"
                   ))
        elif rc == 2:
            self._logger.warning(
                self.
                tr("MQTT failed to connect : connection refused - invalid client identifier"
                   ))
        elif rc == 3:
            self._logger.warning(
                self.
                tr("MQTT failed to connect : connection refused - server unavailable"
                   ))
        elif rc == 4:
            self._logger.warning(
                self.
                tr("MQTT failed to connect : connection refused - bad username or password"
                   ))
        elif rc == 5:
            self._logger.warning(
                self.
                tr("MQTT failed to connect : connection refused - not authorised"
                   ))
        else:
            self._logger.warning("{0} : {1}".format(
                self.tr("MQTT failed to connect : return code"), rc))

        self._logger.debug("Connection state = " + str(self._connectionState))

    #__________________________________________________________________
    def mqttOnDisconnect(self, client, userdata, rc):

        self.changeConnectionState(ConnectionState.DISCONNECTED)

        if self._mqttSwitchingConnection:
            self._logger.info(
                self.tr(
                    "Disconnected from MQTT server (switching connection)"))
            Timer(0, self.mqttConnect).start()
            return
        else:
            self._logger.info(self.tr("Disconnected from MQTT server"))

        serv = ''
        if isinstance(userdata, str):
            try:
                mydata = eval(userdata)
                if isinstance(mydata,
                              dict) and 'host' in mydata and 'port' in mydata:
                    serv = mydata['host'] + ':' + str(mydata['port'])
            except Exception as e:
                self._logger.info(
                    self.tr("MQTT client userdata not as expected"))
                self._logger.debug(e)

        if rc == 0:
            if serv:
                self._logger.info("{0} {1}".format(
                    self.tr("MQTT disconnected on request from"), serv))
            else:
                self._logger.info(self.tr("MQTT disconnected on request"))

        else:
            Timer(15.000, self.mqttConnect).start()
            if serv:
                self._logger.warning("{0}{1} {2} {3}".format(
                    self.tr("MQTT disconnected with rc="), rc, self.tr("from"),
                    serv))
            else:
                self._logger.warning("{0}{1}".format(
                    self.tr("MQTT disconnected with rc="), rc))

        self._logger.debug("Connection state = " + str(self._connectionState))

    #__________________________________________________________________
    def mqttOnLog(self, client, userdata, level, buf):

        self._logger.debug("MQTT log level {0} : {1}".format(level, buf))

    #__________________________________________________________________
    def mqttOnMessage(self, client, userdata, msg):

        if self._mqttSwitchingConnection:
            self._logger.info(
                self.tr("Ignore MQTT message (switching connection)"))
            return

        message = None
        try:
            message = msg.payload.decode(encoding="utf-8", errors="strict")
        except:
            pass

        if not message:
            self._logger.warning("{0} {1}".format(
                self.tr("MQTT message decoding failed on"), msg.topic))
            return

        self._logger.debug('Message: ' + message + ' in ' + msg.topic)

        direction = "&mdash;"
        correspondent = None

        if self._topicRegexInbox:
            if "correspondent" in self._topicRegexInbox.pattern:
                try:
                    m = re.match(self._topicRegexInbox, msg.topic)
                    if m:
                        match = m.groupdict()
                        if match["correspondent"]:
                            correspondent = match["correspondent"]
                            direction = "&rarr;"
                except Exception as e:
                    self._logger.debug(e)
            else:
                self._logger.warning(
                    self.tr("No 'correspondent' field in inbox regex : ") +
                    self._topicRegexInbox.pattern)

        if not correspondent and self._topicRegexOutbox:
            if "correspondent" in self._topicRegexOutbox.pattern:
                try:
                    m = re.match(self._topicRegexOutbox, msg.topic)
                    if m:
                        match = m.groupdict()
                        if match["correspondent"]:
                            correspondent = match["correspondent"]
                            direction = "&larr;"
                except Exception as e:
                    self._logger.debug(e)
            else:
                self._logger.warning(
                    self.tr("No 'correspondent' field in outbox regex : ") +
                    self._topicRegexInbox.pattern)

        if not correspondent and self._topicRegexDefault:
            if "correspondent" in self._topicRegexDefault.pattern:
                try:
                    m = re.match(self._topicRegexDefault, msg.topic)
                    if m:
                        match = m.groupdict()
                        if match["correspondent"]:
                            correspondent = match["correspondent"]
                except Exception as e:
                    self._logger.debug(e)
            else:
                self._logger.warning(
                    self.tr("No 'correspondent' field in default regex : ") +
                    self._topicRegexInbox.pattern)

        if not correspondent:
            self._logger.warning(
                self.tr("No correspondent defined for topic : ") + msg.topic)

        now = time.time()
        msec = repr(now).split('.')[1][:3]
        timestamp = time.strftime("[%d/%m/%Y %H:%M:%S.{}]".format(msec),
                                  time.localtime(now))
        self.messageReceived.emit(correspondent, msg.topic, message, timestamp,
                                  direction)

    #__________________________________________________________________
    def mqttOnPublish(self, client, userdata, mid):

        self._logger.debug("userdata=%s mid=%s", userdata, mid)
        self._logger.info("{0} : mid={1}".format(
            self.tr("MQTT published"), mid))  # mid is a number (message id)

    #__________________________________________________________________
    def mqttOnSubscribe(self, client, userdata, mid, granted_qos):

        self._logger.debug("mid=%s granted_qos=%s", mid,
                           granted_qos)  # granted_qos is (2,)
        self._logger.info("{0} : {1} {2} {3}".format(
            self.tr("MQTT susbcribed to"), mid, self.tr("with QoS"),
            granted_qos))  # mid is a number (count)

    #__________________________________________________________________
    def mqttOnUnsubscribe(self, client, userdata, mid):

        self._logger.debug("mid=%s", mid)
        self._logger.info(
            "{0} : {1}".format(self.tr("MQTT unsusbcribed from"),
                               mid))  # mid is a number (message id)

        if self._mqttSwitchingConnection:
            Timer(0, self.mqttDisconnect).start()

    #__________________________________________________________________
    def mqttReconnect(self):

        self._logger.info(self.tr("MQTT reconnecting"))

        if self._mqttSwitchingConnection:
            self._logger.info(
                self.tr("Ignore MQTT reconnecting (switching connection)"))
            return

        try:
            self._mqttClient.reconnect()
        except Exception as e:
            self._logger.error(self.tr("MQTT reconnection call failed"))
            Timer(15.000, self.mqttConnect).start()
            self._logger.debug(e)

    #__________________________________________________________________
    @pyqtSlot()
    def reload(self):

        reg = QSettings()

        if "current session" in reg.childKeys() and reg.value(
                "current session", '').strip() and reg.value(
                    "current session", '').strip() in reg.childGroups():
            self._session = reg.value("current session")

        self._logger.info(self.tr("Current session : ") + self._session)

        self.setWindowTitle(self._session)

        if self._session not in reg.childGroups():
            reg.beginGroup(self._session)
            reg.setValue("host", self._host)
            reg.setValue("port", self._port)
            reg.setValue("root topic", self._rootTopic)
            reg.endGroup()
        else:
            reg.beginGroup(self._session)
            self._host = reg.value("host", 'localhost')
            try:
                self._port = reg.value("port", 1883, type=int)
            except:
                pass
            self._rootTopic = reg.value("root topic", '')
            reg.endGroup()

        if "current session" in reg.childKeys() and not reg.value(
                "current session", '') in reg.childGroups():
            reg.remove("current session")

        self._mqttSwitchingConnection = False
        self._mqttSwitchingSubscription = False

        if self._host != self._mqttServerHost or self._port != self._mqttServerPort:
            self._mqttSwitchingConnection = True
        elif self._rootTopic != self._mqttRootTopic:
            self._mqttSwitchingSubscription = True

        self._mqttServerHost = self._host
        self._mqttServerPort = self._port
        self._mqttRootTopic = self._rootTopic
        self._mqttSubTopic = '#'

        if self._rootTopic:
            self._mqttSubTopic = self._rootTopic + '/#'

        reg.beginGroup(self._session)
        inbox = reg.value("param inbox", 'inbox')
        outbox = reg.value("param outbox", 'outbox')
        regexInbox = reg.value("regex inbox",
                               r'^%ROOT%/(?P<correspondent>.+)/%INBOX%$')
        regexOutbox = reg.value("regex outbox",
                                r'^%ROOT%/(?P<correspondent>.+)/%OUTBOX%$')
        regexDefault = reg.value("regex default",
                                 r'.*/(?P<correspondent>[^/]+)/[^/]+$')
        reg.endGroup()

        regexInbox = regexInbox.replace("%ROOT%", self._rootTopic).replace(
            "%INBOX%", inbox)
        regexOutbox = regexOutbox.replace("%ROOT%", self._rootTopic).replace(
            "%OUTBOX%", outbox)

        self._topicRegexInbox = None
        try:
            self._topicRegexInbox = re.compile(regexInbox)
        except Exception as e:
            self._logger.error(self.tr("Failed to compile inbox regex"))
            self._logger.debug(e)

        self._topicRegexOutbox = None
        try:
            self._topicRegexOutbox = re.compile(regexOutbox)
        except Exception as e:
            self._logger.error(self.tr("Failed to compile outbox regex"))
            self._logger.debug(e)

        self._topicRegexDefault = None
        try:
            self._topicRegexDefault = re.compile(regexDefault)
        except Exception as e:
            self._logger.error(
                self.tr("Failed to compile topic default regex"))
            self._logger.debug(e)

        index = self._tabWidget.currentIndex()
        current = self._tabWidget.currentWidget()

        for index in (1, self._tabWidget.count()):
            try:
                self._displays.remove(self._tabWidget.widget(index))
                self._tabWidget.widget(index).deleteLater()
                self._tabWidget.removeTab(index)
            except Exception as e:
                self._logger.error(
                    self.
                    tr("Failed to remove observation : not in display list (index="
                       ) + str(index) + self.tr(")"))
                self._logger.debug(e)

        dspmsg = ''
        for d in self._displays:
            if dspmsg:
                dspmsg += ' | '
            else:
                dspmsg = 'Displays : '
            dspmsg += d.title()
        self._logger.debug(dspmsg)

        reg.beginGroup(self._session)
        for i in reg.childGroups():
            self.addDisplay(i)
        reg.endGroup()

        QCoreApplication.processEvents()

        if self._mqttSwitchingConnection:
            self.switchConnection()
        elif self._mqttSwitchingSubscription:
            self.switchSubscription()

    #__________________________________________________________________
    @pyqtSlot()
    def removeCurrentDisplay(self):

        index = self._tabWidget.currentIndex()
        current = self._tabWidget.currentWidget()

        if index > 0 and current == self.sender():
            try:
                title = self._tabWidget.tabText(index)
                self._tabWidget.removeTab(index)
                if current in self._displays:
                    self._displays.remove(self.sender())
                    self.sender().deleteLater()
                    self._logger.info("{0} : {1}".format(
                        self.tr("Remove observation"), title))
                    reg = QSettings()
                    reg.beginGroup(self._session)
                    reg.remove(title)
                    reg.endGroup()
                    reg.sync()
                else:
                    self._logger.warning(
                        self.
                        tr("Failed to remove observation : not in display list (index="
                           ) + str(index) + self.tr(")"))
            except Exception as e:
                self._logger.error(
                    self.
                    tr("Failed to remove observation : not in display list (index="
                       ) + str(index) + self.tr(")"))
                self._logger.debug(e)

        dspmsg = ''
        for d in self._displays:
            if dspmsg:
                dspmsg += ' | '
            else:
                dspmsg = 'Displays : '
            dspmsg += d.title()
        self._logger.debug(dspmsg)

    #__________________________________________________________________
    @pyqtSlot()
    def restoreWindow(self):

        self.resize(QSize(400, 400))
        self.move(QPoint(200, 200))

    #__________________________________________________________________
    def resizeEvent(self, event):

        if self.isVisible():
            Timer(0, self.layoutSaveSettings).start()

    #__________________________________________________________________
    @pyqtSlot()
    def settings(self):

        dlg = ObserverSettingsDialog(self._logger, self._session)
        dlg.move(self.pos() + QPoint(20, 20))

        dlg.correspondentRegex.connect(self.settingsRegex)
        dlg.reloadSession.connect(self.reload)
        dlg.exec()

        reg = QSettings()

        reg.beginGroup(self._session)
        self._host = reg.value("host", 'localhost')
        try:
            self._port = reg.value("port", 1883, type=int)
        except:
            self._port = 1883
        self._rootTopic = reg.value("root topic", '')
        reg.endGroup()

        if self._host != self._mqttServerHost or self._port != self._mqttServerPort:
            self.switchConnection()
        elif self._rootTopic != self._mqttRootTopic:
            self.switchSubscription()

    #__________________________________________________________________
    @pyqtSlot()
    def settingsRegex(self):

        dlg = ObserverRegexDialog(self._logger, self._session)
        dlg.move(self.pos() + QPoint(20, 20))
        dlg.exec()

        reg = QSettings()
        reg.beginGroup(self._session)
        inbox = reg.value("param inbox", 'inbox')
        outbox = reg.value("param outbox", 'outbox')
        regexInbox = reg.value("regex inbox",
                               r'^%ROOT%/(?P<correspondent>.+)/%INBOX%$')
        regexOutbox = reg.value("regex outbox",
                                r'^%ROOT%/(?P<correspondent>.+)/%OUTBOX%$')
        regexDefault = reg.value("regex default",
                                 r'.*/(?P<correspondent>[^/]+)/[^/]+$')
        reg.endGroup()

        regexInbox = regexInbox.replace("%ROOT%", self._rootTopic).replace(
            "%INBOX%", inbox)
        regexOutbox = regexOutbox.replace("%ROOT%", self._rootTopic).replace(
            "%OUTBOX%", outbox)

        self._topicRegexInbox = None
        try:
            self._topicRegexInbox = re.compile(regexInbox)
        except Exception as e:
            self._logger.error(
                self.tr("Failed to compile inbox regex :") + regexInbox)
            self._logger.debug(e)

        self._topicRegexOutbox = None
        try:
            self._topicRegexOutbox = re.compile(regexOutbox)
        except Exception as e:
            self._logger.error(
                self.tr("Failed to compile outbox regex :") + regexOutbox)
            self._logger.debug(e)

        self._topicRegexDefault = None
        try:
            self._topicRegexDefault = re.compile(regexDefault)
        except Exception as e:
            self._logger.error(
                self.tr("Failed to compile topic default regex :") +
                regexDefault)
            self._logger.debug(e)

    #__________________________________________________________________
    def start(self):

        try:
            self._mqttClient.on_connect = self.mqttOnConnect
            self._mqttClient.on_disconnect = self.mqttOnDisconnect
            self._mqttClient.on_log = self.mqttOnLog
            self._mqttClient.on_message = self.mqttOnMessage
            self._mqttClient.on_publish = self.mqttOnPublish
            self._mqttClient.on_subscribe = self.mqttOnSubscribe
            self._mqttClient.on_unsubscribe = self.mqttOnUnsubscribe
            Timer(0, self.mqttConnect).start()
        except:
            self._logger.error(
                self.tr("Can't start MQTT (check definitions in .INI)"))
            msgbox = QMessageBox()
            msgbox.setWindowTitle(self.tr("Observer"))
            msgbox.setWindowIcon(QIcon(':/view-eye.svg'))
            msgbox.setText(
                self.tr("Failed to set MQTT client !") + "<br><br><i>" +
                self.tr("Application will be closed.") + "</i><br>")
            msgbox.setStandardButtons(QMessageBox.Close)
            msgbox.setAttribute(Qt.WA_DeleteOnClose)
            msgbox.setWindowFlags(msgbox.windowFlags()
                                  & ~Qt.WindowContextHelpButtonHint)
            msgbox.button(QMessageBox.Close).setText(self.tr("Close"))
            msgbox.resize(QSize(400, 300))
            msgbox.exec()
            self._logger.info(self.tr("Done"))
            Timer(0, QCoreApplication.quit).start()

        self._logger.debug("Connection state = " + str(self._connectionState))

    #__________________________________________________________________
    def switchConnection(self):

        self._mqttSwitchingConnection = True

        self.resetDisplays.emit()

        current_topic = self._mqttSubTopic

        if self._connectionState == ConnectionState.CONNECTED or self._connectionState == ConnectionState.CONNECTING:
            try:
                (result, mid) = self._mqttClient.unsubscribe(current_topic)
                self._logger.info("{0} {1} : {2}".format(
                    self.tr("MQTT unsubscribing from"), mid, current_topic))
            except Exception as e:
                self._logger.debug(e)
                Timer(0, self.mqttDisconnect).start()
        else:
            Timer(0, self.mqttConnect).start()

        self._logger.debug("Connection state = " + str(self._connectionState))

    #__________________________________________________________________
    def switchSubscription(self):

        self.resetDisplays.emit()

        current_topic = self._mqttSubTopic
        self._mqttRootTopic = self._rootTopic

        if self._rootTopic:
            self._mqttSubTopic = self._rootTopic + '/#'
        else:
            self._mqttSubTopic = '#'

        cloud = self._mqttServerHost + ':' + str(self._mqttServerPort)

        if self._mqttRootTopic:
            cloud += '/' + self._mqttRootTopic + '/#'
        else:
            cloud += '/#'

        self._cloudLabel.setText(cloud)
        self.resetDisplays.emit()

        if self._connectionState == ConnectionState.CONNECTED:
            try:
                (result, mid) = self._mqttClient.unsubscribe(current_topic)
                self._logger.info("{0} {1} : {2}".format(
                    self.tr("MQTT unsubscribing from"), mid, current_topic))
                (result, mid) = self._mqttClient.subscribe(self._mqttSubTopic)
                self._logger.info("{0} {1} : {2}".format(
                    self.tr("MQTT subscribing to"), mid, self._mqttSubTopic))
            except Exception as e:
                self._logger.debug(e)
        else:
            Timer(0, self.mqttReconnect).start()

        self._logger.debug("Connection state = " + str(self._connectionState))
コード例 #25
0
class ImageToolWindow(QMainWindow, _AbstractWindowMixin):
    """ImageToolWindow class.

    This is the second Main GUI which focuses on manipulating the image
    , e.g. selecting ROI, masking, normalization, for different
    data analysis scenarios.
    """
    _title = "Image tool"

    _root_dir = osp.dirname(osp.abspath(__file__))

    _WIDTH, _HEIGHT = config['GUI_IMAGE_TOOL_SIZE']

    mask_file_path_sgn = pyqtSignal(str)

    class TabIndex(IntEnum):
        OVERVIEW = 0
        GAIN_OFFSET = 1
        REFERENCE = 2
        AZIMUTHAL_INTEG_1D = 3
        GEOMETRY = 4
        IMAGE_TRANSFORM = 5

    def __init__(self,
                 queue,
                 *,
                 pulse_resolved=True,
                 require_geometry=True,
                 parent=None):
        """Initialization.

        :param deque queue: data queue.
        :param bool pulse_resolved: whether the related data is
            pulse-resolved or not.
        :param bool require_geometry: whether the detector requires a
            geometry to assemble its modules.
        """
        super().__init__(parent=parent)

        self._queue = queue
        self._pulse_resolved = pulse_resolved
        self._require_geometry = require_geometry

        self._mediator = Mediator()

        try:
            title = parent.title + " - " + self._title
        except AttributeError:
            title = self._title  # for unit test where parent is None
        self.setWindowTitle(title)

        self._ctrl_widgets = []

        # -----------------------------
        # ctrl panel
        # -----------------------------

        self._bulletin_view = self.createView(BulletinView)
        self._image_ctrl_widget = self.createCtrlWidget(ImageCtrlWidget)
        self._mask_ctrl_widget = self.createCtrlWidget(MaskCtrlWidget)

        # -----------------------------
        # view panel
        # -----------------------------

        self._views_tab = QTabWidget()
        self._corrected_view = self.createView(CorrectedView)
        self._calibration_view = self.createView(CalibrationView)
        self._reference_view = self.createView(ReferenceView)
        self._azimuthal_integ_1d_view = self.createView(AzimuthalInteg1dView)
        self._geometry_view = self.createView(GeometryView)
        self._transform_view = self.createView(TransformView)

        # Whether the view is updated automatically
        self._auto_update = True

        self._cw = QWidget()
        self.setCentralWidget(self._cw)

        self.initUI()
        self.initConnections()
        self.updateMetaData()

        self.resize(self._WIDTH, self._HEIGHT)

    def initUI(self):
        """Override."""
        corrected_tab_idx = self._views_tab.addTab(self._corrected_view,
                                                   "Overview")
        cali_idx = self._views_tab.addTab(self._calibration_view,
                                          "Gain / offset")
        ref_idx = self._views_tab.addTab(self._reference_view, "Reference")
        azimuthal_integ_tab_idx = self._views_tab.addTab(
            self._azimuthal_integ_1d_view, "Azimuthal integration 1D")
        geom_idx = self._views_tab.addTab(self._geometry_view, "Geometry")
        if not self._require_geometry:
            self._views_tab.setTabEnabled(geom_idx, False)
        transform_idx = self._views_tab.addTab(self._transform_view,
                                               "Feature extraction")

        assert (corrected_tab_idx == self.TabIndex.OVERVIEW)
        assert (cali_idx == self.TabIndex.GAIN_OFFSET)
        assert (ref_idx == self.TabIndex.REFERENCE)
        assert (azimuthal_integ_tab_idx == self.TabIndex.AZIMUTHAL_INTEG_1D)
        assert (geom_idx == self.TabIndex.GEOMETRY)
        assert (transform_idx == self.TabIndex.IMAGE_TRANSFORM)

        ctrl_panel = QWidget()
        ctrl_panel_layout = QVBoxLayout()
        ctrl_panel_layout.addWidget(self._bulletin_view)
        ctrl_panel_layout.addWidget(self._image_ctrl_widget)
        ctrl_panel_layout.addWidget(self._mask_ctrl_widget)
        ctrl_panel_layout.addStretch(1)
        ctrl_panel.setLayout(ctrl_panel_layout)
        ctrl_panel.setFixedWidth(ctrl_panel.minimumSizeHint().width() + 10)

        layout = QHBoxLayout()
        layout.addWidget(self._views_tab)
        layout.addWidget(ctrl_panel)
        self._cw.setLayout(layout)
        self.layout().setContentsMargins(0, 0, 0, 0)

    def initConnections(self):
        self._image_ctrl_widget.auto_update_cb.toggled.connect(
            self.onAutoUpdateToggled)

        mediator = self._mediator

        self._image_ctrl_widget.update_image_btn.clicked.connect(
            self.onUpdateWidgets)
        self._image_ctrl_widget.auto_level_btn.clicked.connect(
            mediator.reset_image_level_sgn)
        self._image_ctrl_widget.save_image_btn.clicked.connect(
            self._corrected_view.onSaveImage)

        self._mask_ctrl_widget.draw_mask_btn.toggled.connect(
            self._corrected_view.onDrawMask)
        self._mask_ctrl_widget.erase_mask_btn.toggled.connect(
            self._corrected_view.onEraseMask)
        self._mask_ctrl_widget.remove_btn.clicked.connect(
            self._corrected_view.onRemoveMask)
        self._mask_ctrl_widget.load_btn.clicked.connect(
            self._corrected_view.onLoadMask)
        self._mask_ctrl_widget.save_btn.clicked.connect(
            self._corrected_view.onSaveMask)
        self._mask_ctrl_widget.mask_save_in_modules_cb.toggled.connect(
            self._corrected_view.onMaskSaveInModulesChange)

        self._views_tab.tabBarClicked.connect(self.onViewsTabClicked)
        self._views_tab.currentChanged.connect(self.onViewsTabChanged)

        self._transform_view.transform_type_changed_sgn.connect(
            self._onTransformViewTypeChanged)

    def onStart(self):
        for widget in self._ctrl_widgets:
            widget.onStart()

    def onStop(self):
        for widget in self._ctrl_widgets:
            widget.onStop()

    def createView(self, view_class):
        return view_class(pulse_resolved=self._pulse_resolved, parent=self)

    def createCtrlWidget(self, widget_class, *args, **kwargs):
        """Register a ctrl widget.

        Ctrl widgets reside in (views of) ImageToolWindow should explicitly
        call this method to be registered.
        """
        widget = widget_class(*args,
                              pulse_resolved=self._pulse_resolved,
                              require_geometry=self._require_geometry,
                              **kwargs)
        self._ctrl_widgets.append(widget)
        return widget

    def updateMetaData(self):
        """Update metadata from all the ctrl widgets.

        :returns bool: True if all metadata successfully parsed
            and emitted, otherwise False.
        """
        for widget in self._ctrl_widgets:
            if not widget.updateMetaData():
                return False
        return True

    def loadMetaData(self):
        """Load metadata from Redis and set child control widgets."""
        for widget in self._ctrl_widgets:
            widget.loadMetaData()

    def reset(self):
        """Override."""
        pass

    @pyqtSlot()
    def onUpdateWidgets(self):
        """Used for updating manually."""
        self._updateWidgets(True)

    def updateWidgetsF(self):
        """Override."""
        self._updateWidgets(self._auto_update)

    def _updateWidgets(self, auto_update):
        if len(self._queue) == 0:
            return
        data = self._queue[0]

        # update bulletin
        self._bulletin_view.updateF(data, auto_update)
        # update other ImageView/PlotWidget in the activated tab
        self._views_tab.currentWidget().updateF(data, auto_update)

    @pyqtSlot(int)
    def onViewsTabClicked(self, idx):
        if self._views_tab.currentIndex() == idx:
            return
        self._views_tab.currentWidget().onDeactivated()

    @pyqtSlot(int)
    def onViewsTabChanged(self, idx):
        self._views_tab.currentWidget().onActivated()
        if self._views_tab.currentIndex() != self.TabIndex.IMAGE_TRANSFORM:
            self._updateWidgets(True)  # force update

        self._mask_ctrl_widget.setInteractiveButtonsEnabled(
            self._views_tab.currentIndex() == self.TabIndex.OVERVIEW)

    @pyqtSlot(bool)
    def onAutoUpdateToggled(self, state):
        self._auto_update = state

    @pyqtSlot(int)
    def _onTransformViewTypeChanged(self, tp):
        if self._views_tab.currentIndex() == self.TabIndex.IMAGE_TRANSFORM:
            self._updateWidgets(True)
コード例 #26
0
class Main(QMainWindow):
    def __init__(self): 
        global downloads_list_file
        QMainWindow.__init__(self)
        self.setWindowIcon(QIcon(":/quartz.png")) 
        self.setWindowTitle("Quartz Browser - "+__version__)
        # Window Properties
        self.history = []
        self.downloads = []
        self.confirm_before_quit = True
        # Create required directories
        for folder in [configdir, icon_dir, thumbnails_dir]:
            if not os.path.exists(folder):
                os.mkdir(folder)
        # Import and Apply Settings
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.settings = QSettings(1, 0, "quartz-browser","Quartz", self)
        self.opensettings()
        self.websettings = QWebSettings.globalSettings()
        self.websettings.setAttribute(QWebSettings.DnsPrefetchEnabled, True)
        self.websettings.setMaximumPagesInCache(10)
        self.websettings.setIconDatabasePath(icon_dir)
        self.websettings.setAttribute(QWebSettings.JavascriptCanOpenWindows, True)
        self.websettings.setAttribute(QWebSettings.JavascriptCanCloseWindows, True)
        if webkit.enable_adblock:
            self.websettings.setUserStyleSheetUrl(QUrl.fromLocalFile(program_dir + 'userContent.css'))
        # Import Downloads and Bookmarks
        self.dwnldsmodel = DownloadsModel(self.downloads, QApplication.instance())
        self.dwnldsmodel.deleteDownloadsRequested.connect(self.deleteDownloads)
        imported_downloads = importDownloads(downloads_list_file)
        for [filepath, url, totalsize, timestamp] in imported_downloads:
            try :                                                  # Check if downloads.txt is valid
                tymstamp = float(timestamp)
            except :
                self.downloads = []
                exportDownloads(downloads_list_file, [])
                print("Error in importing Downloads.")
                break
            old_download = Download(networkmanager)
            old_download.loadDownload(filepath, url, totalsize, timestamp)
            old_download.datachanged.connect(self.dwnldsmodel.datachanged)
            self.downloads.append(old_download)
        self.bookmarks = importBookmarks(configdir+"bookmarks.txt")
        self.favourites = importFavourites(configdir + 'favourites.txt')
        # Find and set icon theme name
        for theme_name in ['Adwaita', 'Gnome', 'Tango']:
            if os.path.exists('/usr/share/icons/' + theme_name):
                QIcon.setThemeName(theme_name)
                break
        self.initUI()
        self.resize(1024,714)

    def initUI(self):
###############################  Create  Actions ##############################
        self.loadimagesaction = QAction("Load Images",self)
        self.loadimagesaction.setCheckable(True)
        self.loadimagesaction.triggered.connect(self.loadimages)

        self.javascriptmode = QAction("Enable Javascript",self)
        self.javascriptmode.setCheckable(True)
        self.javascriptmode.triggered.connect(self.setjavascript)

        self.useragent_mode_desktop = QAction("Desktop",self)
        self.useragent_mode_desktop.setCheckable(True)
        self.useragent_mode_desktop.triggered.connect(self.setUserAgentDesktop)

        self.useragent_mode_mobile = QAction("Mobile",self)
        self.useragent_mode_mobile.setCheckable(True)
        self.useragent_mode_mobile.triggered.connect(self.setUserAgentMobile)

        self.useragent_mode_custom = QAction("Custom",self)
        self.useragent_mode_custom.setCheckable(True)
        self.useragent_mode_custom.triggered.connect(self.setUserAgentCustom)

################ Add Actions to Menu ####################
        # This sub-menu sets useragent mode to desktop/mobile/custom
        self.useragentMenu = QMenu('UserAgent', self)
        self.useragentMenu.setIcon(QIcon(":/computer.png"))
        self.useragentMenu.addAction(self.useragent_mode_desktop)
        self.useragentMenu.addAction(self.useragent_mode_mobile)
        self.useragentMenu.addAction(self.useragent_mode_custom)

        # This is main menu
        self.menu = QMenu(self)
        self.menu.addAction(QIcon(":/edit-find.png"), "Find Text", self.findmode, "Ctrl+F")
        self.menu.addAction(QIcon(":/list-add.png"), "Zoom In", self.zoomin, "Ctrl++")
        self.menu.addAction(QIcon(":/list-remove.png"), "Zoom Out", self.zoomout, "Ctrl+-")
        self.menu.addAction(QIcon(":/view-fullscreen.png"), "Toggle Fullscreen", self.fullscreenmode, "F11")
        self.menu.addSeparator()

        self.menu.addAction(self.loadimagesaction)
        self.menu.addAction(self.javascriptmode)
        self.menu.addMenu(self.useragentMenu)
        self.menu.addAction(QIcon(":/applications-system.png"), "Settings", self.settingseditor, "Ctrl+,")
        self.menu.addSeparator()

        self.menu.addAction(QIcon(":/image-x-generic.png"), "Save as Image", self.saveAsImage, "Shift+Ctrl+S")
        self.menu.addAction(QIcon(":/text-html.png"), "Save as HTML", self.saveashtml, "Ctrl+S")
        self.menu.addAction(QIcon(":/document-print.png"), "Print to PDF", self.printpage, "Ctrl+P")
        self.menu.addSeparator()
        self.menu.addAction(QIcon(":/process-stop.png"), "Quit", self.forceClose, "Ctrl+Q")

        self.bmk_menu = QMenu(self)
        self.bmk_menu.addAction(QIcon(':/add-bookmark.png'), 'Add Bookmark', self.addbookmark)
        self.bmk_menu.addAction(QIcon(':/favourites.png'), 'Add to Home', self.addToFavourites)
        
###############################  Create Gui Parts ##############################
        self.centralwidget = QWidget(self)
        self.setCentralWidget(self.centralwidget)
        grid = QGridLayout(self.centralwidget)
        grid.setSpacing(1)
        grid.setContentsMargins(0,2,0,0)

        self.toolBar = QWidget(self)
        horLayout = QHBoxLayout(self.toolBar)
        horLayout.setSpacing(1)
        horLayout.setContentsMargins(0,2,0,0)

        self.addtabBtn = QPushButton(QIcon(":/add-tab.png"), "",self)
        self.addtabBtn.setToolTip("New Tab\n[Ctrl+Tab]")
        self.addtabBtn.setShortcut("Ctrl+Tab")
        self.addtabBtn.clicked.connect(self.addTab)

        self.reload = QPushButton(QIcon(":/refresh.png"), "",self) 
        self.reload.setMinimumSize(35,26) 
        self.reload.setToolTip("Reload/Stop\n  [Space]")
        self.reload.setShortcut("Space")
        self.reload.clicked.connect(self.Reload)

        self.back = QPushButton(QIcon(":/prev.png"), "", self) 
        self.back.setToolTip("Previous Page")
        self.back.setMinimumSize(35,26) 
        self.back.clicked.connect(self.Back)

        self.forw = QPushButton(QIcon(":/next.png"), "",self) 
        self.forw.setToolTip("Next Page")
        self.forw.setMinimumSize(35,26) 
        self.forw.clicked.connect(self.Forward)

        self.homeBtn = QPushButton(QIcon(":/home.png"), "",self) 
        self.homeBtn.setToolTip("Go Home")
        self.homeBtn.clicked.connect(self.goToHome)

        self.videoDownloadButton = QPushButton(QIcon(":/video-dwnld.png"), "", self)
        self.videoDownloadButton.setToolTip("Download this Video")
        self.videoDownloadButton.clicked.connect(self.downloadVideo)
        self.videoDownloadButton.hide()

        self.addbookmarkBtn = QToolButton(self)
        self.addbookmarkBtn.setIcon(QIcon(":/add-bookmark.png"))
        self.addbookmarkBtn.setToolTip("Add Bookmark")
        self.addbookmarkBtn.setMenu(self.bmk_menu)
        self.addbookmarkBtn.setPopupMode(QToolButton.InstantPopup)

        self.menuBtn = QToolButton(self)
        self.menuBtn.setIcon(QIcon(":/menu.png"))
        self.menuBtn.setMenu(self.menu)
        self.menuBtn.setPopupMode(QToolButton.InstantPopup)

        self.bookmarkBtn = QPushButton(QIcon(":/bookmarks.png"), "", self)
        self.bookmarkBtn.setToolTip("Manage Bookmarks\n         [Alt+B]")
        self.bookmarkBtn.setShortcut("Alt+B")
        self.bookmarkBtn.clicked.connect(self.managebookmarks)
        self.historyBtn = QPushButton(QIcon(":/history.png"), "", self)
        self.historyBtn.setShortcut("Alt+H")
        self.historyBtn.setToolTip("View History\n     [Alt+H]")
        self.historyBtn.clicked.connect(self.viewhistory)

        self.downloadsBtn = QPushButton(QIcon(":/download.png"), "", self)
        self.downloadsBtn.setToolTip("Download Manager")
        self.downloadsBtn.clicked.connect(self.download_manager)

        self.find = QPushButton(self)
        self.find.setText("Find/Next")
        self.find.clicked.connect(self.findnext)
        self.find.hide()
        self.findprev = QPushButton(self)
        self.findprev.setText("Backward")
        self.findprev.clicked.connect(self.findback)
        self.findprev.hide()
        self.cancelfind = QPushButton(self)
        self.cancelfind.setText("Cancel")
        self.cancelfind.clicked.connect(self.cancelfindmode)
        self.cancelfind.hide()

        self.pbar = QProgressBar(self) 
        self.pbar.setTextVisible(False)
        self.pbar.setStyleSheet("QProgressBar::chunk { background-color: #bad8ff; }")
        pbarLayout = QGridLayout(self.pbar)
        pbarLayout.setContentsMargins(0,0,0,0)

        self.line = webkit.UrlEdit(self.pbar)
        self.line.openUrlRequested.connect(self.Enter)
        self.line.textEdited.connect(self.urlsuggestions)
        self.line.downloadRequested.connect(self.download_requested_file)
        pbarLayout.addWidget(self.line)

        self.listmodel = QStringListModel(self)
        self.completer = QCompleter(self.listmodel, self.line)
        self.completer.setCompletionMode(1)
        self.completer.setMaxVisibleItems(10)
        self.line.setCompleter(self.completer)

        self.statusbar = QLabel(self)
        self.statusbar.setStyleSheet("QLabel { font-size: 12px; border-radius: 2px; padding: 2px; background: palette(highlight); color: palette(highlighted-text); }")
        self.statusbar.setMaximumHeight(16)
        self.statusbar.hide()

        self.tabWidget = QTabWidget(self)
        self.tabWidget.setTabsClosable(True)
        self.tabWidget.setDocumentMode(True)
        self.tabWidget.tabBar().setExpanding(True)
        self.tabWidget.tabBar().setElideMode(Qt.ElideMiddle)
        self.tabWidget.currentChanged.connect(self.onTabSwitch)
        self.tabWidget.tabCloseRequested.connect(self.closeTab)
        self.addTab()
        self.applysettings()
#       
        grid.addWidget(self.toolBar, 0,0, 1,1)
        for widget in [self.addtabBtn, self.back, self.forw, self.reload, self.homeBtn, self.videoDownloadButton,
                self.pbar, self.find, self.findprev, self.cancelfind, self.addbookmarkBtn, self.menuBtn,
                self.bookmarkBtn, self.historyBtn, self.downloadsBtn]:
            horLayout.addWidget(widget)
        grid.addWidget(self.tabWidget, 1, 0, 1, 1)

#------------------------------------------------------------------------------------------
#        Must be at the end, otherwise cause segmentation fault
#       self.status = self.statusBar() 

    def addTab(self, webview_tab=None):
        """ Creates a new tab and add to QTabWidget
            applysettings() must be called after adding each tab"""
        if not webview_tab:
            webview_tab = webkit.MyWebView(self.tabWidget, networkmanager) 
        webview_tab.windowCreated.connect(self.addTab)
        webview_tab.loadStarted.connect(self.onLoadStart) 
        webview_tab.loadFinished.connect(self.onLoadFinish) 
        webview_tab.loadProgress.connect(self.onProgress)
        webview_tab.urlChanged.connect(self.onUrlChange)
        webview_tab.titleChanged.connect(self.onTitleChange)
        webview_tab.iconChanged.connect(self.onIconChange)
        webview_tab.videoListRequested.connect(self.getVideos)
        webview_tab.page().printRequested.connect(self.printpage)
        webview_tab.page().downloadRequested.connect(self.download_requested_file)
        webview_tab.page().unsupportedContent.connect(self.handleUnsupportedContent)
        webview_tab.page().linkHovered.connect(self.onLinkHover)
        webview_tab.page().windowCloseRequested.connect(self.closeRequestedTab)

        self.tabWidget.addTab(webview_tab, "( Untitled )")
        if self.tabWidget.count()==1:
            self.tabWidget.tabBar().hide()
        else:
            self.tabWidget.tabBar().show()
        self.tabWidget.setCurrentIndex(self.tabWidget.count()-1)

    def closeTab(self, index=None):
        """ Closes tab, hides tabbar if only one tab remains"""
        if index==None:
            index = self.tabWidget.currentIndex()
        widget = self.tabWidget.widget(index)
        self.tabWidget.removeTab(index)
        widget.deleteLater()
        # Auto hide tab bar, when no. of tab widget is one
        if self.tabWidget.count()==1:
            self.tabWidget.tabBar().hide()

    def closeRequestedTab(self):
        """ Close tab requested by the page """
        webview = self.sender().view()
        index = self.tabWidget.indexOf(webview)
        self.closeTab(index)

    def Enter(self): 
        url = self.line.text()
        if url == 'about:home':
            self.goToHome()
        else:
            self.GoTo(url)

    def GoTo(self, url):
        URL = QUrl.fromUserInput(url)
        self.tabWidget.currentWidget().openLink(URL)
        self.line.setText(url)
        self.tabWidget.currentWidget().setFocus()

    def goToHome(self):
        self.GoTo(homepage)
        loop = QEventLoop()
        QTimer.singleShot(10, loop.quit)
        loop.exec_()
        document = self.tabWidget.currentWidget().page().mainFrame().documentElement()
        gallery = document.findFirst('div')
        for i, fav in enumerate(self.favourites):
            title, url, img = fav[0], fav[1], thumbnails_dir+fav[2]
            child = '<div class="photo"> <a href="{}"><img src="{}"></a><div class="desc">{}</div></div>'.format(url, img, title)
            gallery.appendInside(child)

    def onLoadStart(self):
        webview = self.sender()
        if webview is self.tabWidget.currentWidget():
          self.reload.setIcon(QIcon(":/stop.png"))

    def onProgress(self, progress):
        webview = self.sender()
        if webview is self.tabWidget.currentWidget() and webview.loading:
            self.pbar.setValue(progress)

    def onLoadFinish(self, ok):
        webview = self.sender()
        if webview is self.tabWidget.currentWidget():
          self.reload.setIcon(QIcon(":/refresh.png"))
          self.pbar.reset()
          url = self.line.text()
          self.handleVideoButton(url)

    def onTabSwitch(self, index):
        """ Updates urlbox, refresh icon, progress bar on switching tab"""
        webview = self.tabWidget.currentWidget()
        if webview.loading == True:
            self.reload.setIcon(QIcon(":/stop.png"))
            self.pbar.setValue(webview.progressVal)
        else:
            self.reload.setIcon(QIcon(":/refresh.png"))
            self.pbar.reset()
        url =  webview.url().toString()
        if url == homepage : url = 'about:home'
        self.line.setText(url)
        self.statusbar.hide()
        self.onIconChange(webview)
        self.handleVideoButton(url)

    def onUrlChange(self,url):
        url = url.toString()
        if url == homepage : url = 'about:home'
        webview = self.sender()
        if webview is self.tabWidget.currentWidget():
            self.line.setText(url)
            self.onIconChange(webview)
            self.handleVideoButton(url)

    def onTitleChange(self, title):
        webview = self.sender()
        index = self.tabWidget.indexOf(webview)
        if not title == '':
            self.tabWidget.tabBar().setTabText(index, title)
            url = webview.url().toString()
            for item in self.history:  # Removes the old item, inserts new same item on the top
                if url == item[1]:
                    self.history.remove(item)
            self.history.insert(0, [title, url])

    def onIconChange(self, webview=None):
        if not webview:
            webview = self.sender()
        icon = webview.icon()
        if icon.isNull():
            icon = QIcon(':/quartz.png')
        if webview is self.tabWidget.currentWidget():
            self.line.setIcon(icon)
        index = self.tabWidget.indexOf(webview)
        self.tabWidget.setTabIcon(index, icon)

    def onLinkHover(self, url):
        if url=="":
            self.statusbar.hide()
            return
        self.statusbar.setText(url)
        self.statusbar.adjustSize()
        self.statusbar.show()
        self.statusbar.move(QPoint(0, self.height()-self.statusbar.height()))

    def Back(self): 
        self.tabWidget.currentWidget().back() 
    def Forward(self): 
        self.tabWidget.currentWidget().forward()
    def Reload(self):
        if self.tabWidget.currentWidget().loading:
            self.tabWidget.currentWidget().stop()
        else:
            if self.line.text() == 'about:home':
                self.goToHome()
            else:
                self.tabWidget.currentWidget().reload()

    def urlsuggestions(self, text):
        """ Creates the list of url suggestions for URL box """
        suggestions = []
        if not webkit.find_mode_on:
            for [title, url] in self.history:
                if text in url:
                    suggestions.insert(0, url)
            for [title, address] in self.bookmarks:
                if text in address:
                    suggestions.insert(0, address)
        self.listmodel.setStringList( suggestions )

    def handleVideoButton(self, url):
        if youtube.validYoutubeUrl(url):
            self.videoDownloadButton.show()
            return
        frames = [self.tabWidget.currentWidget().page().mainFrame()]
        frames += frames[0].childFrames()
        for frame in frames:
            video = frame.findFirstElement('video')
            if not video.isNull():
                self.videoDownloadButton.show()
                return
        self.videoDownloadButton.hide()


##################### Downloading and Printing  ########################
    def download_requested_file(self, networkrequest):
        """ Gets called when the page requests a file to be downloaded """
        reply = networkmanager.get(networkrequest)
        self.handleUnsupportedContent(reply)

    def handleUnsupportedContent(self, reply, preset_filename=None, page_url=None):
        """ This is called when url content is a downloadable file. e.g- pdf,mp3,mp4 """
        if reply.rawHeaderList() == []:
            loop = QEventLoop()
            reply.metaDataChanged.connect(loop.quit)
            QTimer.singleShot(5000, loop.quit)
            loop.exec_()
        if reply.hasRawHeader(b'Location'):
            URL = QUrl.fromUserInput(str_(reply.rawHeader(b'Location')))
            reply.abort()
            reply = networkmanager.get(QNetworkRequest(URL))
            self.handleUnsupportedContent(reply, preset_filename)
            return
        for (title, header) in reply.rawHeaderPairs():
            print( str_(title) + "-> " + str_(header) )
        # copy url to clipboard
        QApplication.clipboard().setText(reply.url().toString())
        # Get filename and mimetype
        mimetype = None
        if reply.hasRawHeader(b'Content-Type'):
            mimetype = str_(reply.rawHeader(b'Content-Type')).split(';')[0] # eg - audio/mpeg; name=""
        content_name = str_(reply.rawHeader(b'Content-Disposition'))
        if preset_filename:
            filename = preset_filename
        else:
            filename = filenameFromHeader(content_name)
            if filename == '':
                filename = filenameFromUrl(reply.url().toString())
        filename = validateFileName(filename, mimetype)
        # Create downld Confirmation dialog
        dlDialog = DownloadDialog(self)
        dlDialog.filenameEdit.setText(filename)
        # Get filesize
        if reply.hasRawHeader(b'Content-Length'):
            filesize = reply.header(1)
            if filesize >= 1048576 :
                file_size = "{} M".format(round(float(filesize)/1048576, 2))
            elif 1023 < filesize < 1048576 :
                file_size = "{} k".format(round(float(filesize)/1024, 1))
            else:
                file_size = "{} B".format(filesize)
            dlDialog.labelFileSize.setText(file_size)
        # Get filetype and resume support info
        if mimetype:
            dlDialog.labelFileType.setText(mimetype)
        if reply.hasRawHeader(b'Accept-Ranges') or reply.hasRawHeader(b'Content-Range'):
            dlDialog.labelResume.setText("True")
        # Execute dialog and show confirmation
        if dlDialog.exec_()== QDialog.Accepted:
            filepath = dlDialog.folder + dlDialog.filenameEdit.text()
            url = reply.url().toString()
            if self.useexternaldownloader:
                download_externally(url, self.externaldownloader)
                reply.abort()
                reply.deleteLater()
                return

            global downloads_list_file
            newdownload = Download(networkmanager, page_url)
            newdownload.startDownload(reply, filepath)
            newdownload.datachanged.connect(self.dwnldsmodel.datachanged)
            self.downloads.insert(0, newdownload)
            imported_downloads = importDownloads(downloads_list_file)
            imported_downloads.insert(0, [filepath, url, str(newdownload.totalsize), newdownload.timestamp])
            exportDownloads(downloads_list_file, imported_downloads)
        else:
            reply.abort()
            reply.deleteLater()

    def download_manager(self):
        """ Opens download manager dialog """
        dialog = QDialog(self)
        downloads_dialog = Downloads_Dialog()
        downloads_dialog.setupUi(dialog, self.dwnldsmodel)
        dialog.exec_()

    def deleteDownloads(self, timestamps):
        global downloads_list_file
        imported_downloads = importDownloads(downloads_list_file)
        exported_downloads = []
        for download in imported_downloads:
            if download[-1] not in timestamps:
                exported_downloads.append(download)
        exportDownloads(downloads_list_file, exported_downloads)

    def downloadVideo(self):
        url = self.tabWidget.currentWidget().url().toString()
        # For youtube videos, parse youtube links in separate thread
        if youtube.validYoutubeUrl(url):
            vid_id = parse_qs(urlparse(url).query)['v'][0]
            ytThread = youtube.YoutubeThread(self)
            ytThread.ytParseFailed.connect(self.onYtParseFail)
            ytThread.ytVideoParsed.connect(self.onYtVideoParse)
            ytThread.finished.connect(ytThread.deleteLater)
            ytThread.vid_id = vid_id
            ytThread.start()
            return
        # For embeded HTML5 videos
        self.getVideos()

    def onYtVideoParse(self, videos):
        dialog = youtube.YoutubeDialog(videos, self)
        if dialog.exec_() == 1 :
            index = abs(dialog.buttonGroup.checkedId())-2
            vid = videos[index]
            reply = networkmanager.get( QNetworkRequest(QUrl.fromUserInput(vid.url)) )
            self.handleUnsupportedContent(reply, vid.filename + '.' + vid.extension)

    def onYtParseFail(self):
        # Show error on fail to parse youtube
        QMessageBox.warning(self, "Download Failed !","This Video can not be downloaded")

    def getVideos(self):
        dialog = youtube.Media_Dialog(self, self.tabWidget.currentWidget().page(), networkmanager)
        dialog.downloadRequested.connect(self.handleUnsupportedContent)
        dialog.exec_()

    def saveAsImage(self):
        """ Saves the whole page as PNG/JPG image"""
        title = self.tabWidget.currentWidget().page().mainFrame().title()
        title == validateFileName(title)
        filename = QFileDialog.getSaveFileName(self,
                                      "Select Image to Save", downloaddir + title +".jpg",
                                      "JPEG Image (*.jpg);;PNG Image (*.png)" )[0]
        if filename == '': return
        viewportsize = self.tabWidget.currentWidget().page().viewportSize()
        contentsize = self.tabWidget.currentWidget().page().mainFrame().contentsSize()
        self.tabWidget.currentWidget().page().setViewportSize(contentsize)
        img = QPixmap(contentsize)
        painter = QPainter(img)
        self.tabWidget.currentWidget().page().mainFrame().render(painter)
        painter.end()
        if img.save(filename):
            QMessageBox.information(self, "Successful !","Page has been successfully saved as\n"+filename)
        else:
            QMessageBox.warning(self, "Saving Failed !","Exporting page to Image hasbeen failed")
        self.tabWidget.currentWidget().page().setViewportSize(viewportsize)

    def saveashtml(self):
        """ Saves current page as HTML , bt does not saves any content (e.g images)"""
        title = self.tabWidget.currentWidget().page().mainFrame().title()
        title = validateFileName(title)
        filename = QFileDialog.getSaveFileName(self,
                                "Enter HTML File Name", downloaddir + title +".html",
                                "HTML Document (*.html)" )[0]
        if filename == '': return
        #html = self.tabWidget.currentWidget().page().mainFrame().toHtml()
        page_URL = self.tabWidget.currentWidget().url()
        useragent = self.tabWidget.currentWidget().page().userAgentForUrl(page_URL)
        doc = self.tabWidget.currentWidget().page().mainFrame().documentElement().clone()
        #doc.setInnerXml(html)
        SaveAsHtml(networkmanager, doc, filename, page_URL, useragent)

    def printpage(self, page=None):
        """ Prints current/requested page """
        if not page:
            page = self.tabWidget.currentWidget().page().currentFrame()
        printer = QPrinter(QPrinter.HighResolution)
        printer.setPaperSize(QPrinter.A4)
        printer.setPageSize(QPrinter.A4)
        printer.setColorMode(QPrinter.Color)
        printer.setCreator("Quartz Browser")
        title = self.tabWidget.currentWidget().page().mainFrame().title()
        title = validateFileName(title)
        printer.setDocName(title)
        printer.setOutputFileName(docdir + title + ".pdf")
        #printer.setOutputFormat(QPrinter.PdfFormat)
        print_dialog = QPrintPreviewDialog(printer, self)
        print_dialog.paintRequested.connect(page.print_)
        print_dialog.exec_()

##################################################################################################
    def addToFavourites(self):
        dialog = QDialog(self)
        addbmkdialog = Add_Bookmark_Dialog()
        addbmkdialog.setupUi(dialog)
        dialog.setWindowTitle('Add to HomePage')
        addbmkdialog.titleEdit.setMaxLength(31)
        addbmkdialog.titleEdit.setText(self.tabWidget.currentWidget().page().mainFrame().title())
        addbmkdialog.addressEdit.setText(self.line.text())
        if (dialog.exec_() == QDialog.Accepted):
            title = addbmkdialog.titleEdit.text()
            addr = addbmkdialog.addressEdit.text()
            imgfile = str(time.time()) + '.jpg'
            viewportsize = self.tabWidget.currentWidget().page().viewportSize()
            contentsize = QSize(640, 640)
            self.tabWidget.currentWidget().page().setViewportSize(contentsize)
            img = QPixmap(contentsize)
            painter = QPainter(img)
            self.tabWidget.currentWidget().page().mainFrame().render(painter, QWebFrame.AllLayers)
            painter.end()
            self.tabWidget.currentWidget().page().setViewportSize(viewportsize)
            icon = img.scaledToWidth(184, 1).copy(0,0, 180, 120)
            icon.save(thumbnails_dir + imgfile)
            self.favourites = importFavourites(configdir + 'favourites.txt')
            self.favourites.append([title, addr, imgfile])
            exportFavourites(configdir + 'favourites.txt', self.favourites)

    def addbookmark(self):
        """ Opens add bookmark dialog and gets url from url box"""
        dialog = QDialog(self)
        addbmkdialog = Add_Bookmark_Dialog()
        addbmkdialog.setupUi(dialog)
        addbmkdialog.titleEdit.setText(self.tabWidget.currentWidget().page().mainFrame().title())
        addbmkdialog.addressEdit.setText(self.line.text())
        if (dialog.exec_() == QDialog.Accepted):
            url = addbmkdialog.addressEdit.text()
            bmk = [addbmkdialog.titleEdit.text(), url]
            self.bookmarks = importBookmarks(configdir+"bookmarks.txt")
            self.bookmarks.insert(0, bmk)
            exportBookmarks(configdir+"bookmarks.txt", self.bookmarks)
            icon = self.tabWidget.currentWidget().icon()
            if not icon.isNull():
                icon.pixmap(16, 16).save(icon_dir + url.split('/')[2] + '.png')

    def managebookmarks(self):
        """ Opens Bookmarks dialog """
        dialog = QDialog(self)
        bmk_dialog = Bookmarks_Dialog()
        bmk_dialog.setupUi(dialog, self.bookmarks, self.favourites)
        bmk_dialog.bookmarks_table.doubleclicked.connect(self.GoTo)
        bmk_dialog.favs_table.doubleclicked.connect(self.GoTo)
        dialog.exec_()
        if bmk_dialog.bookmarks_table.data_changed:
            self.bookmarks = bmk_dialog.bookmarks_table.data
            exportBookmarks(configdir+"bookmarks.txt", self.bookmarks)
        if bmk_dialog.favs_table.data_changed:
            self.favourites = bmk_dialog.favs_table.data
            exportFavourites(configdir+"favourites.txt", self.favourites)

    def viewhistory(self):
        """ Open history dialog """
        dialog = QDialog(self)
        history_dialog = History_Dialog()
        history_dialog.setupUi(dialog, self.history)
        history_dialog.tableView.doubleclicked.connect(self.GoTo)
        dialog.exec_()

    def findmode(self):
        """ Starts find mode and unhides find buttons"""
        webkit.find_mode_on = True
        self.line.clear()
        self.find.show()
        self.findprev.show()
        self.cancelfind.show()
        self.line.setFocus()
    def cancelfindmode(self):
        """ Hides the find buttons, updates urlbox"""
        webkit.find_mode_on = False
        self.tabWidget.currentWidget().findText("")
        self.find.hide()
        self.findprev.hide()
        self.cancelfind.hide()
        self.line.setText(self.tabWidget.currentWidget().url().toString())
    def findnext(self):
        text = self.line.text()
        self.tabWidget.currentWidget().findText(text)
    def findback(self):
        text = self.line.text()
        self.tabWidget.currentWidget().findText(text, QWebPage.FindBackward)

#####################  View Settings  ###################
    def zoomin(self):
        zoomlevel = self.tabWidget.currentWidget().zoomFactor()
        self.tabWidget.currentWidget().setZoomFactor(zoomlevel+0.1) # Use setZoomFactor() to zoom text and images
    def zoomout(self):
        zoomlevel = self.tabWidget.currentWidget().zoomFactor()
        self.tabWidget.currentWidget().setZoomFactor(zoomlevel-0.1)
    def fullscreenmode(self):
        if self.isFullScreen():
            self.showNormal()
        else:
            self.showFullScreen()

    def loadimages(self, state):
        """ TOggles image loading on/off"""
        self.websettings.setAttribute(QWebSettings.AutoLoadImages, state)
        self.loadimagesval = bool(state)

    def setjavascript(self, state):
        """ Toggles js on/off """
        self.websettings.setAttribute(QWebSettings.JavascriptEnabled, state)
        self.javascriptenabledval = bool(state)

    def setUserAgentDesktop(self, checked):
        if bool(checked):
            webkit.useragent_mode = 'Desktop'
            self.useragent_mode_mobile.setChecked(False)
            self.useragent_mode_custom.setChecked(False)

    def setUserAgentMobile(self, checked):
        if bool(checked):
            webkit.useragent_mode = 'Mobile'
            self.useragent_mode_desktop.setChecked(False)
            self.useragent_mode_custom.setChecked(False)

    def setUserAgentCustom(self, checked):
        if bool(checked):
            webkit.useragent_mode = 'Custom'
            self.useragent_mode_mobile.setChecked(False)
            self.useragent_mode_desktop.setChecked(False)

########################## Settings Portion #########################
    def settingseditor(self):  
        """ Opens the settings manager dialog, then applies the change"""
        dialog = QDialog(self)
        websettingsdialog = Ui_SettingsDialog()
        websettingsdialog.setupUi(dialog)
        # Enable AdBlock
        websettingsdialog.checkAdBlock.setChecked(webkit.enable_adblock)
        # Fonts blocking
        websettingsdialog.checkFontLoad.setChecked(webkit.block_fonts)
        # Popups blocking
        websettingsdialog.checkBlockPopups.setChecked(webkit.block_popups)
        # Custom user agent
        websettingsdialog.useragentEdit.setText(webkit.useragent_custom)
        # External download manager
        websettingsdialog.checkDownMan.setChecked(self.useexternaldownloader)
        websettingsdialog.downManEdit.setText(self.externaldownloader)
        # RTSP media player command
        websettingsdialog.mediaPlayerEdit.setText(webkit.video_player_command)
        websettingsdialog.mediaPlayerEdit.setCursorPosition(0)
        # Font settings
        websettingsdialog.spinFontSize.setValue(self.minfontsizeval)
        websettingsdialog.standardfontCombo.setCurrentFont(QFont(self.standardfontval))
        websettingsdialog.sansfontCombo.setCurrentFont(QFont(self.sansfontval))
        websettingsdialog.seriffontCombo.setCurrentFont(QFont(self.seriffontval))
        websettingsdialog.fixedfontCombo.setCurrentFont(QFont(self.fixedfontval))
        # Clear Data buttons
        websettingsdialog.clearCacheButton.clicked.connect(self.websettings.clearMemoryCaches)
        websettingsdialog.cookiesButton.clicked.connect(cookiejar.clearCookies)
        websettingsdialog.iconDBButton.clicked.connect(self.websettings.clearIconDatabase)

        if dialog.exec_() == QDialog.Accepted:
            # Enable AdBlock
            webkit.enable_adblock = websettingsdialog.checkAdBlock.isChecked()
            # Block Fonts
            webkit.block_fonts = websettingsdialog.checkFontLoad.isChecked()
            # Block Popups
            webkit.block_popups = websettingsdialog.checkBlockPopups.isChecked()
            # User Agent
            webkit.useragent_custom = websettingsdialog.useragentEdit.text()
            # Download Manager
            self.useexternaldownloader = websettingsdialog.checkDownMan.isChecked()
            self.externaldownloader = websettingsdialog.downManEdit.text()
            # Media Player Command
            webkit.video_player_command = websettingsdialog.mediaPlayerEdit.text()

            self.minfontsizeval = websettingsdialog.spinFontSize.value()
            self.standardfontval = websettingsdialog.standardfontCombo.currentText()
            self.sansfontval = websettingsdialog.sansfontCombo.currentText()
            self.seriffontval = websettingsdialog.seriffontCombo.currentText()
            self.fixedfontval = websettingsdialog.fixedfontCombo.currentText()
            self.applysettings()
            self.savesettings()

    def opensettings(self): 
        """ Reads settings file in ~/.config/quartz-browser/ directory and
            saves values in settings variables"""
        webkit.enable_adblock = _bool(self.settings.value('EnableAdblock', True))
        self.loadimagesval = _bool(self.settings.value('LoadImages', True))
        self.javascriptenabledval = _bool(self.settings.value('JavaScriptEnabled', True))
        webkit.block_fonts = _bool(self.settings.value('BlockFontLoading', False))
        webkit.block_popups = _bool(self.settings.value('BlockPopups', False))
        webkit.useragent_mode = self.settings.value('UserAgentMode', webkit.useragent_mode)
        webkit.useragent_custom = self.settings.value('UserAgent', webkit.useragent_custom)
        self.useexternaldownloader = _bool(self.settings.value('UseExternalDownloader', False))
        self.externaldownloader = self.settings.value('ExternalDownloader', "x-terminal-emulator wget -c %u")
        webkit.video_player_command = self.settings.value('MediaPlayerCommand', webkit.video_player_command)
        self.maximize_window = _bool(self.settings.value('MaximizeWindow', False))
        self.minfontsizeval = int(self.settings.value('MinFontSize', 11))
        self.standardfontval = self.settings.value('StandardFont', 'Sans')
        self.sansfontval = self.settings.value('SansFont', 'Sans')
        self.seriffontval = self.settings.value('SerifFont', 'Serif')
        self.fixedfontval = self.settings.value('FixedFont', 'Monospace')

    def savesettings(self):
        """ Writes setings to disk in ~/.config/quartz-browser/ directory"""
        self.settings.setValue('EnableAdblock', webkit.enable_adblock)
        self.settings.setValue('LoadImages', self.loadimagesval)
        self.settings.setValue('JavaScriptEnabled', self.javascriptenabledval)
        self.settings.setValue('BlockFontLoading', webkit.block_fonts)
        self.settings.setValue('BlockPopups', webkit.block_popups)
        self.settings.setValue('UserAgent', webkit.useragent_custom)
        self.settings.setValue('UserAgentMode', webkit.useragent_mode)
        self.settings.setValue('UseExternalDownloader', self.useexternaldownloader)
        self.settings.setValue('ExternalDownloader', self.externaldownloader)
        self.settings.setValue('MediaPlayerCommand', webkit.video_player_command)
        self.settings.setValue('MaximizeWindow', self.isMaximized())
        self.settings.setValue('MinFontSize', self.minfontsizeval)
        self.settings.setValue('StandardFont', self.standardfontval)
        self.settings.setValue('SansFont', self.sansfontval)
        self.settings.setValue('SerifFont', self.seriffontval)
        self.settings.setValue('FixedFont', self.fixedfontval)

    def applysettings(self):
        """ Reads settings variables, and changes browser settings.This is run after
            changing settings by Settings Dialog"""
        if webkit.enable_adblock:
            self.websettings.setUserStyleSheetUrl(QUrl.fromLocalFile(program_dir + 'userContent.css'))
        else:
            self.websettings.setUserStyleSheetUrl(QUrl(''))
        self.websettings.setAttribute(QWebSettings.AutoLoadImages, self.loadimagesval)
        self.loadimagesaction.setChecked(self.loadimagesval)
        self.websettings.setAttribute(QWebSettings.JavascriptEnabled, self.javascriptenabledval)
        self.javascriptmode.setChecked(self.javascriptenabledval)
        if webkit.useragent_mode == 'Mobile':
            self.useragent_mode_mobile.setChecked(True)
        elif webkit.useragent_mode == 'Custom':
            self.useragent_mode_custom.setChecked(True)
        else:
            self.useragent_mode_desktop.setChecked(True)
        self.websettings.setFontSize(QWebSettings.MinimumFontSize, self.minfontsizeval)
        self.websettings.setFontFamily(QWebSettings.StandardFont, self.standardfontval)
        self.websettings.setFontFamily(QWebSettings.SansSerifFont, self.sansfontval)
        self.websettings.setFontFamily(QWebSettings.SerifFont, self.seriffontval)
        self.websettings.setFontFamily(QWebSettings.FixedFont, self.fixedfontval)
#        self.websettings.setFontSize(QWebSettings.DefaultFontSize, 14)

    def enableKiosk(self):
        webkit.KIOSK_MODE = True
        self.menu.clear()
        self.toolBar.hide()
        self.showFullScreen()

    def forceClose(self):
        self.confirm_before_quit = False
        self.close()

    def closeEvent(self, event):
        """This saves all settings, bookmarks, cookies etc. during window close"""
        if self.confirm_before_quit:
            confirm = QMessageBox.warning(self, 'Quit Browser ?', 'Are you sure to close the Browser',
                                                QMessageBox.Yes|QMessageBox.No, QMessageBox.Yes)
            if confirm == QMessageBox.No :
                event.ignore()
                return
        self.savesettings()
        cookiejar.exportCookies()
        # Delete excess thumbnails
        thumbnails = [ x for x in os.listdir(thumbnails_dir) ]
        for fav in self.favourites:
            if fav[2] in thumbnails:
                thumbnails.remove(fav[2])
        for f in thumbnails: os.remove(thumbnails_dir + f)
        # Delete excess icons
        icons = [ x for x in os.listdir(icon_dir) if x.endswith('.png') ]
        for bmk in self.bookmarks:
            host = QUrl(bmk[1]).host()
            if host + '.png' in icons:
                icons.remove(host + '.png')
        for f in icons: os.remove( icon_dir + f )
        super(Main, self).closeEvent(event)
コード例 #27
0
class EditorMainWindow(QMainWindow):


    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.ui = Ui_ScriptEditor()
        self.ui.setupUi(self)
        #self.ui.actionExit.triggered.connect(self.exit)
        self.splitter = QSplitter(Qt.Vertical, self)
        self.setCentralWidget(self.splitter)
        self.edit_tab = QTabWidget(self.splitter)
        self.console_tab = QTabWidget(self.splitter)
        self.py_console = PythonConsole(self.console_tab)
        self.console_tab.addTab(self.py_console, "&Python console")
        self.js_console = QtQmlConsole(self.console_tab)
        self.console_tab.addTab(self.js_console, "&QtQml console")
        self.editors = []
        self.on_actionNewPython_triggered()

    @pyqtSlot()
    def closeEvent(self, event):
	while(self.editors.__len__()):
	    edit = self.edit_tab.currentWidget()
            if edit:
	        if(edit.isModified()):
		    saveBox = SaveDialog("You have unsaved script. Save it now?")
		    prompt = saveBox.exec_()
		    if(prompt == QMessageBox.Save):
			event.ignore()
		        self.save(True)
		    elif(prompt == QMessageBox.Cancel):
		        event.ignore()
			return
		    elif(prompt == QMessageBox.Discard):
		        event.accept()
                i = self.edit_tab.indexOf(edit)
                self.edit_tab.removeTab(i)
                self.editors.remove(edit)
	event.accept()

	

    @pyqtSlot()
    def on_actionExit_triggered(self):
	while(self.editors.__len__()):
	    edit = self.edit_tab.currentWidget()
            if edit:
	        if(edit.isModified()):
		    saveBox = SaveDialog("You have unsaved script. Save it now?")
		    prompt = saveBox.exec_()
		    if(prompt == QMessageBox.Save):
		        self.save(True)
		    elif(prompt == QMessageBox.Cancel):
		        return
		    elif(prompt == QMessageBox.Discard):
		        pass
		i = self.edit_tab.indexOf(edit)
                self.edit_tab.removeTab(i)
                self.editors.remove(edit)
	self.close()

    @pyqtSlot()
    def on_actionNewPython_triggered(self):
        pyedit = PythonEditorWidget(self.edit_tab)
        pyedit.setPlainText(template_py)
        self.edit_tab.addTab(pyedit, "Python")
        self.edit_tab.setCurrentWidget(pyedit)
        self.editors.append(pyedit)
        self.py_console.attach()
        self.console_tab.setCurrentIndex(0)
        pyedit.setFocus()
        pyedit.view.setFocus()


    @pyqtSlot()
    def on_actionNewQtQml_triggered(self):
        jsedit = QtQmlEditorWidget(self.edit_tab)
        self.edit_tab.addTab(jsedit, "QtQml")
        self.edit_tab.setCurrentWidget(jsedit)
        self.editors.append(jsedit)
        self.js_console.attach()
        self.console_tab.setCurrentIndex(1)


    @pyqtSlot()
    def on_actionClose_triggered(self):
        edit = self.edit_tab.currentWidget()
        if edit:
	    if(edit.isModified()):
		saveBox = SaveDialog("Do you want to save this Script?")
		prompt = saveBox.exec_()
		if(prompt == QMessageBox.Save):
		    self.save(True)
		elif(prompt == QMessageBox.Cancel):
		    return
		elif(prompt == QMessageBox.Discard):
		    pass
            i = self.edit_tab.indexOf(edit)
            self.edit_tab.removeTab(i)
            self.editors.remove(edit)

        
    @pyqtSlot()
    def on_actionClear_triggered(self):
        #edit = self.edit_tab.currentWidget()
	#edit.setPlainText(template_py)
	self.py_console.clear()


    @pyqtSlot()
    def on_actionSave_As_triggered(self):
	self.save()


    @pyqtSlot()
    def on_actionSave_triggered(self):
	self.save(True)


    #Path of the script file in each tab will be stored in tabToolTip
    def save(self, Update = False):
        edit = self.edit_tab.currentWidget()
	contents = str(edit.toPlainText())
	if((Update == False) or (self.edit_tab.tabText(self.edit_tab.currentIndex()) == "Python") ):
	    #Save in its first invocation and Save As will enter  
	    filename = QFileDialog.getSaveFileName(self, "Save File", "", "*.spy")
	    fil = open(filename , 'w')
	    if(filename and self.edit_tab.tabText(self.edit_tab.currentIndex()) == "Python"):
		#Script hasn't been saved before and user specifies a valid filename
	        self.edit_tab.setTabToolTip(self.edit_tab.currentIndex(), filename+'.spy')
	        self.edit_tab.setTabText(self.edit_tab.currentIndex(), os.path.basename(str(filename+'.spy')))
	else:
	    #filename = self.edit_tab.tabText(self.edit_tab.currentIndex())
	    filename = self.edit_tab.tabToolTip(self.edit_tab.currentIndex())
	    fil = open( filename , 'w')
	fil.write(contents)	
	fil.close()
	edit.setModified(False)


    @pyqtSlot()
    def on_actionOpen_triggered(self):
	filename = QFileDialog.getOpenFileName(self,"Open File","","*.spy")
	try:
	    fil = open(filename , 'r')
	except IOError:
	    return
	code = fil.read()
	edit = self.edit_tab.currentWidget()
	self.edit_tab.setTabText(self.edit_tab.currentIndex(), os.path.basename(str(filename)))
	self.edit_tab.setTabToolTip(self.edit_tab.currentIndex(), filename)
	edit.setPlainText(code)
	fil.close()


    @pyqtSlot()
    def on_actionRun_triggered(self):
        self.run()


    @pyqtSlot()
    def on_actionRunConsole_triggered(self):
        self.run(True)


    def run(self, console=False):
        edit = self.edit_tab.currentWidget()
        code = str(edit.toPlainText())
        if isinstance(edit, PythonEditorWidget):
            self.py_console.attach()
            self.console_tab.setCurrentIndex(0)
            if console:
                namespace = self.py_console.namespace
            else:
                namespace = {}
            try:
                exec code in namespace
            except Exception as e:
                traceback.print_exc()
            try:
                Scripter.activeWindow.redraw = True
                Scripter.activeWindow.update()
            except: pass
        else:
            self.js_console.attach()
            self.console_tab.setCurrentIndex(1)
            if console:
                self.js_console.inter.execute(code)
            else:
                self.js_console.inter.execute_code(code)
コード例 #28
0
ファイル: dialog.py プロジェクト: 19joho66/frescobaldi
class ScoreWizardDialog(QDialog):

    pitchLanguageChanged = pyqtSignal(str)

    def __init__(self, mainwindow):
        super(ScoreWizardDialog, self).__init__(mainwindow)
        self.addAction(mainwindow.actionCollection.help_whatsthis)
        self._pitchLanguage = None

        layout = QVBoxLayout()
        self.setLayout(layout)

        self.tabs = QTabWidget()
        b = self.dialogButtons = QDialogButtonBox()
        b.setStandardButtons(
            QDialogButtonBox.Reset
            | QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        b.accepted.connect(self.accept)
        b.rejected.connect(self.reject)
        userguide.addButton(b, "scorewiz")
        b.button(QDialogButtonBox.Reset).clicked.connect(self.reset)
        self.previewButton = b.addButton('', QDialogButtonBox.ActionRole)
        self.previewButton.clicked.connect(self.showPreview)
        layout.addWidget(self.tabs)
        layout.addWidget(b)

        self.header = Header(self)
        self.tabs.addTab(self.header, '')
        self.parts = Parts(self)
        self.tabs.addTab(self.parts, '')
        self.settings = Settings(self)
        self.tabs.addTab(self.settings, '')

        self.tabs.setCurrentIndex(0)
        self.tabs.widget(0).widget() # activate it
        self.tabs.currentChanged.connect(self.slotCurrentChanged)
        qutil.saveDialogSize(self, "scorewiz/dialog/size")
        app.translateUI(self)
        self.accepted.connect(self.slotAccepted)

    def translateUI(self):
        self.setWindowTitle(app.caption(_("Score Setup Wizard")))
        for i in range(self.tabs.count()):
            self.tabs.setTabText(i, self.tabs.widget(i).title())
        self.dialogButtons.button(QDialogButtonBox.Reset).setText(_("Clear"))
        self.dialogButtons.button(QDialogButtonBox.Reset).setToolTip(_(
            "Clears the current page of the Score Wizard."))
        self.previewButton.setText(_("Preview"))

    def slotCurrentChanged(self, i):
        """Lazy-loads the tab's page if shown for the first time."""
        self.tabs.widget(i).widget()

    def reset(self):
        self.tabs.currentWidget().widget().clear()

    def setPitchLanguage(self, language):
        if language != self._pitchLanguage:
            self._pitchLanguage = language
            self.pitchLanguageChanged.emit(language)

    def pitchLanguage(self):
        if self._pitchLanguage is None:
            # load setting; saving occurs in .settings.py
            lang = QSettings().value('scorewiz/lilypond/pitch_language', '', str)
            from .scoreproperties import keyNames
            if lang not in keyNames:
                lang = ''
            self._pitchLanguage = lang
        return self._pitchLanguage

    def slotAccepted(self):
        """Makes the score and puts it in the editor."""
        from . import build
        builder = build.Builder(self)       # get the builder
        text = builder.text()               # get the source text
        lydoc = ly.document.Document(text)  # temporarily store it in a lydoc
        cursor = ly.document.Cursor(lydoc)  # make a cursor selecting it
        indent.indenter().indent(cursor)    # indent it according to user prefs
        doc = app.openUrl(QUrl())           # get a new Frescobaldi document
        doc.setPlainText(lydoc.plaintext()) # write the text in it
        doc.setModified(False)              # make it "not modified"
        self.parent().setCurrentDocument(doc)

    def showPreview(self):
        """Shows a preview."""
        # get the document and fill in some example music
        from . import preview, build
        builder = build.Builder(self)
        doc = builder.document()
        preview.examplify(doc)
        # preview it
        import musicpreview
        dlg = musicpreview.MusicPreviewDialog(self)
        dlg.preview(builder.text(doc), _("Score Preview"))
        dlg.exec_()
        dlg.cleanup()
コード例 #29
0
class PreferencesDialogBase(QDialog):
    def __init__(self, parent, app, **kwargs):
        flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint
        super().__init__(parent, flags, **kwargs)
        self.app = app
        all_languages = get_langnames()
        self.supportedLanguages = sorted(SUPPORTED_LANGUAGES,
                                         key=lambda lang: all_languages[lang])
        self._setupUi()

        self.filterHardnessSlider.valueChanged["int"].connect(
            self.filterHardnessLabel.setNum)
        self.buttonBox.clicked.connect(self.buttonClicked)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)

    def _setupFilterHardnessBox(self):
        self.filterHardnessHLayout = QHBoxLayout()
        self.filterHardnessLabel = QLabel(self)
        self.filterHardnessLabel.setText(tr("Filter Hardness:"))
        self.filterHardnessLabel.setMinimumSize(QSize(0, 0))
        self.filterHardnessHLayout.addWidget(self.filterHardnessLabel)
        self.filterHardnessVLayout = QVBoxLayout()
        self.filterHardnessVLayout.setSpacing(0)
        self.filterHardnessHLayoutSub1 = QHBoxLayout()
        self.filterHardnessHLayoutSub1.setSpacing(12)
        self.filterHardnessSlider = QSlider(self)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.filterHardnessSlider.sizePolicy().hasHeightForWidth())
        self.filterHardnessSlider.setSizePolicy(sizePolicy)
        self.filterHardnessSlider.setMinimum(1)
        self.filterHardnessSlider.setMaximum(100)
        self.filterHardnessSlider.setTracking(True)
        self.filterHardnessSlider.setOrientation(Qt.Horizontal)
        self.filterHardnessHLayoutSub1.addWidget(self.filterHardnessSlider)
        self.filterHardnessLabel = QLabel(self)
        self.filterHardnessLabel.setText("100")
        self.filterHardnessLabel.setMinimumSize(QSize(21, 0))
        self.filterHardnessHLayoutSub1.addWidget(self.filterHardnessLabel)
        self.filterHardnessVLayout.addLayout(self.filterHardnessHLayoutSub1)
        self.filterHardnessHLayoutSub2 = QHBoxLayout()
        self.filterHardnessHLayoutSub2.setContentsMargins(-1, 0, -1, -1)
        self.moreResultsLabel = QLabel(self)
        self.moreResultsLabel.setText(tr("More Results"))
        self.filterHardnessHLayoutSub2.addWidget(self.moreResultsLabel)
        spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding,
                                 QSizePolicy.Minimum)
        self.filterHardnessHLayoutSub2.addItem(spacerItem)
        self.fewerResultsLabel = QLabel(self)
        self.fewerResultsLabel.setText(tr("Fewer Results"))
        self.filterHardnessHLayoutSub2.addWidget(self.fewerResultsLabel)
        self.filterHardnessVLayout.addLayout(self.filterHardnessHLayoutSub2)
        self.filterHardnessHLayout.addLayout(self.filterHardnessVLayout)

    def _setupBottomPart(self):
        # The bottom part of the pref panel is always the same in all editions.
        self.copyMoveLabel = QLabel(self)
        self.copyMoveLabel.setText(tr("Copy and Move:"))
        self.widgetsVLayout.addWidget(self.copyMoveLabel)
        self.copyMoveDestinationComboBox = QComboBox(self)
        self.copyMoveDestinationComboBox.addItem(tr("Right in destination"))
        self.copyMoveDestinationComboBox.addItem(tr("Recreate relative path"))
        self.copyMoveDestinationComboBox.addItem(tr("Recreate absolute path"))
        self.widgetsVLayout.addWidget(self.copyMoveDestinationComboBox)
        self.customCommandLabel = QLabel(self)
        self.customCommandLabel.setText(
            tr("Custom Command (arguments: %d for dupe, %r for ref):"))
        self.widgetsVLayout.addWidget(self.customCommandLabel)
        self.customCommandEdit = QLineEdit(self)
        self.widgetsVLayout.addWidget(self.customCommandEdit)

    def _setupDisplayPage(self):
        self.ui_groupbox = QGroupBox("&General Interface")
        layout = QVBoxLayout()
        self.languageLabel = QLabel(tr("Language:"), self)
        self.languageComboBox = QComboBox(self)
        for lang in self.supportedLanguages:
            self.languageComboBox.addItem(get_langnames()[lang])
        layout.addLayout(
            horizontalWrap([self.languageLabel, self.languageComboBox, None]))
        self._setupAddCheckbox(
            "tabs_default_pos",
            tr("Use default position for tab bar (requires restart)"))
        self.tabs_default_pos.setToolTip(
            tr("Place the tab bar below the main menu instead of next to it\n\
On MacOS, the tab bar will fill up the window's width instead."))
        layout.addWidget(self.tabs_default_pos)
        self.ui_groupbox.setLayout(layout)
        self.displayVLayout.addWidget(self.ui_groupbox)

        gridlayout = QFormLayout()
        result_groupbox = QGroupBox("&Result Table")
        self.fontSizeSpinBox = QSpinBox()
        self.fontSizeSpinBox.setMinimum(5)
        gridlayout.addRow(tr("Font size:"), self.fontSizeSpinBox)
        self._setupAddCheckbox("reference_bold_font",
                               tr("Use bold font for references"))
        gridlayout.addRow(self.reference_bold_font)

        self.result_table_ref_foreground_color = ColorPickerButton(self)
        gridlayout.addRow(tr("Reference foreground color:"),
                          self.result_table_ref_foreground_color)
        self.result_table_ref_background_color = ColorPickerButton(self)
        gridlayout.addRow(tr("Reference background color:"),
                          self.result_table_ref_background_color)
        self.result_table_delta_foreground_color = ColorPickerButton(self)
        gridlayout.addRow(tr("Delta foreground color:"),
                          self.result_table_delta_foreground_color)
        gridlayout.setLabelAlignment(Qt.AlignLeft)

        # Keep same vertical spacing as parent layout for consistency
        gridlayout.setVerticalSpacing(self.displayVLayout.spacing())
        result_groupbox.setLayout(gridlayout)
        self.displayVLayout.addWidget(result_groupbox)

        details_groupbox = QGroupBox("&Details Window")
        self.details_groupbox_layout = QVBoxLayout()
        self._setupAddCheckbox("details_dialog_titlebar_enabled",
                               tr("Show the title bar and can be docked"))
        self.details_dialog_titlebar_enabled.setToolTip(
            tr("While the title bar is hidden, \
use the modifier key to drag the floating window around") if ISLINUX else
            tr("The title bar can only be disabled while the window is docked"
               ))
        self.details_groupbox_layout.addWidget(
            self.details_dialog_titlebar_enabled)
        self._setupAddCheckbox("details_dialog_vertical_titlebar",
                               tr("Vertical title bar"))
        self.details_dialog_vertical_titlebar.setToolTip(
            tr("Change the title bar from horizontal on top, to vertical on the left side"
               ))
        self.details_groupbox_layout.addWidget(
            self.details_dialog_vertical_titlebar)
        self.details_dialog_vertical_titlebar.setEnabled(
            self.details_dialog_titlebar_enabled.isChecked())
        self.details_dialog_titlebar_enabled.stateChanged.connect(
            self.details_dialog_vertical_titlebar.setEnabled)
        gridlayout = QGridLayout()
        self.details_table_delta_foreground_color_label = QLabel(
            tr("Delta foreground color:"))
        gridlayout.addWidget(self.details_table_delta_foreground_color_label,
                             4, 0)
        self.details_table_delta_foreground_color = ColorPickerButton(self)
        gridlayout.addWidget(self.details_table_delta_foreground_color, 4, 2,
                             1, 1, Qt.AlignLeft)
        gridlayout.setColumnStretch(1, 1)
        gridlayout.setColumnStretch(3, 4)
        self.details_groupbox_layout.addLayout(gridlayout)
        details_groupbox.setLayout(self.details_groupbox_layout)
        self.displayVLayout.addWidget(details_groupbox)

    def _setupAddCheckbox(self, name, label, parent=None):
        if parent is None:
            parent = self
        cb = QCheckBox(parent)
        cb.setText(label)
        setattr(self, name, cb)

    def _setupPreferenceWidgets(self):
        # Edition-specific
        pass

    def _setupUi(self):
        self.setWindowTitle(tr("Options"))
        self.setSizeGripEnabled(False)
        self.setModal(True)
        self.mainVLayout = QVBoxLayout(self)
        self.tabwidget = QTabWidget()
        self.page_general = QWidget()
        self.page_display = QWidget()
        self.widgetsVLayout = QVBoxLayout()
        self.page_general.setLayout(self.widgetsVLayout)
        self.displayVLayout = QVBoxLayout()
        self.displayVLayout.setSpacing(
            5)  # arbitrary value, might conflict with style
        self.page_display.setLayout(self.displayVLayout)
        self._setupPreferenceWidgets()
        self._setupDisplayPage()
        # self.mainVLayout.addLayout(self.widgetsVLayout)
        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok
                                          | QDialogButtonBox.RestoreDefaults)
        self.mainVLayout.addWidget(self.tabwidget)
        self.mainVLayout.addWidget(self.buttonBox)
        self.layout().setSizeConstraint(QLayout.SetFixedSize)
        self.tabwidget.addTab(self.page_general, "General")
        self.tabwidget.addTab(self.page_display, "Display")
        self.displayVLayout.addStretch(0)
        self.widgetsVLayout.addStretch(0)

    def _load(self, prefs, setchecked, section):
        # Edition-specific
        pass

    def _save(self, prefs, ischecked):
        # Edition-specific
        pass

    def load(self, prefs=None, section=Sections.ALL):
        if prefs is None:
            prefs = self.app.prefs
        setchecked = lambda cb, b: cb.setCheckState(Qt.Checked
                                                    if b else Qt.Unchecked)
        if section & Sections.GENERAL:
            self.filterHardnessSlider.setValue(prefs.filter_hardness)
            self.filterHardnessLabel.setNum(prefs.filter_hardness)
            setchecked(self.mixFileKindBox, prefs.mix_file_kind)
            setchecked(self.useRegexpBox, prefs.use_regexp)
            setchecked(self.removeEmptyFoldersBox, prefs.remove_empty_folders)
            setchecked(self.ignoreHardlinkMatches,
                       prefs.ignore_hardlink_matches)
            setchecked(self.debugModeBox, prefs.debug_mode)
            self.copyMoveDestinationComboBox.setCurrentIndex(
                prefs.destination_type)
            self.customCommandEdit.setText(prefs.custom_command)
        if section & Sections.DISPLAY:
            setchecked(self.reference_bold_font, prefs.reference_bold_font)
            setchecked(self.tabs_default_pos, prefs.tabs_default_pos)
            setchecked(self.details_dialog_titlebar_enabled,
                       prefs.details_dialog_titlebar_enabled)
            setchecked(self.details_dialog_vertical_titlebar,
                       prefs.details_dialog_vertical_titlebar)
            self.fontSizeSpinBox.setValue(prefs.tableFontSize)
            self.details_table_delta_foreground_color.setColor(
                prefs.details_table_delta_foreground_color)
            self.result_table_ref_foreground_color.setColor(
                prefs.result_table_ref_foreground_color)
            self.result_table_ref_background_color.setColor(
                prefs.result_table_ref_background_color)
            self.result_table_delta_foreground_color.setColor(
                prefs.result_table_delta_foreground_color)
            try:
                langindex = self.supportedLanguages.index(
                    self.app.prefs.language)
            except ValueError:
                langindex = 0
            self.languageComboBox.setCurrentIndex(langindex)
        self._load(prefs, setchecked, section)

    def save(self):
        prefs = self.app.prefs
        prefs.filter_hardness = self.filterHardnessSlider.value()
        ischecked = lambda cb: cb.checkState() == Qt.Checked
        prefs.mix_file_kind = ischecked(self.mixFileKindBox)
        prefs.use_regexp = ischecked(self.useRegexpBox)
        prefs.remove_empty_folders = ischecked(self.removeEmptyFoldersBox)
        prefs.ignore_hardlink_matches = ischecked(self.ignoreHardlinkMatches)
        prefs.debug_mode = ischecked(self.debugModeBox)
        prefs.reference_bold_font = ischecked(self.reference_bold_font)
        prefs.details_dialog_titlebar_enabled = ischecked(
            self.details_dialog_titlebar_enabled)
        prefs.details_dialog_vertical_titlebar = ischecked(
            self.details_dialog_vertical_titlebar)
        prefs.details_table_delta_foreground_color = self.details_table_delta_foreground_color.color
        prefs.result_table_ref_foreground_color = self.result_table_ref_foreground_color.color
        prefs.result_table_ref_background_color = self.result_table_ref_background_color.color
        prefs.result_table_delta_foreground_color = self.result_table_delta_foreground_color.color
        prefs.destination_type = self.copyMoveDestinationComboBox.currentIndex(
        )
        prefs.custom_command = str(self.customCommandEdit.text())
        prefs.tableFontSize = self.fontSizeSpinBox.value()
        prefs.tabs_default_pos = ischecked(self.tabs_default_pos)
        lang = self.supportedLanguages[self.languageComboBox.currentIndex()]
        oldlang = self.app.prefs.language
        if oldlang not in self.supportedLanguages:
            oldlang = "en"
        if lang != oldlang:
            QMessageBox.information(
                self,
                "",
                tr("dupeGuru has to restart for language changes to take effect."
                   ),
            )
        self.app.prefs.language = lang
        self._save(prefs, ischecked)

    def resetToDefaults(self, section_to_update):
        self.load(Preferences(), section_to_update)

    # --- Events
    def buttonClicked(self, button):
        role = self.buttonBox.buttonRole(button)
        if role == QDialogButtonBox.ResetRole:
            current_tab = self.tabwidget.currentWidget()
            section_to_update = Sections.ALL
            if current_tab is self.page_general:
                section_to_update = Sections.GENERAL
            if current_tab is self.page_display:
                section_to_update = Sections.DISPLAY
            self.resetToDefaults(section_to_update)
コード例 #30
0
class SimulatorWindow(QMainWindow):
    def __init__(self, argv):
        QMainWindow.__init__(self)
        self.setWindowTitle("SimSo: Real-Time Scheduling Simulator")

        # Possible actions:
        style = QApplication.style()

        # New
        self._newAction = QAction(
            style.standardIcon(QStyle.SP_FileDialogNewFolder), '&New', None)
        self._newAction.setShortcut(Qt.CTRL + Qt.Key_N)
        self._newAction.triggered.connect(self.fileNew)

        # Open
        self._openAction = QAction(
            style.standardIcon(QStyle.SP_DialogOpenButton), '&Open', None)
        self._openAction.setShortcut(Qt.CTRL + Qt.Key_O)
        self._openAction.triggered.connect(self.fileOpen)

        # Save
        self._saveAction = QAction(
            style.standardIcon(QStyle.SP_DialogSaveButton), '&Save', None)
        self._saveAction.setShortcut(Qt.CTRL + Qt.Key_S)
        self._saveAction.triggered.connect(self.fileSave)

        # Save As
        self._saveAsAction = QAction(
            style.standardIcon(QStyle.SP_DialogSaveButton), 'Save &As', None)
        self._saveAsAction.setShortcut(Qt.CTRL + Qt.SHIFT + Qt.Key_S)
        self._saveAsAction.triggered.connect(self.fileSaveAs)

        # Run
        self._runAction = QAction(
            style.standardIcon(QStyle.SP_MediaPlay), '&Run', None)
        self._runAction.setShortcut(Qt.CTRL + Qt.Key_R)
        self._runAction.triggered.connect(self.fileRun)

        # Show Model data
        self._modelAction = QAction('&Model data', None)
        self._modelAction.setShortcut(Qt.CTRL + Qt.Key_M)
        #self._ganttAction.setCheckable(True)
        self._modelAction.triggered.connect(self.showModelWindow)

        # Show Gantt
        self._ganttAction = QAction('&Gantt', None)
        self._ganttAction.setShortcut(Qt.CTRL + Qt.Key_G)
        self._ganttAction.setEnabled(False)
        #self._ganttAction.setCheckable(True)
        self._ganttAction.triggered.connect(self.showGantt)

        # Show Results
        self._metricsAction = QAction('&Results', None)
        self._metricsAction.setShortcut(Qt.CTRL + Qt.Key_I)
        self._metricsAction.setEnabled(False)
        #self._metricsAction.setCheckable(True)
        self._metricsAction.triggered.connect(self.showResults)

        # Show Doc
        self._docAction = QAction('&Documentation', None)
        self._docAction.triggered.connect(self.showDocumentation)

        self._aboutAction = QAction('&About SimSo', None)
        self._aboutAction.triggered.connect(self.showAbout)

        # Recent files
        self._recentFileActions = []
        for i in range(5):
            act = QAction(self)
            act.setVisible(False)
            act.triggered.connect(self.openRecentFile)
            self._recentFileActions.append(act)

        # File Menu:
        file_menu = QMenu('&File', self)
        file_menu.addAction(self._newAction)
        file_menu.addAction(self._openAction)
        file_menu.addAction(self._saveAction)
        file_menu.addAction(self._saveAsAction)
        file_menu.addAction(self._runAction)
        file_menu.addSeparator()
        for act in self._recentFileActions:
            file_menu.addAction(act)
        file_menu.addSeparator()
        file_menu.addAction('&Quit', self.fileQuit, Qt.CTRL + Qt.Key_Q)
        self.updateRecentFileActions()

        # View Menu:
        view_menu = QMenu('&View', self)
        view_menu.addAction(self._modelAction)
        view_menu.addAction(self._ganttAction)
        view_menu.addAction(self._metricsAction)

        # Help Menu:
        help_menu = QMenu('&Help', self)
        help_menu.addAction(self._docAction)
        help_menu.addAction(self._aboutAction)

        # Add menus to menuBar:
        self.menuBar().addMenu(file_menu)
        self.menuBar().addMenu(view_menu)
        self.menuBar().addMenu(help_menu)

        # ToolBar:
        self.toolBar = QToolBar("Main ToolBar")
        self.addToolBar(self.toolBar)
        self.toolBar.addAction(self._newAction)
        self.toolBar.addAction(self._openAction)
        self.toolBar.addAction(self._saveAction)
        self.toolBar.addAction(self._runAction)
        self.toolBar.addAction(self._ganttAction)
        self.toolBar.addAction(self._metricsAction)

        # Tab:
        self.main_tab = QTabWidget()
        self.main_tab.setTabsClosable(True)
        self.main_tab.setMovable(True)
        self.main_tab.tabCloseRequested.connect(self.tabCloseRequested)
        self.main_tab.currentChanged.connect(self.tabChanged)
        self.setCentralWidget(self.main_tab)

        # Init statusBar:
        self.statusBar().showMessage("", 2000)

        self._documentation = None

        if argv:
            for arg in argv:
                try:
                    self.open_file(arg)
                except Exception as e:
                    print(e)
        else:
            self.fileNew()

    def openRecentFile(self):
        try:
            self.open_file(self.sender().data().toString())
        except AttributeError:
            self.open_file(self.sender().data())

    def updateRecentFileActions(self):
        settings = QSettings()
        files = settings.value("recentFileList", defaultValue=[],
                               type='QString')
        for i in range(5):
            if i < len(files):
                text = "&{} {}".format(i + 1, QFileInfo(files[i]).fileName())
                self._recentFileActions[i].setText(text)
                self._recentFileActions[i].setData(files[i])
                self._recentFileActions[i].setVisible(True)
            else:
                self._recentFileActions[i].setVisible(False)

    def setCurrentFile(self, filename):
        filename = QFileInfo(filename).absoluteFilePath()
        settings = QSettings()
        files = settings.value("recentFileList", defaultValue=[],
                               type='QString')

        if filename in files:
            files.remove(filename)
        files.insert(0, filename)
        while len(files) > 5:
            del files[-1]

        settings.setValue("recentFileList", files)
        self.updateRecentFileActions()

    def showAbout(self):
        QMessageBox.about(
            self, "About SimSo",
            "<b>SimSo - Simulation of Multiprocessor Scheduling with Overheads</b><br/><br/>"
            "Version: SimSo {}, Graphical User Interface {}<br/><br/>"
            "SimSo is a free software developed by Maxime Cheramy (LAAS-CNRS).<br/>"
            "This software is distributed under the <a href='http://www.cecill.info'>CECILL license</a>, "
            "compatible with the GNU GPL.<br/><br/>"
            "Contact: <a href='mailto:[email protected]'>[email protected]</a>".format(simso.__version__, simsogui.__version__)
        )

    def showDocumentation(self):
        if self._documentation is None:
            doc = QWebView(self)
            doc.load(QUrl("doc/html/index.html"))
            self._documentation = QDockWidget("Documentation", self)
            self._documentation.setWidget(doc)
            self._documentation.closeEvent = lambda _: self.hide_documentation()

        self.addDockWidget(Qt.LeftDockWidgetArea, self._documentation)

    def showGantt(self):
        self.main_tab.currentWidget().showGantt()

    def showModelWindow(self):
        self.main_tab.currentWidget().showModelWindow()

    def showResults(self):
        self.main_tab.currentWidget().showResults()

    def hide_documentation(self):
        self._documentation = None

    def fileNew(self):
        self.main_tab.addTab(SimulationTab(self), 'Unsaved')

    def fileOpen(self):
        simulation_file = QFileDialog.getOpenFileName(
            filter="*.xml", caption="Open XML simulation file.")[0]
        if simulation_file:
            self.open_file(simulation_file)

    def open_file(self, simulation_file):
        try:
            simulation_file = unicode(simulation_file)
        except NameError:
            pass

        try:
            self.setCurrentFile(simulation_file)
            sim = SimulationTab(self, simulation_file)
            if (self.main_tab.currentWidget()
                    and not self.main_tab.currentWidget().simulation_file
                    and self.main_tab.currentWidget().configuration.is_saved()
                    and self.main_tab.count() == 1):
                self.main_tab.removeTab(0)
            self.main_tab.addTab(sim, os.path.split(simulation_file)[1])
            self.main_tab.setCurrentWidget(sim)
            self.updateMenus()
        except Exception:
            QMessageBox.critical(
                self, "Could not open file",
                "The file {} could not be opened.".format(simulation_file))
            print(traceback.format_exc())

    def fileSave(self):
        try:
            self.main_tab.currentWidget().save()
        except:
            self.fileSaveAs()

    def fileSaveAs(self):
        simulation_file = QFileDialog.getSaveFileName(
            filter="*.xml", caption="Save XML simulation file.")[0]
        try:
            simulation_file = unicode(simulation_file)
        except NameError:
            pass
        if simulation_file:
            if simulation_file[-4:] != '.xml':
                simulation_file += '.xml'
            self.main_tab.currentWidget().save_as(simulation_file)
            self.setCurrentFile(simulation_file)

    def fileRun(self):
        self._runAction.setEnabled(False)
        self.main_tab.currentWidget().run()

    def fileQuit(self):
        self.close()

    def setTabText(self, tab, text):
        self.main_tab.setTabText(self.main_tab.indexOf(tab), text)

    def tabChanged(self, index):
        self.updateMenus()

    def tabCloseRequested(self, index):
        if self.main_tab.widget(index).close():
            self.main_tab.removeTab(index)
            self.updateMenus()

    def closeEvent(self, event):
        while self.main_tab.count() > 0:
            if self.main_tab.widget(0).close():
                self.main_tab.removeTab(0)
            else:
                event.ignore()
                return

    def updateMenus(self):
        if self.main_tab.count() > 0:
            widget = self.main_tab.currentWidget()
            self._runAction.setEnabled(True)
            self._modelAction.setEnabled(True)
            self._ganttAction.setEnabled(widget._model is not None)
            self._metricsAction.setEnabled(widget._model is not None)
        else:
            self._runAction.setEnabled(False)
            self._modelAction.setEnabled(False)
            self._ganttAction.setEnabled(False)
            self._metricsAction.setEnabled(False)
コード例 #31
0
class UIDocumentTools(object):
    def __init__(self):
        self.mainDialog = documenttoolsdialog.DocumentToolsDialog()
        self.mainLayout = QVBoxLayout(self.mainDialog)
        self.formLayout = QFormLayout()
        self.documentLayout = QVBoxLayout()
        self.refreshButton = QPushButton(i18n("Refresh"))
        self.widgetDocuments = QListWidget()
        self.tabTools = QTabWidget()
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)

        self.kritaInstance = krita.Krita.instance()
        self.documentsList = []

        self.refreshButton.clicked.connect(self.refreshButtonClicked)
        self.buttonBox.accepted.connect(self.confirmButton)
        self.buttonBox.rejected.connect(self.mainDialog.close)

        self.mainDialog.setWindowModality(Qt.NonModal)
        self.widgetDocuments.setSelectionMode(QAbstractItemView.MultiSelection)
        self.widgetDocuments.setSizeAdjustPolicy(
            QAbstractScrollArea.AdjustToContents)

    def initialize(self):
        self.loadDocuments()
        self.loadTools()

        self.documentLayout.addWidget(self.widgetDocuments)
        self.documentLayout.addWidget(self.refreshButton)

        self.formLayout.addRow(i18n("Documents:"), self.documentLayout)
        self.formLayout.addRow(self.tabTools)

        self.line = QFrame()
        self.line.setFrameShape(QFrame.HLine)
        self.line.setFrameShadow(QFrame.Sunken)

        self.mainLayout.addLayout(self.formLayout)
        self.mainLayout.addWidget(self.line)
        self.mainLayout.addWidget(self.buttonBox)

        self.mainDialog.resize(500, 300)
        self.mainDialog.setWindowTitle(i18n("Document Tools"))
        self.mainDialog.setSizeGripEnabled(True)
        self.mainDialog.show()
        self.mainDialog.activateWindow()

    def loadTools(self):
        modulePath = 'documenttools.tools'
        toolsModule = importlib.import_module(modulePath)
        modules = []

        for classPath in toolsModule.ToolClasses:
            _module = classPath[:classPath.rfind(".")]
            _klass = classPath[classPath.rfind(".") + 1:]
            modules.append(
                dict(module='{0}.{1}'.format(modulePath, _module),
                     klass=_klass))

        for module in modules:
            m = importlib.import_module(module['module'])
            toolClass = getattr(m, module['klass'])
            obj = toolClass(self.mainDialog)
            self.tabTools.addTab(obj, obj.objectName())

    def loadDocuments(self):
        self.widgetDocuments.clear()

        self.documentsList = [
            document for document in self.kritaInstance.documents()
            if document.fileName()
        ]

        for document in self.documentsList:
            self.widgetDocuments.addItem(document.fileName())

    def refreshButtonClicked(self):
        self.loadDocuments()

    def confirmButton(self):
        selectedPaths = [
            item.text() for item in self.widgetDocuments.selectedItems()
        ]
        selectedDocuments = [
            document for document in self.documentsList
            for path in selectedPaths if path == document.fileName()
        ]

        self.msgBox = QMessageBox(self.mainDialog)
        if selectedDocuments:
            widget = self.tabTools.currentWidget()
            widget.adjust(selectedDocuments)
            self.msgBox.setText(
                i18n("The selected documents has been modified."))
        else:
            self.msgBox.setText(i18n("Select at least one document."))
        self.msgBox.exec_()
コード例 #32
0
class MainWindow(QMainWindow):

    def __init__(self, filename):
        super().__init__()

        self.setGeometry(20, 20, 1324, 1068)
        self.setWindowTitle('qt-Notepad')
        self.setStyleSheet('font-size: 14pt; font-family: Courier;')

        self.show()
        self.init_ui()
        centralWidget = QWidget()
        self.tabs = QTabWidget(centralWidget)
        self.setCentralWidget(self.tabs)
        self.tabs.setTabsClosable(True)
        self.tabs.setMovable(True)
        self.tabs.tabCloseRequested.connect(self.closeTab)
        if filename:
            f = open(filename, 'r')
            filedata = f.read()
            f.close()
            newfile = QTextEdit()
            newfile.setText(filedata)
            i = self.tabs.addTab(newfile, filename)
            self.tabs.setCurrentIndex(i)
        else:
            self.open_file()

    def init_ui(self):

        new_action = QAction('New File', self)
        new_action.setShortcut('Ctrl+N')
        new_action.setStatusTip('Create new file')
        new_action.triggered.connect(self.new_file)

        open_action = QAction('Open...', self)
        open_action.setShortcut('Ctrl+O')
        open_action.setStatusTip('Open a file')
        open_action.triggered.connect(self.open_file)

        save_action = QAction('Save File', self)
        save_action.setShortcut('Ctrl+S')
        save_action.setStatusTip('Save current file')
        save_action.triggered.connect(self.save_file)

        new_save_action = QAction('Save File As...', self)
        new_save_action.setShortcut('Shift+Ctrl+S')
        new_save_action.setStatusTip('Save current file')
        new_save_action.triggered.connect(self.save_file_as)

        close_action = QAction('Close File', self)
        close_action.setShortcut('Ctrl+W')
        close_action.setStatusTip('Close file and exit tab')
        close_action.triggered.connect(self.close_file)

        exit_action = QAction('Exit qt-Notepad', self)
        exit_action.setShortcut('Ctrl+Q')
        exit_action.setStatusTip('Close Notepad')
        exit_action.triggered.connect(self.close)

        undo_action = QAction('Undo', self)
        undo_action.setShortcut('Ctrl+Z')

        copy_action = QAction('Copy', self)
        copy_action.setShortcut('Ctrl+C')

        cut_action = QAction('Cut', self)
        cut_action.setShortcut('Ctrl+X')

        paste_action = QAction('Paste', self)
        paste_action.setShortcut('Ctrl+V')

        minimize_action = QAction('Minimize', self)
        minimize_action.setShortcut('Ctrl+M')

        view_action = QAction('Show', self)
        view_action.setShortcut('Ctrl+/')

        menubar = self.menuBar()
        file_menu = menubar.addMenu('&File')
        edit_menu = menubar.addMenu('&Edit')
        view_menu = menubar.addMenu('&View')
        window_menu = menubar.addMenu('&Window')

        file_menu.addAction(new_action)
        file_menu.addAction(open_action)
        file_menu.addAction(save_action)
        file_menu.addAction(new_save_action)
        file_menu.addAction(close_action)
        file_menu.addAction(exit_action)

        edit_menu.addAction(undo_action)
        edit_menu.addAction(copy_action)
        edit_menu.addAction(cut_action)
        edit_menu.addAction(paste_action)

        view_menu.addAction(view_action)

        window_menu.addAction(minimize_action)

    def closeTab(self, currentIndex):
        currentQWidget = self.tabs.currentWidget()
        currentQWidget.deleteLater()
        self.tabs.removeTab(currentIndex)

    def new_file(self):
        newfile = QTextEdit()
        i = self.tabs.addTab(newfile, 'New Document')
        self.tabs.setCurrentIndex(i)

    def save_file(self):
        editor = self.tabs.currentWidget()
        filename = self.tabs.tabText(self.tabs.currentIndex())
        if filename != 'New Document':
            f = open(filename, 'w')
            filedata = editor.toPlainText()
            f.write(filedata)
            f.close()
        else:
            self.save_file_as()

    def save_file_as(self):
        filename = QFileDialog.getSaveFileName(
            self, 'Save File', os.getenv('HOME'))[0]
        print(filename)
        if filename != ('', ''):
            f = open(filename, 'w')
            filedata = self.text.toPlainText()
            f.write(filedata)
            f.close()

    def open_file(self):
        filename = QFileDialog.getOpenFileName(
            self, 'Open File', os.getenv('HOME'))[0]
        f = open(filename, 'r')
        filedata = f.read()
        f.close()
        newfile = QTextEdit()
        newfile.setText(filedata)
        i = self.tabs.addTab(newfile, filename)
        self.tabs.setCurrentIndex(i)

    def close_file(self):
        self.save_file()
        currentIndex = self.tabs.currentIndex()
        self.tabs.removeTab(currentIndex)
コード例 #33
0
class Window(QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.setGeometry(75, 75, 1800, 900)
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.toolbar = NavigationToolbar(self.canvas, self)

        self.figure2 = plt.figure()
        self.canvas2 = FigureCanvas(self.figure2)
        self.toolbar2 = NavigationToolbar(self.canvas2, self)

        # Just some button connected to `plot` method
        self.button = QPushButton('Plot')
        self.button.clicked.connect(self.plot)

        # set the layout
        hlayout = QHBoxLayout()

        vlayout1 = QVBoxLayout()
        vlayout1.addWidget(self.toolbar)
        vlayout1.addWidget(self.canvas)

        vlayout2 = QVBoxLayout()
        vlayout2.addWidget(self.toolbar2)
        vlayout2.addWidget(self.canvas2)

        hlayout.addLayout(vlayout1)
        hlayout.addLayout(vlayout2)

        self.tab1 = QWidget()
        self.tab2 = QWidget()
        self.tab1.setObjectName("1")
        self.tab2.setObjectName("2")

        self.tabs = QTabWidget()

        mainlayout = QVBoxLayout()
        mainlayout.addLayout(hlayout)
        self.tab1UI()
        self.tab2UI()
        self.tabs.addTab(self.tab1, "Равномерное распределение")
        self.tabs.addTab(self.tab2, "Распределение Эрланга")

        mainlayout.addWidget(self.tabs)
        mainlayout.addWidget(self.button)
        self.setLayout(mainlayout)
        self.is_show = False

    def tab1UI(self):
        layout = QFormLayout()
        self.a = QDoubleSpinBox()
        self.b = QDoubleSpinBox()
        self.start_x = QDoubleSpinBox()
        self.stop_x = QDoubleSpinBox()

        self.a.setRange(-1e6, 1e6)
        self.b.setRange(-1e6, 1e6)
        self.start_x.setRange(-1e6, 1e6)
        self.stop_x.setRange(-1e6, 1e6)

        self.a.setValue(3)
        self.b.setValue(6)
        self.start_x.setValue(1)
        self.stop_x.setValue(10)

        layout.addRow("a", self.a)
        layout.addRow("b", self.b)

        layout.addRow("x start", self.start_x)
        layout.addRow("x end", self.stop_x)

        self.tab1.setLayout(layout)

    def tab2UI(self):
        layout = QFormLayout()
        self.lmbd = QDoubleSpinBox()
        self.n = QDoubleSpinBox()
        self.k_start = QDoubleSpinBox()
        self.k_stop = QDoubleSpinBox()

        self.lmbd.setRange(-1e6, 1e6)
        self.n.setRange(-1e-6, 1e6)
        self.k_start.setRange(-1e6, 1e6)
        self.k_stop.setRange(-1e6, 1e6)

        self.lmbd.setValue(10)
        self.n.setValue(2.00)
        self.k_start.setValue(-1.00)
        self.k_stop.setValue(20.00)

        layout.addRow("λ", self.lmbd)
        layout.addRow("n", self.n)
        layout.addRow("x start", self.k_start)
        layout.addRow("x end", self.k_stop)

        self.tab2.setLayout(layout)

    def show_warning(self):
        msg = QMessageBox(parent=self)
        msg.setIcon(QMessageBox.Warning)
        msg.setText("Некорректные данные")
        msg.setStandardButtons(QMessageBox.Ok)
        msg.exec()

    def getdata_uniform(self, foo):
        start = self.start_x.value()
        end = self.stop_x.value()
        N = self.N = 100

        a = self.a.value()
        b = self.b.value()

        if (a >= b) or (start >= end):
            self.show_warning()
            return None, None

        h = (end - start) / N
        X = [start + h * i for i in range(N)]
        Y = [foo(a, b, x) for x in X]
        return X, Y

    def getdata_Erlang(self, foo):
        k_start = self.k_start.value()
        k_stop = self.k_stop.value()
        lmbd = self.lmbd.value()
        n = self.n.value()

        N = self.N = 100
        h = (k_stop - k_start) / N

        if (k_start >= k_stop):
            self.show_warning()
            return None, None

        X = [k_start + h * i for i in range(N)]
        Y = [foo(lmbd, n, k) for k in X]

        return X, Y

    def get_status(self, type):
        tabname = self.tabs.currentWidget().objectName()
        type.append(tabname)
        X_d, Y_d = None, None
        X_f, Y_f = None, None

        if tabname == "1":
            X_d, Y_d = self.getdata_uniform(uniform_density)
            if X_d is None:
                return (None, None, None, None)
            X_f, Y_f = self.getdata_uniform(uniform_function)
        else:
            X_d, Y_d = self.getdata_Erlang(Erlang_density)
            if X_d is None:
                return (None, None, None, None)
            X_f, Y_f = self.getdata_Erlang(Erlang_function)
        return (X_f, Y_f, X_d, Y_d)

    def plot(self):
        type = []
        X_f, Y_f, X_d, Y_d = self.get_status(type)

        if X_f is None:
            return

        self.figure.clear()
        self.figure2.clear()

        ax = self.figure.add_subplot(111)
        ax2 = self.figure2.add_subplot(111)

        ax.grid(True)
        ax2.grid(True)

        if type[0] == '1':
            ax.plot(X_d, Y_d)
            ax2.plot(X_f, Y_f)
        else:
            ax.plot(X_d, Y_d)
            ax2.plot(X_f, Y_f)

        ax.legend(['Пл-ть распр.'])
        ax2.legend(['Ф-ция распр.'])

        self.canvas.draw()
        self.canvas2.draw()
コード例 #34
0
class SquidGui( QMainWindow ):
    defaults = {}
    defaults.update(SquidAxon.defaults)
    defaults.update(ClampCircuit.defaults)
    defaults.update({'runtime': 50.0,
                  'simdt': 0.01,
                  'plotdt': 0.1,
                  'vclamp.holdingV': 0.0,
                  'vclamp.holdingT': 10.0,
                  'vclamp.prepulseV': 0.0,
                  'vclamp.prepulseT': 0.0,
                  'vclamp.clampV': 50.0,
                  'vclamp.clampT': 20.0,
                  'iclamp.baseI': 0.0,
                  'iclamp.firstI': 0.1,
                  'iclamp.firstT': 40.0,
                  'iclamp.firstD': 5.0,
                  'iclamp.secondI': 0.0,
                  'iclamp.secondT': 0.0,
                  'iclamp.secondD': 0.0
                  })
    def __init__(self, *args):
        QMainWindow.__init__(self, *args)
        self.squid_setup = SquidSetup()
        self._plotdt = SquidGui.defaults['plotdt']
        self._plot_dict = defaultdict(list)
        self.setWindowTitle('Squid Axon simulation')        
        self.setDockNestingEnabled(True)
        self._createRunControl()
        self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self._runControlDock) 
        self._runControlDock.setFeatures(QDockWidget.AllDockWidgetFeatures)	 
        self._createChannelControl()
        self._channelCtrlBox.setWindowTitle('Channel properties')
        self._channelControlDock.setFeatures(QDockWidget.AllDockWidgetFeatures)	 
        self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self._channelControlDock) 
        self._createElectronicsControl()
        self._electronicsDock.setFeatures(QDockWidget.AllDockWidgetFeatures)	 
        self._electronicsDock.setWindowTitle('Electronics')
        self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self._electronicsDock) 
        self._createPlotWidget()             
        self.setCentralWidget(self._plotWidget)
        self._createStatePlotWidget()
        self._createHelpMessage()
        self._helpWindow.setVisible(False)
        self._statePlotWidget.setWindowFlags(QtCore.Qt.Window)
        self._statePlotWidget.setWindowTitle('State plot')
        self._initActions()
        self._createRunToolBar()
        self._createPlotToolBar()

    def getFloatInput(self, widget, name):
        try:
            return float(str(widget.text()))
        except ValueError:
            QMessageBox.critical(self, 'Invalid input', 'Please enter a valid number for {}'.format(name))
            raise

        
    def _createPlotWidget(self):
        self._plotWidget = QWidget()
        self._plotFigure = Figure()
        self._plotCanvas = FigureCanvas(self._plotFigure)
        self._plotCanvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self._plotCanvas.updateGeometry()
        self._plotCanvas.setParent(self._plotWidget)
        self._plotCanvas.mpl_connect('scroll_event', self._onScroll)
        self._plotFigure.set_canvas(self._plotCanvas)
        # Vm and command voltage go in the same subplot
        self._vm_axes = self._plotFigure.add_subplot(2,2,1, title='Membrane potential')
        self._vm_axes.set_ylim(-20.0, 120.0)
        # Channel conductances go to the same subplot
        self._g_axes = self._plotFigure.add_subplot(2,2,2, title='Channel conductance')
        self._g_axes.set_ylim(0.0, 0.5)
        # Injection current for Vclamp/Iclamp go to the same subplot
        self._im_axes = self._plotFigure.add_subplot(2,2,3, title='Injection current')
        self._im_axes.set_ylim(-0.5, 0.5)
        # Channel currents go to the same subplot
        self._i_axes = self._plotFigure.add_subplot(2,2,4, title='Channel current')
        self._i_axes.set_ylim(-10, 10)
        for axis in self._plotFigure.axes:
            axis.set_autoscale_on(False)
        layout = QVBoxLayout()
        layout.addWidget(self._plotCanvas)
        self._plotNavigator = NavigationToolbar(self._plotCanvas, self._plotWidget)
        layout.addWidget(self._plotNavigator)
        self._plotWidget.setLayout(layout)

    def _createStatePlotWidget(self):        
        self._statePlotWidget = QWidget()
        self._statePlotFigure = Figure()
        self._statePlotCanvas = FigureCanvas(self._statePlotFigure)
        self._statePlotCanvas.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self._statePlotCanvas.updateGeometry()
        self._statePlotCanvas.setParent(self._statePlotWidget)
        self._statePlotFigure.set_canvas(self._statePlotCanvas)
        self._statePlotFigure.subplots_adjust(hspace=0.5)
        self._statePlotAxes = self._statePlotFigure.add_subplot(2,1,1, title='State plot')
        self._state_plot, = self._statePlotAxes.plot([], [], label='state')
        self._activationParamAxes = self._statePlotFigure.add_subplot(2,1,2, title='H-H activation parameters vs time')
        self._activationParamAxes.set_xlabel('Time (ms)')
        #for axis in self._plotFigure.axes:
        #    axis.autoscale(False)
        self._stateplot_xvar_label = QLabel('Variable on X-axis')
        self._stateplot_xvar_combo = QComboBox()
        self._stateplot_xvar_combo.addItems(['V', 'm', 'n', 'h'])
        self._stateplot_xvar_combo.setCurrentText('V')
        self._stateplot_xvar_combo.setEditable(False)
        self._stateplot_xvar_combo.currentIndexChanged[str].connect( self._statePlotXSlot )
        self._stateplot_yvar_label = QLabel('Variable on Y-axis')
        self._stateplot_yvar_combo = QComboBox()
        self._stateplot_yvar_combo.addItems(['V', 'm', 'n', 'h'])
        self._stateplot_yvar_combo.setCurrentIndex(2)
        self._stateplot_yvar_combo.setEditable(False)
        self._stateplot_yvar_combo.currentIndexChanged[str].connect(self._statePlotYSlot)
        self._statePlotNavigator = NavigationToolbar(self._statePlotCanvas, self._statePlotWidget)
        frame = QFrame()
        frame.setFrameStyle(QFrame.StyledPanel + QFrame.Raised)
        layout = QHBoxLayout()
        layout.addWidget(self._stateplot_xvar_label)
        layout.addWidget(self._stateplot_xvar_combo)
        layout.addWidget(self._stateplot_yvar_label)
        layout.addWidget(self._stateplot_yvar_combo)
        frame.setLayout(layout)
        self._closeStatePlotAction = QAction('Close', self)
        self._closeStatePlotAction.triggered.connect(self._statePlotWidget.close)
        self._closeStatePlotButton = QToolButton()
        self._closeStatePlotButton.setDefaultAction(self._closeStatePlotAction)
        layout = QVBoxLayout()
        layout.addWidget(frame)
        layout.addWidget(self._statePlotCanvas)
        layout.addWidget(self._statePlotNavigator)
        layout.addWidget(self._closeStatePlotButton)
        self._statePlotWidget.setLayout(layout)  
        # Setting the close event so that when the help window is
        # closed the ``State plot`` button becomes unchecked
        self._statePlotWidget.closeEvent = lambda event: self._showStatePlotAction.setChecked(False)

    def _createRunControl(self):
        self._runControlBox = QGroupBox(self)
        self._runControlBox.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred)
        self._runTimeLabel = QLabel("Run time (ms)", self._runControlBox)
        self._simTimeStepLabel = QLabel("Simulation time step (ms)", self._runControlBox)
        self._runTimeEdit = QLineEdit('%g' % (SquidGui.defaults['runtime']), self._runControlBox)
        set_default_line_edit_size(self._runTimeEdit)
        self._simTimeStepEdit = QLineEdit('%g' % (SquidGui.defaults['simdt']), self._runControlBox)
        set_default_line_edit_size(self._simTimeStepEdit)
        layout = QGridLayout()
        layout.addWidget(self._runTimeLabel, 0, 0)
        layout.addWidget(self._runTimeEdit, 0, 1)
        layout.addWidget(self._simTimeStepLabel, 1, 0)
        layout.addWidget(self._simTimeStepEdit, 1, 1)
        layout.setColumnStretch(2, 1.0)
        layout.setRowStretch(2, 1.0)
        self._runControlBox.setLayout(layout)
        self._runControlDock = QDockWidget('Simulation', self)
        self._runControlDock.setWidget(self._runControlBox)

    def _createChannelControl(self):
        self._channelControlDock = QDockWidget('Channels', self)
        self._channelCtrlBox = QGroupBox(self)
        self._naConductanceToggle = QCheckBox('Block Na+ channel', self._channelCtrlBox)
        self._naConductanceToggle.setToolTip('<html>%s</html>' % (tooltip_NaChan))
        self._kConductanceToggle = QCheckBox('Block K+ channel', self._channelCtrlBox)
        self._kConductanceToggle.setToolTip('<html>%s</html>' % (tooltip_KChan))
        self._kOutLabel = QLabel('[K+]out (mM)', self._channelCtrlBox)
        self._kOutEdit = QLineEdit('%g' % (self.squid_setup.squid_axon.K_out), 
                                         self._channelCtrlBox)
        self._kOutLabel.setToolTip('<html>%s</html>' % (tooltip_Nernst))
        self._kOutEdit.setToolTip('<html>%s</html>' % (tooltip_Nernst))
        set_default_line_edit_size(self._kOutEdit)
        self._naOutLabel = QLabel('[Na+]out (mM)', self._channelCtrlBox)
        self._naOutEdit = QLineEdit('%g' % (self.squid_setup.squid_axon.Na_out), 
                                         self._channelCtrlBox)
        self._naOutLabel.setToolTip('<html>%s</html>' % (tooltip_Nernst))
        self._naOutEdit.setToolTip('<html>%s</html>' % (tooltip_Nernst))
        set_default_line_edit_size(self._naOutEdit)
        self._kInLabel = QLabel('[K+]in (mM)', self._channelCtrlBox)
        self._kInEdit = QLineEdit('%g' % (self.squid_setup.squid_axon.K_in), 
                                         self._channelCtrlBox)
        self._kInEdit.setToolTip(tooltip_Nernst)
        self._naInLabel = QLabel('[Na+]in (mM)', self._channelCtrlBox)
        self._naInEdit = QLineEdit('%g' % (self.squid_setup.squid_axon.Na_in), 
                                         self._channelCtrlBox)
        self._naInEdit.setToolTip('<html>%s</html>' % (tooltip_Nernst))
        self._temperatureLabel = QLabel('Temperature (C)', self._channelCtrlBox)
        self._temperatureEdit = QLineEdit('%g' % (self.defaults['temperature'] - CELSIUS_TO_KELVIN),
                                                self._channelCtrlBox)
        self._temperatureEdit.setToolTip('<html>%s</html>' % (tooltip_Nernst))
        set_default_line_edit_size(self._temperatureEdit)
        for child in self._channelCtrlBox.children():
            if isinstance(child, QLineEdit):
                set_default_line_edit_size(child)
        layout = QGridLayout(self._channelCtrlBox)
        layout.addWidget(self._naConductanceToggle, 0, 0)
        layout.addWidget(self._kConductanceToggle, 1, 0)
        layout.addWidget(self._naOutLabel, 2, 0)
        layout.addWidget(self._naOutEdit, 2, 1)
        layout.addWidget(self._naInLabel, 3, 0)
        layout.addWidget(self._naInEdit, 3, 1)
        layout.addWidget(self._kOutLabel, 4, 0)
        layout.addWidget(self._kOutEdit, 4, 1)
        layout.addWidget(self._kInLabel, 5, 0)
        layout.addWidget(self._kInEdit, 5, 1)
        layout.addWidget(self._temperatureLabel, 6, 0)
        layout.addWidget(self._temperatureEdit, 6, 1)
        layout.setRowStretch(7, 1.0)
        self._channelCtrlBox.setLayout(layout)
        self._channelControlDock.setWidget(self._channelCtrlBox)
        return self._channelCtrlBox        

    def __get_stateplot_data(self, name):
        data = []
        if name == 'V':
            data = self.squid_setup.vm_table.vector
        elif name == 'm':
            data = self.squid_setup.m_table.vector
        elif name == 'h':
            data = self.squid_setup.h_table.vector
        elif name == 'n':
            data = self.squid_setup.n_table.vector
        else:
            raise ValueError('Unrecognized selection: %s' % name )
        return numpy.asarray(data)
    
    def _statePlotYSlot(self, selectedItem):
        ydata = self.__get_stateplot_data(str(selectedItem))
        self._state_plot.set_ydata(ydata)
        self._statePlotAxes.set_ylabel(selectedItem)
        if str(selectedItem) == 'V':
            self._statePlotAxes.set_ylim(-20, 120)
        else:
            self._statePlotAxes.set_ylim(0, 1)
        self._statePlotCanvas.draw()
        
    def _statePlotXSlot(self, selectedItem):
        xdata = self.__get_stateplot_data(str(selectedItem))
        self._state_plot.set_xdata(xdata)
        self._statePlotAxes.set_xlabel(selectedItem)
        if str(selectedItem) == 'V':
            self._statePlotAxes.set_xlim(-20, 120)
        else:
            self._statePlotAxes.set_xlim(0, 1)
        self._statePlotCanvas.draw()

    def _createElectronicsControl(self):
        """Creates a tabbed widget of voltage clamp and current clamp controls"""
        self._electronicsTab = QTabWidget(self)
        self._electronicsTab.addTab(self._getIClampCtrlBox(), 'Current clamp')
        self._electronicsTab.addTab(self._getVClampCtrlBox(), 'Voltage clamp')
        self._electronicsDock = QDockWidget(self)
        self._electronicsDock.setWidget(self._electronicsTab)

    def _getVClampCtrlBox(self):
        vClampPanel = QGroupBox(self)
        self._vClampCtrlBox = vClampPanel
        self._holdingVLabel = QLabel("Holding Voltage (mV)", vClampPanel)
        self._holdingVEdit = QLineEdit('%g' % (SquidGui.defaults['vclamp.holdingV']), vClampPanel)
        self._holdingTimeLabel = QLabel("Holding Time (ms)", vClampPanel)
        self._holdingTimeEdit = QLineEdit('%g' % (SquidGui.defaults['vclamp.holdingT']), vClampPanel)
        self._prePulseVLabel = QLabel("Pre-pulse Voltage (mV)", vClampPanel)
        self._prePulseVEdit = QLineEdit('%g' % (SquidGui.defaults['vclamp.prepulseV']), vClampPanel)
        self._prePulseTimeLabel = QLabel("Pre-pulse Time (ms)", vClampPanel)
        self._prePulseTimeEdit = QLineEdit('%g' % (SquidGui.defaults['vclamp.prepulseT']), vClampPanel)
        self._clampVLabel = QLabel("Clamp Voltage (mV)", vClampPanel)
        self._clampVEdit = QLineEdit('%g' % (SquidGui.defaults['vclamp.clampV']), vClampPanel)
        self._clampTimeLabel = QLabel("Clamp Time (ms)", vClampPanel)
        self._clampTimeEdit = QLineEdit('%g' % (SquidGui.defaults['vclamp.clampT']), vClampPanel)
        for child in vClampPanel.children():
            if isinstance(child, QLineEdit):
                set_default_line_edit_size(child)
        layout = QGridLayout(vClampPanel)
        layout.addWidget(self._holdingVLabel, 0, 0)
        layout.addWidget(self._holdingVEdit, 0, 1)
        layout.addWidget(self._holdingTimeLabel, 1, 0)
        layout.addWidget(self._holdingTimeEdit, 1, 1)
        layout.addWidget(self._prePulseVLabel, 2, 0)
        layout.addWidget(self._prePulseVEdit, 2, 1)
        layout.addWidget(self._prePulseTimeLabel,3,0)
        layout.addWidget(self._prePulseTimeEdit, 3, 1)
        layout.addWidget(self._clampVLabel, 4, 0)
        layout.addWidget(self._clampVEdit, 4, 1)
        layout.addWidget(self._clampTimeLabel, 5, 0)
        layout.addWidget(self._clampTimeEdit, 5, 1)
        layout.setRowStretch(6, 1.0)
        vClampPanel.setLayout(layout)
        return self._vClampCtrlBox

    def _getIClampCtrlBox(self):
        iClampPanel = QGroupBox(self)
        self._iClampCtrlBox = iClampPanel
        self._baseCurrentLabel = QLabel("Base Current Level (uA)",iClampPanel)
        self._baseCurrentEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.baseI']),iClampPanel)
        self._firstPulseLabel = QLabel("First Pulse Current (uA)", iClampPanel)
        self._firstPulseEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.firstI']), iClampPanel)
        self._firstDelayLabel = QLabel("First Onset Delay (ms)", iClampPanel)
        self._firstDelayEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.firstD']),iClampPanel)
        self._firstPulseWidthLabel = QLabel("First Pulse Width (ms)", iClampPanel)
        self._firstPulseWidthEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.firstT']), iClampPanel)
        self._secondPulseLabel = QLabel("Second Pulse Current (uA)", iClampPanel)
        self._secondPulseEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.secondI']), iClampPanel)
        self._secondDelayLabel = QLabel("Second Onset Delay (ms)", iClampPanel)
        self._secondDelayEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.secondD']),iClampPanel)
        self._secondPulseWidthLabel = QLabel("Second Pulse Width (ms)", iClampPanel)
        self._secondPulseWidthEdit = QLineEdit('%g' % (SquidGui.defaults['iclamp.secondT']), iClampPanel)
        self._pulseMode = QComboBox(iClampPanel)
        self._pulseMode.addItem("Single Pulse")
        self._pulseMode.addItem("Pulse Train")
        for child in iClampPanel.children():
            if isinstance(child, QLineEdit):
                set_default_line_edit_size(child)
        layout = QGridLayout(iClampPanel)
        layout.addWidget(self._baseCurrentLabel, 0, 0)
        layout.addWidget(self._baseCurrentEdit, 0, 1)
        layout.addWidget(self._firstPulseLabel, 1, 0)
        layout.addWidget(self._firstPulseEdit, 1, 1)
        layout.addWidget(self._firstDelayLabel, 2, 0)
        layout.addWidget(self._firstDelayEdit, 2, 1)
        layout.addWidget(self._firstPulseWidthLabel, 3, 0)
        layout.addWidget(self._firstPulseWidthEdit, 3, 1)
        layout.addWidget(self._secondPulseLabel, 4, 0)
        layout.addWidget(self._secondPulseEdit, 4, 1)
        layout.addWidget(self._secondDelayLabel, 5, 0)
        layout.addWidget(self._secondDelayEdit, 5, 1)
        layout.addWidget(self._secondPulseWidthLabel, 6, 0)
        layout.addWidget(self._secondPulseWidthEdit, 6, 1)
        layout.addWidget(self._pulseMode, 7, 0, 1, 2)
        layout.setRowStretch(8, 1.0)        
        # layout.setSizeConstraint(QLayout.SetFixedSize)
        iClampPanel.setLayout(layout)
        return self._iClampCtrlBox

    def _overlayPlots(self, overlay):        
        if not overlay:
            for axis in (self._plotFigure.axes + self._statePlotFigure.axes):
                title = axis.get_title()
                axis.clear()
                axis.set_title(title)
            suffix = ''
        else:
            suffix = '_%d' % (len(self._plot_dict['vm']))
        self._vm_axes.set_xlim(0.0, self._runtime)
        self._g_axes.set_xlim(0.0, self._runtime)
        self._im_axes.set_xlim(0.0, self._runtime)
        self._i_axes.set_xlim(0.0, self._runtime)
        self._vm_plot, = self._vm_axes.plot([], [], label='Vm%s'%(suffix))
        self._plot_dict['vm'].append(self._vm_plot)
        self._command_plot, = self._vm_axes.plot([], [], label='command%s'%(suffix))
        self._plot_dict['command'].append(self._command_plot)
        # Channel conductances go to the same subplot
        self._gna_plot, = self._g_axes.plot([], [], label='Na%s'%(suffix))
        self._plot_dict['gna'].append(self._gna_plot)
        self._gk_plot, = self._g_axes.plot([], [], label='K%s'%(suffix))
        self._plot_dict['gk'].append(self._gk_plot)
        # Injection current for Vclamp/Iclamp go to the same subplot
        self._iclamp_plot, = self._im_axes.plot([], [], label='Iclamp%s'%(suffix))
        self._vclamp_plot, = self._im_axes.plot([], [], label='Vclamp%s'%(suffix))
        self._plot_dict['iclamp'].append(self._iclamp_plot)
        self._plot_dict['vclamp'].append(self._vclamp_plot)
        # Channel currents go to the same subplot
        self._ina_plot, = self._i_axes.plot([], [], label='Na%s'%(suffix))
        self._plot_dict['ina'].append(self._ina_plot)
        self._ik_plot, = self._i_axes.plot([], [], label='K%s'%(suffix))
        self._plot_dict['ik'].append(self._ik_plot)
        # self._i_axes.legend()
        # State plots
        self._state_plot, = self._statePlotAxes.plot([], [], label='state%s'%(suffix))
        self._plot_dict['state'].append(self._state_plot)
        self._m_plot, = self._activationParamAxes.plot([],[], label='m%s'%(suffix))
        self._h_plot, = self._activationParamAxes.plot([], [], label='h%s'%(suffix))
        self._n_plot, = self._activationParamAxes.plot([], [], label='n%s'%(suffix))
        self._plot_dict['m'].append(self._m_plot)
        self._plot_dict['h'].append(self._h_plot)
        self._plot_dict['n'].append(self._n_plot)
        if self._showLegendAction.isChecked():
            for axis in (self._plotFigure.axes + self._statePlotFigure.axes):            
                axis.legend()

    def _updateAllPlots(self):
        self._updatePlots()
        self._updateStatePlot()

    def _updatePlots(self):
        if len(self.squid_setup.vm_table.vector) <= 0:
            return        
        vm = numpy.asarray(self.squid_setup.vm_table.vector)
        cmd = numpy.asarray(self.squid_setup.cmd_table.vector)
        ik = numpy.asarray(self.squid_setup.ik_table.vector)
        ina = numpy.asarray(self.squid_setup.ina_table.vector)
        iclamp = numpy.asarray(self.squid_setup.iclamp_table.vector)
        vclamp = numpy.asarray(self.squid_setup.vclamp_table.vector)
        gk = numpy.asarray(self.squid_setup.gk_table.vector)
        gna = numpy.asarray(self.squid_setup.gna_table.vector)
        time_series = numpy.linspace(0, self._plotdt * len(vm), len(vm))        
        self._vm_plot.set_data(time_series, vm)
        time_series = numpy.linspace(0, self._plotdt * len(cmd), len(cmd))        
        self._command_plot.set_data(time_series, cmd)
        time_series = numpy.linspace(0, self._plotdt * len(ik), len(ik))
        self._ik_plot.set_data(time_series, ik)
        time_series = numpy.linspace(0, self._plotdt * len(ina), len(ina))
        self._ina_plot.set_data(time_series, ina)
        time_series = numpy.linspace(0, self._plotdt * len(iclamp), len(iclamp))
        self._iclamp_plot.set_data(time_series, iclamp)
        time_series = numpy.linspace(0, self._plotdt * len(vclamp), len(vclamp))
        self._vclamp_plot.set_data(time_series, vclamp)
        time_series = numpy.linspace(0, self._plotdt * len(gk), len(gk))
        self._gk_plot.set_data(time_series, gk)
        time_series = numpy.linspace(0, self._plotdt * len(gna), len(gna))
        self._gna_plot.set_data(time_series, gna)
        # self._vm_axes.margins(y=0.1)
        # self._g_axes.margin(y=0.1)
        # self._im_axes.margins(y=0.1)
        # self._i_axes.margins(y=0.1)
        if self._autoscaleAction.isChecked():
            for axis in self._plotFigure.axes:
                axis.relim()
                axis.margins(0.1, 0.1)
                axis.autoscale_view(tight=True)
        else:
            self._vm_axes.set_ylim(-20.0, 120.0)
            self._g_axes.set_ylim(0.0, 0.5)
            self._im_axes.set_ylim(-0.5, 0.5)
            self._i_axes.set_ylim(-10, 10)
        self._vm_axes.set_xlim(0.0, time_series[-1])
        self._g_axes.set_xlim(0.0, time_series[-1])
        self._im_axes.set_xlim(0.0, time_series[-1])
        self._i_axes.set_xlim(0.0, time_series[-1])
        self._plotCanvas.draw()

    def _updateStatePlot(self):
        if len(self.squid_setup.vm_table.vector) <= 0:
            return
        sx = str(self._stateplot_xvar_combo.currentText())
        sy = str(self._stateplot_yvar_combo.currentText())
        xdata = self.__get_stateplot_data(sx)
        ydata = self.__get_stateplot_data(sy)
        minlen = min(len(xdata), len(ydata))
        self._state_plot.set_data(xdata[:minlen], ydata[:minlen])
        self._statePlotAxes.set_xlabel(sx)
        self._statePlotAxes.set_ylabel(sy)
        if sx == 'V':
            self._statePlotAxes.set_xlim(-20, 120)
        else:
            self._statePlotAxes.set_xlim(0, 1)
        if sy == 'V':
            self._statePlotAxes.set_ylim(-20, 120)
        else:
            self._statePlotAxes.set_ylim(0, 1)
        self._activationParamAxes.set_xlim(0, self._runtime)
        m = self.__get_stateplot_data('m')
        n = self.__get_stateplot_data('n')
        h = self.__get_stateplot_data('h')
        time_series = numpy.linspace(0, self._plotdt*len(m), len(m))
        self._m_plot.set_data(time_series, m)
        time_series = numpy.linspace(0, self._plotdt*len(h), len(h))
        self._h_plot.set_data(time_series, h)
        time_series = numpy.linspace(0, self._plotdt*len(n), len(n))
        self._n_plot.set_data(time_series, n)
        if self._autoscaleAction.isChecked():
            for axis in self._statePlotFigure.axes:
                axis.relim()
                axis.set_autoscale_on(True)
                axis.autoscale_view(True)
        self._statePlotCanvas.draw()

    def _runSlot(self):
        if moose.isRunning():
            print('Stopping simulation in progress ...')
            moose.stop()
        self._runtime = self.getFloatInput(self._runTimeEdit, self._runTimeLabel.text())
        self._overlayPlots(self._overlayAction.isChecked())
        self._simdt = self.getFloatInput(self._simTimeStepEdit, self._simTimeStepLabel.text())
        clampMode = None
        singlePulse = True
        if self._electronicsTab.currentWidget() == self._vClampCtrlBox:
            clampMode = 'vclamp'
            baseLevel = self.getFloatInput(self._holdingVEdit, self._holdingVLabel.text())
            firstDelay = self.getFloatInput(self._holdingTimeEdit, self._holdingTimeLabel.text())
            firstWidth = self.getFloatInput(self._prePulseTimeEdit, self._prePulseTimeLabel.text())
            firstLevel = self.getFloatInput(self._prePulseVEdit, self._prePulseVLabel.text())
            secondDelay = firstWidth
            secondWidth = self.getFloatInput(self._clampTimeEdit, self._clampTimeLabel.text())
            secondLevel = self.getFloatInput(self._clampVEdit, self._clampVLabel.text())
            if not self._autoscaleAction.isChecked():
                self._im_axes.set_ylim(-10.0, 10.0)
        else:
            clampMode = 'iclamp'
            baseLevel = self.getFloatInput(self._baseCurrentEdit, self._baseCurrentLabel.text())
            firstDelay = self.getFloatInput(self._firstDelayEdit, self._firstDelayLabel.text())
            firstWidth = self.getFloatInput(self._firstPulseWidthEdit, self._firstPulseWidthLabel.text())
            firstLevel = self.getFloatInput(self._firstPulseEdit, self._firstPulseLabel.text())
            secondDelay = self.getFloatInput(self._secondDelayEdit, self._secondDelayLabel.text())
            secondLevel = self.getFloatInput(self._secondPulseEdit, self._secondPulseLabel.text())
            secondWidth = self.getFloatInput(self._secondPulseWidthEdit, self._secondPulseWidthLabel.text())
            singlePulse = (self._pulseMode.currentIndex() == 0)
            if not self._autoscaleAction.isChecked():
                self._im_axes.set_ylim(-0.4, 0.4)
        self.squid_setup.clamp_ckt.configure_pulses(baseLevel=baseLevel,
                                                    firstDelay=firstDelay,
                                                    firstWidth=firstWidth,
                                                    firstLevel=firstLevel,
                                                    secondDelay=secondDelay,
                                                    secondWidth=secondWidth,
                                                    secondLevel=secondLevel,
                                                    singlePulse=singlePulse)
        if self._kConductanceToggle.isChecked():
            self.squid_setup.squid_axon.specific_gK = 0.0
        else:
            self.squid_setup.squid_axon.specific_gK = SquidAxon.defaults['specific_gK']
        if self._naConductanceToggle.isChecked():
            self.squid_setup.squid_axon.specific_gNa = 0.0
        else:
            self.squid_setup.squid_axon.specific_gNa = SquidAxon.defaults['specific_gNa']
        self.squid_setup.squid_axon.celsius = self.getFloatInput(self._temperatureEdit, self._temperatureLabel.text())
        self.squid_setup.squid_axon.K_out = self.getFloatInput(self._kOutEdit, self._kOutLabel.text())
        self.squid_setup.squid_axon.Na_out = self.getFloatInput(self._naOutEdit, self._naOutLabel.text())
        self.squid_setup.squid_axon.K_in = self.getFloatInput(self._kInEdit, self._kInLabel.text())
        self.squid_setup.squid_axon.Na_in = self.getFloatInput(self._naInEdit, self._naInLabel.text())
        self.squid_setup.squid_axon.updateEk()
        self.squid_setup.schedule(self._simdt, self._plotdt, clampMode)
        # The following line is for use with Qthread
        self.squid_setup.run(self._runtime)
        self._updateAllPlots()

    def _toggleDocking(self, on):
        self._channelControlDock.setFloating(on)
        self._electronicsDock.setFloating(on)
        self._runControlDock.setFloating(on)
        
    def _restoreDocks(self):
        self._channelControlDock.setVisible(True)
        self._electronicsDock.setVisible(True)
        self._runControlDock.setVisible(True)

    def _initActions(self):
        self._runAction = QAction(self.tr('Run'), self)
        self._runAction.setShortcut(self.tr('F5'))
        self._runAction.setToolTip('Run simulation (F5)')
        self._runAction.triggered.connect( self._runSlot)
        self._resetToDefaultsAction = QAction(self.tr('Restore defaults'), self)
        self._resetToDefaultsAction.setToolTip('Reset all settings to their default values')
        self._resetToDefaultsAction.triggered.connect( self._useDefaults)
        self._showLegendAction = QAction(self.tr('Display legend'), self)
        self._showLegendAction.setCheckable(True)
        self._showLegendAction.toggled.connect(self._showLegend)
        self._showStatePlotAction = QAction(self.tr('State plot'), self)
        self._showStatePlotAction.setCheckable(True)
        self._showStatePlotAction.setChecked(False)
        self._showStatePlotAction.toggled.connect(self._statePlotWidget.setVisible)
        self._autoscaleAction  = QAction(self.tr('Auto-scale plots'), self)
        self._autoscaleAction.setCheckable(True)
        self._autoscaleAction.setChecked(False)
        self._autoscaleAction.toggled.connect(self._autoscale)
        self._overlayAction = QAction('Overlay plots', self)
        self._overlayAction.setCheckable(True)
        self._overlayAction.setChecked(False) 
        self._dockAction = QAction('Undock all', self)
        self._dockAction.setCheckable(True)
        self._dockAction.setChecked(False)
        #  self._dockAction.toggle.connect( self._toggleDocking)
        self._restoreDocksAction = QAction('Show all', self)
        self._restoreDocksAction.triggered.connect( self._restoreDocks)
        self._quitAction = QAction(self.tr('&Quit'), self)
        self._quitAction.setShortcut(self.tr('Ctrl+Q'))
        self._quitAction.triggered.connect(qApp.closeAllWindows)

        

    def _createRunToolBar(self):
        self._simToolBar = self.addToolBar(self.tr('Simulation control'))
        self._simToolBar.addAction(self._quitAction)
        self._simToolBar.addAction(self._runAction)
        self._simToolBar.addAction(self._resetToDefaultsAction)
        self._simToolBar.addAction(self._dockAction)
        self._simToolBar.addAction(self._restoreDocksAction)

    def _createPlotToolBar(self):
        self._plotToolBar = self.addToolBar(self.tr('Plotting control'))
        self._plotToolBar.addAction(self._showLegendAction)
        self._plotToolBar.addAction(self._autoscaleAction)
        self._plotToolBar.addAction(self._overlayAction)
        self._plotToolBar.addAction(self._showStatePlotAction)
        self._plotToolBar.addAction(self._helpAction)
        self._plotToolBar.addAction(self._helpBiophysicsAction)

    def _showLegend(self, on):
        if on:
            for axis in (self._plotFigure.axes + self._statePlotFigure.axes):            
                axis.legend().set_visible(True)
        else:
            for axis in (self._plotFigure.axes + self._statePlotFigure.axes):            
                axis.legend().set_visible(False)
        self._plotCanvas.draw()
        self._statePlotCanvas.draw()

    def _autoscale(self, on):
        if on:
            for axis in (self._plotFigure.axes + self._statePlotFigure.axes):            
                axis.relim()
                axis.set_autoscale_on(True)
                axis.autoscale_view(True)
        else:
            for axis in self._plotFigure.axes:
                axis.set_autoscale_on(False)            
            self._vm_axes.set_ylim(-20.0, 120.0)
            self._g_axes.set_ylim(0.0, 0.5)
            self._im_axes.set_ylim(-0.5, 0.5)
            self._i_axes.set_ylim(-10, 10)
        self._plotCanvas.draw()
        self._statePlotCanvas.draw()
        
    def _useDefaults(self):
        self._runTimeEdit.setText('%g' % (self.defaults['runtime']))
        self._simTimeStepEdit.setText('%g' % (self.defaults['simdt']))
        self._overlayAction.setChecked(False)
        self._naConductanceToggle.setChecked(False)
        self._kConductanceToggle.setChecked(False)
        self._kOutEdit.setText('%g' % (SquidGui.defaults['K_out']))
        self._naOutEdit.setText('%g' % (SquidGui.defaults['Na_out']))
        self._kInEdit.setText('%g' % (SquidGui.defaults['K_in']))
        self._naInEdit.setText('%g' % (SquidGui.defaults['Na_in']))
        self._temperatureEdit.setText('%g' % (SquidGui.defaults['temperature'] - CELSIUS_TO_KELVIN))
        self._holdingVEdit.setText('%g' % (SquidGui.defaults['vclamp.holdingV']))
        self._holdingTimeEdit.setText('%g' % (SquidGui.defaults['vclamp.holdingT']))
        self._prePulseVEdit.setText('%g' % (SquidGui.defaults['vclamp.prepulseV']))
        self._prePulseTimeEdit.setText('%g' % (SquidGui.defaults['vclamp.prepulseT']))
        self._clampVEdit.setText('%g' % (SquidGui.defaults['vclamp.clampV']))
        self._clampTimeEdit.setText('%g' % (SquidGui.defaults['vclamp.clampT']))
        self._baseCurrentEdit.setText('%g' % (SquidGui.defaults['iclamp.baseI']))
        self._firstPulseEdit.setText('%g' % (SquidGui.defaults['iclamp.firstI']))
        self._firstDelayEdit.setText('%g' % (SquidGui.defaults['iclamp.firstD']))
        self._firstPulseWidthEdit.setText('%g' % (SquidGui.defaults['iclamp.firstT']))
        self._secondPulseEdit.setText('%g' % (SquidGui.defaults['iclamp.secondI']))
        self._secondDelayEdit.setText('%g' % (SquidGui.defaults['iclamp.secondD']))
        self._secondPulseWidthEdit.setText('%g' % (SquidGui.defaults['iclamp.secondT']))
        self._pulseMode.setCurrentIndex(0)

    def _onScroll(self, event):
        if event.inaxes is None:
            return  
        axes = event.inaxes
        zoom = 0.0
        if event.button == 'up':
            zoom = -1.0
        elif event.button == 'down':
            zoom = 1.0
        if zoom != 0.0:
            self._plotNavigator.push_current()
            axes.get_xaxis().zoom(zoom)
            axes.get_yaxis().zoom(zoom)        
        self._plotCanvas.draw()

    def closeEvent(self, event):
        qApp.closeAllWindows()

    def _showBioPhysicsHelp(self):
        self._createHelpMessage()
        self._helpMessageText.setText('<html><p>%s</p><p>%s</p><p>%s</p><p>%s</p><p>%s</p></html>' % 
                                      (tooltip_Nernst, 
                                       tooltip_Erest,
                                       tooltip_KChan,
                                       tooltip_NaChan,
                                       tooltip_Im))
        self._helpWindow.setVisible(True)

    def _showRunningHelp(self):
        self._createHelpMessage()
        self._helpMessageText.setSource(QtCore.QUrl(self._helpBaseURL))
        self._helpWindow.setVisible(True)

    def _createHelpMessage(self):
        if hasattr(self, '_helpWindow'):
            return
        self._helpWindow = QWidget()
        self._helpWindow.setWindowFlags(QtCore.Qt.Window)
        layout = QVBoxLayout()
        self._helpWindow.setLayout(layout)
        self._helpMessageArea = QScrollArea()
        self._helpMessageText = QTextBrowser()
        self._helpMessageText.setOpenExternalLinks(True)
        self._helpMessageArea.setWidget(self._helpMessageText)
        layout.addWidget(self._helpMessageText)
        self._squidGuiPath = os.path.dirname(os.path.abspath(__file__))
        self._helpBaseURL = os.path.join(self._squidGuiPath,'help.html')
        self._helpMessageText.setSource(QtCore.QUrl(self._helpBaseURL))
        self._helpMessageText.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self._helpMessageArea.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self._helpMessageText.setMinimumSize(800, 600)
        self._closeHelpAction = QAction('Close', self)
        self._closeHelpAction.triggered.connect(self._helpWindow.close)        
        # Setting the close event so that the ``Help`` button is
        # unchecked when the help window is closed
        self._helpWindow.closeEvent = lambda event: self._helpAction.setChecked(False)
        self._helpTOCAction = QAction('Help running demo', self)
        self._helpTOCAction.triggered.connect( self._jumpToHelpTOC)                
        # This panel is for putting two buttons using horizontal
        # layout
        panel = QFrame()
        panel.setFrameStyle(QFrame.StyledPanel + QFrame.Raised)
        layout.addWidget(panel)
        layout = QHBoxLayout()
        panel.setLayout(layout)
        self._helpAction = QAction('Help running', self)
        self._helpAction.triggered.connect(self._showRunningHelp)
        self._helpBiophysicsAction = QAction('Help biophysics', self)
        self._helpBiophysicsAction.triggered.connect(self._showBioPhysicsHelp)
        self._helpTOCButton = QToolButton()
        self._helpTOCButton.setDefaultAction(self._helpTOCAction)
        self._helpBiophysicsButton = QToolButton()
        self._helpBiophysicsButton.setDefaultAction(self._helpBiophysicsAction)
        layout.addWidget(self._helpTOCButton)
        layout.addWidget(self._helpBiophysicsButton)
        self._closeHelpButton = QToolButton()
        self._closeHelpButton.setDefaultAction(self._closeHelpAction)
        layout.addWidget(self._closeHelpButton)
        
    def _jumpToHelpTOC(self):
        self._helpMessageText.setSource(QtCore.QUrl(self._helpBaseURL))
コード例 #35
0
class QueryUI(QWidget):
    def __init__(self):
        super().__init__()
        try:
            self.keyValues = getOfficialKeys()
        except RequestException:
            logging.warning(
                "There was a problem with the internet connection. You will not be able to see the existing keys."
            )
        self.onClearPolygonF = lambda: None
        self.onPolygonEnabledF = lambda: None
        self.onPolygonDisabledF = lambda: None
        self.currentHtml = EMPTY_HTML
        self.initUI()

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

        self.requestAreaWidget = QToolBox()
        self.requestAreaWidget.layout().setSpacing(1)

        self.requestTabs = QTabWidget()
        self.requestTabs.setUsesScrollButtons(True)
        self.requestTabs.currentChanged.connect(self.__updateTabSizes__)
        self.requestAreaWidget.addItem(self.requestTabs, "Requests")

        self.requestOps = RequestsOperations(self)
        self.requestAreaWidget.addItem(self.requestOps, "Operations")

        self.generalConfig = GlobalOverpassSettingUI(self)
        self.requestAreaWidget.addItem(self.generalConfig, "General")

        self.disambiguationWidget = DisambiguationWidget(
            self.__getRequestByName__, self.__applyTableRow__, self)
        self.requestAreaWidget.addItem(self.disambiguationWidget,
                                       "Disambiguation")

        self.headers = self.requestAreaWidget.findChildren(
            QAbstractButton, "qt_toolbox_toolboxbutton")
        self.requestAreaWidget.currentChanged.connect(
            self.__onToolTabChanged__)
        self.headers[0].setIcon(QIcon(os.path.join(picturesDir,
                                                   "arrowUp.png")))
        for i in range(1, len(self.headers)):
            self.headers[i].setIcon(
                QIcon(os.path.join(picturesDir, "arrowDown.png")))

        self.layout.addWidget(self.requestAreaWidget)

        self.setLayout(self.layout)

    def __getRequestByName__(self, requestName):
        for requestWidget in self.findChildren(RequestWidget):
            if requestWidget.getName() == requestName:
                return requestWidget.getRequest()
        return None

    def __applyTableRow__(self, name, data):
        filters, ids = data
        for requestWidget in self.findChildren(RequestWidget):
            if requestWidget.getName() == name:
                for newFilter in filters:
                    requestWidget.addFilter(newFilter)
                break

        if len(ids) > 0:
            idsRequestName = SetNameManagement.getUniqueSetName()
            request = OverpassRequest(OsmType.WAYS, Surround.NONE,
                                      idsRequestName)
            request.setIds(ids)
            self.addRequest(request)

            differenceOpName = SetNameManagement.getUniqueSetName()
            self.requestOps.addOp(OverpassDiff(name, differenceOpName),
                                  [idsRequestName])
            self.requestOps.setOutputSet(differenceOpName)

        logging.info("Configuration from the table row has been applied.")

    def __onToolTabChanged__(self, i):
        for h in range(len(self.headers)):
            if h == i:
                self.headers[h].setIcon(
                    QIcon(os.path.join(picturesDir, "arrowUp.png")))
            else:
                self.headers[h].setIcon(
                    QIcon(os.path.join(picturesDir, "arrowDown.png")))

    def __updateTabSizes__(self, index):
        for i in range(self.requestTabs.count()):
            if i != index:
                self.requestTabs.widget(i).setSizePolicy(
                    QSizePolicy.Ignored, QSizePolicy.Ignored)

        if index >= 0:
            self.requestTabs.widget(index).setSizePolicy(
                QSizePolicy.Preferred, QSizePolicy.Preferred)
            self.requestTabs.widget(index).resize(
                self.requestTabs.widget(index).minimumSizeHint())
            self.requestTabs.widget(index).adjustSize()

    def setOnRequestChanged(self, f):
        self.requestTabs.currentChanged.connect(f)

    def addRequestByFilters(self, filters=None):
        requestWidget = RequestWidget(self, self.keyValues)
        setName = requestWidget.requestName
        requestWidget.changePage(self.currentHtml)
        self.requestTabs.addTab(requestWidget, setName)
        self.requestOps.addRequest(setName)
        self.disambiguationWidget.addSet(setName)

        if filters is not None:
            for filter in filters:
                requestWidget.addFilter(filter)

    def addRequest(self, request):
        if not SetNameManagement.isAvailable(request.name):
            raise ValueError("There is another request with the same name.")
        else:
            SetNameManagement.assign(request.name)

        requestWidget = RequestWidget(self, self.keyValues, request)
        requestWidget.changePage(self.currentHtml)
        self.requestTabs.addTab(requestWidget, request.name)
        self.requestOps.addRequest(request.name)
        self.disambiguationWidget.addSet(request.name)

    def removeRequest(self):
        requestName = self.requestTabs.currentWidget().getName()
        self.requestOps.removeSetAndDependencies(requestName)
        self.disambiguationWidget.removeSet(requestName)
        currentRequestWidget = self.requestTabs.currentWidget()
        SetNameManagement.releaseName(currentRequestWidget.requestName)
        self.requestTabs.removeTab(self.requestTabs.currentIndex())
        currentRequestWidget.deleteLater()

    def requestsCount(self):
        return self.requestTabs.count()

    def getQuery(self):
        query = OverpassQuery(self.requestOps.outputSet())
        query.addDate(self.generalConfig.getDate())

        for i in range(self.requestTabs.count()):
            query.addRequest(self.requestTabs.widget(i).getRequest())

        for op in self.requestOps.ops:
            query.addSetsOp(op)

        return query

    def setQuery(self, query):
        self.reset()
        for request in query.requests:
            self.addRequest(request)
        for op in query.ops:
            self.requestOps.addOp(op)
        if query.config.get("date") is not None:
            self.generalConfig.setDate(
                datetime.strptime(query.config["date"], "%Y-%m-%dT00:00:00Z"))
        else:
            self.generalConfig.setDate()
        self.requestOps.setOutputSet(query.outputSet)

    def reset(self):
        while self.requestTabs.count() > 0:
            self.removeRequest()
        self.generalConfig.setDate()

    def updateMaps(self, html):
        self.currentHtml = html
        for requestWidget in self.findChildren(RequestWidget):
            requestWidget.changePage(html)

        return self.getCurrentMap()

    def updateMapFromRow(self):
        return self.updateMaps(
            self.disambiguationWidget.getHtmlFromSelectedRow())

    def getCurrentMap(self):
        if self.requestTabs.currentWidget() is None:
            return None
        else:
            return self.requestTabs.currentWidget().getMap()
コード例 #36
0
ファイル: window.py プロジェクト: daffodil/retext
class ReTextWindow(QMainWindow):
	def __init__(self, parent=None):
		QMainWindow.__init__(self, parent)
		self.resize(950, 700)
		screenRect = QDesktopWidget().screenGeometry()
		if globalSettings.windowGeometry:
			self.restoreGeometry(globalSettings.windowGeometry)
		else:
			self.move((screenRect.width()-self.width())/2, (screenRect.height()-self.height())/2)
		if not screenRect.contains(self.geometry()):
			self.showMaximized()
		if globalSettings.iconTheme:
			QIcon.setThemeName(globalSettings.iconTheme)
		if QIcon.themeName() in ('hicolor', ''):
			if not QFile.exists(icon_path + 'document-new.png'):
				QIcon.setThemeName(get_icon_theme())
		if QFile.exists(icon_path+'retext.png'):
			self.setWindowIcon(QIcon(icon_path+'retext.png'))
		elif QFile.exists('/usr/share/pixmaps/retext.png'):
			self.setWindowIcon(QIcon('/usr/share/pixmaps/retext.png'))
		else:
			self.setWindowIcon(QIcon.fromTheme('retext',
				QIcon.fromTheme('accessories-text-editor')))
		self.tabWidget = QTabWidget(self)
		self.initTabWidget()
		self.setCentralWidget(self.tabWidget)
		self.tabWidget.currentChanged.connect(self.changeIndex)
		self.tabWidget.tabCloseRequested.connect(self.closeTab)
		toolBar = QToolBar(self.tr('File toolbar'), self)
		self.addToolBar(Qt.TopToolBarArea, toolBar)
		self.editBar = QToolBar(self.tr('Edit toolbar'), self)
		self.addToolBar(Qt.TopToolBarArea, self.editBar)
		self.searchBar = QToolBar(self.tr('Search toolbar'), self)
		self.addToolBar(Qt.BottomToolBarArea, self.searchBar)
		toolBar.setVisible(not globalSettings.hideToolBar)
		self.editBar.setVisible(not globalSettings.hideToolBar)
		self.actionNew = self.act(self.tr('New'), 'document-new',
			self.createNew, shct=QKeySequence.New)
		self.actionNew.setPriority(QAction.LowPriority)
		self.actionOpen = self.act(self.tr('Open'), 'document-open',
			self.openFile, shct=QKeySequence.Open)
		self.actionOpen.setPriority(QAction.LowPriority)
		self.actionSetEncoding = self.act(self.tr('Set encoding'),
			trig=self.showEncodingDialog)
		self.actionSetEncoding.setEnabled(False)
		self.actionReload = self.act(self.tr('Reload'), 'view-refresh',
			lambda: self.currentTab.readTextFromFile())
		self.actionReload.setEnabled(False)
		self.actionSave = self.act(self.tr('Save'), 'document-save',
			self.saveFile, shct=QKeySequence.Save)
		self.actionSave.setEnabled(False)
		self.actionSave.setPriority(QAction.LowPriority)
		self.actionSaveAs = self.act(self.tr('Save as'), 'document-save-as',
			self.saveFileAs, shct=QKeySequence.SaveAs)
		self.actionNextTab = self.act(self.tr('Next tab'), 'go-next',
			lambda: self.switchTab(1), shct=Qt.CTRL+Qt.Key_PageDown)
		self.actionPrevTab = self.act(self.tr('Previous tab'), 'go-previous',
			lambda: self.switchTab(-1), shct=Qt.CTRL+Qt.Key_PageUp)
		self.actionPrint = self.act(self.tr('Print'), 'document-print',
			self.printFile, shct=QKeySequence.Print)
		self.actionPrint.setPriority(QAction.LowPriority)
		self.actionPrintPreview = self.act(self.tr('Print preview'), 'document-print-preview',
			self.printPreview)
		self.actionViewHtml = self.act(self.tr('View HTML code'), 'text-html', self.viewHtml)
		self.actionChangeEditorFont = self.act(self.tr('Change editor font'),
			trig=self.changeEditorFont)
		self.actionChangePreviewFont = self.act(self.tr('Change preview font'),
			trig=self.changePreviewFont)
		self.actionSearch = self.act(self.tr('Find text'), 'edit-find', shct=QKeySequence.Find)
		self.actionSearch.setCheckable(True)
		self.actionSearch.triggered[bool].connect(self.searchBar.setVisible)
		self.searchBar.visibilityChanged.connect(self.searchBarVisibilityChanged)
		self.actionPreview = self.act(self.tr('Preview'), shct=Qt.CTRL+Qt.Key_E,
			trigbool=self.preview)
		if QIcon.hasThemeIcon('document-preview'):
			self.actionPreview.setIcon(QIcon.fromTheme('document-preview'))
		elif QIcon.hasThemeIcon('preview-file'):
			self.actionPreview.setIcon(QIcon.fromTheme('preview-file'))
		elif QIcon.hasThemeIcon('x-office-document'):
			self.actionPreview.setIcon(QIcon.fromTheme('x-office-document'))
		else:
			self.actionPreview.setIcon(QIcon(icon_path+'document-preview.png'))
		self.actionLivePreview = self.act(self.tr('Live preview'), shct=Qt.CTRL+Qt.Key_L,
		trigbool=self.enableLivePreview)
		menuPreview = QMenu()
		menuPreview.addAction(self.actionLivePreview)
		self.actionPreview.setMenu(menuPreview)
		self.actionTableMode = self.act(self.tr('Table mode'), shct=Qt.CTRL+Qt.Key_T,
			trigbool=lambda x: self.currentTab.editBox.enableTableMode(x))
		if ReTextFakeVimHandler:
			self.actionFakeVimMode = self.act(self.tr('FakeVim mode'),
				shct=Qt.CTRL+Qt.ALT+Qt.Key_V, trigbool=self.enableFakeVimMode)
			if globalSettings.useFakeVim:
				self.actionFakeVimMode.setChecked(True)
				self.enableFakeVimMode(True)
		self.actionFullScreen = self.act(self.tr('Fullscreen mode'), 'view-fullscreen',
			shct=Qt.Key_F11, trigbool=self.enableFullScreen)
		self.actionFullScreen.setPriority(QAction.LowPriority)
		self.actionConfig = self.act(self.tr('Preferences'), icon='preferences-system',
			trig=self.openConfigDialog)
		self.actionConfig.setMenuRole(QAction.PreferencesRole)
		self.actionSaveHtml = self.act('HTML', 'text-html', self.saveFileHtml)
		self.actionPdf = self.act('PDF', 'application-pdf', self.savePdf)
		self.actionOdf = self.act('ODT', 'x-office-document', self.saveOdf)
		self.getExportExtensionsList()
		self.actionQuit = self.act(self.tr('Quit'), 'application-exit', shct=QKeySequence.Quit)
		self.actionQuit.setMenuRole(QAction.QuitRole)
		self.actionQuit.triggered.connect(self.close)
		self.actionUndo = self.act(self.tr('Undo'), 'edit-undo',
			lambda: self.currentTab.editBox.undo(), shct=QKeySequence.Undo)
		self.actionRedo = self.act(self.tr('Redo'), 'edit-redo',
			lambda: self.currentTab.editBox.redo(), shct=QKeySequence.Redo)
		self.actionCopy = self.act(self.tr('Copy'), 'edit-copy',
			lambda: self.currentTab.editBox.copy(), shct=QKeySequence.Copy)
		self.actionCut = self.act(self.tr('Cut'), 'edit-cut',
			lambda: self.currentTab.editBox.cut(), shct=QKeySequence.Cut)
		self.actionPaste = self.act(self.tr('Paste'), 'edit-paste',
			lambda: self.currentTab.editBox.paste(), shct=QKeySequence.Paste)
		self.actionUndo.setEnabled(False)
		self.actionRedo.setEnabled(False)
		self.actionCopy.setEnabled(False)
		self.actionCut.setEnabled(False)
		qApp = QApplication.instance()
		qApp.clipboard().dataChanged.connect(self.clipboardDataChanged)
		self.clipboardDataChanged()
		if enchant_available:
			self.actionEnableSC = self.act(self.tr('Enable'), trigbool=self.enableSpellCheck)
			self.actionSetLocale = self.act(self.tr('Set locale'), trig=self.changeLocale)
		self.actionWebKit = self.act(self.tr('Use WebKit renderer'), trigbool=self.enableWebKit)
		self.actionWebKit.setChecked(globalSettings.useWebKit)
		self.actionShow = self.act(self.tr('Show directory'), 'system-file-manager', self.showInDir)
		self.actionFind = self.act(self.tr('Next'), 'go-next', self.find,
			shct=QKeySequence.FindNext)
		self.actionFindPrev = self.act(self.tr('Previous'), 'go-previous',
			lambda: self.find(back=True), shct=QKeySequence.FindPrevious)
		self.actionCloseSearch = self.act(self.tr('Close'), 'window-close',
			lambda: self.searchBar.setVisible(False))
		self.actionCloseSearch.setPriority(QAction.LowPriority)
		self.actionHelp = self.act(self.tr('Get help online'), 'help-contents', self.openHelp)
		self.aboutWindowTitle = self.tr('About ReText')
		self.actionAbout = self.act(self.aboutWindowTitle, 'help-about', self.aboutDialog)
		self.actionAbout.setMenuRole(QAction.AboutRole)
		self.actionAboutQt = self.act(self.tr('About Qt'))
		self.actionAboutQt.setMenuRole(QAction.AboutQtRole)
		self.actionAboutQt.triggered.connect(qApp.aboutQt)
		availableMarkups = markups.get_available_markups()
		if not availableMarkups:
			print('Warning: no markups are available!')
		self.defaultMarkup = availableMarkups[0] if availableMarkups else None
		if globalSettings.defaultMarkup:
			mc = markups.find_markup_class_by_name(globalSettings.defaultMarkup)
			if mc and mc.available():
				self.defaultMarkup = mc
		if len(availableMarkups) > 1:
			self.chooseGroup = QActionGroup(self)
			markupActions = []
			for markup in availableMarkups:
				markupAction = self.act(markup.name, trigbool=self.markupFunction(markup))
				if markup == self.defaultMarkup:
					markupAction.setChecked(True)
				self.chooseGroup.addAction(markupAction)
				markupActions.append(markupAction)
		self.actionBold = self.act(self.tr('Bold'), shct=QKeySequence.Bold,
			trig=lambda: self.insertFormatting('bold'))
		self.actionItalic = self.act(self.tr('Italic'), shct=QKeySequence.Italic,
			trig=lambda: self.insertFormatting('italic'))
		self.actionUnderline = self.act(self.tr('Underline'), shct=QKeySequence.Underline,
			trig=lambda: self.insertFormatting('underline'))
		self.usefulTags = ('header', 'italic', 'bold', 'underline', 'numbering',
			'bullets', 'image', 'link', 'inline code', 'code block', 'blockquote')
		self.usefulChars = ('deg', 'divide', 'dollar', 'hellip', 'laquo', 'larr',
			'lsquo', 'mdash', 'middot', 'minus', 'nbsp', 'ndash', 'raquo',
			'rarr', 'rsquo', 'times')
		self.formattingBox = QComboBox(self.editBar)
		self.formattingBox.addItem(self.tr('Formatting'))
		self.formattingBox.addItems(self.usefulTags)
		self.formattingBox.activated[str].connect(self.insertFormatting)
		self.symbolBox = QComboBox(self.editBar)
		self.symbolBox.addItem(self.tr('Symbols'))
		self.symbolBox.addItems(self.usefulChars)
		self.symbolBox.activated.connect(self.insertSymbol)
		self.updateStyleSheet()
		menubar = self.menuBar()
		menuFile = menubar.addMenu(self.tr('File'))
		menuEdit = menubar.addMenu(self.tr('Edit'))
		menuHelp = menubar.addMenu(self.tr('Help'))
		menuFile.addAction(self.actionNew)
		menuFile.addAction(self.actionOpen)
		self.menuRecentFiles = menuFile.addMenu(self.tr('Open recent'))
		self.menuRecentFiles.aboutToShow.connect(self.updateRecentFiles)
		menuFile.addAction(self.actionShow)
		menuFile.addAction(self.actionSetEncoding)
		menuFile.addAction(self.actionReload)
		menuFile.addSeparator()
		menuFile.addAction(self.actionSave)
		menuFile.addAction(self.actionSaveAs)
		menuFile.addSeparator()
		menuFile.addAction(self.actionNextTab)
		menuFile.addAction(self.actionPrevTab)
		menuFile.addSeparator()
		menuExport = menuFile.addMenu(self.tr('Export'))
		menuExport.addAction(self.actionSaveHtml)
		menuExport.addAction(self.actionOdf)
		menuExport.addAction(self.actionPdf)
		if self.extensionActions:
			menuExport.addSeparator()
			for action, mimetype in self.extensionActions:
				menuExport.addAction(action)
			menuExport.aboutToShow.connect(self.updateExtensionsVisibility)
		menuFile.addAction(self.actionPrint)
		menuFile.addAction(self.actionPrintPreview)
		menuFile.addSeparator()
		menuFile.addAction(self.actionQuit)
		menuEdit.addAction(self.actionUndo)
		menuEdit.addAction(self.actionRedo)
		menuEdit.addSeparator()
		menuEdit.addAction(self.actionCut)
		menuEdit.addAction(self.actionCopy)
		menuEdit.addAction(self.actionPaste)
		menuEdit.addSeparator()
		if enchant_available:
			menuSC = menuEdit.addMenu(self.tr('Spell check'))
			menuSC.addAction(self.actionEnableSC)
			menuSC.addAction(self.actionSetLocale)
		menuEdit.addAction(self.actionSearch)
		menuEdit.addAction(self.actionChangeEditorFont)
		menuEdit.addAction(self.actionChangePreviewFont)
		menuEdit.addSeparator()
		if len(availableMarkups) > 1:
			self.menuMode = menuEdit.addMenu(self.tr('Default markup'))
			for markupAction in markupActions:
				self.menuMode.addAction(markupAction)
		menuFormat = menuEdit.addMenu(self.tr('Formatting'))
		menuFormat.addAction(self.actionBold)
		menuFormat.addAction(self.actionItalic)
		menuFormat.addAction(self.actionUnderline)
		menuEdit.addAction(self.actionWebKit)
		menuEdit.addSeparator()
		menuEdit.addAction(self.actionViewHtml)
		menuEdit.addAction(self.actionPreview)
		menuEdit.addAction(self.actionTableMode)
		if ReTextFakeVimHandler:
			menuEdit.addAction(self.actionFakeVimMode)
		menuEdit.addSeparator()
		menuEdit.addAction(self.actionFullScreen)
		menuEdit.addAction(self.actionConfig)
		menuHelp.addAction(self.actionHelp)
		menuHelp.addSeparator()
		menuHelp.addAction(self.actionAbout)
		menuHelp.addAction(self.actionAboutQt)
		toolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
		toolBar.addAction(self.actionNew)
		toolBar.addSeparator()
		toolBar.addAction(self.actionOpen)
		toolBar.addAction(self.actionSave)
		toolBar.addAction(self.actionPrint)
		toolBar.addSeparator()
		toolBar.addAction(self.actionPreview)
		toolBar.addAction(self.actionFullScreen)
		self.editBar.addAction(self.actionUndo)
		self.editBar.addAction(self.actionRedo)
		self.editBar.addSeparator()
		self.editBar.addAction(self.actionCut)
		self.editBar.addAction(self.actionCopy)
		self.editBar.addAction(self.actionPaste)
		self.editBar.addSeparator()
		self.editBar.addWidget(self.formattingBox)
		self.editBar.addWidget(self.symbolBox)
		self.searchEdit = QLineEdit(self.searchBar)
		self.searchEdit.setPlaceholderText(self.tr('Search'))
		self.searchEdit.returnPressed.connect(self.find)
		self.csBox = QCheckBox(self.tr('Case sensitively'), self.searchBar)
		self.searchBar.addWidget(self.searchEdit)
		self.searchBar.addSeparator()
		self.searchBar.addWidget(self.csBox)
		self.searchBar.addAction(self.actionFindPrev)
		self.searchBar.addAction(self.actionFind)
		self.searchBar.addAction(self.actionCloseSearch)
		self.searchBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
		self.searchBar.setVisible(False)
		self.autoSaveEnabled = globalSettings.autoSave
		if self.autoSaveEnabled:
			timer = QTimer(self)
			timer.start(60000)
			timer.timeout.connect(self.saveAll)
		self.ind = None
		if enchant_available:
			self.sl = globalSettings.spellCheckLocale
			if self.sl:
				try:
					enchant.Dict(self.sl)
				except Exception as e:
					print(e, file=sys.stderr)
					self.sl = None
			if globalSettings.spellCheck:
				self.actionEnableSC.setChecked(True)
		self.fileSystemWatcher = QFileSystemWatcher()
		self.fileSystemWatcher.fileChanged.connect(self.fileChanged)

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

	def updateStyleSheet(self):
		if globalSettings.styleSheet:
			sheetfile = QFile(globalSettings.styleSheet)
			sheetfile.open(QIODevice.ReadOnly)
			self.ss = QTextStream(sheetfile).readAll()
			sheetfile.close()
		else:
			palette = QApplication.palette()
			self.ss = 'html { color: %s; }\n' % palette.color(QPalette.WindowText).name()
			self.ss += 'td, th { border: 1px solid #c3c3c3; padding: 0 3px 0 3px; }\n'
			self.ss += 'table { border-collapse: collapse; }\n'

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

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

	def actIcon(self, name):
		return QIcon.fromTheme(name, QIcon(icon_path+name+'.png'))

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

	def createTab(self, fileName):
		self.currentTab = ReTextTab(self, fileName,
			previewState=int(globalSettings.livePreviewByDefault))
		self.tabWidget.addTab(self.currentTab.getSplitter(), self.tr("New document"))

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

	def docTypeChanged(self):
		markupClass = self.currentTab.getMarkupClass()
		if type(self.currentTab.markup) != markupClass:
			self.currentTab.setMarkupClass(markupClass)
			self.currentTab.updatePreviewBox()
		dtMarkdown = (markupClass == markups.MarkdownMarkup)
		dtMkdOrReST = dtMarkdown or (markupClass == markups.ReStructuredTextMarkup)
		self.formattingBox.setEnabled(dtMarkdown)
		self.symbolBox.setEnabled(dtMarkdown)
		self.actionUnderline.setEnabled(dtMarkdown)
		self.actionBold.setEnabled(dtMkdOrReST)
		self.actionItalic.setEnabled(dtMkdOrReST)
		canReload = bool(self.currentTab.fileName) and not self.autoSaveActive()
		self.actionSetEncoding.setEnabled(canReload)
		self.actionReload.setEnabled(canReload)

	def changeIndex(self, ind):
		self.currentTab = self.tabWidget.currentWidget().tab
		editBox = self.currentTab.editBox
		previewState = self.currentTab.previewState
		self.actionUndo.setEnabled(editBox.document().isUndoAvailable())
		self.actionRedo.setEnabled(editBox.document().isRedoAvailable())
		self.actionCopy.setEnabled(editBox.textCursor().hasSelection())
		self.actionCut.setEnabled(editBox.textCursor().hasSelection())
		self.actionPreview.setChecked(previewState >= PreviewLive)
		self.actionLivePreview.setChecked(previewState == PreviewLive)
		self.actionTableMode.setChecked(editBox.tableModeEnabled)
		self.editBar.setEnabled(previewState < PreviewNormal)
		self.ind = ind
		if self.currentTab.fileName:
			self.setCurrentFile()
		else:
			self.setWindowTitle(self.tr('New document') + '[*]')
			self.docTypeChanged()
		self.modificationChanged(editBox.document().isModified())
		editBox.setFocus(Qt.OtherFocusReason)

	def changeEditorFont(self):
		font, ok = QFontDialog.getFont(globalSettings.editorFont, self)
		if ok:
			globalSettings.editorFont = font
			for tab in self.iterateTabs():
				tab.editBox.updateFont()

	def changePreviewFont(self):
		font, ok = QFontDialog.getFont(globalSettings.font, self)
		if ok:
			globalSettings.font = font
			for tab in self.iterateTabs():
				tab.updatePreviewBox()

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

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

	def enableWebKit(self, enable):
		globalSettings.useWebKit = enable
		for i in range(self.tabWidget.count()):
			splitter = self.tabWidget.widget(i)
			tab = splitter.tab
			tab.previewBox.disconnectExternalSignals()
			tab.previewBox.setParent(None)
			tab.previewBox.deleteLater()
			tab.previewBox = tab.createPreviewBox(tab.editBox)
			tab.previewBox.setMinimumWidth(125)
			splitter.addWidget(tab.previewBox)
			splitter.setSizes((50, 50))
			tab.updatePreviewBox()
			tab.updateBoxesVisibility()

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

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

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

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

	def enableSpellCheck(self, yes):
		if yes:
			self.setAllDictionaries(enchant.Dict(self.sl or None))
		else:
			self.setAllDictionaries(None)
		globalSettings.spellCheck = yes

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

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

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

	def find(self, back=False):
		flags = QTextDocument.FindFlags()
		if back:
			flags |= QTextDocument.FindBackward
		if self.csBox.isChecked():
			flags |= QTextDocument.FindCaseSensitively
		text = self.searchEdit.text()
		editBox = self.currentTab.editBox
		cursor = editBox.textCursor()
		newCursor = editBox.document().find(text, cursor, flags)
		if not newCursor.isNull():
			editBox.setTextCursor(newCursor)
			return self.setSearchEditColor(True)
		cursor.movePosition(QTextCursor.End if back else QTextCursor.Start)
		newCursor = editBox.document().find(text, cursor, flags)
		if not newCursor.isNull():
			editBox.setTextCursor(newCursor)
			return self.setSearchEditColor(True)
		self.setSearchEditColor(False)

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

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

	def setCurrentFile(self):
		self.setWindowTitle("")
		self.tabWidget.setTabText(self.ind, self.currentTab.getDocumentTitle(baseName=True))
		self.tabWidget.setTabToolTip(self.ind, self.currentTab.fileName or '')
		self.setWindowFilePath(self.currentTab.fileName)
		files = readListFromSettings("recentFileList")
		while self.currentTab.fileName in files:
			files.remove(self.currentTab.fileName)
		files.insert(0, self.currentTab.fileName)
		if len(files) > 10:
			del files[10:]
		writeListToSettings("recentFileList", files)
		QDir.setCurrent(QFileInfo(self.currentTab.fileName).dir().path())
		self.docTypeChanged()

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

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

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

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

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

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

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

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

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

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

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

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

	def saveFile(self):
		self.saveFileMain(dlg=False)

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

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

	def saveFileMain(self, dlg):
		if (not self.currentTab.fileName) or dlg:
			markupClass = self.currentTab.getMarkupClass()
			if (markupClass is None) or not hasattr(markupClass, 'default_extension'):
				defaultExt = self.tr("Plain text (*.txt)")
				ext = ".txt"
			else:
				defaultExt = self.tr('%s files',
					'Example of final string: Markdown files') \
					% markupClass.name + ' (' + str.join(' ',
					('*'+extension for extension in markupClass.file_extensions)) + ')'
				if markupClass == markups.MarkdownMarkup:
					ext = globalSettings.markdownDefaultFileExtension
				elif markupClass == markups.ReStructuredTextMarkup:
					ext = globalSettings.restDefaultFileExtension
				else:
					ext = markupClass.default_extension
			newFileName = QFileDialog.getSaveFileName(self,
				self.tr("Save file"), "", defaultExt)[0]
			if newFileName:
				if not QFileInfo(newFileName).suffix():
					newFileName += ext
				if self.currentTab.fileName:
					self.fileSystemWatcher.removePath(self.currentTab.fileName)
				self.currentTab.fileName = newFileName
				self.actionSetEncoding.setDisabled(self.autoSaveActive())
		if self.currentTab.fileName:
			if self.currentTab.saveTextToFile():
				self.setCurrentFile()
				self.currentTab.editBox.document().setModified(False)
				self.setWindowModified(False)
				return True
			else:
				QMessageBox.warning(self, '',
				self.tr("Cannot save to file because it is read-only!"))
		return False

	def saveHtml(self, fileName):
		if not QFileInfo(fileName).suffix():
			fileName += ".html"
		try:
			htmltext = self.currentTab.getHtml(includeStyleSheet=False,
				webenv=True)
		except Exception:
			return self.printError()
		htmlFile = QFile(fileName)
		htmlFile.open(QIODevice.WriteOnly)
		html = QTextStream(htmlFile)
		if globalSettings.defaultCodec:
			html.setCodec(globalSettings.defaultCodec)
		html << htmltext
		htmlFile.close()

	def textDocument(self):
		td = QTextDocument()
		td.setMetaInformation(QTextDocument.DocumentTitle,
		                      self.currentTab.getDocumentTitle())
		if self.ss:
			td.setDefaultStyleSheet(self.ss)
		td.setHtml(self.currentTab.getHtml())
		td.setDefaultFont(globalSettings.font)
		return td

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

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

	def getDocumentForPrint(self):
		if globalSettings.useWebKit:
			return self.currentTab.previewBox
		try:
			return self.textDocument()
		except Exception:
			self.printError()

	def standardPrinter(self):
		printer = QPrinter(QPrinter.HighResolution)
		printer.setDocName(self.currentTab.getDocumentTitle())
		printer.setCreator('ReText %s' % app_version)
		return printer

	def savePdf(self):
		self.currentTab.updatePreviewBox()
		fileName = QFileDialog.getSaveFileName(self,
			self.tr("Export document to PDF"),
			"", self.tr("PDF files (*.pdf)"))[0]
		if fileName:
			if not QFileInfo(fileName).suffix():
				fileName += ".pdf"
			printer = self.standardPrinter()
			printer.setOutputFormat(QPrinter.PdfFormat)
			printer.setOutputFileName(fileName)
			document = self.getDocumentForPrint()
			if document != None:
				document.print(printer)

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

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

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

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

	def modificationChanged(self, changed):
		if self.autoSaveActive():
			changed = False
		self.actionSave.setEnabled(changed)
		self.setWindowModified(changed)

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

	def insertFormatting(self, formatting):
		cursor = self.currentTab.editBox.textCursor()
		text = cursor.selectedText()
		moveCursorTo = None

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

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

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

		if formatting not in toinsert:
			return

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

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

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

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

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

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

	def closeEvent(self, closeevent):
		for ind in range(self.tabWidget.count()):
			if not self.maybeSave(ind):
				return closeevent.ignore()
		if globalSettings.saveWindowGeometry and not self.isMaximized():
			globalSettings.windowGeometry = self.saveGeometry()
		closeevent.accept()

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

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

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

	def setDefaultMarkup(self, markupClass):
		self.defaultMarkup = markupClass
		defaultName = markups.get_available_markups()[0].name
		writeToSettings('defaultMarkup', markupClass.name, defaultName)
		for tab in self.iterateTabs():
			if not tab.fileName:
				tab.setMarkupClass(markupClass)
				tab.updatePreviewBox()
		self.docTypeChanged()
コード例 #37
0
class MainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        url = "http://127.0.0.1:43110/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D/"
        if "url" in kwargs:
            url = kwargs["url"]
            del kwargs["url"]

        if "zeronet_path" in kwargs:
            self.zeronet_path = kwargs["zeronet_path"]
            del kwargs["zeronet_path"]

        super(MainWindow, self).__init__(*args, **kwargs)

        # Tabs
        self.tabs = QTabWidget()
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.close_tab)

        # New tab button
        #self.tab_add_button_index = self.tabs.addTab(QWidget(), '+')
        self.add_tab_button = QToolButton()
        self.add_tab_button.setText('+')
        self.add_tab_button.setStyleSheet(
            'QToolButton {border: none; margin: 4px 20px 4px 0px; height: 480px; border-left: 1px solid lightgrey; padding: 0px 4px 0px 4px; font-weight: bold; color: #5d5b59}'
            'QToolButton:hover { background-color: lightgrey }'
            'QToolButton:pressed { background-color: grey }')
        self.add_tab_button.clicked.connect(self.new_tab_clicked)
        self.tabs.setCornerWidget(self.add_tab_button)

        # Navigation bar
        self.navigation = NavigationBar()
        self.navigation.url_bar.returnPressed.connect(self.navigate_to_url)

        # Back
        self.navigation.back_btn.triggered.connect(
            lambda: self.tabs.currentWidget().back())

        # Next
        self.navigation.next_btn.triggered.connect(
            lambda: self.tabs.currentWidget().forward())

        # Reload
        self.navigation.reload_btn.triggered.connect(
            lambda: self.tabs.currentWidget().reload())
        self.navigation.shortcut_reload.activated.connect(
            lambda: self.tabs.currentWidget().reload())
        self.navigation.shortcut_reload_f5.activated.connect(
            lambda: self.tabs.currentWidget().reload())

        # Home
        self.navigation.home_btn.triggered.connect(self.go_home)

        # Menu: Edit config action
        self.navigation.edit_config_action.triggered.connect(
            self.edit_zeronet_config_file)

        # Add new tab
        self.add_new_tab(url, "Home")

        # Get everything fitting in the main window
        self.addToolBar(self.navigation)
        self.setCentralWidget(self.tabs)
        self.show()
        self.setWindowTitle("ZeroNet Browser")
        self.setWindowIcon(QIcon("icons/zeronet-logo.svg"))
        self.showMaximized()

    def contextMenuEvent(self, event):
        print(event)

    def update_url_bar(self, q, browser=None):

        if browser != self.tabs.currentWidget():
            # If this signal is not from the current tab, ignore
            return

        url_array = q.toString().split('/')[3:]
        formatted_url = '/'.join(str(x) for x in url_array)
        self.navigation.url_bar.setText('zero://' + formatted_url)
        self.navigation.url_bar.setCursorPosition(0)

        if (self.tabs.currentWidget().can_go_back()):
            self.navigation.back_btn.setDisabled(False)
        else:
            self.navigation.back_btn.setDisabled(True)

        if (self.tabs.currentWidget().can_go_forward()):
            self.navigation.next_btn.setDisabled(False)
        else:
            self.navigation.next_btn.setDisabled(True)

    def navigate_to_url(self):
        # Get url
        url = self.navigation.url_bar.text()

        if url.startswith('zero://'):
            # ZeroNet protocol
            url_array = url.split('/')
            url = 'http://127.0.0.1:43110/' + url_array[2]
        elif url.startswith('http://'):
            # http protocol
            pass
        else:
            # Nothing mentionned
            url = 'http://127.0.0.1:43110/' + url

        self.tabs.currentWidget().setUrl(QUrl(url))

    def go_home(self):
        self.tabs.currentWidget().setUrl(
            QUrl("http://127.0.0.1:43110/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D/"))

    def new_tab_clicked(self):
        self.add_new_tab(
            "http://127.0.0.1:43110/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D/",
            "Home")

    def get_link_url_from_context_menu(self):
        tab = self.tabs.currentWidget()
        page = tab.page()
        context = page.contextMenuData()
        qurl = context.linkUrl()
        return qurl.url()

    def open_in_new_tab(self):
        url = self.get_link_url_from_context_menu()
        self.add_new_tab(url, "Home")

    # Doesnt feel right to have it here but it is working
    def open_in_new_window(self):
        url = self.get_link_url_from_context_menu()
        kwargs = {"url": url}
        self.window = self.__class__(**kwargs)

    def add_new_tab(self, qurl, label):
        # Instead of browser it should be called WebView !
        browser = Browser()

        # Triggered open in new tab
        openLinkInNewTabAction = browser.pageAction(
            QWebEnginePage.OpenLinkInNewTab)
        openLinkInNewWindowAction = browser.pageAction(
            QWebEnginePage.OpenLinkInNewWindow)
        openLinkInNewTabAction.triggered.connect(self.open_in_new_tab)
        openLinkInNewWindowAction.triggered.connect(self.open_in_new_window)
        self.addAction(openLinkInNewTabAction)

        browser.urlChanged.connect(
            lambda qurl, browser=browser: self.update_url_bar(qurl, browser))
        indexTab = self.tabs.addTab(browser, label)
        # Maybe change current index after loading?
        self.tabs.setCurrentIndex(indexTab)
        # We need to update the url !
        if qurl.startswith('zero://'):
            # ZeroNet protocol
            url_array = qurl.split('/')
            qurl = 'http://127.0.0.1:43110/' + url_array[2]
        elif qurl.startswith('http://'):
            # http protocol
            pass
        else:
            # Nothing mentionned
            qurl = 'http://127.0.0.1:43110/' + qurl

        currentTab = self.tabs.currentWidget()
        currentTab.loadFinished.connect(self.page_loaded)
        index = self.tabs.currentIndex()
        currentTab.titleChanged.connect(
            lambda title, index=index: self.tabs.setTabText(index, title))
        currentTab.iconChanged.connect(
            lambda icon, index=index: self.tabs.setTabIcon(index, icon))

        currentTab.setUrl(QUrl(qurl))
        return indexTab

    def page_loaded(self, ok):
        if ok:
            currentTab = self.tabs.currentWidget()
            index = self.tabs.currentIndex()
            label = currentTab.title()
            icon = currentTab.icon()
            self.tabs.setTabIcon(index, icon)
            self.tabs.setTabText(index, label)

    def close_tab(self, index):
        if self.tabs.count() == 1:
            self.tabs.currentWidget().setUrl(
                QUrl(
                    "http://127.0.0.1:43110/1HeLLo4uzjaLetFx6NH3PMwFP3qbRbTf3D/"
                ))
            return
        self.tabs.removeTab(index)

    def edit_zeronet_config_file(self):
        filepath = os.path.join(os.sep, self.zeronet_path, "zeronet.conf")

        if sys.platform.startswith('darwin'):  # macOS
            subprocess.run(['open', filepath])
        elif sys.platform.startswith('win'):  # Windows
            os.startfile(filepath)
        else:  # linux variants
            subprocess.run(['xdg-open', filepath])
コード例 #38
0
ファイル: prob4.py プロジェクト: GiantZwlin/SoftPracticeWork
class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setUI()

    def setUI(self):
        self.setWindowTitle('Browser')

        self.urlBar = QLineEdit()
        self.urlBar.returnPressed.connect(self.navigatorToUrl)

        self.tabs = QTabWidget()
        self.tabs.setDocumentMode(True)
        self.tabs.tabBarDoubleClicked.connect(self.tabOpenDoubleClick)
        self.tabs.currentChanged.connect(self.currentTabChanged)
        self.tabs.setTabsClosable(True)
        self.tabs.tabCloseRequested.connect(self.closeCurrentTab)

        self.addNewTab(QUrl('https://baidu.com'), 'Homepage')
        self.setCentralWidget(self.tabs)

        navigationBar = QToolBar('Navigation')
        navigationBar.setIconSize(QSize(16, 16))
        self.addToolBar(navigationBar)

        backButton = QAction(QIcon('icons/back.png'), 'Back', self)
        nextButton = QAction(QIcon('icons/next.png'), 'Forward', self)
        stopButton = QAction(QIcon('icons/cross.png'), 'Stop', self)
        reloadButton = QAction(QIcon('icons/renew.png'), 'Reload', self)

        backButton.triggered.connect(self.tabs.currentWidget().back)
        nextButton.triggered.connect(self.tabs.currentWidget().forward)
        stopButton.triggered.connect(self.tabs.currentWidget().stop)
        reloadButton.triggered.connect(self.tabs.currentWidget().reload)

        navigationBar.addAction(backButton)
        navigationBar.addAction(nextButton)
        navigationBar.addAction(stopButton)
        navigationBar.addAction(reloadButton)
        navigationBar.addSeparator()
        navigationBar.addWidget(self.urlBar)
        self.resize(1500, 900)
        self.show()

    def addNewTab(self, qurl=QUrl(''), label='blank'):
        browser = QWebEngineView()
        browser.load(qurl)

        i = self.tabs.addTab(browser, label)
        self.tabs.setCurrentIndex(i)

        browser.urlChanged.connect(
            lambda qurl, browser=browser: self.reNewUrlBar(qurl, browser))
        self.urlBar.setText(qurl.toString())
        browser.loadFinished.connect(lambda _, i=i, browser=browser: self.tabs.
                                     setTabText(i,
                                                browser.page().title()))

    def navigatorToUrl(self):
        self.tabs.currentWidget().load(QUrl(self.urlBar.text()))

    def closeCurrentTab(self, i):
        if self.tabs.count() < 2:
            return
        self.tabs.removeTab(i)

    def currentTabChanged(self, i):
        qurl = self.tabs.currentWidget().url()
        self.reNewUrlBar(qurl, self.tabs.currentWidget())

    def tabOpenDoubleClick(self, i):
        if i == -1:
            self.addNewTab(QUrl("https://baidu.com"))

    def reNewUrlBar(self, q, browser=None):
        if browser != self.tabs.currentWidget():
            return
        self.urlBar.setText(q.toString())
        self.urlBar.setCursorPosition(0)
コード例 #39
0
ファイル: RGui.py プロジェクト: archelangelo/RamanKit
class RGui(QMainWindow):

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

    def initUI(self):
        # Main window set up
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowTitle("RGui")

        # File menu
        self.fileMenu = self.menuBar().addMenu('&File')
        self.fileMenu.addAction('&Open', self.openFile,
            Qt.CTRL + Qt.Key_O)
        self.fileMenu.addAction('&Save figure', self.saveFigure,
            Qt.SHIFT + Qt.CTRL + Qt.Key_S)

        # Main widget and its layout
        # subWidget is embedded in the right half of mainWidget
        self.mainWidget = QSplitter(Qt.Horizontal, self)
        self.subWidget = QSplitter(Qt.Vertical, self)

        # Plot canvas set up, added to layout
        self.canvas = CanvasWidget(self,
            width = 10, height = 8, dpi = 100)

        # Set up the control panel
        self.ctrPane = QTabWidget(self)
        self.initCtrPane()

        # List widget embedded in Tab widget
        self.selectPane = QTabWidget(self.subWidget)
        listWidget = QListWidget(self.selectPane)
        listWidget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.selectPane.addTab(listWidget, 'Untitled')
        self.firstPlot = True
        self.spec = []

        # Set up the layouts
        self.mainWidget.addWidget(self.canvas)
        self.subWidget.addWidget(self.ctrPane)
        self.subWidget.addWidget(self.selectPane)
        self.mainWidget.addWidget(self.subWidget)

        # Set up the MainWindow
        self.mainWidget.setFocus()
        self.setCentralWidget(self.mainWidget)
        self.setGeometry(300, 300, 500, 400)
        self.statusBar()

    def initCtrPane(self):
        # main control set up
        mainCtr = QFrame(self.ctrPane)
        mainCtr.setFrameShape(QFrame.StyledPanel)
        mainCtr.setFrameShadow(QFrame.Sunken)
        # buttons and controls
        backSubButton = QPushButton('Background Subtraction', mainCtr)
        backSubButton.clicked.connect(self.backSub)
        plotButton = QPushButton('Plot', mainCtr)
        plotButton.clicked.connect(self.updatePlot1)
        newTabButton = QPushButton('New tab', mainCtr)
        newTabButton.clicked.connect(self.addTab)
        self.plotPeak = QCheckBox('Plot fitted peak', mainCtr)
        holdPlot = QCheckBox('Hold plot', mainCtr)
        holdPlot.stateChanged.connect(self.canvas.toggleHold)
        # layout
        mainLayout = QGridLayout(mainCtr)
        mainLayout.addWidget(backSubButton, 0, 0)
        mainLayout.addWidget(plotButton, 0, 1)
        mainLayout.addWidget(newTabButton, 1, 0)
        mainLayout.addWidget(self.plotPeak, 2, 0)
        mainLayout.addWidget(holdPlot, 2, 1)
        mainCtr.setLayout(mainLayout)

        self.ctrPane.addTab(mainCtr, 'Main Control')

        # NMF control set up
        NMFCtr = QFrame(self.ctrPane)
        NMFCtr.setFrameShape(QFrame.StyledPanel)
        NMFCtr.setFrameShadow(QFrame.Sunken)
        # input & buttons
        self.alphaBox = MyDoubleBox(NMFCtr)
        self.l1RatioBox = MyDoubleBox(NMFCtr)
        self.loadSettings()
        NMFButton = QPushButton('NMF', NMFCtr)
        NMFButton.clicked.connect(self.NMF)
        # layout
        NMFLayout = QGridLayout(NMFCtr)
        NMFLayout.addWidget(QLabel('α'), 0, 0)
        NMFLayout.addWidget(QLabel('l1 ratio'), 1, 0)
        NMFLayout.addWidget(self.alphaBox, 0, 1)
        NMFLayout.addWidget(self.l1RatioBox, 1, 1)
        NMFLayout.addWidget(NMFButton, 2, 0, 1, 2)

        NMFCtr.setLayout(NMFLayout)

        self.ctrPane.addTab(NMFCtr, 'NMF Control')

    # slots

    def openFile(self):
        fileName = QFileDialog.getOpenFileName(self, "Open file")
        if fileName[0]:
            self.addSpec(fileName[0],
                os.path.basename(fileName[0]))

    def saveFigure(self):
        fileName = QFileDialog.getSaveFileName(self, "Save current figure")
        if fileName[0]:
            self.canvas.saveFigure(fileName)

    def addSpec(self, fileName, title):
        # import spectra from file
        j = self.selectPane.currentIndex()
        l = self.spec[j].nSpec()
        listWidget = self.selectPane.currentWidget()
        self.selectPane.setTabText(j, title)
        self.spec[j].addSpec(fileName, np.array([[0, 0, 0]]))
        for i in range(l + 1, self.spec[j]._coord.shape[0]):
            newItem = QListWidgetItem("[%d %d %d]" % \
                tuple(self.spec[j]._coord[i]), listWidget)
            newItem.setData(Qt.UserRole,
                QVariant([j, i]))
            listWidget.addItem(newItem)
        listWidget.itemDoubleClicked.connect(self.updatePlot2)

    def addTab(self):
        listWidget = QListWidget(self.selectPane)
        listWidget.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.selectPane.addTab(listWidget, 'Untitled')
        self.spec.append(rd.SpecData())

    # defines two update plot slots
    def updatePlot1(self):
        # slot for multiple items
        items = self.selectPane.currentWidget().selectedItems()
        if not items:
            pass # raise error
        bArray = items[0].data(Qt.UserRole)
        n = int(bArray[0])
        use = []
        for item in items:
            bArray = item.data(Qt.UserRole)
            use.append(int(bArray[1]))
        use = np.array(use).reshape(-1)
        self.canvas.updatePlot(self.spec[n], use, self.plotPeak.isChecked())

    def updatePlot2(self, item):
        # slot for a single item
        bArray = item.data(Qt.UserRole)
        n = int(bArray[0])
        i = int(bArray[1])
        use = np.array(i).reshape(-1)
        self.canvas.updatePlot(self.spec[n], use, self.plotPeak.isChecked())

    # Here comes the data analysis operations

    def backSub(self):
        if self.firstPlot:
            pass # raise an error

        fileName = QFileDialog.getOpenFileName(self, "Open background file")
        if fileName[0]:
            bg = rd.SpecData(fileName[0])
            listWidget = self.selectPane.currentWidget()
            item = listWidget.item(0)
            n = item.data(Qt.UserRole)[0]
            newSpec = self.spec[n].backSub(bg.getSpec(0))
            self.addSpec(newSpec, self.currentTabTitle() + '_subtracted')

    def NMF(self):
        if self.firstPlot:
            pass # raise an error

        item = self.selectPane.currentWidget().item(0)
        n = item.data(Qt.UserRole)[0]
        alpha = float(self.alphaBox.text())
        l1Ratio = float(self.l1RatioBox.text())
        model = self.spec[n].NMF(n_components = 3, init = 'nndsvd',
            alpha = alpha, l1_ratio = l1Ratio, sparseness = 'data')
        newSpec = rd.SpecData()
        newSpec._data = np.append(self.spec[n]._data[[0]],
            model.components_, axis = 0)
        newSpec._coord = np.array([[0, 0, 0], [0, 0, 1], [0, 0, 2]])
        newSpec._dim = np.array([1, 1, 3])
        self.addSpec(newSpec, self.currentTabTitle() + '_NMF')

        # save settings
        self.saveSettings()

    def saveSettings(self):
        settings = QSettings(QSettings.UserScope, 'Georgia Tech', 'RamanGui',
            self)
        settings.setValue('alpha', self.alphaBox.text())
        settings.setValue('l1Ratio', self.l1RatioBox.text())

    def loadSettings(self):
        settings = QSettings(QSettings.UserScope, 'Georgia Tech', 'RamanGui',
            self)
        if settings.contains('alpha'):
            self.alphaBox.setText(settings.value('alpha'))
        if settings.contains('l1Ratio'):
            self.l1RatioBox.setText(settings.value('l1Ratio'))

    def currentTabTitle(self):
        return self.selectPane.tabText(self.selectPane.currentIndex())
コード例 #40
0
ファイル: orderform.py プロジェクト: Axel-Erfurt/pyqt5
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()

        fileMenu = QMenu("&File", self)
        newAction = fileMenu.addAction("&New...")
        newAction.setShortcut("Ctrl+N")
        self.printAction = fileMenu.addAction("&Print...", self.printFile)
        self.printAction.setShortcut("Ctrl+P")
        self.printAction.setEnabled(False)
        quitAction = fileMenu.addAction("E&xit")
        quitAction.setShortcut("Ctrl+Q")
        self.menuBar().addMenu(fileMenu)

        self.letters = QTabWidget()

        newAction.triggered.connect(self.openDialog)
        quitAction.triggered.connect(self.close)

        self.setCentralWidget(self.letters)
        self.setWindowTitle("Order Form")

    def createLetter(self, name, address, orderItems, sendOffers):
        editor = QTextEdit()
        tabIndex = self.letters.addTab(editor, name)
        self.letters.setCurrentIndex(tabIndex)

        cursor = editor.textCursor()
        cursor.movePosition(QTextCursor.Start)
        topFrame = cursor.currentFrame()
        topFrameFormat = topFrame.frameFormat()
        topFrameFormat.setPadding(16)
        topFrame.setFrameFormat(topFrameFormat)

        textFormat = QTextCharFormat()
        boldFormat = QTextCharFormat()
        boldFormat.setFontWeight(QFont.Bold)

        referenceFrameFormat = QTextFrameFormat()
        referenceFrameFormat.setBorder(1)
        referenceFrameFormat.setPadding(8)
        referenceFrameFormat.setPosition(QTextFrameFormat.FloatRight)
        referenceFrameFormat.setWidth(QTextLength(QTextLength.PercentageLength, 40))
        cursor.insertFrame(referenceFrameFormat)

        cursor.insertText("A company", boldFormat)
        cursor.insertBlock()
        cursor.insertText("321 City Street")
        cursor.insertBlock()
        cursor.insertText("Industry Park")
        cursor.insertBlock()
        cursor.insertText("Another country")

        cursor.setPosition(topFrame.lastPosition())

        cursor.insertText(name, textFormat)
        for line in address.split("\n"):
            cursor.insertBlock()
            cursor.insertText(line)

        cursor.insertBlock()
        cursor.insertBlock()

        date = QDate.currentDate()
        cursor.insertText("Date: %s" % date.toString('d MMMM yyyy'),
                textFormat)
        cursor.insertBlock()

        bodyFrameFormat = QTextFrameFormat()
        bodyFrameFormat.setWidth(QTextLength(QTextLength.PercentageLength, 100))
        cursor.insertFrame(bodyFrameFormat)

        cursor.insertText("I would like to place an order for the following "
                "items:", textFormat)
        cursor.insertBlock()
        cursor.insertBlock()

        orderTableFormat = QTextTableFormat()
        orderTableFormat.setAlignment(Qt.AlignHCenter)
        orderTable = cursor.insertTable(1, 2, orderTableFormat)

        orderFrameFormat = cursor.currentFrame().frameFormat()
        orderFrameFormat.setBorder(1)
        cursor.currentFrame().setFrameFormat(orderFrameFormat)

        cursor = orderTable.cellAt(0, 0).firstCursorPosition()
        cursor.insertText("Product", boldFormat)
        cursor = orderTable.cellAt(0, 1).firstCursorPosition()
        cursor.insertText("Quantity", boldFormat)

        for text, quantity in orderItems:
            row = orderTable.rows()

            orderTable.insertRows(row, 1)
            cursor = orderTable.cellAt(row, 0).firstCursorPosition()
            cursor.insertText(text, textFormat)
            cursor = orderTable.cellAt(row, 1).firstCursorPosition()
            cursor.insertText(str(quantity), textFormat)

        cursor.setPosition(topFrame.lastPosition())

        cursor.insertBlock()

        cursor.insertText("Please update my records to take account of the "
                "following privacy information:")
        cursor.insertBlock()

        offersTable = cursor.insertTable(2, 2)

        cursor = offersTable.cellAt(0, 1).firstCursorPosition()
        cursor.insertText("I want to receive more information about your "
                "company's products and special offers.", textFormat)
        cursor = offersTable.cellAt(1, 1).firstCursorPosition()
        cursor.insertText("I do not want to receive any promotional "
                "information from your company.", textFormat)

        if sendOffers:
            cursor = offersTable.cellAt(0, 0).firstCursorPosition()
        else:
            cursor = offersTable.cellAt(1, 0).firstCursorPosition()

        cursor.insertText('X', boldFormat)

        cursor.setPosition(topFrame.lastPosition())
        cursor.insertBlock()
        cursor.insertText("Sincerely,", textFormat)
        cursor.insertBlock()
        cursor.insertBlock()
        cursor.insertBlock()
        cursor.insertText(name)

        self.printAction.setEnabled(True)

    def createSample(self):
        dialog = DetailsDialog('Dialog with default values', self)
        self.createLetter('Mr Smith',
                '12 High Street\nSmall Town\nThis country',
                dialog.orderItems(), True)

    def openDialog(self):
        dialog = DetailsDialog("Enter Customer Details", self)

        if dialog.exec_() == QDialog.Accepted:
            self.createLetter(dialog.senderName(), dialog.senderAddress(),
                    dialog.orderItems(), dialog.sendOffers())

    def printFile(self):
        editor = self.letters.currentWidget()
        printer = QPrinter()

        dialog = QPrintDialog(printer, self)
        dialog.setWindowTitle("Print Document")

        if editor.textCursor().hasSelection():
            dialog.addEnabledOption(QAbstractPrintDialog.PrintSelection)

        if dialog.exec_() != QDialog.Accepted:
            return

        editor.print_(printer)