Author: jannis
Date: 2007-03-18 02:23:12 +0000 (Sun, 18 Mar 2007)
New Revision: 25185

Added:
   libfrap/trunk/libfrap/menu/frap-menu-layout.c
   libfrap/trunk/libfrap/menu/frap-menu-layout.h
   libfrap/trunk/libfrap/menu/frap-menu-separator.c
   libfrap/trunk/libfrap/menu/frap-menu-separator.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
   libfrap/trunk/libfrap/menu/libfrapmenu.h
   libfrap/trunk/libfrap/menu/tests/test-display-root-menu.c
Log:
        * frap-menu-layout.{c,h}: FrapMenuLayout added. It only supports
          <Filename>, <Separator> and <Merge> elements currently.
        * frap-menu-separator.{c,h}: FrapMenuSeparator added. This is a
          singleton to be inserted into the GSList returned by 
          frap_menu_get_layout_items() whenever a separator is required.
        * frap-menu.{c,h}: Implement parsing of <Layout>, <Separator>
          and <Merge> elements. Add layout member to the FrapMenu struct.
          Add method to fetch all items based on the layout: 
          frap_menu_get_layout_items(). Call _frap_menu_separator_init()
          in frap_menu_init() and _frap_menu_separator_shutdown() in
          frap_menu_shutdown(). Check filename != NULL in 
          frap_menu_new(). 
        * libfrapmenu.h: Add separator and layout to the main header.
        * tests/test-display-root-menu.c: Use 
          frap_menu_get_layout_items() instead of frap_menu_get_items().
        * Makefile.am: Add separator and layout sources.
        * STATUS: Status updated.

Modified: libfrap/trunk/libfrap/menu/ChangeLog
===================================================================
--- libfrap/trunk/libfrap/menu/ChangeLog        2007-03-17 22:54:06 UTC (rev 
25184)
+++ libfrap/trunk/libfrap/menu/ChangeLog        2007-03-18 02:23:12 UTC (rev 
25185)
@@ -1,5 +1,25 @@
-2007-02-14     Janins Pohlmann <[EMAIL PROTECTED]>
+2007-03-18     Jannis Pohlmann <[EMAIL PROTECTED]>
 
+       * frap-menu-layout.{c,h}: FrapMenuLayout added. It only supports
+         <Filename>, <Separator> and <Merge> elements currently.
+       * frap-menu-separator.{c,h}: FrapMenuSeparator added. This is a
+         singleton to be inserted into the GSList returned by 
+         frap_menu_get_layout_items() whenever a separator is required.
+       * frap-menu.{c,h}: Implement parsing of <Layout>, <Separator>
+         and <Merge> elements. Add layout member to the FrapMenu struct.
+         Add method to fetch all items based on the layout: 
+         frap_menu_get_layout_items(). Call _frap_menu_separator_init()
+         in frap_menu_init() and _frap_menu_separator_shutdown() in
+         frap_menu_shutdown(). Check filename != NULL in 
+         frap_menu_new(). 
+       * libfrapmenu.h: Add separator and layout to the main header.
+       * tests/test-display-root-menu.c: Use 
+         frap_menu_get_layout_items() instead of frap_menu_get_items().
+       * Makefile.am: Add separator and layout sources.
+       * STATUS: Status updated.
+
+2007-02-14     Jannis Pohlmann <[EMAIL PROTECTED]>
+
        * STATUS: Menu spec test suite results added.
        * tests/test-display-root-menu.c: Fix warning caused by copying
          a string into a const gchar*.

Modified: libfrap/trunk/libfrap/menu/Makefile.am
===================================================================
--- libfrap/trunk/libfrap/menu/Makefile.am      2007-03-17 22:54:06 UTC (rev 
25184)
+++ libfrap/trunk/libfrap/menu/Makefile.am      2007-03-18 02:23:12 UTC (rev 
25185)
@@ -14,6 +14,8 @@
 
 libfrapmenu_la_SOURCES =                                               \
        frap-menu.c                                                     \
+       frap-menu-separator.c                                           \
+       frap-menu-layout.c                                              \
        frap-menu-directory.c                                           \
        frap-menu-rules.c                                               \
        frap-menu-standard-rules.c                                      \
@@ -32,6 +34,8 @@
 noinst_HEADERS =                                                       \
        libfrapmenu.h                                                   \
        frap-menu.h                                                     \
+       frap-menu-separator.h                                           \
+       frap-menu-layout.h                                              \
        frap-menu-directory.h                                           \
        frap-menu-rules.h                                               \
        frap-menu-standard-rules.h                                      \

Modified: libfrap/trunk/libfrap/menu/STATUS
===================================================================
--- libfrap/trunk/libfrap/menu/STATUS   2007-03-17 22:54:06 UTC (rev 25184)
+++ libfrap/trunk/libfrap/menu/STATUS   2007-03-18 02:23:12 UTC (rev 25185)
@@ -84,15 +84,18 @@
 
   [ ] <New>
 
-  [ ] <Layout>
+  [-] <Layout>
 
+        The <Layout> element is parsed including all children, but the
+       layout attributes are not handled yet.
+
   [ ] <DefaultLayout>
 
   [ ] <Menuname>
 
-  [ ] <Separator>
+  [x] <Separator>
 
-  [ ] <Merge>
+  [x] <Merge>
 
 
 

Added: libfrap/trunk/libfrap/menu/frap-menu-layout.c
===================================================================
--- libfrap/trunk/libfrap/menu/frap-menu-layout.c                               
(rev 0)
+++ libfrap/trunk/libfrap/menu/frap-menu-layout.c       2007-03-18 02:23:12 UTC 
(rev 25185)
@@ -0,0 +1,337 @@
+/* $Id$ */
+/* vi:set expandtab sw=2 sts=2: */
+/*-
+ * Copyright (c) 2007 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 <frap-menu-layout.h>
+
+
+
+#define FRAP_MENU_LAYOUT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), 
FRAP_TYPE_MENU_LAYOUT, FrapMenuLayoutPrivate))
+
+
+
+/* Property identifiers */
+enum
+{
+  PROP_0,
+};
+
+
+
+struct _FrapMenuLayoutNode
+{
+  FrapMenuLayoutNodeType   type;
+  union
+  {
+    gchar                  *filename;
+    FrapMenuLayoutMergeType merge_type;
+  } data;
+};
+
+
+
+static void frap_menu_layout_class_init   (FrapMenuLayoutClass *klass);
+static void frap_menu_layout_init         (FrapMenuLayout      *layout);
+static void frap_menu_layout_finalize     (GObject             *object);
+static void frap_menu_layout_get_property (GObject             *object,
+                                           guint                prop_id,
+                                           GValue              *value,
+                                           GParamSpec          *pspec);
+static void frap_menu_layout_set_property (GObject             *object,
+                                           guint                prop_id,
+                                           const GValue        *value,
+                                           GParamSpec          *pspec);
+static void frap_menu_layout_free_node    (FrapMenuLayoutNode  *node);
+
+
+
+struct _FrapMenuLayoutClass
+{
+  GObjectClass __parent__;
+};
+
+struct _FrapMenuLayoutPrivate
+{
+  GSList *nodes;
+};
+
+struct _FrapMenuLayout
+{
+  GObject __parent__;
+
+  /* < private > */
+  FrapMenuLayoutPrivate *priv;
+};
+
+
+
+static GObjectClass *frap_menu_layout_parent_class = NULL;
+
+
+
+GType
+frap_menu_layout_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (FrapMenuLayoutClass),
+        NULL,
+        NULL,
+        (GClassInitFunc) frap_menu_layout_class_init,
+        NULL,
+        NULL,
+        sizeof (FrapMenuLayout),
+        0,
+        (GInstanceInitFunc) frap_menu_layout_init,
+        NULL,
+      };
+
+      type = g_type_register_static (G_TYPE_OBJECT, "FrapMenuLayout", &info, 
0);
+    }
+
+  return type;
+}
+
+
+
+static void
+frap_menu_layout_class_init (FrapMenuLayoutClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  g_type_class_add_private (klass, sizeof (FrapMenuLayoutPrivate));
+
+  /* Determine parent type class */
+  frap_menu_layout_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = frap_menu_layout_finalize;
+  gobject_class->get_property = frap_menu_layout_get_property;
+  gobject_class->set_property = frap_menu_layout_set_property;
+}
+
+
+
+static void
+frap_menu_layout_init (FrapMenuLayout *layout)
+{
+  layout->priv = FRAP_MENU_LAYOUT_GET_PRIVATE (layout);
+  layout->priv->nodes = NULL;
+}
+
+
+
+static void
+frap_menu_layout_finalize (GObject *object)
+{
+  FrapMenuLayout *layout = FRAP_MENU_LAYOUT (object);
+
+  /* Free nodes */
+  g_slist_foreach (layout->priv->nodes, (GFunc) frap_menu_layout_free_node, 
NULL);
+  g_slist_free (layout->priv->nodes);
+
+  (*G_OBJECT_CLASS (frap_menu_layout_parent_class)->finalize) (object);
+}
+
+
+
+static void
+frap_menu_layout_get_property (GObject    *object,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  FrapMenuLayout *layout = FRAP_MENU_LAYOUT (layout);
+
+  switch (prop_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+frap_menu_layout_set_property (GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  FrapMenuLayout *layout = FRAP_MENU_LAYOUT (layout);
+
+  switch (prop_id)
+    {
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+FrapMenuLayout*
+frap_menu_layout_new (void)
+{
+  return g_object_new (FRAP_TYPE_MENU_LAYOUT, NULL);
+}
+
+
+
+static void
+frap_menu_layout_free_node (FrapMenuLayoutNode *node)
+{
+  if (node->type == FRAP_MENU_LAYOUT_NODE_FILENAME)
+    g_free (node->data.filename);
+
+  g_free (node);
+}
+
+
+
+void
+frap_menu_layout_add_filename (FrapMenuLayout *layout,
+                               const gchar    *filename)
+{
+  g_return_if_fail (FRAP_IS_MENU_LAYOUT (layout));
+  g_return_if_fail (filename != NULL);
+
+  /* Build filename node */
+  FrapMenuLayoutNode *node = g_new0 (FrapMenuLayoutNode, 1);
+  node->type = FRAP_MENU_LAYOUT_NODE_FILENAME;
+  node->data.filename = g_strdup (filename);
+
+  g_debug ("frap_menu_layout_add_filename ('%s')", filename);
+
+  /* Append node to the list */
+  layout->priv->nodes = g_slist_append (layout->priv->nodes, node);
+}
+
+
+
+void
+frap_menu_layout_add_separator (FrapMenuLayout *layout)
+{
+  g_return_if_fail (FRAP_IS_MENU_LAYOUT (layout));
+
+  /* Build separator node */
+  FrapMenuLayoutNode *node = g_new0 (FrapMenuLayoutNode, 1);
+  node->type = FRAP_MENU_LAYOUT_NODE_SEPARATOR;
+
+  g_debug ("frap_menu_layout_add_separator ()");
+
+  /* Append node to the list */
+  layout->priv->nodes = g_slist_append (layout->priv->nodes, node);
+}
+
+
+
+void
+frap_menu_layout_add_merge (FrapMenuLayout         *layout,
+                            FrapMenuLayoutMergeType type)
+{
+  g_return_if_fail (FRAP_IS_MENU_LAYOUT (layout));
+
+  /* Build merge node */
+  FrapMenuLayoutNode *node = g_new0 (FrapMenuLayoutNode, 1);
+  node->type = FRAP_MENU_LAYOUT_NODE_MERGE;
+  node->data.merge_type = type;
+
+  g_debug ("frap_menu_layout_add_merge (%d)", type);
+
+  /* Append node to the list */
+  layout->priv->nodes = g_slist_append (layout->priv->nodes, node);
+}
+
+
+
+GSList*
+frap_menu_layout_get_nodes (FrapMenuLayout *layout)
+{
+  g_return_val_if_fail (FRAP_IS_MENU_LAYOUT (layout), NULL);
+  return layout->priv->nodes;
+}
+
+
+
+gboolean 
+frap_menu_layout_get_filename_used (FrapMenuLayout *layout,
+                                    const gchar    *filename)
+{
+  FrapMenuLayoutNode *node;
+  GSList             *iter;
+  gboolean            found = FALSE;
+
+  g_return_val_if_fail (FRAP_IS_MENU_LAYOUT (layout), FALSE);
+  g_return_val_if_fail (filename != NULL, FALSE);
+
+  for (iter = layout->priv->nodes; iter != NULL; iter = g_slist_next (iter))
+    {
+      node = (FrapMenuLayoutNode *)iter->data;
+
+      if (G_UNLIKELY (node == NULL))
+        continue;
+
+      if (G_UNLIKELY (node->type == FRAP_MENU_LAYOUT_NODE_FILENAME && 
g_utf8_collate (node->data.filename, filename) == 0))
+        {
+          found = TRUE;
+          break;
+        }
+    }
+
+  return found;
+}
+
+
+
+FrapMenuLayoutNodeType
+frap_menu_layout_node_get_type (FrapMenuLayoutNode *node)
+{
+  g_return_val_if_fail (node != NULL, FRAP_MENU_LAYOUT_NODE_INVALID);
+  return node->type;
+}
+
+
+
+const gchar*
+frap_menu_layout_node_get_filename (FrapMenuLayoutNode *node)
+{
+  g_return_val_if_fail (node != NULL && node->type == 
FRAP_MENU_LAYOUT_NODE_FILENAME, NULL);
+  return node->data.filename;
+}
+
+
+
+
+FrapMenuLayoutMergeType
+frap_menu_layout_node_get_merge_type (FrapMenuLayoutNode *node)
+{
+  g_return_val_if_fail (node != NULL && node->type == 
FRAP_MENU_LAYOUT_NODE_MERGE, FRAP_MENU_LAYOUT_MERGE_ALL);
+  return node->data.merge_type;
+}


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

Added: libfrap/trunk/libfrap/menu/frap-menu-layout.h
===================================================================
--- libfrap/trunk/libfrap/menu/frap-menu-layout.h                               
(rev 0)
+++ libfrap/trunk/libfrap/menu/frap-menu-layout.h       2007-03-18 02:23:12 UTC 
(rev 25185)
@@ -0,0 +1,85 @@
+/* $Id$ */
+/* vi:set expandtab sw=2 sts=2: */
+/*-
+ * Copyright (c) 2007 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
+
+#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_LAYOUT_H__
+#define __FRAP_MENU_LAYOUT_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS;
+
+typedef enum
+{
+  FRAP_MENU_LAYOUT_MERGE_MENUS,
+  FRAP_MENU_LAYOUT_MERGE_FILES,
+  FRAP_MENU_LAYOUT_MERGE_ALL,
+} FrapMenuLayoutMergeType;
+
+typedef enum
+{
+  FRAP_MENU_LAYOUT_NODE_INVALID,
+  FRAP_MENU_LAYOUT_NODE_FILENAME,
+  FRAP_MENU_LAYOUT_NODE_MENUNAME,
+  FRAP_MENU_LAYOUT_NODE_SEPARATOR,
+  FRAP_MENU_LAYOUT_NODE_MERGE,
+} FrapMenuLayoutNodeType;
+
+typedef struct _FrapMenuLayoutNode    FrapMenuLayoutNode;
+
+typedef struct _FrapMenuLayoutPrivate FrapMenuLayoutPrivate;
+typedef struct _FrapMenuLayoutClass   FrapMenuLayoutClass;
+typedef struct _FrapMenuLayout        FrapMenuLayout;
+
+#define FRAP_TYPE_MENU_LAYOUT            (frap_menu_layout_get_type())
+#define FRAP_MENU_LAYOUT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), 
FRAP_TYPE_MENU_LAYOUT, FrapMenuLayout))
+#define FRAP_MENU_LAYOUT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), 
FRAP_TYPE_MENU_LAYOUT, FrapMenuLayoutClass))
+#define FRAP_IS_MENU_LAYOUT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), 
FRAP_TYPE_MENU_LAYOUT))
+#define FRAP_IS_MENU_LAYOUT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), 
FRAP_TYPE_MENU_LAYOUT))
+#define FRAP_MENU_LAYOUT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), 
FRAP_TYPE_MENU_LAYOUT, FrapMenuLayoutClass))
+
+GType                   frap_menu_layout_get_type          (void) G_GNUC_CONST;
+
+FrapMenuLayout         *frap_menu_layout_new               (void) 
G_GNUC_MALLOC;
+void                    frap_menu_layout_add_filename      (FrapMenuLayout     
     *layout,
+                                                            const gchar        
     *filename);
+void                    frap_menu_layout_add_separator     (FrapMenuLayout     
     *layout);
+void                    frap_menu_layout_add_merge         (FrapMenuLayout     
     *layout,
+                                                            
FrapMenuLayoutMergeType  type);
+GSList                 *frap_menu_layout_get_nodes         (FrapMenuLayout     
     *layout);
+gboolean                frap_menu_layout_get_filename_used (FrapMenuLayout     
     *layout,
+                                                            const gchar        
     *filename);
+
+FrapMenuLayoutNodeType  frap_menu_layout_node_get_type     (FrapMenuLayoutNode 
      *node);
+const gchar            *frap_menu_layout_node_get_filename (FrapMenuLayoutNode 
      *node);
+FrapMenuLayoutMergeType frap_menu_layout_get_merge_type    (FrapMenuLayoutNode 
      *node);
+
+G_END_DECLS;
+
+#endif /* !__FRAP_MENU_LAYOUT_H__ */
+


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

Added: libfrap/trunk/libfrap/menu/frap-menu-separator.c
===================================================================
--- libfrap/trunk/libfrap/menu/frap-menu-separator.c                            
(rev 0)
+++ libfrap/trunk/libfrap/menu/frap-menu-separator.c    2007-03-18 02:23:12 UTC 
(rev 25185)
@@ -0,0 +1,136 @@
+/* $Id$ */
+/* vim:set et ai sw=2 sts=2: */
+/*-
+ * Copyright (c) 2007 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 <frap-menu-separator.h>
+
+
+
+static void               frap_menu_separator_class_init 
(FrapMenuSeparatorClass *klass);
+static void               frap_menu_separator_init       (FrapMenuSeparator    
  *separator);
+static void               frap_menu_separator_finalize   (GObject              
  *object);
+
+
+
+static FrapMenuSeparator *_frap_menu_separator = NULL;
+
+
+
+void
+_frap_menu_separator_init (void)
+{
+  if (G_LIKELY (_frap_menu_separator == NULL))
+    _frap_menu_separator = g_object_new (FRAP_TYPE_MENU_SEPARATOR, NULL);
+}
+
+
+
+void
+_frap_menu_separator_shutdown (void)
+{
+  if (G_LIKELY (_frap_menu_separator != NULL))
+    g_object_unref (G_OBJECT (_frap_menu_separator));
+}
+
+
+
+struct _FrapMenuSeparatorClass
+{
+  GObjectClass __parent__;
+};
+
+struct _FrapMenuSeparator
+{
+  GObject __parent__;
+};
+
+
+
+static GObjectClass *frap_menu_separator_parent_class = NULL;
+
+
+
+GType
+frap_menu_separator_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (FrapMenuSeparatorClass),
+        NULL,
+        NULL,
+        (GClassInitFunc) frap_menu_separator_class_init,
+        NULL,
+        NULL,
+        sizeof (FrapMenuSeparator),
+        0,
+        (GInstanceInitFunc) frap_menu_separator_init,
+        NULL,
+      };
+
+      type = g_type_register_static (G_TYPE_OBJECT, "FrapMenuSeparator", 
&info, 0);
+    }
+
+  return type;
+}
+
+
+
+static void
+frap_menu_separator_class_init (FrapMenuSeparatorClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* Determine parent type class */
+  frap_menu_separator_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = frap_menu_separator_finalize;
+}
+
+
+
+static void
+frap_menu_separator_init (FrapMenuSeparator *separator)
+{
+}
+
+
+
+static void
+frap_menu_separator_finalize (GObject *object)
+{
+  (*G_OBJECT_CLASS (frap_menu_separator_parent_class)->finalize) (object);
+}
+
+
+
+FrapMenuSeparator*
+frap_menu_separator_get_default (void)
+{
+  return _frap_menu_separator;
+}


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

Added: libfrap/trunk/libfrap/menu/frap-menu-separator.h
===================================================================
--- libfrap/trunk/libfrap/menu/frap-menu-separator.h                            
(rev 0)
+++ libfrap/trunk/libfrap/menu/frap-menu-separator.h    2007-03-18 02:23:12 UTC 
(rev 25185)
@@ -0,0 +1,59 @@
+/* $Id$ */
+/* vi:set et ai sw=2 sts=2: */
+/*-
+ * Copyright (c) 2007 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
+
+#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_SEPARATOR_H__
+#define __FRAP_MENU_SEPARATOR_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS;
+
+typedef struct _FrapMenuSeparatorClass FrapMenuSeparatorClass;
+typedef struct _FrapMenuSeparator      FrapMenuSeparator;
+
+#define FRAP_TYPE_MENU_SEPARATOR            (frap_menu_separator_get_type())
+#define FRAP_MENU_SEPARATOR(obj)            (G_TYPE_CHECK_INSTANCE_CAST 
((obj), FRAP_TYPE_MENU_SEPARATOR, FrapMenuSeparator))
+#define FRAP_MENU_SEPARATOR_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), 
FRAP_TYPE_MENU_SEPARATOR, FrapMenuSeparatorClass))
+#define FRAP_IS_MENU_SEPARATOR(obj)         (G_TYPE_CHECK_INSTANCE_TYPE 
((obj), FRAP_TYPE_MENU_SEPARATOR))
+#define FRAP_IS_MENU_SEPARATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), 
FRAP_TYPE_MENU_SEPARATOR))
+#define FRAP_MENU_SEPARATOR_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), 
FRAP_TYPE_MENU_SEPARATOR, FrapMenuSeparatorClass))
+
+
+GType              frap_menu_separator_get_type    (void) G_GNUC_CONST;
+
+FrapMenuSeparator *frap_menu_separator_get_default (void);
+
+#if defined(LIBFRAPMENU_COMPILATION)
+void               _frap_menu_separator_init       (void) G_GNUC_INTERNAL;
+void               _frap_menu_separator_shutdown   (void) G_GNUC_INTERNAL;
+#endif
+
+G_END_DECLS;
+
+#endif /* !__FRAP_MENU_SEPARATOR_H__ */


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

Modified: libfrap/trunk/libfrap/menu/frap-menu.c
===================================================================
--- libfrap/trunk/libfrap/menu/frap-menu.c      2007-03-17 22:54:06 UTC (rev 
25184)
+++ libfrap/trunk/libfrap/menu/frap-menu.c      2007-03-18 02:23:12 UTC (rev 
25185)
@@ -40,6 +40,8 @@
 #include <frap-menu-item-pool.h>
 #include <frap-menu-item-cache.h>
 #include <frap-menu-move.h>
+#include <frap-menu-layout.h>
+#include <frap-menu-separator.h>
 #include <frap-menu.h>
 
 
@@ -95,6 +97,9 @@
 
       /* Initialize the directory module */
       _frap_menu_directory_init ();
+
+      /* Creates the menu separator */
+      _frap_menu_separator_init ();
     }
 }
 
@@ -113,6 +118,9 @@
       /* Unset desktop environment */
       frap_menu_set_environment (NULL);
 
+      /* Destroys the menu separator */
+      _frap_menu_separator_shutdown ();
+
       /* Shutdown the directory module */
       _frap_menu_directory_shutdown ();
 
@@ -136,6 +144,7 @@
   FRAP_MENU_PARSE_STATE_RULE,
   FRAP_MENU_PARSE_STATE_END,
   FRAP_MENU_PARSE_STATE_MOVE,
+  FRAP_MENU_PARSE_STATE_LAYOUT,
 
 } FrapMenuParseState;
 
@@ -342,6 +351,9 @@
   /* Shared menu item cache */
   FrapMenuItemCache *cache;
 
+  /* Menu layout */
+  FrapMenuLayout    *layout;
+
   /* Parse information (used for resolving) */
   FrapMenuParseInfo *parse_info;
 };
@@ -495,6 +507,7 @@
   menu->priv->rules = NULL;
   menu->priv->moves = NULL;
   menu->priv->pool = frap_menu_item_pool_new ();
+  menu->priv->layout = frap_menu_layout_new ();
 
   /* Take reference on the menu item cache */
   menu->priv->cache = frap_menu_item_cache_get_default ();
@@ -548,6 +561,9 @@
   /* Free item pool */
   g_object_unref (G_OBJECT (menu->priv->pool));
 
+  /* Free menu layout */
+  g_object_unref (G_OBJECT (menu->priv->layout));
+
   /* Release item cache reference */
   g_object_unref (G_OBJECT (menu->priv->cache));
 
@@ -711,7 +727,7 @@
 {
   FrapMenu *menu;
 
-  g_return_val_if_fail (g_path_is_absolute (filename), NULL);
+  g_return_val_if_fail (filename != NULL && g_path_is_absolute (filename), 
NULL);
 
   /* Create new menu */
   menu = g_object_new (FRAP_TYPE_MENU, "filename", filename, NULL);
@@ -1216,6 +1232,11 @@
           /* Set parse state */
           menu_context->state = FRAP_MENU_PARSE_STATE_MOVE;
         }
+      else if (g_utf8_collate (element_name, "Layout") == 0)
+        {
+          /* Set parse state */
+          menu_context->state = FRAP_MENU_PARSE_STATE_LAYOUT;
+        }
       
       break;
 
@@ -1289,6 +1310,53 @@
         menu_context->node_type = FRAP_MENU_PARSE_NODE_TYPE_NEW;
 
       break;
+
+    case FRAP_MENU_PARSE_STATE_LAYOUT:
+      /* Fetch current menu from stack */
+      current_menu = g_list_first (menu_context->menu_stack)->data;
+
+      if (g_utf8_collate (element_name, "Filename") == 0)
+        {
+          /* Set node type */
+          menu_context->node_type = FRAP_MENU_PARSE_NODE_TYPE_FILENAME;
+        }
+      else if (g_utf8_collate (element_name, "Separator") == 0)
+        {
+          /* Add separator to the menu layout */
+          frap_menu_layout_add_separator (current_menu->priv->layout);
+        }
+      else if (g_utf8_collate (element_name, "Merge") == 0)
+        {
+          FrapMenuLayoutMergeType type = FRAP_MENU_LAYOUT_MERGE_ALL;
+
+          gboolean type_found = FALSE;
+          gint     i;
+
+          /* Find 'type' attribute */
+          for (i = 0; i < g_strv_length (attribute_names); ++i) 
+            {
+              if (g_utf8_collate (attribute_names[i], "type") == 0)
+                {
+                  /* Determine merge type */
+                  if (g_utf8_collate (attribute_values[i], "menus") == 0)
+                    type = FRAP_MENU_LAYOUT_MERGE_MENUS;
+                  else if (g_utf8_collate (attribute_values[i], "files") == 0)
+                    type = FRAP_MENU_LAYOUT_MERGE_FILES;
+                  else if (g_utf8_collate (attribute_values[i], "all") == 0)
+                    type = FRAP_MENU_LAYOUT_MERGE_ALL;
+                  else 
+                    g_warning ("Unsupported layout merge type <Merge 
type='%s'/> detected. Using type 'all'.", attribute_values[i]);
+
+                  type_found = TRUE;
+                }
+            }
+
+          if (G_UNLIKELY (!type_found))
+            g_warning ("Type attribute missing for <Merge> element. Using type 
'all'.");
+
+          /* Add merge to the menu layout */
+          frap_menu_layout_add_merge (current_menu->priv->layout, type);
+        }
     }
 }
 
@@ -1370,6 +1438,16 @@
       else if (g_utf8_collate (element_name, "New") == 0)
         menu_context->move = NULL;
       break;
+
+    case FRAP_MENU_PARSE_STATE_LAYOUT:
+      if (g_utf8_collate (element_name, "Layout") == 0)
+        {
+          if (g_list_length (menu_context->menu_stack) > 1)
+            menu_context->state = FRAP_MENU_PARSE_STATE_MENU;
+          else
+            menu_context->state = FRAP_MENU_PARSE_STATE_ROOT;
+        }
+      break;
     }
 }
 
@@ -1416,8 +1494,13 @@
       break;
 
     case FRAP_MENU_PARSE_NODE_TYPE_FILENAME:
-      if (G_LIKELY (current_rule != NULL))
-        frap_menu_rules_add_filename (current_rule, content);
+      if (menu_context->state == FRAP_MENU_PARSE_STATE_RULE) 
+        {
+          if (G_LIKELY (current_rule != NULL))
+            frap_menu_rules_add_filename (current_rule, content);
+        }
+      else if (menu_context->state == FRAP_MENU_PARSE_STATE_LAYOUT)
+        frap_menu_layout_add_filename (current_menu->priv->layout, content);
       break;
 
     case FRAP_MENU_PARSE_NODE_TYPE_CATEGORY:
@@ -2473,6 +2556,53 @@
 static void
 frap_menu_resolve_moves (FrapMenu *menu)
 {
+  FrapMenuMove *move;
+  FrapMenu     *source;
+  FrapMenu     *destination;
+  GSList       *iter;
+
+  g_return_if_fail (FRAP_IS_MENU (menu));
+
+  /* Recurse into the submenus which need to perform move actions first */
+  for (iter = menu->priv->submenus; iter != NULL; iter = g_slist_next (iter))
+    {
+      source = FRAP_MENU (iter->data);
+
+      /* Resolve moves of the child menu */
+      frap_menu_resolve_moves (source);
+    }
+
+  /* Iterate over move instructions */
+  for (iter = menu->priv->moves; iter != NULL; iter = g_slist_next (iter))
+    {
+      move = FRAP_MENU_MOVE (iter->data);
+      
+      g_critical ("Moving %s to %s ...", frap_menu_move_get_old (move), 
frap_menu_move_get_new (move));
+
+      /* Determine submenu with the old name */
+      source = frap_menu_get_menu_with_name (menu, frap_menu_move_get_old 
(move));
+
+      g_critical ("source = 0x%x", source);
+
+      /* Skip if there is no such submenu */
+      if (G_LIKELY (source == NULL))
+        continue;
+
+      /* Determine destination submenu */
+      destination = frap_menu_get_menu_with_name (menu, frap_menu_move_get_new 
(move));
+
+      g_critical ("destination = 0x%x", destination);
+
+      /* If destination does not exist, simply reset the name of the source 
menu */
+      if (G_LIKELY (destination == NULL))
+        frap_menu_set_name (source, frap_menu_move_get_new (move));
+      else
+        {
+          /* TODO: See section "Merging" in the menu specification. */
+        }
+    }
+
+#if 0
   FrapMenu     *submenu;
   FrapMenu     *target_submenu;
   FrapMenuMove *move;
@@ -2532,6 +2662,7 @@
             }
         }
     }
+#endif
 }
 
 
@@ -2617,3 +2748,73 @@
 
   return items;
 }
+
+
+
+GSList*
+frap_menu_get_layout_items (FrapMenu *menu)
+{
+  GSList *items = NULL;
+  GSList *menu_items;
+  GSList *nodes;
+  GSList *iter;
+
+  g_return_val_if_fail (FRAP_IS_MENU (menu), NULL);
+
+  /* Fetch layout nodes */
+  nodes = frap_menu_layout_get_nodes (menu->priv->layout);
+
+  /* Only process layout if there are any layout information at all */
+  if (G_UNLIKELY (nodes != NULL))
+    {
+      g_debug ("Menu has layout");
+
+      /* Process layout nodes in order */
+      for (iter = nodes; iter != NULL; iter = g_slist_next (iter))
+        {
+          FrapMenuLayoutNode    *node = (FrapMenuLayoutNode *)iter->data;
+          FrapMenuLayoutNodeType type;
+          FrapMenuItem          *item;
+          FrapMenuSeparator     *separator;
+
+          /* Determine layout node type */
+          type = frap_menu_layout_node_get_type (node);
+
+          switch (type)
+            {
+            case FRAP_MENU_LAYOUT_NODE_FILENAME:
+              item = frap_menu_item_pool_lookup (menu->priv->pool, 
frap_menu_layout_node_get_filename (node));
+              if (G_LIKELY (item != NULL))
+                items = g_slist_append (items, item);
+              break;
+            case FRAP_MENU_LAYOUT_NODE_SEPARATOR:
+              items = g_slist_append (items, frap_menu_separator_get_default 
());
+              break;
+            case FRAP_MENU_LAYOUT_NODE_MERGE:
+              switch (node->data.merge_type)
+                {
+                case FRAP_MENU_LAYOUT_MERGE_ALL:
+                  /* TODO Fetch all items which are not used in the layout yet 
and sort them 
+                   * by displayed name (ascending) */
+                  break;
+                case FRAP_MENU_LAYOUT_MERGE_FILES:
+                  /* TODO Fetch all menu items which are not used in the 
layout yet and sort them 
+                   * by displayed name (ascending) */
+                  break;
+                case FRAP_MENU_LAYOUT_MERGE_MENUS:
+                  /* TODO Fetch all submenus which are not used in the layout 
yet and sort them 
+                   * by displayed name (ascending) */
+                  break;
+                }
+              break;
+            }
+        }
+    }
+  else
+    {
+      /* No layout used - just return items without layout */
+      items = frap_menu_get_items (menu);
+    }
+
+  return items;
+}

Modified: libfrap/trunk/libfrap/menu/frap-menu.h
===================================================================
--- libfrap/trunk/libfrap/menu/frap-menu.h      2007-03-17 22:54:06 UTC (rev 
25184)
+++ libfrap/trunk/libfrap/menu/frap-menu.h      2007-03-18 02:23:12 UTC (rev 
25185)
@@ -77,6 +77,7 @@
 FrapMenu          *frap_menu_get_parent            (FrapMenu          *menu);
 FrapMenuItemPool  *frap_menu_get_item_pool         (FrapMenu          *menu);
 GSList            *frap_menu_get_items             (FrapMenu          *menu);
+GSList            *frap_menu_get_layout_items      (FrapMenu          *menu);
 
 G_END_DECLS;
 

Modified: libfrap/trunk/libfrap/menu/libfrapmenu.h
===================================================================
--- libfrap/trunk/libfrap/menu/libfrapmenu.h    2007-03-17 22:54:06 UTC (rev 
25184)
+++ libfrap/trunk/libfrap/menu/libfrapmenu.h    2007-03-18 02:23:12 UTC (rev 
25185)
@@ -33,6 +33,8 @@
 #include <frap-menu-and-rules.h>
 #include <frap-menu-not-rules.h>
 #include <frap-menu-directory.h>
+#include <frap-menu-layout.h>
+#include <frap-menu-separator.h>
 #include <frap-menu.h>
 
 #define LIBFRAPMENU_INSIDE_LIBFRAPMENU_H

Modified: libfrap/trunk/libfrap/menu/tests/test-display-root-menu.c
===================================================================
--- libfrap/trunk/libfrap/menu/tests/test-display-root-menu.c   2007-03-17 
22:54:06 UTC (rev 25184)
+++ libfrap/trunk/libfrap/menu/tests/test-display-root-menu.c   2007-03-18 
02:23:12 UTC (rev 25185)
@@ -163,8 +163,7 @@
 
 
 void
-create_item_widgets_for_menu (const gchar  *desktop_id,
-                              FrapMenuItem *item,
+create_item_widgets_for_menu (FrapMenuItem *item,
                               GtkWidget    *widget)
 {
   GtkWidget *menu_item;
@@ -206,65 +205,77 @@
   GtkWidget         *submenu;
   GtkWidget         *image;
   GSList            *iter;
-  GSList            *menus;
+  GSList            *items;
   const gchar       *icon_name;
   GdkPixbuf         *pixbuf;
   GtkIconTheme      *icon_theme = gtk_icon_theme_get_default ();
 
-  /* Create sorted copy of the submenu list */
-  menus = g_slist_sort (g_slist_copy (frap_menu_get_menus (menu)), 
(GCompareFunc) compare_menus);
+  /* Get submenus and items based on the menu layout */
+  items = frap_menu_get_layout_items (menu);
 
-  for (iter = menus; iter != NULL; iter = g_slist_next (iter))
+  /* Iterate over children */
+  for (iter = items; iter != NULL; iter = g_slist_next (iter))
     {
-      /* Get menu directory */
-      directory = frap_menu_get_directory (FRAP_MENU (iter->data));
+      if (FRAP_IS_MENU_ITEM (iter->data))
+        {
+          /* Add menu item to the menu */
+          create_item_widgets_for_menu (FRAP_MENU_ITEM (iter->data), widget);
+        }
+      else if (FRAP_IS_MENU (iter->data))
+        {
+          FrapMenu *child_menu = FRAP_MENU (iter->data);
 
-      /* Skip if menu has no directory (and thus, no display information) */
-      if (G_UNLIKELY (directory == NULL))
-        continue;
+          /* Get menu directory */
+          directory = frap_menu_get_directory (FRAP_MENU (child_menu));
 
-      /* Skip if menu is empty */
-      if (frap_menu_item_pool_get_empty (frap_menu_get_item_pool (iter->data)))
-        continue;
+          /* Skip if menu has no directory (and thus, no display information) 
*/
+          if (G_UNLIKELY (directory == NULL))
+            continue;
 
-      /* Skip if menu is only shown in other environments or is not shown in
-       * this one */
-      if (!frap_menu_directory_show_in_environment (directory))
-        continue;
+          /* Skip if menu is empty */
+          if (frap_menu_item_pool_get_empty (frap_menu_get_item_pool 
(child_menu)))
+            continue;
 
-      /* Determine icon name */
-      icon_name = frap_menu_directory_get_icon (directory);
+          /* Skip if menu is only shown in other environments or is not shown 
in
+           * this one */
+          if (!frap_menu_directory_show_in_environment (directory))
+            continue;
 
-      /* Load menu icon */
-      pixbuf = gtk_icon_theme_load_icon (icon_theme, icon_name, ICON_SIZE, 
GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
-      if (G_UNLIKELY (pixbuf == NULL))
-        pixbuf = gtk_icon_theme_load_icon (icon_theme, "applications-other", 
ICON_SIZE, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+          /* Determine icon name */
+          icon_name = frap_menu_directory_get_icon (directory);
 
-      /* Create image widget */
-      image = gtk_image_new_from_pixbuf (pixbuf);
+          /* Load menu icon */
+          pixbuf = gtk_icon_theme_load_icon (icon_theme, icon_name, ICON_SIZE, 
GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+          if (G_UNLIKELY (pixbuf == NULL))
+            pixbuf = gtk_icon_theme_load_icon (icon_theme, 
"applications-other", ICON_SIZE, GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
 
-      /* Create menu item */
-      menu_item = gtk_image_menu_item_new_with_label 
(frap_menu_directory_get_name (directory));
-      gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), image);
-      gtk_menu_shell_append (GTK_MENU_SHELL (widget), menu_item);
-      gtk_widget_show (menu_item);
+          /* Create image widget */
+          image = gtk_image_new_from_pixbuf (pixbuf);
 
-      /* Create submenu */
-      submenu = gtk_menu_new ();
-      gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), submenu);
+          /* Create menu item */
+          menu_item = gtk_image_menu_item_new_with_label 
(frap_menu_directory_get_name (directory));
+          gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), 
image);
+          gtk_menu_shell_append (GTK_MENU_SHELL (widget), menu_item);
+          gtk_widget_show (menu_item);
 
-      /* Create widgets for submenu */
-      create_widgets_for_menu (submenu, FRAP_MENU (iter->data));
+          /* Create submenu */
+          submenu = gtk_menu_new ();
+          gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), submenu);
+
+          /* Create widgets for submenu */
+          create_widgets_for_menu (submenu, FRAP_MENU (child_menu));
+        }
+      else if (FRAP_IS_MENU_SEPARATOR (iter->data))
+        {
+          /* Add a separator to the menu */
+          menu_item = gtk_separator_menu_item_new ();
+          gtk_menu_shell_append (GTK_MENU_SHELL (widget), menu_item);
+          gtk_widget_show (menu_item);
+        }
     }
 
-  /* Get item pool */
-  pool = frap_menu_get_item_pool (menu);
-
-  /* Create menu items */
-  frap_menu_item_pool_foreach (pool, (GHFunc) create_item_widgets_for_menu, 
widget);
-
-  /* Free submenu list */
-  g_slist_free (menus);
+  /* Free items list */
+  g_slist_free (items);
 }
 
 

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

Reply via email to