예제 #1
0
    def create_dockwidget(self):
        """Add to parent QMainWindow as a dock widget"""

        # This is not clear yet why the following do not work...
        # (see Issue #880)
        ##         # Using Qt.Window window flags solves Issue #880 (detached dockwidgets
        ##         # are not painted after restarting Spyder and restoring their hexstate)
        ##         # but it does not work with PyQt <=v4.7 (dockwidgets can't be docked)
        ##         # or non-Windows platforms (lot of warnings are printed out)
        ##         # (so in those cases, we use the default window flags: Qt.Widget):
        ##         flags = Qt.Widget if is_old_pyqt or os.name != 'nt' else Qt.Window
        dock = QDockWidget(self.get_plugin_title(), self.main)  #, flags)

        dock.setObjectName(self.__class__.__name__ + "_dw")
        dock.setAllowedAreas(self.ALLOWED_AREAS)
        dock.setFeatures(self.FEATURES)
        dock.setWidget(self)
        self.update_margins()
        self.connect(dock, SIGNAL('visibilityChanged(bool)'),
                     self.visibility_changed)
        self.dockwidget = dock
        short = self.get_option("shortcut", None)
        if short is not None:
            shortcut = QShortcut(QKeySequence(short), self.main,
                                 self.switch_to_plugin)
            self.register_shortcut(shortcut,
                                   "_",
                                   "Switch to %s" % self.CONF_SECTION,
                                   default=short)
        return (dock, self.LOCATION)
예제 #2
0
class Main(plugin.Plugin):
    " dock Class "
    def initialize(self):
        " Init Class dock "
        self.dock = QDockWidget()
        self.dock.setFeatures(QDockWidget.DockWidgetFloatable |
                              QDockWidget.DockWidgetMovable)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.boton = QPushButton(QIcon.fromTheme("media-eject"),
                                 ' Open Media ', self.dock)
        try:
            self.factory = KPluginLoader("dragonpart").factory()
            self.part = self.factory.create(self)
            self.boton.clicked.connect(lambda: self.part.openUrl(KUrl(str(
                QFileDialog.getOpenFileName(self.dock, ' Open Media File ',
                path.expanduser("~"), ';;'.join(['(*.{})'.format(e) for e in
                ['ogv', 'webm', 'avi', 'mpg', 'mpeg', '3gp', 'wmv', 'mp3',
                'asf', 'dat', 'flv', 'flac', 'ogg', 'mkv', 'mov', 'swf', 'wav',
                'rm', 'm4v', 'aaf', 'mp4', 'raw', '*']]))))))
            self.dock.setWidget(self.part.widget())
        except:
            self.dock.setWidget(QLabel(""" <center> <h3>ಠ_ಠ<br>
            ERROR: Please, install Dragon Player and PyKDE ! </h3><br>
            <br><i> (Sorry, cant embed non-Qt Apps). </i>><center>"""))
        self.misc = self.locator.get_service('misc')
        self.misc.add_widget(self.dock,
                            QIcon.fromTheme("applications-multimedia"), __doc__)
예제 #3
0
 def setupUI(self):
     
     self.browser = browser = SimpleServerBrowser()
     self.player = player = video.Player() #VideoPlayer()        
     
     dock = QDockWidget(u'Przeglądarka serwerów', self)
     dock.setContentsMargins(0, 0, 0, 0)
     
     dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
     dock.setWidget(browser)        
     
     self.addDockWidget(Qt.LeftDockWidgetArea, dock)        
             
     #self.setCentralWidget(player.videoWidget())
     self.setCentralWidget(player.videoWidget)
     
     dock = QDockWidget(self)
     dock.setAllowedAreas(Qt.BottomDockWidgetArea)
     dock.setWidget(player.controlPanel)
     
     dock.setFloating(False)
     dock.setFeatures(QDockWidget.NoDockWidgetFeatures)
     self.addDockWidget(Qt.BottomDockWidgetArea, dock)
 
     QWidget.connect(self.browser, SIGNAL("play"), self.play)
     self.resize(800, 480)
예제 #4
0
 def insertDockWidgets(self):
     """ adds the Tree-DockWidget to the GUI <br>
         this function is connected to the signal SignalProxy::insertDockWidgets() """
     dock = QDockWidget(self.name)
     dock.setObjectName(self.name + "View")
     dock.setWidget(self.view)
     self.distributedObjects.signalProxy.emitAddDockWidget(Qt.BottomDockWidgetArea, dock, True)
예제 #5
0
 def _createDock(self):
     dock = QDockWidget("Workflow")
     dock.setObjectName("ERTGUI Workflow")
     dock.setWidget(self.contentsWidget)
     dock.setFeatures(QDockWidget.DockWidgetClosable)
     dock.setAllowedAreas(Qt.LeftDockWidgetArea)
     return dock
예제 #6
0
class QutePyEditor(QMainWindow):
    '''
    Arranges an instance of the Qutepart editor and minimap in a widget
    '''
    def __init__(self, parent=None):
        '''
        Constructor. Just setting up member-variables. initQutePyEditor needs to be called to create sub-widgets.
        '''
        super(QutePyEditor, self).__init__(parent)

        self._qutePy = None
        self._qutePyDockWidget = None
        self._miniMapWidget = None
        self._miniMapDockWidget = None

    def initQutePyEditor(self):

        self.setWindowTitle(self.__class__.__name__)

        self._qutePyDockWidget = QDockWidget(self)
        self._miniMapDockWidget = QDockWidget(self)

        self._qutePy = QutePy(self._qutePyDockWidget)
        self._miniMapWidget = MiniMapWidget(self._qutePy,
                                            parent=self._miniMapDockWidget)

        self._qutePyDockWidget.setWidget(self._qutePy)
        self._miniMapDockWidget.setWidget(self._miniMapWidget)

        self._miniMapDockWidget.setWindowTitle(
            self._miniMapWidget.__class__.__name__)

        self.addDockWidget(Qt.LeftDockWidgetArea, self._qutePyDockWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, self._miniMapDockWidget)
예제 #7
0
class OLOverview(object):

    def __init__(self, iface, olLayerTypeRegistry):
        self._iface = iface
        self._olLayerTypeRegistry = olLayerTypeRegistry
        self._dockwidget = None
        self._oloWidget = None

    # Private
    def _setDocWidget(self):
        self._dockwidget = QDockWidget(QApplication.translate("OpenLayersOverviewWidget", "OpenLayers Overview"), self._iface.mainWindow())
        self._dockwidget.setObjectName("dwOpenlayersOverview")
        self._oloWidget = OpenLayersOverviewWidget(self._iface, self._dockwidget, self._olLayerTypeRegistry)
        self._dockwidget.setWidget(self._oloWidget)

    def _initGui(self):
        self._setDocWidget()
        self._iface.addDockWidget(Qt.LeftDockWidgetArea, self._dockwidget)

    def _unload(self):
        self._dockwidget.close()
        self._iface.removeDockWidget(self._dockwidget)
        del self._oloWidget
        self._dockwidget = None

    # Public
    def setVisible(self, visible):
        if visible:
            if self._dockwidget is None:
                self._initGui()
        else:
            if not self._dockwidget is None:
                self._unload()
예제 #8
0
def add_widget_into_main(parent):
    """add a widget into the main window of LabGuiMain
    
    create a QDock widget and store a reference to the widget
    """
    


            
    

    mywidget = SimpleConnectWidget(parent = parent)
    
    #create a QDockWidget
    simpleconnectDockWidget = QDockWidget("Simple instrument console",
                                                parent)
    simpleconnectDockWidget.setObjectName("simpleConnectWidgetDockWidget")
    simpleconnectDockWidget.setAllowedAreas(
            Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        
    #fill the dictionnary with the widgets added into LabGuiMain
    parent.widgets['ConnectTerminalWidget'] = mywidget
    
    simpleconnectDockWidget.setWidget(mywidget)
    parent.addDockWidget(Qt.RightDockWidgetArea, simpleconnectDockWidget)
    
    #Enable the toggle view action
    parent.windowMenu.addAction(simpleconnectDockWidget.toggleViewAction())
    simpleconnectDockWidget.hide()      
예제 #9
0
    def __init__(self, data, scheme, parent=None):
        super(NodeWindow, self).__init__(parent)
        self.pathWidget = PathWidget(self.openWidgetByPath, data.path())
        self.setStatusBar(self.pathWidget)
#        layout_set_sm_and_mrg(self.layout)
        self.cachedWidgets = {}
        self.currentStructuredWidget = None
        self.stacked = QStackedWidget(self)
        self.setCentralWidget(self.stacked)

        self.data, self.scheme = data, scheme
        self.data.add_set_notify(self.change_caption)
        self.toolbar = QToolBar()
        self.toolbar.addActions((self.parent().actionSave,self.parent().actionSaveAs,))
        self.addToolBar(self.toolbar)
        self.setUnifiedTitleAndToolBarOnMac(True)
        self.messageBoxChanged = None
        self.reallyQuit = False
        self.change_caption()

        if "ExcelScheme" in self.scheme.get_meta():
            actionExcelExport = QAction("Export to excel", self)
            self.toolbar.addAction(actionExcelExport)
            actionExcelExport.triggered.connect(self.excel_export)
            actionExcelMerge = QAction("Merge from excel", self)
            actionExcelMerge.triggered.connect(self.excel_import)
            self.toolbar.addAction(actionExcelMerge)

        self.tree_widget = DataTreeWidget(self.data, self)
        dock = QDockWidget(self)
        dock.setWidget(self.tree_widget)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)
        self.tree_widget.pathChanged.connect(self._open_widget_by_path)

        self.openWidgetByPath(Path())
예제 #10
0
    def __init__(self):
        QMainWindow.__init__(self)

        self.figure = matplotlib.pyplot.figure()
        self.drawing = self.figure.add_subplot(111)
        self.canvas = matplotlib.backends.backend_qt4agg.FigureCanvasQTAgg(
            self.figure)

        self.setCentralWidget(self.canvas)

        dock = QDockWidget("Values")
        self.addDockWidget(Qt.RightDockWidgetArea, dock)

        sliders = QWidget()
        sliders_grid = QGridLayout(sliders)

        def add_slider(foo, col):
            sld = QSlider(Qt.Vertical, sliders)
            sld.setFocusPolicy(Qt.NoFocus)
            sld.valueChanged[int].connect(foo)
            sld.valueChanged.connect(self.plot)
            sliders_grid.addWidget(sld, 0, col)

        add_slider(foo=self.set_cos, col=0)
        add_slider(foo=self.set_sin, col=1)

        dock.setWidget(sliders)

        self.plot()
예제 #11
0
파일: __init__.py 프로젝트: koll00/Gui_SM
    def create_dockwidget(self):
        """Add to parent QMainWindow as a dock widget"""

        # This is not clear yet why the following do not work...
        # (see Issue #880)
##         # Using Qt.Window window flags solves Issue #880 (detached dockwidgets
##         # are not painted after restarting Spyder and restoring their hexstate)
##         # but it does not work with PyQt <=v4.7 (dockwidgets can't be docked)
##         # or non-Windows platforms (lot of warnings are printed out)
##         # (so in those cases, we use the default window flags: Qt.Widget):
##         flags = Qt.Widget if is_old_pyqt or os.name != 'nt' else Qt.Window
        dock = QDockWidget(self.get_plugin_title(), self.main)#, flags)

        dock.setObjectName(self.__class__.__name__+"_dw")
        dock.setAllowedAreas(self.ALLOWED_AREAS)
        dock.setFeatures(self.FEATURES)
        dock.setWidget(self)
        self.update_margins()
        self.connect(dock, SIGNAL('visibilityChanged(bool)'),
                     self.visibility_changed)
        self.dockwidget = dock
        short = self.get_option("shortcut", None)
        if short is not None:
            shortcut = QShortcut(QKeySequence(short),
                                 self.main, self.switch_to_plugin)
            self.register_shortcut(shortcut, "_",
                                   "Switch to %s" % self.CONF_SECTION,
                                   default=short)
        return (dock, self.LOCATION)
예제 #12
0
class Main(plugin.Plugin):
    " dock Class "
    def initialize(self):
        " Init Class dock "
        self.dock = QDockWidget()
        self.dock.setFeatures(QDockWidget.DockWidgetFloatable |
                              QDockWidget.DockWidgetMovable)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.boton = QPushButton(QIcon.fromTheme("document-open-recent"),
                                 'Edit Track', self.dock)
        self.boton.setToolTip('Edit iCal: {}'.format(TRACK_FILE))
        try:
            self.factory = KPluginLoader("ktimetrackerpart").factory()
            self.part = self.factory.create(self)
            self.part.setReadWrite(True)
            self.part.closeUrl()
            self.part.openUrl(KUrl(str(TRACK_FILE)))
            self.boton.clicked.connect(lambda:
                            call('xdg-open {}'.format(TRACK_FILE), shell=True))
            self.dock.setWidget(self.part.widget())
        except:
            self.dock.setWidget(QLabel(""" <center> <h3>ಠ_ಠ<br>
            ERROR: Please, install kTimeTracker and PyKDE ! </h3><br>
            <br><i> (Sorry, cant embed non-Qt Apps). </i><center>"""))
        self.misc = self.locator.get_service('misc')
        self.misc.add_widget(self.dock, QIcon.fromTheme("user-away"), __doc__)
예제 #13
0
 def _createDock(self):
     dock = QDockWidget("")
     dock.setObjectName("ERTGUI Workflow")
     dock.setWidget(self.contentsWidget)
     dock.setFeatures(QDockWidget.DockWidgetClosable)
     dock.setAllowedAreas(Qt.LeftDockWidgetArea)
     return dock
예제 #14
0
파일: ui.py 프로젝트: jlowenz/pyimgann
 def dock(self, widget, where, title=None):
     if title:
         d = QDockWidget(title, self)
     else:
         d = QDockWidget(self)
     d.setWidget(widget)
     self.addDockWidget(where, d)
     return d
예제 #15
0
class StackController(QObject):
    def __init__(self, distributedObjects):
        QObject.__init__(self)
        self.distributedObjects = distributedObjects

        self.editorController = distributedObjects.editorController

        self.stackModel = StackModel(
            self, self.distributedObjects.debugController, self.distributedObjects.gdb_connector
        )
        self.stackView = StackView(self)

        self.stackView.stackView.setModel(self.stackModel)

        QObject.connect(
            self.distributedObjects.signalProxy,
            SIGNAL("inferiorStoppedNormally(PyQt_PyObject)"),
            self.stackModel.update,
        )
        QObject.connect(
            self.distributedObjects.signalProxy, SIGNAL("inferiorHasExited(PyQt_PyObject)"), self.stackModel.clear
        )
        QObject.connect(self.distributedObjects.signalProxy, SIGNAL("executableOpened()"), self.stackModel.clear)
        QObject.connect(
            self.distributedObjects.signalProxy, SIGNAL("inferiorIsRunning(PyQt_PyObject)"), self.removeStackMarkers
        )
        QObject.connect(self.stackView.showStackTrace, SIGNAL("stateChanged(int)"), self.showStackTraceChanged)

        QObject.connect(self.distributedObjects.signalProxy, SIGNAL("insertDockWidgets()"), self.insertDockWidgets)

    def insertDockWidgets(self):
        self.stackDock = QDockWidget("Stack")
        self.stackDock.setObjectName("StackView")
        self.stackDock.setWidget(self.stackView)
        self.distributedObjects.signalProxy.addDockWidget(Qt.BottomDockWidgetArea, self.stackDock, True)

    def stackInStackViewActivated(self, index):
        item = index.internalPointer()
        self.distributedObjects.gdb_connector.selectStackFrame(item.level)
        self.distributedObjects.signalProxy.openFile(item.fullname, item.line)
        # FIXME: make locals view etc change their view too!

    def insertStackMarkers(self):
        if self.stackView.showStackTrace.checkState() == Qt.Checked:
            for entry in self.stackModel.stack:
                if int(entry.level) != 0 and hasattr(entry, "fullname") and hasattr(entry, "line"):
                    self.editorController.addStackMarker(entry.fullname, entry.line)

    def removeStackMarkers(self):
        for entry in self.stackModel.stack:
            if int(entry.level) != 0 and hasattr(entry, "fullname"):
                self.editorController.delStackMarkers(entry.fullname)

    def showStackTraceChanged(self, state):
        if state == Qt.Checked:
            self.insertStackMarkers()
        elif state == Qt.Unchecked:
            self.removeStackMarkers()
예제 #16
0
    def addDock(self, name, widget, area=Qt.LeftDockWidgetArea, allowed_areas=Qt.AllDockWidgetAreas):
        dock_widget = QDockWidget(name)
        dock_widget.setObjectName("%sDock" % name)
        dock_widget.setWidget(widget)
        dock_widget.setAllowedAreas(allowed_areas)
        dock_widget.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)

        self.addDockWidget(area, dock_widget)
        return dock_widget
예제 #17
0
파일: uiMainWindow.py 프로젝트: gxgjnn/live
 def createDock(self, widgetClass, widgetName, widgetArea):
     """创建停靠组件"""
     widget = widgetClass(self.mainEngine, self.eventEngine)
     dock = QDockWidget(widgetName)
     dock.setWidget(widget)
     dock.setObjectName(widgetName)
     dock.setFeatures(dock.DockWidgetFloatable | dock.DockWidgetMovable)
     self.addDockWidget(widgetArea, dock)
     return widget, dock
예제 #18
0
	def setup_dock(self, widget, name, area):
		"""Helps to setup docks more semantically"""
		dock = QDockWidget(name, self)
		dock.setObjectName(name)
		
		yield dock
		
		self.addDockWidget(area, dock)
		dock.setWidget(widget)
예제 #19
0
    def addDock(self, name, widget, area=Qt.LeftDockWidgetArea, allowed_areas=Qt.AllDockWidgetAreas):
        dock_widget = QDockWidget(name)
        dock_widget.setObjectName("%sDock" % name)
        dock_widget.setWidget(widget)
        dock_widget.setAllowedAreas(allowed_areas)
        dock_widget.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)

        self.addDockWidget(area, dock_widget)
        return dock_widget
예제 #20
0
	def __init__(self, layer, prop):
		QMainWindow.__init__(self)
		
		self.setWindowTitle('PostGIS Viewer - %s' % (layer.name()))
		
		self.canvas = QgsMapCanvas()
		self.canvas.setCanvasColor(Qt.white)
		self.canvas.enableAntiAliasing(True)
		
		tmp = QgsMapLayerRegistry.instance()
		tmp.addMapLayer(layer)
		
		self.canvas.setExtent(layer.extent())
		self.canvas.setLayerSet( [ QgsMapCanvasLayer(layer) ] )
		
		self.setCentralWidget(self.canvas)
		
		actionZoomIn = QAction(QString("Zoom in"), self)
		actionZoomOut = QAction(QString("Zoom out"), self)
		actionPan = QAction(QString("Pan"), self)
		
		actionZoomIn.setCheckable(True)
		actionZoomOut.setCheckable(True)
		actionPan.setCheckable(True)
		
		self.connect(actionZoomIn, SIGNAL("triggered()"), self.zoomIn)
		self.connect(actionZoomOut, SIGNAL("triggered()"), self.zoomOut)
		self.connect(actionPan, SIGNAL("triggered()"), self.pan)
		
		self.toolbar = self.addToolBar("Canvas actions")
		self.toolbar.addAction(actionZoomIn)
		self.toolbar.addAction(actionZoomOut)
		self.toolbar.addAction(actionPan)
		
		# create the map tools
		self.toolPan = QgsMapToolPan(self.canvas)
		self.toolPan.setAction(actionPan)
		self.toolZoomIn = QgsMapToolZoom(self.canvas, False) # false = in
		self.toolZoomIn.setAction(actionZoomIn)
		self.toolZoomOut = QgsMapToolZoom(self.canvas, True) # true = out
		self.toolZoomOut.setAction(actionZoomOut)
		
		self.pan()
		
		dock_layer_prop = QDockWidget(self.tr('Layer Properties'), self)
		dock_layer_prop.setAllowedAreas(Qt.BottomDockWidgetArea)
		self.layer_prop = QListWidget(dock_layer_prop)
		self.layer_prop.addItems(QStringList()
			<< "Layer: %s" % layer.name()
			<< "Source: %s" % layer.source()
			<< "Geometry: %s" % prop['geom_type']
			<< "Extent: %s" % layer.extent().toString()
			<< "PostGIS: %s" % prop['postgis_version']
			)
		dock_layer_prop.setWidget(self.layer_prop)
		self.addDockWidget(Qt.BottomDockWidgetArea, dock_layer_prop)
예제 #21
0
    def addDock(self, name, widget, area=Qt.RightDockWidgetArea, allowed_areas=Qt.AllDockWidgetAreas):
        dock_widget = QDockWidget(name)
        dock_widget.setObjectName("%sDock" % name)
        dock_widget.setWidget(widget)
        dock_widget.setAllowedAreas(allowed_areas)

        self.addDockWidget(area, dock_widget)

        self.__view_menu.addAction(dock_widget.toggleViewAction())
        return dock_widget
예제 #22
0
    def insertDockWidget(self, widget, name, area, addToggleViewAction):
        d = QDockWidget(name, self)
        d.setObjectName(name)
        d.setWidget(widget)

        self.addDockWidget(area, d)
        if addToggleViewAction:
            self.ui.menuShow_View.addAction(d.toggleViewAction())

        return d
예제 #23
0
    def addDock(self, name, widget, area=Qt.RightDockWidgetArea, allowed_areas=Qt.AllDockWidgetAreas):
        dock_widget = QDockWidget(name)
        dock_widget.setObjectName("%sDock" % name)
        dock_widget.setWidget(widget)
        dock_widget.setAllowedAreas(allowed_areas)

        self.addDockWidget(area, dock_widget)

        self.__view_menu.addAction(dock_widget.toggleViewAction())
        return dock_widget
예제 #24
0
파일: main.py 프로젝트: juancarlospaco/diff
class Main(plugin.Plugin):
    " dock Class "
    def initialize(self):
        " Init Class dock "
        self.dock = QDockWidget()
        self.dock.setFeatures(QDockWidget.DockWidgetFloatable |
                              QDockWidget.DockWidgetMovable)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.open = QAction(QIcon.fromTheme("document-open"), 'Open DIFF', self)
        self.diff = QAction(QIcon.fromTheme("document-new"), 'Make DIFF', self)
        self.diff.triggered.connect(self.run_gui_and_get_results)
        self.save = QAction(QIcon.fromTheme("document-save"), 'Save DIFF', self)
        self.save.triggered.connect(self.save_a_diff)
        self.patc = QAction(QIcon.fromTheme("document-edit"), 'PATCH it!', self)
        self.patc.triggered.connect(lambda: QMessageBox.information(self.dock,
            __doc__, ' Sorry. This Feature is not ready yet !, thank you... '))
        QToolBar(self.dock).addActions((self.open, self.diff,
                                        self.save, self.patc))
        try:
            self.factory = KPluginLoader("komparepart").factory()
            self.part = self.factory.create(self)
            self.dock.setWidget(self.part.widget())
            self.open.triggered.connect(lambda: self.part.openUrl(KUrl(str(
                QFileDialog.getOpenFileName(self.dock, ' Open a DIFF file ',
                                        path.expanduser("~"), ';;(*.diff)')))))
        except:
            self.dock.setWidget(QLabel(""" <center> <h3>ಠ_ಠ<br>
            ERROR: Please, install Kompare and PyKDE ! </h3><br>
            <br><i> (Sorry, cant embed non-Qt Apps). </i><center>"""))

        self.misc = self.locator.get_service('misc')
        self.misc.add_widget(self.dock,
                                QIcon.fromTheme("edit-select-all"), __doc__)

    def run_gui_and_get_results(self):
        ' run_gui_and_get_results '
        gui = Diff_GUI()
        if gui.diff_path is not None and path.isfile(gui.diff_path) is True:
            self.part.openUrl(KUrl(str(gui.diff_path)))
        return gui.diff_path

    def save_a_diff(self):
        ' save a diff '
        out_file = path.abspath(str(QFileDialog.getSaveFileName(self.dock,
                   'Save a Diff file', path.expanduser("~"), ';;(*.diff)')))
        inp_file = file(str(QUrl(
               self.part.url()).toString()).replace('file://', ''), 'r').read()
        end_file = file(out_file, 'w')
        end_file.write(inp_file)
        end_file.close()
예제 #25
0
class GdbIoController(QObject):
    def __init__(self, distributedObjects):
        QObject.__init__(self)
        self.distributedObjects = distributedObjects

        self.gdbioView = GdbIoView(self.distributedObjects.debugController)

        self.distributedObjects.signalProxy.insertDockWidgets.connect(self.insertDockWidgets)

    def insertDockWidgets(self):
        self.gdbioDock = QDockWidget("GDB Console")
        self.gdbioDock.setObjectName("GdbIoView")
        self.gdbioDock.setWidget(self.gdbioView)
        self.distributedObjects.signalProxy.emitAddDockWidget(Qt.BottomDockWidgetArea, self.gdbioDock, True)
예제 #26
0
class InferiorIoController(QObject):
    def __init__(self, distributedObjects):
        QObject.__init__(self)
        self.distributedObjects = distributedObjects

        self.inferiorioView = InferiorIoView(self.distributedObjects.debugController)

        QObject.connect(self.distributedObjects.signalProxy, SIGNAL('insertDockWidgets()'), self.insertDockWidgets)

    def insertDockWidgets(self):
        self.inferiorioDock = QDockWidget("Output")
        self.inferiorioDock.setObjectName("InferiorIoView")
        self.inferiorioDock.setWidget(self.inferiorioView)
        self.distributedObjects.signalProxy.addDockWidget(Qt.BottomDockWidgetArea, self.inferiorioDock, True)
예제 #27
0
class Main(plugin.Plugin):
    " dock Class "

    def initialize(self):
        " Init Class dock "
        self.dock = QDockWidget()
        self.dock.setFeatures(QDockWidget.DockWidgetFloatable
                              | QDockWidget.DockWidgetMovable)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.boton = QAction(QIcon.fromTheme("list-add"), 'Open', self)
        self.saver = QAction(QIcon.fromTheme("document-save"), 'Save', self)
        self.apiss = QAction(QIcon.fromTheme("help"), 'Python API Help', self)
        QToolBar(self.dock).addActions((self.boton, self.saver, self.apiss))
        try:
            self.factory = KPluginLoader("kigpart").factory()
            self.part = self.factory.create(self)
            self.part.setReadWrite(True)
            self.boton.triggered.connect(lambda: self.part.openUrl(
                KUrl(
                    str(
                        QFileDialog.getOpenFileName(
                            self.dock, ' Open Geometry Plot ',
                            path.expanduser("~"), ';;'.join([
                                '(*.{})'.format(e)
                                for e in ['fig', 'kig', 'kigz', 'seg', 'fgeo']
                            ]))))))
            self.saver.triggered.connect(lambda: self.part.saveAs(
                KUrl(
                    str(
                        QFileDialog.getSaveFileName(
                            self.dock, ' Save Geometry Plot ',
                            path.expanduser("~"), ';;'.join([
                                '(*.{})'.format(e)
                                for e in ['kig', 'kigz', 'fig']
                            ]))))))
            self.apiss.triggered.connect(lambda: open_new_tab(
                'http://edu.kde.org/kig/manual/scripting-api/classObject.html')
                                         )
            self.dock.setWidget(self.part.widget())
        except:
            self.dock.setWidget(
                QLabel(""" <center> <h3>ಠ_ಠ<br>
            ERROR: Please, install KIG and PyKDE ! </h3><br>
            <br><i> (Sorry, cant embed non-Qt Apps). </i><center>"""))
        self.misc = self.locator.get_service('misc')
        self.misc.add_widget(self.dock,
                             QIcon.fromTheme("accessories-calculator"),
                             __doc__)
예제 #28
0
class PyIoController(QObject):
    
    def __init__(self, distributed_objects):
        QObject.__init__(self)
        self.distributed_objects = distributed_objects
        
        self.pyioView = PyIoView(self.distributed_objects.debug_controller)
        
        QObject.connect(self.distributed_objects.signal_proxy, SIGNAL('insertDockWidgets()'), self.insertDockWidgets)
        
    def insertDockWidgets(self):
        self.pyioDock = QDockWidget("Python Console")
        self.pyioDock.setObjectName("PyIoView")
        self.pyioDock.setWidget(self.pyioView)
        self.distributed_objects.signal_proxy.addDockWidget(Qt.BottomDockWidgetArea, self.pyioDock, True)
예제 #29
0
파일: dock.py 프로젝트: yisuax11/orange2
    def __init__(self, *args, **kwargs):
        QDockWidget.__init__(self, *args, **kwargs)

        self.__expandedWidget = None
        self.__collapsedWidget = None
        self.__expanded = True

        self.__trueMinimumWidth = -1

        self.setFeatures(QDockWidget.DockWidgetClosable | \
                         QDockWidget.DockWidgetMovable)
        self.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)

        self.featuresChanged.connect(self.__onFeaturesChanged)
        self.dockLocationChanged.connect(self.__onDockLocationChanged)

        # Use the toolbar horizontal extension button icon as the default
        # for the expand/collapse button
        pm = self.style().standardPixmap(
            QStyle.SP_ToolBarHorizontalExtensionButton
        )

        # Rotate the icon
        transform = QTransform()
        transform.rotate(180)

        pm_rev = pm.transformed(transform)

        self.__iconRight = QIcon(pm)
        self.__iconLeft = QIcon(pm_rev)

        close = self.findChild(QAbstractButton,
                               name="qt_dockwidget_closebutton")

        close.installEventFilter(self)
        self.__closeButton = close

        self.__stack = AnimatedStackedWidget()

        self.__stack.setSizePolicy(QSizePolicy.Fixed,
                                   QSizePolicy.Expanding)

        self.__stack.transitionStarted.connect(self.__onTransitionStarted)
        self.__stack.transitionFinished.connect(self.__onTransitionFinished)

        QDockWidget.setWidget(self, self.__stack)

        self.__closeButton.setIcon(self.__iconLeft)
예제 #30
0
 def create_dockwidget(self):
     """Add to parent QMainWindow as a dock widget"""
     dock = QDockWidget(self.get_plugin_title(), self.main)#, self.FLAGS) -> bug in Qt 4.4
     dock.setObjectName(self.__class__.__name__+"_dw")
     dock.setAllowedAreas(self.ALLOWED_AREAS)
     dock.setFeatures(self.FEATURES)
     dock.setWidget(self)
     self.connect(dock, SIGNAL('visibilityChanged(bool)'),
                  self.visibility_changed)
     self.dockwidget = dock
     self.refresh_plugin()
     short = CONF.get(self.ID, "shortcut", None)
     if short is not None:
         QShortcut(QKeySequence(short), self.main,
                   lambda: self.visibility_changed(True))
     return (dock, self.LOCATION)
예제 #31
0
 def create_dockwidget(self):
     """Add to parent QMainWindow as a dock widget"""
     dock = QDockWidget(self.get_widget_title(), self.main)#, self.flags) -> bug in Qt 4.4
     dock.setObjectName(self.__class__.__name__+"_dw")
     dock.setAllowedAreas(self.allowed_areas)
     dock.setFeatures(self.features)
     dock.setWidget(self)
     self.connect(dock, SIGNAL('visibilityChanged(bool)'),
                  self.visibility_changed)
     self.dockwidget = dock
     self.refresh()
     short = CONF.get(self.ID, "shortcut", None)
     if short is not None:
         QShortcut(QKeySequence(short), self.main,
                   lambda: self.visibility_changed(True))
     return (dock, self.location)
예제 #32
0
    def create_widgets(self):

        logDockWidget = QDockWidget("Log", self)
        logDockWidget.setObjectName("LogDockWidget")
        logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea |
                                      Qt.RightDockWidgetArea)
        self.listWidget = QListWidget()
        logDockWidget.setWidget(self.listWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)

        self.sizeLabel = QLabel()
        self.sizeLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        self.status = self.statusBar()
        self.status.setSizeGripEnabled(False)
        self.status.addPermanentWidget(self.sizeLabel)
        self.status.showMessage("Ready", 5000)
예제 #33
0
class ValueTool:
    def __init__(self, iface):
        # save reference to the QGIS interface
        self.iface = iface

    def initGui(self):
        # create action that will start plugin configuration
        # self.action = QAction(QIcon(":/plugins/valuetool/icon.png"), "Value Tool", self.iface.getMainWindow())
        # self.action.setWhatsThis("Value Tool")
        # QObject.connect(self.action, SIGNAL("activated()"), self.run)
        # # add toolbar button and menu item
        # self.iface.addToolBarIcon(self.action)
        # self.iface.addPluginMenu("Analyses", self.action)
        # # add the tool to select feature
        # self.tool = selectPointTool(self.iface.getMapCanvas(),self.action)

        # create the widget to display information
        self.valuewidget = ValueWidget(self.iface)
        # create the dockwidget with the correct parent and add the valuewidget
        self.valuedockwidget = QDockWidget("Value Tool",
                                           self.iface.mainWindow())
        self.valuedockwidget.setObjectName("Value Tool")
        self.valuedockwidget.setWidget(self.valuewidget)
        QObject.connect(self.valuedockwidget,
                        SIGNAL('visibilityChanged ( bool )'),
                        self.showHideDockWidget)

        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.valuedockwidget)
        # self.valuewidget.show()
        # ##Qt.AllDockWidgetAreas

    def unload(self):
        self.valuedockwidget.close()
        self.valuewidget.disconnect()
        # remove the dockwidget from iface
        self.iface.removeDockWidget(self.valuedockwidget)
        # remove the plugin menu item and icon
        # self.iface.removePluginMenu("Analyses",self.action)
        # self.iface.removeToolBarIcon(self.action)

    def showHideDockWidget(self):
        if self.valuedockwidget.isVisible(
        ) and self.valuewidget.cbxActive.isChecked():
            state = Qt.Checked
        else:
            state = Qt.Unchecked
        self.valuewidget.changeActive(state)
예제 #34
0
class LabControl(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        # self.ui=uic.loadUi("mainwindow.ui",self)
        self.DelayStageDock = QDockWidget("DelayStage", self)
        self.DelayStageDock.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.DelayStageDock.setWidget(DelayStageWidget(self))
        self.DelayStageDock.widget().setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.addDockWidget(Qt.TopDockWidgetArea, self.DelayStageDock)

        self.DelayStageDock.widget().delaystage.throwMessage.connect(self.getMessage)

    def on_actionDelayStage_triggered(self):
        self.close()

    def getMessage(self, text, level):
        print (text)
예제 #35
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        openAction = QAction("&Connect", self)
        openAction.triggered.connect(self.connection)
        self.menuBar().addAction(openAction)
        localAction = QAction("&Local", self)
        localAction.triggered.connect(self.local)
        self.menuBar().addAction(localAction)
        loader = DStructs().find("Import").newObject()
        #loader.file("../../../examples/modules/libdestruct_rpczmq.so")
        loader.file("../../../examples/modules/libdestruct_rpczmq.so")
        loader.file("../../../examples/modules/libdestruct_registry.so")

    def addRegistryBrowserWidget(self, regf):
        self.registryBrowserWidget = RegistryBrowserWidget(regf)
        self.dockWidget = QDockWidget()
        self.dockWidget.setWidget(self.registryBrowserWidget)
        self.addDockWidget(Qt.TopDockWidgetArea, self.dockWidget)

    def local(self):
        filePath = QFileDialog.getOpenFileName().toUtf8()
        self.registry = DStructs().find("Registry").newObject()
        regf = self.registry.open(str(filePath))
        self.addRegistryBrowserWidget(regf)

    def connection(self):
        connectionDialog = ConnectionDialog(self)
        ok = connectionDialog.exec_()
        if not ok:
            return

        arg = DStructs().find("ClientArgument").newObject()
        arg.port = connectionDialog.port.value()
        arg.address = str(connectionDialog.ipAddress.text())
        auth = DStructs().find("RPCAuth").newObject()
        auth.cert = "clicert/rpczmq_client_cert.txt"
        auth.certStore = "clicert/"
        #arg.auth = auth
        self.client = DStructs().find("Client").newObject(arg)
        serverLoader = self.client.generate("Import")
        if serverLoader.file("../modules/libdestruct_registry.so") == 0:
            serverLoader.file("destruct_registry.dll")
        self.registry = self.client.generate("Registry")
        regf = self.registry.open(str(connectionDialog.filePath.text()))
        self.addRegistryBrowserWidget(regf)
예제 #36
0
class LabControl(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        #self.ui=uic.loadUi("mainwindow.ui",self)
        self.DelayStageDock=QDockWidget("DelayStage",self)
        self.DelayStageDock.setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed)
        self.DelayStageDock.setWidget(DelayStageWidget(self))
        self.DelayStageDock.widget().setSizePolicy(QSizePolicy.Fixed,QSizePolicy.Fixed)
        self.addDockWidget(Qt.TopDockWidgetArea,self.DelayStageDock)

        self.DelayStageDock.widget().delaystage.throwMessage.connect(self.getMessage)
        
    def on_actionDelayStage_triggered(self):
        self.close()

    def getMessage(self,text,level):
        print(text)
예제 #37
0
class FeatureTemplates:

    def __init__(self, iface):
        self.iface = iface
        self.dock = None
        self.plugin_dir = os.path.dirname(__file__)
        locale = QSettings().value("locale/userLocale")[0:2]
        localePath = os.path.join(self.plugin_dir, 
                                  'i18n', 
                                  'featuretemplates_{}.qm'.format(locale))

        if os.path.exists(localePath):
            self.translator = QTranslator()
            self.translator.load(localePath)

            if qVersion() > '4.3.3':
                QCoreApplication.installTranslator(self.translator)

    def initGui(self):
        self.action = QAction(QIcon(":/plugins/featuretemplates/icon.png"),
                              u"Feature Templates", 
                              self.iface.mainWindow())

        self.action.triggered.connect(self.show_dock)
        self.iface.addToolBarIcon(self.action)
        self.iface.addPluginToMenu(u"&FeatureTemplates", self.action)

    def unload(self):
        self.iface.removePluginMenu(u"&FeatureTemplates", self.action)
        self.iface.removeToolBarIcon(self.action)
        
        if self.dock:
            self.iface.removeDockWidget(self.dock)

    def show_dock(self):
        if not self.dock:
            self.dock = QDockWidget('Feature Templates', self.iface.mainWindow())
            self.widget = FeatureTemplatesWidget(self.dock)
            template = {'name' : 'Test'}
            self.model = FeatureTemplatesModel(templates=[template])
            self.widget.setModel(self.model)
            self.dock.setWidget(self.widget)
            self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dock)
        
        self.dock.show()
예제 #38
0
class MainWindow(QMainWindow):

    def __init__(self, model):
        super(MainWindow, self).__init__()
        self.tree_dock = QDockWidget()
        self.props_dock = QDockWidget()
        self.tree_view = TreeWidget()
        self.tree_view.setModel(model)
        self.tree_dock.setWidget(self.tree_view)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.tree_dock)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.props_dock)

        self.tree_view.clicked.connect(self.change_props_widget)

    def change_props_widget(self, idx):
        self.props_dock.setWidget(
            self.tree_view.model().itemFromIndex(idx).props_widget
        )
예제 #39
0
class ValueTool:

    def __init__(self, iface):
        # save reference to the QGIS interface
        self.iface = iface

    def initGui(self):
        # create action that will start plugin configuration
        # self.action = QAction(QIcon(":/plugins/valuetool/icon.png"), "Value Tool", self.iface.getMainWindow())
        # self.action.setWhatsThis("Value Tool")
        # QObject.connect(self.action, SIGNAL("activated()"), self.run)
        # # add toolbar button and menu item
        # self.iface.addToolBarIcon(self.action)
        # self.iface.addPluginMenu("Analyses", self.action)
        # # add the tool to select feature
        # self.tool = selectPointTool(self.iface.getMapCanvas(),self.action)

        # create the widget to display information
        self.valuewidget = ValueWidget(self.iface)
        # create the dockwidget with the correct parent and add the valuewidget
        self.valuedockwidget = QDockWidget("Value Tool", self.iface.mainWindow())
        self.valuedockwidget.setObjectName("Value Tool")
        self.valuedockwidget.setWidget(self.valuewidget)
        QObject.connect(self.valuedockwidget, SIGNAL('visibilityChanged ( bool )'), self.showHideDockWidget)

        self.iface.addDockWidget(Qt.LeftDockWidgetArea, self.valuedockwidget)
        # self.valuewidget.show()
        # ##Qt.AllDockWidgetAreas

    def unload(self):
        self.valuedockwidget.close()
        self.valuewidget.disconnect()
        # remove the dockwidget from iface
        self.iface.removeDockWidget(self.valuedockwidget)
        # remove the plugin menu item and icon
        # self.iface.removePluginMenu("Analyses",self.action)
        # self.iface.removeToolBarIcon(self.action)

    def showHideDockWidget(self):
        if self.valuedockwidget.isVisible() and self.valuewidget.cbxActive.isChecked():
            state = Qt.Checked
        else:
            state = Qt.Unchecked
        self.valuewidget.changeActive(state)
예제 #40
0
class Terminal(plugin.Plugin):
    " Terminal Class "
    def initialize(self):
        " Init Class Terminal "
        self.terminal = QDockWidget()
        self.terminal.setFeatures(QDockWidget.DockWidgetFloatable |
                                  QDockWidget.DockWidgetMovable)
        self.terminal.setWindowTitle(__doc__)
        self.terminal.setStyleSheet('QDockWidget::title{text-align: center;}')
        try:
            self.factory = KPluginLoader("libkonsolepart").factory()
            self.terminal.setWidget(self.factory.create(self).widget())
        except:
            self.terminal.setWidget(QLabel(""" <center> <h3>ಠ_ಠ<br>
            ERROR: Please, install Konsole Terminal and PyKDE ! </h3><br>
            <br><i> (Sorry, cant embed non-Qt Terminal Apps). </i><center>"""))
        self.misc = self.locator.get_service('misc')
        self.misc.add_widget(self.terminal,
                               QIcon.fromTheme("utilities-terminal"), __doc__)
예제 #41
0
class SideBar(QToolBar):
    def __init__(self, parent):
        self.parent = parent
        QToolBar.__init__(self)
        self.setObjectName('sideBar')
        self.parent.addToolBar(Qt.LeftToolBarArea, self)

        self.setIconSize(
            QSize(48, 48))
        self.setMovable(False)

        self.dock = QDockWidget()
        self.dock.setObjectName('sideBarDock')
        self.dock.stack = QStackedWidget()
        self.stack = self.dock.stack
        self.dock.setWidget(self.stack)
        self.parent.addDockWidget(Qt.LeftDockWidgetArea, self.dock)

        self.dock.hide()
예제 #42
0
class Plugin():
    def __init__(self, iface):
        self.__iface = iface
        self.__section_main = MainWindow(iface)
        self.__dock = QDockWidget('Section')
        self.__dock.setWidget(self.__section_main)

        self.__legend_dock = QDockWidget('Section Legend')
        self.__legend_dock.setWidget(self.__section_main.tree_view)

    def initGui(self):
        self.__section_main.add_default_section_buttons()
        self.__iface.addDockWidget(Qt.BottomDockWidgetArea, self.__dock)
        self.__iface.addDockWidget(Qt.LeftDockWidgetArea, self.__legend_dock)

    def unload(self):
        self.__iface.removeDockWidget(self.__dock)
        self.__iface.removeDockWidget(self.__legend_dock)

        self.__section_main.unload()
예제 #43
0
class Plugin():
    def __init__(self, iface):
        self.__iface = iface
        self.__section_main = MainWindow(iface)
        self.__dock = QDockWidget('Section')
        self.__dock.setWidget(self.__section_main)

        self.__legend_dock = QDockWidget('Section Legend')
        self.__legend_dock.setWidget(self.__section_main.tree_view)

    def initGui(self):
        self.__section_main.add_default_section_buttons()
        self.__iface.addDockWidget(Qt.BottomDockWidgetArea, self.__dock)
        self.__iface.addDockWidget(Qt.LeftDockWidgetArea, self.__legend_dock)

    def unload(self):
        self.__iface.removeDockWidget(self.__dock)
        self.__iface.removeDockWidget(self.__legend_dock)

        self.__section_main.unload()
예제 #44
0
    def __init__(self, game, parent = None):
        super(MainWindow, self).__init__(parent)
        self.game = game
        self.boardWidget = BoardWidget(self.game)
        self.chat = Chat()
        self.playerInfo = PlayerInfo(self.game)

        playerDock = QDockWidget("Players")
        playerDock.setWidget(self.playerInfo)
        playerDock.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable)
        self.addDockWidget(Qt.RightDockWidgetArea, playerDock)

        chatDock = QDockWidget("Chat")
        chatDock.setWidget(self.chat)
        chatDock.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetFloatable)
        self.addDockWidget(Qt.RightDockWidgetArea, chatDock)

        self.setCentralWidget(self.boardWidget)
        self.statusBar()
        self.initMenuBar()
예제 #45
0
    def create_widgets(self):
        self.imageLabel = QLabel()
        self.imageLabel.setMinimumSize(200, 200)
        self.imageLabel.setAlignment(Qt.AlignCenter)
        self.imageLabel.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.setCentralWidget(self.imageLabel)

        logDockWidget = QDockWidget("Log", self)
        logDockWidget.setObjectName("LogDockWidget")
        logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea|
                                      Qt.RightDockWidgetArea)
        self.listWidget = QListWidget()
        logDockWidget.setWidget(self.listWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)

        self.sizeLabel = QLabel()
        self.sizeLabel.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken)
        status = self.statusBar()
        status.setSizeGripEnabled(False)
        status.addPermanentWidget(self.sizeLabel)
        status.showMessage("Ready", 5000)
예제 #46
0
    def create_widgets(self):
        self.imageLabel = QLabel()
        self.imageLabel.setMinimumSize(200, 200)
        self.imageLabel.setAlignment(Qt.AlignCenter)
        self.imageLabel.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.setCentralWidget(self.imageLabel)

        logDockWidget = QDockWidget("Log", self)
        logDockWidget.setObjectName("LogDockWidget")
        logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea
                                      | Qt.RightDockWidgetArea)
        self.listWidget = QListWidget()
        logDockWidget.setWidget(self.listWidget)
        self.addDockWidget(Qt.RightDockWidgetArea, logDockWidget)

        self.sizeLabel = QLabel()
        self.sizeLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
        status = self.statusBar()
        status.setSizeGripEnabled(False)
        status.addPermanentWidget(self.sizeLabel)
        status.showMessage("Ready", 5000)
예제 #47
0
    def __init__(self, content, plot_labels, plot_name, *args, parent=None, **kwargs):
        """
        Initialisation of the PlotContainer widget.

        content - Content for the plotcontainer
        plot_lables - Labels of the plot widget
        plot_name - Name of the associated software
        parent - Parent widget (default None)

        Returns:
        None
        """
        super(PlotContainer, self).__init__(parent)
        self.setCentralWidget(None)
        self.setTabPosition(Qt.TopDockWidgetArea, QTabWidget.North)
        self.plot_name = plot_name

        self.content = []
        dock_widgets = []
        for label in plot_labels:
            label = label[0]
            if label == 'mic_number':
                continue
            elif label == 'file_name':
                continue
            else:
                pass

            widget = PlotWidget(label=label, plot_typ=content, parent=self)
            self.content.append(widget)

            dock_widget = QDockWidget(label, self)
            dock_widget.setWidget(widget)
            dock_widget.installEventFilter(self)
            dock_widget.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
            dock_widgets.append(dock_widget)
            self.addDockWidget(Qt.TopDockWidgetArea, dock_widget, Qt.Horizontal)

        for idx in range(1, len(dock_widgets)):
            self.tabifyDockWidget(dock_widgets[0], dock_widgets[idx])
예제 #48
0
    def __init__(self):
        super().__init__()

        daq = Traces(args)
        dock_daq = QDockWidget('DAQ', self)
        dock_daq.setWidget(daq)
        dock_daq.setObjectName('DAQ')
        dock_daq.setFeatures(QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.TopDockWidgetArea, dock_daq)

        widgets = {
            'daq': daq,
        }
        self.controlpanel = ControlPanel(widgets)
        self.setCentralWidget(self.controlpanel)

        window_geometry = settings.value('window/geometry')
        if window_geometry is not None:
            self.restoreGeometry(window_geometry)
        window_state = settings.value('window/state')
        if window_state is not None:
            self.restoreState(window_state, float(VERSION))
예제 #49
0
    def __init__(self, parent=None):
        super(SR785_MainWindow, self).__init__(parent)
        centralWidget = SR785_Widget()
        self.setCentralWidget(centralWidget)

        visaResource = 'GPIB0::10'
        sr785 = SR785(visaResource)
        sr785.configureScreenDump()
        centralWidget.associateInstrument(sr785)
        self.setWindowTitle('SR785 Front Panel Emulation: %s' % sr785.visaId())
        self.progressBar = QProgressBar()
        statusBar = self.statusBar()
        statusBar.addWidget(self.progressBar)

        toolBar = QToolBar('Screen')
        toolBar.addActions(centralWidget.screenActions)
        self.addToolBar(toolBar)

        thread = centralWidget.workerThread
        thread.gifDownloadStarted.connect(self.gifDownloadStarted)
        thread.gifReceived.connect(self.gifReceived)
        thread.keyPressSimulated.connect(self.keyPressSimulated)
        thread.knobRotated.connect(self.knobRotated)

        dockWidget = QDockWidget('History')
        self.historyTe = QTextEdit()
        dockWidget.setWidget(self.historyTe)
        self.addDockWidget(Qt.TopDockWidgetArea, dockWidget)

        toolBar = self.addToolBar('File')
        action = QAction('Save screen', self)
        action.triggered.connect(self.saveScreen)
        toolBar.addAction(action)
        action = QAction('Print', self)
        action.triggered.connect(self.printScreen)
        toolBar.addAction(action)
예제 #50
0
 def setWidget(self, widget):
     self.mainWidget = XDockMainWidgetWrapper(self)
     self.mainWidget.setWidget(widget)
     QDockWidget.setWidget(self, self.mainWidget)
예제 #51
0
파일: mleap.py 프로젝트: ChannelFinder/hla
class OrbitPlotMainWindow(QMainWindow):
    """
    the main window has three major widgets: current, orbit tabs and element
    editor.
    """
    def __init__(self, parent=None, machines=[], **kwargs):
        QMainWindow.__init__(self, parent)
        self.iqtApp = kwargs.get("iqt", None)

        self.setIconSize(QSize(32, 32))
        self.error_bar = True
        self._dlgOrbitCor = None
        # logging
        self.logdock = QDockWidget("Log")
        self.logdock.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        textedit = QPlainTextEdit(self.logdock)

        self.logger = logging.getLogger(__name__)

        self.guilogger = logging.getLogger("aphla.gui")
        # the "aphla" include lib part logging. When the lib is inside
        # QThread, logging message will be sent to TextEdit which is cross
        # thread.
        # self.guilogger = logging.getLogger("aphla")
        handler = QTextEditLoggingHandler(textedit)
        self.guilogger.addHandler(handler)
        self.guilogger.setLevel(logging.INFO)
        self.logdock.setWidget(textedit)
        self.logdock.setAllowedAreas(Qt.BottomDockWidgetArea)
        self.logdock.setFeatures(QDockWidget.DockWidgetMovable
                                 | QDockWidget.DockWidgetClosable)
        self.logdock.setFloating(False)
        self.logdock.setMinimumHeight(20)
        self.logdock.setMaximumHeight(100)
        self.logdock.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        self.logdock.resize(200, 60)
        #print self.logdock.sizeHint()
        self.addDockWidget(Qt.BottomDockWidgetArea, self.logdock)
        #print self.logdock.sizeHint()
        #print self.logdock.minimumSize()
        #print self.logdock.maximumSize()
        #self.logger.info("INFO")
        #self.logdock.setMinimumHeight(40)
        #self.logdock.setMaximumHeight(160)

        for msg in kwargs.get("infos", []):
            self.logger.info(msg)
        # dict of (machine, (lattice dict, default_lat, pvm))
        self._mach = dict([(v[0], (v[1], v[2], v[3])) for v in machines])
        for m, (lats, lat0, pvm) in self._mach.items():
            self.logger.info(
                "machine '%s' initialized: [%s]" %
                (m, ", ".join([lat.name for k, lat in lats.items()])))
            if pvm:
                for pv in pvm.dead():
                    self.logger.warn("'{0}' is disconnected.".format(pv))
        ## DCCT current plot
        #self.dcct = DcctCurrentPlot()
        #self.dcct.setMinimumHeight(100)
        #self.dcct.setMaximumHeight(150)

        #t0 = time.time()
        #t = np.linspace(t0 - 8*3600*24, t0, 100)
        #self.dcct.curve.t = t
        #v = 500*np.exp((t[0] - t[:50])/(4*3600*24))
        #self.dcct.curve.v = v.tolist()+v.tolist()
        #self.dcct.updatePlot()

        ## MDI area
        self.mdiarea = QMdiArea()
        self.connect(self.mdiarea, SIGNAL("subWindowActivated(QMdiSubWindow)"),
                     self.updateMachineLatticeNames)
        self.mdiarea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.physics = ApOrbitPhysics(self.mdiarea, iqt=self.iqtApp)
        self.live_orbit = True

        self.setCentralWidget(self.mdiarea)

        #self._elemed = ElementPropertyTabs()
        #self.elemeditor = ElementEditorDock(parent=self)
        #self.elemeditor.setAllowedAreas(Qt.RightDockWidgetArea)
        #self.elemeditor.setFeatures(QDockWidget.DockWidgetMovable|
        #                            QDockWidget.DockWidgetClosable)
        #self.elemeditor.setFloating(False)
        #self.elemeditor.setEnabled(False)
        #self.elemeditor.setMinimumWidth(400)
        #self.elemeditor.setWidget(self._elemed)
        #self.elemeditor.show()
        #self.elemeditor.hide()
        #self.connect(self.elemeditor,
        #             SIGNAL("elementChecked(PyQt_PyObject, bool)"),
        #             self.physics.elementChecked)
        #self.addDockWidget(Qt.RightDockWidgetArea, self.elemeditor)

        self.createMenuToolBar()

        # the first machine is the default
        self.machBox.addItems([v for v in self._mach.keys()])
        self.reloadLatticeNames(self.machBox.currentText())
        self.connect(self.machBox, SIGNAL("currentIndexChanged(QString)"),
                     self.reloadLatticeNames)

        # update at 1/2Hz
        self.dt, self.itimer = 1500, 0
        #self.timerId = None
        self.timerId = self.startTimer(self.dt)

        self.vbpm = None
        self.statusBar().showMessage("Welcome")

        #self.initMachine("nsls2v2")
        #self._newVelemPlot("V2SR", aphla.machines.HLA_VBPM, 'x',
        #                   "H Orbit", c = None)
        #print "Thread started", self.machinit.isRunning()

        #self.newElementPlots("BPM", "x, y")
        #self.newElementPlot("BPM", "y")
        #self.newElementPlot("HCOR", "x")
        #self.newElementPlot("VCOR", "y")
        #self.newElementPlot("QUAD", "b1")
        #self.newElementPlot("SEXT", "b2")

    def updateMachineLatticeNames(self, wsub):
        i = self.machBox.findText(wsub.machlat[0])
        self.machBox.setCurrentIndex(i)
        self.reloadLatticeNames(wsub.machlat[0])

    def reloadLatticeNames(self, mach):
        self.latBox.clear()
        cur_mach = str(self.machBox.currentText())
        lats, lat0, pvm = self._mach.get(cur_mach, ({}, None, None))
        self.latBox.addItems([lat for lat in lats.keys()])
        if lat0:
            i = self.latBox.findText(lat0.name)
            self.latBox.setCurrentIndex(i)

    def closeEvent(self, event):
        self.physics.close()
        self.mdiarea.closeAllSubWindows()
        event.accept()

    def createMenuToolBar(self):
        #
        # file menu
        #
        #self.machMenu = self.menuBar().addMenu("&Machines")
        #self.connect(self.machMenu, SIGNAL("aboutToShow()"),
        #             self.updateMachMenu)
        self.openMenu = self.menuBar().addMenu("&Open")
        self.openMenu.addAction("New Plot ...", self.openNewPlot)
        self.openMenu.addAction("New Tune Plot", self.openTunePlot)
        self.openMenu.addAction("New BPM Plot",
                                partial(self.newElementPlots, "BPM", "x,y"))
        self.openMenu.addAction("New HCOR Plot",
                                partial(self.newElementPlots, "HCOR", "x"))
        self.openMenu.addAction("New VCOR Plot",
                                partial(self.newElementPlots, "VCOR", "y"))

        self.openMenu.addSeparator()
        self.openMenu.addAction("Open ORM", self.loadOrm)

        self.openMenu.addSeparator()
        self.openMenu.addAction("Save Lattice ...", self.saveSnapshot)

        fileQuitAction = QAction(QIcon(":/file_quit.png"), "&Quit", self)
        fileQuitAction.setShortcut("Ctrl+Q")
        fileQuitAction.setToolTip("Quit the application")
        fileQuitAction.setStatusTip("Quit the application")
        #fileQuitAction.setIcon(Qt.QIcon(":/filequit.png"))
        self.connect(fileQuitAction, SIGNAL("triggered()"), self.close)
        self.openMenu.addAction(fileQuitAction)

        # view
        self.viewMenu = self.menuBar().addMenu("&View")

        mkmenu = QMenu("&Mark", self.viewMenu)
        for fam in ["BPM", "COR", "QUAD", "SEXT", "INSERTION"]:
            famAct = QAction(fam, self)
            famAct.setCheckable(True)
            self.connect(famAct, SIGNAL("toggled(bool)"), self.click_markfam)
            mkmenu.addAction(famAct)
        #

        # errorbar
        #viewErrorBarAction = QAction(QIcon(":/view_errorbar.png"),
        #                            "Errorbar", self)
        #viewErrorBarAction.setCheckable(True)
        #viewErrorBarAction.setChecked(True)
        #self.connect(viewErrorBarAction, SIGNAL("toggled(bool)"),
        #             self.errorBar)
        #
        #zoomM = QMenu("Zoom", self.viewMenu)

        #
        #
        #drift_from_now = QAction("Drift from Now", self)
        #drift_from_now.setCheckable(True)
        #drift_from_now.setShortcut("Ctrl+N")
        #drift_from_golden = QAction("Drift from Golden", self)
        #drift_from_golden.setCheckable(True)
        #drift_from_none = QAction("None", self)
        #drift_from_none.setCheckable(True)

        #self.viewMenu.addAction(viewLiveAction)
        #self.viewMenu.addAction(viewSingleShotAction)
        #self.viewMenu.addSeparator()

        #self.viewMenu.addAction(drift_from_now)
        #self.viewMenu.addAction(drift_from_golden)
        #self.viewMenu.addAction(drift_from_none)
        #self.viewMenu.addAction(viewAutoScale)
        #self.viewMenu.addAction(viewErrorBarAction)
        #self.viewMenu.addSeparator()

        self.viewMenu.addMenu(mkmenu)

        #drift_group = QActionGroup(self)
        #drift_group.addAction(drift_from_none)
        #drift_group.addAction(drift_from_now)
        #drift_group.addAction(drift_from_golden)
        #drift_from_none.setChecked(True)

        sep = self.viewMenu.addSeparator()
        #sep.setText("Drift")
        #self.connect(drift_from_now, SIGNAL("triggered()"), self.setDriftNow)
        #self.connect(drift_from_none, SIGNAL("triggered()"), self.setDriftNone)
        #self.connect(drift_from_golden, SIGNAL("triggered()"),
        #             self.setDriftGolden)

        #viewStyle = QMenu("Line Style", self.viewMenu)
        #for act in ["Increase Point Size", "Decrease Point Size", None,
        #            "NoCurve", "Lines", "Sticks", None,
        #            "Solid Line", "Dashed Line", "Dotted Line", None,
        #            "Increase Line Width", "Decrease Line Width", None,
        #            "NoSymbol", "Ellipse", "Rect", "Diamond", "Triangle",
        #            "Cross", "XCross", "HLine", "VLine",
        #            "Star1", "Star2", "Hexagon", None,
        #            "Red", "Blue", "Green"]:
        #    if act is None:
        #        viewStyle.addSeparator()
        #    else:
        #        viewStyle.addAction(act, self.setPlotStyle)
        #self.viewMenu.addMenu(viewStyle)

        #self.viewMenu.addSeparator()
        #self.viewMenu.addAction(viewZoomOut15Action)
        #self.viewMenu.addAction(viewZoomIn15Action)
        #self.viewMenu.addAction(viewZoomAutoAction)
        #self.viewMenu.addSeparator()
        self.viewMenu.addAction("ORM SV", self.plotSVD)
        # a bug in PyQwt5 for datetime x-axis, waiting for Debian 7
        #self.viewMenu.addAction(viewDcct)
        #for ac in self.viewMenu.actions(): ac.setDisabled(True)

        #
        self.controlMenu = self.menuBar().addMenu("&Tools")

        self.controlMenu.addAction(QIcon(":/control_choosebpm.png"),
                                   "En-/Disable BPM",
                                   partial(chooseElement, 'BPM'))
        self.controlMenu.addAction("En-/Disable COR",
                                   partial(chooseElement, 'COR'))
        #self.controlMenu.addAction(controlResetPvDataAction)
        self.controlMenu.addSeparator()
        self.controlMenu.addAction("Lattice Snapshot ...", self.openSnapshot)
        #self.controlMenu.addAction(controlZoomInPlot1Action)
        #self.controlMenu.addAction(controlZoomOutPlot1Action)
        #self.controlMenu.addAction(controlZoomInPlot2Action)
        #self.controlMenu.addAction(controlZoomOutPlot2Action)
        self.controlMenu.addSeparator()
        self.controlMenu.addAction("Correct Hor. orbit",
                                   partial(aphla.correctOrbit, plane="H"))
        self.controlMenu.addAction("Correct Vert. orbit",
                                   partial(aphla.correctOrbit, plane="V"))
        self.controlMenu.addAction(QIcon(":/control_corrorbit.png"),
                                   "Correct orbit",
                                   partial(aphla.correctOrbit, plane="HV"))
        #steer_orbit.setDisabled(True)
        self.controlMenu.addAction("Local Bump ...", self.createLocalBump)
        self.controlMenu.addAction("Element Editor ...",
                                   self.showElementEditor)
        self.controlMenu.addSeparator()
        self.controlMenu.addAction("meas Beta", self.physics.measBeta)
        self.controlMenu.addAction("meas Dispersion",
                                   self.physics.measDispersion)
        self.controlMenu.addAction("beam based alignment", self.runBba)
        #for ac in self.controlMenu.actions(): ac.setDisabled(True)

        # Window
        self.windowMenu = self.menuBar().addMenu("&Windows")
        #self.windowMenu.addAction(self.elemeditor.toggleViewAction())
        self.windowMenu.addAction(self.logdock.toggleViewAction())
        #viewDcct = QAction("Beam Current", self)
        #viewDcct.setCheckable(True)
        #viewDcct.setChecked(True)
        #self.connect(viewDcct, SIGNAL("toggled(bool)"), self.dcct.setVisible)
        #self.windowMenu.addAction(viewDcct)
        self.windowMenu.addSeparator()
        self.windowMenu.addAction("Cascade", self.mdiarea.cascadeSubWindows)
        self.windowMenu.addAction("Tile", self.mdiarea.tileSubWindows)
        self.windowMenu.addAction("Tile Horizontally",
                                  self.tileSubWindowsHorizontally)
        # "ctrl+page up", "ctrl+page down"
        self.windowMenu.addAction("Previous",
                                  self.mdiarea.activatePreviousSubWindow,
                                  "Ctrl+Left")
        self.windowMenu.addAction("Next", self.mdiarea.activateNextSubWindow,
                                  "Ctrl+Right")
        self.windowMenu.addSeparator()

        # debug
        self.debugMenu = self.menuBar().addMenu("&Debug")
        self.debugMenu.addAction("_Reset Correctors_", self._reset_correctors)
        self.debugMenu.addAction("_Reset Quadrupoles_",
                                 self._reset_quadrupoles)
        self.debugMenu.addAction("_Random V Kick_", self._random_vkick)
        self.debugMenu.addAction("_Random H Kick_", self._random_hkick)
        #for ac in self.debugMenu.actions(): ac.setDisabled(True)

        # help
        self.helpMenu = self.menuBar().addMenu("&Help")
        self.helpMenu.addAction("About mleap", self.showAbout)

        #toolbar
        machToolBar = self.addToolBar("Machines")
        self.machBox = QtGui.QComboBox()
        self.latBox = QtGui.QComboBox()
        #self.connect(self.latBox, SIGNAL("currentIndexChanged(QString)"),
        #             self.__setLattice)
        machToolBar.addWidget(self.machBox)
        machToolBar.addWidget(self.latBox)
        #toolbar = QToolBar(self)
        #self.addToolBar(toolbar)
        #fileToolBar = self.addToolBar("File")
        #fileToolBar.setObjectName("FileToolBar")
        #fileToolBar.addAction(fileQuitAction)

        #
        viewToolBar1 = self.addToolBar("Live View")
        #viewToolBar.setObjectName("ViewToolBar")
        #viewToolBar.addAction(viewZoomOut15Action)
        #viewToolBar.addAction(viewZoomIn15Action)
        #viewToolBar.addAction(viewZoomAutoAction)
        #viewToolBar1.addAction(viewLiveAction)
        #viewToolBar1.addAction(viewSingleShotAction)
        #viewToolBar1.addSeparator()
        viewToolBar1.addAction(QIcon(":/new_bpm.png"), "Orbits",
                               partial(self.newElementPlots, "BPM", "x,y"))
        viewToolBar1.addAction(QIcon(":/new_cor.png"), "Correctors",
                               partial(self.newElementPlots, "COR", "x,y"))
        viewToolBar1.addAction(QIcon(":/new_quad.png"), "Quadrupoles",
                               partial(self.newElementPlots, "QUAD", "b1"))
        viewToolBar1.addAction(QIcon(":/new_sext.png"), "Sextupoles",
                               partial(self.newElementPlots, "SEXT", "b2"))
        #viewToolBar.addAction(viewErrorBarAction)
        #viewToolBar.addAction(QWhatsThis.createAction(self))

        #viewToolBar2 = self.addToolBar("Scale Plot")
        #zoomActions = [(":/view_zoom_xy.png", "Fit", self.scalePlot),
        #               (None, None, None),
        #               (":/view_zoom_y.png", "Fit In Y", self.scalePlot),
        #               (":/view_zoomin_y.png", "Zoom In Y", self.scalePlot),
        #               (":/view_zoomout_y.png", "Zoom Out Y", self.scalePlot),
        #               (":/view_move_up.png", "Move Up", self.scalePlot),
        #               (":/view_move_down.png", "Move Down", self.scalePlot),
        #               (None, None, None),
        #               (":/view_zoom_x.png", "Fit In X", self.scalePlot),
        #               (":/view_zoomin_x.png", "Zoom In X", self.scalePlot),
        #               (":/view_zoomout_x.png", "Zoom Out X", self.scalePlot),
        #               (":/view_move_left.png", "Move Left", self.scalePlot),
        #               (":/view_move_right.png", "Move Right", self.scalePlot),
        #               ]
        #for ico,name,hdl in zoomActions:
        #    if hdl is None: continue
        #    viewToolBar2.addAction(QIcon(ico), name, hdl)

        controlToolBar = self.addToolBar("Control")
        controlToolBar.addAction(QIcon(":/control_orbitcor.png"),
                                 "Correct Orbit", aphla.correctOrbit)
        controlToolBar.addAction(QIcon(":/control_localbump.png"),
                                 "Local Bump ...", self.createLocalBump)
        #controlToolBar.addAction(controlResetPvDataAction)

    def showAbout(self):
        QMessageBox.about(
            self, self.tr("mleap"),
            (self.tr("""<b>Machine/Lattice Editor And Plotter</b> v %1
                <p>Copyright &copy; Lingyun Yang, BNL, 2013-2014. 
                All rights reserved.
                <p>This application can be used to perform
                high level accelerator controls.
                <p>Python %2 - Qt %3 - PyQt %4 
                on %5""").arg(aphla.version.version).arg(
                platform.python_version()).arg(QtCore.QT_VERSION_STR).arg(
                    QtCore.PYQT_VERSION_STR).arg(platform.system())))

    def showElementEditor(self):
        mach, lat = self.getCurrentMachLattice()
        ed = ElementEditor(lat, parent=self)
        ed.setWindowFlags(Qt.Window)
        ed.setAttribute(Qt.WA_DeleteOnClose)
        ed.show()

    def getCurrentMachLattice(self, cadata=False):
        """return the current machine name and lattice object"""
        mach = str(self.machBox.currentText())
        latname = str(self.latBox.currentText())
        lat_dict, lat0, pvm = self._mach[mach]
        if not cadata:
            return mach, lat_dict[latname]
        else:
            return mach, lat_dict[latname], pvm

    def newElementPlots(self, elem, fields, **kw):
        self.logger.info("new plots: %s %s" % (elem, fields))
        _mach, _lat, _pvm = self.getCurrentMachLattice(cadata=True)
        mach, lat = kw.get("machlat", (_mach, _lat))
        handle = kw.get("handle", "readback")
        elems = lat.getElementList(elem)
        x, pvs = [], []
        field_list = re.findall(r'[^ ,]+', fields)
        for fld in field_list:
            si, pvsi = [], []
            for e in elems:
                if not e.isEnabled(): continue
                epv = e.pv(field=fld, handle=handle)
                if not epv: continue
                pvsi.append(epv[0])
                si.append(e.sb)
            x.append(si)
            pvs.append(pvsi)

        if not pvs:
            self.logger.error("no data found for elements '{0}' "
                              "and field '{1}'".format(elem, field))
            return

        p = ApMdiSubPlot(pvs=pvs,
                         x=x,
                         labels=["%s.%s" % (elem, fld) for fld in field_list],
                         magprof=lat.getBeamlineProfile(),
                         iqt=self.iqtApp,
                         **kw)
        #QObject.installEventFilter(p.aplot)
        #p.data = ManagedPvData(pvm, s, pvs, element=elemnames,
        #                       label="{0}.{1}".format(elem,field))
        p.setAttribute(Qt.WA_DeleteOnClose)
        str_elem = "{0}".format(elem)
        if len(str_elem) > 12: str_elem = str_elem[:9] + "..."
        str_field = "{0}".format(fields)
        if len(str_field) > 12: str_field = str_field[:9] + "..."
        p.setWindowTitle("[%s.%s] %s %s" %
                         (mach, lat.name, str_elem, str_field))
        self.connect(p, SIGNAL("elementSelected(PyQt_PyObject)"),
                     self.elementSelected)
        self.connect(p, SIGNAL("destroyed()"), self.subPlotDestroyed)
        #p.updatePlot()
        # set the zoom stack
        #p.aplot.setErrorBar(self.error_bar)
        #p.wid.autoScaleXY()
        #p.aplot.replot()
        self.mdiarea.addSubWindow(p)
        #print "Show"
        p.show()

        ##print "Enable the buttons"
        #if len(self.mdiarea.subWindowList()) > 0:
        #    self.elemeditor.setEnabled(True)

    def subPlotDestroyed(self):
        #if len(self.mdiarea.subWindowList()) == 0:
        #    self.elemeditor.setEnabled(False)
        pass

    def loadOrm(self):
        fileName = QtGui.QFileDialog.getOpenFileName(
            self, "Open Orbit Response Matrix", "",
            "ORM Files (*.h5 *.hdf5);;Text File (*.txt);;All Files(*)")
        fileName = str(fileName)
        try:
            m = np.loadtxt(fileName)
        except:
            QMessageBox.critical(self, "Abort", "Invalid matrix data")
            return
        mach, lat = self.getCurrentMachLattice()
        # assuming we already have the PV, name, field but just want to
        # replace the matrix elements.
        assert np.shape(m) == np.shape(lat.ormdata.m)
        nx, ny = np.shape(lat.ormdata.m)
        for i in range(nx):
            for j in range(ny):
                lat.ormdata.m[i, j] = m[i, j]

    def saveSnapshot(self):
        latdict = dict([(k, v[0]) for k, v in self._mach.items()])
        mach, lat = self.getCurrentMachLattice()
        snapdlg = SaveSnapshotDialog(latdict, mach)
        snapdlg.exec_()

    def saveLatSnapshot(self):
        mach, lat = self.getCurrentMachLattice()
        dpath = self._prepare_parent_dirs(mach)
        if not dpath:
            QMessageBox.warning(self, "Abort", "Aborted")
            return
        dt = datetime.datetime.now()
        fname = os.path.join(
            dpath,
            dt.strftime("snapshot_%d_%H%M%S_") + lat.name + ".hdf5")
        fileName = QtGui.QFileDialog.getSaveFileName(
            self, "Save Lattice Snapshot Data", fname,
            "Data Files (*.h5 *.hdf5);;All Files(*)")
        fileName = str(fileName)
        if not fileName: return
        aphla.catools.save_lat_epics(fileName, lat, mode='a')
        self.logger.info("snapshot created '%s'" % fileName)

    def saveMachSnapshot(self):
        mach, lat = self.getCurrentMachLattice()
        dpath = self._prepare_parent_dirs(mach)
        if not dpath:
            QMessageBox.warning(self, "Abort", "Aborted")
            return
        dt = datetime.datetime.now()
        fname = os.path.join(dpath, dt.strftime("snapshot_%d_%H%M%S.hdf5"))
        fileName = QtGui.QFileDialog.getSaveFileName(
            self, "Save Lattice Snapshot Data", fname,
            "Data Files (*.h5 *.hdf5);;All Files(*)")
        if not fileName: return
        fileName = str(fileName)
        import h5py
        f = h5py.File(str(fileName), 'w')
        f.close()
        self.logger.info("clean snapshot file created: '%s'" % fileName)
        for k, lat in self._mach[mach][0].items():
            aphla.catools.save_lat_epics(fileName, lat, mode='a')
            self.logger.info("lattice snapshot appended for '%s'" % lat.name)

    def openSnapshot(self):
        #self.logger.info("loading snapshot?")
        latdict = dict([(k, v[0]) for k, v in self._mach.items()])
        mach, lat = self.getCurrentMachLattice()
        lv = LatSnapshotMain(self, latdict, mach, self.logger)
        lv.setWindowFlags(Qt.Window)
        #self.logger.info("initialized")
        #lv.loadLatSnapshotH5()
        lv.exec_()

    def openTunePlot(self):
        mach, lat = self.getCurrentMachLattice()
        nu = lat.getElementList('tune')
        pvs = [(e.pv(field="x",
                     handle="readback")[0], e.pv(field="y",
                                                 handle="readback")[0])
               for e in nu]
        labels = [e.name for e in nu]
        twiss = lat.getElementList("VA")
        pvs.extend([(e.pv(field="nux", handle="readback")[0],
                     e.pv(field="nuy", handle="readback")[0]) for e in twiss])
        labels.extend([e.name for e in twiss])

        p = ApMdiSubPlot(pvs=pvs, labels=labels, dtype="Tunes")
        #QObject.installEventFilter(p.aplot)
        #p.data = ManagedPvData(pvm, s, pvs, element=elemnames,
        #                       label="{0}.{1}".format(elem,field))
        p.setAttribute(Qt.WA_DeleteOnClose)
        p.setWindowTitle("[%s.%s] Tunes" % (mach, lat.name))
        self.connect(p, SIGNAL("elementSelected(PyQt_PyObject)"),
                     self.elementSelected)
        self.connect(p, SIGNAL("destroyed()"), self.subPlotDestroyed)
        #p.updatePlot()
        # set the zoom stack
        #p.aplot.setErrorBar(self.error_bar)
        #p.wid.autoScaleXY()
        #p.aplot.replot()
        self.mdiarea.addSubWindow(p)
        #print "Show"
        p.show()

    def openNewPlot(self):
        mach, lat = self.getCurrentMachLattice()
        fl = QtGui.QFormLayout()
        fl.addRow("Machine", QtGui.QLabel("%s" % mach))
        fl.addRow("Lattice", QtGui.QLabel("%s" % lat.name))
        elem, fld = QtGui.QLineEdit(), QtGui.QLineEdit()
        fl.addRow("Elements", elem)
        fl.addRow("Field", fld)
        dtype = QtGui.QComboBox()
        for tx in ["Array", "Waveform", "Time Series"]:
            dtype.addItem(tx)
        fl.addRow("Data Type", dtype)
        dlg = QtGui.QDialog()
        bx = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok
                                    | QtGui.QDialogButtonBox.Cancel)
        self.connect(bx, SIGNAL("accepted()"), dlg.accept)
        self.connect(bx, SIGNAL("rejected()"), dlg.reject)
        h1 = QtGui.QHBoxLayout()
        h1.addStretch()
        h1.addWidget(bx)
        v1 = QtGui.QVBoxLayout()
        v1.addLayout(fl)
        v1.addLayout(h1)
        dlg.setLayout(v1)

        if dlg.exec_():
            self.newElementPlots(str(elem.text()),
                                 str(fld.text()),
                                 machlat=(mach, lat),
                                 dtype=str(dtype.currentText()))

    def click_markfam(self, on):
        famname = self.sender().text()
        mks = []
        mach, lat = self.getCurrentMachLattice()
        # need to convert to python str
        for elem in lat.getElementList(str(famname)):
            if elem.family != famname: continue
            if elem.virtual: continue
            mks.append([elem.name, 0.5 * (elem.sb + elem.se)])

        for w in self.mdiarea.subWindowList():
            w.setMarkers(mks, on)
        #print self._machlat.keys()

    def _reset_correctors(self):
        self.logger.info("reset correctors")
        aphla.hlalib._reset_trims()

    def _reset_quadrupoles(self):
        self.logger.info("reset quadrupoles")
        aphla.hlalib._reset_quad()

    def _random_hkick(self):
        mach, lat = self.getCurrentMachLattice()
        hcors = lat.getElementList('HCOR')
        for k in range(3):
            i = np.random.randint(len(hcors))
            self.logger.info("Setting {0}/{1} HCOR".format(i, len(hcors)))
            hcors[i].x += np.random.rand() * 2e-6

    def _random_vkick(self):
        mach, lat = self.getCurrentMachLattice()
        cors = lat.getElementList('VCOR')
        for k in range(3):
            i = np.random.randint(len(cors))
            cors[i].y += np.random.rand() * 1e-6
            self.logger.info("increased kicker '{0}' by 1e-7 ({1} {2})".format(
                cors[i].name, cors[i].y, cors[i].getUnit('y', None)))

    def viewDcctPlot(self, on):
        self.dcct.setVisible(on)

    def liveData(self, on):
        """Switch on/off live data taking"""
        self.live_orbit = on

    def scalePlot(self):
        w = self.mdiarea.currentSubWindow()
        if not w: return
        st, p = self.sender().text(), w.aplot
        if st == "Fit":
            p.scaleXBottom()
            p.scaleYLeft()
            # a hack
            bound = p.curvesBound()
            p.zoomer1.setZoomStack([bound])
        elif st == "Fit In Y":
            p.scaleYLeft()
        elif st == "Zoom In Y":
            p.scaleYLeft(1. / 1.5)
        elif st == "Zoom Out Y":
            p.scaleYLeft(1.5)
        elif st == "Move Up":
            p.moveCurves(Qwt.QwtPlot.yLeft, 0.8)
        elif st == "Move Down":
            p.moveCurves(Qwt.QwtPlot.yLeft, -0.8)
        elif st == "Fit In X":
            p.scaleXBottom()
        elif st == "Zoom In X":
            p.scaleXBottom(1.0 / 1.5)
        elif st == "Zoom Out X":
            p.scaleXBottom(1.5)
        elif st == "Move Left":
            p.moveCurves(Qwt.QwtPlot.xBottom, 0.8)
        elif st == "Move Right":
            p.moveCurves(Qwt.QwtPlot.xBottom, -0.8)
        else:
            self.logger.error("unknow action '{0}'".format(st))

    def getVisibleRange(self):
        w = self.mdiarea.currentSubWindow()
        if not w:
            mach, lat = self.getCurrentMachLattice()
            self.logger.warn(
                "no active plot, use full range of {0}.{1}".format(
                    mach, lat.name))
            return lat.getLocationRange()
        else:
            return w.currentXlim()

    def getVisibleElements(self, elemname, sb=None, se=None):
        w = self.mdiarea.currentSubWindow()
        mach, lat = self.getCurrentMachLattice()
        elems = lat.getElementList(elemname)
        if sb is not None:
            elems = [e for e in elems if e.sb >= sb]
        if se is not None:
            elems = [e for e in elems if e.se <= se]

        self.logger.info("searching for '{0}' in range [{1}, {2}]".format(
            elemname, sb, se))

        return elems

    def timerEvent(self, e):
        if e.timerId() != self.timerId: return

        #if not self.elemeditor.isHidden():
        #    self.elemeditor.updateModelData()

        #if self.live_orbit:
        #    self.itimer += 1
        #    #self.updatePlots()
        #    #self.updateStatus()
        #    for w in self.mdiarea.subWindowList():
        #        if not isinstance(w, ApMdiSubPlot): continue
        #        if not w.live: continue
        #        w.updatePlot()
        #    self.statusBar().showMessage("plot updated: {0}".format(
        #        time.strftime("%F %T")))
        #else:
        #    self.statusBar().showMessage("live update disabled")

    def singleShot(self):
        for w in self.mdiarea.subWindowList():
            if not isinstance(w, ApMdiSubPlot): continue
            w.updatePlot()

        self.statusBar().showMessage("plot updated: {0}".format(
            time.strftime("%F %T")))

    def elementSelected(self, elems):
        """this action is ignored"""
        mach, lat, elemnames = elems
        #_lat = self._machlat[mach][lat]
        self.logger.info("element selected")

        #elemobjs = _lat.getElementList(elemnames)
        #self._elemed.addElements(elemobjs)

    def activeOrbitPlot(self, field):
        mach = str(self.machBox.currentText())
        lat = str(self.latBox.currentText())
        for w in self.mdiarea.subWindowList():
            #print w.machine(), w.lattice(), w.data.yfield
            if not isinstance(w, ApMdiSubPlot): continue
            if w.machine() != mach: continue
            if w.lattice() != lat: continue
            if w.data.yfield != field: continue
            return w

        return None

    def createLocalBump_(self):
        """create local bump"""
        if self._dlgOrbitCor is None:
            bpms = ap.getElements("BPM")
            cors = ap.getElements("COR")
            self._dlgOrbitCor = OrbitCorrDlg(bpms, cors)
            #corbitdlg.resize(600, 500)
            self._dlgOrbitCor.setWindowTitle("Create Local Bump")
        self._dlgOrbitCor.show()
        self._dlgOrbitCor.raise_()
        self._dlgOrbitCor.activateWindow()

    def createLocalBump(self):
        """create local bump"""
        bpms = ap.getElements("BPM")
        cors = ap.getElements("COR")
        dlgOrbitCor = OrbitCorrDlg(bpms, cors, parent=self)
        #corbitdlg.resize(600, 500)
        dlgOrbitCor.setWindowTitle("Create Local Bump")
        dlgOrbitCor.show()
        dlgOrbitCor.raise_()
        dlgOrbitCor.activateWindow()
        dlgOrbitCor.setAttribute(Qt.WA_DeleteOnClose)

    def runBba(self):
        mach, lat = self.getCurrentMachLattice()
        bpms = [
            e for e in lat.getElementList('BPM')
            if e not in self.physics.deadelems
        ]
        self.physics.runBba(bpms)

    def plotSVD(self):
        mach, lat = self.getCurrentMachLattice()
        if not lat.ormdata:
            QMessageBox.critical(self, "ORM SVD",
                                 "machine '%s' ORM data is not available" % \
                                 mach,
                                 QMessageBox.Ok)
            return
        m, brec, trec = lat.ormdata.getMatrix(None,
                                              None,
                                              full=False,
                                              ignore=self.getDeadElements())
        U, s, V = np.linalg.svd(m, full_matrices=True)
        #print np.shape(s), s
        self.sp = ApSvdPlot(s)
        self.sp.show()

    def tileSubWindowsHorizontally(self):
        pos = QtCore.QPoint(0, 0)
        subwins = self.mdiarea.subWindowList()
        for w in subwins:
            height = self.mdiarea.height() / len(subwins)
            rect = QtCore.QRect(0, 0, self.mdiarea.width(), height)
            w.setGeometry(rect)
            w.move(pos)
            pos.setY(pos.y() + w.height())
예제 #52
0
    def __init__(self):
        QMainWindow.__init__(self)

        self.commSignal.connect(self.plot)

        self.figure, self.drawing = plt.subplots()
        self.figure.set_tight_layout(True)
        self.canvas = FigureCanvas(self.figure)

        self.setCentralWidget(self.canvas)
        dock = QDockWidget("Values")
        self.addDockWidget(Qt.RightDockWidgetArea, dock)

        # -----------------------------------------------------------------
        sliders = QWidget()
        sliders_grid = QGridLayout(sliders)

        chkRepeaterRun = QCheckBox("&Repeater...")
        chkRepeaterRun.setFocusPolicy(Qt.NoFocus)
        sliders_grid.addWidget(chkRepeaterRun, 0, 0)

        self.lowROI = QLineEdit()
        # self.lowROI.setFocusPolicy(Qt.NoFocus)
        self.lowROI.setValidator(QIntValidator(0, self.maxBins - 1))
        self.highROI = QLineEdit()
        # self.highROI.setFocusPolicy(Qt.NoFocus)
        self.highROI.setValidator(QIntValidator(0, self.maxBins - 1))
        sliders_grid.addWidget(self.lowROI,  1, 0)
        sliders_grid.addWidget(self.highROI, 2, 0)

        dock.setWidget(sliders)
        # -----------------------------------------------------------------

        self.dxpMcaPVs = []
        self.mcas = []
        self.noOfElement = 7
        self.dxpAcqPV = epics.PV('BL7D:dxpXMAP:Acquiring')

        for i in range(1, self.noOfElement+1, 1):
            self.dxpMcaPVs.append(epics.PV('BL7D:dxpXMAP:mca' + str(i)))

        # Read current mcas
        for i in self.dxpMcaPVs:
            self.mcas.append(i.get())

        # Create x axis value
        self.x = np.arange(0, len(self.mcas[0]), 1)

        # 1st plot mca data
        self.drawing.plot(self.x, self.mcas[0], self.x, self.mcas[1],
                          self.x, self.mcas[2], self.x, self.mcas[3],
                          self.x, self.mcas[4], self.x, self.mcas[5],
                          self.x, self.mcas[6], linewidth=1.0)

        self.drawing.grid()
        self.drawing.autoscale()

        self.a = Point(self.canvas, self.drawing, self.maxBins / 4, self.callback)
        self.b = Point(self.canvas, self.drawing, self.maxBins / 2, self.callback)

        # self.plot()
        # We need to draw *and* flush
        self.figure.canvas.draw()
        self.figure.canvas.flush_events()

        self.addCallbackAcq()
예제 #53
0
class PluginManualIntegrator(MSPlugin):
    def __init__(self, model, view, parent=None):
        MSPlugin.__init__(self, model, view, parent)
        #self.connect(self.view.mdiArea, SIGNAL('subWindowActivated(QMdiSubWindow*)'), self.updateCurrentWindow)
        self.guiWidget = []

        self.view.mdiArea.subWindowActivated.connect(self.updateCurrentWindow)
        self.x1val = 0

        self.dock = QDockWidget("Manual Integrator")
        self.guiWidget.append(self.dock)
        self.window = self.view.mdiArea.activeSubWindow(
        ) if self.view.mdiArea.activeSubWindow() else None
        if self.window is not None:
            #self.connect(self.window.widget().pw,
            #            SIGNAL(self.window.widget().pw.sigMouseReleased),
            #            self.pluginAlgorithm)
            self.window.widget().pw.plotItem.vb.sigClick.connect(
                self.pluginAlgorithm)

        self.label = QLabel('Inactive') if not self.window else QLabel(
            'Active')
        self.dock.setWidget(self.label)
        self._guiUpdate()

    def _guiUpdate(self):
        self.view.addDockWidget(
            0x1, self.dock
        )  #showInformationMessage('test', "Hello From Integrator Plugin")

    def _buildConnections(self):
        pass

    def updateCurrentWindow(self, win):
        if win is None: return
        #print "update current window", win
        self.window = win
        #self.connect(self.window.widget().pw,
        #            SIGNAL(self.window.widget().pw.sigMouseReleased),
        #            self.pluginAlgorithm)
        self.window.widget().pw.plotItem.vb.sigClick.connect(
            self.pluginAlgorithm)
        self.dock.setWidget(Widget(self.dock))

    def pluginAlgorithm(self, e):
        """
        receive the event off release MouseEvent
        
        """
        if not self.x1val:
            self.x1val = e.x()
            self.dock.widget().x1.setText(str(self.x1val))
            self.dock.widget().x2.setText('')
            self.dock.widget().result.setText('')
            return

        x2 = e.x()
        self.dock.widget().x2.setText(str(x2))
        chrom = self.window.widget().data[0]  #take the first one
        res = chrom.integrationBtw(self.x1val, x2)
        self.dock.widget().result.setText(",success:".join(
            [str(res[2]), str(res[3])]))
        self.x1val = 0
        #self.reinitialize()

    def reinitialize(self):
        self.x1val = 0
        self.dock.widget().x2.setText('')
        self.dock.widget().x1.setText('')

    def unload(self):
        for e in self.guiWidget:
            e.setParent(None)
            del e
        self.view.update()
예제 #54
0
class DBMainWindow(QMainWindow):
    """Main Window and Portal
    
    .. todo:: Remember the dock position
    """

    W_NAME = "DBMainWindow"

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

        self.db = None

        self.setWindowTitle("PyQtDb")
        self.setWindowIcon(Ico.icon(Ico.FavIcon))

        self.setMinimumWidth(800)
        self.setMinimumHeight(800)
        """
        topBar = QToolBar()
        self.addToolBar(Qt.TopToolBarArea, topBar)
        
        topBar.addAction("New Server")
        """

        ## Servers Widget
        self.dockServers = QDockWidget("Servers")
        self.dockServers.setFeatures(QDockWidget.DockWidgetMovable)
        self.dockServers.setAllowedAreas(Qt.LeftDockWidgetArea
                                         | Qt.RightDockWidgetArea)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockServers)

        self.serversWidget = DBServersWidget.DBServersWidget(self)
        """Instance of :py:class:`~pyqtdb.DBServersWidget.DBServersWidget` in dock"""
        self.dockServers.setWidget(self.serversWidget)
        self.connect(self.serversWidget, SIGNAL("open_server"),
                     self.on_open_server)

        self.cenWid = QWidget()
        self.setCentralWidget(self.cenWid)

        self.mainLayout = QHBoxLayout()
        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.setSpacing(0)
        self.cenWid.setLayout(self.mainLayout)

        self.tabWidget = QTabWidget()
        """The main tabs"""
        self.tabWidget.setTabsClosable(True)
        self.mainLayout.addWidget(self.tabWidget)

        G.settings.restore_window(self)

    def on_open_server(self, srv):
        """Opens server by adding a :py:class:`~pyqtdb.DBBrowser.DBBrowser` in the the tabWidget"""
        server = G.settings.get_server(str(srv))
        print "oopen", srv, server
        widget = DBBrowser.DBBrowser(self, server)
        self.tabWidget.addTab(widget, Ico.icon(Ico.Server), server['server'])
        self.tabWidget.setCurrentIndex(self.tabWidget.indexOf(widget))

    def closeEvent(self, event):
        """Save window settings on close with :py:class:`~pyqtdb.XSettings.XSettings.save_window` """
        G.settings.save_window(self)
예제 #55
0
class MenuBuilderDialog(QDialog, Ui_Dialog):
    def __init__(self, uiparent):
        super(MenuBuilderDialog, self).__init__()

        self.setupUi(self)

        # reference to caller
        self.uiparent = uiparent

        self.combo_profile.lineEdit().setPlaceholderText(
            self.tr("Profile name"))

        # add icons
        self.button_add_menu.setIcon(
            QIcon(":/plugins/MenuBuilder/resources/plus.svg"))
        self.button_delete_profile.setIcon(
            QIcon(":/plugins/MenuBuilder/resources/delete.svg"))

        # custom qtreeview
        self.target = CustomQtTreeView(self)
        self.target.setGeometry(QRect(440, 150, 371, 451))
        self.target.setAcceptDrops(True)
        self.target.setDragEnabled(True)
        self.target.setDragDropMode(QAbstractItemView.DragDrop)
        self.target.setObjectName("target")
        self.target.setDropIndicatorShown(True)
        self.target.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.target.setHeaderHidden(True)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.target.sizePolicy().hasHeightForWidth())
        self.target.setSizePolicy(sizePolicy)
        self.target.setAutoFillBackground(True)
        self.verticalLayout_2.addWidget(self.target)

        self.browser = QgsBrowserModel()
        self.source.setModel(self.browser)
        self.source.setHeaderHidden(True)
        self.source.setDragEnabled(True)
        self.source.setSelectionMode(QAbstractItemView.ExtendedSelection)

        self.menumodel = MenuTreeModel(self)
        self.target.setModel(self.menumodel)
        self.target.setAnimated(True)

        # add a dock widget
        self.dock_widget = QDockWidget("Menus")
        self.dock_widget.resize(400, 300)
        self.dock_widget.setFloating(True)
        self.dock_widget.setObjectName(self.tr("Menu Tree"))
        self.dock_widget_content = QWidget()
        self.dock_widget.setWidget(self.dock_widget_content)
        dock_layout = QVBoxLayout()
        self.dock_widget_content.setLayout(dock_layout)
        self.dock_view = DockQtTreeView(self.dock_widget_content)
        self.dock_view.setDragDropMode(QAbstractItemView.DragOnly)
        self.dock_menu_filter = QLineEdit()
        self.dock_menu_filter.setPlaceholderText(
            self.tr("Filter by table description (postgis only)"))
        dock_layout.addWidget(self.dock_menu_filter)
        dock_layout.addWidget(self.dock_view)
        self.dock_view.setHeaderHidden(True)
        self.dock_view.setDragEnabled(True)
        self.dock_view.setSelectionMode(QAbstractItemView.ExtendedSelection)
        self.dock_view.setAnimated(True)
        self.dock_view.setObjectName("treeView")
        self.proxy_model = LeafFilterProxyModel(self)
        self.proxy_model.setFilterRole(Qt.ToolTipRole)
        self.proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive)

        self.profile_list = []
        self.table = 'qgis_menubuilder_metadata'

        self.layer_handler = {
            'vector': self.load_vector,
            'raster': self.load_raster
        }

        # connect signals and handlers
        self.combo_database.activated.connect(
            partial(self.set_connection, dbname=None))
        self.combo_schema.activated.connect(self.update_profile_list)
        self.combo_profile.activated.connect(
            partial(self.update_model_idx, self.menumodel))
        self.button_add_menu.released.connect(self.add_menu)
        self.button_delete_profile.released.connect(self.delete_profile)
        self.dock_menu_filter.textEdited.connect(self.filter_update)
        self.dock_view.doubleClicked.connect(self.load_from_index)

        self.buttonBox.rejected.connect(self.reject)
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.button(QDialogButtonBox.Apply).clicked.connect(
            self.apply)

    def filter_update(self):
        text = self.dock_menu_filter.displayText()
        self.proxy_model.setFilterRegExp(text)

    def show_dock(self, state, profile=None, schema=None):
        if not state:
            # just hide widget
            self.dock_widget.setVisible(state)
            return
        # dock must be read only and deepcopy of model is not supported (c++ inside!)
        self.dock_model = MenuTreeModel(self)
        if profile:
            # bypass combobox
            self.update_model(self.dock_model, schema, profile)
        else:
            self.update_model_idx(self.dock_model,
                                  self.combo_profile.currentIndex())
        self.dock_model.setHorizontalHeaderLabels(["Menus"])
        self.dock_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.proxy_model.setSourceModel(self.dock_model)
        self.dock_view.setModel(self.proxy_model)
        self.dock_widget.setVisible(state)

    def show_menus(self, state, profile=None, schema=None):
        if state:
            self.load_menus(profile=profile, schema=schema)
            return
        # remove menus
        for menu in self.uiparent.menus:
            self.uiparent.iface.mainWindow().menuBar().removeAction(
                menu.menuAction())

    def add_menu(self):
        """
        Add a menu inside qtreeview
        """
        item = QStandardItem('NewMenu')
        item.setIcon(QIcon(':/plugins/MenuBuilder/resources/menu.svg'))
        # select current index selected and insert as a sibling
        brother = self.target.selectedIndexes()

        if not brother or not brother[0].parent():
            # no selection, add menu at the top level
            self.menumodel.insertRow(self.menumodel.rowCount(), item)
            return

        parent = self.menumodel.itemFromIndex(brother[0].parent())
        if not parent:
            self.menumodel.insertRow(self.menumodel.rowCount(), item)
            return
        parent.appendRow(item)

    def update_database_list(self):
        """update list of defined postgres connections"""
        settings = QSettings()
        settings.beginGroup("/PostgreSQL/connections")
        keys = settings.childGroups()
        self.combo_database.clear()
        self.combo_schema.clear()
        self.menumodel.clear()
        self.combo_database.addItems(keys)
        self.combo_database.setCurrentIndex(-1)
        settings.endGroup()
        # clear profile list
        self.combo_profile.clear()
        self.combo_profile.setCurrentIndex(-1)

    def set_connection(self, databaseidx, dbname=None):
        """
        Connect to selected postgresql database
        """
        selected = self.combo_database.itemText(databaseidx) or dbname
        if not selected:
            return

        settings = QSettings()
        settings.beginGroup("/PostgreSQL/connections/{}".format(selected))

        if not settings.contains("database"):
            # no entry?
            QMessageBox.critical(self, "Error",
                                 "There is no defined database connection")
            return

        uri = QgsDataSourceURI()

        settingsList = [
            "service", "host", "port", "database", "username", "password"
        ]
        service, host, port, database, username, password = map(
            lambda x: settings.value(x, "", type=str), settingsList)

        useEstimatedMetadata = settings.value("estimatedMetadata",
                                              False,
                                              type=bool)
        sslmode = settings.value("sslmode",
                                 QgsDataSourceURI.SSLprefer,
                                 type=int)

        settings.endGroup()

        if service:
            uri.setConnection(service, database, username, password, sslmode)
        else:
            uri.setConnection(host, port, database, username, password,
                              sslmode)

        uri.setUseEstimatedMetadata(useEstimatedMetadata)

        # connect to db
        self.connect_to_uri(uri)
        # update schema list
        self.update_schema_list()

    @contextmanager
    def transaction(self):
        try:
            yield
            self.connection.commit()
        except self.pg_error_types() as e:
            self.connection.rollback()
            raise e

    def check_connected(func):
        """
        Decorator that checks if a database connection is active before executing function
        """
        @wraps(func)
        def wrapped(inst, *args, **kwargs):
            if not getattr(inst, 'connection', False):
                QMessageBox(
                    QMessageBox.Warning, "Menu Builder",
                    inst.tr(
                        "Not connected to any database, please select one"),
                    QMessageBox.Ok, inst).exec_()
                return
            if inst.connection.closed:
                QMessageBox(
                    QMessageBox.Warning, "Menu Builder",
                    inst.tr(
                        "Not connected to any database, please select one"),
                    QMessageBox.Ok, inst).exec_()
                return
            return func(inst, *args, **kwargs)

        return wrapped

    def connect_to_uri(self, uri):
        self.close_connection()
        self.host = uri.host() or os.environ.get('PGHOST')
        self.port = uri.port() or os.environ.get('PGPORT')

        username = uri.username() or os.environ.get(
            'PGUSER') or os.environ.get('USER')
        password = uri.password() or os.environ.get('PGPASSWORD')

        try:
            self.connection = psycopg2.connect(uri.connectionInfo())
        except self.pg_error_types() as e:
            err = str(e)
            conninfo = uri.connectionInfo()

            ok, username, password = QgsCredentials.instance().get(
                conninfo, username, password, err)
            if not ok:
                raise Exception(e)

            if username:
                uri.setUsername(username)

            if password:
                uri.setPassword(password)

            self.connection = psycopg2.connect(uri.connectionInfo())

        self.pgencoding = self.connection.encoding

        return True

    def pg_error_types(self):
        return (psycopg2.InterfaceError, psycopg2.OperationalError,
                psycopg2.ProgrammingError)

    @check_connected
    def update_schema_list(self):
        self.combo_schema.clear()
        with self.transaction():
            cur = self.connection.cursor()
            cur.execute("""
                select nspname
                from pg_namespace
                where nspname not ilike 'pg_%'
                and nspname not in ('pg_catalog', 'information_schema')
                """)
            schemas = [row[0] for row in cur.fetchall()]
            self.combo_schema.addItems(schemas)

    @check_connected
    def update_profile_list(self, schemaidx):
        """
        update profile list from database
        """
        schema = self.combo_schema.itemText(schemaidx)
        with self.transaction():
            cur = self.connection.cursor()
            cur.execute("""
                select 1
                from pg_tables
                    where schemaname = '{0}'
                    and tablename = '{1}'
                union
                select 1
                from pg_matviews
                    where schemaname = '{0}'
                    and matviewname = '{1}'
                """.format(schema, self.table))
            tables = cur.fetchone()
            if not tables:
                box = QMessageBox(
                    QMessageBox.Warning, "Menu Builder",
                    self.tr("Table '{}.{}' not found in this database, "
                            "would you like to create it now ?").format(
                                schema, self.table),
                    QMessageBox.Cancel | QMessageBox.Yes, self)
                ret = box.exec_()
                if ret == QMessageBox.Cancel:
                    return False
                elif ret == QMessageBox.Yes:
                    cur.execute("""
                        create table {}.{} (
                            id serial,
                            name varchar,
                            profile varchar,
                            model_index varchar,
                            datasource_uri text
                        )
                        """.format(schema, self.table))
                    self.connection.commit()
                    return False

            cur.execute("""
                select distinct(profile) from {}.{}
                """.format(schema, self.table))
            profiles = [row[0] for row in cur.fetchall()]
            saved_profile = self.combo_profile.currentText()
            self.combo_profile.clear()
            self.combo_profile.addItems(profiles)
            self.combo_profile.setCurrentIndex(
                self.combo_profile.findText(saved_profile))

    @check_connected
    def delete_profile(self):
        """
        Delete profile currently selected
        """
        idx = self.combo_profile.currentIndex()
        schema = self.combo_schema.currentText()
        profile = self.combo_profile.itemText(idx)
        box = QMessageBox(QMessageBox.Warning, "Menu Builder",
                          self.tr("Delete '{}' profile ?").format(profile),
                          QMessageBox.Cancel | QMessageBox.Yes, self)
        ret = box.exec_()
        if ret == QMessageBox.Cancel:
            return False
        elif ret == QMessageBox.Yes:
            self.combo_profile.removeItem(idx)
            with self.transaction():
                cur = self.connection.cursor()
                cur.execute("""
                    delete from {}.{}
                    where profile = '{}'
                    """.format(schema, self.table, profile))
        self.menumodel.clear()
        self.combo_profile.setCurrentIndex(-1)

    def update_model_idx(self, model, profile_index):
        """
        wrapper that checks combobox
        """
        profile = self.combo_profile.itemText(profile_index)
        schema = self.combo_schema.currentText()
        self.update_model(model, schema, profile)

    def sortby_modelindex(self, rows):
        return sorted(
            rows,
            key=lambda line: '/'.join(
                ['{:04}'.format(elem[0]) for elem in json.loads(line[2])]))

    @check_connected
    def update_model(self, model, schema, profile):
        """
        Update the model by retrieving the profile given in database
        """
        menudict = {}

        with self.transaction():
            cur = self.connection.cursor()
            select = """
                select name, profile, model_index, datasource_uri
                from {}.{}
                where profile = '{}'
                """.format(schema, self.table, profile)
            cur.execute(select)
            rows = cur.fetchall()
            model.clear()
            for name, profile, model_index, datasource_uri in self.sortby_modelindex(
                    rows):
                menu = model.invisibleRootItem()
                indexes = json.loads(model_index)
                parent = ''
                for idx, subname in indexes[:-1]:
                    parent += '{}-{}/'.format(idx, subname)
                    if parent in menudict:
                        # already created entry
                        menu = menudict[parent]
                        continue
                    # create menu
                    item = QStandardItem(subname)
                    uri_struct = QgsMimeDataUtils.Uri(datasource_uri)
                    item.setData(uri_struct)
                    item.setIcon(
                        QIcon(':/plugins/MenuBuilder/resources/menu.svg'))
                    item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsUserCheckable
                                  | Qt.ItemIsEnabled | Qt.ItemIsDropEnabled
                                  | Qt.ItemIsEditable)
                    item.setWhatsThis("menu")
                    menu.appendRow(item)
                    menudict[parent] = item
                    # set current menu to the new created item
                    menu = item

                # add leaf (layer item)
                item = QStandardItem(name)
                uri_struct = QgsMimeDataUtils.Uri(datasource_uri)
                # fix layer name instead of table name
                # usefull when the layer has been renamed in menu
                uri_struct.name = name
                if uri_struct.providerKey in ICON_MAPPER:
                    item.setIcon(QIcon(ICON_MAPPER[uri_struct.providerKey]))
                item.setData(uri_struct)
                # avoid placing dragged layers on it
                item.setDropEnabled(False)
                if uri_struct.providerKey == 'postgres':
                    # set tooltip to postgres comment
                    comment = self.get_table_comment(uri_struct.uri)
                    item.setToolTip(comment)
                menudict[parent].appendRow(item)

    @check_connected
    def save_changes(self, save_to_db=True):
        """
        Save changes in the postgres table
        """
        schema = self.combo_schema.currentText()
        profile = self.combo_profile.currentText()
        if not profile:
            QMessageBox(QMessageBox.Warning, "Menu Builder",
                        self.tr("Profile cannot be empty"), QMessageBox.Ok,
                        self).exec_()
            return False

        if save_to_db:
            try:
                with self.transaction():
                    cur = self.connection.cursor()
                    cur.execute(
                        "delete from {}.{} where profile = '{}'".format(
                            schema, self.table, profile))
                    for item, data in self.target.iteritems():
                        if not data:
                            continue
                        cur.execute(
                            """
                        insert into {}.{} (name,profile,model_index,datasource_uri)
                        values (%s, %s, %s, %s)
                        """.format(schema, self.table),
                            (item[-1][1], profile, json.dumps(item),
                             data.data()))
            except Exception as exc:
                QMessageBox(QMessageBox.Warning, "Menu Builder",
                            exc.message.decode(self.pgencoding),
                            QMessageBox.Ok, self).exec_()
                return False

        self.save_session(self.combo_database.currentText(), schema, profile,
                          self.activate_dock.isChecked(),
                          self.activate_menubar.isChecked())
        self.update_profile_list(self.combo_schema.currentIndex())
        self.show_dock(self.activate_dock.isChecked())
        self.show_menus(self.activate_menubar.isChecked())
        return True

    @check_connected
    def load_menus(self, profile=None, schema=None):
        """
        Load menus in the main windows qgis bar
        """
        if not schema:
            schema = self.combo_schema.currentText()
        if not profile:
            profile = self.combo_profile.currentText()
        # remove previous menus
        for menu in self.uiparent.menus:
            self.uiparent.iface.mainWindow().menuBar().removeAction(
                menu.menuAction())

        with self.transaction():
            cur = self.connection.cursor()
            select = """
                select name, profile, model_index, datasource_uri
                from {}.{}
                where profile = '{}'
                """.format(schema, self.table, profile)
            cur.execute(select)
            rows = cur.fetchall()
        # item accessor ex: '0-menu/0-submenu/1-item/'
        menudict = {}
        # reference to parent item
        parent = ''
        # reference to qgis main menu bar
        menubar = self.uiparent.iface.mainWindow().menuBar()

        for name, profile, model_index, datasource_uri in self.sortby_modelindex(
                rows):
            uri_struct = QgsMimeDataUtils.Uri(datasource_uri)
            indexes = json.loads(model_index)
            # root menu
            parent = '{}-{}/'.format(indexes[0][0], indexes[0][1])
            if parent not in menudict:
                menu = QMenu(self.uiparent.iface.mainWindow())
                self.uiparent.menus.append(menu)
                menu.setObjectName(indexes[0][1])
                menu.setTitle(indexes[0][1])
                menubar.insertMenu(
                    self.uiparent.iface.firstRightStandardMenu().menuAction(),
                    menu)
                menudict[parent] = menu
            else:
                # menu already there
                menu = menudict[parent]

            for idx, subname in indexes[1:-1]:
                # intermediate submenus
                parent += '{}-{}/'.format(idx, subname)
                if parent not in menudict:
                    submenu = menu.addMenu(subname)
                    submenu.setObjectName(subname)
                    submenu.setTitle(subname)
                    menu = submenu
                    # store it for later use
                    menudict[parent] = menu
                    continue
                # already treated
                menu = menudict[parent]

            # last item = layer
            layer = QAction(name, self.uiparent.iface.mainWindow())

            if uri_struct.providerKey in ICON_MAPPER:
                layer.setIcon(QIcon(ICON_MAPPER[uri_struct.providerKey]))

            if uri_struct.providerKey == 'postgres':
                # set tooltip to postgres comment
                comment = self.get_table_comment(uri_struct.uri)
                layer.setStatusTip(comment)
                layer.setToolTip(comment)

            layer.setData(uri_struct.uri)
            layer.setWhatsThis(uri_struct.providerKey)
            layer.triggered.connect(self.layer_handler[uri_struct.layerType])
            menu.addAction(layer)

    def get_table_comment(self, uri):
        schema, table = re.match('.*table=(.*)\(.*',
                                 uri).group(1).strip().replace('"',
                                                               '').split('.')
        with self.transaction():
            cur = self.connection.cursor()
            select = """
                select description from pg_description
                join pg_class on pg_description.objoid = pg_class.oid
                join pg_namespace on pg_class.relnamespace = pg_namespace.oid
                where relname = '{}' and nspname='{}'
                """.format(table, schema)
            cur.execute(select)
            row = cur.fetchone()
            if row:
                return row[0]
        return ''

    def load_from_index(self, index):
        """Load layers from selected item index"""
        item = self.dock_model.itemFromIndex(
            self.proxy_model.mapToSource(index))
        if item.whatsThis() == 'menu':
            return
        if item.data().layerType == 'vector':
            layer = QgsVectorLayer(
                item.data().uri,  # uri
                item.text(),  # layer name
                item.data().providerKey  # provider name
            )
        elif item.data().layerType == 'raster':
            layer = QgsRasterLayer(
                item.data().uri,  # uri
                item.text(),  # layer name
                item.data().providerKey  # provider name
            )
        if not layer:
            return
        QgsMapLayerRegistry.instance().addMapLayer(layer)

    def load_vector(self):
        action = self.sender()
        layer = QgsVectorLayer(
            action.data(),  # uri
            action.text(),  # layer name
            action.whatsThis()  # provider name
        )
        QgsMapLayerRegistry.instance().addMapLayer(layer)

    def load_raster(self):
        action = self.sender()
        layer = QgsRasterLayer(
            action.data(),  # uri
            action.text(),  # layer name
            action.whatsThis()  # provider name
        )
        QgsMapLayerRegistry.instance().addMapLayer(layer)

    def accept(self):
        if self.save_changes():
            QDialog.reject(self)
            self.close_connection()

    def apply(self):
        if self.save_changes(save_to_db=False):
            QDialog.reject(self)

    def reject(self):
        self.close_connection()
        QDialog.reject(self)

    def close_connection(self):
        """close current pg connection if exists"""
        if getattr(self, 'connection', False):
            if self.connection.closed:
                return
            self.connection.close()

    def save_session(self, database, schema, profile, dock, menubar):
        """save current profile for next session"""
        settings = QSettings()
        settings.setValue("MenuBuilder/database", database)
        settings.setValue("MenuBuilder/schema", schema)
        settings.setValue("MenuBuilder/profile", profile)
        settings.setValue("MenuBuilder/dock", dock)
        settings.setValue("MenuBuilder/menubar", menubar)

    def restore_session(self):
        settings = QSettings()
        database = settings.value("MenuBuilder/database", False)
        schema = settings.value("MenuBuilder/schema", 'public')
        profile = settings.value("MenuBuilder/profile", False)
        dock = settings.value("MenuBuilder/dock", False)
        menubar = settings.value("MenuBuilder/menubar", False)
        if not any([database, profile]):
            return

        self.set_connection(0, dbname=database)
        self.show_dock(bool(dock), profile=profile, schema=schema)
        if bool(dock):
            self.uiparent.iface.addDockWidget(Qt.LeftDockWidgetArea,
                                              self.dock_widget)
        self.show_menus(bool(menubar), profile=profile, schema=schema)
예제 #56
0
class MikiWindow(QMainWindow):
    def __init__(self, settings, parent=None):
        super(MikiWindow, self).__init__(parent)
        self.setObjectName("mikiWindow")
        self.settings = settings
        self.notePath = settings.notePath
        lockPath = os.path.join(settings.notebookPath, '.mikidown_lock')
        if not os.path.exists(lockPath):
            self.lockPathFH = os.open(lockPath,
                                      os.O_CREAT | os.O_EXCL | os.O_RDWR)
        ################ Setup core components ################
        self.notesTree = MikiTree(self)
        self.quickNoteNav = QLineEdit()
        self.notesTab = QWidget()
        self.completer = SlashPleter()
        self.completer.setModel(self.notesTree.model())
        self.quickNoteNav.setCompleter(self.completer)
        self.notesTree.setObjectName("notesTree")
        self.initTree(self.notePath, self.notesTree)
        self.notesTree.sortItems(0, Qt.AscendingOrder)

        self.ix = None
        self.setupWhoosh()

        self.viewedList = QToolBar(self.tr('Recently Viewed'), self)
        self.viewedList.setIconSize(QSize(16, 16))
        self.viewedList.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.viewedListActions = []
        self.noteSplitter = QSplitter(Qt.Horizontal)

        self.dockIndex = QDockWidget(self.tr("Index"))
        self.dockSearch = QDockWidget(self.tr("Search"))
        self.searchEdit = QLineEdit()
        self.searchView = MikiSearch(self)
        self.searchTab = QWidget()
        self.dockToc = QDockWidget(self.tr("TOC"))
        self.tocTree = TocTree()
        self.dockAttachment = QDockWidget(self.tr("Attachment"))
        self.attachmentView = AttachmentView(self)

        self.notesEdit = MikiEdit(self)
        self.notesEdit.setObjectName(self.tr("notesEdit"))
        self.loadHighlighter()
        self.notesView = MikiView(self)

        self.findBar = QToolBar(self.tr('Find'), self)
        self.findBar.setFixedHeight(30)
        self.findEdit = QLineEdit(self.findBar)
        self.checkBox = QCheckBox(self.tr('Match case'), self.findBar)

        self.statusBar = QStatusBar(self)
        self.statusLabel = QLabel(self)

        self.altPressed = False

        ################ Setup actions ################
        self.actions = dict()
        self.setupActions()

        ################ Setup mainwindow ################
        self.setupMainWindow()

        # show changelogs after upgrade mikidown
        if self.settings.version < __version__ or Mikibook.settings.value(
                "version", defaultValue="0") < __version__:
            self.changelogHelp()
            self.settings.qsettings.setValue("version", __version__)
            Mikibook.settings.setValue("version", __version__)

    def loadHighlighter(self):
        fnt = Mikibook.settings.value('editorFont', defaultValue=None)
        fntsize = Mikibook.settings.value('editorFontSize',
                                          type=int,
                                          defaultValue=12)
        header_scales_font = Mikibook.settings.value('headerScaleFont',
                                                     type=bool,
                                                     defaultValue=True)
        if fnt is not None:
            self.notesEdit.setFontFamily(fnt)
            self.notesEdit.setFontPointSize(fntsize)
        h = MikiHighlighter(parent=self.notesEdit,
                            scale_font_sizes=header_scales_font)
        tw = Mikibook.settings.value('tabWidth', type=int, defaultValue=4)
        qfm = QFontMetrics(h.patterns[0][1].font())
        self.notesEdit.setTabStopWidth(tw * qfm.width(' '))

    def setupActions(self):

        # Global Actions
        actTabIndex = self.act(self.tr('Switch to Index Tab'),
                               lambda: self.raiseDock(self.dockIndex),
                               self.tr('Ctrl+Shift+I'))
        actTabSearch = self.act(self.tr('Switch to Search Tab'),
                                lambda: self.raiseDock(self.dockSearch),
                                self.tr('Ctrl+Shift+F'))
        self.addAction(actTabIndex)
        self.addAction(actTabSearch)

        ################ Menu Actions ################
        # actions in menuFile
        actionNewPage = self.act(self.tr('&New Page...'),
                                 self.notesTree.newPage, QKeySequence.New)
        self.actions.update(newPage=actionNewPage)

        actionNewSubpage = self.act(self.tr('New Sub&page...'),
                                    self.notesTree.newSubpage,
                                    self.tr('Ctrl+Shift+N'))
        self.actions.update(newSubpage=actionNewSubpage)

        actionImportPage = self.act(self.tr('&Import Page...'),
                                    self.importPage)
        self.actions.update(importPage=actionImportPage)

        actionNBSettings = self.act(self.tr('Notebook Set&tings...'),
                                    self.notebookSettings)
        self.actions.update(NBSettings=actionNBSettings)

        actionMDSettings = self.act(self.tr('&Mikidown Settings...'),
                                    self.mikidownSettings)
        self.actions.update(MDSettings=actionMDSettings)

        actionOpenNotebook = self.act(self.tr('&Open Notebook...'),
                                      self.openNotebook, QKeySequence.Open)
        self.actions.update(openNotebook=actionOpenNotebook)

        actionReIndex = self.act(self.tr('Re-index'), self.reIndex)
        self.actions.update(reIndex=actionReIndex)

        actionSave = self.act(self.tr('&Save'), self.saveCurrentNote,
                              QKeySequence.Save)
        actionSave.setEnabled(False)
        self.actions.update(save=actionSave)

        actionSaveAs = self.act(self.tr('Save &As...'), self.saveNoteAs,
                                QKeySequence.SaveAs)
        self.actions.update(saveAs=actionSaveAs)

        actionHtml = self.act(self.tr('to &HTML'), self.notesEdit.saveAsHtml)
        self.actions.update(html=actionHtml)

        actionPrint = self.act(self.tr('&Print'), self.printNote,
                               QKeySequence.Print)
        self.actions.update(print_=actionPrint)

        actionRenamePage = self.act(self.tr('&Rename Page...'),
                                    self.notesTree.renamePage, 'F2')
        self.actions.update(renamePage=actionRenamePage)

        actionDelPage = self.act(self.tr('&Delete Page'),
                                 self.notesTree.delPageWrapper,
                                 QKeySequence.Delete)
        self.actions.update(delPage=actionDelPage)

        actionQuit = self.act(self.tr('&Quit'), self.close, QKeySequence.Quit)
        actionQuit.setMenuRole(QAction.QuitRole)
        self.actions.update(quit=actionQuit)

        # actions in menuEdit
        actionUndo = self.act(self.tr('&Undo'), lambda: self.notesEdit.undo(),
                              QKeySequence.Undo)
        actionUndo.setEnabled(False)
        self.notesEdit.undoAvailable.connect(actionUndo.setEnabled)
        self.actions.update(undo=actionUndo)

        actionRedo = self.act(self.tr('&Redo'), lambda: self.notesEdit.redo(),
                              QKeySequence.Redo)
        actionRedo.setEnabled(False)
        self.notesEdit.redoAvailable.connect(actionRedo.setEnabled)
        self.actions.update(redo=actionRedo)

        actionFindText = self.act(self.tr('&Find Text'),
                                  self.findBar.setVisible, QKeySequence.Find,
                                  True)
        self.actions.update(findText=actionFindText)

        actionFindRepl = self.act(self.tr('Find and Replace'),
                                  FindReplaceDialog(self.notesEdit).open,
                                  QKeySequence.Replace)
        self.actions.update(findRepl=actionFindRepl)

        actionFind = self.act(self.tr('Next'), self.findText,
                              QKeySequence.FindNext)
        self.actions.update(find=actionFind)

        actionFindPrev = self.act(self.tr('Previous'),
                                  lambda: self.findText(back=True),
                                  QKeySequence.FindPrevious)
        self.actions.update(findPrev=actionFindPrev)

        actionSortLines = self.act(self.tr('&Sort Lines'), self.sortLines)
        self.actions.update(sortLines=actionSortLines)

        actionQuickNav = self.act(self.tr("&Quick Open Note"),
                                  self.quickNoteNav.setFocus,
                                  self.tr('Ctrl+G'))
        self.addAction(actionQuickNav)

        actionInsertImage = self.act(self.tr('&Insert Attachment'),
                                     self.notesEdit.insertAttachmentWrapper,
                                     self.tr('Ctrl+I'))
        actionInsertImage.setEnabled(False)
        self.actions.update(insertImage=actionInsertImage)

        # actions in menuView
        QIcon.setThemeName(
            Mikibook.settings.value('iconTheme', QIcon.themeName()))
        #print(QIcon.themeName())
        actionEdit = self.act(self.tr('Edit'), self.edit, self.tr('Ctrl+E'),
                              True, QIcon.fromTheme('document-edit'),
                              self.tr('Edit mode (Ctrl+E)'))
        self.actions.update(edit=actionEdit)

        actionSplit = self.act(self.tr('Split'), self.liveView,
                               self.tr('Ctrl+R'), True,
                               QIcon.fromTheme('view-split-left-right'),
                               self.tr('Split mode (Ctrl+R)'))
        self.actions.update(split=actionSplit)

        actionFlipEditAndView = self.act(self.tr('Flip Edit and View'),
                                         self.flipEditAndView)
        actionFlipEditAndView.setEnabled(False)
        self.actions.update(flipEditAndView=actionFlipEditAndView)

        #actionLeftAndRight = self.act(
        #    self.tr('Split into Left and Right'), trig=self.leftAndRight)
        #actionUpAndDown = self.act(
        #    self.tr('Split into Up and Down'), trig=self.upAndDown)
        # self.actionLeftAndRight.setEnabled(False)
        # self.actionUpAndDown.setEnabled(False)

        # actions in menuHelp
        actionReadme = self.act(self.tr('README'), self.readmeHelp)
        self.actions.update(readme=actionReadme)

        actionChangelog = self.act(self.tr('Changelog'), self.changelogHelp)
        self.actions.update(changelog=actionChangelog)

        actionAboutQt = self.act(self.tr('About Qt'), qApp.aboutQt)
        self.actions.update(aboutQt=actionAboutQt)

    def setupMainWindow(self):
        self.resize(800, 600)
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width() - size.width()) / 2,
                  (screen.height() - size.height()) / 2)
        self.setWindowTitle('{} - {}'.format(self.settings.notebookName,
                                             __appname__))

        self.viewedList.setFixedHeight(25)
        self.noteSplitter.addWidget(self.notesEdit)
        self.noteSplitter.addWidget(self.notesView)
        mainSplitter = QSplitter(Qt.Vertical)
        mainSplitter.setChildrenCollapsible(False)
        mainSplitter.addWidget(self.viewedList)
        mainSplitter.addWidget(self.noteSplitter)
        mainSplitter.addWidget(self.findBar)
        self.setCentralWidget(mainSplitter)

        self.searchEdit.returnPressed.connect(self.searchNote)
        self.quickNoteNav.returnPressed.connect(self.openFuncWrapper)
        searchLayout = QVBoxLayout()
        searchLayout.addWidget(self.searchEdit)
        searchLayout.addWidget(self.searchView)
        self.searchTab.setLayout(searchLayout)

        indexLayout = QVBoxLayout(self.notesTab)
        indexLayout.addWidget(self.quickNoteNav)
        indexLayout.addWidget(self.notesTree)

        self.dockIndex.setObjectName("Index")
        self.dockIndex.setWidget(self.notesTab)
        self.dockSearch.setObjectName("Search")
        self.dockSearch.setWidget(self.searchTab)
        self.dockToc.setObjectName("TOC")
        self.dockToc.setWidget(self.tocTree)
        self.dockAttachment.setObjectName("Attachment")
        self.dockAttachment.setWidget(self.attachmentView)

        self.setDockOptions(QMainWindow.VerticalTabs)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockIndex)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockSearch)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockToc)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dockAttachment)
        self.tabifyDockWidget(self.dockIndex, self.dockSearch)
        self.tabifyDockWidget(self.dockSearch, self.dockToc)
        self.tabifyDockWidget(self.dockToc, self.dockAttachment)
        self.setTabPosition(Qt.LeftDockWidgetArea, QTabWidget.North)
        self.dockIndex.raise_()  # Put dockIndex on top of the tab stack

        menuBar = QMenuBar(self)
        self.setMenuBar(menuBar)
        menuFile = menuBar.addMenu(self.tr('&File'))
        menuEdit = menuBar.addMenu(self.tr('&Edit'))
        menuView = menuBar.addMenu(self.tr('&View'))
        menuHelp = menuBar.addMenu(self.tr('&Help'))
        # menuFile
        menuFile.addAction(self.actions['newPage'])
        menuFile.addAction(self.actions['newSubpage'])
        menuFile.addAction(self.actions['NBSettings'])
        menuFile.addAction(self.actions['MDSettings'])
        menuFile.addAction(self.actions['importPage'])
        menuFile.addAction(self.actions['openNotebook'])
        menuFile.addAction(self.actions['reIndex'])
        menuFile.addSeparator()
        menuFile.addAction(self.actions['save'])
        menuFile.addAction(self.actions['saveAs'])
        menuFile.addAction(self.actions['print_'])
        menuExport = menuFile.addMenu(self.tr('&Export'))
        menuExport.addAction(self.actions['html'])
        menuFile.addSeparator()
        menuFile.addAction(self.actions['renamePage'])
        menuFile.addAction(self.actions['delPage'])
        menuFile.addSeparator()
        menuFile.addAction(self.actions['quit'])
        # menuEdit
        menuEdit.addAction(self.actions['undo'])
        menuEdit.addAction(self.actions['redo'])
        menuEdit.addAction(self.actions['findText'])
        menuEdit.addAction(self.actions['findRepl'])
        menuEdit.addSeparator()
        menuEdit.addAction(self.actions['sortLines'])
        menuEdit.addAction(self.actions['insertImage'])
        # menuView
        menuView.addAction(self.actions['edit'])
        menuView.addAction(self.actions['split'])
        menuView.addAction(self.actions['flipEditAndView'])
        menuShowHide = menuView.addMenu(self.tr('Show/Hide'))
        menuShowHide.addAction(self.dockIndex.toggleViewAction())
        menuShowHide.addAction(self.dockSearch.toggleViewAction())
        menuShowHide.addAction(self.dockToc.toggleViewAction())
        menuShowHide.addAction(self.dockAttachment.toggleViewAction())
        #menuMode = menuView.addMenu(self.tr('Mode'))
        #menuMode.addAction(self.actionLeftAndRight)
        #menuMode.addAction(self.actionUpAndDown)
        # menuHelp
        menuHelp.addAction(self.actions['readme'])
        menuHelp.addAction(self.actions['changelog'])
        menuHelp.addAction(self.actions['aboutQt'])

        toolBar = QToolBar(self.tr("toolbar"), self)
        toolBar.setObjectName("toolbar")  # needed in saveState()
        #toolBar.setIconSize(QSize(16, 16))
        toolBar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
        self.addToolBar(Qt.TopToolBarArea, toolBar)
        toolBar.addAction(self.actions['edit'])
        toolBar.addAction(self.actions['split'])
        self.findEdit.returnPressed.connect(self.findText)
        self.findBar.addWidget(self.findEdit)
        self.findBar.addWidget(self.checkBox)
        self.findBar.addAction(self.actions['findPrev'])
        self.findBar.addAction(self.actions['find'])
        self.findBar.setVisible(False)
        self.findBar.visibilityChanged.connect(self.findBarVisibilityChanged)

        self.setStatusBar(self.statusBar)
        self.statusBar.addWidget(self.statusLabel, 1)

        self.notesTree.currentItemChanged.connect(
            self.currentItemChangedWrapper)
        self.notesTree.nvwCallback = self.newNoteDisplay
        self.notesTree.nvwtCallback = self.newPlainTextNoteDisplay
        self.tocTree.itemClicked.connect(self.tocNavigate)
        self.notesEdit.textChanged.connect(self.noteEditted)

        self.notesEdit.document().modificationChanged.connect(
            self.modificationChanged)

        self.updateRecentViewedNotes()
        notes = self.settings.recentViewedNotes()
        if len(notes) != 0:
            item = self.notesTree.pageToItem(notes[0])
            self.notesTree.setCurrentItem(item)

    def newNoteDisplay(self, item, anchor=None):
        msn = MikiSepNote(self.settings,
                          item.text(0),
                          self.notesTree.itemToFile(item),
                          plain_text=False,
                          parent=self)
        if anchor:
            msn.note_view.page().mainFrame().scrollToAnchor(anchor)
        msn.show()

    def newPlainTextNoteDisplay(self, item, anchor=None):
        msn = MikiSepNote(self.settings,
                          item.text(0),
                          self.notesTree.itemToFile(item),
                          plain_text=True,
                          parent=self)
        if anchor:
            item = msn.findItemByAnchor(anchor)[0]
            msn.tocNavigate(item)
        msn.show()

    def openFuncWrapper(self):
        self.openFunction(self.quickNoteNav.text())()

    def setupWhoosh(self):
        # Initialize whoosh index, make sure notePath/.indexdir exists
        indexdir = self.settings.indexdir
        try:
            self.ix = open_dir(indexdir)
        except:
            QDir().mkpath(indexdir)
            self.ix = create_in(indexdir, self.settings.schema)
            # Fork a process to update index, which benefit responsiveness.
            p = Thread(target=self.whoosh_index, args=())
            p.start()

    def restore(self):
        """ Restore saved geometry and state.
            Set the status of side panels in View Menu correspondently.
        """
        if self.settings.geometry:
            self.restoreGeometry(self.settings.geometry)
        if self.settings.windowstate:
            self.restoreState(self.settings.windowstate)

    def initTree(self, notePath, parent):
        ''' When there exist foo.md, foo.mkd, foo.markdown,
            only one item will be shown in notesTree.
        '''
        if not QDir(notePath).exists():
            return
        notebookDir = QDir(notePath)
        notesList = notebookDir.entryInfoList(['*.md', '*.mkd', '*.markdown'],
                                              QDir.NoFilter,
                                              QDir.Name | QDir.IgnoreCase)
        nl = [note.completeBaseName() for note in notesList]
        noduplicate = list(set(nl))
        for name in noduplicate:
            item = QTreeWidgetItem(parent, [name])
            path = notePath + '/' + name
            self.initTree(path, item)

    def updateToc(self):
        ''' TOC is updated in `updateView`
            tocTree fields: [hdrText, hdrPosition, hdrAnchor]
        '''
        root = self.notesTree.currentPage()
        strip_math_for_header_parsing = False
        strip_fence_for_header_parsing = False
        if 'asciimathml' in self.settings.extensions:
            strip_math_for_header_parsing = True
        if 'fenced_code' in self.settings.extensions or 'extra' in self.settings.extensions:
            strip_fence_for_header_parsing = True
        self.tocTree.updateToc(
            root,
            parseHeaders(self.notesEdit.toPlainText(),
                         strip_fenced_block=strip_fence_for_header_parsing,
                         strip_ascii_math=strip_math_for_header_parsing))

    def updateAttachmentView(self):
        # Update attachmentView to show corresponding attachments.
        item = self.notesTree.currentItem()
        index = self.attachmentView.model.index(
            self.notesTree.itemToAttachmentDir(item))
        self.attachmentView.setRootIndex(index)

    def openFile(self, filename):
        fh = QFile(filename)
        try:
            if not fh.open(QIODevice.ReadOnly):
                raise IOError(fh.errorString())
        except IOError as e:
            QMessageBox.warning(
                self, self.tr('Read Error'),
                self.tr('Failed to open %s: %s') % (filename, e))
        finally:
            if fh is not None:
                noteBody = QTextStream(fh).readAll()
                fh.close()
                self.notesEdit.setPlainText(noteBody)
                self.notesView.scrollPosition = QPoint(0, 0)
                # self.actionSave.setEnabled(False)
                self.notesEdit.document().setModified(False)
                self.notesView.updateView()
                self.setCurrentNote()
                self.updateRecentViewedNotes()
                #self.statusLabel.setText(noteFullName)

    def currentItemChangedWrapper(self, current, previous):
        if current is None:
            return
        #if previous != None and self.notesTree.pageExists(previous):
        prev = self.notesTree.itemToPage(previous)
        if self.notesTree.pageExists(prev):
            self.saveNote(previous)

        currentFile = self.notesTree.itemToFile(current)
        self.openFile(currentFile)

        # Update attachmentView to show corresponding attachments.
        index = self.attachmentView.model.index(
            self.notesTree.itemToAttachmentDir(current))
        self.attachmentView.setRootIndex(index)

    def tocNavigate(self, current):
        ''' works for notesEdit now '''
        if current is None:
            return
        pos = int(current.text(1))
        link = "file://" + self.notePath + "/#" + current.text(2)
        # Move cursor to END first will ensure
        # header is positioned at the top of visual area.
        self.notesEdit.moveCursor(QTextCursor.End)
        cur = self.notesEdit.textCursor()
        cur.setPosition(pos, QTextCursor.MoveAnchor)
        self.notesEdit.setTextCursor(cur)
        self.notesView.load(QUrl(link))

    def switchNote(self, num):
        if num < len(self.viewedListActions):
            self.viewedListActions[num].trigger()

    def saveCurrentNote(self):
        item = self.notesTree.currentItem()
        self.saveNote(item)

    def saveNote(self, item):
        if self.notesEdit.document().isModified():
            self.notesEdit.document().setModified(False)
        else:
            return
        self.notesEdit.save(item)

    def saveNoteAs(self):
        self.saveCurrentNote()
        fileName = QFileDialog.getSaveFileName(
            self, self.tr('Save as'), '',
            '(*.md *.mkd *.markdown);;' + self.tr('All files(*)'))
        if fileName == '':
            return
        if not QFileInfo(fileName).suffix():
            fileName += '.md'
        fh = QFile(fileName)
        fh.open(QIODevice.WriteOnly)
        savestream = QTextStream(fh)
        savestream << self.notesEdit.toPlainText()
        fh.close()

    def printNote(self):
        printer = QPrinter(QPrinter.HighResolution)
        printer.setCreator(__appname__ + ' ' + __version__)
        printer.setDocName(self.notesTree.currentItem().text(0))
        printdialog = QPrintDialog(printer, self)
        if printdialog.exec() == QDialog.Accepted:
            self.notesView.print_(printer)

    def noteEditted(self):
        """ Continuously get fired while editing"""
        self.updateToc()
        self.notesView.updateLiveView()

    def modificationChanged(self, changed):
        """ Fired one time: modified or not """
        self.actions['save'].setEnabled(changed)
        name = self.notesTree.currentPage()
        self.statusBar.clearMessage()
        if changed:
            self.statusLabel.setText(name + '*')
        else:
            self.statusLabel.setText(name)

    def importPage(self):
        filename = QFileDialog.getOpenFileName(
            self, self.tr('Import file'), '',
            '(*.md *.mkd *.markdown *.txt);;' + self.tr('All files(*)'))
        if filename == '':
            return
        self.importPageCore(filename)

    def importPageCore(self, filename):
        fh = QFile(filename)
        fh.open(QIODevice.ReadOnly)
        fileBody = QTextStream(fh).readAll()
        fh.close()
        page = QFileInfo(filename).completeBaseName()
        fh = QFile(self.notesTree.pageToFile(page))
        if fh.exists():
            QMessageBox.warning(self, self.tr("Import Error"),
                                self.tr("Page already exists: %s") % page)
            dialog = LineEditDialog(self.notePath, self)
            if dialog.exec_():
                page = dialog.editor.text()
                fh.close()
                fh = QFile(self.notesTree.pageToFile(page))
            else:
                return
        fh.open(QIODevice.WriteOnly)
        savestream = QTextStream(fh)
        savestream << fileBody
        fh.close()
        item = QTreeWidgetItem(self.notesTree, [page])
        self.notesTree.sortItems(0, Qt.AscendingOrder)
        self.notesTree.setCurrentItem(item)

    def openNotebook(self):
        dialog = NotebookListDialog(self)
        if dialog.exec_():
            pass

    def notebookSettings(self):
        dialog = NotebookSettingsDialog(self)
        if dialog.exec_():
            pass

    def mikidownSettings(self):
        dialog = MikidownCfgDialog(self)
        if dialog.exec_():
            pass

    def reIndex(self):
        """ Whoosh index breaks for unknown reasons (sometimes) """
        shutil.rmtree(self.settings.indexdir)
        self.setupWhoosh()

    def act(self,
            name,
            trig,
            shortcut=None,
            checkable=False,
            icon=None,
            tooltip=None):
        """ A wrapper to several QAction methods """
        if icon:
            action = QAction(icon, name, self)
        else:
            action = QAction(name, self)
        if shortcut:
            action.setShortcut(QKeySequence(shortcut))
        action.setCheckable(checkable)
        if tooltip:
            action.setToolTip(tooltip)
        action.triggered.connect(trig)
        return action

    def edit(self, viewmode):
        """ Switch between EDIT and VIEW mode. """

        if self.actions['split'].isChecked():
            self.actions['split'].setChecked(False)
        self.notesView.setVisible(not viewmode)
        self.notesEdit.setVisible(viewmode)

        # Gives the keyboard input focus to notesEdit/notesView.
        # Without this, keyboard input may change note text even when
        # notesEdit is invisible.
        if viewmode:
            self.notesEdit.setFocus()
        else:
            self.notesView.setFocus()

        self.saveCurrentNote()
        self.actions['insertImage'].setEnabled(viewmode)
        #self.actionLeftAndRight.setEnabled(True)
        #self.actionUpAndDown.setEnabled(True)

        # Render the note text as it is.
        self.notesView.updateView()

    def liveView(self, viewmode):
        """ Switch between VIEW and LIVE VIEW mode. """

        self.actions['split'].setChecked(viewmode)
        sizes = self.noteSplitter.sizes()
        if self.actions['edit'].isChecked():
            self.actions['edit'].setChecked(False)
            self.notesView.setVisible(viewmode)
            splitSize = [sizes[0] * 0.45, sizes[0] * 0.55]
        else:
            self.notesEdit.setVisible(viewmode)
            splitSize = [sizes[1] * 0.45, sizes[1] * 0.55]

        # setFocus for the same reason as in edit(self, viewmode)
        if viewmode:
            self.notesEdit.setFocus()
        else:
            self.notesView.setFocus()

        self.actions['flipEditAndView'].setEnabled(viewmode)
        #self.actionUpAndDown.setEnabled(viewmode)
        self.actions['insertImage'].setEnabled(viewmode)
        self.noteSplitter.setSizes(splitSize)
        self.saveCurrentNote()

        # Render the note text as it is.
        self.notesView.updateView()

    def findBarVisibilityChanged(self, visible):
        self.actions['findText'].setChecked(visible)
        if visible:
            self.findEdit.setFocus(Qt.ShortcutFocusReason)

    def findText(self, back=False):
        flags = 0
        if back:
            flags = QTextDocument.FindBackward
        if self.checkBox.isChecked():
            flags = flags | QTextDocument.FindCaseSensitively
        text = self.findEdit.text()
        if not self.findMain(text, flags):
            if text in self.notesEdit.toPlainText():
                cursor = self.notesEdit.textCursor()
                if back:
                    cursor.movePosition(QTextCursor.End)
                else:
                    cursor.movePosition(QTextCursor.Start)
                self.notesEdit.setTextCursor(cursor)
                self.findMain(text, flags)
        # self.notesView.findText(text, flags)

    def findMain(self, text, flags):
        viewFlags = QWebPage.FindFlags(
            flags) | QWebPage.FindWrapsAroundDocument
        if flags:
            self.notesView.findText(text, viewFlags)
            return self.notesEdit.find(text, flags)
        else:
            self.notesView.findText(text)
            return self.notesEdit.find(text)

    def sortLines(self):
        ''' sort selected lines
            TODO: second sort reverse the order
        '''
        cursor = self.notesEdit.textCursor()
        start = cursor.selectionStart()
        end = cursor.selectionEnd()
        cursor.setPosition(start)
        cursor.movePosition(QTextCursor.StartOfLine)
        cursor.setPosition(end, mode=QTextCursor.KeepAnchor)
        cursor.movePosition(QTextCursor.EndOfLine, mode=QTextCursor.KeepAnchor)
        text = cursor.selectedText()
        lines = text.split('\u2029')  # '\u2029' is the line break
        sortedLines = sorted(lines)
        cursor.insertText('\n'.join(sortedLines))

    def notesEditInFocus(self, e):
        if e.gotFocus:
            self.actions['insertImage'].setEnabled(True)
        # if e.lostFocus:
        #    self.actionInsertImage.setEnabled(False)

        # QWidget.focusInEvent(self,f)

    def searchNote(self):
        """ Sorting criteria: "title > path > content"
            Search matches are organized into html source.
        """

        pattern = self.searchEdit.text()
        if not pattern:
            return
        results = []
        print("Searching using", pattern)
        with self.ix.searcher() as searcher:
            matches = []
            queryp = QueryParser("content", self.ix.schema)
            #allow escaped qutoes when regex searching
            queryp.add_plugin(
                RegexPlugin(expr=r'r"(?P<text>[^"\\]*(\\.[^"\\]*)*)"'))
            # ~~r"pattern" is the desired regex term format~~ Don't autoforce regexing
            query = queryp.parse(pattern)
            #print("durp durp", query)
            ms = searcher.search(query, limit=None)  # default limit is 10!
            for m in ms:
                #if not m in matches:
                matches.append(m)

            for r in matches:
                title = r['title']
                path = r['path']
                term = r.highlights("content")
                results.append([title, path, term])

            html = ""
            for title, path, hi in results:
                html += ("<p><a href='" + path + "'>" + title +
                         "</a><br/><span class='path'>" + path +
                         "</span><br/>" + hi + "</p>")
            self.searchView.setHtml(html)
            print("Finished searching", pattern)

    def whoosh_index(self):
        it = QTreeWidgetItemIterator(self.notesTree,
                                     QTreeWidgetItemIterator.All)
        print("Starting complete indexing.")
        #writer = self.ix.writer()
        writer = AsyncWriter(self.ix)
        while it.value():
            treeItem = it.value()
            name = self.notesTree.itemToPage(treeItem)
            path = os.path.join(self.notesTree.pageToFile(name)).replace(
                os.sep, '/')
            print(path)
            fileobj = open(path, 'r', encoding='utf-8')
            content = fileobj.read()
            fileobj.close()
            if METADATA_CHECKER.match(
                    content) and 'meta' in self.settings.extensions:
                no_metadata_content = METADATA_CHECKER.sub("",
                                                           content,
                                                           count=1).lstrip()
                self.settings.md.reset().convert(content)
                writer.update_document(
                    path=name,
                    title=parseTitle(content, name),
                    content=no_metadata_content,
                    tags=','.join(self.settings.md.Meta.get('tags',
                                                            [])).strip())
            else:
                writer.add_document(path=name,
                                    title=parseTitle(content, name),
                                    content=content,
                                    tags='')

            it += 1
        writer.commit()
        print("Finished completely reindexing.")

    def listItemChanged(self, row):
        if row != -1:
            item = self.searchList.currentItem().data(Qt.UserRole)
            self.notesTree.setCurrentItem(item)
            flags = QWebPage.HighlightAllOccurrences
            self.notesView.findText(self.searchEdit.text(), flags)

    def setCurrentNote(self):
        item = self.notesTree.currentItem()
        name = self.notesTree.itemToPage(item)

        # Current note is inserted to head of list.
        notes = self.settings.recentViewedNotes()
        for f in notes:
            if f == name:
                notes.remove(f)
        notes.insert(0, name)

        recent_notes_n = Mikibook.settings.value('recentNotesNumber',
                                                 type=int,
                                                 defaultValue=20)
        if len(notes) > recent_notes_n:
            del notes[recent_notes_n:]
        self.settings.updateRecentViewedNotes(notes)

    def updateRecentViewedNotes(self):
        """ Switching notes will trigger this.
            When Alt pressed, show note number.
        """

        self.viewedList.clear()
        self.viewedListActions = []

        # Check notes exists.
        viewedNotes = self.settings.recentViewedNotes()
        existedNotes = []
        i = 0
        for f in viewedNotes:
            if self.notesTree.pageExists(f):
                existedNotes.append(f)
                names = f.split('/')
                if self.altPressed and i in range(1, 10):
                    action = self.act(names[-1], self.openFunction(f),
                                      'Alt+' + str(i), True, ViewedNoteIcon(i),
                                      'Alt+' + str(i))
                else:
                    action = self.act(names[-1], self.openFunction(f), None,
                                      True)
                self.viewedListActions.append(action)
                i += 1

        if not self.altPressed:
            self.settings.updateRecentViewedNotes(existedNotes)
        for action in self.viewedListActions:
            self.viewedList.addAction(action)
        if len(self.viewedListActions):
            self.viewedListActions[0].setChecked(True)

    def openFunction(self, name):
        item = self.notesTree.pageToItem(name)
        return lambda: self.notesTree.setCurrentItem(item)

    def raiseDock(self, widget):
        if not widget.isVisible():
            widget.show()
        if widget == self.dockSearch:
            self.searchEdit.setFocus()
        widget.raise_()

    def flipEditAndView(self):
        index = self.noteSplitter.indexOf(self.notesEdit)
        if index == 0:
            self.noteSplitter.insertWidget(1, self.notesEdit)
        else:
            self.noteSplitter.insertWidget(0, self.notesEdit)

    def leftAndRight(self):
        self.liveView(True)
        self.noteSplitter.setOrientation(Qt.Horizontal)
        #self.actionLeftAndRight.setEnabled(False)
        #self.actionUpAndDown.setEnabled(True)

    def upAndDown(self):
        self.liveView(True)
        self.noteSplitter.setOrientation(Qt.Vertical)
        #self.actionUpAndDown.setEnabled(False)
        #self.actionLeftAndRight.setEnabled(True)

    def readmeHelp(self):
        readmeFile = '/usr/share/mikidown/README.mkd'
        if not os.path.exists(readmeFile):
            readmeFile = os.path.join(
                os.path.dirname(os.path.dirname(__file__)),
                'README.mkd').replace(os.sep, '/')
        self.importPageCore(readmeFile)

    def changelogHelp(self):
        changeLog = "/usr/share/mikidown/Changelog.md"
        if not os.path.exists(changeLog):
            changeLog = os.path.join(
                os.path.dirname(os.path.dirname(__file__)),
                'Changelog.md').replace(os.sep, '/')
        self.importPageCore(changeLog)

    def keyPressEvent(self, event):
        """ When Alt pressed, note number will be shown in viewedList. """
        if event.key() == Qt.Key_Alt:
            self.altPressed = True
            self.updateRecentViewedNotes()
        else:
            QMainWindow.keyPressEvent(self, event)

    def keyReleaseEvent(self, event):
        if event.key() == Qt.Key_Alt:
            self.altPressed = False
            self.updateRecentViewedNotes()
        else:
            QMainWindow.keyPressEvent(self, event)

    def closeEvent(self, event):
        """
            saveGeometry: Saves the current geometry and state for
                          top-level widgets
            saveState: Restores the state of this mainwindow's toolbars
                       and dockwidgets
        """
        self.saveCurrentNote()
        self.ix.close()
        self.notesEdit.ix.close()
        if hasattr(self.notesTree, 'ix'):
            self.notesTree.ix.close()
        self.settings.saveGeometry(self.saveGeometry())
        self.settings.saveWindowState(self.saveState())
        event.accept()
        os.close(self.lockPathFH)
        lockPath = os.path.join(self.settings.notebookPath, '.mikidown_lock')
        os.remove(lockPath)
예제 #57
0
class Main(plugin.Plugin):
    " dock Class "

    def initialize(self):
        " Init Class dock "
        self.dock = QDockWidget()
        self.dock.setFeatures(QDockWidget.DockWidgetFloatable
                              | QDockWidget.DockWidgetMovable)
        self.dock.setWindowTitle(__doc__)
        self.dock.setStyleSheet('QDockWidget::title{text-align: center;}')
        self.open = QAction(QIcon.fromTheme("document-open"), 'Open DIFF',
                            self)
        self.diff = QAction(QIcon.fromTheme("document-new"), 'Make DIFF', self)
        self.diff.triggered.connect(self.run_gui_and_get_results)
        self.save = QAction(QIcon.fromTheme("document-save"), 'Save DIFF',
                            self)
        self.save.triggered.connect(self.save_a_diff)
        self.patc = QAction(QIcon.fromTheme("document-edit"), 'PATCH it!',
                            self)
        self.patc.triggered.connect(lambda: QMessageBox.information(
            self.dock, __doc__,
            ' Sorry. This Feature is not ready yet !, thank you... '))
        QToolBar(self.dock).addActions(
            (self.open, self.diff, self.save, self.patc))
        try:
            self.factory = KPluginLoader("komparepart").factory()
            self.part = self.factory.create(self)
            self.dock.setWidget(self.part.widget())
            self.open.triggered.connect(lambda: self.part.openUrl(
                KUrl(
                    str(
                        QFileDialog.getOpenFileName(
                            self.dock, ' Open a DIFF file ',
                            path.expanduser("~"), ';;(*.diff)')))))
        except:
            self.dock.setWidget(
                QLabel(""" <center>
            <h3>ಠ_ಠ<br> ERROR: Please, install Kompare App ! </h3><br>
            <br><i> (Sorry, cant embed non-Qt Apps). </i><center>"""))

        self.misc = self.locator.get_service('misc')
        self.misc.add_widget(self.dock, QIcon.fromTheme("edit-select-all"),
                             __doc__)

    def run_gui_and_get_results(self):
        ' run_gui_and_get_results '
        gui = Diff_GUI()
        if gui.diff_path is not None and path.isfile(gui.diff_path) is True:
            self.part.openUrl(KUrl(str(gui.diff_path)))
        return run_gui.diff_path

    def save_a_diff(self):
        ' save a diff '
        out_file = path.abspath(
            str(
                QFileDialog.getSaveFileName(self.dock, 'Save a Diff file',
                                            path.expanduser("~"),
                                            ';;(*.diff)')))
        inp_file = file(
            str(QUrl(self.part.url()).toString()).replace('file://', ''),
            'r').read()
        end_file = file(out_file, 'w')
        end_file.write(inp_file)
        end_file.close()
예제 #58
0
파일: xeb.py 프로젝트: GDYendell/iocbuilder
class GUI(QMainWindow):
    def __init__(self, debug=False):
        QMainWindow.__init__(self)
        # initialise filename
        self.filename = None
        # make the data store
        from xmlstore import Store
        self.store = Store(debug=debug)
        # view the current table
        self.tableView = TableView(self)
        #self.tableView.setDragEnabled(True);
        #self.tableView.setDragDropMode(QAbstractItemView.InternalMove)
        #self.tableView.setAcceptDrops(True);
        #self.tableView.setDropIndicatorShown(True);
        self.tableView.verticalHeader().sectionMoved.connect(self.sectionMoved)
        self.tableView.verticalHeader().setMovable(True)

        self.setCentralWidget(self.tableView)
        # add a custom delegate to it
        self.delegate = ComboBoxDelegate()
        self.tableView.setItemDelegate(self.delegate)
        # dock the table selection on the left
        self.dock1 = QDockWidget(self)
        self.listView = ListView(self)
        self.listView.setDragEnabled(True)
        self.listView.setDragDropMode(QAbstractItemView.InternalMove)
        self.listView.setDropIndicatorShown(True)
        self.dock1.setWidget(self.listView)
        self.dock1.setFeatures(QDockWidget.DockWidgetFloatable
                               | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dock1)
        # connect it to the populate method
        self.connect(self.listView,
                     SIGNAL('activated ( const QModelIndex & )'),
                     self.populate)
        self.connect(self.listView, SIGNAL('clicked ( const QModelIndex & )'),
                     self.populate)
        # dock the undoView on the left
        self.dock2 = QDockWidget(self)
        self.undoView = QUndoView(self.store.stack)
        self.dock2.setWidget(self.undoView)
        self.dock2.setFeatures(QDockWidget.DockWidgetFloatable
                               | QDockWidget.DockWidgetMovable)
        self.dock2.setWindowTitle('Undo Stack')
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dock2)
        # create a menubar
        self.menu = self.menuBar()
        # create file menu headings
        self.menuFile = self.menu.addMenu('File')
        self.menuFile.addAction('New', self.New).setShortcut('CTRL+N')
        self.menuFile.addAction('Open...', self.Open).setShortcut('CTRL+O')
        self.menuFile.addAction('Reload', self.Reload)
        self.menuFile.addAction('Save', self.Save).setShortcut('CTRL+S')
        self.menuFile.addAction('Save As...', self.SaveAs)
        self.menuFile.addSeparator()
        self.menuFile.addAction('Set Architecture...', self.setArch)
        self.menuFile.addSeparator()
        self.menuFile.addAction('Quit', self.closeEvent).setShortcuts(
            ['CTRL+Q', 'ALT+F4'])
        # create edit menu headings
        self.menuEdit = self.menu.addMenu('Edit')
        self.menuEdit.addAction('Insert Row',
                                self.tableView.insertRow).setShortcut('CTRL+I')
        self.menuEdit.addAction(
            'Insert Row Under',
            self.tableView.insertRowUnder).setShortcut('CTRL+U')
        self.menuEdit.addAction('Remove Row', self.tableView.removeRow)
        self.menuEdit.addSeparator()
        self.menuEdit.addAction('Cut',
                                self.tableView.cut).setShortcut('CTRL+X')
        self.menuEdit.addAction('Copy', self.tableView.copy).setShortcuts(
            ['CTRL+C', 'CTRL+INS'])
        self.menuEdit.addAction('Paste', self.tableView.paste).setShortcuts(
            ['CTRL+V', 'SHIFT+INS'])
        self.menuEdit.addAction('Clear',
                                self.tableView.menuClear).setShortcut('CTRL+D')
        self.menuEdit.addSeparator()
        self.menuEdit.addAction('Fill Cells',
                                self.tableView.fillCells).setShortcut('CTRL+L')
        self.menuEdit.addAction(
            'Fill Cells and Increment',
            self.tableView.fillCellsInc).setShortcut('CTRL+R')
        self.menuEdit.addAction(
            'Python Code...', self.tableView.pythonCode).setShortcut('CTRL+P')
        self.tableView.codeBox = pythonCode()
        self.menuEdit.addSeparator()
        self.menuEdit.addAction('Undo', self.store.stack,
                                SLOT('undo()')).setShortcut('CTRL+Z')
        self.menuEdit.addAction('Redo', self.store.stack,
                                SLOT('redo()')).setShortcut('CTRL+SHIFT+Z')
        # create component menu
        self.menuComponents = self.menu.addMenu('Components')
        self.resize(QSize(1000, 500))

    def Save(self):
        # save menu command
        self.SaveAs(self.filename)

    def setArch(self):
        arch = self.store.getArch()
        arch, ok = QInputDialog.getText(self, 'Architecture Dialog',
                                        'Enter Architecture', QLineEdit.Normal,
                                        arch)
        arch = str(arch)
        if ok:
            self.store.setArch(arch)

    def SaveAs(self, filename=''):
        # save as menu command
        if filename == '':
            filename = str(QFileDialog.getSaveFileName())
        if filename != '':
            self.filename = filename
            self.store.Save(filename)
            self._setClean()

    def Reload(self):
        if self.filename is not None:
            self.Open(self.filename, name=self.tablename)

    def Open(self, filename='', name=None):
        # make sure the user is sure if there are unsaved changes
        if self.__prompt_unsaved() == QMessageBox.Cancel:
            return
        # ask for a filename
        if filename == '':
            filename = str(
                QFileDialog.getOpenFileName(
                    filter="Xml Files (*.xml);;All files (*.*)"))
        if filename == '':
            return
        # store the filename
        self.filename = filename
        # tell the store to open a new set of tables
        try:
            problems, warnings = self.store.Open(filename)
            if problems:
                errorstr = 'Can\'t load all object types: ' + ', '.join(
                    problems)
                QMessageBox.warning(self, 'Open Error', errorstr)
            if warnings:
                errorstr = \
                    'The following warnings were generated:\n' + \
                    '\n'.join(warnings)
                QMessageBox.warning(self, 'Open Warnings', errorstr)
        except Exception, e:
            x = formLog(
                'An error ocurred. Make sure all the modules listed '
                'in RELEASE files are built. Check the text below for '
                'details:\n\n' + traceback.format_exc(), self)
            x.show()
            return
        # populate
        self.setWindowTitle('XEB - %s[*]' % filename)
        self.listView.clear()
        for t in self.store.getTableNames():
            self.__insertListViewItem(t)
        self.__populateMenu()
        self.populate(name=name)
        self._setClean()