예제 #1
1
class QtTrajectoryViewer(QMainWindow):
    """Bases: `PyQt4.QtGui.QMainWindow`

    Interface for viewing trajectory.

    It provides interface elements to play/pause and set the speed of
    the animation.
    
    **Example**

    To set up a QtTrajectoryViewer you have to add renderers to the
    scene, set the number of frames present in the animation by calling
    ;py:meth:`~chemlab.graphics.QtTrajectoryViewer.set_ticks` and
    define an update function.

    Below is an example taken from the function
    :py:func:`chemlab.graphics.display_trajectory`::
    
        from chemlab.graphics.qt import QtTrajectoryViewer
        
        # sys = some System
        # coords_list = some list of atomic coordinates
        
        v = QtTrajectoryViewer()
        sr = v.add_renderer(AtomRenderer, sys.r_array, sys.type_array,
                            backend='impostors')
        br = v.add_renderer(BoxRenderer, sys.box_vectors)
        
        v.set_ticks(len(coords_list))
        
        @v.update_function
        def on_update(index):
            sr.update_positions(coords_list[index])
            br.update(sys.box_vectors)
            v.set_text(format_time(times[index]))
            v.widget.repaint()
     
        v.run()
    
    .. warning:: Use with caution, the API for this element is not
                 fully stabilized and may be subject to change.

    """

    def __init__(self):
        super(QtTrajectoryViewer, self).__init__()
        
        self.controls = QDockWidget()
        
        # Eliminate the dock titlebar
        title_widget = QtGui.QWidget(self)
        self.controls.setTitleBarWidget(title_widget)
        
        traj_controls = TrajectoryControls(self)
        self.controls.setWidget(traj_controls)
        
        # Molecular viewer
        self.widget = QChemlabWidget(self)
        self.setCentralWidget(self.widget)
        self.addDockWidget(Qt.DockWidgetArea(Qt.BottomDockWidgetArea),
                           self.controls)

        self.show()
        # Replace in this way
        
        traj_controls.frame_changed.connect(self.on_frame_changed)
        self.traj_controls = traj_controls

    def set_ticks(self, number):
        self.traj_controls.set_ticks(number)
        
    def set_text(self, text):
        '''Update the time indicator in the interface.

        '''
        self.traj_controls.timelabel.setText(self.traj_controls._label_tmp.format(text))

    def on_frame_changed(self, index):
        self._update_function(index)

    def on_pause(self):
        self._timer.stop()

    def on_slider_change(self, value):
        self.current_index = value
        self._update_function(self.current_index)

    def on_slider_down(self):
        self._timer.stop()
        self.play_stop.set_pause()

    def on_speed_changed(self, index):
        self.speed = self.speeds[index]
        if self._timer.isActive():
            self._timer.stop()
            self._timer.start(self.speed)

    def add_renderer(self, klass, *args, **kwargs):
        '''The behaviour of this function is the same as
        :py:meth:`chemlab.graphics.QtViewer.add_renderer`.

        '''
        renderer = klass(self.widget, *args, **kwargs)
        self.widget.renderers.append(renderer)
        return renderer

    def add_ui(self, klass, *args, **kwargs):
        '''Add an UI element for the current scene. The approach is
        the same as renderers.

        .. warning:: The UI api is not yet finalized

        '''

        ui = klass(self.widget, *args, **kwargs)
        self.widget.uis.append(ui)
        return ui

    def add_post_processing(self, klass, *args, **kwargs):
        pp = klass(self.widget, *args, **kwargs)
        self.widget.post_processing.append(pp)
        return pp

    def run(self):
        app.exec_()

    def update_function(self, func, frames=None):
        '''Set the function to be called when it's time to display a frame.

        *func* should be a function that takes one integer argument that
        represents the frame that has to be played::

            def func(index):
                # Update the renderers to match the
                # current animation index

        '''
        # Back-compatibility
        if frames is not None:
            self.traj_controls.set_ticks(frames)
        
        self._update_function = func

    def _toggle_settings(self):
        self._settings_pan.setVisible(not self._settings_pan.isVisible())
예제 #2
0
class QtTrajectoryViewer(QMainWindow):
    """Bases: `PyQt4.QtGui.QMainWindow`

    Interface for viewing trajectory.

    It provides interface elements to play/pause and set the speed of
    the animation.
    
    **Example**

    To set up a QtTrajectoryViewer you have to add renderers to the
    scene, set the number of frames present in the animation by calling
    ;py:meth:`~chemlab.graphics.QtTrajectoryViewer.set_ticks` and
    define an update function.

    Below is an example taken from the function
    :py:func:`chemlab.graphics.display_trajectory`::
    
        from chemlab.graphics.qt import QtTrajectoryViewer
        
        # sys = some System
        # coords_list = some list of atomic coordinates
        
        v = QtTrajectoryViewer()
        sr = v.add_renderer(AtomRenderer, sys.r_array, sys.type_array,
                            backend='impostors')
        br = v.add_renderer(BoxRenderer, sys.box_vectors)
        
        v.set_ticks(len(coords_list))
        
        @v.update_function
        def on_update(index):
            sr.update_positions(coords_list[index])
            br.update(sys.box_vectors)
            v.set_text(format_time(times[index]))
            v.widget.repaint()
     
        v.run()
    
    .. warning:: Use with caution, the API for this element is not
                 fully stabilized and may be subject to change.

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

        self.controls = QDockWidget()

        # Eliminate the dock titlebar
        title_widget = QtGui.QWidget(self)
        self.controls.setTitleBarWidget(title_widget)

        traj_controls = TrajectoryControls(self)
        self.controls.setWidget(traj_controls)

        # Molecular viewer
        self.widget = QChemlabWidget(self)
        self.setCentralWidget(self.widget)
        self.addDockWidget(Qt.DockWidgetArea(Qt.BottomDockWidgetArea),
                           self.controls)

        self.show()
        # Replace in this way

        traj_controls.frame_changed.connect(self.on_frame_changed)
        self.traj_controls = traj_controls

    def set_ticks(self, number):
        self.traj_controls.set_ticks(number)

    def set_text(self, text):
        '''Update the time indicator in the interface.

        '''
        self.traj_controls.timelabel.setText(
            self.traj_controls._label_tmp.format(text))

    def on_frame_changed(self, index):
        self._update_function(index)

    def on_pause(self):
        self._timer.stop()

    def on_slider_change(self, value):
        self.current_index = value
        self._update_function(self.current_index)

    def on_slider_down(self):
        self._timer.stop()
        self.play_stop.set_pause()

    def on_speed_changed(self, index):
        self.speed = self.speeds[index]
        if self._timer.isActive():
            self._timer.stop()
            self._timer.start(self.speed)

    def add_renderer(self, klass, *args, **kwargs):
        '''The behaviour of this function is the same as
        :py:meth:`chemlab.graphics.QtViewer.add_renderer`.

        '''
        renderer = klass(self.widget, *args, **kwargs)
        self.widget.renderers.append(renderer)
        return renderer

    def add_ui(self, klass, *args, **kwargs):
        '''Add an UI element for the current scene. The approach is
        the same as renderers.

        .. warning:: The UI api is not yet finalized

        '''

        ui = klass(self.widget, *args, **kwargs)
        self.widget.uis.append(ui)
        return ui

    def add_post_processing(self, klass, *args, **kwargs):
        pp = klass(self.widget, *args, **kwargs)
        self.widget.post_processing.append(pp)
        return pp

    def run(self):
        app.exec_()

    def update_function(self, func, frames=None):
        '''Set the function to be called when it's time to display a frame.

        *func* should be a function that takes one integer argument that
        represents the frame that has to be played::

            def func(index):
                # Update the renderers to match the
                # current animation index

        '''
        # Back-compatibility
        if frames is not None:
            self.traj_controls.set_ticks(frames)

        self._update_function = func

    def _toggle_settings(self):
        self._settings_pan.setVisible(not self._settings_pan.isVisible())
class ViewerWnd( QMainWindow ):
    def __init__( self, app, dictOpts ):
        QMainWindow.__init__( self )
        self.setWindowTitle( "PostGIS Layer Viewer - v.1.6.1" )
        self.setTabPosition( Qt.BottomDockWidgetArea, QTabWidget.North )

        self.canvas = QgsMapCanvas()
        self.canvas.setCanvasColor( Qt.white )
        self.canvas.useImageToRender( True )
        self.canvas.enableAntiAliasing( True )
        self.setCentralWidget( self.canvas )

        actionZoomIn = QAction( QIcon( imgs_dir + "mActionZoomIn.png" ), QString( "Zoom in" ), self )
        actionZoomOut = QAction( QIcon( imgs_dir + "mActionZoomOut.png" ), QString( "Zoom out" ), self )
        actionPan = QAction( QIcon( imgs_dir + "mActionPan.png" ), QString( "Pan" ), self )
        actionZoomFullExtent = QAction( QIcon( imgs_dir + "mActionZoomFullExtent.png" ), QString( "Zoom full" ), 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.connect(actionZoomFullExtent, SIGNAL( "triggered()" ), self.zoomFullExtent )

        self.actionGroup = QActionGroup( self )
        self.actionGroup.addAction( actionPan )
        self.actionGroup.addAction( actionZoomIn )
        self.actionGroup.addAction( actionZoomOut )        

        # Create the toolbar
        self.toolbar = self.addToolBar( "Map tools" )
        self.toolbar.addAction( actionPan )
        self.toolbar.addAction( actionZoomIn )
        self.toolbar.addAction( actionZoomOut )
        self.toolbar.addAction( actionZoomFullExtent )

        # 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 )
        
        # Create the statusbar
        self.statusbar = QStatusBar( self )
        self.statusbar.setObjectName( "statusbar" )
        self.setStatusBar( self.statusbar )

        self.lblXY = QLabel()
        self.lblXY.setFrameStyle( QFrame.Box )
        self.lblXY.setMinimumWidth( 170 )
        self.lblXY.setAlignment( Qt.AlignCenter )
        self.statusbar.setSizeGripEnabled( False )
        self.statusbar.addPermanentWidget( self.lblXY, 0 )

        self.lblScale = QLabel()
        self.lblScale.setFrameStyle( QFrame.StyledPanel )
        self.lblScale.setMinimumWidth( 140 )
        self.statusbar.addPermanentWidget( self.lblScale, 0 )

        self.createLegendWidget()   # Create the legend widget

        self.connect( app, SIGNAL( "loadPgLayer" ), self.loadLayer )
        self.connect( self.canvas, SIGNAL( "scaleChanged(double)" ),
            self.changeScale )
        self.connect( self.canvas, SIGNAL( "xyCoordinates(const QgsPoint&)" ),
            self.updateXY )

        self.pan() # Default

        self.plugins = Plugins( self, self.canvas, dictOpts['-h'], dictOpts['-p'], dictOpts['-d'], dictOpts['-U'], dictOpts['-W'] )

        self.createAboutWidget()
        self.layerSRID = '-1'
        self.loadLayer( dictOpts )
    
    def zoomIn( self ):
        self.canvas.setMapTool( self.toolZoomIn )

    def zoomOut( self ):
        self.canvas.setMapTool( self.toolZoomOut )

    def pan( self ):
        self.canvas.setMapTool( self.toolPan )

    def zoomFullExtent( self ):
        self.canvas.zoomToFullExtent()
    
    def about( self ):
        pass

    def createLegendWidget( self ):
        """ Create the map legend widget and associate it to the canvas """
        self.legend = Legend( self )
        self.legend.setCanvas( self.canvas )
        self.legend.setObjectName( "theMapLegend" )

        self.LegendDock = QDockWidget( "Layers", self )
        self.LegendDock.setObjectName( "legend" )
        self.LegendDock.setTitleBarWidget( QWidget() )
        self.LegendDock.setWidget( self.legend )
        self.LegendDock.setContentsMargins ( 0, 0, 0, 0 )
        self.addDockWidget( Qt.BottomDockWidgetArea, self.LegendDock )

    def createAboutWidget( self ):
        self.AboutDock = QDockWidget( "About", self )
        self.AboutDock.setObjectName( "about" )
        self.AboutDock.setTitleBarWidget( QWidget() )
        self.AboutDock.setContentsMargins( 0, 0, 0, 0 )
        self.tabifyDockWidget( self.LegendDock, self.AboutDock )
        self.LegendDock.raise_() # legendDock at the top

        from PyQt4.QtCore import QRect
        from PyQt4.QtGui import QSizePolicy, QGridLayout, QFont
        font = QFont()
        font.setFamily("Sans Serif")
        font.setPointSize(8.7)
        self.AboutWidget = QWidget()
        self.AboutWidget.setFont( font )
        self.AboutWidget.setObjectName("AboutWidget") 
        self.AboutDock.setWidget( self.AboutWidget )
        self.labelAbout = QLabel( self.AboutWidget )
        self.labelAbout.setAlignment(Qt.AlignCenter)
        self.labelAbout.setWordWrap(True)
        self.gridLayout = QGridLayout(self.AboutWidget)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setObjectName("gridLayout")
        self.gridLayout.addWidget(self.labelAbout, 0, 1, 1, 1)
        self.labelAbout.setTextInteractionFlags(Qt.LinksAccessibleByMouse|Qt.LinksAccessibleByKeyboard|Qt.TextSelectableByKeyboard|Qt.TextSelectableByMouse) 
        self.labelAbout.setOpenExternalLinks( True )
        self.labelAbout.setText("<html><head/><body><a href=\"http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/293-consola-sql-para-plugin-pgadmin-postgis-viewer\">PostGIS Layer Viewer</a> v.1.6.1 (2015.02.24)<br \><br \>" \
            "Copyright (c) 2010 Ivan Mincik,<br \>[email protected]<br \>" \
            u"Copyright (c) 2011-2015 Germán Carrillo,<br \>[email protected]<br \><br \>" \
            "<i>Licensed under the terms of GNU GPL v.2.0</i><br \><br \>" \
            "Based on PyQGIS. Plugin Fast SQL Layer by Pablo T. Carreira.</body></html>" )

    def loadLayer( self, dictOpts ):
        print 'I: Loading the layer...'
        self.layerSRID = dictOpts[ 'srid' ] # To access the SRID when querying layer properties

        if not self.isActiveWindow():
            self.activateWindow()            
            self.raise_() 

        if dictOpts['type'] == 'vector':
            # QGIS connection
            uri = QgsDataSourceURI()
            uri.setConnection( dictOpts['-h'], dictOpts['-p'], dictOpts['-d'], 
                dictOpts['-U'], dictOpts['-W'] )
            uri.setDataSource( dictOpts['-s'], dictOpts['-t'], dictOpts['-g'] )
            layer = QgsVectorLayer( uri.uri(), dictOpts['-s'] + '.' + dictOpts['-t'],
                "postgres" )        
        elif dictOpts['type'] == 'raster':          
            connString = "PG: dbname=%s host=%s user=%s password=%s port=%s mode=2 " \
                "schema=%s column=%s table=%s" % ( dictOpts['-d'], dictOpts['-h'], 
                dictOpts['-U'], dictOpts['-W'], dictOpts['-p'], dictOpts['-s'], 
                dictOpts['col'], dictOpts['-t'] )
            layer = QgsRasterLayer( connString, dictOpts['-s'] + '.' + dictOpts['-t'] )
            
            if layer.isValid():
                layer.setContrastEnhancement( QgsContrastEnhancement.StretchToMinimumMaximum )

        self.addLayer( layer, self.layerSRID )

    def addLayer( self, layer, srid='-1' ):
        if layer.isValid():
            # Only in case that srid != -1, read the layer SRS properties, otherwise don't since it will return 4326
            if srid != '-1': 
               self.layerSRID = layer.crs().description() + ' (' + str( layer.crs().postgisSrid() ) + ')'
            else:
               self.layerSRID = 'Unknown SRS (-1)'

            if self.canvas.layerCount() == 0:
                self.canvas.setExtent( layer.extent() )

                if srid != '-1':
                    print 'I: Map SRS (EPSG): %s' % self.layerSRID                    
                    self.canvas.setMapUnits( layer.crs().mapUnits() )
                else:
                    print 'I: Unknown Reference System'
                    self.canvas.setMapUnits( 0 ) # 0: QGis.Meters

            return QgsMapLayerRegistry.instance().addMapLayer( layer )
        return False

    def activeLayer( self ):
        """ Returns the active layer in the layer list widget """
        return self.legend.activeLayer()

    def getLayerProperties( self, l ):
        """ Create a layer-properties string (l:layer)"""
        print 'I: Generating layer properties...'
        if l.type() == 0: # Vector
            wkbType = ["WKBUnknown","WKBPoint","WKBLineString","WKBPolygon",
                       "WKBMultiPoint","WKBMultiLineString","WKBMultiPolygon",
                       "WKBNoGeometry","WKBPoint25D","WKBLineString25D","WKBPolygon25D",
                       "WKBMultiPoint25D","WKBMultiLineString25D","WKBMultiPolygon25D"]
            properties = "Source: %s\n" \
                         "Geometry type: %s\n" \
                         "Number of features: %s\n" \
                         "Number of fields: %s\n" \
                         "SRS (EPSG): %s\n" \
                         "Extent: %s " \
                          % ( l.source(), wkbType[l.wkbType()], l.featureCount(), 
                              l.dataProvider().fields().count(), self.layerSRID, 
                              l.extent().toString() )
        elif l.type() == 1: # Raster
            rType = [ "GrayOrUndefined (single band)", "Palette (single band)", "Multiband", "ColorLayer" ]
            properties = "Source: %s\n" \
                         "Raster type: %s\n" \
                         "Width-Height (pixels): %sx%s\n" \
                         "Bands: %s\n" \
                         "SRS (EPSG): %s\n" \
                         "Extent: %s" \
                         % ( l.source(), rType[l.rasterType()], l.width(), l.height(),
                             l.bandCount(), self.layerSRID, l.extent().toString() )

        self.layerSRID = '-1' # Initialize the srid 
        return properties

    def changeScale( self, scale ):
        self.lblScale.setText( "Scale 1:" + formatNumber( scale ) )

    def updateXY( self, p ):
        if self.canvas.mapUnits() == 2: # Degrees
            self.lblXY.setText( formatToDegrees( p.x() ) + " | " \
                + formatToDegrees( p.y() ) )
        else: # Unidad lineal
            self.lblXY.setText( formatNumber( p.x() ) + " | " \
                + formatNumber( p.y() ) + "" )
예제 #4
0
class ViewerWnd(QMainWindow):
    def __init__(self, app, dictOpts):
        QMainWindow.__init__(self)
        self.setWindowTitle("PostGIS Layer Viewer - v.1.6.1")
        self.setTabPosition(Qt.BottomDockWidgetArea, QTabWidget.North)

        self.canvas = QgsMapCanvas()
        self.canvas.setCanvasColor(Qt.white)
        self.canvas.useImageToRender(True)
        self.canvas.enableAntiAliasing(True)
        self.setCentralWidget(self.canvas)

        actionZoomIn = QAction(QIcon(imgs_dir + "mActionZoomIn.png"),
                               QString("Zoom in"), self)
        actionZoomOut = QAction(QIcon(imgs_dir + "mActionZoomOut.png"),
                                QString("Zoom out"), self)
        actionPan = QAction(QIcon(imgs_dir + "mActionPan.png"), QString("Pan"),
                            self)
        actionZoomFullExtent = QAction(
            QIcon(imgs_dir + "mActionZoomFullExtent.png"),
            QString("Zoom full"), 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.connect(actionZoomFullExtent, SIGNAL("triggered()"),
                     self.zoomFullExtent)

        self.actionGroup = QActionGroup(self)
        self.actionGroup.addAction(actionPan)
        self.actionGroup.addAction(actionZoomIn)
        self.actionGroup.addAction(actionZoomOut)

        # Create the toolbar
        self.toolbar = self.addToolBar("Map tools")
        self.toolbar.addAction(actionPan)
        self.toolbar.addAction(actionZoomIn)
        self.toolbar.addAction(actionZoomOut)
        self.toolbar.addAction(actionZoomFullExtent)

        # 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)

        # Create the statusbar
        self.statusbar = QStatusBar(self)
        self.statusbar.setObjectName("statusbar")
        self.setStatusBar(self.statusbar)

        self.lblXY = QLabel()
        self.lblXY.setFrameStyle(QFrame.Box)
        self.lblXY.setMinimumWidth(170)
        self.lblXY.setAlignment(Qt.AlignCenter)
        self.statusbar.setSizeGripEnabled(False)
        self.statusbar.addPermanentWidget(self.lblXY, 0)

        self.lblScale = QLabel()
        self.lblScale.setFrameStyle(QFrame.StyledPanel)
        self.lblScale.setMinimumWidth(140)
        self.statusbar.addPermanentWidget(self.lblScale, 0)

        self.createLegendWidget()  # Create the legend widget

        self.connect(app, SIGNAL("loadPgLayer"), self.loadLayer)
        self.connect(self.canvas, SIGNAL("scaleChanged(double)"),
                     self.changeScale)
        self.connect(self.canvas, SIGNAL("xyCoordinates(const QgsPoint&)"),
                     self.updateXY)

        self.pan()  # Default

        self.plugins = Plugins(self, self.canvas, dictOpts['-h'],
                               dictOpts['-p'], dictOpts['-d'], dictOpts['-U'],
                               dictOpts['-W'])

        self.createAboutWidget()
        self.layerSRID = '-1'
        self.loadLayer(dictOpts)

    def zoomIn(self):
        self.canvas.setMapTool(self.toolZoomIn)

    def zoomOut(self):
        self.canvas.setMapTool(self.toolZoomOut)

    def pan(self):
        self.canvas.setMapTool(self.toolPan)

    def zoomFullExtent(self):
        self.canvas.zoomToFullExtent()

    def about(self):
        pass

    def createLegendWidget(self):
        """ Create the map legend widget and associate it to the canvas """
        self.legend = Legend(self)
        self.legend.setCanvas(self.canvas)
        self.legend.setObjectName("theMapLegend")

        self.LegendDock = QDockWidget("Layers", self)
        self.LegendDock.setObjectName("legend")
        self.LegendDock.setTitleBarWidget(QWidget())
        self.LegendDock.setWidget(self.legend)
        self.LegendDock.setContentsMargins(0, 0, 0, 0)
        self.addDockWidget(Qt.BottomDockWidgetArea, self.LegendDock)

    def createAboutWidget(self):
        self.AboutDock = QDockWidget("About", self)
        self.AboutDock.setObjectName("about")
        self.AboutDock.setTitleBarWidget(QWidget())
        self.AboutDock.setContentsMargins(0, 0, 0, 0)
        self.tabifyDockWidget(self.LegendDock, self.AboutDock)
        self.LegendDock.raise_()  # legendDock at the top

        from PyQt4.QtCore import QRect
        from PyQt4.QtGui import QSizePolicy, QGridLayout, QFont
        font = QFont()
        font.setFamily("Sans Serif")
        font.setPointSize(8.7)
        self.AboutWidget = QWidget()
        self.AboutWidget.setFont(font)
        self.AboutWidget.setObjectName("AboutWidget")
        self.AboutDock.setWidget(self.AboutWidget)
        self.labelAbout = QLabel(self.AboutWidget)
        self.labelAbout.setAlignment(Qt.AlignCenter)
        self.labelAbout.setWordWrap(True)
        self.gridLayout = QGridLayout(self.AboutWidget)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setObjectName("gridLayout")
        self.gridLayout.addWidget(self.labelAbout, 0, 1, 1, 1)
        self.labelAbout.setTextInteractionFlags(Qt.LinksAccessibleByMouse
                                                | Qt.LinksAccessibleByKeyboard
                                                | Qt.TextSelectableByKeyboard
                                                | Qt.TextSelectableByMouse)
        self.labelAbout.setOpenExternalLinks(True)
        self.labelAbout.setText("<html><head/><body><a href=\"http://geotux.tuxfamily.org/index.php/en/geo-blogs/item/293-consola-sql-para-plugin-pgadmin-postgis-viewer\">PostGIS Layer Viewer</a> v.1.6.1 (2015.02.24)<br \><br \>" \
            "Copyright (c) 2010 Ivan Mincik,<br \>[email protected]<br \>" \
            u"Copyright (c) 2011-2015 Germán Carrillo,<br \>[email protected]<br \><br \>" \
            "<i>Licensed under the terms of GNU GPL v.2.0</i><br \><br \>" \
            "Based on PyQGIS. Plugin Fast SQL Layer by Pablo T. Carreira.</body></html>" )

    def loadLayer(self, dictOpts):
        print 'I: Loading the layer...'
        self.layerSRID = dictOpts[
            'srid']  # To access the SRID when querying layer properties

        if not self.isActiveWindow():
            self.activateWindow()
            self.raise_()

        if dictOpts['type'] == 'vector':
            # QGIS connection
            uri = QgsDataSourceURI()
            uri.setConnection(dictOpts['-h'], dictOpts['-p'], dictOpts['-d'],
                              dictOpts['-U'], dictOpts['-W'])
            uri.setDataSource(dictOpts['-s'], dictOpts['-t'], dictOpts['-g'])
            layer = QgsVectorLayer(uri.uri(),
                                   dictOpts['-s'] + '.' + dictOpts['-t'],
                                   "postgres")
        elif dictOpts['type'] == 'raster':
            connString = "PG: dbname=%s host=%s user=%s password=%s port=%s mode=2 " \
                "schema=%s column=%s table=%s" % ( dictOpts['-d'], dictOpts['-h'],
                dictOpts['-U'], dictOpts['-W'], dictOpts['-p'], dictOpts['-s'],
                dictOpts['col'], dictOpts['-t'] )
            layer = QgsRasterLayer(connString,
                                   dictOpts['-s'] + '.' + dictOpts['-t'])

            if layer.isValid():
                layer.setContrastEnhancement(
                    QgsContrastEnhancement.StretchToMinimumMaximum)

        self.addLayer(layer, self.layerSRID)

    def addLayer(self, layer, srid='-1'):
        if layer.isValid():
            # Only in case that srid != -1, read the layer SRS properties, otherwise don't since it will return 4326
            if srid != '-1':
                self.layerSRID = layer.crs().description() + ' (' + str(
                    layer.crs().postgisSrid()) + ')'
            else:
                self.layerSRID = 'Unknown SRS (-1)'

            if self.canvas.layerCount() == 0:
                self.canvas.setExtent(layer.extent())

                if srid != '-1':
                    print 'I: Map SRS (EPSG): %s' % self.layerSRID
                    self.canvas.setMapUnits(layer.crs().mapUnits())
                else:
                    print 'I: Unknown Reference System'
                    self.canvas.setMapUnits(0)  # 0: QGis.Meters

            return QgsMapLayerRegistry.instance().addMapLayer(layer)
        return False

    def activeLayer(self):
        """ Returns the active layer in the layer list widget """
        return self.legend.activeLayer()

    def getLayerProperties(self, l):
        """ Create a layer-properties string (l:layer)"""
        print 'I: Generating layer properties...'
        if l.type() == 0:  # Vector
            wkbType = [
                "WKBUnknown", "WKBPoint", "WKBLineString", "WKBPolygon",
                "WKBMultiPoint", "WKBMultiLineString", "WKBMultiPolygon",
                "WKBNoGeometry", "WKBPoint25D", "WKBLineString25D",
                "WKBPolygon25D", "WKBMultiPoint25D", "WKBMultiLineString25D",
                "WKBMultiPolygon25D"
            ]
            properties = "Source: %s\n" \
                         "Geometry type: %s\n" \
                         "Number of features: %s\n" \
                         "Number of fields: %s\n" \
                         "SRS (EPSG): %s\n" \
                         "Extent: %s " \
                          % ( l.source(), wkbType[l.wkbType()], l.featureCount(),
                              l.dataProvider().fields().count(), self.layerSRID,
                              l.extent().toString() )
        elif l.type() == 1:  # Raster
            rType = [
                "GrayOrUndefined (single band)", "Palette (single band)",
                "Multiband", "ColorLayer"
            ]
            properties = "Source: %s\n" \
                         "Raster type: %s\n" \
                         "Width-Height (pixels): %sx%s\n" \
                         "Bands: %s\n" \
                         "SRS (EPSG): %s\n" \
                         "Extent: %s" \
                         % ( l.source(), rType[l.rasterType()], l.width(), l.height(),
                             l.bandCount(), self.layerSRID, l.extent().toString() )

        self.layerSRID = '-1'  # Initialize the srid
        return properties

    def changeScale(self, scale):
        self.lblScale.setText("Scale 1:" + formatNumber(scale))

    def updateXY(self, p):
        if self.canvas.mapUnits() == 2:  # Degrees
            self.lblXY.setText( formatToDegrees( p.x() ) + " | " \
                + formatToDegrees( p.y() ) )
        else:  # Unidad lineal
            self.lblXY.setText( formatNumber( p.x() ) + " | " \
                + formatNumber( p.y() ) + "" )
예제 #5
0
class OneClockAddon:

    def __init__(self):
        self.db = TomatoDB("_TomatoClock.db")
        self.dlg = OneClock(mw)

        self.pb = None
        self._connect_slots()
        self._set_style_sheet(mw)
        self.tm = None
        self.dlg_rest = None
        self.pb_w = None

        self.replace_mw_overview()
        self.replace_mw_deckbrowser()

    def replace_mw_overview(self):
        mw.overview = anki_overview(self.dlg, self.db)

    def replace_mw_reviewer(self):
        mw.reviewer = anki_reviewer(self.dlg.mode, self.db)

    def replace_mw_deckbrowser(self):
        mw.deckBrowser = anki_deckbrowser(self.db)
        mw.deckBrowser.refresh()

    @staticmethod
    def _set_style_sheet(obj):
        with open(os.path.join(os.path.dirname(__file__), "ui", "designer", "style.css"), "r") as f:
            obj.setStyleSheet(f.read())

    def _connect_slots(self):
        self.dlg.btn_start.clicked.connect(self.on_btn_start_clicked)

    def perform_hooks(self, func):
        func('reviewCleanup', self.on_review_cleanup)
        func('profileLoaded', self.on_profile_loaded)
        func('afterStateChange', self.after_anki_state_change)

    def on_profile_loaded(self):
        ProfileConfig.donate_alerted = False
        UserConfig.BREAK_MINUTES  # just ensure json file is generated
        try:
            if UserConfig.LIVE_CODE_DOWNLOAD:
                thr = _live_chart_py_downloader()
                thr.start()
        except:
            pass

    def on_review_cleanup(self):
        mw.setWindowIcon(QIcon(":/icons/anki.png"))
        if self.tm and self.tm.isActive():
            self.tm.stop()
        if self.pb:
            self.pb_w.hide()
            self.pb.reset()

        if self.dlg_rest:
            self.dlg_rest.hide()

        try:
            mw.reviewer.restore_layouts()
        except AttributeError:  # just in case "replace_mw_reviewer" is not called
            pass

    def on_btn_start_clicked(self):
        self.replace_mw_reviewer()

        mw.setWindowIcon(QIcon(":/icon/tomato.png"))
        assert isinstance(mw, AnkiQt)

        self.setup_progressbar()
        self.pb.set_seconds(self.dlg.min * MIN_SECS)
        if not self.tm:
            self.tm = Timer(mw)
            self.tm.timeout.connect(self.on_timer)
        self.tm.start()

        # click study button
        mw.overview._linkHandler("study")

        self.db.start_session(
            self.dlg.min,
            UserConfig.ANSWER_TIMEOUT_SECONDS,
            self.dlg.mode
        )

    def after_anki_state_change(self, state, oldState):
        if state == 'overview' and oldState == 'review':
            self.on_tomato(False)
            mw.overview.refresh()

    def on_tomato(self, from_timer=True):
        self.db.end_session()
        if self.tm:
            self.tm.stop()
        self.pb_w.hide()
        self.pb.reset()
        if from_timer:
            mw.moveToState("overview")
            if not self.dlg_rest:
                self.dlg_rest = RestDialog(mw)
                self._set_style_sheet(self.dlg_rest)
                self.dlg_rest.accepted.connect(self.on_dlg_rest_accepted)
                self.dlg_rest.rejected.connect(self.on_dlg_rest_rejected)
            if UserConfig.PLAY_SOUNDS["break"]:
                play(BREAK)
            self.dlg_rest.exec_(self.dlg.min)

    @staticmethod
    def on_dlg_rest_accepted():
        mw.overview._linkHandler("tomato_clock")

    def on_dlg_rest_rejected(self):
        pass

    def on_timer(self):
        if self.pb:
            self.pb_w.show()
            self.pb.on_timer()
        self.db.commit()

    def setup_progressbar(self):

        dockArea = Qt.TopDockWidgetArea
        # dockArea = Qt.LeftDockWidgetArea
        # dockArea = Qt.BottomDockWidgetArea

        self.pb_w = QDockWidget(mw)
        self.pb_w.setObjectName("progress_dock")
        if not self.pb:
            self.pb = ClockProgress(mw, dockArea)
            self.pb.tomato.connect(self.on_tomato)
        else:
            self.pb.reset()

        self.pb.set_seconds(self.dlg.min * MIN_SECS)
        self.pb_w.setWidget(self.pb)
        w = QWidget(self.pb_w)
        w.setFixedHeight(self.pb.height())
        self.pb_w.setTitleBarWidget(w)
        self.pb_w.setFeatures(QDockWidget.NoDockWidgetFeatures)

        # first check existing widgets
        existing_widgets = [widget for widget in mw.findChildren(QDockWidget) if mw.dockWidgetArea(widget) == dockArea]

        # then add ourselves
        mw.addDockWidget(dockArea, self.pb_w)

        # stack with any existing widgets
        if len(existing_widgets) > 0:
            mw.setDockNestingEnabled(True)

            if dockArea == Qt.TopDockWidgetArea or dockArea == Qt.BottomDockWidgetArea:
                stack_method = Qt.Vertical
            if dockArea == Qt.LeftDockWidgetArea or dockArea == Qt.RightDockWidgetArea:
                stack_method = Qt.Horizontal
            mw.splitDockWidget(existing_widgets[0], self.pb_w, stack_method)

        mw.web.setFocus()
        self._set_style_sheet(self.pb)