From b3e60df70d30451437b045b1d4c0d456da80d844 Mon Sep 17 00:00:00 2001 From: Stefano Karapetsas Date: Thu, 12 Jan 2012 18:43:33 +0100 Subject: Alacarte => Mozo --- Alacarte/MainWindow.py | 624 --------------------------------------- Alacarte/Makefile.am | 24 -- Alacarte/Makefile.in | 482 ------------------------------ Alacarte/MenuEditor.py | 775 ------------------------------------------------- Alacarte/__init__.py | 0 Alacarte/config.py.in | 9 - Alacarte/util.py | 244 ---------------- 7 files changed, 2158 deletions(-) delete mode 100644 Alacarte/MainWindow.py delete mode 100644 Alacarte/Makefile.am delete mode 100644 Alacarte/Makefile.in delete mode 100644 Alacarte/MenuEditor.py delete mode 100644 Alacarte/__init__.py delete mode 100644 Alacarte/config.py.in delete mode 100644 Alacarte/util.py (limited to 'Alacarte') diff --git a/Alacarte/MainWindow.py b/Alacarte/MainWindow.py deleted file mode 100644 index 07467d0..0000000 --- a/Alacarte/MainWindow.py +++ /dev/null @@ -1,624 +0,0 @@ -# -*- coding: utf-8 -*- -# Alacarte Menu Editor - Simple fd.o Compliant Menu Editor -# Copyright (C) 2006 Travis Watkins -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -import gtk, matemenu, gobject, gio -import cgi, os -import gettext -import subprocess -import urllib -try: - from Alacarte import config - gettext.bindtextdomain(config.GETTEXT_PACKAGE,config.localedir) - gettext.textdomain(config.GETTEXT_PACKAGE) -except: - pass -_ = gettext.gettext -from Alacarte.MenuEditor import MenuEditor -from Alacarte import util - -class MainWindow: - timer = None - #hack to make editing menu properties work - allow_update = True - #drag-and-drop stuff - dnd_items = [('ALACARTE_ITEM_ROW', gtk.TARGET_SAME_APP, 0), ('text/plain', 0, 1)] - dnd_menus = [('ALACARTE_MENU_ROW', gtk.TARGET_SAME_APP, 0)] - dnd_both = [dnd_items[0],] + dnd_menus - drag_data = None - edit_pool = [] - - def __init__(self, datadir, version, argv): - self.file_path = datadir - self.version = version - self.editor = MenuEditor() - gtk.window_set_default_icon_name('alacarte') - self.tree = gtk.Builder() - self.tree.set_translation_domain(config.GETTEXT_PACKAGE) - self.tree.add_from_file(os.path.join(self.file_path, 'alacarte.ui')) - self.tree.connect_signals(self) - self.setupMenuTree() - self.setupItemTree() - self.tree.get_object('edit_delete').set_sensitive(False) - self.tree.get_object('edit_revert_to_original').set_sensitive(False) - self.tree.get_object('edit_properties').set_sensitive(False) - self.tree.get_object('move_up_button').set_sensitive(False) - self.tree.get_object('move_down_button').set_sensitive(False) - self.tree.get_object('new_separator_button').set_sensitive(False) - accelgroup = gtk.AccelGroup() - keyval, modifier = gtk.accelerator_parse('Z') - accelgroup.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE, self.on_mainwindow_undo) - keyval, modifier = gtk.accelerator_parse('Z') - accelgroup.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE, self.on_mainwindow_redo) - keyval, modifier = gtk.accelerator_parse('F1') - accelgroup.connect_group(keyval, modifier, gtk.ACCEL_VISIBLE, self.on_help_button_clicked) - self.tree.get_object('mainwindow').add_accel_group(accelgroup) - - def run(self): - self.loadMenus() - self.editor.applications.tree.add_monitor(self.menuChanged, None) - self.editor.settings.tree.add_monitor(self.menuChanged, None) - self.tree.get_object('mainwindow').show_all() - gtk.main() - - def menuChanged(self, *a): - if self.timer: - gobject.source_remove(self.timer) - self.timer = None - self.timer = gobject.timeout_add(3, self.loadUpdates) - - def loadUpdates(self): - if not self.allow_update: - return False - menu_tree = self.tree.get_object('menu_tree') - item_tree = self.tree.get_object('item_tree') - items, iter = item_tree.get_selection().get_selected() - update_items = False - item_id, separator_path = None, None - if iter: - update_items = True - if items[iter][3].get_type() == matemenu.TYPE_DIRECTORY: - item_id = os.path.split(items[iter][3].get_desktop_file_path())[1] - update_items = True - elif items[iter][3].get_type() == matemenu.TYPE_ENTRY: - item_id = items[iter][3].get_desktop_file_id() - update_items = True - elif items[iter][3].get_type() == matemenu.TYPE_SEPARATOR: - item_id = items.get_path(iter) - update_items = True - menus, iter = menu_tree.get_selection().get_selected() - update_menus = False - menu_id = None - if iter: - if menus[iter][2].get_desktop_file_path(): - menu_id = os.path.split(menus[iter][2].get_desktop_file_path())[1] - else: - menu_id = menus[iter][2].get_menu_id() - update_menus = True - self.loadMenus() - #find current menu in new tree - if update_menus: - menu_tree.get_model().foreach(self.findMenu, menu_id) - menus, iter = menu_tree.get_selection().get_selected() - if iter: - self.on_menu_tree_cursor_changed(menu_tree) - #find current item in new list - if update_items: - i = 0 - for item in item_tree.get_model(): - found = False - if item[3].get_type() == matemenu.TYPE_ENTRY and item[3].get_desktop_file_id() == item_id: - found = True - if item[3].get_type() == matemenu.TYPE_DIRECTORY and item[3].get_desktop_file_path(): - if os.path.split(item[3].get_desktop_file_path())[1] == item_id: - found = True - if item[3].get_type() == matemenu.TYPE_SEPARATOR: - if not isinstance(item_id, tuple): - continue - #separators have no id, have to find them manually - #probably won't work with two separators together - if (item_id[0] - 1,) == (i,): - found = True - elif (item_id[0] + 1,) == (i,): - found = True - elif (item_id[0],) == (i,): - found = True - if found: - item_tree.get_selection().select_path((i,)) - self.on_item_tree_cursor_changed(item_tree) - break - i += 1 - return False - - def findMenu(self, menus, path, iter, menu_id): - if not menus[path][2].get_desktop_file_path(): - if menu_id == menus[path][2].get_menu_id(): - menu_tree = self.tree.get_object('menu_tree') - menu_tree.expand_to_path(path) - menu_tree.get_selection().select_path(path) - return True - return False - if os.path.split(menus[path][2].get_desktop_file_path())[1] == menu_id: - menu_tree = self.tree.get_object('menu_tree') - menu_tree.expand_to_path(path) - menu_tree.get_selection().select_path(path) - return True - - def setupMenuTree(self): - self.menu_store = gtk.TreeStore(gtk.gdk.Pixbuf, str, object) - menus = self.tree.get_object('menu_tree') - column = gtk.TreeViewColumn(_('Name')) - column.set_spacing(4) - cell = gtk.CellRendererPixbuf() - column.pack_start(cell, False) - column.set_attributes(cell, pixbuf=0) - cell = gtk.CellRendererText() - cell.set_fixed_size(-1, 25) - column.pack_start(cell, True) - column.set_attributes(cell, markup=1) - column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) - menus.append_column(column) - menus.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, self.dnd_menus, gtk.gdk.ACTION_COPY) - menus.enable_model_drag_dest(self.dnd_both, gtk.gdk.ACTION_PRIVATE) - - def setupItemTree(self): - items = self.tree.get_object('item_tree') - column = gtk.TreeViewColumn(_('Show')) - cell = gtk.CellRendererToggle() - cell.connect('toggled', self.on_item_tree_show_toggled) - column.pack_start(cell, True) - column.set_attributes(cell, active=0) - #hide toggle for separators - column.set_cell_data_func(cell, self._cell_data_toggle_func) - items.append_column(column) - column = gtk.TreeViewColumn(_('Item')) - column.set_spacing(4) - cell = gtk.CellRendererPixbuf() - column.pack_start(cell, False) - column.set_attributes(cell, pixbuf=1) - cell = gtk.CellRendererText() - cell.set_fixed_size(-1, 25) - column.pack_start(cell, True) - column.set_attributes(cell, markup=2) - items.append_column(column) - self.item_store = gtk.ListStore(bool, gtk.gdk.Pixbuf, str, object) - items.set_model(self.item_store) - items.enable_model_drag_source(gtk.gdk.BUTTON1_MASK, self.dnd_items, gtk.gdk.ACTION_COPY) - items.enable_model_drag_dest(self.dnd_items, gtk.gdk.ACTION_PRIVATE) - - def _cell_data_toggle_func(self, tree_column, renderer, model, treeiter): - if model[treeiter][3].get_type() == matemenu.TYPE_SEPARATOR: - renderer.set_property('visible', False) - else: - renderer.set_property('visible', True) - - def loadMenus(self): - self.menu_store.clear() - for menu in self.editor.getMenus(): - iters = [None]*20 - self.loadMenu(iters, menu) - menu_tree = self.tree.get_object('menu_tree') - menu_tree.set_model(self.menu_store) - for menu in self.menu_store: - #this might not work for some reason - try: - menu_tree.expand_to_path(menu.path) - except: - pass - menu_tree.get_selection().select_path((0,)) - self.on_menu_tree_cursor_changed(menu_tree) - - def loadMenu(self, iters, parent, depth=0): - if depth == 0: - icon = util.getIcon(parent) - iters[depth] = self.menu_store.append(None, (icon, cgi.escape(parent.get_name()), parent)) - depth += 1 - for menu, show in self.editor.getMenus(parent): - if show: - name = cgi.escape(menu.get_name()) - else: - name = '' + cgi.escape(menu.get_name()) + '' - icon = util.getIcon(menu) - iters[depth] = self.menu_store.append(iters[depth-1], (icon, name, menu)) - self.loadMenu(iters, menu, depth) - depth -= 1 - - def loadItems(self, menu, menu_path): - self.item_store.clear() - for item, show in self.editor.getItems(menu): - menu_icon = None - if item.get_type() == matemenu.TYPE_SEPARATOR: - name = '---' - icon = None - elif item.get_type() == matemenu.TYPE_ENTRY: - if show: - name = cgi.escape(item.get_display_name()) - else: - name = '' + cgi.escape(item.get_display_name()) + '' - icon = util.getIcon(item) - else: - if show: - name = cgi.escape(item.get_name()) - else: - name = '' + cgi.escape(item.get_name()) + '' - icon = util.getIcon(item) - self.item_store.append((show, icon, name, item)) - - #this is a little timeout callback to insert new items after - #mate-desktop-item-edit has finished running - def waitForNewItemProcess(self, process, parent_id, file_path): - if process.poll() != None: - if os.path.isfile(file_path): - self.editor.insertExternalItem(os.path.split(file_path)[1], parent_id) - return False - return True - - def waitForNewMenuProcess(self, process, parent_id, file_path): - if process.poll() != None: - #hack for broken mate-desktop-item-edit - broken_path = os.path.join(os.path.split(file_path)[0], '.directory') - if os.path.isfile(broken_path): - os.rename(broken_path, file_path) - if os.path.isfile(file_path): - self.editor.insertExternalMenu(os.path.split(file_path)[1], parent_id) - return False - return True - - #this callback keeps you from editing the same item twice - def waitForEditProcess(self, process, file_path): - if process.poll() != None: - self.edit_pool.remove(file_path) - return False - return True - - def on_new_menu_button_clicked(self, button): - menu_tree = self.tree.get_object('menu_tree') - menus, iter = menu_tree.get_selection().get_selected() - if not iter: - parent = menus[(0,)][2] - menu_tree.expand_to_path((0,)) - menu_tree.get_selection().select_path((0,)) - else: - parent = menus[iter][2] - file_path = os.path.join(util.getUserDirectoryPath(), util.getUniqueFileId('alacarte-made', '.directory')) - process = subprocess.Popen(['mate-desktop-item-edit', file_path], env=os.environ) - gobject.timeout_add(100, self.waitForNewMenuProcess, process, parent.menu_id, file_path) - - def on_new_item_button_clicked(self, button): - menu_tree = self.tree.get_object('menu_tree') - menus, iter = menu_tree.get_selection().get_selected() - if not iter: - parent = menus[(0,)][2] - menu_tree.expand_to_path((0,)) - menu_tree.get_selection().select_path((0,)) - else: - parent = menus[iter][2] - file_path = os.path.join(util.getUserItemPath(), util.getUniqueFileId('alacarte-made', '.desktop')) - process = subprocess.Popen(['mate-desktop-item-edit', file_path], env=os.environ) - gobject.timeout_add(100, self.waitForNewItemProcess, process, parent.menu_id, file_path) - - def on_new_separator_button_clicked(self, button): - item_tree = self.tree.get_object('item_tree') - items, iter = item_tree.get_selection().get_selected() - if not iter: - return - else: - after = items[iter][3] - menu_tree = self.tree.get_object('menu_tree') - menus, iter = menu_tree.get_selection().get_selected() - parent = menus[iter][2] - self.editor.createSeparator(parent, after=after) - - def on_edit_delete_activate(self, menu): - item_tree = self.tree.get_object('item_tree') - items, iter = item_tree.get_selection().get_selected() - if not iter: - return - item = items[iter][3] - if item.get_type() == matemenu.TYPE_ENTRY: - self.editor.deleteItem(item) - elif item.get_type() == matemenu.TYPE_DIRECTORY: - self.editor.deleteMenu(item) - elif item.get_type() == matemenu.TYPE_SEPARATOR: - self.editor.deleteSeparator(item) - - def on_edit_revert_to_original_activate(self, menu): - item_tree = self.tree.get_object('item_tree') - items, iter = item_tree.get_selection().get_selected() - if not iter: - return - item = items[iter][3] - if item.get_type() == matemenu.TYPE_ENTRY: - self.editor.revertItem(item) - elif item.get_type() == matemenu.TYPE_DIRECTORY: - self.editor.revertMenu(item) - - def on_edit_properties_activate(self, menu): - item_tree = self.tree.get_object('item_tree') - items, iter = item_tree.get_selection().get_selected() - if not iter: - return - item = items[iter][3] - if item.get_type() not in (matemenu.TYPE_ENTRY, matemenu.TYPE_DIRECTORY): - return - - if item.get_type() == matemenu.TYPE_ENTRY: - 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('alacarte-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_type = 'Menu' - - if not os.path.isfile(file_path): - data = open(item.get_desktop_file_path()).read() - open(file_path, 'w').write(data) - self.editor._MenuEditor__addUndo([(file_type, os.path.split(file_path)[1]),]) - else: - self.editor._MenuEditor__addUndo([item,]) - if file_path not in self.edit_pool: - self.edit_pool.append(file_path) - process = subprocess.Popen(['mate-desktop-item-edit', file_path], env=os.environ) - gobject.timeout_add(100, self.waitForEditProcess, process, file_path) - - def on_menu_tree_cursor_changed(self, treeview): - menus, iter = treeview.get_selection().get_selected() - menu_path = menus.get_path(iter) - item_tree = self.tree.get_object('item_tree') - item_tree.get_selection().unselect_all() - self.loadItems(self.menu_store[menu_path][2], menu_path) - self.tree.get_object('edit_delete').set_sensitive(False) - self.tree.get_object('edit_revert_to_original').set_sensitive(False) - self.tree.get_object('edit_properties').set_sensitive(False) - self.tree.get_object('move_up_button').set_sensitive(False) - self.tree.get_object('move_down_button').set_sensitive(False) - self.tree.get_object('new_separator_button').set_sensitive(False) - - def on_menu_tree_drag_data_get(self, treeview, context, selection, target_id, etime): - menus, iter = treeview.get_selection().get_selected() - self.drag_data = menus[iter][2] - - def on_menu_tree_drag_data_received(self, treeview, context, x, y, selection, info, etime): - menus = treeview.get_model() - drop_info = treeview.get_dest_row_at_pos(x, y) - if drop_info: - path, position = drop_info - types = (gtk.TREE_VIEW_DROP_INTO_OR_BEFORE, gtk.TREE_VIEW_DROP_INTO_OR_AFTER) - if position not in types: - context.finish(False, False, etime) - return False - if selection.target in ('ALACARTE_ITEM_ROW', 'ALACARTE_MENU_ROW'): - if self.drag_data == None: - return False - item = self.drag_data - new_parent = menus[path][2] - treeview.get_selection().select_path(path) - if item.get_type() == matemenu.TYPE_ENTRY: - self.editor.copyItem(item, new_parent) - elif item.get_type() == matemenu.TYPE_DIRECTORY: - if self.editor.moveMenu(item, new_parent) == False: - self.loadUpdates() - else: - context.finish(False, False, etime) - context.finish(True, True, etime) - self.drag_data = None - - def on_item_tree_show_toggled(self, cell, path): - item = self.item_store[path][3] - if item.get_type() == matemenu.TYPE_SEPARATOR: - return - if self.item_store[path][0]: - self.editor.setVisible(item, False) - else: - self.editor.setVisible(item, True) - self.item_store[path][0] = not self.item_store[path][0] - - def on_item_tree_cursor_changed(self, treeview): - items, iter = treeview.get_selection().get_selected() - if iter is None: - return - item = items[iter][3] - self.tree.get_object('edit_delete').set_sensitive(True) - self.tree.get_object('new_separator_button').set_sensitive(True) - if self.editor.canRevert(item): - self.tree.get_object('edit_revert_to_original').set_sensitive(True) - else: - self.tree.get_object('edit_revert_to_original').set_sensitive(False) - if not item.get_type() == matemenu.TYPE_SEPARATOR: - self.tree.get_object('edit_properties').set_sensitive(True) - else: - self.tree.get_object('edit_properties').set_sensitive(False) - - # If first item... - if items.get_path(iter)[0] == 0: - self.tree.get_object('move_up_button').set_sensitive(False) - else: - self.tree.get_object('move_up_button').set_sensitive(True) - - # If last item... - if items.get_path(iter)[0] == (len(items)-1): - self.tree.get_object('move_down_button').set_sensitive(False) - else: - self.tree.get_object('move_down_button').set_sensitive(True) - - def on_item_tree_row_activated(self, treeview, path, column): - self.on_edit_properties_activate(None) - - def on_item_tree_popup_menu(self, item_tree, event=None): - model, iter = item_tree.get_selection().get_selected() - if event: - #don't show if it's not the right mouse button - if event.button != 3: - return - button = event.button - event_time = event.time - info = item_tree.get_path_at_pos(int(event.x), int(event.y)) - if info != None: - path, col, cellx, celly = info - item_tree.grab_focus() - item_tree.set_cursor(path, col, 0) - else: - path = model.get_path(iter) - button = 0 - event_time = 0 - item_tree.grab_focus() - item_tree.set_cursor(path, item_tree.get_columns()[0], 0) - popup = self.tree.get_object('edit_menu') - popup.popup(None, None, None, button, event_time) - #without this shift-f10 won't work - return True - - def on_item_tree_drag_data_get(self, treeview, context, selection, target_id, etime): - items, iter = treeview.get_selection().get_selected() - self.drag_data = items[iter][3] - - def on_item_tree_drag_data_received(self, treeview, context, x, y, selection, info, etime): - items = treeview.get_model() - types = (gtk.TREE_VIEW_DROP_BEFORE, gtk.TREE_VIEW_DROP_INTO_OR_BEFORE) - if selection.target == 'ALACARTE_ITEM_ROW': - drop_info = treeview.get_dest_row_at_pos(x, y) - before = None - after = None - if self.drag_data == None: - return False - item = self.drag_data - if drop_info: - path, position = drop_info - if position in types: - before = items[path][3] - else: - after = items[path][3] - else: - path = (len(items) - 1,) - after = items[path][3] - if item.get_type() == matemenu.TYPE_ENTRY: - self.editor.moveItem(item, item.get_parent(), before, after) - elif item.get_type() == matemenu.TYPE_DIRECTORY: - if self.editor.moveMenu(item, item.get_parent(), before, after) == False: - self.loadUpdates() - elif item.get_type() == matemenu.TYPE_SEPARATOR: - self.editor.moveSeparator(item, item.get_parent(), before, after) - context.finish(True, True, etime) - elif selection.target == 'text/plain': - if selection.data == None: - return False - menus, iter = self.tree.get_object('menu_tree').get_selection().get_selected() - parent = menus[iter][2] - drop_info = treeview.get_dest_row_at_pos(x, y) - before = None - after = None - if drop_info: - path, position = drop_info - if position in types: - before = items[path][3] - else: - after = items[path][3] - else: - path = (len(items) - 1,) - after = items[path][3] - file_path = urllib.unquote(selection.data).strip() - if not file_path.startswith('file:'): - return - myfile = gio.File(uri=file_path) - file_info = myfile.query_info(gio.FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE) - content_type = file_info.get_content_type() - if content_type == 'application/x-desktop': - input_stream = myfile.read() - open('/tmp/alacarte-dnd.desktop', 'w').write(input_stream.read()) - parser = util.DesktopParser('/tmp/alacarte-dnd.desktop') - 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) - 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.drag_data = None - - def on_item_tree_key_press_event(self, item_tree, event): - if event.keyval == gtk.keysyms.Delete: - self.on_edit_delete_activate(item_tree) - - def on_move_up_button_clicked(self, button): - item_tree = self.tree.get_object('item_tree') - items, iter = item_tree.get_selection().get_selected() - if not iter: - return - path = items.get_path(iter) - #at top, can't move up - if path[0] == 0: - return - item = items[path][3] - before = items[(path[0] - 1,)][3] - if item.get_type() == matemenu.TYPE_ENTRY: - self.editor.moveItem(item, item.get_parent(), before=before) - elif item.get_type() == matemenu.TYPE_DIRECTORY: - self.editor.moveMenu(item, item.get_parent(), before=before) - elif item.get_type() == matemenu.TYPE_SEPARATOR: - self.editor.moveSeparator(item, item.get_parent(), before=before) - - def on_move_down_button_clicked(self, button): - item_tree = self.tree.get_object('item_tree') - items, iter = item_tree.get_selection().get_selected() - if not iter: - return - path = items.get_path(iter) - #at bottom, can't move down - if path[0] == (len(items) - 1): - return - item = items[path][3] - after = items[path][3] - if item.get_type() == matemenu.TYPE_ENTRY: - self.editor.moveItem(item, item.get_parent(), after=after) - elif item.get_type() == matemenu.TYPE_DIRECTORY: - self.editor.moveMenu(item, item.get_parent(), after=after) - elif item.get_type() == matemenu.TYPE_SEPARATOR: - self.editor.moveSeparator(item, item.get_parent(), after=after) - - def on_mainwindow_undo(self, accelgroup, window, keyval, modifier): - self.editor.undo() - - def on_mainwindow_redo(self, accelgroup, window, keyval, modifier): - self.editor.redo() - - def on_help_button_clicked(self, *args): - gtk.show_uri(gtk.gdk.screen_get_default(), "ghelp:user-guide#menu-editor", gtk.get_current_event_time()) - - def on_revert_button_clicked(self, button): - dialog = self.tree.get_object('revertdialog') - dialog.set_transient_for(self.tree.get_object('mainwindow')) - dialog.show_all() - if dialog.run() == gtk.RESPONSE_YES: - self.editor.revert() - dialog.hide() - - def on_close_button_clicked(self, button): - try: - self.tree.get_object('mainwindow').hide() - except: - pass - gobject.timeout_add(10, self.quit) - - def on_style_set(self, *args): - self.loadUpdates() - - def quit(self): - self.editor.quit() - gtk.main_quit() diff --git a/Alacarte/Makefile.am b/Alacarte/Makefile.am deleted file mode 100644 index 6359d93..0000000 --- a/Alacarte/Makefile.am +++ /dev/null @@ -1,24 +0,0 @@ -## Process this file with automake to produce Makefile.in - -appdir = $(pythondir)/Alacarte -app_PYTHON = __init__.py MainWindow.py MenuEditor.py util.py -nodist_app_PYTHON = config.py - -config.py: config.py.in - sed \ - -e s!\@prefix\@!$(prefix)! \ - -e s!\@datadir\@!$(datadir)! \ - -e s!\@pkgdatadir\@!$(pkgdatadir)! \ - -e s!\@libexecdir\@!$(libexecdir)! \ - -e s!\@libdir\@!$(libdir)! \ - -e s!\@PACKAGE\@!$(PACKAGE)! \ - -e s!\@VERSION\@!$(VERSION)! \ - -e s!\@GETTEXT_PACKAGE\@!$(GETTEXT_PACKAGE)! \ - < $< > $@ -config.py: Makefile - -CLEANFILES = config.py -EXTRA_DIST = config.py.in - -all-local: config.py - diff --git a/Alacarte/Makefile.in b/Alacarte/Makefile.in deleted file mode 100644 index f4f6510..0000000 --- a/Alacarte/Makefile.in +++ /dev/null @@ -1,482 +0,0 @@ -# Makefile.in generated by automake 1.11.1 from Makefile.am. -# @configure_input@ - -# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, -# Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -@SET_MAKE@ -VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkglibexecdir = $(libexecdir)/@PACKAGE@ -am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -install_sh_DATA = $(install_sh) -c -m 644 -install_sh_PROGRAM = $(install_sh) -c -install_sh_SCRIPT = $(install_sh) -c -INSTALL_HEADER = $(INSTALL_DATA) -transform = $(program_transform_name) -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -subdir = Alacarte -DIST_COMMON = $(app_PYTHON) $(srcdir)/Makefile.am \ - $(srcdir)/Makefile.in -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ - $(top_srcdir)/configure.ac -am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ - $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = $(top_builddir)/config.h -CONFIG_CLEAN_FILES = -CONFIG_CLEAN_VPATH_FILES = -SOURCES = -DIST_SOURCES = -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__installdirs = "$(DESTDIR)$(appdir)" "$(DESTDIR)$(appdir)" -py_compile = $(top_srcdir)/py-compile -DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) -ACLOCAL = @ACLOCAL@ -ALACARTE_CFLAGS = @ALACARTE_CFLAGS@ -ALACARTE_LIBS = @ALACARTE_LIBS@ -ALL_LINGUAS = @ALL_LINGUAS@ -AMTAR = @AMTAR@ -AUTOCONF = @AUTOCONF@ -AUTOHEADER = @AUTOHEADER@ -AUTOMAKE = @AUTOMAKE@ -AWK = @AWK@ -CATALOGS = @CATALOGS@ -CATOBJEXT = @CATOBJEXT@ -CC = @CC@ -CCDEPMODE = @CCDEPMODE@ -CFLAGS = @CFLAGS@ -CPP = @CPP@ -CPPFLAGS = @CPPFLAGS@ -CYGPATH_W = @CYGPATH_W@ -DATADIRNAME = @DATADIRNAME@ -DEFS = @DEFS@ -DEPDIR = @DEPDIR@ -ECHO_C = @ECHO_C@ -ECHO_N = @ECHO_N@ -ECHO_T = @ECHO_T@ -EGREP = @EGREP@ -EXEEXT = @EXEEXT@ -GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ -GMOFILES = @GMOFILES@ -GMSGFMT = @GMSGFMT@ -GREP = @GREP@ -INSTALL = @INSTALL@ -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -INSTOBJEXT = @INSTOBJEXT@ -INTLLIBS = @INTLLIBS@ -INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@ -INTLTOOL_MERGE = @INTLTOOL_MERGE@ -INTLTOOL_PERL = @INTLTOOL_PERL@ -INTLTOOL_UPDATE = @INTLTOOL_UPDATE@ -LDFLAGS = @LDFLAGS@ -LIBOBJS = @LIBOBJS@ -LIBS = @LIBS@ -LTLIBOBJS = @LTLIBOBJS@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -MKDIR_P = @MKDIR_P@ -MKINSTALLDIRS = @MKINSTALLDIRS@ -MSGFMT = @MSGFMT@ -MSGFMT_OPTS = @MSGFMT_OPTS@ -MSGMERGE = @MSGMERGE@ -OBJEXT = @OBJEXT@ -PACKAGE = @PACKAGE@ -PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ -PACKAGE_NAME = @PACKAGE_NAME@ -PACKAGE_STRING = @PACKAGE_STRING@ -PACKAGE_TARNAME = @PACKAGE_TARNAME@ -PACKAGE_URL = @PACKAGE_URL@ -PACKAGE_VERSION = @PACKAGE_VERSION@ -PATH_SEPARATOR = @PATH_SEPARATOR@ -PKG_CONFIG = @PKG_CONFIG@ -PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ -PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ -POFILES = @POFILES@ -POSUB = @POSUB@ -PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@ -PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@ -PYTHON = @PYTHON@ -PYTHON2_4 = @PYTHON2_4@ -PYTHON2_5 = @PYTHON2_5@ -PYTHON2_6 = @PYTHON2_6@ -PYTHON2_7 = @PYTHON2_7@ -PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@ -PYTHON_PLATFORM = @PYTHON_PLATFORM@ -PYTHON_PREFIX = @PYTHON_PREFIX@ -PYTHON_VERSION = @PYTHON_VERSION@ -SET_MAKE = @SET_MAKE@ -SHELL = @SHELL@ -STRIP = @STRIP@ -USE_NLS = @USE_NLS@ -VERSION = @VERSION@ -XGETTEXT = @XGETTEXT@ -abs_builddir = @abs_builddir@ -abs_srcdir = @abs_srcdir@ -abs_top_builddir = @abs_top_builddir@ -abs_top_srcdir = @abs_top_srcdir@ -ac_ct_CC = @ac_ct_CC@ -am__include = @am__include@ -am__leading_dot = @am__leading_dot@ -am__quote = @am__quote@ -am__tar = @am__tar@ -am__untar = @am__untar@ -bindir = @bindir@ -build_alias = @build_alias@ -builddir = @builddir@ -datadir = @datadir@ -datarootdir = @datarootdir@ -docdir = @docdir@ -dvidir = @dvidir@ -exec_prefix = @exec_prefix@ -host_alias = @host_alias@ -htmldir = @htmldir@ -includedir = @includedir@ -infodir = @infodir@ -install_sh = @install_sh@ -libdir = @libdir@ -libexecdir = @libexecdir@ -localedir = @localedir@ -localstatedir = @localstatedir@ -mandir = @mandir@ -mkdir_p = @mkdir_p@ -oldincludedir = @oldincludedir@ -pdfdir = @pdfdir@ -pkgpyexecdir = @pkgpyexecdir@ -pkgpythondir = @pkgpythondir@ -prefix = @prefix@ -program_transform_name = @program_transform_name@ -psdir = @psdir@ -pyexecdir = @pyexecdir@ -pythondir = @pythondir@ -sbindir = @sbindir@ -sharedstatedir = @sharedstatedir@ -srcdir = @srcdir@ -sysconfdir = @sysconfdir@ -target_alias = @target_alias@ -top_build_prefix = @top_build_prefix@ -top_builddir = @top_builddir@ -top_srcdir = @top_srcdir@ -appdir = $(pythondir)/Alacarte -app_PYTHON = __init__.py MainWindow.py MenuEditor.py util.py -nodist_app_PYTHON = config.py -CLEANFILES = config.py -EXTRA_DIST = config.py.in -all: all-am - -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) - @for dep in $?; do \ - case '$(am__configure_deps)' in \ - *$$dep*) \ - ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ - && { if test -f $@; then exit 0; else break; fi; }; \ - exit 1;; \ - esac; \ - done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Alacarte/Makefile'; \ - $(am__cd) $(top_srcdir) && \ - $(AUTOMAKE) --gnu Alacarte/Makefile -.PRECIOUS: Makefile -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - @case '$?' in \ - *config.status*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ - *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ - esac; - -$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh - -$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh -$(am__aclocal_m4_deps): -install-appPYTHON: $(app_PYTHON) - @$(NORMAL_INSTALL) - test -z "$(appdir)" || $(MKDIR_P) "$(DESTDIR)$(appdir)" - @list='$(app_PYTHON)'; dlist=; list2=; test -n "$(appdir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \ - if test -f $$b$$p; then \ - $(am__strip_dir) \ - dlist="$$dlist $$f"; \ - list2="$$list2 $$b$$p"; \ - else :; fi; \ - done; \ - for file in $$list2; do echo $$file; done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(appdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(appdir)" || exit $$?; \ - done || exit $$?; \ - if test -n "$$dlist"; then \ - if test -z "$(DESTDIR)"; then \ - PYTHON=$(PYTHON) $(py_compile) --basedir "$(appdir)" $$dlist; \ - else \ - PYTHON=$(PYTHON) $(py_compile) --destdir "$(DESTDIR)" --basedir "$(appdir)" $$dlist; \ - fi; \ - else :; fi - -uninstall-appPYTHON: - @$(NORMAL_UNINSTALL) - @list='$(app_PYTHON)'; test -n "$(appdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - filesc=`echo "$$files" | sed 's|$$|c|'`; \ - fileso=`echo "$$files" | sed 's|$$|o|'`; \ - echo " ( cd '$(DESTDIR)$(appdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(appdir)" && rm -f $$files || exit $$?; \ - echo " ( cd '$(DESTDIR)$(appdir)' && rm -f" $$filesc ")"; \ - cd "$(DESTDIR)$(appdir)" && rm -f $$filesc || exit $$?; \ - echo " ( cd '$(DESTDIR)$(appdir)' && rm -f" $$fileso ")"; \ - cd "$(DESTDIR)$(appdir)" && rm -f $$fileso -install-nodist_appPYTHON: $(nodist_app_PYTHON) - @$(NORMAL_INSTALL) - test -z "$(appdir)" || $(MKDIR_P) "$(DESTDIR)$(appdir)" - @list='$(nodist_app_PYTHON)'; dlist=; list2=; test -n "$(appdir)" || list=; \ - for p in $$list; do \ - if test -f "$$p"; then b=; else b="$(srcdir)/"; fi; \ - if test -f $$b$$p; then \ - $(am__strip_dir) \ - dlist="$$dlist $$f"; \ - list2="$$list2 $$b$$p"; \ - else :; fi; \ - done; \ - for file in $$list2; do echo $$file; done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(appdir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(appdir)" || exit $$?; \ - done || exit $$?; \ - if test -n "$$dlist"; then \ - if test -z "$(DESTDIR)"; then \ - PYTHON=$(PYTHON) $(py_compile) --basedir "$(appdir)" $$dlist; \ - else \ - PYTHON=$(PYTHON) $(py_compile) --destdir "$(DESTDIR)" --basedir "$(appdir)" $$dlist; \ - fi; \ - else :; fi - -uninstall-nodist_appPYTHON: - @$(NORMAL_UNINSTALL) - @list='$(nodist_app_PYTHON)'; test -n "$(appdir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - test -n "$$files" || exit 0; \ - filesc=`echo "$$files" | sed 's|$$|c|'`; \ - fileso=`echo "$$files" | sed 's|$$|o|'`; \ - echo " ( cd '$(DESTDIR)$(appdir)' && rm -f" $$files ")"; \ - cd "$(DESTDIR)$(appdir)" && rm -f $$files || exit $$?; \ - echo " ( cd '$(DESTDIR)$(appdir)' && rm -f" $$filesc ")"; \ - cd "$(DESTDIR)$(appdir)" && rm -f $$filesc || exit $$?; \ - echo " ( cd '$(DESTDIR)$(appdir)' && rm -f" $$fileso ")"; \ - cd "$(DESTDIR)$(appdir)" && rm -f $$fileso -tags: TAGS -TAGS: - -ctags: CTAGS -CTAGS: - - -distdir: $(DISTFILES) - @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ - list='$(DISTFILES)'; \ - dist_files=`for file in $$list; do echo $$file; done | \ - sed -e "s|^$$srcdirstrip/||;t" \ - -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ - case $$dist_files in \ - */*) $(MKDIR_P) `echo "$$dist_files" | \ - sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ - sort -u` ;; \ - esac; \ - for file in $$dist_files; do \ - if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - if test -d $$d/$$file; then \ - dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test -d "$(distdir)/$$file"; then \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ - find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ - fi; \ - cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ - else \ - test -f "$(distdir)/$$file" \ - || cp -p $$d/$$file "$(distdir)/$$file" \ - || exit 1; \ - fi; \ - done -check-am: all-am -check: check-am -all-am: Makefile all-local -installdirs: - for dir in "$(DESTDIR)$(appdir)" "$(DESTDIR)$(appdir)"; do \ - test -z "$$dir" || $(MKDIR_P) "$$dir"; \ - done -install: install-am -install-exec: install-exec-am -install-data: install-data-am -uninstall: uninstall-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am - -installcheck: installcheck-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ - install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ - `test -z '$(STRIP)' || \ - echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install -mostlyclean-generic: - -clean-generic: - -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) - -distclean-generic: - -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) - -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) - -maintainer-clean-generic: - @echo "This command is intended for maintainers to use" - @echo "it deletes files that may require special tools to rebuild." -clean: clean-am - -clean-am: clean-generic mostlyclean-am - -distclean: distclean-am - -rm -f Makefile -distclean-am: clean-am distclean-generic - -dvi: dvi-am - -dvi-am: - -html: html-am - -html-am: - -info: info-am - -info-am: - -install-data-am: install-appPYTHON install-nodist_appPYTHON - -install-dvi: install-dvi-am - -install-dvi-am: - -install-exec-am: - -install-html: install-html-am - -install-html-am: - -install-info: install-info-am - -install-info-am: - -install-man: - -install-pdf: install-pdf-am - -install-pdf-am: - -install-ps: install-ps-am - -install-ps-am: - -installcheck-am: - -maintainer-clean: maintainer-clean-am - -rm -f Makefile -maintainer-clean-am: distclean-am maintainer-clean-generic - -mostlyclean: mostlyclean-am - -mostlyclean-am: mostlyclean-generic - -pdf: pdf-am - -pdf-am: - -ps: ps-am - -ps-am: - -uninstall-am: uninstall-appPYTHON uninstall-nodist_appPYTHON - -.MAKE: install-am install-strip - -.PHONY: all all-am all-local check check-am clean clean-generic \ - distclean distclean-generic distdir dvi dvi-am html html-am \ - info info-am install install-am install-appPYTHON install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-nodist_appPYTHON \ - install-pdf install-pdf-am install-ps install-ps-am \ - install-strip installcheck installcheck-am installdirs \ - maintainer-clean maintainer-clean-generic mostlyclean \ - mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am \ - uninstall-appPYTHON uninstall-nodist_appPYTHON - - -config.py: config.py.in - sed \ - -e s!\@prefix\@!$(prefix)! \ - -e s!\@datadir\@!$(datadir)! \ - -e s!\@pkgdatadir\@!$(pkgdatadir)! \ - -e s!\@libexecdir\@!$(libexecdir)! \ - -e s!\@libdir\@!$(libdir)! \ - -e s!\@PACKAGE\@!$(PACKAGE)! \ - -e s!\@VERSION\@!$(VERSION)! \ - -e s!\@GETTEXT_PACKAGE\@!$(GETTEXT_PACKAGE)! \ - < $< > $@ -config.py: Makefile - -all-local: config.py - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/Alacarte/MenuEditor.py b/Alacarte/MenuEditor.py deleted file mode 100644 index 5ec5b21..0000000 --- a/Alacarte/MenuEditor.py +++ /dev/null @@ -1,775 +0,0 @@ -# -*- coding: utf-8 -*- -# Alacarte Menu Editor - Simple fd.o Compliant Menu Editor -# Copyright (C) 2006 Travis Watkins, Heinrich Wendel -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -import os, re, xml.dom.minidom, locale -import matemenu -from Alacarte import util - -class Menu: - tree = None - visible_tree = None - path = None - dom = None - -class MenuEditor: - #lists for undo/redo functionality - __undo = [] - __redo = [] - - def __init__(self): - self.locale = locale.getdefaultlocale()[0] - self.__loadMenus() - - def __loadMenus(self): - self.applications = Menu() - self.applications.tree = matemenu.lookup_tree('mate-applications.menu', matemenu.FLAGS_SHOW_EMPTY|matemenu.FLAGS_INCLUDE_EXCLUDED|matemenu.FLAGS_INCLUDE_NODISPLAY|matemenu.FLAGS_SHOW_ALL_SEPARATORS) - self.applications.visible_tree = matemenu.lookup_tree('mate-applications.menu') - self.applications.tree.sort_key = matemenu.SORT_DISPLAY_NAME - self.applications.visible_tree.sort_key = matemenu.SORT_DISPLAY_NAME - self.applications.path = os.path.join(util.getUserMenuPath(), self.applications.tree.get_menu_file()) - if not os.path.isfile(self.applications.path): - self.applications.dom = xml.dom.minidom.parseString(util.getUserMenuXml(self.applications.tree)) - else: - self.applications.dom = xml.dom.minidom.parse(self.applications.path) - self.__remove_whilespace_nodes(self.applications.dom) - - self.settings = Menu() - self.settings.tree = matemenu.lookup_tree('mate-settings.menu', matemenu.FLAGS_SHOW_EMPTY|matemenu.FLAGS_INCLUDE_EXCLUDED|matemenu.FLAGS_INCLUDE_NODISPLAY|matemenu.FLAGS_SHOW_ALL_SEPARATORS) - self.settings.visible_tree = matemenu.lookup_tree('mate-settings.menu') - self.settings.tree.sort_key = matemenu.SORT_DISPLAY_NAME - self.settings.visible_tree.sort_key = matemenu.SORT_DISPLAY_NAME - self.settings.path = os.path.join(util.getUserMenuPath(), self.settings.tree.get_menu_file()) - if not os.path.isfile(self.settings.path): - self.settings.dom = xml.dom.minidom.parseString(util.getUserMenuXml(self.settings.tree)) - else: - self.settings.dom = xml.dom.minidom.parse(self.settings.path) - self.__remove_whilespace_nodes(self.settings.dom) - - self.save(True) - - def save(self, from_loading=False): - for menu in ('applications', 'settings'): - fd = open(getattr(self, menu).path, 'w') - fd.write(re.sub("\n[\s]*([^\n<]*)\n[\s]*\n', ''))) - fd.close() - if not from_loading: - self.__loadMenus() - - def quit(self): - for file_name in os.listdir(util.getUserItemPath()): - if file_name[-6:-2] in ('redo', 'undo'): - file_path = os.path.join(util.getUserItemPath(), file_name) - os.unlink(file_path) - for file_name in os.listdir(util.getUserDirectoryPath()): - if file_name[-6:-2] in ('redo', 'undo'): - file_path = os.path.join(util.getUserDirectoryPath(), file_name) - os.unlink(file_path) - for file_name in os.listdir(util.getUserMenuPath()): - if file_name[-6:-2] in ('redo', 'undo'): - file_path = os.path.join(util.getUserMenuPath(), file_name) - os.unlink(file_path) - - def revert(self): - for name in ('applications', 'settings'): - menu = getattr(self, name) - self.revertTree(menu.tree.root) - path = os.path.join(util.getUserMenuPath(), menu.tree.get_menu_file()) - try: - os.unlink(path) - except OSError: - pass - #reload DOM for each menu - if not os.path.isfile(menu.path): - menu.dom = xml.dom.minidom.parseString(util.getUserMenuXml(menu.tree)) - else: - menu.dom = xml.dom.minidom.parse(menu.path) - self.__remove_whilespace_nodes(menu.dom) - #reset undo/redo, no way to recover from this - self.__undo, self.__redo = [], [] - self.save() - - def revertTree(self, menu): - for child in menu.get_contents(): - if child.get_type() == matemenu.TYPE_DIRECTORY: - self.revertTree(child) - elif child.get_type() == matemenu.TYPE_ENTRY: - self.revertItem(child) - self.revertMenu(menu) - - def undo(self): - if len(self.__undo) == 0: - return - files = self.__undo.pop() - redo = [] - for file_path in files: - new_path = file_path.rsplit('.', 1)[0] - redo_path = util.getUniqueRedoFile(new_path) - data = open(new_path).read() - open(redo_path, 'w').write(data) - data = open(file_path).read() - open(new_path, 'w').write(data) - os.unlink(file_path) - redo.append(redo_path) - #reload DOM to make changes stick - for name in ('applications', 'settings'): - menu = getattr(self, name) - if not os.path.isfile(menu.path): - menu.dom = xml.dom.minidom.parseString(util.getUserMenuXml(menu.tree)) - else: - menu.dom = xml.dom.minidom.parse(menu.path) - self.__remove_whilespace_nodes(menu.dom) - self.__redo.append(redo) - - def redo(self): - if len(self.__redo) == 0: - return - files = self.__redo.pop() - undo = [] - for file_path in files: - new_path = file_path.rsplit('.', 1)[0] - undo_path = util.getUniqueUndoFile(new_path) - data = open(new_path).read() - open(undo_path, 'w').write(data) - data = open(file_path).read() - open(new_path, 'w').write(data) - os.unlink(file_path) - undo.append(undo_path) - #reload DOM to make changes stick - for name in ('applications', 'settings'): - menu = getattr(self, name) - if not os.path.isfile(menu.path): - menu.dom = xml.dom.minidom.parseString(util.getUserMenuXml(menu.tree)) - else: - menu.dom = xml.dom.minidom.parse(menu.path) - self.__remove_whilespace_nodes(menu.dom) - self.__undo.append(undo) - - def getMenus(self, parent=None): - if parent == None: - yield self.applications.tree.root - yield self.settings.tree.root - else: - for menu in parent.get_contents(): - if menu.get_type() == matemenu.TYPE_DIRECTORY: - yield (menu, self.__isVisible(menu)) - - def getItems(self, menu): - for item in menu.get_contents(): - if item.get_type() == matemenu.TYPE_SEPARATOR: - yield (item, True) - else: - if item.get_type() == matemenu.TYPE_ENTRY and item.get_desktop_file_id()[-19:] == '-usercustom.desktop': - continue - yield (item, self.__isVisible(item)) - - def canRevert(self, item): - if item.get_type() == matemenu.TYPE_ENTRY: - if util.getItemPath(item.get_desktop_file_id()): - path = util.getUserItemPath() - if os.path.isfile(os.path.join(path, item.get_desktop_file_id())): - return True - elif item.get_type() == matemenu.TYPE_DIRECTORY: - if item.get_desktop_file_path(): - file_id = os.path.split(item.get_desktop_file_path())[1] - else: - file_id = item.get_menu_id() + '.directory' - if util.getDirectoryPath(file_id): - path = util.getUserDirectoryPath() - if os.path.isfile(os.path.join(path, file_id)): - return True - return False - - def setVisible(self, item, visible): - dom = self.__getMenu(item).dom - if item.get_type() == matemenu.TYPE_ENTRY: - self.__addUndo([self.__getMenu(item), item]) - 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) - else: - self.__addXmlFilename(menu_xml, dom, item.get_desktop_file_id(), 'Exclude') - self.__addXmlTextElement(menu_xml, 'AppDir', util.getUserItemPath(), dom) - elif item.get_type() == matemenu.TYPE_DIRECTORY: - self.__addUndo([self.__getMenu(item), item]) - #don't mess with it if it's empty - if len(item.get_contents()) == 0: - return - 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.__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) - self.insertExternalItem(file_id, parent.menu_id, before, after) - - def insertExternalItem(self, file_id, parent_id, before=None, after=None): - parent = self.__findMenu(parent_id) - dom = self.__getMenu(parent).dom - self.__addItem(parent, file_id, dom) - self.__positionItem(parent, ('Item', file_id), before, after) - 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) - dom = self.__getMenu(parent).dom - self.__addXmlDefaultLayout(self.__getXmlMenu(self.__getPath(parent), dom, dom) , dom) - menu_xml = self.__getXmlMenu(self.__getPath(parent) + '/' + menu_id, dom, dom) - self.__addXmlTextElement(menu_xml, 'Directory', file_id, dom) - self.__positionItem(parent, ('Menu', menu_id), before, after) - self.__addUndo([self.__getMenu(parent), ('Menu', file_id)]) - self.save() - - def createSeparator(self, parent, before=None, after=None): - self.__positionItem(parent, ('Separator',), before, after) - self.__addUndo([self.__getMenu(parent), ('Separator',)]) - self.save() - - def editItem(self, item, icon, name, comment, command, use_term, parent=None, final=True): - #if nothing changed don't make a user copy - if icon == item.get_icon() and name == item.get_display_name() and comment == item.get_comment() and command == item.get_exec() and use_term == item.get_launch_in_terminal(): - return - #hack, item.get_parent() seems to fail a lot - if not parent: - parent = item.get_parent() - if final: - self.__addUndo([self.__getMenu(parent), item]) - self.__writeItem(item, icon, name, comment, command, use_term) - if final: - dom = self.__getMenu(parent).dom - menu_xml = self.__getXmlMenu(self.__getPath(parent), dom, dom) - self.__addXmlTextElement(menu_xml, 'AppDir', util.getUserItemPath(), dom) - self.save() - - def editMenu(self, menu, icon, name, comment, final=True): - #if nothing changed don't make a user copy - if icon == menu.get_icon() and name == menu.get_name() and comment == menu.get_comment(): - return - #we don't use this, we just need to make sure the exists - #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) - if final: - self.__addXmlTextElement(menu_xml, 'DirectoryDir', util.getUserDirectoryPath(), dom) - self.__addUndo([self.__getMenu(menu), menu]) - self.save() - - 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) - file_id = util.getUniqueFileId(item.get_name(), '.desktop') - out_path = os.path.join(util.getUserItemPath(), file_id) - keyfile.write(open(out_path, 'w')) - 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)]) - self.save() - return file_id - - def moveItem(self, item, new_parent, before=None, after=None): - undo = [] - if item.get_parent() != new_parent: - #hide old item - self.deleteItem(item) - undo.append(item) - file_id = self.copyItem(item, new_parent) - item = ('Item', file_id) - undo.append(item) - self.__positionItem(new_parent, item, before, after) - undo.append(self.__getMenu(new_parent)) - self.__addUndo(undo) - self.save() - - def moveMenu(self, menu, new_parent, before=None, after=None): - parent = new_parent - #don't move a menu into it's child - while parent.get_parent(): - parent = parent.get_parent() - if parent == menu: - return False - - #don't move a menu into itself - if new_parent == menu: - return False - - #can't move between top-level menus - if self.__getMenu(menu) != self.__getMenu(new_parent): - return False - if menu.get_parent() != new_parent: - dom = self.__getMenu(menu).dom - root_path = self.__getPath(menu).split('/', 1)[0] - xml_root = self.__getXmlMenu(root_path, dom, dom) - old_path = self.__getPath(menu).split('/', 1)[1] - #root menu's path has no / - if '/' in self.__getPath(new_parent): - new_path = self.__getPath(new_parent).split('/', 1)[1] + '/' + menu.get_menu_id() - else: - new_path = menu.get_menu_id() - self.__addXmlMove(xml_root, old_path, new_path, dom) - self.__positionItem(new_parent, menu, before, after) - self.__addUndo([self.__getMenu(new_parent),]) - self.save() - - def moveSeparator(self, separator, new_parent, before=None, after=None): - self.__positionItem(new_parent, separator, before, after) - self.__addUndo([self.__getMenu(new_parent),]) - self.save() - - def deleteItem(self, item): - self.__writeItem(item, hidden=True) - self.__addUndo([item,]) - self.save() - - def deleteMenu(self, menu): - dom = self.__getMenu(menu).dom - menu_xml = self.__getXmlMenu(self.__getPath(menu), dom, dom) - self.__addDeleted(menu_xml, dom) - self.__addUndo([self.__getMenu(menu),]) - self.save() - - def deleteSeparator(self, item): - parent = item.get_parent() - contents = parent.get_contents() - contents.remove(item) - layout = self.__createLayout(contents) - dom = self.__getMenu(parent).dom - menu_xml = self.__getXmlMenu(self.__getPath(parent), dom, dom) - self.__addXmlLayout(menu_xml, layout, dom) - self.__addUndo([self.__getMenu(item.get_parent()),]) - self.save() - - def revertItem(self, item): - if not self.canRevert(item): - return - self.__addUndo([item,]) - try: - os.remove(item.get_desktop_file_path()) - except OSError: - pass - self.save() - - def revertMenu(self, menu): - if not self.canRevert(menu): - return - #wtf happened here? oh well, just bail - if not menu.get_desktop_file_path(): - return - self.__addUndo([menu,]) - file_id = os.path.split(menu.get_desktop_file_path())[1] - path = os.path.join(util.getUserDirectoryPath(), file_id) - try: - os.remove(path) - except OSError: - pass - self.save() - - #private stuff - def __addUndo(self, items): - self.__undo.append([]) - for item in items: - if isinstance(item, Menu): - file_path = item.path - elif isinstance(item, tuple): - if item[0] == 'Item': - file_path = os.path.join(util.getUserItemPath(), item[1]) - if not os.path.isfile(file_path): - file_path = util.getItemPath(item[1]) - elif item[0] == 'Menu': - file_path = os.path.join(util.getUserDirectoryPath(), item[1]) - if not os.path.isfile(file_path): - file_path = util.getDirectoryPath(item[1]) - else: - continue - elif item.get_type() == matemenu.TYPE_DIRECTORY: - if item.get_desktop_file_path() == None: - continue - file_path = os.path.join(util.getUserDirectoryPath(), os.path.split(item.get_desktop_file_path())[1]) - if not os.path.isfile(file_path): - file_path = item.get_desktop_file_path() - elif item.get_type() == matemenu.TYPE_ENTRY: - file_path = os.path.join(util.getUserItemPath(), item.get_desktop_file_id()) - if not os.path.isfile(file_path): - file_path = item.get_desktop_file_path() - else: - continue - data = open(file_path).read() - undo_path = util.getUniqueUndoFile(file_path) - open(undo_path, 'w').write(data) - self.__undo[-1].append(undo_path) - - def __getMenu(self, item): - root = item.get_parent() - if not root: - #already at the top - root = item - else: - while True: - if root.get_parent(): - root = root.get_parent() - else: - break - if root.menu_id == self.applications.tree.root.menu_id: - return self.applications - return self.settings - - def __findMenu(self, menu_id, parent=None): - if parent == None: - menu = self.__findMenu(menu_id, self.applications.tree.root) - if menu != None: - return menu - else: - return self.__findMenu(menu_id, self.settings.tree.root) - if menu_id == self.applications.tree.root.menu_id: - return self.applications.tree.root - if menu_id == self.settings.tree.root.menu_id: - return self.settings.tree.root - for item in parent.get_contents(): - if item.get_type() == matemenu.TYPE_DIRECTORY: - if item.menu_id == menu_id: - return item - menu = self.__findMenu(menu_id, item) - if menu != None: - return menu - - def __isVisible(self, item): - if item.get_type() == matemenu.TYPE_ENTRY: - return not (item.get_is_excluded() or item.get_is_nodisplay()) - menu = self.__getMenu(item) - if menu == self.applications: - root = self.applications.visible_tree.root - elif menu == self.settings: - root = self.settings.visible_tree.root - if item.get_type() == matemenu.TYPE_DIRECTORY: - if self.__findMenu(item.menu_id, root) == None: - return False - return True - - def __getPath(self, menu, path=None): - if not path: - path = menu.tree.root.get_menu_id() - if menu.get_parent(): - path = self.__getPath(menu.get_parent(), path) - path += '/' - path += menu.menu_id - return path - - def __getXmlMenu(self, path, element, dom): - if '/' in path: - (name, path) = path.split('/', 1) - else: - name = path - path = '' - - found = None - for node in self.__getXmlNodesByName('Menu', element): - for child in self.__getXmlNodesByName('Name', node): - if child.childNodes[0].nodeValue == name: - if path: - found = self.__getXmlMenu(path, node, dom) - else: - found = node - break - if found: - break - if not found: - node = self.__addXmlMenuElement(element, name, dom) - if path: - found = self.__getXmlMenu(path, node, dom) - else: - found = node - - return found - - def __addXmlMenuElement(self, element, name, dom): - node = dom.createElement('Menu') - self.__addXmlTextElement(node, 'Name', name, dom) - return element.appendChild(node) - - def __addXmlTextElement(self, element, name, text, dom): - for temp in element.childNodes: - if temp.nodeName == name: - if temp.childNodes[0].nodeValue == text: - return - node = dom.createElement(name) - text = dom.createTextNode(text) - node.appendChild(text) - return element.appendChild(node) - - def __addXmlFilename(self, element, dom, filename, type = 'Include'): - # remove old filenames - for node in self.__getXmlNodesByName(['Include', 'Exclude'], element): - if node.childNodes[0].nodeName == 'Filename' and node.childNodes[0].childNodes[0].nodeValue == filename: - element.removeChild(node) - - # add new filename - node = dom.createElement(type) - node.appendChild(self.__addXmlTextElement(node, 'Filename', filename, dom)) - return element.appendChild(node) - - def __addDeleted(self, element, dom): - 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: - file_path = item.get_desktop_file_path() - 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(name, '.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')) - return file_id - - def __writeMenu(self, menu=None, icon=None, name=None, comment=None, no_display=None): - if menu: - 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: - 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')) - return file_id - - def __getXmlNodesByName(self, name, element): - for child in element.childNodes: - if child.nodeType == xml.dom.Node.ELEMENT_NODE: - if isinstance(name, str) and child.nodeName == name: - yield child - elif isinstance(name, list) or isinstance(name, tuple): - if child.nodeName in name: - yield child - - def __remove_whilespace_nodes(self, node): - remove_list = [] - for child in node.childNodes: - if child.nodeType == xml.dom.minidom.Node.TEXT_NODE: - child.data = child.data.strip() - if not child.data.strip(): - remove_list.append(child) - elif child.hasChildNodes(): - self.__remove_whilespace_nodes(child) - for node in remove_list: - node.parentNode.removeChild(node) - - def __addXmlMove(self, element, old, new, dom): - if not self.__undoMoves(element, old, new, dom): - node = dom.createElement('Move') - node.appendChild(self.__addXmlTextElement(node, 'Old', old, dom)) - node.appendChild(self.__addXmlTextElement(node, 'New', new, dom)) - #are parsed in reverse order, need to put at the beginning - return element.insertBefore(node, element.firstChild) - - def __addXmlLayout(self, element, layout, dom): - # remove old layout - for node in self.__getXmlNodesByName('Layout', element): - element.removeChild(node) - - # add new layout - node = dom.createElement('Layout') - for order in layout.order: - if order[0] == 'Separator': - child = dom.createElement('Separator') - node.appendChild(child) - elif order[0] == 'Filename': - child = self.__addXmlTextElement(node, 'Filename', order[1], dom) - elif order[0] == 'Menuname': - child = self.__addXmlTextElement(node, 'Menuname', order[1], dom) - elif order[0] == 'Merge': - child = dom.createElement('Merge') - child.setAttribute('type', order[1]) - node.appendChild(child) - return element.appendChild(node) - - def __addXmlDefaultLayout(self, element, dom): - # remove old default layout - for node in self.__getXmlNodesByName('DefaultLayout', element): - element.removeChild(node) - - # add new layout - node = dom.createElement('DefaultLayout') - node.setAttribute('inline', 'false') - return element.appendChild(node) - - def __createLayout(self, items): - layout = Layout() - layout.order = [] - - layout.order.append(['Merge', 'menus']) - for item in items: - if isinstance(item, tuple): - if item[0] == 'Separator': - layout.parseSeparator() - elif item[0] == 'Menu': - layout.parseMenuname(item[1]) - elif item[0] == 'Item': - layout.parseFilename(item[1]) - elif item.get_type() == matemenu.TYPE_DIRECTORY: - layout.parseMenuname(item.get_menu_id()) - elif item.get_type() == matemenu.TYPE_ENTRY: - layout.parseFilename(item.get_desktop_file_id()) - elif item.get_type() == matemenu.TYPE_SEPARATOR: - layout.parseSeparator() - layout.order.append(['Merge', 'files']) - return layout - - def __addItem(self, parent, file_id, dom): - xml_parent = self.__getXmlMenu(self.__getPath(parent), dom, dom) - self.__addXmlFilename(xml_parent, dom, file_id, 'Include') - - def __deleteItem(self, parent, file_id, dom, before=None, after=None): - xml_parent = self.__getXmlMenu(self.__getPath(parent), dom, dom) - self.__addXmlFilename(xml_parent, dom, file_id, 'Exclude') - - def __positionItem(self, parent, item, before=None, after=None): - if not before and not after: - return - if after: - index = parent.contents.index(after) + 1 - elif before: - index = parent.contents.index(before) - contents = parent.contents - #if this is a move to a new parent you can't remove the item - try: - contents.remove(item) - except: - pass - contents.insert(index, item) - layout = self.__createLayout(contents) - dom = self.__getMenu(parent).dom - menu_xml = self.__getXmlMenu(self.__getPath(parent), dom, dom) - self.__addXmlLayout(menu_xml, layout, dom) - - def __undoMoves(self, element, old, new, dom): - nodes = [] - matches = [] - original_old = old - final_old = old - #get all elements - for node in self.__getXmlNodesByName(['Move'], element): - nodes.insert(0, node) - #if the matches our old parent we've found a stage to undo - for node in nodes: - xml_old = node.getElementsByTagName('Old')[0] - xml_new = node.getElementsByTagName('New')[0] - if xml_new.childNodes[0].nodeValue == old: - matches.append(node) - #we should end up with this path when completed - final_old = xml_old.childNodes[0].nodeValue - #undoing s - for node in matches: - element.removeChild(node) - if len(matches) > 0: - for node in nodes: - xml_old = node.getElementsByTagName('Old')[0] - xml_new = node.getElementsByTagName('New')[0] - path = os.path.split(xml_new.childNodes[0].nodeValue) - if path[0] == original_old: - element.removeChild(node) - for node in dom.getElementsByTagName('Menu'): - name_node = node.getElementsByTagName('Name')[0] - name = name_node.childNodes[0].nodeValue - if name == os.path.split(new)[1]: - #copy app and dir directory info from old - root_path = dom.getElementsByTagName('Menu')[0].getElementsByTagName('Name')[0].childNodes[0].nodeValue - xml_menu = self.__getXmlMenu(root_path + '/' + new, dom, dom) - for app_dir in node.getElementsByTagName('AppDir'): - xml_menu.appendChild(app_dir) - for dir_dir in node.getElementsByTagName('DirectoryDir'): - xml_menu.appendChild(dir_dir) - parent = node.parentNode - parent.removeChild(node) - node = dom.createElement('Move') - node.appendChild(self.__addXmlTextElement(node, 'Old', xml_old.childNodes[0].nodeValue, dom)) - node.appendChild(self.__addXmlTextElement(node, 'New', os.path.join(new, path[1]), dom)) - element.appendChild(node) - if final_old == new: - return True - node = dom.createElement('Move') - node.appendChild(self.__addXmlTextElement(node, 'Old', final_old, dom)) - node.appendChild(self.__addXmlTextElement(node, 'New', new, dom)) - return element.appendChild(node) - -class Layout: - def __init__(self, node=None): - self.order = [] - - def parseMenuname(self, value): - self.order.append(['Menuname', value]) - - def parseSeparator(self): - self.order.append(['Separator']) - - def parseFilename(self, value): - self.order.append(['Filename', value]) - - def parseMerge(self, merge_type='all'): - self.order.append(['Merge', merge_type]) diff --git a/Alacarte/__init__.py b/Alacarte/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/Alacarte/config.py.in b/Alacarte/config.py.in deleted file mode 100644 index 1b90871..0000000 --- a/Alacarte/config.py.in +++ /dev/null @@ -1,9 +0,0 @@ -prefix="@prefix@" -datadir="@datadir@" -localedir=datadir+"/locale" -pkgdatadir="@pkgdatadir@" -libdir="@libdir@" -libexecdir="@libexecdir@" -PACKAGE="@PACKAGE@" -VERSION="@VERSION@" -GETTEXT_PACKAGE="@GETTEXT_PACKAGE@" diff --git a/Alacarte/util.py b/Alacarte/util.py deleted file mode 100644 index affd2f5..0000000 --- a/Alacarte/util.py +++ /dev/null @@ -1,244 +0,0 @@ -# -*- coding: utf-8 -*- -# Alacarte Menu Editor - Simple fd.o Compliant Menu Editor -# Copyright (C) 2006 Travis Watkins -# -# This library is free software; you can redistribute it and/or -# modify it under the terms of the GNU Library General Public -# License as published by the Free Software Foundation; either -# version 2 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Library General Public License for more details. -# -# You should have received a copy of the GNU Library General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -import os -import gtk, matemenu -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') - -def getUniqueFileId(name, extension): - append = 0 - while 1: - if append == 0: - filename = name + extension - else: - filename = name + '-' + str(append) + extension - if extension == '.desktop': - path = getUserItemPath() - if not os.path.isfile(os.path.join(path, filename)) and not getItemPath(filename): - break - elif extension == '.directory': - path = getUserDirectoryPath() - if not os.path.isfile(os.path.join(path, filename)) and not getDirectoryPath(filename): - break - append += 1 - return filename - -def getUniqueRedoFile(filepath): - append = 0 - while 1: - new_filepath = filepath + '.redo-' + str(append) - if not os.path.isfile(new_filepath): - break - else: - append += 1 - return new_filepath - -def getUniqueUndoFile(filepath): - filename, extension = os.path.split(filepath)[1].rsplit('.', 1) - append = 0 - while 1: - if extension == 'desktop': - path = getUserItemPath() - elif extension == 'directory': - path = getUserDirectoryPath() - elif extension == 'menu': - path = getUserMenuPath() - new_filepath = os.path.join(path, filename + '.' + extension + '.undo-' + str(append)) - if not os.path.isfile(new_filepath): - break - else: - append += 1 - return new_filepath - -def getUserMenuPath(): - menu_dir = None - if os.environ.has_key('XDG_CONFIG_HOME'): - menu_dir = os.path.join(os.environ['XDG_CONFIG_HOME'], 'menus') - else: - menu_dir = os.path.join(os.environ['HOME'], '.config', 'menus') - #move .config out of the way if it's not a dir, it shouldn't be there - if os.path.isfile(os.path.split(menu_dir)[0]): - os.rename(os.path.split(menu_dir)[0], os.path.split(menu_dir)[0] + '.old') - if not os.path.isdir(menu_dir): - os.makedirs(menu_dir) - return menu_dir - -def getItemPath(file_id): - if os.environ.has_key('XDG_DATA_DIRS'): - for system_path in os.environ['XDG_DATA_DIRS'].split(':'): - file_path = os.path.join(system_path, 'applications', file_id) - if os.path.isfile(file_path): - return file_path - file_path = os.path.join('/', 'usr', 'share', 'applications', file_id) - if os.path.isfile(file_path): - return file_path - return False - -def getUserItemPath(): - item_dir = None - if os.environ.has_key('XDG_DATA_HOME'): - item_dir = os.path.join(os.environ['XDG_DATA_HOME'], 'applications') - else: - item_dir = os.path.join(os.environ['HOME'], '.local', 'share', 'applications') - if not os.path.isdir(item_dir): - os.makedirs(item_dir) - return item_dir - -def getDirectoryPath(file_id): - home = getUserDirectoryPath() - file_path = os.path.join(home, file_id) - if os.path.isfile(file_path): - return file_path - if os.environ.has_key('XDG_DATA_DIRS'): - for system_path in os.environ['XDG_DATA_DIRS'].split(':'): - file_path = os.path.join(system_path, 'desktop-directories', file_id) - if os.path.isfile(file_path): - return file_path - file_path = os.path.join('/', 'usr', 'share', 'desktop-directories', file_id) - if os.path.isfile(file_path): - return file_path - return False - -def getUserDirectoryPath(): - menu_dir = None - if os.environ.has_key('XDG_DATA_HOME'): - menu_dir = os.path.join(os.environ['XDG_DATA_HOME'], 'desktop-directories') - else: - menu_dir = os.path.join(os.environ['HOME'], '.local', 'share', 'desktop-directories') - if not os.path.isdir(menu_dir): - os.makedirs(menu_dir) - return menu_dir - -def getSystemMenuPath(file_name): - if os.environ.has_key('XDG_CONFIG_DIRS'): - for system_path in os.environ['XDG_CONFIG_DIRS'].split(':'): - file_path = os.path.join(system_path, 'menus', file_name) - if os.path.isfile(file_path): - return file_path - file_path = os.path.join('/', 'etc', 'xdg', 'menus', file_name) - if os.path.isfile(file_path): - return file_path - return False - -def getUserMenuXml(tree): - system_file = getSystemMenuPath(tree.get_menu_file()) - name = tree.root.get_menu_id() - menu_xml = "\n" - menu_xml += "\n " + name + "\n " - menu_xml += "" + system_file + "\n\n" - return menu_xml - -def getIcon(item, for_properties=False): - pixbuf, path = None, None - if item == None: - if for_properties: - return None, None - return None - if isinstance(item, str): - iconName = item - else: - iconName = item.get_icon() - if iconName and not '/' in iconName and iconName[-3:] in ('png', 'svg', 'xpm'): - iconName = iconName[:-4] - icon_theme = gtk.icon_theme_get_default() - try: - pixbuf = icon_theme.load_icon(iconName, 24, 0) - path = icon_theme.lookup_icon(iconName, 24, 0).get_filename() - except: - if iconName and '/' in iconName: - try: - pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(iconName, 24, 24) - path = iconName - except: - pass - if pixbuf == None: - if for_properties: - return None, None - if item.get_type() == matemenu.TYPE_DIRECTORY: - iconName = 'mate-fs-directory' - elif item.get_type() == matemenu.TYPE_ENTRY: - iconName = 'application-default-icon' - try: - pixbuf = icon_theme.load_icon(iconName, 24, 0) - path = icon_theme.lookup_icon(iconName, 24, 0).get_filename() - except: - return None - if pixbuf == None: - return None - if pixbuf.get_width() != 24 or pixbuf.get_height() != 24: - pixbuf = pixbuf.scale_simple(24, 24, gtk.gdk.INTERP_HYPER) - if for_properties: - return pixbuf, path - return pixbuf -- cgit v1.2.1