diff options
-rw-r--r-- | Mozo/MainWindow.py | 23 | ||||
-rw-r--r-- | Mozo/MenuEditor.py | 126 | ||||
-rw-r--r-- | Mozo/util.py | 76 |
3 files changed, 85 insertions, 140 deletions
diff --git a/Mozo/MainWindow.py b/Mozo/MainWindow.py index b7c1ab6..5ce6d0b 100644 --- a/Mozo/MainWindow.py +++ b/Mozo/MainWindow.py @@ -370,15 +370,7 @@ class MainWindow: file_path = os.path.join(util.getUserItemPath(), item.get_desktop_file_id()) file_type = 'Item' elif item.get_type() == matemenu.TYPE_DIRECTORY: - if item.get_desktop_file_path() == None: - file_path = util.getUniqueFileId('mozo-made', '.directory') - parser = util.DesktopParser(file_path, 'Directory') - parser.set('Name', item.get_name()) - parser.set('Comment', item.get_comment()) - parser.set('Icon', item.get_icon()) - parser.write(open(file_path)) - else: - file_path = os.path.join(util.getUserDirectoryPath(), os.path.split(item.get_desktop_file_path())[1]) + file_path = os.path.join(util.getUserDirectoryPath(), os.path.split(item.get_desktop_file_path())[1]) file_type = 'Menu' if not os.path.isfile(file_path): @@ -571,13 +563,14 @@ class MainWindow: content_type = file_info.get_content_type() if content_type == 'application/x-desktop': input_stream = myfile.read() - (fd, tmppath) = tempfile.mkstemp(prefix='mozo-dnd', suffix='.desktop') - with open(fd, "w") as f: - f.write(input_stream.read()) - parser = util.DesktopParser(tmppath) - self.editor.createItem(parent, parser.get('Icon'), parser.get('Name', self.editor.locale), parser.get('Comment', self.editor.locale), parser.get('Exec'), parser.get('Terminal'), before, after) + keyfile = GLib.KeyFile() + keyfile.load_from_data(input_stream.read()) + self.editor.createItem(parent, before, after, KeyFile=keyfile) elif content_type in ('application/x-shellscript', 'application/x-executable'): - self.editor.createItem(parent, None, os.path.split(file_path)[1].strip(), None, file_path.replace('file://', '').strip(), False, before, after) + self.editor.createItem(parent, before, after, + Name=os.path.split(file_path)[1].strip(), + Exec=file_path.replace('file://', '').strip(), + Terminal=False) self.drag_data = None def on_item_tree_key_press_event(self, item_tree, event): diff --git a/Mozo/MenuEditor.py b/Mozo/MenuEditor.py index 79aaf1e..02c8e29 100644 --- a/Mozo/MenuEditor.py +++ b/Mozo/MenuEditor.py @@ -18,6 +18,7 @@ import os, re, xml.dom.minidom, locale import matemenu +from gi.repository import GLib from Mozo import util class Menu: @@ -201,7 +202,7 @@ class MenuEditor: menu_xml = self.__getXmlMenu(self.__getPath(item.get_parent()), dom, dom) if visible: self.__addXmlFilename(menu_xml, dom, item.get_desktop_file_id(), 'Include') - self.__writeItem(item, no_display=False) + self.__writeItem(item, NoDisplay=False) else: self.__addXmlFilename(menu_xml, dom, item.get_desktop_file_id(), 'Exclude') self.__addXmlTextElement(menu_xml, 'AppDir', util.getUserItemPath(), dom) @@ -213,15 +214,12 @@ class MenuEditor: menu_xml = self.__getXmlMenu(self.__getPath(item), dom, dom) for node in self.__getXmlNodesByName(['Deleted', 'NotDeleted'], menu_xml): node.parentNode.removeChild(node) - if visible: - self.__writeMenu(item, no_display=False) - else: - self.__writeMenu(item, no_display=True) + self.__writeMenu(item, NoDisplay=not visible) self.__addXmlTextElement(menu_xml, 'DirectoryDir', util.getUserDirectoryPath(), dom) self.save() - def createItem(self, parent, icon, name, comment, command, use_term, before=None, after=None): - file_id = self.__writeItem(None, icon, name, comment, command, use_term) + def createItem(self, parent, before, after, **kwargs): + file_id = self.__writeItem(None, **kwargs) self.insertExternalItem(file_id, parent.menu_id, before, after) def insertExternalItem(self, file_id, parent_id, before=None, after=None): @@ -232,10 +230,6 @@ class MenuEditor: self.__addUndo([self.__getMenu(parent), ('Item', file_id)]) self.save() - def createMenu(self, parent, icon, name, comment, before=None, after=None): - file_id = self.__writeMenu(None, icon, name, comment) - self.insertExternalMenu(file_id, parent.menu_id, before, after) - def insertExternalMenu(self, file_id, parent_id, before=None, after=None): menu_id = file_id.rsplit('.', 1)[0] parent = self.__findMenu(parent_id) @@ -261,7 +255,7 @@ class MenuEditor: parent = item.get_parent() if final: self.__addUndo([self.__getMenu(parent), item]) - self.__writeItem(item, icon, name, comment, command, use_term) + self.__writeItem(item, Icon=icon, Name=name, Comment=comment, Exec=command, Terminal=use_term) if final: dom = self.__getMenu(parent).dom menu_xml = self.__getXmlMenu(self.__getPath(parent), dom, dom) @@ -276,7 +270,7 @@ class MenuEditor: #otherwise changes won't show up dom = self.__getMenu(menu).dom menu_xml = self.__getXmlMenu(self.__getPath(menu), dom, dom) - file_id = self.__writeMenu(menu, icon, name, comment) + self.__writeMenu(menu, Icon=icon, Name=name, Comment=comment) if final: self.__addXmlTextElement(menu_xml, 'DirectoryDir', util.getUserDirectoryPath(), dom) self.__addUndo([self.__getMenu(menu), menu]) @@ -285,13 +279,19 @@ class MenuEditor: def copyItem(self, item, new_parent, before=None, after=None): dom = self.__getMenu(new_parent).dom file_path = item.get_desktop_file_path() - keyfile = util.DesktopParser(file_path) - #erase Categories in new file - keyfile.set('Categories', ('',)) - keyfile.set('Hidden', False) + keyfile = GLib.KeyFile() + keyfile.load_from_file(file_path, util.KEY_FILE_FLAGS) + + util.fillKeyFile(keyfile, dict(Categories=[], Hidden=False)) + file_id = util.getUniqueFileId(item.get_name().replace(os.sep, '-'), '.desktop') out_path = os.path.join(util.getUserItemPath(), file_id) - keyfile.write(open(out_path, 'w')) + + contents, length = keyfile.to_data() + + with open(out_path, 'w') as f: + f.write(contents) + self.__addItem(new_parent, file_id, dom) self.__positionItem(new_parent, ('Item', file_id), before, after) self.__addUndo([self.__getMenu(new_parent), ('Item', file_id)]) @@ -356,7 +356,7 @@ class MenuEditor: def deleteItem(self, item): self.__addUndo([item,]) - self.__writeItem(item, hidden=True) + self.__writeItem(item, Hidden=True) self.save() def deleteMenu(self, menu): @@ -549,65 +549,59 @@ class MenuEditor: node = dom.createElement('Deleted') return element.appendChild(node) - def __writeItem(self, item=None, icon=None, name=None, comment=None, command=None, use_term=None, no_display=None, startup_notify=None, hidden=None): - if item: + def __makeKeyFile(self, file_path, kwargs): + if 'KeyFile' in kwargs: + return kwargs['KeyFile'] + + keyfile = GLib.KeyFile() + + if file_path is not None: + keyfile.load_from_file(file_path, util.KEY_FILE_FLAGS) + + util.fillKeyFile(keyfile, kwargs) + return keyfile + + def __writeItem(self, item, **kwargs): + if item is not None: file_path = item.get_desktop_file_path() + else: + file_path = None + + keyfile = self.__makeKeyFile(file_path, kwargs) + + if item is not None: file_id = item.get_desktop_file_id() - keyfile = util.DesktopParser(file_path) - elif item == None and name == None: - raise Exception('New menu items need a name') else: - file_id = util.getUniqueFileId(item.get_name().replace(os.sep, '-'), '.desktop') - keyfile = util.DesktopParser() - if icon: - keyfile.set('Icon', icon) - keyfile.set('Icon', icon, self.locale) - if name: - keyfile.set('Name', name) - keyfile.set('Name', name, self.locale) - if comment: - keyfile.set('Comment', comment) - keyfile.set('Comment', comment, self.locale) - if command: - keyfile.set('Exec', command) - if use_term != None: - keyfile.set('Terminal', use_term) - if no_display != None: - keyfile.set('NoDisplay', no_display) - if startup_notify != None: - keyfile.set('StartupNotify', startup_notify) - if hidden != None: - keyfile.set('Hidden', hidden) - out_path = os.path.join(util.getUserItemPath(), file_id) - keyfile.write(open(out_path, 'w')) + file_id = util.getUniqueFileId(keyfile.get_string(GLib.KEY_FILE_DESKTOP_GROUP, 'Name'), '.desktop') + + contents, length = keyfile.to_data() + + with open(os.path.join(util.getUserItemPath(), file_id), 'w') as f: + f.write(contents) return file_id - def __writeMenu(self, menu=None, icon=None, name=None, comment=None, no_display=None): - if menu: + def __writeMenu(self, menu, **kwargs): + if menu is not None: file_id = os.path.split(menu.get_desktop_file_path())[1] file_path = menu.get_desktop_file_path() - keyfile = util.DesktopParser(file_path) - elif menu == None and name == None: + keyfile = GLib.KeyFile() + keyfile.load_from_file(file_path, util.KEY_FILE_FLAGS) + elif menu is None and 'Name' not in kwargs: raise Exception('New menus need a name') else: - file_id = util.getUniqueFileId(name, '.directory') - keyfile = util.DesktopParser(file_type='Directory') - if icon: - keyfile.set('Icon', icon) - if name: - keyfile.set('Name', name) - keyfile.set('Name', name, self.locale) - if comment: - keyfile.set('Comment', comment) - keyfile.set('Comment', comment, self.locale) - if no_display != None: - keyfile.set('NoDisplay', no_display) - out_path = os.path.join(util.getUserDirectoryPath(), file_id) - keyfile.write(open(out_path, 'w')) + file_id = util.getUniqueFileId(kwargs['Name'], '.directory') + keyfile = GLib.KeyFile() + + util.fillKeyFile(keyfile, kwargs) + + contents, length = keyfile.to_data() + + with open(os.path.join(util.getUserDirectoryPath(), file_id), 'w') as f: + f.write(contents) return file_id def __getXmlNodesByName(self, name, element): - for child in element.childNodes: + for child in element.childNodes: if child.nodeType == xml.dom.Node.ELEMENT_NODE: if isinstance(name, str) and child.nodeName == name: yield child diff --git a/Mozo/util.py b/Mozo/util.py index 89506a5..3ea68d7 100644 --- a/Mozo/util.py +++ b/Mozo/util.py @@ -19,65 +19,23 @@ import os import matemenu import gi -from gi.repository import Gtk, Gdk, GdkPixbuf -from ConfigParser import ConfigParser - -class DesktopParser(ConfigParser): - def __init__(self, filename=None, file_type='Application'): - ConfigParser.__init__(self) - self.filename = filename - self.file_type = file_type - if filename: - if len(self.read(filename)) == 0: - #file doesn't exist - self.add_section('Desktop Entry') - else: - self.add_section('Desktop Entry') - self._list_separator = ';' - - def optionxform(self, option): - #makes keys not be lowercase - return option - - def get(self, option, locale=None): - locale_option = option + '[%s]' % locale - try: - value = ConfigParser.get(self, 'Desktop Entry', locale_option) - except: - try: - value = ConfigParser.get(self, 'Desktop Entry', option) - except: - return None - if self._list_separator in value: - value = value.split(self._list_separator) - if value == 'true': - value = True - if value == 'false': - value = False - return value - - def set(self, option, value, locale=None): - if locale: - option = option + '[%s]' % locale - if value == True: - value = 'true' - if value == False: - value = 'false' - if isinstance(value, tuple) or isinstance(value, list): - value = self._list_separator.join(value) + ';' - ConfigParser.set(self, 'Desktop Entry', option, value) - - def write(self, file_object): - file_object.write('[Desktop Entry]\n') - items = [] - if not self.filename: - file_object.write('Encoding=UTF-8\n') - file_object.write('Type=' + str(self.file_type) + '\n') - for item in self.items('Desktop Entry'): - items.append(item) - items.sort() - for item in items: - file_object.write(item[0] + '=' + item[1] + '\n') +from collections import Sequence +from gi.repository import GLib, Gtk, Gdk, GdkPixbuf + +DESKTOP_GROUP = GLib.KEY_FILE_DESKTOP_GROUP +KEY_FILE_FLAGS = GLib.KeyFileFlags.KEEP_COMMENTS | GLib.KeyFileFlags.KEEP_TRANSLATIONS + +def fillKeyFile(keyfile, items): + for key, item in items.iteritems(): + if item is None: + continue + + if isinstance(item, bool): + keyfile.set_boolean(DESKTOP_GROUP, key, item) + elif isinstance(item, Sequence): + keyfile.set_string_list(DESKTOP_GROUP, key, item) + elif isinstance(item, basestring): + keyfile.set_string(DESKTOP_GROUP, key, item) def getUniqueFileId(name, extension): append = 0 |