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:`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")
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))
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))
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()
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()
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()
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)
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)