def __init__(self, file): INIConfigFile.__init__(self, file) if os.name == 'nt': endofline = 'dos' else: endofline = 'unix' name = file.dir.basename if hasattr(file, 'dir') else file.parent( ).basename # HACK zim.fs and zim.newfs compat self['Notebook'].define(( ('version', String('.'.join(map(str, DATA_FORMAT_VERSION)))), ('name', String(name)), ('interwiki', String(None)), ('home', ConfigDefinitionByClass(Path('Home'))), ('icon', String(None)), # XXX should be file, but resolves relative ('document_root', String(None)), # XXX should be dir, but resolves relative ('short_links', Boolean(False)), ('shared', Boolean(True)), ('endofline', Choice(endofline, {'dos', 'unix'})), ('disable_trash', Boolean(False)), ('default_file_format', String('zim-wiki')), ('default_file_extension', String('.txt')), ('notebook_layout', String('files')), ))
def __init__(self, file): INIConfigFile.__init__(self, file) if os.name == 'nt': endofline = 'dos' else: endofline = 'unix' self['Notebook'].define(( ('version', String('.'.join(map(str, DATA_FORMAT_VERSION)))), ('name', String(file.dir.basename)), ('interwiki', String(None)), ('home', ConfigDefinitionByClass(Path('Home'))), ('icon', String(None)), # XXX should be file, but resolves relative ('document_root', String(None)), # XXX should be dir, but resolves relative ('shared', Boolean(True)), ('endofline', Choice(endofline, set(('dos', 'unix')))), ('disable_trash', Boolean(False)), ('profile', String(None)), ))
class CustomToolDict(DesktopEntryDict): '''This is a specialized desktop entry type that is used for custom tools for the "Tools" menu in zim. It uses a non-standard Exec spec with zim specific escapes for "X-Zim-ExecTool". The following fields are expanded: - C{%f} for source file as tmp file current page - C{%d} for attachment directory - C{%s} for real source file (if any) - C{%n} for notebook location (file or directory) - C{%D} for document root - C{%t} for selected text or word under cursor - C{%T} for the selected text including wiki formatting Other additional keys are: - C{X-Zim-ReadOnly} - boolean - C{X-Zim-ShowInToolBar} - boolean - C{X-Zim-ShowInContextMenu} - 'None', 'Text' or 'Page' These tools should always be executed with 3 arguments: notebook, page & pageview. ''' _definitions = DesktopEntryDict._definitions + ( ('X-Zim-ExecTool', String(None)), ('X-Zim-ReadOnly', Boolean(True)), ('X-Zim-ShowInToolBar', Boolean(False)), ('X-Zim-ShowInContextMenu', Choice(None, ('Text', 'Page'))), ('X-Zim-ReplaceSelection', Boolean(False)), ) def isvalid(self): '''Check if all required fields are set. @returns: C{True} if all required fields are set ''' entry = self['Desktop Entry'] if entry.get('Type') == 'X-Zim-CustomTool' \ and entry.get('Version') == 1.0 \ and entry.get('Name') \ and entry.get('X-Zim-ExecTool') \ and not entry.get('X-Zim-ReadOnly') is None \ and not entry.get('X-Zim-ShowInToolBar') is None \ and 'X-Zim-ShowInContextMenu' in entry: return True else: logger.error('Invalid custom tool entry: %s %s', self.key, entry) return False def get_pixbuf(self, size): pixbuf = DesktopEntryDict.get_pixbuf(self, size) if pixbuf is None: pixbuf = gtk.Label().render_icon(gtk.STOCK_EXECUTE, size) # FIXME hack to use arbitrary widget to render icon return pixbuf @property def icon(self): return self['Desktop Entry'].get('Icon') or gtk.STOCK_EXECUTE # get('Icon', gtk.STOCK_EXECUTE) still returns empty string if key exists but no value @property def execcmd(self): return self['Desktop Entry']['X-Zim-ExecTool'] @property def isreadonly(self): return self['Desktop Entry']['X-Zim-ReadOnly'] @property def showintoolbar(self): return self['Desktop Entry']['X-Zim-ShowInToolBar'] @property def showincontextmenu(self): return self['Desktop Entry']['X-Zim-ShowInContextMenu'] @property def replaceselection(self): return self['Desktop Entry']['X-Zim-ReplaceSelection'] def parse_exec(self, args=None): if not (isinstance(args, tuple) and len(args) == 3): raise AssertionError, 'Custom commands needs 3 arguments' # assert statement could be optimized away notebook, page, pageview = args cmd = split_quoted_strings(self['Desktop Entry']['X-Zim-ExecTool']) if '%f' in cmd: self._tmpfile = TmpFile('tmp-page-source.txt') self._tmpfile.writelines(page.dump('wiki')) cmd[cmd.index('%f')] = self._tmpfile.path if '%d' in cmd: dir = notebook.get_attachments_dir(page) if dir: cmd[cmd.index('%d')] = dir.path else: cmd[cmd.index('%d')] = '' if '%s' in cmd: if hasattr(page, 'source') and isinstance(page.source, File): cmd[cmd.index('%s')] = page.source.path else: cmd[cmd.index('%s')] = '' if '%p' in cmd: cmd[cmd.index('%p')] = page.name if '%n' in cmd: cmd[cmd.index('%n')] = File(notebook.uri).path if '%D' in cmd: dir = notebook.document_root if dir: cmd[cmd.index('%D')] = dir.path else: cmd[cmd.index('%D')] = '' if '%t' in cmd: text = pageview.get_selection() or pageview.get_word() cmd[cmd.index('%t')] = text or '' # FIXME - need to substitute this in arguments + url encoding if '%T' in cmd: text = pageview.get_selection(format='wiki') or pageview.get_word(format='wiki') cmd[cmd.index('%T')] = text or '' # FIXME - need to substitute this in arguments + url encoding return tuple(cmd) _cmd = parse_exec # To hook into Application.spawn and Application.run def run(self, args, cwd=None): self._tmpfile = None Application.run(self, args, cwd=cwd) if self._tmpfile: notebook, page, pageview = args page.parse('wiki', self._tmpfile.readlines()) self._tmpfile = None def update(self, E=(), **F): self['Desktop Entry'].update(E, **F) # Set sane default for X-Zim-ShowInContextMenus if not (E and 'X-Zim-ShowInContextMenu' in E) \ and not 'X-Zim-ShowInContextMenu' in F: cmd = split_quoted_strings(self['Desktop Entry']['X-Zim-ExecTool']) if any(c in cmd for c in ['%f', '%d', '%s']): context = 'Page' elif '%t' in cmd: context = 'Text' else: context = None self['Desktop Entry']['X-Zim-ShowInContextMenu'] = context