def __columnsShow(self): self.__colMenu.clear() reg = Registry() model = self.viewWidget().model() types = model.typeCodes().copy() columns = model.getColumns() for col in columns: (uti, path) = col.split(':') if uti != "": types.add(uti) # add stat columns self.__columnsShowAddEntry(self.__colMenu, columns, ":size", "Size") self.__columnsShowAddEntry(self.__colMenu, columns, ":mtime", "Modification time") self.__columnsShowAddEntry(self.__colMenu, columns, ":type", "Type code") self.__columnsShowAddEntry(self.__colMenu, columns, ":creator", "Creator code") self.__columnsShowAddEntry(self.__colMenu, columns, ":comment", "Comment") self.__colMenu.addSeparator() # add meta columns metaSpecs = {} for t in types: metaSpecs.update(reg.searchAll(t, "meta")) for (uti, specs) in metaSpecs.items(): subMenu = self.__colMenu.addMenu(reg.getDisplayString(uti)) for spec in specs: key = uti+":"+reduce(lambda x,y: x+"/"+y, spec["key"]) self.__columnsShowAddEntry(subMenu, columns, key, spec["display"])
def update(self, updateItem=True): # reset everything self.__valid = False self.__icon = None for i in xrange(len(self.__columnDefs)): column = self.__columnDefs[i] if column.derived(): self.__columnValues[i] = column.default() # determine revision needMerge = False isReplicated = False if self.__doc: l = Connector().lookupDoc(self.__doc) isReplicated = len(l.stores()) > 1 revisions = l.revs() if len(revisions) == 0: return elif len(revisions) > 1: needMerge = True if updateItem: self.__item[''].update() self.__rev = self.__item[''].rev() # stat try: s = Connector().stat(self.__rev) except IOError: return self.__uti = s.type() if needMerge or isReplicated: image = QtGui.QImage(Registry().getIcon(s.type())) painter = QtGui.QPainter() painter.begin(image) if needMerge: painter.drawImage(0, 16, QtGui.QImage("icons/emblems/split.png")) elif isReplicated: painter.drawImage( 0, 16, QtGui.QImage("icons/emblems/distributed.png")) painter.end() self.__icon = QtGui.QIcon(QtGui.QPixmap.fromImage(image)) else: self.__icon = QtGui.QIcon(Registry().getIcon(s.type())) self.__isFolder = Registry().conformes(self.__uti, "org.peerdrive.folder") self.__replacable = not needMerge and not self.__isFolder self.__valid = True self.__updateColumns(s)
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 __addCreateActions(self, menu): newMenu = menu.addMenu(QtGui.QIcon("icons/filenew.png"), "New document") action = newMenu.addAction(QtGui.QIcon("icons/uti/folder.png"), "Folder") action.triggered.connect(self.__doCreateFolder) newMenu.addSeparator() items = {} sysStore = Connector().enum().sysStore().sid sysDict = struct.Folder(connector.DocLink(sysStore, sysStore)) templatesDoc = sysDict.get("templates") if templatesDoc: templatesDict = struct.Folder(templatesDoc.update(sysStore)) items = templatesDict.items() items.sort(key=lambda item: item[0]) if items: for (name, link) in items: rev = link.rev() icon = QtGui.QIcon(Registry().getIcon( Connector().stat(rev).type())) action = newMenu.addAction(icon, name) action.triggered.connect( lambda x, r=rev, n=name: self.__doCreateFromTemplate( sysStore, r, n)) else: action = newMenu.addAction("No templates found") action.setEnabled(False)
def load(self, store, rev): try: stat = Connector().stat(rev, [store]) self.__typeLabel.setText(Registry().getDisplayString(stat.type())) self.__crtimeLabel.setText(str(stat.crtime())) self.__mtimeLabel.setText(str(stat.mtime())) size = stat.dataSize() for a in stat.attachments(): size += stat.size(a) for unit in ['Bytes', 'KiB', 'MiB', 'GiB']: if size < (1 << 10): break else: size = size >> 10 sizeText = "%d %s (%d attachments)" % (size, unit, len(stat.attachments())) self.__sizeLabel.setText(sizeText) if stat.flags(): flagsText = reduce(lambda x, y: x + ", " + y, [ flagToText.get(f, "<" + str(f) + ">") for f in stat.flags() ]) else: flagsText = "-" self.__flagsLabel.setText(flagsText) except IOError: self.__typeLabel.setText("n/a") self.__mtimeLabel.setText("n/a") self.__sizeLabel.setText("n/a")
def __setViewHandler(self, link): link.update() try: type = Connector().stat(link.rev()).type() executables = Registry().getExecutables(type) except IOError: executables = [] if not executables: # Probably a bad idea to leave the current view widget, but what # else can we do? return for executable in executables: if executable in BrowserWindow.TYPES: break handler = BrowserWindow.TYPES[executable] if self.__viewHandler: if isinstance(self.__viewHandler, handler): return self.__viewHandler.delete() self.__viewHandler = handler(self) self.setCentralWidget(self.__viewHandler.getView()) self.__viewHandler.getView().distributionChanged.connect( self.__updateStoreButtons)
def _columnFactory(key): (uti, path) = key.split(':') if uti == "": return StatColumnInfo(key) else: for meta in Registry().search(uti, "meta", recursive=False, default=[]): if path == reduce(lambda x, y: x + "/" + y, meta["key"]): return MetaColumnInfo(key, meta) return None
def __doubleClicked(self, index): link = self.model().getItemLink(self.modelMapIndex(index)) if link: try: uti = Connector().stat(link.rev()).type() executables = Registry().getExecutables(uti) except IOError: executables = [] self.itemOpen.emit(link, None, "org.peerdrive.browser.py" in executables)
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 __addOpenActions(self, menu, link, isDoc): try: uti = Connector().stat(link.rev()).type() executables = Registry().getExecutables(uti) except IOError: executables = [] prefix = "Open" browseHint = False browsePreferred = False if "org.peerdrive.browser.py" in executables: browsePreferred = True for e in executables: if e in self.__browseTypes: browseHint = True prefix = "Browse" break if browseHint: action = menu.addAction("&Browse") action.triggered.connect( lambda x, l=link: self.itemOpen.emit(l, None, True)) if browsePreferred: menu.setDefaultAction(action) action = menu.addAction("&Open") action.triggered.connect( lambda x, l=link: self.itemOpen.emit(l, None, False)) if not browsePreferred: menu.setDefaultAction(action) else: action = menu.addAction("&Open") action.triggered.connect( lambda x, l=link: self.itemOpen.emit(l, None, False)) menu.setDefaultAction(action) if len(executables) > 1: openWith = menu.addMenu("Open with") for e in executables: action = openWith.addAction(e) action.triggered.connect( lambda x, l=link, e=e: self.itemOpen.emit(l, e, False))
def __dropContents(self, mime): # unfortunately Qt will only return the first object and nothing # in case of Outlook messages content = str(mime.data('FileContents')) if len(content) == 0: return False name = getFileNamesFromMime(mime)[0] ext = os.path.splitext(name)[1].lower() uti = Registry().getUtiFromExtension(ext) data = {"org.peerdrive.annotation": {"title": name}}, spec = [('_', content)], handle = importer.importObject(self.__store, uti, data, spec, []) if handle: try: self.insertLink( connector.DocLink(self.__store, handle.getDoc())) self.__parent.save() finally: handle.close() return True
if not path: s = Connector().stat(link.rev()) hash = s.hash('_') name = hash.encode('hex') ext = "" with Connector().peek(link.store(), link.rev()) as r: annotation = r.getData("/org.peerdrive.annotation") # read title if "title" in annotation: (name, ext) = os.path.splitext(annotation["title"]) # try to get extension from Registry if title has none if not ext: extensions = Registry().search(s.type(), "extensions") if extensions: ext = extensions[0] # try to get extension from origin if we don't have one already if not ext and ("origin" in annotation): ext = os.path.splitext(annotation["origin"])[1] # copy out file (if necessary) path = os.path.join(tempfile.gettempdir(), hash.encode('hex'), name + ext) if not os.path.isdir(os.path.dirname(path)): os.makedirs(os.path.dirname(path)) if not os.path.isfile(path): with open(path, "wb") as file: with Connector().peek(link.store(), link.rev()) as reader: file.write(reader.readAll('_'))