def triggered(self, cause, store): enum = Connector().enum() mounted = set([s.label for s in enum.regularStores()]) for s in self.__mounted - mounted: self.__trayIcon.showMessage("Unmount", "Store '" + s + "' has been unmounted") for s in mounted - self.__mounted: self.__trayIcon.showMessage("Mount", "Store '" + s + "' has been mounted") self.__mounted = mounted
def triggered(self, cause, store): enum = Connector().enum() mounted = set([s.label for s in enum.regularStores()]) for s in (self.__mounted - mounted): self.__trayIcon.showMessage("Unmount", "Store '"+s+"' has been unmounted") for s in (mounted - self.__mounted): self.__trayIcon.showMessage("Mount", "Store '"+s+"' has been mounted") self.__mounted = mounted
def __init__(self): self.sysStore = Connector().enum().sysStore().sid self.syncDoc = struct.Folder(DocLink(self.sysStore, self.sysStore))["syncrules"].doc() self.syncRev = Connector().lookupDoc(self.syncDoc).rev(self.sysStore) with Connector().peek(self.sysStore, self.syncRev) as r: rules = r.getData('/org.peerdrive.syncrules') self.__changed = False self.__rules = {} for rule in rules: self.__rules[(rule['from'].decode('hex'), rule['to'].decode('hex'))] = rule
def __fillMenu(self, menu, menuLink, store=None): menu.clear() c = struct.Folder(menuLink) listing = [] for (title, link) in c.items(): link.update() try: type = Connector().stat(link.rev()).type() except IOError: type = None if not type: continue if len(title) > 40: title = title[:40] + '...' listing.append((title, link, Registry().conformes(type, "org.peerdrive.folder"), QtGui.QIcon(Registry().getIcon(type)))) listing = sorted(listing, cmp=Launchbox.__cmp) for (title, link, folder, icon) in listing: if folder: m = menu.addMenu(icon, title) m.aboutToShow.connect(lambda m=m, l=link: self.__fillMenu(m, l)) else: a = menu.addAction(icon, title) a.triggered.connect(lambda x,l=link,r=menuLink: showDocument(l, referrer=r)) menu.addSeparator() action = menu.addAction("Open") action.triggered.connect(lambda x,l=menuLink: showDocument(l)) try: type = Connector().stat(menuLink.rev(), [menuLink.store()]).type() executables = Registry().getExecutables(type) except IOError: executables = [] if len(executables) > 1: openMenu = menu.addMenu("Open with") for e in executables: action = openMenu.addAction(e) action.triggered.connect(lambda x,l=menuLink,e=e: showDocument(l, executable=e)) menu.addSeparator() if store: action = menu.addAction(QtGui.QIcon("icons/unmount.png"), "Unmount") action.triggered.connect(lambda x,s=store: self.__unmount(s)) action = menu.addAction("Properties") action.triggered.connect(lambda x,l=menuLink: showProperties(l))
def __fillAddChooser(self): self.__addChooser.clear() self.__addItems = [] enum = Connector().enum() rules = self.__rules.rules() stores = [enum.doc(s) for s in enum.allStores() if not enum.isSystem(s) and enum.isMounted(s)] self.__addItems = [(s, p) for s in stores for p in stores if s < p and (s,p) not in rules and (p,s) not in rules ] self.__addBtn.setEnabled(bool(self.__addItems)) for (store, peer) in self.__addItems: title = (struct.readTitle(struct.DocLink(store, store, False), '?') + ' - ' + struct.readTitle(struct.DocLink(peer, peer, False), '?')) self.__addChooser.addItem(title)
def __fillAddChooser(self): self.__addChooser.clear() self.__addItems = [] enum = Connector().enum() rules = self.__rules.rules() stores = [s.sid for s in enum.regularStores()] self.__addItems = [(s, p) for s in stores for p in stores if s < p and (s,p) not in rules and (p,s) not in rules ] self.__addBtn.setEnabled(bool(self.__addItems)) for (store, peer) in self.__addItems: fromStore = '[' + enum.fromSId(store).label + '] ' fromStore += struct.readTitle(DocLink(store, store, False), '?') peerStore = '[' + enum.fromSId(peer).label + '] ' peerStore += struct.readTitle(DocLink(peer, peer, False), '?') self.__addChooser.addItem(fromStore + ' - ' + peerStore)
def __init__(self, parent=None): super(Launchbox, self).__init__(parent) self.setSizePolicy( QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum ) self.progressWidgets = {} self.progressContainer = QtGui.QWidget() self.progressLayout = QtGui.QVBoxLayout() self.progressLayout.setMargin(0) self.progressContainer.setLayout(self.progressLayout) self.mainLayout = QtGui.QVBoxLayout() self.mainLayout.setSizeConstraint(QtGui.QLayout.SetMinimumSize) enum = Connector().enum() for store in enum.allStores(): if not enum.isSystem(store): self.mainLayout.addWidget(StoreWidget(store)) syncButton = QtGui.QPushButton("Synchronization") syncButton.clicked.connect(lambda: SyncEditor().exec_()) setupLayout = QtGui.QHBoxLayout() setupLayout.addWidget(syncButton) setupLayout.addStretch() hLine = QtGui.QFrame() hLine.setFrameStyle(QtGui.QFrame.HLine | QtGui.QFrame.Raised) self.mainLayout.addWidget(hLine) self.mainLayout.addLayout(setupLayout) hLine = QtGui.QFrame() hLine.setFrameStyle(QtGui.QFrame.HLine | QtGui.QFrame.Raised) self.mainLayout.addWidget(hLine) self.mainLayout.addWidget(self.progressContainer) self.mainLayout.addStretch() self.setLayout(self.mainLayout) self.setWindowTitle("PeerDrive launch box") self.setWindowIcon(QtGui.QIcon("icons/launch.png")) self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMinimizeButtonHint) Connector().regProgressHandler(start=self.progressStart, stop=self.progressStop)
def update(self): if self.watch: Connector().unwatch(self.watch) self.watch = None enum = Connector().enum() self.mountBtn.setEnabled(enum.isRemovable(self.mountId)) if enum.isMounted(self.mountId): doc = enum.doc(self.mountId) self.mountBtn.setText("Unmount") self.storeBtn.setDocument(doc, doc) self.watch = StoreWidget.StoreWatch(doc, self.update) Connector().watch(self.watch) self.mounted = True else: self.mountBtn.setText("Mount") self.storeBtn.setText(enum.name(self.mountId)) self.mounted = False
def __fillAddChooser(self): self.__addChooser.clear() self.__addItems = [] enum = Connector().enum() rules = self.__rules.rules() stores = [s.sid for s in enum.regularStores()] self.__addItems = [ (s, p) for s in stores for p in stores if s < p and (s, p) not in rules and (p, s) not in rules ] self.__addBtn.setEnabled(bool(self.__addItems)) for (store, peer) in self.__addItems: fromStore = "[" + enum.fromSId(store).label + "] " fromStore += struct.readTitle(DocLink(store, store, False), "?") peerStore = "[" + enum.fromSId(peer).label + "] " peerStore += struct.readTitle(DocLink(peer, peer, False), "?") self.__addChooser.addItem(fromStore + " - " + peerStore)
def save(self): if not self.__changed: return rules = [ rule for rule in self.__rules.values() ] with Connector().update(self.sysStore, self.syncDoc, self.syncRev) as w: w.setData('/org.peerdrive.syncrules', rules) w.commit() self.rev = w.getRev()
def __init__(self, parent=None): super(Launchbox, self).__init__(parent) self.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) self.progressWidgets = {} self.__idleMessage = QtGui.QLabel("PeerDrive is idle...") self.__idleMessage.setAlignment(QtCore.Qt.AlignCenter) self.progressLayout = QtGui.QVBoxLayout() self.progressLayout.setMargin(0) self.progressLayout.setSizeConstraint(QtGui.QLayout.SetMinimumSize) self.progressLayout.addWidget(self.__idleMessage) self.setLayout(self.progressLayout) self.setWindowTitle("PeerDrive status") self.setWindowIcon(QtGui.QIcon("icons/peerdrive.png")) self.setWindowFlags(QtCore.Qt.Window | QtCore.Qt.WindowCloseButtonHint | QtCore.Qt.WindowMinimizeButtonHint) self.__syncRulesAction = QtGui.QAction("Manage synchronization...", self) self.__syncRulesAction.triggered.connect(lambda: SyncEditor().exec_()) self.__quitAction = QtGui.QAction("Quit", self) self.__quitAction.triggered.connect(QtCore.QCoreApplication.instance().quit) self.__restoreAction = QtGui.QAction("Show status", self) self.__restoreAction.triggered.connect(lambda: self.setVisible(True)) self.__trayIconMenu = QtGui.QMenu(self) self.__trayIconMenu.aboutToShow.connect(self.__trayMenuShow) self.__trayIcon = QtGui.QSystemTrayIcon(self) self.__trayIcon.setContextMenu(self.__trayIconMenu) self.__trayIcon.setIcon(QtGui.QIcon("icons/peerdrive.png")) self.__trayIcon.setToolTip("PeerDrive") self.__trayIcon.activated.connect(self.__trayActivated) self.__trayIcon.show() self.__fstab = struct.FSTab() self.__watch = Launchbox.RootWatch(self.__trayIcon) Connector().watch(self.__watch) Connector().regProgressHandler(start=self.__progressStart, stop=self.__progressStop)
def __init__(self, tag, typ, fromStore, toStore, item, trayIcon): super(ProgressWidget, self).__init__() self.tag = tag self.__type = typ self.__state = Connector().PROGRESS_RUNNING self.__fromStore = fromStore self.__toStore = toStore self.__trayIcon = trayIcon self.setFrameStyle(QtGui.QFrame.StyledPanel | QtGui.QFrame.Sunken) self.__progressInd = QtGui.QLabel() self.__progressInd.setMargin(4) if typ == Connector().PROGRESS_SYNC: self.fromBtn = DocButton(fromStore, fromStore, True) self.__progressInd.setPixmap(QtGui.QPixmap("icons/progress-sync.png")) elif typ == Connector().PROGRESS_REP_DOC: self.fromBtn = DocButton(fromStore, item, True) self.__progressInd.setPixmap(QtGui.QPixmap("icons/progress-replicate.png")) elif typ == Connector().PROGRESS_REP_REV: self.fromBtn = RevButton(fromStore, item, True) self.__progressInd.setPixmap(QtGui.QPixmap("icons/progress-replicate.png")) self.toBtn = DocButton(toStore, toStore, True) self.progressBar = QtGui.QProgressBar() self.progressBar.setMinimum(0) self.progressBar.setMaximum(0) self.__pauseBtn = QtGui.QToolButton() self.__pauseBtn.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) self.__pauseBtn.setIcon(QtGui.QIcon("icons/progress-pause.png")) self.__pauseBtn.setToolTip("Pause") self.__pauseBtn.clicked.connect(self.__pause) self.__stopBtn = QtGui.QToolButton() self.__stopBtn.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) self.__stopBtn.setIcon(QtGui.QIcon("icons/progress-stop.png")) self.__stopBtn.setToolTip("Abort") self.__stopBtn.clicked.connect(self.__stop) self.__skipBtn = QtGui.QToolButton() self.__skipBtn.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) self.__skipBtn.setIcon(QtGui.QIcon("icons/progress-skip.png")) self.__skipBtn.setToolTip("Skip") self.__skipBtn.clicked.connect(self.__skip) self.__skipBtn.hide() self.__errorMsg = QtGui.QLabel() self.__errorMsg.setWordWrap(True) self.__errorMsg.hide() layout = QtGui.QHBoxLayout() layout.setMargin(0) layout.addWidget(self.__progressInd) layout.addWidget(self.fromBtn) layout.addWidget(self.progressBar) layout.addWidget(self.__errorMsg) layout.addWidget(self.toBtn) layout.addWidget(self.__pauseBtn) layout.addWidget(self.__skipBtn) if typ != Connector().PROGRESS_SYNC: layout.addWidget(self.__stopBtn) self.setLayout(layout) Connector().regProgressHandler(progress=self.progress)
def __addStoreMenu(self, store, removable): l = DocLink(store.sid, store.sid) type = Connector().stat(l.rev(), [store.sid]).type() executables = Registry().getExecutables(type) title = struct.readTitle(l) if len(title) > 20: title = title[:20] + '...' title += ' ['+store.label+']' menu = self.__trayIconMenu.addMenu(QtGui.QIcon("icons/uti/store.png"), title) if removable: menu.aboutToShow.connect(lambda m=menu, l=l, s=store: self.__fillMenu(m, l, s)) else: menu.aboutToShow.connect(lambda m=menu, l=l: self.__fillMenu(m, l))
def progress(self, tag, state, value, err_code=None, err_doc=None, err_rev=None): if self.tag != tag: return if value > 0: self.progressBar.setMaximum(255) self.progressBar.setValue(value) if self.__state == state: return self.__state = state self.progressBar.setVisible(state != Connector().PROGRESS_ERROR) self.__errorMsg.setVisible(state == Connector().PROGRESS_ERROR) self.__skipBtn.setVisible(state == Connector().PROGRESS_ERROR) if state == Connector().PROGRESS_RUNNING: self.__pauseBtn.setIcon(QtGui.QIcon("icons/progress-pause.png")) self.__pauseBtn.setToolTip("Pause") if self.__type == Connector().PROGRESS_SYNC: self.__progressInd.setPixmap(QtGui.QPixmap("icons/progress-sync.png")) else: self.__progressInd.setPixmap(QtGui.QPixmap("icons/progress-replicate.png")) elif state == Connector().PROGRESS_PAUSED: self.__pauseBtn.setIcon(QtGui.QIcon("icons/progress-start.png")) self.__pauseBtn.setToolTip("Resume") self.__progressInd.setPixmap(QtGui.QPixmap("icons/progress-pause.png")) elif state == Connector().PROGRESS_ERROR: self.__pauseBtn.setIcon(QtGui.QIcon("icons/progress-retry.png")) self.__pauseBtn.setToolTip("Retry") self.__progressInd.setPixmap(QtGui.QPixmap("icons/progress-error.png")) doc = struct.readTitle(RevLink(self.__fromStore, err_rev), 'unknown document') self.__errorMsg.setText("Error '" + err_code[1] + "' while processing '" + doc + "'!") if self.__type == Connector().PROGRESS_SYNC: title = "Synchronization error" message = "synchronizing" else: title = "Replication error" message = "replicating" message = "Error '" + err_code[1] + "' while " + message + " '" + doc + \ "' \nfrom '" + struct.readTitle(DocLink(self.__fromStore, self.__fromStore), "unknown store") + \ "' to '" + struct.readTitle(DocLink(self.__toStore, self.__toStore), "unknown store") + \ "'!" self.__trayIcon.showMessage(title, message, QtGui.QSystemTrayIcon.Warning)
def __trayMenuShow(self): self.__trayIconMenu.clear() try: stores = Connector().enum().regularStores() for store in stores: try: self.__addStoreMenu(store, True) except IOError: pass unmounted = (set(self.__fstab.knownLabels()) - set([ s.label for s in stores ])) for label in unmounted: action = self.__trayIconMenu.addAction("Mount "+label) action.triggered.connect(lambda x,l=label: self.__mount(l)) except IOError: pass self.__trayIconMenu.addSeparator() self.__trayIconMenu.addAction(self.__syncRulesAction) self.__trayIconMenu.addAction(self.__restoreAction) self.__trayIconMenu.addSeparator() self.__trayIconMenu.addAction(self.__quitAction)
def __skip(self): Connector().progressResume(self.tag, True)
def __stop(self): Connector().progressStop(self.tag)
def __pause(self): if self.__state == Connector().PROGRESS_RUNNING: Connector().progressPause(self.tag) else: Connector().progressResume(self.tag)
def remove(self): Connector().unregProgressHandler(progress=self.progress) self.fromBtn.cleanup() self.toBtn.cleanup() self.deleteLater()
def __init__(self, trayIcon): self.__trayIcon = trayIcon enum = Connector().enum() self.__mounted = set([s.label for s in enum.regularStores()]) Watch.__init__(self, Watch.TYPE_DOC, Watch.ROOT_DOC)
def __unmount(self, store): try: Connector().unmount(store.sid) except IOError as e: QtGui.QMessageBox.warning(self, store.label, 'Unmount opertaion failed: ' + str(e))