Author: jannis
Date: 2006-11-03 21:41:41 +0000 (Fri, 03 Nov 2006)
New Revision: 23620

Added:
   libfrap/trunk/libfrap/menu/frap-menu-move.c
   libfrap/trunk/libfrap/menu/frap-menu-move.h
Modified:
   libfrap/trunk/libfrap/menu/ChangeLog
   libfrap/trunk/libfrap/menu/Makefile.am
   libfrap/trunk/libfrap/menu/STATUS
   libfrap/trunk/libfrap/menu/frap-menu.c
   libfrap/trunk/libfrap/menu/frap-menu.h
Log:
        * frap-menu.{c,h}, frap-menu-move.{c,h}, Makefile.am, STATUS: 
          frap_menu_get_menu_with_name() added. Implemented <Move>, <New> 
          and <Old> elements (also added error handling for incomplete move 
          instructions). A move instruction is a FrapMenuMove with properties 
          "old" and "new", which refers to the source and target menu names. 
          

Modified: libfrap/trunk/libfrap/menu/ChangeLog
===================================================================
--- libfrap/trunk/libfrap/menu/ChangeLog        2006-11-03 20:37:26 UTC (rev 
23619)
+++ libfrap/trunk/libfrap/menu/ChangeLog        2006-11-03 21:41:41 UTC (rev 
23620)
@@ -1,3 +1,11 @@
+2006-11-03     Jannis Pohlmann <[EMAIL PROTECTED]>
+
+       * frap-menu.{c,h}, frap-menu-move.{c,h}, Makefile.am, STATUS: 
+         frap_menu_get_menu_with_name() added. Implemented <Move>, <New> 
+         and <Old> elements (also added error handling for incomplete move 
+         instructions). A move instruction is a FrapMenuMove with properties 
+         "old" and "new", which refers to the source and target menu names. 
+         
 2006-10-31     Jannis Pohlmann <[EMAIL PROTECTED]>
 
        * Makefile.am, tdb/: tdb added.

Modified: libfrap/trunk/libfrap/menu/Makefile.am
===================================================================
--- libfrap/trunk/libfrap/menu/Makefile.am      2006-11-03 20:37:26 UTC (rev 
23619)
+++ libfrap/trunk/libfrap/menu/Makefile.am      2006-11-03 21:41:41 UTC (rev 
23620)
@@ -16,6 +16,7 @@
        frap-menu-not-rules.c                                           \
        frap-menu-item-pool.c                                           \
        frap-menu-item-cache.c                                          \
+       frap-menu-move.c                                                \
        frap-menu-item.c                                                
 
 libfrapmenu_la_DEPENDENCIES =                                          \
@@ -32,6 +33,7 @@
        frap-menu-not-rules.h                                           \
        frap-menu-item-pool.h                                           \
        frap-menu-item-cache.h                                          \
+       frap-menu-move.h                                                \
        frap-menu-item.h                                                
 
 INCLUDES =                                                             \

Modified: libfrap/trunk/libfrap/menu/STATUS
===================================================================
--- libfrap/trunk/libfrap/menu/STATUS   2006-11-03 20:37:26 UTC (rev 23619)
+++ libfrap/trunk/libfrap/menu/STATUS   2006-11-03 21:41:41 UTC (rev 23620)
@@ -30,8 +30,6 @@
 
   [x] <Include> 
 
-        TODO: Recursively load elements (using a stack).
-
         Recursion scheme (only recurse on and/or/not elements):
 
            and|or|not
@@ -74,11 +72,11 @@
 
         See <LegacyDir>
 
-  [ ] <Move>
+  [x] <Move>
 
-  [ ] <Old>
+  [x] <Old>
 
-  [ ] <New>
+  [x] <New>
 
   [ ] <Layout>
 

Added: libfrap/trunk/libfrap/menu/frap-menu-move.c
===================================================================
--- libfrap/trunk/libfrap/menu/frap-menu-move.c                         (rev 0)
+++ libfrap/trunk/libfrap/menu/frap-menu-move.c 2006-11-03 21:41:41 UTC (rev 
23620)
@@ -0,0 +1,292 @@
+/* $Id$ */
+/* vi:set expandtab sw=2 sts=2: */
+/*-
+ * Copyright (c) 2006 Jannis Pohlmann <[EMAIL PROTECTED]>
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libxfce4util/libxfce4util.h>
+
+#include <frap-menu-move.h>
+
+
+
+/* Property identifiers */
+enum
+{
+  PROP_0,
+  PROP_OLD,
+  PROP_NEW,
+};
+
+
+
+static void frap_menu_move_class_init   (FrapMenuMoveClass *klass);
+static void frap_menu_move_init         (FrapMenuMove      *move);
+static void frap_menu_move_finalize     (GObject           *object);
+static void frap_menu_move_get_property (GObject           *object,
+                                         guint              prop_id,
+                                         GValue            *value,
+                                         GParamSpec        *pspec);
+static void frap_menu_move_set_property (GObject           *object,
+                                         guint              prop_id,
+                                         const GValue      *value,
+                                         GParamSpec        *pspec);
+
+
+
+struct _FrapMenuMoveClass
+{
+  GObjectClass __parent__;
+};
+
+struct _FrapMenuMove
+{
+  GObject  __parent__;
+
+  /* Name of the submenu to move/rename */
+  gchar   *old;
+
+  /* Name of the target path/name */
+  gchar   *new;
+};
+
+
+
+static GObjectClass *frap_menu_move_parent_class = NULL;
+
+
+
+GType
+frap_menu_move_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info = 
+      {
+        sizeof (FrapMenuMoveClass),
+        NULL,
+        NULL,
+        (GClassInitFunc) frap_menu_move_class_init,
+        NULL,
+        NULL,
+        sizeof (FrapMenuMove),
+        0,
+        (GInstanceInitFunc) frap_menu_move_init,
+        NULL,
+      };
+
+      type = g_type_register_static (G_TYPE_OBJECT, "FrapMenuMove", &info, 0);
+    }
+
+  return type;
+}
+
+
+
+static void
+frap_menu_move_class_init (FrapMenuMoveClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* Determine parent type class */
+  frap_menu_move_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = frap_menu_move_finalize;
+  gobject_class->get_property = frap_menu_move_get_property;
+  gobject_class->set_property = frap_menu_move_set_property;
+
+  /**
+   * FrapMenuMove:old:
+   *
+   * Name of the submenu to be moved/renamed.
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_OLD,
+                                   g_param_spec_string ("old",
+                                                        _("Old name"),
+                                                        _("Name of the submenu 
to be moved"),
+                                                        NULL,
+                                                        G_PARAM_READWRITE));
+
+  /**
+   * FrapMenuMove:new:
+   *
+   * Target path/name of the move/rename operation.
+   */
+  g_object_class_install_property (gobject_class,
+                                   PROP_NEW,
+                                   g_param_spec_string ("new",
+                                                        _("New name"),
+                                                        _("Target path/name of 
the move/rename operation"),
+                                                        NULL,
+                                                        G_PARAM_READWRITE));
+}
+
+
+
+static void
+frap_menu_move_init (FrapMenuMove *move)
+{
+  move->old = NULL;
+  move->new = NULL;
+}
+
+
+
+static void
+frap_menu_move_finalize (GObject *object)
+{
+  FrapMenuMove *move = FRAP_MENU_MOVE (object);
+
+  /* Free instance variables */
+  frap_menu_move_set_old (move, NULL);
+  frap_menu_move_set_new (move, NULL);
+
+  (*G_OBJECT_CLASS (frap_menu_move_parent_class)->finalize) (object);
+}
+
+
+
+static void
+frap_menu_move_get_property (GObject    *object,
+                             guint       prop_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
+{
+  FrapMenuMove *move = FRAP_MENU_MOVE (object);
+
+  switch (prop_id)
+    {
+    case PROP_OLD:
+      g_value_set_string (value, frap_menu_move_get_old (move));
+      break;
+
+    case PROP_NEW:
+      g_value_set_string (value, frap_menu_move_get_new (move));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+frap_menu_move_set_property (GObject      *object,
+                             guint         prop_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
+{
+  FrapMenuMove *move = FRAP_MENU_MOVE (object);
+
+  switch (prop_id)
+    {
+    case PROP_OLD:
+      frap_menu_move_set_old (move, g_value_get_string (value));
+      break;
+
+    case PROP_NEW:
+      frap_menu_move_set_new (move, g_value_get_string (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+FrapMenuMove*
+frap_menu_move_new (void)
+{
+  return g_object_new (FRAP_TYPE_MENU_MOVE, NULL);
+}
+
+
+
+const gchar*
+frap_menu_move_get_old (FrapMenuMove *move)
+{
+  g_return_val_if_fail (FRAP_IS_MENU_MOVE (move), NULL);
+  return move->old;
+}
+
+
+
+void
+frap_menu_move_set_old (FrapMenuMove *move, 
+                        const gchar  *old)
+{
+  g_return_if_fail (FRAP_IS_MENU_MOVE (move));
+
+  /* Check if old value is set */
+  if (G_UNLIKELY (move->old != NULL))
+    {
+      /* Abort if old and new value is the same */
+      if (G_UNLIKELY (old != NULL && g_utf8_collate (move->old, old) == 0))
+        return;
+
+      /* Otherwise, free the old value */
+      g_free (move->old);
+    }
+
+  /* Assign the new value */
+  move->old = g_strdup (old);
+}
+
+
+
+const gchar*
+frap_menu_move_get_new (FrapMenuMove *move)
+{
+  g_return_val_if_fail (FRAP_IS_MENU_MOVE (move), NULL);
+  return move->new;
+}
+
+
+
+void
+frap_menu_move_set_new (FrapMenuMove *move, 
+                        const gchar  *new)
+{
+  g_return_if_fail (FRAP_IS_MENU_MOVE (move));
+
+  /* Check if old value is set */
+  if (G_UNLIKELY (move->new != NULL))
+    {
+      /* Abort if old and new value is the same */
+      if (G_UNLIKELY (new != NULL && g_utf8_collate (move->new, new) == 0))
+        return;
+
+      /* Otherwise, free the old value */
+      g_free (move->new);
+    }
+
+  /* Assign the new value */
+  move->new = g_strdup (new);
+}


Property changes on: libfrap/trunk/libfrap/menu/frap-menu-move.c
___________________________________________________________________
Name: svn:keywords
   + Id Author Date Revision

Added: libfrap/trunk/libfrap/menu/frap-menu-move.h
===================================================================
--- libfrap/trunk/libfrap/menu/frap-menu-move.h                         (rev 0)
+++ libfrap/trunk/libfrap/menu/frap-menu-move.h 2006-11-03 21:41:41 UTC (rev 
23620)
@@ -0,0 +1,57 @@
+/* $Id$ */
+/* vi:set expandtab sw=2 sts=2: */
+/*-
+ * Copyright (c) 2006 Jannis Pohlmann <[EMAIL PROTECTED]>
+ *
+ * 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.
+ */
+
+#if !defined(LIBFRAPMENU_INSIDE_LIBFRAPMENU_H) && 
!defined(LIBFRAPMENU_COMPILATION)
+#error "Only <libfrapmenu/libfrapmenu.h> can be included directly. This file 
may disappear or change contents."
+#endif
+
+#ifndef __FRAP_MENU_MOVE_H__
+#define __FRAP_MENU_MOVE_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _FrapMenuMoveClass FrapMenuMoveClass;
+typedef struct _FrapMenuMove      FrapMenuMove;
+
+#define FRAP_TYPE_MENU_MOVE            (frap_menu_move_get_type())
+#define FRAP_MENU_MOVE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
FRAP_TYPE_MENU_MOVE, FrapMenuMove))
+#define FRAP_MENU_MOVE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), 
FRAP_TYPE_MENU_MOVE, FrapMenuMoveClass))
+#define FRAP_IS_MENU_MOVE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
FRAP_TYPE_MENU_MOVE))
+#define FRAP_IS_MENU_MOVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), 
FRAP_TYPE_MENU_MOVE))
+#define FRAP_MENU_MOVE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), 
FRAP_TYPE_MENU_MOVE, FrapMenuMoveClass))
+
+GType         frap_menu_move_get_type    (void) G_GNUC_CONST;
+
+FrapMenuMove *frap_menu_move_new         (void);
+
+const gchar  *frap_menu_move_get_old     (FrapMenuMove *move);
+void          frap_menu_move_set_old     (FrapMenuMove *move,
+                                          const gchar  *old);
+
+const gchar  *frap_menu_move_get_new     (FrapMenuMove *move);
+void          frap_menu_move_set_new     (FrapMenuMove *move,
+                                          const gchar  *new);
+
+G_END_DECLS;
+
+#endif /* !__FRAP_MENU_MOVE_H__ */


Property changes on: libfrap/trunk/libfrap/menu/frap-menu-move.h
___________________________________________________________________
Name: svn:keywords
   + Id Author Date Revision

Modified: libfrap/trunk/libfrap/menu/frap-menu.c
===================================================================
--- libfrap/trunk/libfrap/menu/frap-menu.c      2006-11-03 20:37:26 UTC (rev 
23619)
+++ libfrap/trunk/libfrap/menu/frap-menu.c      2006-11-03 21:41:41 UTC (rev 
23620)
@@ -36,6 +36,7 @@
 #include <frap-menu-directory.h>
 #include <frap-menu-item-pool.h>
 #include <frap-menu-item-cache.h>
+#include <frap-menu-move.h>
 #include <frap-menu.h>
 
 
@@ -99,6 +100,7 @@
   FRAP_MENU_PARSE_STATE_MENU,
   FRAP_MENU_PARSE_STATE_RULE,
   FRAP_MENU_PARSE_STATE_END,
+  FRAP_MENU_PARSE_STATE_MOVE,
 
 } FrapMenuParseState;
 
@@ -113,6 +115,8 @@
   FRAP_MENU_PARSE_NODE_TYPE_DIRECTORY_DIR,
   FRAP_MENU_PARSE_NODE_TYPE_FILENAME,
   FRAP_MENU_PARSE_NODE_TYPE_CATEGORY,
+  FRAP_MENU_PARSE_NODE_TYPE_OLD,
+  FRAP_MENU_PARSE_NODE_TYPE_NEW,
 
 } FrapMenuParseNodeType;
 
@@ -131,6 +135,9 @@
   /* Include/exclude rules stack */
   GList                *rule_stack;
 
+  /* Current move instruction */
+  FrapMenuMove         *move;
+
   /* Current node type (for text handler) */
   FrapMenuParseNodeType node_type;
 
@@ -225,11 +232,14 @@
 static GSList            *frap_menu_get_rules                              
(FrapMenu              *menu);
 static void               frap_menu_add_rule                               
(FrapMenu              *menu,
                                                                             
FrapMenuRules         *rules);
+static void               frap_menu_add_move                               
(FrapMenu              *menu,
+                                                                            
FrapMenuMove          *move);
 static void               frap_menu_resolve_items                          
(FrapMenu              *menu);
 static void               frap_menu_resolve_items_from_path                
(FrapMenu              *menu,
                                                                             
const gchar           *path,
                                                                             
const gchar           *id_prefix);
 static void               frap_menu_resolve_deleted                        
(FrapMenu              *menu);
+static void               frap_menu_resolve_moves                          
(FrapMenu              *menu);
 
 
 
@@ -268,6 +278,9 @@
   /* Include/exclude rules */
   GSList            *rules;
 
+  /* Move instructions */
+  GSList            *moves;
+
   /* Menu item pool */
   FrapMenuItemPool  *pool;
 
@@ -425,6 +438,7 @@
   menu->priv->app_dirs = NULL;
   menu->priv->only_unallocated = FALSE;
   menu->priv->rules = NULL;
+  menu->priv->moves = NULL;
   menu->priv->pool = frap_menu_item_pool_new ();
 
   /* Take reference on the menu item cache */
@@ -470,6 +484,10 @@
   g_slist_foreach (menu->priv->rules, (GFunc) g_object_unref, NULL);
   g_slist_free (menu->priv->rules);
 
+  /* Free move instructions */
+  g_slist_foreach (menu->priv->moves, (GFunc) g_object_unref, NULL);
+  g_slist_free (menu->priv->moves);
+
   /* Free item pool */
   g_object_unref (G_OBJECT (menu->priv->pool));
 
@@ -915,6 +933,7 @@
   menu_context.state = FRAP_MENU_PARSE_NODE_TYPE_NONE;
   menu_context.menu_stack = NULL;
   menu_context.rule_stack = NULL;
+  menu_context.move = NULL;
 
   /* Allocate parse context */
   context = g_markup_parse_context_new (&parser, 0, &menu_context, NULL);
@@ -938,10 +957,7 @@
 
   frap_menu_remove_duplicates (menu);
   frap_menu_resolve_directory (menu);
-#if 0
-  /* TODO */
-  frap_menu_resolve_move (menu);
-#endif
+  frap_menu_resolve_moves (menu);
   frap_menu_resolve_deleted (menu);
   frap_menu_resolve_items (menu);
 }
@@ -1058,6 +1074,12 @@
           menu_context->menu_stack = g_list_prepend (menu_context->menu_stack, 
menu);
         }
 
+      else if (g_utf8_collate (element_name, "Move") == 0)
+        {
+          /* Set parse state */
+          menu_context->state = FRAP_MENU_PARSE_STATE_MOVE;
+        }
+      
       break;
 
     case FRAP_MENU_PARSE_STATE_RULE:
@@ -1107,6 +1129,25 @@
         }
 
       break;
+
+    case FRAP_MENU_PARSE_STATE_MOVE:
+      /* Fetch current menu from stack */
+      current_menu = g_list_first (menu_context->menu_stack)->data;
+
+      if (g_utf8_collate (element_name, "Old") == 0)
+        {
+          /* Create a new move instruction in the parse context */
+          menu_context->move = frap_menu_move_new ();
+
+          /* Add move instruction to the menu */
+          frap_menu_add_move (current_menu, menu_context->move);
+
+          menu_context->node_type = FRAP_MENU_PARSE_NODE_TYPE_OLD;
+        }
+      else if (g_utf8_collate (element_name, "New") == 0)
+        menu_context->node_type = FRAP_MENU_PARSE_NODE_TYPE_NEW;
+
+      break;
     }
 }
 
@@ -1160,6 +1201,32 @@
             }
         }
       break;
+
+    case FRAP_MENU_PARSE_STATE_MOVE:
+      if (g_utf8_collate (element_name, "Move") == 0)
+        {
+          /* Set menu parse state */
+          menu_context->state = FRAP_MENU_PARSE_STATE_MENU;
+
+          /* Handle incomplete move commands (those missing a <New> element) */
+          if (G_UNLIKELY (menu_context->move != NULL && frap_menu_move_get_new 
(menu_context->move) == NULL))
+            {
+              /* Determine current menu */
+              FrapMenu *current_menu = FRAP_MENU (g_list_first 
(menu_context->menu_stack)->data);
+
+              /* Print warning */
+              g_warning ("Ignoring <Old>%s</Old>", frap_menu_move_get_old 
(menu_context->move));
+
+              /* Remove move command from the menu */
+              current_menu->priv->moves = g_slist_remove 
(current_menu->priv->moves, menu_context->move);
+
+              /* Free the move command */
+              g_object_unref (menu_context->move);
+            }
+        }
+      else if (g_utf8_collate (element_name, "New") == 0)
+        menu_context->move = NULL;
+      break;
     }
 }
 
@@ -1208,6 +1275,17 @@
     case FRAP_MENU_PARSE_NODE_TYPE_CATEGORY:
       frap_menu_rules_add_category (current_rule, content);
       break;
+
+    case FRAP_MENU_PARSE_NODE_TYPE_OLD:
+      frap_menu_move_set_old (menu_context->move, content);
+      break;
+
+    case FRAP_MENU_PARSE_NODE_TYPE_NEW:
+      if (G_LIKELY (menu_context->move != NULL))
+        frap_menu_move_set_new (menu_context->move, content);
+      else
+        g_warning ("Ignored <New>%s</New>", content);
+      break;
     }
 
   /* Free string */
@@ -1535,6 +1613,35 @@
 
 
 
+FrapMenu*
+frap_menu_get_menu_with_name (FrapMenu    *menu,
+                              const gchar *name)
+{
+  FrapMenu *result = NULL;
+  FrapMenu *submenu;
+  GSList   *iter;
+
+  g_return_val_if_fail (FRAP_IS_MENU (menu), NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+
+  /* Iterate over the submenu list */
+  for (iter = menu->priv->submenus; iter != NULL; iter = g_slist_next (iter))
+    {
+      submenu = FRAP_MENU (iter->data);
+
+      /* End loop when a matching submenu is found */
+      if (G_UNLIKELY (g_utf8_collate (frap_menu_get_name (submenu), name) == 
0))
+        {
+          result = submenu;
+          break;
+        }
+    }
+
+  return result;
+}
+
+
+
 FrapMenu *
 frap_menu_get_parent (FrapMenu *menu)
 {
@@ -1598,6 +1705,10 @@
         }
 
       /* Copy menu information */
+      /* FIXME This introduces possible bugs. E.g. if merged_menu has one 
<Deleted> 
+       * element and submenu has none, the lines below would set it to 
<NotDeleted> 
+       * (which is the default value). This does not follow the spec! Same goes
+       * for <OnlyUnallocated>. */
       frap_menu_set_name (merged_menu, frap_menu_get_name (submenu));
       frap_menu_set_only_unallocated (merged_menu, 
frap_menu_get_only_unallocated (submenu));
       frap_menu_set_deleted (merged_menu, frap_menu_get_deleted (submenu));
@@ -1833,7 +1944,7 @@
   GDir        *dir;
   const gchar *app_dir;
 
-  g_return_if_fail (FRAP_IS_MENU (menu));
+  g_return_if_fail (menu != NULL && FRAP_IS_MENU (menu));
 
   /* TODO Remove all items from the pool if there are no include rules! */
 
@@ -1971,6 +2082,69 @@
 }
 
 
+
+static void
+frap_menu_resolve_moves (FrapMenu *menu)
+{
+  FrapMenu     *submenu;
+  FrapMenu     *target_submenu;
+  FrapMenuMove *move;
+  GSList       *iter;
+  GSList       *submenu_iter;
+  GSList       *removed_menus;
+
+  g_return_if_fail (FRAP_IS_MENU (menu));
+
+  /* Recurse into the submenus which need to perform move actions first */
+  for (submenu_iter = menu->priv->submenus; submenu_iter != NULL; submenu_iter 
= g_slist_next (submenu_iter))
+    {
+      submenu = FRAP_MENU (submenu_iter->data);
+
+      /* Resolve moves of the child menu */
+      frap_menu_resolve_moves (submenu);
+    }
+
+  /* Iterate over the move instructions */
+  for (iter = menu->priv->moves; iter != NULL; iter = g_slist_next (iter))
+    {
+      move = FRAP_MENU_MOVE (iter->data);
+
+      /* Fetch submenu with the old name */
+      submenu = frap_menu_get_menu_with_name (menu, frap_menu_move_get_old 
(move));
+
+      /* Only go into details if there actually is a submenu with this name */
+      if (submenu != NULL)
+        {
+          /* Fetch the target submenu */
+          target_submenu = frap_menu_get_menu_with_name (menu, 
frap_menu_move_get_new (move));
+
+          /* If there is no target, just rename the submenu */
+          if (target_submenu == NULL)
+            frap_menu_set_name (submenu, frap_menu_move_get_new (move));
+          else
+            {
+              /* TODO Set <Deleted>, <OnlyUnallocated>, etc. See FIXME in this 
file for what kind 
+               * of bugs this may introduce. */
+
+              /* Append directory names, directory and app dirs as well as 
rules to the merged menu */      
+              g_slist_foreach (submenu->priv->parse_info->directory_names, 
(GFunc) frap_menu_merge_directory_name, target_submenu);
+              g_slist_foreach (submenu->priv->directory_dirs, (GFunc) 
frap_menu_merge_directory_dir, target_submenu);
+              g_slist_foreach (submenu->priv->app_dirs, (GFunc) 
frap_menu_merge_app_dir, target_submenu);
+              g_slist_foreach (submenu->priv->rules, (GFunc) 
frap_menu_merge_rule, target_submenu);
+              
+              /* Remove submenu from the submenu list */
+              menu->priv->submenus = g_slist_remove (menu->priv->submenus, 
submenu);
+
+              /* TODO Free the submenu - this introduces a strange item pool
+               * error ... */
+              /* g_object_unref (submenu); */
+            }
+        }
+    }
+}
+
+
+
 static GSList*
 frap_menu_get_rules (FrapMenu *menu)
 {
@@ -1992,6 +2166,18 @@
 
 
 
+static void
+frap_menu_add_move (FrapMenu     *menu,
+                    FrapMenuMove *move)
+{
+  g_return_if_fail (FRAP_IS_MENU (menu));
+  g_return_if_fail (FRAP_IS_MENU_MOVE (move));
+
+  menu->priv->moves = g_slist_append (menu->priv->moves, move);
+}
+
+
+
 FrapMenuItemPool*
 frap_menu_get_item_pool (FrapMenu *menu)
 {
@@ -1999,4 +2185,3 @@
 
   return menu->priv->pool;
 }
-

Modified: libfrap/trunk/libfrap/menu/frap-menu.h
===================================================================
--- libfrap/trunk/libfrap/menu/frap-menu.h      2006-11-03 20:37:26 UTC (rev 
23619)
+++ libfrap/trunk/libfrap/menu/frap-menu.h      2006-11-03 21:41:41 UTC (rev 
23620)
@@ -71,6 +71,8 @@
 GSList            *frap_menu_get_menus             (FrapMenu          *menu);
 void               frap_menu_add_menu              (FrapMenu          *menu,
                                                     FrapMenu          
*submenu);
+FrapMenu          *frap_menu_get_menu_with_name    (FrapMenu          *menu,
+                                                    const gchar       *name);
 FrapMenu          *frap_menu_get_parent            (FrapMenu          *menu);
 FrapMenuItemPool  *frap_menu_get_item_pool         (FrapMenu          *menu);
 

_______________________________________________
Xfce4-commits mailing list
Xfce4-commits@xfce.org
http://foo-projects.org/mailman/listinfo/xfce4-commits

Reply via email to