示例#1
0
 def contextMenuEvent(self, e):
     """Pops a contextual menu up on right-clicks"""
     item = self.itemAt(e.pos())
     if item:
         menu = QMenu(self)
         if isinstance(item, CircuitItem):
             pos = item.mapFromScene(self.mapToScene(e.pos()))
             plug = item.handleAtPos(pos)
             item = plug if plug else item
             menu.addAction(self.str_setName, lambda: self.getNewName(item))
         elif isinstance(item, PlugItem):
             if isinstance(item.data, Clock):
                 thread = item.data.clkThread
                 if thread.paused:
                     menu.addAction(
                         self.str_startClock, lambda: thread.unpause())
                 else:
                     menu.addAction(
                         self.str_pauseClock, lambda: thread.pause())
             menu.addAction(self.str_setName, lambda: self.getNewName(item))
             if item.data.isInput:
                 menu.addAction(
                     str(item.data.value), item.setAndUpdate)
         elif isinstance(item, WireItem):
             pos = item.mapFromScene(self.mapToScene(e.pos()))
             if item.handleAtPos(pos):
                 menu.addAction(
                     self.str_removeLast, lambda: item.removeLast())
         menu.popup(e.globalPos())
    def showHeaderMenu( self, pos ):
        header = self.horizontalHeader()
        column = header.logicalIndexAt(pos.x())

        filterAction = QAction(self)
        filterAction.setText('Filter column')
        filterAction.triggered.connect(lambda: self.filterColumn(self.indexAt(pos)))
        symbolAction = QAction(self)
        symbolAction.setText('Symbol')
        symbolAction.triggered.connect(lambda: self.changeColumnDisplay(self.indexAt(pos),'symbol'))
        colourAction = QAction(self)
        colourAction.setText('Color')
        colourAction.triggered.connect(lambda: self.changeColumnDisplay(self.indexAt(pos),'brush'))
        sizeAction = QAction(self)
        sizeAction.setText('Size')
        sizeAction.triggered.connect(lambda: self.changeColumnDisplay(self.indexAt(pos),'size'))
        # show menu about the column
        menu = QMenu(self)
        displayMenu = menu.addMenu('Change graph display')
        displayMenu.addAction(symbolAction)
        displayMenu.addAction(colourAction)
        displayMenu.addAction(sizeAction)
        menu.addAction(filterAction)

        menu.popup(header.mapToGlobal(pos))
    def contextMenuEvent(self, event):
        """
        Handles the ``contextMenuEvent`` event for :class:`MDISubWindow_TextEdit`.

        :param `event`: a `QContextMenuEvent` event to be processed.
        """
        menu = QMenu(self)
        menu.addAction(self.action_Edit_Undo)
        menu.addAction(self.action_Edit_Redo)
        menu.addSeparator()
        menu.addAction(self.action_Edit_Cut)
        menu.addAction(self.action_Edit_Copy)
        menu.addAction(self.action_Edit_Paste)
        menu.addAction(self.action_Edit_Delete)
        menu.addSeparator()
        menu.addAction(self.action_Edit_SelectAll)
        menu.popup(self.mapToGlobal(event.pos()))
        # menu.exec_(self.mapToGlobal(event.pos()))
        event.accept()
        print("MDISubWindow_TextEdit contextMenuEvent")
    def contextMenuEvent(self, event):
        """
        Handles the ``contextMenuEvent`` event for :class:`MDISubWindow_TextEdit`.

        :param `event`: a `QContextMenuEvent` event to be processed.
        """
        menu = QMenu(self)
        menu.addAction(self.action_Edit_Undo)
        menu.addAction(self.action_Edit_Redo)
        menu.addSeparator()
        menu.addAction(self.action_Edit_Cut)
        menu.addAction(self.action_Edit_Copy)
        menu.addAction(self.action_Edit_Paste)
        menu.addAction(self.action_Edit_Delete)
        menu.addSeparator()
        menu.addAction(self.action_Edit_SelectAll)
        menu.popup(self.mapToGlobal(event.pos()))
        # menu.exec_(self.mapToGlobal(event.pos()))
        event.accept()
        print("MDISubWindow_TextEdit contextMenuEvent")
示例#5
0
    def contextMenuEvent(self, event):
        """
        Handles the ``contextMenuEvent`` event for :class:`MDIArea`.

        :param `event`: A `QContextMenuEvent`_ to be processed.
        """
        mainWin = self.mainWin
        if not len(self.subWindowList()): # Nothing is open.
            # Build a menu suitable for the startup screen.
            menu = QMenu(self)
            menu.addAction(mainWin.actionHash["ACTION_new"])
            menu.addAction(mainWin.actionHash["ACTION_open"])
            menu.addAction(mainWin.actionHash["ACTION_settingsdialog"])
            menu.addAction(mainWin.actionHash["ACTION_help"])
            menu.addAction(mainWin.actionHash["ACTION_about"])
            menu.addAction(mainWin.actionHash["ACTION_exit"])
            menu.popup(self.mapToGlobal(event.pos()))
            # menu.exec_(self.mapToGlobal(event.pos()))
        else:
            # Build a menu suitable for when the mdi workspace is open.
            mainWin.fileMenu.popup(self.mapToGlobal(event.pos()))

        event.accept()
        qDebug("QMdiArea contextMenuEvent")
示例#6
0
    def contextMenuEvent(self, event):
        """
        Handles the ``contextMenuEvent`` event for :class:`MDIArea`.

        :param `event`: A `QContextMenuEvent`_ to be processed.
        """
        mainWin = self.mainWin
        if not len(self.subWindowList()):  # Nothing is open.
            # Build a menu suitable for the startup screen.
            menu = QMenu(self)
            menu.addAction(mainWin.actionHash["ACTION_new"])
            menu.addAction(mainWin.actionHash["ACTION_open"])
            menu.addAction(mainWin.actionHash["ACTION_settingsdialog"])
            menu.addAction(mainWin.actionHash["ACTION_help"])
            menu.addAction(mainWin.actionHash["ACTION_about"])
            menu.addAction(mainWin.actionHash["ACTION_exit"])
            menu.popup(self.mapToGlobal(event.pos()))
            # menu.exec_(self.mapToGlobal(event.pos()))
        else:
            # Build a menu suitable for when the mdi workspace is open.
            mainWin.fileMenu.popup(self.mapToGlobal(event.pos()))

        event.accept()
        qDebug("QMdiArea contextMenuEvent")
示例#7
0
class MainWindow(QMainWindow):
    """docstring for MainWindow"""
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.serviceProvider = 0
        self.popupMenu = None
        self.mapControlButtons = []
        self.mapControlTypes = []
        self.markerObjects = []
        self.setWindowTitle(self.tr('Map Viewer Demo'))

        self.routingManager = None
        self.mapManager = None
        self.mapWidget = None
        self.markerIcon = None
        self.slider = None

        manager = QNetworkConfigurationManager()

        canStartIAP = manager.capabilities() & QNetworkConfigurationManager.CanStartAndStopInterfaces

        configuration = manager.defaultConfiguration()

        if not configuration.isValid or (not canStartIAP and configuration.starte() != QNetworkConfiguration.Active):
            QMessageBox.information(self, self.tr('Map Viewer Demo'),
                                    self.tr('Available Access Points not found.'))
            return

        self.session = QNetworkSession(configuration, self)
        self.session.opened.connect(self.networkSessionOpened)
        self.session.error.connect(self.error)

        self.session.open()
        self.session.waitForOpened()

        self.setProvider('nokia')
        self.setupUi()

    def networkSessionOpened(self):
        pass

    def sliderValueChanged(self, value):
        self.mapWidget.setZoomLevel(value)

    def mapZoomLevelChanged(self, level):
        self.slider.setSliderPosition(int(level))

    def mapTypeChanged(self, newType):
        index = self.mapControlTypes.index(newType)
        if index != -1:
            self.mapControButtons[index].setChecked(True)

    def mapTypeToggled(self, checked):
        if checked:
            button = self.sender()
            index = self.mapControlButtons.index(button)
            if index != -1:
                print index, self.mapControlTypes[index]
                self.mapWidget.setMapType(self.mapControlTypes[index])

    def updateCoords(self, coords):
        if not coords.isValid():
            return

        self.latitudeEdit.setText('%f' % coords.latitude())
        self.longitudeEdit.setText('%f' % coords.longitude())

    def setCoordsClicked(self):
        lat = float(self.latitudeEdit.text())
        lon = float(self.longitudeEdit.text())
        self.mapWidget.setCenter(QGeoCoordinate(lat, lon))

    def setProvider(self, providerId):
        self.serviceProvider = QGeoServiceProvider(providerId)
        if self.serviceProvider.error() != QGeoServiceProvider.NoError:
            QMessageBox.information(self, self.tr('MapViewer Example'),
                                    self.tr('Unable to dinf the %s geoservices plugin.' % providerId))

            qApp.quit()
            return

        self.mapManager = self.serviceProvider.mappingManager()
        self.routingManager = self.serviceProvider.routingManager()

    def error(self, error):
        if error == QNetworkSession.UnknownSessionError:
            msgBox = QMessageBox(self.parent())
            msgBox.setText('This application requires network access to function.')
            msgBox.setInformativeText('Press Cancel to quit the application.')
            msgBox.setStandardButtons(QMessageBox.Retry | QMessageBox.Cancel)
            msgBox.setIcon(QMessageBox.Information)
            msgBox.setDefaultButton(QMessageBox.Retry)
            ret = msgBox.exec_()
            if ret == QMessageBox.Retry:
                QTimer.singleShot(0, self.session.open)
            elif ret == QMessageBox.Cancel:
                self.close()
        elif error == QNetworkSession.SessionAbortedError:
            msgBox = QMessageBox(self.parent())
            msgBox.setText('Out of range of network')
            msgBox.setInformativeText('Move back into range and press Retry, or press Cancel to quit the application')
            msgBox.setStandardButtons(QMessageBox.Retry | QMessageBox.Cancel)
            msgBox.setIcon(QMessageBox.Information)
            msgBox.setDefaultButton(QMessageBox.Retry)
            ret = msgBox.exec_()
            if ret == QMessageBox.Retry:
                QTimer.singleShot(0, self.session.open)
            elif ret == QMessageBox.Cancel:
                self.close()


    def setupUi(self):

        scene = QGraphicsScene(self)
        self.view = QGraphicsView(scene, self)
        self.view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.view.setVisible(True)
        self.view.setInteractive(True)

        self.createPixmapIcon()

        self.mapWidget = MapWidget(self.mapManager)
        scene.addItem(self.mapWidget)
        self.mapWidget.setCenter(QGeoCoordinate(-8.1, -34.95))
        self.mapWidget.setZoomLevel(5)

        #...
        self.slider = QSlider(Qt.Vertical, self)
        self.slider.setTickInterval(1)
        self.slider.setTickPosition(QSlider.TicksBothSides)
        self.slider.setMaximum(self.mapManager.maximumZoomLevel())
        self.slider.setMinimum(self.mapManager.minimumZoomLevel())

        self.slider.valueChanged[int].connect(self.sliderValueChanged)
        self.mapWidget.zoomLevelChanged[float].connect(self.mapZoomLevelChanged)

        mapControlLayout = QVBoxLayout()

        self.mapWidget.mapTypeChanged.connect(self.mapTypeChanged)

        for mapType in self.mapWidget.supportedMapTypes():
            radio = QRadioButton(self)
            if mapType == QGraphicsGeoMap.StreetMap:
                radio.setText('Street')
            elif mapType == QGraphicsGeoMap.SatelliteMapDay:
                radio.setText('Sattelite')
            elif mapType == QGraphicsGeoMap.SatelliteMapNight:
                radio.setText('Sattelite - Night')
            elif mapType == QGraphicsGeoMap.TerrainMap:
                radio.setText('Terrain')

            if mapType == self.mapWidget.mapType():
                radio.setChecked(True)

            radio.toggled[bool].connect(self.mapTypeToggled)

            self.mapControlButtons.append(radio)
            self.mapControlTypes.append(mapType)
            mapControlLayout.addWidget(radio)

        self.latitudeEdit = QLineEdit()
        self.longitudeEdit = QLineEdit()

        formLayout = QFormLayout()
        formLayout.addRow('Latitude', self.latitudeEdit)
        formLayout.addRow('Longitude', self.longitudeEdit)

        self.captureCoordsButton = QToolButton()
        self.captureCoordsButton.setText('Capture coordinates')
        self.captureCoordsButton.setCheckable(True)

        self.captureCoordsButton.toggled[bool].connect(
                self.mapWidget.setMouseClickCoordQuery)
        self.mapWidget.coordQueryResult.connect(self.updateCoords)

        self.setCoordsButton = QPushButton()
        self.setCoordsButton.setText('Set coordinates')
        self.setCoordsButton.clicked.connect(self.setCoordsClicked)

        buttonLayout = QHBoxLayout()

        buttonLayout.addWidget(self.captureCoordsButton)
        buttonLayout.addWidget(self.setCoordsButton)

        coordControlLayout = QVBoxLayout()
        coordControlLayout.addLayout(formLayout)
        coordControlLayout.addLayout(buttonLayout)

        widget = QWidget(self)
        layout = QGridLayout()
        layout.setRowStretch(0, 1)
        layout.setRowStretch(1, 0)

        topLayout = QGridLayout()
        bottomLayout = QGridLayout()

        topLayout.setColumnStretch(0, 0)
        topLayout.setColumnStretch(1, 1)

        bottomLayout.setColumnStretch(0, 0)
        bottomLayout.setColumnStretch(1, 1)

        topLayout.addWidget(self.slider, 0, 0)
        topLayout.addWidget(self.view, 0, 1)

        bottomLayout.addLayout(mapControlLayout, 0, 0)
        bottomLayout.addLayout(coordControlLayout, 0, 1)

        layout.addLayout(topLayout, 0, 0)
        layout.addLayout(bottomLayout, 1, 0)

        self.layout = layout
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        self.view.setContextMenuPolicy(Qt.CustomContextMenu)

        self.view.customContextMenuRequested.connect(self.customContextMenuRequest)

    def createPixmapIcon(self):
        self.markerIcon = QPixmap(MARKER_WIDTH, MARKER_HEIGHT)
        self.markerIcon.fill(Qt.transparent)

        painter = QPainter(self.markerIcon)

        p1 = QPoint(MARKER_WIDTH / 2, MARKER_HEIGHT - 1)
        p2 = QPoint(MARKER_WIDTH / 2, MARKER_HEIGHT - 1 - MARKER_PIN_LEN)
        pen = QPen(Qt.black)
        pen.setWidth(2)
        pen.setCosmetic(True)
        painter.setPen(pen)
        painter.drawLine(p1, p2)
        ellipse = QRect(0, 0, MARKER_WIDTH - 1, MARKER_HEIGHT - 1)
        pen.setWidth(1)
        painter.setPen(pen)
        color = QColor(Qt.green)
        color.setAlpha(127)
        brush = QBrush(color)
        painter.setBrush(brush)
        painter.drawEllipse(ellipse)

    def resizeEvent(self, event):
        self.view.setSceneRect(QRectF(QPointF(0.0, 0.0), self.view.size()))
        self.mapWidget.resize(self.view.size())

    def showEvent(self, event):
        self.view.setSceneRect(QRectF(QPointF(0.0, 0.0), self.view.size()))
        self.mapWidget.resize(self.view.size())

    def createMenus(self):
        self.popupMenu = QMenu(self)

        # Markers
        subMenuItem = QMenu(self.tr('Marker'), self)
        self.popupMenu.addMenu(subMenuItem)

        menuItem = QAction(self.tr('Set marker'), self)
        subMenuItem.addAction(menuItem)
        menuItem.triggered[bool].connect(self.drawPixmap)

        menuItem = QAction(self.tr('Remove marker'), self)
        subMenuItem.addAction(menuItem)
        menuItem.triggered[bool].connect(self.removePixmaps)

        menuItem = QAction(self.tr('Select objects'), self)
        subMenuItem.addAction(menuItem)
        menuItem.triggered[bool].connect(self.selectObjects)

        # Draw
        subMenuItem = QMenu(self.tr('Draw'), self)
        self.popupMenu.addMenu(subMenuItem)

        menuItem = QAction(self.tr('Rectangle'), self)
        subMenuItem.addAction(menuItem)
        menuItem.triggered[bool].connect(self.drawRect)

        menuItem = QAction(self.tr('Polyline'), self)
        subMenuItem.addAction(menuItem)
        menuItem.triggered[bool].connect(self.drawPolyline)

        menuItem = QAction(self.tr('Polygon'), self)
        subMenuItem.addAction(menuItem)
        menuItem.triggered[bool].connect(self.drawPolygon)

        menuItem = QAction(self.tr('Circle'), self)
        subMenuItem.addAction(menuItem)
        menuItem.triggered[bool].connect(self.drawCircle)

        menuItem = QAction(self.tr('Text'), self)
        subMenuItem.addAction(menuItem)
        menuItem.triggered[bool].connect(self.drawText)

        # Routing
        subMenuItem = QMenu(self.tr('Route'), self)
        self.popupMenu.addMenu(subMenuItem)

        menuItem = QAction(self.tr('Calculate route'), self)
        subMenuItem.addAction(menuItem)
        menuItem.triggered[bool].connect(self.calculateRoute)

    def selectObjects(self):
        for obj in self.mapWidget.mapObjects():
            obj.setSelected(False)

        if len(self.markerObjects) < 2:
            return

        bottomRight = self.markerObjects.pop()
        topLeft = self.markerObjects.pop()

        self.mapWidget.removeMapObject(topLeft)
        self.mapWidget.removeMapObject(bottomRight)

        selectedObjects = self.mapWidget.mapObjectsInScreenRect(
                    QRectF(self.mapWidget.coordinateToScreenPosition(topLeft.coordinate()),
                           self.mapWidget.coordinateToScreenPosition(bottomRight.coordinate()))
                )

        for obj in selectedObjects:
            obj.setSelected(True)

    def drawRect(self):
        if len(self.markerObjects) < 2:
            return

        p1, p2 = self.markerObjects[:2]

        pen = QPen(Qt.white)
        pen.setWidth(2)
        pen.setCosmetic(True)
        fill = QColor(Qt.black)
        fill.setAlpha(65)
        rectangle = QGeoMapRectangleObject(p1.coordinate(), p2.coordinate())
        rectangle.setPen(pen)
        rectangle.setBrush(QBrush(fill))
        self.mapWidget.addMapObject(rectangle)

    def drawPolyline(self):
        path = [mark.coordinate() for mark in self.markerObjects]

        pen = QPen(Qt.white)
        pen.setWidth(2)
        pen.setCosmetic(True)
        polyline = QGeoMapPolylineObject()
        polyline.setPen(pen)
        polyline.setPath(path)

        self.mapWidget.addMapObject(polyline)

    def drawPolygon(self):
        path = [mark.coordinate() for mark in self.markerObjects]

        pen = QPen(Qt.white)
        pen.setWidth(2)
        pen.setCosmetic(True)
        polygon = QGeoMapPolygonObject()
        polygon.setPen(pen)
        fill = QColor(Qt.black)
        fill.setAlpha(65)
        polygon.setBrush(QBrush(fill))
        polygon.setPath(path)

        self.mapWidget.addMapObject(polygon)

    def drawCircle(self):

        if not len(self.markerObjects):
            return

        p1 = self.markerObjects[0]
        center = p1.coordinate()

        radius = 3000 # Meters

        if len(self.markerObjects) >= 2:
            radius = center.distanceTo(self.markerObjects[1].coordinate())

        pen = QPen(Qt.white)
        pen.setWidth(2)
        pen.setCosmetic(True)
        circle = QGeoMapCircleObject(center, radius)
        circle.setPen(pen)
        fill = QColor(Qt.black)
        fill.setAlpha(65)
        circle.setBrush(QBrush(fill))

        self.mapWidget.addMapObject(circle)

    def drawText(self):

        if not len(self.markerObjects):
            return

        start = self.markerObjects[0].coordinate()

        text = QGeoMapTextObject(start, 'Text')

        fill = QColor(Qt.black)
        text.setBrush(fill)
        self.mapWidget.addMapObject(text)

    def calculateRoute(self):
        if len(self.markerObjects) < 2:
            return

        waypoints = [x.coordinate() for x in self.markerObjects[:2]]

        request = QGeoRouteRequest(waypoints)
        self.routeReply = self.routingManager.calculateRoute(request)
        self.routeReply.finished.connect(self.routeFinished)

    def routeFinished(self):

        if not self.routeReply.routes():
            return

        route = QGeoMapRouteObject(self.routeReply.routes()[0])
        routeColor = QColor(Qt.blue)
        routeColor.setAlpha(127)
        pen = QPen(routeColor)
        pen.setWidth(7)
        pen.setCosmetic(True)
        pen.setCapStyle(Qt.RoundCap)
        route.setPen(pen)
        self.mapWidget.addMapObject(route)

    def drawPixmap(self):
        marker = QGeoMapPixmapObject(self.mapWidget.screenPositionToCoordinate(self.lastClicked),
                                    QPoint(-(MARKER_WIDTH / 2), -MARKER_HEIGHT), self.markerIcon)
        self.mapWidget.addMapObject(marker)
        self.markerObjects.append(marker)

    def removePixmaps(self):
        for i in range(len(self.markerObjects)):
            marker = self.markerObjects.pop()

            self.mapWidget.removeMapObject(marker)
            marker.deleteLater()

    def customContextMenuRequest(self, point):
        self.lastClicked = point
        if self.focusWidget() == self.view:
            if not self.popupMenu:
                self.createMenus()

            self.popupMenu.popup(self.view.mapToGlobal(self.lastClicked))
示例#8
0
class MainWindow(QWidget, Ui_Form):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.appname = "poliBeePsync"
        self.settings_fname = 'pbs-settings.ini'
        self.data_fname = 'pbs.data'
        self.setupUi(self)
        self.w = QWidget()

        self.about_text()
        self.timer = QTimer(self)

        # settings_path is a string containing the path to settings
        self.settings_path = None
        # settings is a dictionary of settings
        self.settings = None
        # load_settings() sets settings_path and settings
        self.load_settings()
        self.load_data()

        self.timer.timeout.connect(self.syncfiles)
        self.timer.start(1000 * 60 * int(self.settings['UpdateEvery']))

        self.loginthread = LoginThread(self.user)
        self.loginthread.signal_error.sig.connect(self.myStream_message)
        self.loginthread.signal_error.sig.connect(self.loginstatus)
        self.loginthread.signal_ok.sig.connect(self.myStream_message)
        self.loginthread.signal_ok.sig.connect(self.loginstatus)

        self.refreshcoursesthread = RefreshCoursesThread(self.user)
        self.refreshcoursesthread.dumpuser.sig.connect(self.dumpUser)
        self.refreshcoursesthread.newcourses.sig.connect(self.addtocoursesview)
        self.refreshcoursesthread.newcourses.sig.connect(self.syncnewcourses)
        self.refreshcoursesthread.refreshed.sig.connect(self.myStream_message)
        self.refreshcoursesthread.removable.sig.connect(self.rmfromcoursesview)

        self.downloadthread = DownloadThread(self.user,
                                             self.settings['RootFolder'])
        self.downloadthread.download_signal.connect(
            self.update_course_download)
        #self.downloadthread.download_signal.connect(self._resizeview)
        self.downloadthread.initial_sizes.connect(self.setinizialsizes)
        self.downloadthread.data_signal.connect(self.update_file_localtime)

        self.userCode.setText(str(self.user.username))
        self.userCode.textEdited.connect(self.setusercode)
        self.password.setText(self.user.password)
        self.password.textEdited.connect(self.setpassword)
        self.trylogin.clicked.connect(self.testlogin)

        self.courses_model = CoursesListModel(self.user.available_courses)
        self.coursesView.setModel(self.courses_model)
        self._resizeview()
        self.refreshCourses.clicked.connect(self.refreshcourses)

        self.courses_model.dataChanged.connect(self.dumpUser)
        self.syncNow.clicked.connect(self.syncfiles)
        #self.pushButton.clicked.connect(self.syncfiles)
        #self.pushButton.clicked.connect(self.inittextincourses)

        if self.settings['SyncNewCourses'] == str(True):
            self.sync_new = Qt.Checked
        else:
            self.sync_new = Qt.Unchecked

        self.rootfolder.setText(self.settings['RootFolder'])
        self.rootfolder.textChanged.connect(self.rootfolderslot)

        self.addSyncNewCourses.setCheckState(self.sync_new)
        self.addSyncNewCourses.stateChanged.connect(self.syncnewslot)

        self.timerMinutes.setValue(int(self.settings['UpdateEvery']))
        self.timerMinutes.valueChanged.connect(self.updateminuteslot)

        self.changeRootFolder.clicked.connect(self.chooserootdir)
        #self.version_label.setText("Current version: {}.".format(__version__))
        #self.pushButton_2.clicked.connect(self.checknewversion)

        self.trayIconMenu = QMenu()
        self.trayIcon = QSystemTrayIcon(self.icon, self.w)
        self.trayIcon.activated.connect(self._activate_traymenu)
        self.createTray()

    def _resizeview(self, **kwargs):
        self.coursesView.setColumnWidth(3, 160)
        self.coursesView.resizeColumnToContents(1)
        self.coursesView.setColumnWidth(0, 320)

    def inittextincourses(self):
        self.statusLabel.setText('Started syncing.')

    def checknewversion(self):
        rawdata = requests.get(
            'https://pypi.python.org/pypi/poliBeePsync/json')
        latest = json.loads(rawdata.text)['info']['version']
        self.version_label.setTextFormat(Qt.RichText)
        self.version_label.setOpenExternalLinks(True)
        self.version_label.setLocale(
            QLocale(QLocale.English, QLocale.UnitedStates))
        self.version_label.setScaledContents(True)
        self.version_label.setWordWrap(True)
        if latest != __version__:
            newtext = """<p>Current version: {}.<br>
Latest version: {}. </p>
<p>Visit <a href='http://www.davideolianas.com/polibeepsync/index.html#how-to\
-install-upgrade-remove'>here</a> to find out how to upgrade.
""".format(__version__, latest)
        else:
            newtext = "Current version: {} up-to-date.".format(__version__)
        self.version_label.setText(newtext)

    def _update_time(self, folder, file, path_list):
        print('inside ', folder.name)
        print('path_list: ', path_list)
        while len(path_list) > 0:
            namegoto = path_list.pop(0)
            print('namegoto: ', namegoto)
            # perché a volte è vuoto?
            if namegoto != "":
                fakefolder = Folder(namegoto, 'fake')
                print('contained folders: ', folder.folders)
                ind = folder.folders.index(fakefolder)
                goto = folder.folders[ind]
                self._update_time(goto, file, path_list)
        if file in folder.files:
            ind = folder.files.index(file)
            thisfile = folder.files[ind]
            thisfile.local_creation_time = file.local_creation_time
            self.dumpUser()

    def update_file_localtime(self, data, **kwargs):
        course, coursefile, path = data
        rootpath = os.path.join(self.settings['RootFolder'],
                                course.save_folder_name)
        if path.startswith(rootpath):
            partial = path[len(rootpath):]
        path_list = partial.split(os.path.sep)
        self._update_time(course.documents, coursefile, path_list)

    def update_course_download(self, course, **kwargs):
        logger.info('download size updated')
        if course in self.user.available_courses:
            updating = self.user.available_courses[course.name]
            updating.downloaded_size = course.downloaded_size
            row = self.courses_model.courses.index(updating)
            where = self.courses_model.index(row, 3)
            self.courses_model.dataChanged.emit(where, where)
            self.dumpUser()

    def setinizialsizes(self, course, **kwargs):
        if course in self.user.available_courses:
            updating = self.user.available_courses[course.name]
            updating.downloaded_size = course.downloaded_size
            updating.total_file_size = course.total_file_size
            row = self.courses_model.courses.index(updating)
            where = self.courses_model.index(row, 3)
            self.courses_model.dataChanged.emit(where, where)
            self.dumpUser()

    def syncnewcourses(self, newlist):
        if self.settings['SyncNewCourses'] == 'True':
            for elem in newlist:
                elem.sync = True

    def load_settings(self):
        for path in [
                user_config_dir(self.appname),
                user_data_dir(self.appname)
        ]:
            try:
                os.makedirs(path, exist_ok=True)
            except OSError:
                logger.critical('OSError while calling os.makedirs.',
                                exc_info=True)
                self.myStream_message("I couldn't create {}.\nStart"
                                      " poliBeePsync with --debug "
                                      "error to get more details.")
        self.settings_path = os.path.join(user_config_dir(self.appname),
                                          self.settings_fname)
        defaults = {
            'UpdateEvery': '60',
            'RootFolder': os.path.join(os.path.expanduser('~'), self.appname),
            'SyncNewCourses': 'False'
        }
        self.settings = filesettings.settingsFromFile(self.settings_path,
                                                      defaults)

    def load_data(self):
        try:
            with open(
                    os.path.join(user_data_dir(self.appname), self.data_fname),
                    'rb') as f:
                self.user = pickle.load(f)
                self.myStream_message("Data has been loaded successfully.")

        except FileNotFoundError:
            logger.error('Settings file not found.', exc_info=True)
            self.user = User('', '')
            self.myStream_message("I couldn't find data in the"
                                  " predefined directory. Ignore this"
                                  "message if you're using poliBeePsync"
                                  " for the first time.")

    def loginstatus(self, status):
        self.login_attempt.setText(status)

    # @Slot(int)
    # def notifynew(self, state):
    # if state == 2:
    # self.settings['NotifyNewCourses'] = 'True'
    # else:
    # self.settings['NotifyNewCourses'] = 'False'
    #    filesettings.settingsToFile(self.settings, self.settings_path)

    @Slot(int)
    def syncnewslot(self, state):
        if state == 2:
            self.settings['SyncNewCourses'] = 'True'
        else:
            self.settings['SyncNewCourses'] = 'False'
        filesettings.settingsToFile(self.settings, self.settings_path)

    @Slot(int)
    def updateminuteslot(self, minutes):
        self.settings['UpdateEvery'] = str(minutes)
        filesettings.settingsToFile(self.settings, self.settings_path)
        self.timer.start(1000 * 60 * int(self.settings['UpdateEvery']))

    @Slot(str)
    def rootfolderslot(self, path):
        self.settings['RootFolder'] = path
        filesettings.settingsToFile(self.settings, self.settings_path)

    def chooserootdir(self):
        currentdir = self.settings['RootFolder']
        flags = QFileDialog.DontResolveSymlinks | QFileDialog.ShowDirsOnly
        newroot = QFileDialog.getExistingDirectory(None, "Open Directory",
                                                   currentdir, flags)
        if newroot != "" and str(newroot) != currentdir:
            self.settings['RootFolder'] = str(newroot)
            filesettings.settingsToFile(self.settings, self.settings_path)
            self.rootfolder.setText(newroot)
            # we delete the already present downloadthread and recreate it
            # because otherwise it uses the old download folder. I don't know
            # if there's a cleaner approach
            del self.downloadthread
            self.downloadthread = DownloadThread(self.user,
                                                 self.settings['RootFolder'])
            self.downloadthread.dumpuser.sig.connect(self.dumpUser)
            self.downloadthread.course_finished.sig.connect(
                self.myStream_message)
            self.downloadthread.signal_error.sig.connect(self.myStream_message)

    def setusercode(self):
        newcode = self.userCode.text()
        self.user.username = newcode
        try:
            self.dumpUser()
            if len(newcode) == 8:
                self.myStream_message(
                    "User code changed to {}.".format(newcode))
        except OSError:
            self.myStream_message("I couldn't save data to disk. Run"
                                  " poliBeePsync with option --debug"
                                  " error to get more details.")
            logger.error(
                'OSError raised while trying to write the User'
                'instance to disk.',
                exc_info=True)

    def setpassword(self):
        newpass = self.password.text()
        self.user.password = newpass
        try:
            self.dumpUser()
            self.myStream_message("Password changed.")
        except OSError:
            self.myStream_message("I couldn't save data to disk. Run"
                                  " poliBeePsync with option --debug"
                                  " error to get more details.")
            logger.error(
                'OSError raised while trying to write the User'
                'instance to disk.',
                exc_info=True)

    def testlogin(self):
        if not self.loginthread.isRunning():
            self.loginthread.exiting = False
            self.loginthread.start()
            self.login_attempt.setStyleSheet("color: rgba(0, 0, 0, 255);")
            self.login_attempt.setText("Logging in, please wait.")

    def addtocoursesview(self, addlist):
        for elem in addlist:
            self.courses_model.insertRows(0, 1, elem)

    def rmfromcoursesview(self, removelist):
        for elem in removelist:
            index = self.courses_model.courses.index(elem)
            self.courses_model.removeRows(index, 1)

    def dumpUser(self):
        # we don't use the message...
        with open(os.path.join(user_data_dir(self.appname), self.data_fname),
                  'wb') as f:
            pickle.dump(self.user, f)

    def refreshcourses(self):
        self.statusLabel.setText(
            'Searching for online updates...this may take a'
            ' while.')
        if not self.loginthread.isRunning():
            self.loginthread.exiting = False
            self.loginthread.signal_ok.sig.connect(self.do_refreshcourses)
            self.loginthread.start()

    def do_refreshcourses(self):
        self.loginthread.signal_ok.sig.disconnect(self.do_refreshcourses)
        if not self.refreshcoursesthread.isRunning():
            self.refreshcoursesthread.exiting = False
            self.refreshcoursesthread.start()

    @Slot()
    def syncfiles(self):
        self.refreshcoursesthread.finished.connect(self.do_syncfiles)
        self.refreshcourses()

    def do_syncfiles(self):
        self.refreshcoursesthread.finished.disconnect(self.do_syncfiles)
        self.inittextincourses()
        self.downloadthread.start()

    @Slot(str)
    def myStream_message(self, message):
        self.status.moveCursor(QTextCursor.End)
        self.status.insertPlainText(message + "\n\n")

    def createTray(self):
        restoreAction = QAction("&Restore", self, triggered=self.showNormal)
        quitAction = QAction("&Quit", self, triggered=qApp.quit)
        self.trayIconMenu.addAction(restoreAction)
        self.trayIconMenu.addAction(quitAction)
        self.trayIcon.setContextMenu(self.trayIconMenu)
        self.trayIcon.show()

    def _activate_traymenu(self, reason):
        if reason == QSystemTrayIcon.ActivationReason.Trigger:
            self.showNormal()
        else:
            self.trayIconMenu.activateWindow()
            self.trayIconMenu.popup(QCursor.pos())

    def closeEvent(self, event):
        self.hide()
        event.ignore()

    def about_text(self):
        self.label_3 = QLabel()
        self.label_3.setTextFormat(Qt.RichText)
        self.label_3.setOpenExternalLinks(True)
        self.label_3.setLocale(QLocale(QLocale.English, QLocale.UnitedStates))
        self.label_3.setScaledContents(True)
        self.label_3.setWordWrap(True)
        text = """
<html>
<head/>
<body>
  <p>poliBeePsync is a program written by Davide Olianas,
released under GNU GPLv3+.</p>
  <p>Feel free to contact me at <a
  href=\"mailto:[email protected]\">[email protected]</a> for
  suggestions and bug reports.</p>
  <p>More information is available on the
  <a href=\"http://www.davideolianas.com/polibeepsync\">
  <span style=\" text-decoration: underline; color:#0000ff;\">
  official website</span></a>.
  </p>
</body>
</html>
"""

        if pysideVersion == '1.2.2':
            self.label_3.setText(
                QApplication.translate("Form", text, None,
                                       QApplication.UnicodeUTF8))
        else:
            self.label_3.setText(QApplication.translate("Form", text, None))
示例#9
0
class Indicator(QSystemTrayIcon):
    def __init__(self, *args, **kwargs):
        QSystemTrayIcon.__init__(self, *args, **kwargs)
        self.app = QApplication.instance()
        self.menu = QMenu()
        self.setContextMenu(self.menu)
        self.menu.aboutToShow.connect(self.update)
        self.opened_notes = {}
        self.activated.connect(self._activated)

    def _activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.menu.popup(QCursor().pos())

    def _add_note(self, struct):
        note = Note.from_tuple(struct)
        title = note.title[:40].replace("&", "&&")
        self.menu.addAction(title, Slot()(partial(self.open, note=note)))

    @Slot()
    def update(self):
        self.menu.clear()
        try:
            version = self.app.provider.get_api_version()
        except (dbus.exceptions.UnknownMethodException, dbus.exceptions.DBusException):  # dbus raise some magic
            version = -1
        if version != API_VERSION:
            action = self.menu.addAction(self.tr("API version missmatch, please restart"))
            action.setEnabled(False)
            if version < API_VERSION:
                handler = self.app.provider.kill
            else:
                handler = partial(os.execlp, "everpad", "--replace")
            self.menu.addAction(self.tr("Restart everpad"), handler)
            return
        if get_auth_token():
            pin_notes = self.app.provider.find_notes(
                "", dbus.Array([], signature="i"), dbus.Array([], signature="i"), 0, 20, Note.ORDER_UPDATED_DESC, 1
            )
            notes = self.app.provider.find_notes(
                "",
                dbus.Array([], signature="i"),
                dbus.Array([], signature="i"),
                0,
                20 - len(pin_notes),
                Note.ORDER_UPDATED_DESC,
                0,
            )
            if len(notes) + len(pin_notes) or self.app.provider.is_first_synced():
                self.menu.addAction(self.tr("All Notes"), self.show_all_notes)
                self.menu.addSeparator()
                if len(pin_notes):
                    for struct in pin_notes:
                        self._add_note(struct)
                    self.menu.addSeparator()
                for struct in notes:
                    self._add_note(struct)
                self.menu.addSeparator()
                self.menu.addAction(self.tr("Create Note"), self.create)
                first_sync = False
            else:
                first_sync = True
            if self.app.provider.get_status() == STATUS_SYNC:
                action = self.menu.addAction(
                    self.tr("Wait, first sync in progress") if first_sync else self.tr("Sync in progress")
                )
                action.setEnabled(False)
            else:
                if first_sync:
                    label = self.tr("Please perform first sync")
                else:
                    last_sync = self.app.provider.get_last_sync()
                    delta_sync = (datetime.now() - datetime.strptime(last_sync, "%H:%M")).seconds // 60
                    if delta_sync == 0:
                        label = self.tr("Last Sync: Just now")
                    elif delta_sync == 1:
                        label = self.tr("Last Sync: %s min ago") % delta_sync
                    else:
                        label = self.tr("Last Sync: %s mins ago") % delta_sync
                self.menu.addAction(label, Slot()(self.app.provider.sync))
        self.menu.addAction(self.tr("Settings and Management"), self.show_management)
        self.menu.addSeparator()
        self.menu.addAction(self.tr("Exit"), self.exit)

    def open(self, note, search_term=""):
        old_note_window = self.opened_notes.get(note.id, None)
        if old_note_window and not getattr(old_note_window, "closed", True):
            editor = self.opened_notes[note.id]
            editor.activateWindow()
        else:
            editor = Editor(note)
            editor.show()
            self.opened_notes[note.id] = editor
        if search_term:
            editor.findbar.set_search_term(search_term)
            editor.findbar.show()
        return editor

    @Slot()
    def create(self, attach=None, notebook_id=NONE_ID):
        note_struct = Note(  # maybe replace NONE's to somthing better
            id=NONE_ID,
            title=self.tr("New note"),
            content=self.tr("New note content"),
            tags=dbus.Array([], signature="i"),
            notebook=notebook_id,
            created=NONE_VAL,
            updated=NONE_VAL,
            conflict_parent=NONE_VAL,
            conflict_items=dbus.Array([], signature="i"),
            place="",
        ).struct
        note = Note.from_tuple(self.app.provider.create_note(note_struct))
        editor = self.open(note)
        if attach:
            editor.resource_edit.add_attach(attach)

    @Slot()
    def show_all_notes(self):
        if not hasattr(self, "list") or getattr(self.list, "closed", True):
            self.list = List()
            self.list.show()
        else:
            self.list.activateWindow()

    @Slot()
    def show_management(self):
        if not hasattr(self, "management") or getattr(self.management, "closed", True):
            self.management = Management()
            self.management.show()
        else:
            self.management.activateWindow()

    @Slot()
    def exit(self):
        self.app.quit()
示例#10
0
class Indicator(QSystemTrayIcon):
    def __init__(self, *args, **kwargs):
        QSystemTrayIcon.__init__(self, *args, **kwargs)
        self.app = QApplication.instance()
        self.menu = QMenu()
        self.setContextMenu(self.menu)
        self.menu.aboutToShow.connect(self.update)
        self.opened_notes = {}
        self.activated.connect(self._activated)
        self.settings = QSettings('everpad', 'everpad-pad')
        # Configure logger.
        self.logger = logging.getLogger('everpad-indicator')
        self.logger.setLevel(logging.DEBUG)
        fh = logging.FileHandler(
            os.path.expanduser('~/.everpad/logs/everpad.log'))
        fh.setLevel(logging.DEBUG)
        formatter = logging.Formatter(
            '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        fh.setFormatter(formatter)
        self.logger.addHandler(fh)

    def _activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.menu.popup(QCursor().pos())

    def _add_note(self, menu, struct):
        note = Note.from_tuple(struct)
        title = note.title[:40].replace('&', '&&')
        menu.addAction(title, Slot()(partial(self.open, note=note)))

    @Slot()
    def update(self):
        self.menu.clear()
        try:
            version = self.app.provider.get_api_version()
        except (  # dbus raise some magic
                dbus.exceptions.UnknownMethodException,
                dbus.exceptions.DBusException,
        ):
            version = -1
        if version != API_VERSION:
            action = self.menu.addAction(
                self.tr('API version missmatch, please restart'), )
            action.setEnabled(False)
            if version < API_VERSION:
                handler = self.app.provider.kill
            else:
                handler = partial(os.execlp, 'everpad', '--replace')
            self.menu.addAction(
                self.tr('Restart everpad'),
                handler,
            )
            return
        if self.app.provider.is_authenticated():
            pin_notes = self.app.provider.find_notes(
                '',
                dbus.Array([], signature='i'),
                dbus.Array([], signature='i'),
                0,
                20,
                Note.ORDER_UPDATED_DESC,
                1,
            )
            sort_by_notebook = bool(
                int(
                    self.app.provider.get_settings_value('sort-by-notebook')
                    or 0))
            has_notes = False
            if not sort_by_notebook:
                notes = self.app.provider.find_notes(
                    '',
                    dbus.Array([], signature='i'),
                    dbus.Array([], signature='i'),
                    0,
                    20 - len(pin_notes),
                    Note.ORDER_UPDATED_DESC,
                    0,
                )
                has_notes = bool(notes)
            else:
                notebooks = self.app.provider.list_notebooks()
                notes = {}
                for notebook_struct in notebooks:
                    notebook = Notebook.from_tuple(notebook_struct)
                    _notes = self.app.provider.find_notes(
                        '',
                        [notebook.id],
                        dbus.Array([], signature='i'),
                        0,
                        20 - len(pin_notes),
                        Note.ORDER_UPDATED_DESC,
                        0,
                    )
                    notes[notebook] = _notes
                    if _notes:
                        has_notes = True
            first_sync = not (has_notes or len(pin_notes)
                              or self.app.provider.is_first_synced())

            # Rate Limit indication added
            # STATUS_RATE = -1  # Rate Limit status
            # STATUS_NONE = 0
            # STATUS_SYNC = 1
            # status_syncing = self.app.provider.get_status() == STATUS_SYNC
            status_syncing = self.app.provider.get_status()

            if status_syncing < 0:
                sync_label = self.tr('Rate Limit')
            elif status_syncing and first_sync:
                sync_label = self.tr('Wait, first sync in progress')
            elif status_syncing and not first_sync:
                sync_label = self.tr('Sync in progress')
            elif not status_syncing and first_sync:
                sync_label = self.tr('Please perform first sync')
            else:
                last_sync = self.app.provider.get_last_sync()
                delta_sync = (datetime.now() - datetime.strptime(
                    last_sync, '%H:%M')).seconds // 60
                if delta_sync == 0:
                    sync_label = self.tr('Last Sync: Just now')
                elif delta_sync == 1:
                    sync_label = self.tr('Last Sync: %s min ago') % delta_sync
                else:
                    sync_label = self.tr('Last Sync: %s mins ago') % delta_sync

            menu_items = {
                'create_note': [self.tr('Create Note'), self.create],
                'all_notes': [self.tr('All Notes'), self.show_all_notes],
                'sync': [sync_label,
                         Slot()(self.app.provider.sync)],
                'pin_notes': pin_notes,
                'notes': notes,
            }
            for item in self.app.settings.value('menu-order',
                                                DEFAULT_INDICATOR_LAYOUT):
                if item == 'pin_notes' or item == 'notes':
                    if not first_sync and len(menu_items[item]):
                        self.menu.addSeparator()
                        if item == 'notes' and sort_by_notebook:
                            for notebook in menu_items[item]:
                                sub_menu = self.menu.addMenu(notebook.name)
                                _notes = menu_items[item][notebook]
                                for struct in _notes:
                                    self._add_note(sub_menu, struct)
                        else:
                            for struct in menu_items[item]:
                                self._add_note(self.menu, struct)
                        self.menu.addSeparator()
                else:
                    action = self.menu.addAction(menu_items[item][0],
                                                 menu_items[item][1])
                    if status_syncing and item == 'sync':
                        action.setEnabled(False)
        self.menu.addSeparator()
        self.menu.addAction(self.tr('Settings and Management'),
                            self.show_management)
        self.menu.addAction(self.tr('Exit'), self.exit)

    def open(self, note, search_term=''):
        self.logger.debug('Opening note: "%s".' % note.title)
        old_note_window = self.opened_notes.get(note.id, None)
        if old_note_window and not getattr(old_note_window, 'closed', True):
            editor = self.opened_notes[note.id]
            # hide and show for bringing to front
            editor.hide()
            editor.show()
        else:
            editor = Editor(note)
            editor.show()
            self.opened_notes[note.id] = editor
        if search_term:
            editor.findbar.set_search_term(search_term)
            editor.findbar.show()
        editor.raise_()
        editor.activateWindow()
        return editor

    @Slot()
    def create(self, attach=None, notebook_id=NONE_ID):
        self.logger.debug('Creating new note.')
        note_struct = Note(  # maybe replace NONE's to somthing better
            id=NONE_ID,
            title=self.tr('New note'),
            content=self.tr("New note content"),
            tags=dbus.Array([], signature='i'),
            notebook=notebook_id,
            created=NONE_VAL,
            updated=NONE_VAL,
            conflict_parent=NONE_VAL,
            conflict_items=dbus.Array([], signature='i'),
            place='',
            share_date=NONE_VAL,
            share_url='',
        ).struct
        note = Note.from_tuple(self.app.provider.create_note(note_struct), )
        editor = self.open(note)
        if attach:
            editor.resource_edit.add_all_attach(attach)

    @Slot()
    def show_all_notes(self):
        if not hasattr(self, 'list') or getattr(self.list, 'closed', True):
            self.list = List()
            self.list.show()
        else:
            self.list.activateWindow()

    @Slot()
    def show_management(self):
        if not hasattr(self, 'management') or getattr(self.management,
                                                      'closed', True):
            self.management = Management()
            self.management.show()
        else:
            self.management.activateWindow()

    @Slot()
    def exit(self):
        self.app.quit()
示例#11
0
class Indicator(QSystemTrayIcon):
    def __init__(self, *args, **kwargs):
        QSystemTrayIcon.__init__(self, *args, **kwargs)
        self.app = QApplication.instance()
        self.menu = QMenu()
        self.setContextMenu(self.menu)
        self.menu.aboutToShow.connect(self.update)
        self.opened_notes = {}
        self.activated.connect(self._activated)
        self.settings = QSettings('everpad', 'everpad-pad')

    def _activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.menu.popup(QCursor().pos())

    def _add_note(self, menu, struct):
        note = Note.from_tuple(struct)
        title = note.title[:40].replace('&', '&&')
        menu.addAction(title, Slot()(
            partial(self.open, note=note)
        ))

    @Slot()
    def update(self):
        self.menu.clear()
        try:
            version = self.app.provider.get_api_version()
        except (  # dbus raise some magic
            dbus.exceptions.UnknownMethodException,
            dbus.exceptions.DBusException,
        ):
            version = -1
        if version != API_VERSION:
            action = self.menu.addAction(
                self.tr('API version missmatch, please restart'),
            )
            action.setEnabled(False)
            if version < API_VERSION:
                handler = self.app.provider.kill
            else:
                handler = partial(os.execlp, 'everpad', '--replace')
            self.menu.addAction(
                self.tr('Restart everpad'), handler,
            )
            return
        if self.app.provider.is_authenticated():
            pin_notes = self.app.provider.find_notes(
                '', dbus.Array([], signature='i'),
                dbus.Array([], signature='i'), 0,
                20, Note.ORDER_UPDATED_DESC, 1,
            )
            sort_by_notebook = bool(int(
                self.app.provider.get_settings_value('sort-by-notebook') or 0))
            has_notes = False
            if not sort_by_notebook:
                notes = self.app.provider.find_notes(
                    '', dbus.Array([], signature='i'),
                    dbus.Array([], signature='i'), 0,
                    20 - len(pin_notes), Note.ORDER_UPDATED_DESC, 0,
                )
                has_notes = bool(notes)
            else:
                notebooks = self.app.provider.list_notebooks()
                notes = {}
                for notebook_struct in notebooks:
                    notebook = Notebook.from_tuple(notebook_struct)
                    _notes = self.app.provider.find_notes('', [notebook.id],
                         dbus.Array([], signature='i'), 0,
                         20 - len(pin_notes), Note.ORDER_UPDATED_DESC, 0,
                    )
                    notes[notebook] = _notes
                    if _notes:
                        has_notes = True
            first_sync = not (
                has_notes or len(pin_notes) or self.app.provider.is_first_synced()
            )
            status_syncing = self.app.provider.get_status() == STATUS_SYNC
            if status_syncing and first_sync:
                sync_label = self.tr('Wait, first sync in progress')
            elif status_syncing and not first_sync:
                sync_label = self.tr('Sync in progress')
            elif not status_syncing and first_sync:
                sync_label = self.tr('Please perform first sync')
            else:
                last_sync = self.app.provider.get_last_sync()
                delta_sync = (
                    datetime.now() - datetime.strptime(last_sync, '%H:%M')
                ).seconds // 60
                if delta_sync == 0:
                    sync_label = self.tr('Last Sync: Just now')
                elif delta_sync == 1:
                    sync_label = self.tr('Last Sync: %s min ago') % delta_sync
                else:
                    sync_label = self.tr('Last Sync: %s mins ago') % delta_sync
            menu_items = {
                'create_note': [self.tr('Create Note'), self.create],
                'all_notes': [self.tr('All Notes'), self.show_all_notes],
                'sync': [sync_label, Slot()(self.app.provider.sync)],
                'pin_notes': pin_notes,
                'notes': notes,
            }
            for item in self.app.settings.value('menu-order', DEFAULT_INDICATOR_LAYOUT):
                if item == 'pin_notes' or item == 'notes':
                    if not first_sync and len(menu_items[item]):
                        self.menu.addSeparator()
                        if item == 'notes' and sort_by_notebook:
                            for notebook in menu_items[item]:
                                sub_menu = self.menu.addMenu(notebook.name)
                                _notes = menu_items[item][notebook]
                                for struct in _notes:
                                    self._add_note(sub_menu, struct)
                        else:
                            for struct in menu_items[item]:
                                self._add_note(self.menu, struct)
                        self.menu.addSeparator()
                else:
                    action = self.menu.addAction(menu_items[item][0], menu_items[item][1])
                    if status_syncing and item == 'sync':
                        action.setEnabled(False)
        self.menu.addSeparator()
        self.menu.addAction(self.tr('Settings and Management'), self.show_management)
        self.menu.addAction(self.tr('Exit'), self.exit)

    def open(self, note, search_term=''):
        old_note_window = self.opened_notes.get(note.id, None)
        if old_note_window and not getattr(old_note_window, 'closed', True):
            editor = self.opened_notes[note.id]
            # hide and show for bringing to front
            editor.hide()
            editor.show()
        else:
            editor = Editor(note)
            editor.show()
            self.opened_notes[note.id] = editor
        if search_term:
            editor.findbar.set_search_term(search_term)
            editor.findbar.show()
        editor.raise_()
        editor.activateWindow()
        return editor

    @Slot()
    def create(self, attach=None, notebook_id=NONE_ID):
        note_struct = Note(  # maybe replace NONE's to somthing better
            id=NONE_ID,
            title=self.tr('New note'),
            content=self.tr("New note content"),
            tags=dbus.Array([], signature='i'),
            notebook=notebook_id,
            created=NONE_VAL,
            updated=NONE_VAL,
            conflict_parent=NONE_VAL,
            conflict_items=dbus.Array([], signature='i'),
            place='',
            share_date=NONE_VAL,
            share_url='',
        ).struct
        note = Note.from_tuple(
            self.app.provider.create_note(note_struct),
        )
        editor = self.open(note)
        if attach:
            editor.resource_edit.add_all_attach(attach)

    @Slot()
    def show_all_notes(self):
        if not hasattr(self, 'list') or getattr(self.list, 'closed', True):
            self.list = List()
            self.list.show()
        else:
            self.list.activateWindow()

    @Slot()
    def show_management(self):
        if not hasattr(self, 'management') or getattr(self.management, 'closed', True):
            self.management = Management()
            self.management.show()
        else:
            self.management.activateWindow()

    @Slot()
    def exit(self):
        self.app.quit()
示例#12
0
class Indicator(QSystemTrayIcon):
    def __init__(self, app, *args, **kwargs):
        QSystemTrayIcon.__init__(self, *args, **kwargs)
        self.app = app
        self.menu = QMenu()
        self.setContextMenu(self.menu)
        self.menu.aboutToShow.connect(self.update)
        self.opened_notes = {}
        self.activated.connect(self._activated)

    def _activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.menu.popup(QCursor().pos())

    def _add_note(self, struct):
        note = Note.from_tuple(struct)
        title = note.title[:40].replace('&', '&&')
        self.menu.addAction(title, Slot()(partial(self.open, note=note)))

    @Slot()
    def kill_all(self):
        try:
            self.app.provider.kill()
        except dbus.exceptions.DBusException:
            pass
        os.system('everpad --replace')

    @Slot()
    def update(self):
        self.menu.clear()
        try:
            version = self.app.provider.get_api_version()
        except (  # dbus raise some magic
                dbus.exceptions.UnknownMethodException,
                dbus.exceptions.DBusException,
        ):
            version = -1
        if version != API_VERSION:
            action = self.menu.addAction(
                self.tr('API version missmatch, please restart'), )
            action.setEnabled(False)
            self.menu.addAction(
                self.tr('Restart everpad'),
                self.kill_all,
            )
            return
        if get_auth_token():
            pin_notes = self.app.provider.find_notes(
                '',
                dbus.Array([], signature='i'),
                dbus.Array([], signature='i'),
                0,
                20,
                Note.ORDER_UPDATED_DESC,
                1,
            )
            notes = self.app.provider.find_notes(
                '',
                dbus.Array([], signature='i'),
                dbus.Array([], signature='i'),
                0,
                20 - len(pin_notes),
                Note.ORDER_UPDATED_DESC,
                0,
            )
            if len(notes) + len(
                    pin_notes) or self.app.provider.is_first_synced():
                self.menu.addAction(self.tr('All Notes'), self.show_all_notes)
                self.menu.addSeparator()
                if len(pin_notes):
                    for struct in pin_notes:
                        self._add_note(struct)
                    self.menu.addSeparator()
                for struct in notes:
                    self._add_note(struct)
                self.menu.addSeparator()
                self.menu.addAction(self.tr('Create Note'), self.create)
                first_sync = False
            else:
                first_sync = True
            if self.app.provider.get_status() == STATUS_SYNC:
                action = self.menu.addAction(
                    self.tr('Wait, first sync in progress'
                            ) if first_sync else self.tr('Sync in progress'))
                action.setEnabled(False)
            else:
                if first_sync:
                    label = self.tr('Please perform first sync')
                else:
                    label = self.tr(
                        'Last sync: %s') % self.app.provider.get_last_sync()
                self.menu.addAction(label, Slot()(self.app.provider.sync))
        self.menu.addAction(self.tr('Settings and Management'),
                            self.show_management)
        self.menu.addSeparator()
        self.menu.addAction(self.tr('Exit'), self.exit)

    def open(self, note, search_term=''):
        old_note_window = self.opened_notes.get(note.id, None)
        if old_note_window and not getattr(old_note_window, 'closed', True):
            editor = self.opened_notes[note.id]
            editor.activateWindow()
        else:
            editor = Editor(self.app, note)
            editor.show()
            self.opened_notes[note.id] = editor
        if search_term:
            editor.findbar.set_search_term(search_term)
            editor.findbar.show()
        return editor

    @Slot()
    def create(self, attach=None, notebook_id=NONE_ID):
        note_struct = Note(  # maybe replace NONE's to somthing better
            id=NONE_ID,
            title=self.tr('New note'),
            content=self.tr("New note content"),
            tags=dbus.Array([], signature='i'),
            notebook=notebook_id,
            created=NONE_VAL,
            updated=NONE_VAL,
            place='',
        ).struct
        note = Note.from_tuple(self.app.provider.create_note(note_struct), )
        editor = self.open(note)
        if attach:
            editor.resource_edit.add_attach(attach)

    @Slot()
    def show_all_notes(self):
        if not hasattr(self, 'list') or getattr(self.list, 'closed', True):
            self.list = List(self.app)
            self.list.show()
        else:
            self.list.activateWindow()

    @Slot()
    def show_management(self):
        if not hasattr(self, 'management') or getattr(self.management,
                                                      'closed', True):
            self.management = Management(self.app)
            self.management.show()
        else:
            self.management.activateWindow()

    @Slot()
    def exit(self):
        sys.exit(0)
示例#13
0
class Indicator(QSystemTrayIcon):
    def __init__(self, app, *args, **kwargs):
        QSystemTrayIcon.__init__(self, *args, **kwargs)
        self.app = app
        self.menu = QMenu()
        self.setContextMenu(self.menu)
        self.menu.aboutToShow.connect(self.update)
        self.opened_notes = {}
        self.activated.connect(self._activated)

    def _activated(self, reason):
        if reason == QSystemTrayIcon.Trigger:
            self.menu.popup(QCursor().pos())

    def _add_note(self, struct):
        note = Note.from_tuple(struct)
        title = note.title[:40].replace('&', '&&')
        self.menu.addAction(title, Slot()(
            partial(self.open, note=note)
        ))

    @Slot()
    def kill_all(self):
        try:
            self.app.provider.kill()
        except dbus.exceptions.DBusException:
            pass
        os.system('everpad --replace')

    @Slot()
    def update(self):
        self.menu.clear()
        try:
            version = self.app.provider.get_api_version()
        except (  # dbus raise some magic
            dbus.exceptions.UnknownMethodException,
            dbus.exceptions.DBusException,
        ):
            version = -1
        if version != API_VERSION:
            action = self.menu.addAction(
                self.tr('API version missmatch, please restart'),
            )
            action.setEnabled(False)
            self.menu.addAction(
                self.tr('Restart everpad'), self.kill_all,
            )
            return
        if get_auth_token():
            pin_notes = self.app.provider.find_notes(
                '', dbus.Array([], signature='i'),
                dbus.Array([], signature='i'), 0,
                20, Note.ORDER_UPDATED_DESC, 1,
            )
            notes = self.app.provider.find_notes(
                '', dbus.Array([], signature='i'),
                dbus.Array([], signature='i'), 0,
                20 - len(pin_notes), Note.ORDER_UPDATED_DESC, 0,
            )
            if len(notes) + len(pin_notes) or self.app.provider.is_first_synced():
                self.menu.addAction(self.tr('All Notes'), self.show_all_notes)
                self.menu.addSeparator()
                if len(pin_notes):
                    for struct in pin_notes:
                        self._add_note(struct)
                    self.menu.addSeparator()
                for struct in notes:
                    self._add_note(struct)
                self.menu.addSeparator()
                self.menu.addAction(self.tr('Create Note'), self.create)
                first_sync = False
            else:
                first_sync = True
            if self.app.provider.get_status() == STATUS_SYNC:
                action = self.menu.addAction(
                    self.tr('Wait, first sync in progress') if first_sync
                    else self.tr('Sync in progress')
                )
                action.setEnabled(False)
            else:
                if first_sync:
                    label = self.tr('Please perform first sync')
                else:
                    label = self.tr('Last sync: %s') % self.app.provider.get_last_sync()
                self.menu.addAction(label, Slot()(self.app.provider.sync))
        self.menu.addAction(self.tr('Settings and Management'), self.show_management)
        self.menu.addSeparator()
        self.menu.addAction(self.tr('Exit'), self.exit)

    def open(self, note, search_term=''):
        old_note_window = self.opened_notes.get(note.id, None)
        if old_note_window and not getattr(old_note_window, 'closed', True):
            editor = self.opened_notes[note.id]
            editor.activateWindow()
        else:
            editor = Editor(self.app, note)
            editor.show()
            self.opened_notes[note.id] = editor
        if search_term:
            editor.findbar.set_search_term(search_term)
            editor.findbar.show()
        return editor

    @Slot()
    def create(self, attach=None, notebook_id=NONE_ID):
        note_struct = Note(  # maybe replace NONE's to somthing better
            id=NONE_ID,
            title=self.tr('New note'),
            content=self.tr("New note content"),
            tags=dbus.Array([], signature='i'),
            notebook=notebook_id,
            created=NONE_VAL,
            updated=NONE_VAL,
            place='',
        ).struct
        note = Note.from_tuple(
            self.app.provider.create_note(note_struct),
        )
        editor = self.open(note)
        if attach:
            editor.resource_edit.add_attach(attach)

    @Slot()
    def show_all_notes(self):
        if not hasattr(self, 'list') or getattr(self.list, 'closed', True):
            self.list = List(self.app)
            self.list.show()
        else:
            self.list.activateWindow()

    @Slot()
    def show_management(self):
        if not hasattr(self, 'management') or getattr(self.management, 'closed', True):
            self.management = Management(self.app)
            self.management.show()
        else:
            self.management.activateWindow()

    @Slot()
    def exit(self):
        sys.exit(0)