This is an automated email from the git hooks/post-receive script.

nomad pushed a commit to branch master
in repository apps/xfdashboard.

commit 7ee7e6490d558c216280c45bb5c4997eda69aa6a
Author: Stephan Haller <[email protected]>
Date:   Wed Mar 16 22:25:39 2016 +0100

    Implement our own model class and replace ClutterModel with new 
XfdashboardModel because ClutterModel is deprecated since Clutter version 1.24. 
This new model implementation should be compatible to all Clutter version and 
silence compiler warnings when compiled agaist Clutter 1.24 or higher.
    
    This commit should finally fix for issue GH #117
---
 libxfdashboard/Makefile.am               |    2 +
 libxfdashboard/application.c             |    1 +
 libxfdashboard/applications-menu-model.c |  519 ++++++------
 libxfdashboard/applications-menu-model.h |   19 +-
 libxfdashboard/applications-view.c       |   33 +-
 libxfdashboard/model.c                   | 1306 ++++++++++++++++++++++++++++++
 libxfdashboard/model.h                   |  196 +++++
 7 files changed, 1765 insertions(+), 311 deletions(-)

diff --git a/libxfdashboard/Makefile.am b/libxfdashboard/Makefile.am
index 0dafee6..f61f9ca 100644
--- a/libxfdashboard/Makefile.am
+++ b/libxfdashboard/Makefile.am
@@ -51,6 +51,7 @@ libxfdashboard_la_headers = \
        image-content.h \
        live-window.h \
        live-workspace.h \
+       model.h \
        outline-effect.h \
        plugin.h \
        plugins-manager.h \
@@ -117,6 +118,7 @@ libxfdashboard_la_SOURCES = \
        image-content.c \
        live-window.c \
        live-workspace.c \
+       model.c \
        outline-effect.c \
        plugin.c \
        plugins-manager.c \
diff --git a/libxfdashboard/application.c b/libxfdashboard/application.c
index 4f6b27f..c90f87c 100644
--- a/libxfdashboard/application.c
+++ b/libxfdashboard/application.c
@@ -123,6 +123,7 @@ enum
 
 static guint XfdashboardApplicationSignals[SIGNAL_LAST]={ 0, };
 
+
 /* IMPLEMENTATION: Private variables and methods */
 #define XFDASHBOARD_APP_ID                                     
"de.froevel.nomad.xfdashboard"
 #define XFDASHBOARD_XFCONF_CHANNEL                     "xfdashboard"
diff --git a/libxfdashboard/applications-menu-model.c 
b/libxfdashboard/applications-menu-model.c
index f707563..8f95940 100644
--- a/libxfdashboard/applications-menu-model.c
+++ b/libxfdashboard/applications-menu-model.c
@@ -36,7 +36,7 @@
 /* Define these classes in GObject system */
 G_DEFINE_TYPE(XfdashboardApplicationsMenuModel,
                                xfdashboard_applications_menu_model,
-                               CLUTTER_TYPE_LIST_MODEL)
+                               XFDASHBOARD_TYPE_MODEL)
 
 /* Private structure - access only by public API if needed */
 #define XFDASHBOARD_APPLICATIONS_MENU_MODEL_GET_PRIVATE(obj) \
@@ -65,13 +65,53 @@ static guint 
XfdashboardApplicationsMenuModelSignals[SIGNAL_LAST]={ 0, };
 typedef struct _XfdashboardApplicationsMenuModelFillData               
XfdashboardApplicationsMenuModelFillData;
 struct _XfdashboardApplicationsMenuModelFillData
 {
-       gint            sequenceID;
-       GSList          *populatedMenus;
+       gint                            sequenceID;
+       GSList                          *populatedMenus;
+};
+
+typedef struct _XfdashboardApplicationsMenuModelItem                   
XfdashboardApplicationsMenuModelItem;
+struct _XfdashboardApplicationsMenuModelItem
+{
+       guint                           sequenceID;
+       GarconMenuElement       *menuElement;
+       GarconMenu                      *parentMenu;
+       GarconMenu                      *section;
+       gchar                           *title;
+       gchar                           *description;
 };
 
 /* Forward declarations */
 static void 
_xfdashboard_applications_menu_model_fill_model(XfdashboardApplicationsMenuModel
 *self);
 
+/* Free an item of application menu model */
+static void 
_xfdashboard_applications_menu_model_item_free(XfdashboardApplicationsMenuModelItem
 *inItem)
+{
+       if(inItem)
+       {
+               /* Release allocated resources in item */
+               if(inItem->menuElement) g_object_unref(inItem->menuElement);
+               if(inItem->parentMenu) g_object_unref(inItem->parentMenu);
+               if(inItem->section) g_object_unref(inItem->section);
+               if(inItem->title) g_free(inItem->title);
+               if(inItem->description) g_free(inItem->description);
+
+               /* Free item */
+               g_free(inItem);
+       }
+}
+
+/* Create a new item for application menu model */
+static XfdashboardApplicationsMenuModelItem* 
_xfdashboard_applications_menu_model_item_new(void)
+{
+       XfdashboardApplicationsMenuModelItem    *item;
+
+       /* Create empty item */
+       item=g_new0(XfdashboardApplicationsMenuModelItem, 1);
+
+       /* Return new empty item */
+       return(item);
+}
+
 /* A menu was changed and needs to be reloaded */
 static void 
_xfdashboard_applications_menu_model_on_reload_required(XfdashboardApplicationsMenuModel
 *self,
                                                                                
                                                        gpointer inUserData)
@@ -87,33 +127,16 @@ static void 
_xfdashboard_applications_menu_model_on_reload_required(XfdashboardA
 static void 
_xfdashboard_applications_menu_model_clear(XfdashboardApplicationsMenuModel 
*self)
 {
        XfdashboardApplicationsMenuModelPrivate         *priv;
-       ClutterModelIter                                                        
*iterator;
-       GarconMenuElement                                                       
*menuElement;
 
        g_return_if_fail(XFDASHBOARD_IS_APPLICATIONS_MENU_MODEL(self));
 
        priv=self->priv;
 
        /* Unset filter (forces all rows being accessible and not being 
skipped/filtered) */
-       clutter_model_set_filter(CLUTTER_MODEL(self), NULL, NULL, NULL);
+       xfdashboard_model_set_filter(XFDASHBOARD_MODEL(self), NULL, NULL, NULL);
 
        /* Clean up and remove all rows */
-       while(clutter_model_get_n_rows(CLUTTER_MODEL(self)))
-       {
-               /* Get data from model for clean up */
-               menuElement=NULL;
-               iterator=clutter_model_get_iter_at_row(CLUTTER_MODEL(self), 0);
-               clutter_model_iter_get(iterator,
-                                                               
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_MENU_ELEMENT, &menuElement,
-                                                               -1);
-
-               /* Remove row */
-               clutter_model_remove(CLUTTER_MODEL(self), 0);
-
-               /* Release iterator */
-               if(menuElement) g_object_unref(menuElement);
-               g_object_unref(iterator);
-       }
+       xfdashboard_model_remove_all(XFDASHBOARD_MODEL(self));
 
        /* Destroy root menu */
        if(priv->rootMenu)
@@ -124,48 +147,41 @@ static void 
_xfdashboard_applications_menu_model_clear(XfdashboardApplicationsMe
 }
 
 /* Helper function to filter model data */
-static gboolean 
_xfdashboard_applications_menu_model_filter_by_menu(ClutterModel *inModel,
-                                                                               
                                                        ClutterModelIter 
*inIter,
+static gboolean 
_xfdashboard_applications_menu_model_filter_by_menu(XfdashboardModelIter 
*inIter,
                                                                                
                                                        gpointer inUserData)
 {
-       XfdashboardApplicationsMenuModel                        *self;
-       XfdashboardApplicationsMenuModelPrivate         *priv;
-       GarconMenu                                                              
        *parentMenu;
+       XfdashboardApplicationsMenuModel                        *model;
+       XfdashboardApplicationsMenuModelPrivate         *modelPriv;
+       gboolean                                                                
        doShow;
        GarconMenu                                                              
        *requestedParentMenu;
-       GarconMenuElement                                                       
*menuElement;
+       XfdashboardApplicationsMenuModelItem            *item;
        GarconMenuItemPool                                                      
*itemPool;
        const gchar                                                             
        *desktopID;
-       gboolean                                                                
        doShow;
 
-       g_return_val_if_fail(XFDASHBOARD_IS_APPLICATIONS_MENU_MODEL(inModel), 
FALSE);
-       g_return_val_if_fail(CLUTTER_IS_MODEL_ITER(inIter), FALSE);
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL_ITER(inIter), FALSE);
        g_return_val_if_fail(GARCON_IS_MENU(inUserData), FALSE);
+       
g_return_val_if_fail(XFDASHBOARD_IS_APPLICATIONS_MENU_MODEL(xfdashboard_model_iter_get_model(inIter)),
 FALSE);
 
-       self=XFDASHBOARD_APPLICATIONS_MENU_MODEL(inModel);
-       priv=self->priv;
-       requestedParentMenu=GARCON_MENU(inUserData);
-       menuElement=NULL;
        doShow=FALSE;
+       requestedParentMenu=GARCON_MENU(inUserData);
+       
model=XFDASHBOARD_APPLICATIONS_MENU_MODEL(xfdashboard_model_iter_get_model(inIter));
+       modelPriv=model->priv;
 
        /* Get menu element at iterator */
-       clutter_model_iter_get(inIter,
-                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_MENU_ELEMENT, &menuElement,
-                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_PARENT_MENU, &parentMenu,
-                                                       -1);
-       if(menuElement==NULL) return(FALSE);
+       
item=(XfdashboardApplicationsMenuModelItem*)xfdashboard_model_iter_get(inIter);
+       if(item->menuElement==NULL) return(FALSE);
 
        /* Only menu items and sub-menus can be visible */
-       if(!GARCON_IS_MENU(menuElement) && !GARCON_IS_MENU_ITEM(menuElement))
+       if(!GARCON_IS_MENU(item->menuElement) && 
!GARCON_IS_MENU_ITEM(item->menuElement))
        {
-               g_object_unref(menuElement);
                return(FALSE);
        }
 
        /* If menu element is a menu check if it's parent menu is the requested 
one */
-       if(GARCON_IS_MENU(menuElement))
+       if(GARCON_IS_MENU(item->menuElement))
        {
-               if(requestedParentMenu==parentMenu ||
-                       (!requestedParentMenu && parentMenu==priv->rootMenu))
+               if(requestedParentMenu==item->parentMenu ||
+                       (!requestedParentMenu && 
item->parentMenu==modelPriv->rootMenu))
                {
                        doShow=TRUE;
                }
@@ -174,70 +190,58 @@ static gboolean 
_xfdashboard_applications_menu_model_filter_by_menu(ClutterModel
                else
                {
                        /* Get desktop ID of menu item */
-                       
desktopID=garcon_menu_item_get_desktop_id(GARCON_MENU_ITEM(menuElement));
+                       
desktopID=garcon_menu_item_get_desktop_id(GARCON_MENU_ITEM(item->menuElement));
 
                        /* Get menu items of menu */
-                       itemPool=garcon_menu_get_item_pool(parentMenu);
+                       itemPool=garcon_menu_get_item_pool(item->parentMenu);
 
                        /* Determine if menu item at iterator is in menu's item 
pool */
                        if(garcon_menu_item_pool_lookup(itemPool, 
desktopID)!=FALSE) doShow=TRUE;
                }
 
-       /* Release allocated resources */
-       if(parentMenu) g_object_unref(parentMenu);
-       g_object_unref(menuElement);
-
        /* If we get here return TRUE to show model data item or FALSE to hide 
*/
        return(doShow);
 }
 
-static gboolean 
_xfdashboard_applications_menu_model_filter_by_section(ClutterModel *inModel,
-                                                                               
                                                                
ClutterModelIter *inIter,
+static gboolean 
_xfdashboard_applications_menu_model_filter_by_section(XfdashboardModelIter 
*inIter,
                                                                                
                                                                gpointer 
inUserData)
 {
-       XfdashboardApplicationsMenuModel                        *self;
-       XfdashboardApplicationsMenuModelPrivate         *priv;
-       GarconMenu                                                              
        *section;
-       GarconMenu                                                              
        *requestedSection;
+       XfdashboardApplicationsMenuModel                        *model;
+       XfdashboardApplicationsMenuModelPrivate         *modelPriv;
        gboolean                                                                
        doShow;
+       GarconMenu                                                              
        *requestedSection;
+       XfdashboardApplicationsMenuModelItem            *item;
 
-       g_return_val_if_fail(XFDASHBOARD_IS_APPLICATIONS_MENU_MODEL(inModel), 
FALSE);
-       g_return_val_if_fail(CLUTTER_IS_MODEL_ITER(inIter), FALSE);
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL_ITER(inIter), FALSE);
+       
g_return_val_if_fail(XFDASHBOARD_IS_APPLICATIONS_MENU_MODEL(xfdashboard_model_iter_get_model(inIter)),
 FALSE);
        g_return_val_if_fail(GARCON_IS_MENU(inUserData), FALSE);
 
-       self=XFDASHBOARD_APPLICATIONS_MENU_MODEL(inModel);
-       priv=self->priv;
-       requestedSection=GARCON_MENU(inUserData);
        doShow=FALSE;
+       requestedSection=GARCON_MENU(inUserData);
+       
model=XFDASHBOARD_APPLICATIONS_MENU_MODEL(xfdashboard_model_iter_get_model(inIter));
+       modelPriv=model->priv;
 
        /* Check if root section is requested */
-       if(!requestedSection) requestedSection=priv->rootMenu;
+       if(!requestedSection) requestedSection=modelPriv->rootMenu;
 
        /* Get menu element at iterator */
-       clutter_model_iter_get(inIter,
-                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SECTION, &section,
-                                                       -1);
+       
item=(XfdashboardApplicationsMenuModelItem*)xfdashboard_model_iter_get(inIter);
 
        /* If menu element is a menu check if root menu is parent menu and root 
menu is requested */
-       if((section && section==requestedSection) ||
-               (!section && requestedSection==priv->rootMenu))
+       if((item->section && item->section==requestedSection) ||
+               (!item->section && requestedSection==modelPriv->rootMenu))
        {
                doShow=TRUE;
        }
 
-       /* Release allocated resources */
-       if(section) g_object_unref(section);
-
        /* If we get here return TRUE to show model data item or FALSE to hide 
*/
        return(doShow);
 }
 
-static gboolean _xfdashboard_applications_menu_model_filter_empty(ClutterModel 
*inModel,
-                                                                               
                                                        ClutterModelIter 
*inIter,
+static gboolean 
_xfdashboard_applications_menu_model_filter_empty(XfdashboardModelIter *inIter,
                                                                                
                                                        gpointer inUserData)
 {
-       g_return_val_if_fail(XFDASHBOARD_IS_APPLICATIONS_MENU_MODEL(inModel), 
FALSE);
-       g_return_val_if_fail(CLUTTER_IS_MODEL_ITER(inIter), FALSE);
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL_ITER(inIter), FALSE);
        g_return_val_if_fail(GARCON_IS_MENU(inUserData), FALSE);
 
        /* This functions always returns FALSE because each entry is considered 
empty and hidden */
@@ -391,6 +395,7 @@ static void 
_xfdashboard_applications_menu_model_fill_model_collect_menu(Xfdashb
        GarconMenu                                                              
                *menu;
        GarconMenu                                                              
                *section;
        GList                                                                   
                *elements, *element;
+       XfdashboardApplicationsMenuModelItem                    *item;
 
        g_return_if_fail(XFDASHBOARD_IS_APPLICATIONS_MENU_MODEL(self));
        g_return_if_fail(GARCON_IS_MENU(inMenu));
@@ -431,14 +436,16 @@ static void 
_xfdashboard_applications_menu_model_fill_model_collect_menu(Xfdashb
                         * and no similar menu
                         */
                        inFillData->sequenceID++;
-                       clutter_model_append(CLUTTER_MODEL(self),
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SEQUENCE_ID, inFillData->sequenceID,
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_MENU_ELEMENT, inMenu,
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_PARENT_MENU, inParentMenu,
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SECTION, section,
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_TITLE, title,
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_DESCRIPTION, description,
-                                                                       -1);
+
+                       item=_xfdashboard_applications_menu_model_item_new();
+                       item->sequenceID=inFillData->sequenceID;
+                       if(inMenu) item->menuElement=g_object_ref(inMenu);
+                       if(inParentMenu) 
item->parentMenu=g_object_ref(inParentMenu);
+                       if(section) item->section=g_object_ref(section);
+                       if(title) item->title=g_strdup(title);
+                       if(description) item->description=g_strdup(description);
+
+                       xfdashboard_model_append(XFDASHBOARD_MODEL(self), item, 
NULL);
 
                        /* Add menu to list of populated ones */
                        
inFillData->populatedMenus=g_slist_prepend(inFillData->populatedMenus, inMenu);
@@ -496,14 +503,16 @@ static void 
_xfdashboard_applications_menu_model_fill_model_collect_menu(Xfdashb
 
                        /* Add menu item to model */
                        inFillData->sequenceID++;
-                       clutter_model_append(CLUTTER_MODEL(self),
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SEQUENCE_ID, inFillData->sequenceID,
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_MENU_ELEMENT, menuElement,
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_PARENT_MENU, menu,
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SECTION, section,
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_TITLE, title,
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_DESCRIPTION, description,
-                                                                       -1);
+
+                       item=_xfdashboard_applications_menu_model_item_new();
+                       item->sequenceID=inFillData->sequenceID;
+                       if(menuElement) 
item->menuElement=g_object_ref(menuElement);
+                       if(menu) item->parentMenu=g_object_ref(menu);
+                       if(section) item->section=g_object_ref(section);
+                       if(title) item->title=g_strdup(title);
+                       if(description) item->description=g_strdup(description);
+
+                       xfdashboard_model_append(XFDASHBOARD_MODEL(self), item, 
NULL);
 
                        /* Release allocated resources */
                        g_free(title);
@@ -559,174 +568,6 @@ static gboolean 
_xfdashboard_applications_menu_model_init_idle(gpointer inUserDa
 }
 
 
-/* IMPLEMENTATION: ClutterModel */
-
-/* Resort model */
-static gint 
_xfdashboard_applications_menu_model_resort_menu_element_callback(ClutterModel 
*inModel,
-                                                                               
                                                                                
const GValue *inLeft,
-                                                                               
                                                                                
const GValue *inRight,
-                                                                               
                                                                                
gpointer inUserData)
-{
-       GarconMenuElement               
*leftValue=GARCON_MENU_ELEMENT(g_value_get_object(inLeft));
-       GarconMenuElement               
*rightValue=GARCON_MENU_ELEMENT(g_value_get_object(inRight));
-       const gchar                             
*leftName=garcon_menu_element_get_name(leftValue);
-       const gchar                             
*rightName=garcon_menu_element_get_name(rightValue);
-
-       return(g_strcmp0(leftName, rightName));
-}
-
-static gint 
_xfdashboard_applications_menu_model_resort_parent_menu_callback(ClutterModel 
*inModel,
-                                                                               
                                                                                
const GValue *inLeft,
-                                                                               
                                                                                
const GValue *inRight,
-                                                                               
                                                                                
gpointer inUserData)
-{
-       GarconMenu                              
*leftValue=GARCON_MENU(g_value_get_object(inLeft));
-       GarconMenu                              
*rightValue=GARCON_MENU(g_value_get_object(inRight));
-       gint                                    result=0;
-
-       /* If both menus have the same parent menu sort them by name ... */
-       
if(garcon_menu_get_parent(leftValue)==garcon_menu_get_parent(rightValue))
-       {
-               const gchar                     
*leftName=garcon_menu_element_get_name(GARCON_MENU_ELEMENT(leftValue));
-               const gchar                     
*rightName=garcon_menu_element_get_name(GARCON_MENU_ELEMENT(rightValue));
-
-               result=g_strcmp0(leftName, rightName);
-       }
-               /* ... otherwise get depth of each value and compare name of 
upper menu */
-               else
-               {
-                       GList                   *leftPath=NULL;
-                       GList                   *rightPath=NULL;
-                       GarconMenu              *leftMenu=leftValue;
-                       GarconMenu              *rightMenu=rightValue;
-                       const gchar             *leftName;
-                       const gchar             *rightName;
-                       gint                    upperLevel;
-
-                       /* Build path of left value */
-                       while(leftMenu)
-                       {
-                               leftPath=g_list_prepend(leftPath, leftMenu);
-                               leftMenu=garcon_menu_get_parent(leftMenu);
-                       }
-
-                       /* Build path of right value */
-                       while(rightMenu)
-                       {
-                               rightPath=g_list_prepend(rightPath, rightMenu);
-                               rightMenu=garcon_menu_get_parent(rightMenu);
-                       }
-
-                       /* Find level of upper path of both values */
-                       upperLevel=MIN(g_list_length(leftPath), 
g_list_length(rightPath));
-                       if(upperLevel>0) upperLevel--;
-
-                       /* Get name of both values at upper path */
-                       
leftName=garcon_menu_element_get_name(GARCON_MENU_ELEMENT(g_list_nth_data(leftPath,
 upperLevel)));
-                       
rightName=garcon_menu_element_get_name(GARCON_MENU_ELEMENT(g_list_nth_data(rightPath,
 upperLevel)));
-
-                       /* Compare name of both value at upper path */
-                       result=g_strcmp0(leftName, rightName);
-               }
-
-       /* Return result */
-       return(result);
-}
-
-static gint 
_xfdashboard_applications_menu_model_resort_section_callback(ClutterModel 
*inModel,
-                                                                               
                                                                                
const GValue *inLeft,
-                                                                               
                                                                                
const GValue *inRight,
-                                                                               
                                                                                
gpointer inUserData)
-{
-       GObject                                 
*leftValue=g_value_get_object(inLeft);
-       GObject                                 
*rightValue=g_value_get_object(inLeft);
-       const gchar                             *leftName=NULL;
-       const gchar                             *rightName=NULL;
-
-       if(leftValue &&
-               GARCON_IS_MENU_ELEMENT(leftValue))
-       {
-               
leftName=garcon_menu_element_get_name(GARCON_MENU_ELEMENT(leftValue));
-       }
-
-       if(rightValue &&
-               GARCON_IS_MENU_ELEMENT(rightValue))
-       {
-               
rightName=garcon_menu_element_get_name(GARCON_MENU_ELEMENT(rightValue));
-       }
-
-       return(g_strcmp0(leftName, rightName));
-}
-
-static gint 
_xfdashboard_applications_menu_model_resort_string_callback(ClutterModel 
*inModel,
-                                                                               
                                                                const GValue 
*inLeft,
-                                                                               
                                                                const GValue 
*inRight,
-                                                                               
                                                                gpointer 
inUserData)
-{
-       const gchar             *leftValue=g_value_get_string(inLeft);
-       const gchar             *rightValue=g_value_get_string(inRight);
-
-       return(g_strcmp0(leftValue, rightValue));
-}
-
-static gint 
_xfdashboard_applications_menu_model_resort_uint_callback(ClutterModel *inModel,
-                                                                               
                                                                const GValue 
*inLeft,
-                                                                               
                                                                const GValue 
*inRight,
-                                                                               
                                                                gpointer 
inUserData)
-{
-       guint           leftValue=g_value_get_uint(inLeft);
-       guint           rightValue=g_value_get_uint(inRight);
-
-       if(leftValue<rightValue) return(-1);
-               else if(leftValue>rightValue) return(1);
-       return(0);
-}
-
-static void _xfdashboard_applications_menu_model_resort(ClutterModel *inModel,
-                                                                               
                                ClutterModelSortFunc inSortCallback,
-                                                                               
                                gpointer inUserData)
-{
-       g_return_if_fail(XFDASHBOARD_IS_APPLICATIONS_MENU_MODEL(inModel));
-
-       /* If given sort function is NULL use default one */
-       if(inSortCallback==NULL)
-       {
-               gint    sortColumn=clutter_model_get_sorting_column(inModel);
-
-               switch(sortColumn)
-               {
-                       case 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SEQUENCE_ID:
-                               
inSortCallback=_xfdashboard_applications_menu_model_resort_uint_callback;
-                               break;
-
-                       case 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_MENU_ELEMENT:
-                               
inSortCallback=_xfdashboard_applications_menu_model_resort_menu_element_callback;
-                               break;
-
-                       case 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_PARENT_MENU:
-                               
inSortCallback=_xfdashboard_applications_menu_model_resort_parent_menu_callback;
-                               break;
-
-                       case XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SECTION:
-                               
inSortCallback=_xfdashboard_applications_menu_model_resort_section_callback;
-                               break;
-
-                       case XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_TITLE:
-                       case 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_DESCRIPTION:
-                               
inSortCallback=_xfdashboard_applications_menu_model_resort_string_callback;
-                               break;
-
-                       default:
-                               g_critical(_("Sorting column %d without 
user-defined function is not possible"), sortColumn);
-                               g_assert_not_reached();
-                               break;
-               }
-       }
-
-       /* Call parent's class resort method */
-       
CLUTTER_MODEL_CLASS(xfdashboard_applications_menu_model_parent_class)->resort(inModel,
 inSortCallback, inUserData);
-}
-
 /* IMPLEMENTATION: GObject */
 
 /* Dispose this object */
@@ -764,12 +605,8 @@ static void 
_xfdashboard_applications_menu_model_dispose(GObject *inObject)
  */
 static void 
xfdashboard_applications_menu_model_class_init(XfdashboardApplicationsMenuModelClass
 *klass)
 {
-       ClutterModelClass               *modelClass=CLUTTER_MODEL_CLASS(klass);
        GObjectClass                    *gobjectClass=G_OBJECT_CLASS(klass);
 
-       /* Override functions */
-       modelClass->resort=_xfdashboard_applications_menu_model_resort;
-
        gobjectClass->dispose=_xfdashboard_applications_menu_model_dispose;
 
        /* Set up private structure */
@@ -794,22 +631,6 @@ static void 
xfdashboard_applications_menu_model_class_init(XfdashboardApplicatio
 static void 
xfdashboard_applications_menu_model_init(XfdashboardApplicationsMenuModel *self)
 {
        XfdashboardApplicationsMenuModelPrivate *priv;
-       GType                                                                   
columnTypes[]=  {
-                                                                               
                                                G_TYPE_UINT, /* 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SEQUENCE_ID */
-                                                                               
                                                GARCON_TYPE_MENU_ELEMENT, /* 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_MENU_ELEMENT */
-                                                                               
                                                GARCON_TYPE_MENU, /* 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_PARENT_MENU */
-                                                                               
                                                GARCON_TYPE_MENU, /* 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SECTION */
-                                                                               
                                                G_TYPE_STRING, /* 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_TITLE */
-                                                                               
                                                G_TYPE_STRING /* 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_DESCRIPTION */
-                                                                               
                                        };
-       const gchar*                                                    
columnNames[]=  {
-                                                                               
                                                _("ID"), /* 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SEQUENCE_ID */
-                                                                               
                                                _("Menu item"), /* 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_MENU_ELEMENT */
-                                                                               
                                                _("Parent menu"), /* 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_PARENT_MENU */
-                                                                               
                                                _("Section"), /* 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SECTION */
-                                                                               
                                                _("Title"), /* 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_TITLE */
-                                                                               
                                                _("Description"), /* 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_DESCRIPTION */
-                                                                               
                                        };
 
        priv=self->priv=XFDASHBOARD_APPLICATIONS_MENU_MODEL_GET_PRIVATE(self);
 
@@ -818,10 +639,6 @@ static void 
xfdashboard_applications_menu_model_init(XfdashboardApplicationsMenu
        priv->appDB=NULL;
        priv->reloadRequiredSignalID=0;
 
-       /* Set up model */
-       clutter_model_set_types(CLUTTER_MODEL(self), 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_LAST, columnTypes);
-       clutter_model_set_names(CLUTTER_MODEL(self), 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_LAST, columnNames);
-
        /* Get application database and connect signals */
        priv->appDB=xfdashboard_application_database_get_default();
        priv->reloadRequiredSignalID=g_signal_connect_swapped(priv->appDB,
@@ -832,15 +649,124 @@ static void 
xfdashboard_applications_menu_model_init(XfdashboardApplicationsMenu
        
clutter_threads_add_idle(_xfdashboard_applications_menu_model_init_idle, self);
 }
 
+
 /* IMPLEMENTATION: Public API */
 
-ClutterModel* xfdashboard_applications_menu_model_new(void)
+/* Create a new instance of application menu model */
+XfdashboardModel* xfdashboard_applications_menu_model_new(void)
+{
+       GObject         *model;
+
+       /* Create instance */
+       model=g_object_new(XFDASHBOARD_TYPE_APPLICATIONS_MENU_MODEL,
+                                               "free-data-callback", 
_xfdashboard_applications_menu_model_item_free,
+                                               NULL);
+       if(!model) return(NULL);
+
+       /* Return new instance */
+       return(XFDASHBOARD_MODEL(model));
+}
+
+/* Get values from application menu model at requested iterator and columns */
+void xfdashboard_applications_menu_model_get(XfdashboardApplicationsMenuModel 
*self,
+                                                                               
                XfdashboardModelIter *inIter,
+                                                                               
                ...)
 {
-       
return(CLUTTER_MODEL(g_object_new(XFDASHBOARD_TYPE_APPLICATIONS_MENU_MODEL, 
NULL)));
+       XfdashboardModel                                                        
*model;
+       XfdashboardApplicationsMenuModelItem            *item;
+       va_list                                                                 
        args;
+       gint                                                                    
        column;
+       gpointer                                                                
        *storage;
+
+       g_return_if_fail(XFDASHBOARD_IS_APPLICATIONS_MENU_MODEL(self));
+       g_return_if_fail(XFDASHBOARD_IS_MODEL_ITER(inIter));
+
+       /* Check if iterator belongs to this model */
+       model=xfdashboard_model_iter_get_model(inIter);
+       if(!XFDASHBOARD_IS_APPLICATIONS_MENU_MODEL(model) ||
+               XFDASHBOARD_APPLICATIONS_MENU_MODEL(model)!=self)
+       {
+               g_critical(_("Iterator does not belong to application menu 
model."));
+               return;
+       }
+
+       /* Get item from iterator */
+       
item=(XfdashboardApplicationsMenuModelItem*)xfdashboard_model_iter_get(inIter);
+       g_assert(item);
+
+       /* Iterate through column index and pointer where to store value until
+        * until end of list (marked with -1) is reached.
+        */
+       va_start(args, inIter);
+
+       column=va_arg(args, gint);
+       while(column!=-1)
+       {
+               if(column<0 || 
column>=XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_LAST)
+               {
+                       g_warning(_("Invalid column number %d added to iter 
(remember to end your list of columns with a -1)"),
+                                               column);
+                       break;
+               }
+
+               /* Get generic pointer to storage as it will be casted as 
necessary
+                * when determining which column is requested.
+                */
+               storage=va_arg(args, gpointer*);
+               if(!storage)
+               {
+                       g_warning(_("No storage pointer provided to store value 
of column number %d"),
+                                               column);
+                       break;
+               }
+
+               /* Check which column is requested and store value at pointer */
+               switch(column)
+               {
+                       case 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SEQUENCE_ID:
+                               *((gint*)storage)=item->sequenceID;
+                               break;
+
+                       case 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_MENU_ELEMENT:
+                               if(item->menuElement) 
*storage=g_object_ref(item->menuElement);
+                                       else *storage=NULL;
+                               break;
+
+                       case 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_PARENT_MENU:
+                               if(item->parentMenu) 
*storage=g_object_ref(item->parentMenu);
+                                       else *storage=NULL;
+                               break;
+
+                       case XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_SECTION:
+                               if(item->section) 
*storage=g_object_ref(item->section);
+                                       else *storage=NULL;
+                               break;
+
+                       case XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_TITLE:
+                               if(item->title) 
*((gchar**)storage)=g_strdup(item->title);
+                                       else *((gchar**)storage)=g_strdup("");
+                               break;
+
+                       case 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_DESCRIPTION:
+                               if(item->description) 
*((gchar**)storage)=g_strdup(item->description);
+                                       else *((gchar**)storage)=g_strdup("");
+                               break;
+
+                       default:
+                               g_assert_not_reached();
+                               break;
+               }
+
+               /* Continue with next column and storage pointer */
+               column=va_arg(args, gint);
+       }
+
+       va_end(args);
 }
 
 /* Filter menu items being a direct child item of requested menu */
-void 
xfdashboard_applications_menu_model_filter_by_menu(XfdashboardApplicationsMenuModel
 *self, GarconMenu *inMenu)
+void 
xfdashboard_applications_menu_model_filter_by_menu(XfdashboardApplicationsMenuModel
 *self,
+                                                                               
                                GarconMenu *inMenu)
 {
        XfdashboardApplicationsMenuModelPrivate         *priv;
 
@@ -853,11 +779,15 @@ void 
xfdashboard_applications_menu_model_filter_by_menu(XfdashboardApplicationsM
        if(inMenu==NULL) inMenu=priv->rootMenu;
 
        /* Filter model data */
-       clutter_model_set_filter(CLUTTER_MODEL(self), 
_xfdashboard_applications_menu_model_filter_by_menu, g_object_ref(inMenu), 
g_object_unref);
+       xfdashboard_model_set_filter(XFDASHBOARD_MODEL(self),
+                                                                       
_xfdashboard_applications_menu_model_filter_by_menu,
+                                                                       
g_object_ref(inMenu),
+                                                                       
g_object_unref);
 }
 
 /* Filter menu items being an indirect child item of requested section */
-void 
xfdashboard_applications_menu_model_filter_by_section(XfdashboardApplicationsMenuModel
 *self, GarconMenu *inSection)
+void 
xfdashboard_applications_menu_model_filter_by_section(XfdashboardApplicationsMenuModel
 *self,
+                                                                               
                                        GarconMenu *inSection)
 {
        XfdashboardApplicationsMenuModelPrivate         *priv;
 
@@ -872,11 +802,18 @@ void 
xfdashboard_applications_menu_model_filter_by_section(XfdashboardApplicatio
        /* Filter model data */
        if(inSection)
        {
-               clutter_model_set_filter(CLUTTER_MODEL(self), 
_xfdashboard_applications_menu_model_filter_by_section, 
g_object_ref(inSection), (GDestroyNotify)g_object_unref);
+               g_debug("Filtering section '%s'", 
garcon_menu_element_get_name(GARCON_MENU_ELEMENT(inSection)));
+               xfdashboard_model_set_filter(XFDASHBOARD_MODEL(self),
+                                                                               
_xfdashboard_applications_menu_model_filter_by_section,
+                                                                               
g_object_ref(inSection),
+                                                                               
g_object_unref);
        }
                else
                {
-                       g_debug("Filtering empty (root) section");
-                       clutter_model_set_filter(CLUTTER_MODEL(self), 
_xfdashboard_applications_menu_model_filter_empty, NULL, NULL);
+                       g_debug("Filtering root section because no section 
requested");
+                       xfdashboard_model_set_filter(XFDASHBOARD_MODEL(self),
+                                                                               
        _xfdashboard_applications_menu_model_filter_empty,
+                                                                               
        NULL,
+                                                                               
        NULL);
                }
 }
diff --git a/libxfdashboard/applications-menu-model.h 
b/libxfdashboard/applications-menu-model.h
index b517cc6..f3fbdb0 100644
--- a/libxfdashboard/applications-menu-model.h
+++ b/libxfdashboard/applications-menu-model.h
@@ -29,9 +29,10 @@
 #error "Only <libxfdashboard/libxfdashboard.h> can be included directly."
 #endif
 
-#include <clutter/clutter.h>
 #include <garcon/garcon.h>
 
+#include <libxfdashboard/model.h>
+
 G_BEGIN_DECLS
 
 #define XFDASHBOARD_TYPE_APPLICATIONS_MENU_MODEL                       
(xfdashboard_applications_menu_model_get_type())
@@ -48,7 +49,7 @@ typedef struct _XfdashboardApplicationsMenuModelClass         
XfdashboardApplicationsMe
 struct _XfdashboardApplicationsMenuModel
 {
        /* Parent instance */
-       ClutterListModel                                                        
parent_instance;
+       XfdashboardModel                                                        
parent_instance;
 
        /* Private structure */
        XfdashboardApplicationsMenuModelPrivate         *priv;
@@ -58,7 +59,7 @@ struct _XfdashboardApplicationsMenuModelClass
 {
        /*< private >*/
        /* Parent class */
-       ClutterListModelClass                                           
parent_class;
+       XfdashboardModelClass                                           
parent_class;
 
        /*< public >*/
        /* Virtual functions */
@@ -84,10 +85,16 @@ enum
 
 GType xfdashboard_applications_menu_model_get_type(void) G_GNUC_CONST;
 
-ClutterModel* xfdashboard_applications_menu_model_new(void);
+XfdashboardModel* xfdashboard_applications_menu_model_new(void);
+
+void xfdashboard_applications_menu_model_get(XfdashboardApplicationsMenuModel 
*self,
+                                                                               
                XfdashboardModelIter *inIter,
+                                                                               
                ...);
 
-void 
xfdashboard_applications_menu_model_filter_by_menu(XfdashboardApplicationsMenuModel
 *self, GarconMenu *inMenu);
-void 
xfdashboard_applications_menu_model_filter_by_section(XfdashboardApplicationsMenuModel
 *self, GarconMenu *inSection);
+void 
xfdashboard_applications_menu_model_filter_by_menu(XfdashboardApplicationsMenuModel
 *self,
+                                                                               
                                GarconMenu *inMenu);
+void 
xfdashboard_applications_menu_model_filter_by_section(XfdashboardApplicationsMenuModel
 *self,
+                                                                               
                                        GarconMenu *inSection);
 
 G_END_DECLS
 
diff --git a/libxfdashboard/applications-view.c 
b/libxfdashboard/applications-view.c
index 4c2233d..8ddb76f 100644
--- a/libxfdashboard/applications-view.c
+++ b/libxfdashboard/applications-view.c
@@ -471,7 +471,7 @@ static void 
_xfdashboard_applications_view_on_all_applications_menu_clicked(Xfda
 static void 
_xfdashboard_applications_view_on_filter_changed(XfdashboardApplicationsView 
*self, gpointer inUserData)
 {
        XfdashboardApplicationsViewPrivate      *priv;
-       ClutterModelIter                                        *iterator;
+       XfdashboardModelIter                            *iterator;
        ClutterActor                                            *actor;
        GarconMenuElement                                       
*menuElement=NULL;
        GarconMenu                                                      
*parentMenu=NULL;
@@ -552,15 +552,19 @@ static void 
_xfdashboard_applications_view_on_filter_changed(XfdashboardApplicat
        }
 
        /* Iterate through (filtered) data model and create actor for each 
entry */
-       iterator=clutter_model_get_first_iter(CLUTTER_MODEL(priv->apps));
-       if(iterator && CLUTTER_IS_MODEL_ITER(iterator))
+       iterator=xfdashboard_model_iter_new(XFDASHBOARD_MODEL(priv->apps));
+       if(iterator)
        {
-               while(!clutter_model_iter_is_last(iterator))
+               while(xfdashboard_model_iter_next(iterator))
                {
+                       /* If row is filtered continue with next one 
immediately */
+                       if(!xfdashboard_model_iter_filter(iterator)) continue;
+
                        /* Get data from model */
-                       clutter_model_iter_get(iterator,
-                                                                       
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_MENU_ELEMENT, &menuElement,
-                                                                       -1);
+                       xfdashboard_applications_menu_model_get(priv->apps,
+                                                                               
                        iterator,
+                                                                               
                        
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_MENU_ELEMENT, &menuElement,
+                                                                               
                        -1);
 
                        if(!menuElement) continue;
 
@@ -579,22 +583,27 @@ static void 
_xfdashboard_applications_view_on_filter_changed(XfdashboardApplicat
                                {
                                        gchar           *actorText;
                                        const gchar     *iconName;
+                                       const gchar     *title;
+                                       const gchar     *description;
 
                                        actor=xfdashboard_button_new();
 
                                        
iconName=garcon_menu_element_get_icon_name(menuElement);
                                        if(iconName) 
xfdashboard_button_set_icon_name(XFDASHBOARD_BUTTON(actor), iconName);
 
+                                       
title=garcon_menu_element_get_name(menuElement);
+                                       
description=garcon_menu_element_get_comment(menuElement);
+
                                        
if(priv->viewMode==XFDASHBOARD_VIEW_MODE_LIST)
                                        {
                                                
actorText=g_markup_printf_escaped(priv->formatTitleDescription,
-                                                                               
                                        
garcon_menu_element_get_name(menuElement),
-                                                                               
                                        
garcon_menu_element_get_comment(menuElement));
+                                                                               
                                        title ? title : "",
+                                                                               
                                        description ? description : "");
                                        }
                                                else
                                                {
                                                        
actorText=g_markup_printf_escaped(priv->formatTitleOnly,
-                                                                               
                                                
garcon_menu_element_get_name(menuElement));
+                                                                               
                                                title ? title : "");
                                                }
                                        
xfdashboard_button_set_text(XFDASHBOARD_BUTTON(actor), actorText);
                                        g_free(actorText);
@@ -628,9 +637,6 @@ static void 
_xfdashboard_applications_view_on_filter_changed(XfdashboardApplicat
                        /* Release allocated resources */
                        g_object_unref(menuElement);
                        menuElement=NULL;
-
-                       /* Go to next entry in model */
-                       iterator=clutter_model_iter_next(iterator);
                }
                g_object_unref(iterator);
        }
@@ -1406,7 +1412,6 @@ static void 
xfdashboard_applications_view_init(XfdashboardApplicationsView *self
 
        xfdashboard_view_set_view_fit_mode(XFDASHBOARD_VIEW(self), 
XFDASHBOARD_VIEW_FIT_MODE_HORIZONTAL);
        xfdashboard_applications_view_set_view_mode(self, 
XFDASHBOARD_VIEW_MODE_LIST);
-       clutter_model_set_sorting_column(CLUTTER_MODEL(priv->apps), 
XFDASHBOARD_APPLICATIONS_MENU_MODEL_COLUMN_TITLE);
 
        /* Connect signals */
        g_signal_connect_swapped(priv->apps, "filter-changed", 
G_CALLBACK(_xfdashboard_applications_view_on_filter_changed), self);
diff --git a/libxfdashboard/model.c b/libxfdashboard/model.c
new file mode 100644
index 0000000..7aaf801
--- /dev/null
+++ b/libxfdashboard/model.c
@@ -0,0 +1,1306 @@
+/*
+ * model: A simple and generic data model holding one value per row
+ * 
+ * Copyright 2012-2016 Stephan Haller <[email protected]>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program 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 General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <libxfdashboard/model.h>
+
+#include <glib/gi18n-lib.h>
+
+
+/* Define theses classes in GObject system */
+G_DEFINE_TYPE(XfdashboardModel,
+                               xfdashboard_model,
+                               G_TYPE_OBJECT);
+
+G_DEFINE_TYPE(XfdashboardModelIter,
+                               xfdashboard_model_iter,
+                               G_TYPE_OBJECT);
+
+/* Private structure - access only by public API if needed */
+#define XFDASHBOARD_MODEL_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE((obj), XFDASHBOARD_TYPE_MODEL, 
XfdashboardModelPrivate))
+
+struct _XfdashboardModelPrivate
+{
+       /* Instance related */
+       GSequence                                       *data;
+       GDestroyNotify                          freeDataCallback;
+
+       XfdashboardModelSortFunc        sortCallback;
+       gpointer                                        sortUserData;
+       GDestroyNotify                          sortUserDataDestroyCallback;
+
+       XfdashboardModelFilterFunc      filterCallback;
+       gpointer                                        filterUserData;
+       GDestroyNotify                          filterUserDataDestroyCallback;
+};
+
+#define XFDASHBOARD_MODEL_ITER_GET_PRIVATE(obj) \
+       (G_TYPE_INSTANCE_GET_PRIVATE((obj), XFDASHBOARD_TYPE_MODEL_ITER, 
XfdashboardModelIterPrivate))
+
+struct _XfdashboardModelIterPrivate
+{
+       /* Instance related */
+       XfdashboardModel                        *model;
+       GSequenceIter                           *iter;
+};
+
+/* Properties */
+enum
+{
+       PROP_0,
+
+       PROP_ROWS,
+       PROP_SORT_SET,
+       PROP_FILTER_SET,
+       PROP_FREE_DATA_CALLBACK,
+
+       PROP_LAST
+};
+
+static GParamSpec* XfdashboardModelProperties[PROP_LAST]={ 0, };
+
+/* Signals */
+enum
+{
+       SIGNAL_ROW_ADDED,
+       SIGNAL_ROW_REMOVED,
+       SIGNAL_ROW_CHANGED,
+       SIGNAL_SORT_CHANGED,
+       SIGNAL_FILTER_CHANGED,
+
+       SIGNAL_LAST
+};
+
+static guint XfdashboardModelSignals[SIGNAL_LAST]={ 0, };
+
+
+/* IMPLEMENTATION: Private variables and methods */
+
+typedef struct _XfdashboardModelSortData                       
XfdashboardModelSortData;
+struct _XfdashboardModelSortData
+{
+       XfdashboardModel                        *model;
+       XfdashboardModelIter            *leftIter;
+       XfdashboardModelIter            *rightIter;
+};
+
+/* Checks for valid iterator for model */
+static gboolean _xfdashboard_model_iter_is_valid(XfdashboardModelIter *self, 
gboolean inNeedsIter)
+{
+       XfdashboardModelIterPrivate             *priv;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL_ITER(self), FALSE);
+
+       priv=self->priv;
+
+       /* Check if model is set */
+       if(!priv->model) return(FALSE);
+
+       /* Check if an iterator is set when an iterator is needed */
+       if(inNeedsIter && !priv->iter) return(FALSE);
+
+       /* Check if an iterator is set and if it is then check if associated
+        * GSequence at iterator matches the one associated with the model.
+        * If an iterator is needed the check before ensures that in this check
+        * an iterator exists and the check will be performed.
+        */
+       if(priv->iter)
+       {
+               
if(g_sequence_iter_get_sequence(priv->iter)!=priv->model->priv->data) 
return(FALSE);
+       }
+
+       /* If we get here all tests are passed successfully and iterator is 
valid */
+       return(TRUE);
+}
+
+/* Checks if requested row is valid in this model */
+static gboolean _xfdashboard_model_is_valid_row(XfdashboardModel *self, gint 
inRow)
+{
+       XfdashboardModelPrivate                 *priv;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(self), FALSE);
+
+       priv=self->priv;
+
+       /* Check if row is a positive number and smaller than the total numbers
+        * of rows in model's data.
+        */
+       if(inRow<0 || inRow>=g_sequence_get_length(priv->data)) return(FALSE);
+
+       /* If we get here the requested row is within model's data and valid */
+       return(TRUE);
+}
+
+/* Internal callback function for sorting which creates iterators used for
+ * user supplied callback function.
+ */
+static gint _xfdashboard_model_sort_internal(GSequenceIter *inLeft,
+                                                                               
                GSequenceIter *inRight,
+                                                                               
                gpointer inUserData)
+{
+       XfdashboardModelSortData                *sortData;
+       XfdashboardModelPrivate                 *priv;
+       gint                                                    result;
+
+       g_return_val_if_fail(inLeft, 0);
+       g_return_val_if_fail(inRight, 0);
+       g_return_val_if_fail(inUserData, 0);
+
+       sortData=(XfdashboardModelSortData*)inUserData;
+       priv=sortData->model->priv;
+
+       /* Update iterators to pass to user supplied sort callback function */
+       sortData->leftIter->priv->iter=inLeft;
+       sortData->rightIter->priv->iter=inRight;
+
+       /* Call user supplied sort callback function and return its result */
+       result=(priv->sortCallback)(sortData->leftIter,
+                                                               
sortData->rightIter,
+                                                               
priv->sortUserData);
+
+       /* Return result of user supplied sort callback function */
+       return(result);
+}
+
+/* IMPLEMENTATION: GObject */
+
+/* Dispose this object of type XfdashboardModel */
+static void _xfdashboard_model_dispose(GObject *inObject)
+{
+       XfdashboardModel                                
*self=XFDASHBOARD_MODEL(inObject);
+       XfdashboardModelPrivate                 *priv=self->priv;
+
+       /* Release our allocated variables */
+       if(priv->sortUserData &&
+               priv->sortUserDataDestroyCallback)
+       {
+               (priv->sortUserDataDestroyCallback)(priv->sortUserData);
+       }
+       priv->sortUserDataDestroyCallback=NULL;
+       priv->sortUserData=NULL;
+       priv->sortCallback=NULL;
+
+       if(priv->filterUserData &&
+               priv->filterUserDataDestroyCallback)
+       {
+               (priv->filterUserDataDestroyCallback)(priv->filterUserData);
+       }
+       priv->filterUserDataDestroyCallback=NULL;
+       priv->filterUserData=NULL;
+       priv->filterCallback=NULL;
+
+       if(priv->data)
+       {
+               g_sequence_free(priv->data);
+               priv->data=NULL;
+       }
+       priv->freeDataCallback=NULL;
+
+       /* Call parent's class dispose method */
+       G_OBJECT_CLASS(xfdashboard_model_parent_class)->dispose(inObject);
+}
+
+/* Set/get properties of type XfdashboardModel */
+static void _xfdashboard_model_set_property(GObject *inObject,
+                                                                               
        guint inPropID,
+                                                                               
        const GValue *inValue,
+                                                                               
        GParamSpec *inSpec)
+{
+       XfdashboardModel                                
*self=XFDASHBOARD_MODEL(inObject);
+
+       switch(inPropID)
+       {
+               case PROP_FREE_DATA_CALLBACK:
+                       
self->priv->freeDataCallback=g_value_get_pointer(inValue);
+                       break;
+
+               default:
+                       G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, 
inSpec);
+                       break;
+       }
+}
+
+static void _xfdashboard_model_get_property(GObject *inObject,
+                                                                               
        guint inPropID,
+                                                                               
        GValue *outValue,
+                                                                               
        GParamSpec *inSpec)
+{
+       XfdashboardModel                                
*self=XFDASHBOARD_MODEL(inObject);
+
+       switch(inPropID)
+       {
+               case PROP_ROWS:
+                       g_value_set_int(outValue, 
xfdashboard_model_get_rows_count(self));
+                       break;
+
+               case PROP_SORT_SET:
+                       g_value_set_boolean(outValue, 
xfdashboard_model_is_sorted(self));
+                       break;
+
+               case PROP_FILTER_SET:
+                       g_value_set_boolean(outValue, 
xfdashboard_model_is_filtered(self));
+                       break;
+
+               default:
+                       G_OBJECT_WARN_INVALID_PROPERTY_ID(inObject, inPropID, 
inSpec);
+                       break;
+       }
+}
+
+/* Class initialization of type XfdashboardModel
+ * Override functions in parent classes and define properties
+ * and signals
+ */
+static void xfdashboard_model_class_init(XfdashboardModelClass *klass)
+{
+       GObjectClass                    *gobjectClass=G_OBJECT_CLASS(klass);
+
+       /* Override functions */
+       gobjectClass->dispose=_xfdashboard_model_dispose;
+       gobjectClass->set_property=_xfdashboard_model_set_property;
+       gobjectClass->get_property=_xfdashboard_model_get_property;
+
+       /* Set up private structure */
+       g_type_class_add_private(klass, sizeof(XfdashboardModelPrivate));
+
+       /* Define properties */
+       XfdashboardModelProperties[PROP_ROWS]=
+               g_param_spec_int("rows",
+                                                       _("Rows"),
+                                                       _("The number of rows 
this model contains"),
+                                                       0, G_MAXINT,
+                                                       0,
+                                                       G_PARAM_READABLE | 
G_PARAM_STATIC_STRINGS);
+
+       XfdashboardModelProperties[PROP_SORT_SET]=
+               g_param_spec_boolean("sort-set",
+                                                               _("Sort set"),
+                                                               _("Whether a 
sorting function is set or not"),
+                                                               FALSE,
+                                                               
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+       XfdashboardModelProperties[PROP_FILTER_SET]=
+               g_param_spec_boolean("filter-set",
+                                                               _("Filter set"),
+                                                               _("Whether a 
filter is set or not"),
+                                                               FALSE,
+                                                               
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
+
+       XfdashboardModelProperties[PROP_FREE_DATA_CALLBACK]=
+               g_param_spec_pointer("free-data-callback",
+                                                               _("Free data 
callback"),
+                                                               _("Callback 
function to free data when removing or overwriting data in model"),
+                                                               
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+       g_object_class_install_properties(gobjectClass, PROP_LAST, 
XfdashboardModelProperties);
+
+       /* Define signals */
+       XfdashboardModelSignals[SIGNAL_ROW_ADDED]=
+               g_signal_new("row-added",
+                                               G_TYPE_FROM_CLASS(klass),
+                                               G_SIGNAL_RUN_LAST,
+                                               
G_STRUCT_OFFSET(XfdashboardModelClass, row_added),
+                                               NULL,
+                                               NULL,
+                                               g_cclosure_marshal_VOID__OBJECT,
+                                               G_TYPE_NONE,
+                                               1,
+                                               XFDASHBOARD_TYPE_MODEL_ITER);
+
+       XfdashboardModelSignals[SIGNAL_ROW_REMOVED]=
+               g_signal_new("row-removed",
+                                               G_TYPE_FROM_CLASS(klass),
+                                               G_SIGNAL_RUN_LAST,
+                                               
G_STRUCT_OFFSET(XfdashboardModelClass, row_removed),
+                                               NULL,
+                                               NULL,
+                                               g_cclosure_marshal_VOID__OBJECT,
+                                               G_TYPE_NONE,
+                                               1,
+                                               XFDASHBOARD_TYPE_MODEL_ITER);
+
+       XfdashboardModelSignals[SIGNAL_ROW_CHANGED]=
+               g_signal_new("row-changed",
+                                               G_TYPE_FROM_CLASS(klass),
+                                               G_SIGNAL_RUN_LAST,
+                                               
G_STRUCT_OFFSET(XfdashboardModelClass, row_changed),
+                                               NULL,
+                                               NULL,
+                                               g_cclosure_marshal_VOID__OBJECT,
+                                               G_TYPE_NONE,
+                                               1,
+                                               XFDASHBOARD_TYPE_MODEL_ITER);
+
+       XfdashboardModelSignals[SIGNAL_SORT_CHANGED]=
+               g_signal_new("sort-changed",
+                                               G_TYPE_FROM_CLASS(klass),
+                                               G_SIGNAL_RUN_LAST,
+                                               
G_STRUCT_OFFSET(XfdashboardModelClass, sort_changed),
+                                               NULL,
+                                               NULL,
+                                               g_cclosure_marshal_VOID__VOID,
+                                               G_TYPE_NONE,
+                                               0);
+
+       XfdashboardModelSignals[SIGNAL_FILTER_CHANGED]=
+               g_signal_new("filter-changed",
+                                               G_TYPE_FROM_CLASS(klass),
+                                               G_SIGNAL_RUN_LAST,
+                                               
G_STRUCT_OFFSET(XfdashboardModelClass, filter_changed),
+                                               NULL,
+                                               NULL,
+                                               g_cclosure_marshal_VOID__VOID,
+                                               G_TYPE_NONE,
+                                               0);
+}
+
+/* Object initialization of type XfdashboardModel
+ * Create private structure and set up default values
+ */
+static void xfdashboard_model_init(XfdashboardModel *self)
+{
+       XfdashboardModelPrivate                 *priv;
+
+       priv=self->priv=XFDASHBOARD_MODEL_GET_PRIVATE(self);
+
+       /* Set up default values */
+       priv->data=g_sequence_new(NULL);
+       priv->freeDataCallback=NULL;
+
+       priv->sortCallback=NULL;
+       priv->sortUserData=NULL;
+       priv->sortUserDataDestroyCallback=NULL;
+
+       priv->filterCallback=NULL;
+       priv->filterUserData=NULL;
+       priv->filterUserDataDestroyCallback=NULL;
+}
+
+/* Dispose this object of type XfdashboardModelIter */
+static void _xfdashboard_model_iter_dispose(GObject *inObject)
+{
+       XfdashboardModelIter                    
*self=XFDASHBOARD_MODEL_ITER(inObject);
+       XfdashboardModelIterPrivate             *priv=self->priv;
+
+       /* Release our allocated variables */
+       if(priv->model)
+       {
+               g_object_unref(priv->model);
+               priv->model=NULL;
+       }
+
+       priv->iter=NULL;
+
+       /* Call parent's class dispose method */
+       G_OBJECT_CLASS(xfdashboard_model_iter_parent_class)->dispose(inObject);
+}
+
+/* Class initialization of type XfdashboardModelIter
+ * Override functions in parent classes and define properties
+ * and signals
+ */
+static void xfdashboard_model_iter_class_init(XfdashboardModelIterClass *klass)
+{
+       GObjectClass                    *gobjectClass=G_OBJECT_CLASS(klass);
+
+       /* Override functions */
+       gobjectClass->dispose=_xfdashboard_model_iter_dispose;
+
+       /* Set up private structure */
+       g_type_class_add_private(klass, sizeof(XfdashboardModelIterPrivate));
+}
+
+/* Object initialization of type XfdashboardModelIter
+ * Create private structure and set up default values
+ */
+static void xfdashboard_model_iter_init(XfdashboardModelIter *self)
+{
+       XfdashboardModelIterPrivate             *priv;
+
+       priv=self->priv=XFDASHBOARD_MODEL_ITER_GET_PRIVATE(self);
+
+       /* Set up default values */
+       priv->model=NULL;
+       priv->iter=NULL;
+}
+
+
+/* IMPLEMENTATION: Public API of XfdashboardModel */
+
+/* Model creation functions */
+XfdashboardModel* xfdashboard_model_new(void)
+{
+       GObject         *model;
+
+       model=g_object_new(XFDASHBOARD_TYPE_MODEL, NULL);
+       if(!model) return(NULL);
+
+       return(XFDASHBOARD_MODEL(model));
+}
+
+/* Return number of rows in this model */
+gint xfdashboard_model_get_rows_count(XfdashboardModel *self)
+{
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(self), 0);
+
+       return(g_sequence_get_length(self->priv->data));
+}
+
+/* Get item at requested row of this model */
+gpointer xfdashboard_model_get(XfdashboardModel *self, gint inRow)
+{
+       XfdashboardModelPrivate                 *priv;
+       GSequenceIter                                   *iter;
+       gpointer                                                item;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(self), NULL);
+       g_return_val_if_fail(_xfdashboard_model_is_valid_row(self, inRow), 
NULL);
+
+       priv=self->priv;
+       item=NULL;
+
+       /* Get iterator at requested row */
+       iter=g_sequence_get_iter_at_pos(priv->data, inRow);
+       if(iter)
+       {
+               /* Get item from iterator */
+               item=g_sequence_get(iter);
+       }
+
+       /* Return item found */
+       return(item);
+}
+
+/* Add a new item to end of model's data */
+gboolean xfdashboard_model_append(XfdashboardModel *self,
+                                                                       
gpointer inData,
+                                                                       
XfdashboardModelIter **outIter)
+{
+       XfdashboardModelPrivate                 *priv;
+       XfdashboardModelIter                    *iter;
+       GSequenceIter                                   *seqIter;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(self), FALSE);
+       g_return_val_if_fail(outIter==NULL || *outIter==NULL, FALSE);
+
+       priv=self->priv;
+
+       /* Append data to model's data */
+       seqIter=g_sequence_append(priv->data, inData);
+
+       /* Create iterator for returned sequence iterator */
+       iter=xfdashboard_model_iter_new(self);
+       iter->priv->iter=seqIter;
+
+       /* Emit signal */
+       g_signal_emit(self, XfdashboardModelSignals[SIGNAL_ROW_ADDED], 0, iter);
+
+       /* Store iterator if callee requested it */
+       if(outIter) *outIter=XFDASHBOARD_MODEL_ITER(g_object_ref(iter));
+
+       /* Release allocated resources */
+       if(iter) g_object_unref(iter);
+
+       /* Return TRUE for success */
+       return(TRUE);
+}
+
+/* Add a new item to begin of model's data */
+gboolean xfdashboard_model_prepend(XfdashboardModel *self,
+                                                                       
gpointer inData,
+                                                                       
XfdashboardModelIter **outIter)
+{
+       XfdashboardModelPrivate                 *priv;
+       XfdashboardModelIter                    *iter;
+       GSequenceIter                                   *seqIter;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(self), FALSE);
+       g_return_val_if_fail(outIter==NULL || *outIter==NULL, FALSE);
+
+       priv=self->priv;
+
+       /* Append data to model's data */
+       seqIter=g_sequence_prepend(priv->data, inData);
+
+       /* Create iterator for returned sequence iterator */
+       iter=xfdashboard_model_iter_new(self);
+       iter->priv->iter=seqIter;
+
+       /* Emit signal */
+       g_signal_emit(self, XfdashboardModelSignals[SIGNAL_ROW_ADDED], 0, iter);
+
+       /* Store iterator if callee requested it */
+       if(outIter) *outIter=XFDASHBOARD_MODEL_ITER(g_object_ref(iter));
+
+       /* Release allocated resources */
+       if(iter) g_object_unref(iter);
+
+       /* Return TRUE for success */
+       return(TRUE);
+}
+
+/* Add a new item at requested row (i.e. before the item at requested row)
+ * at model's data.
+ */
+gboolean xfdashboard_model_insert(XfdashboardModel *self,
+                                                                       gint 
inRow,
+                                                                       
gpointer inData,
+                                                                       
XfdashboardModelIter **outIter)
+{
+       XfdashboardModelPrivate                 *priv;
+       XfdashboardModelIter                    *iter;
+       GSequenceIter                                   *seqIter;
+       GSequenceIter                                   *insertIter;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(self), FALSE);
+       g_return_val_if_fail(_xfdashboard_model_is_valid_row(self, inRow), 
FALSE);
+       g_return_val_if_fail(outIter==NULL || *outIter==NULL, FALSE);
+
+       priv=self->priv;
+
+       /* Create sequence iterator where to insert new data at */
+       insertIter=g_sequence_get_iter_at_pos(priv->data, inRow);
+
+       /* Insert data at "insert iterator" at model's data */
+       seqIter=g_sequence_insert_before(insertIter, inData);
+
+       /* Create iterator for returned sequence iterator */
+       iter=xfdashboard_model_iter_new(self);
+       iter->priv->iter=seqIter;
+
+       /* Emit signal */
+       g_signal_emit(self, XfdashboardModelSignals[SIGNAL_ROW_ADDED], 0, iter);
+
+       /* Store iterator if callee requested it */
+       if(outIter) *outIter=XFDASHBOARD_MODEL_ITER(g_object_ref(iter));
+
+       /* Release allocated resources */
+       if(iter) g_object_unref(iter);
+
+       /* Return TRUE for success */
+       return(TRUE);
+}
+
+/* Set or replace data at iterator */
+gboolean xfdashboard_model_set(XfdashboardModel *self,
+                                                               gint inRow,
+                                                               gpointer inData,
+                                                               
XfdashboardModelIter **outIter)
+{
+       XfdashboardModelPrivate                 *priv;
+       XfdashboardModelIter                    *iter;
+       GSequenceIter                                   *seqIter;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(self), FALSE);
+       g_return_val_if_fail(_xfdashboard_model_is_valid_row(self, inRow), 
FALSE);
+
+       priv=self->priv;
+
+       /* Create sequence iterator to row which is set */
+       seqIter=g_sequence_get_iter_at_pos(priv->data, inRow);
+
+       /* If a function is provided to free data on removal then call it now */
+       if(priv->freeDataCallback)
+       {
+               gpointer                                        oldData;
+
+               /* Get data to remove */
+               oldData=g_sequence_get(seqIter);
+
+               /* Call function to free data */
+               (priv->freeDataCallback)(oldData);
+       }
+
+       /* Set new data at iterator */
+       g_sequence_set(seqIter, inData);
+
+       /* Create iterator for returned sequence iterator */
+       iter=xfdashboard_model_iter_new(self);
+       iter->priv->iter=seqIter;
+
+       /* Emit signal */
+       g_signal_emit(self, XfdashboardModelSignals[SIGNAL_ROW_CHANGED], 0, 
iter);
+
+       /* Store iterator if callee requested it */
+       if(outIter) *outIter=XFDASHBOARD_MODEL_ITER(g_object_ref(iter));
+
+       /* Release allocated resources */
+       if(iter) g_object_unref(iter);
+
+       /* Return TRUE for success */
+       return(TRUE);
+}
+
+/* Remove data at requested row from model's data */
+gboolean xfdashboard_model_remove(XfdashboardModel *self, gint inRow)
+{
+       XfdashboardModelPrivate                 *priv;
+       XfdashboardModelIter                    *iter;
+       GSequenceIter                                   *seqIter;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(self), FALSE);
+       g_return_val_if_fail(_xfdashboard_model_is_valid_row(self, inRow), 
FALSE);
+
+       priv=self->priv;
+
+       /* Create sequence iterator to row which is to remove */
+       seqIter=g_sequence_get_iter_at_pos(priv->data, inRow);
+
+       /* Create iterator for returned sequence iterator */
+       iter=xfdashboard_model_iter_new(self);
+       iter->priv->iter=seqIter;
+
+       /* Emit signal before removal to give signal handlers a changed
+        * to access the data at iterator a last time.
+        */
+       g_signal_emit(self, XfdashboardModelSignals[SIGNAL_ROW_REMOVED], 0, 
iter);
+
+       /* If a function is provided to free data on removal then call it now */
+       if(priv->freeDataCallback)
+       {
+               gpointer                                        oldData;
+
+               /* Get data to remove */
+               oldData=g_sequence_get(seqIter);
+
+               /* Call function to free data */
+               (priv->freeDataCallback)(oldData);
+       }
+
+       /* Remove data from model's data */
+       g_sequence_remove(seqIter);
+
+       /* Release allocated resources */
+       if(iter) g_object_unref(iter);
+
+       /* Return TRUE for success */
+       return(TRUE);
+}
+
+/* Remove all data from model's data */
+void xfdashboard_model_remove_all(XfdashboardModel *self)
+{
+       XfdashboardModelPrivate                 *priv;
+       XfdashboardModelIter                    *iter;
+
+       g_return_if_fail(XFDASHBOARD_IS_MODEL(self));
+
+       priv=self->priv;
+
+       /* Create iterator used to iterate through all items in model's data
+        * and it is used when emitting signal.
+        */
+       iter=xfdashboard_model_iter_new(self);
+       iter->priv->iter=g_sequence_get_begin_iter(priv->data);
+
+       /* Iterate through all items in model's data, emit signal for each item
+        * being remove and remove them finally. If model provides a function to
+        * free data call it with the item to remove.
+        */
+       while(!g_sequence_iter_is_end(iter->priv->iter))
+       {
+               /* Emit signal before removal to give signal handlers a changed
+                * to access the data at iterator a last time.
+                */
+               g_signal_emit(self, 
XfdashboardModelSignals[SIGNAL_ROW_REMOVED], 0, iter);
+
+               /* If a function is provided to free data on removal then call 
it now */
+               if(priv->freeDataCallback)
+               {
+                       gpointer                                        oldData;
+
+                       /* Get data to remove */
+                       oldData=g_sequence_get(iter->priv->iter);
+
+                       /* Call function to free data */
+                       (priv->freeDataCallback)(oldData);
+               }
+
+               /* Remove data from model's data */
+               g_sequence_remove(iter->priv->iter);
+
+               /* Move iterator to next item in model's data */
+               iter->priv->iter=g_sequence_iter_next(iter->priv->iter);
+       }
+
+       /* Release allocated resources */
+       if(iter) g_object_unref(iter);
+}
+
+/* Iterate through all items in model's data and call user supplied callback
+ * function for each item.
+ */
+void xfdashboard_model_foreach(XfdashboardModel *self,
+                                                               
XfdashboardModelForeachFunc inForeachCallback,
+                                                               gpointer 
inUserData)
+{
+       XfdashboardModelIter                    *iter;
+       gpointer                                                item;
+
+       g_return_if_fail(XFDASHBOARD_IS_MODEL(self));
+       g_return_if_fail(inForeachCallback);
+
+       /* Iterate through all items in model's data */
+       /* Call user supplied callback function */
+       iter=xfdashboard_model_iter_new(self);
+       while(xfdashboard_model_iter_next(iter))
+       {
+               /* Get item at position the iterator points to */
+               item=xfdashboard_model_iter_get(iter);
+
+               /* Call user supplied callback function */
+               (inForeachCallback)(iter, item, inUserData);
+       }
+
+       /* Release allocated resources */
+       if(iter) g_object_unref(iter);
+}
+
+/* Model sort functions */
+gboolean xfdashboard_model_is_sorted(XfdashboardModel *self)
+{
+       XfdashboardModelPrivate                 *priv;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(self), FALSE);
+
+       priv=self->priv;
+
+       /* If a sort function is set then return TRUE ... */
+       if(priv->sortCallback) return(TRUE);
+
+       /* ... otherwise FALSE */
+       return(FALSE);
+}
+
+/* Set sorting function */
+void xfdashboard_model_set_sort(XfdashboardModel *self,
+                                                               
XfdashboardModelSortFunc inSortCallback,
+                                                               gpointer 
inUserData,
+                                                               GDestroyNotify 
inUserDataDestroyCallback)
+{
+       XfdashboardModelPrivate                 *priv;
+
+       g_return_if_fail(XFDASHBOARD_IS_MODEL(self));
+
+       priv=self->priv;
+
+       /* Set value if changed */
+       if(priv->sortCallback!=inSortCallback ||
+               priv->sortUserData!=inUserData ||
+               priv->sortUserDataDestroyCallback!=inUserDataDestroyCallback)
+       {
+               gboolean                                oldSortIsSet;
+               gboolean                                newSortIsSet;
+
+               /* Get old "sort-set" value. It is used later to determine if 
this
+                * property has changed also.
+                */
+               oldSortIsSet=xfdashboard_model_is_sorted(self);
+
+               /* Release old values */
+               if(priv->sortUserData &&
+                       priv->sortUserDataDestroyCallback)
+               {
+                       (priv->sortUserDataDestroyCallback)(priv->sortUserData);
+               }
+               priv->sortUserDataDestroyCallback=NULL;
+               priv->sortUserData=NULL;
+               priv->sortCallback=NULL;
+
+               /* Set value */
+               priv->sortCallback=inSortCallback;
+               priv->sortUserData=inUserData;
+               priv->sortUserDataDestroyCallback=inUserDataDestroyCallback;
+
+               /* Get new "sort-set" value to determine if this property has
+                * changed also.
+                */
+               newSortIsSet=xfdashboard_model_is_sorted(self);
+
+               /* Sort model if sort function is set */
+               if(newSortIsSet) xfdashboard_model_resort(self);
+
+               /* Notify about change of 'sort-set' if changed and after model
+                * was sorted.
+                */
+               if(oldSortIsSet!=newSortIsSet)
+               {
+                       g_object_notify_by_pspec(G_OBJECT(self), 
XfdashboardModelProperties[PROP_SORT_SET]);
+               }
+
+               /* Emit signal that sorting has changed */
+               g_signal_emit(self, 
XfdashboardModelSignals[SIGNAL_SORT_CHANGED], 0);
+       }
+}
+
+/* Resort this model's data with sorting function set */
+void xfdashboard_model_resort(XfdashboardModel *self)
+{
+       XfdashboardModelPrivate                 *priv;
+       XfdashboardModelSortData                sortData;
+
+       g_return_if_fail(XFDASHBOARD_IS_MODEL(self));
+
+       priv=self->priv;
+
+       /* If no sort function is set return immediately because this model
+        * cannot be sorted without a sort function.
+        */
+       if(!priv->sortCallback) return;
+
+       /* Set up sort data which wraps all needed information into a structure.
+        * The interators are pre-initialized and updated in internal sort 
function
+        * which is passed to GSequence's sort function. This internal callback
+        * only updates the existing iterators to reduce creation and 
destructions
+        * of these iterator. This can be done because the model does not change
+        * while sorting.
+        */
+       sortData.model=XFDASHBOARD_MODEL(g_object_ref(self));
+       sortData.leftIter=xfdashboard_model_iter_new(self);
+       sortData.rightIter=xfdashboard_model_iter_new(self);
+
+       /* Sort this model again by using internal sorting function which
+        * calls user's sort function with adjusted parameters.
+        */
+       g_sequence_sort_iter(priv->data, _xfdashboard_model_sort_internal, 
&sortData);
+
+       /* Release allocated resources */
+       if(sortData.model) g_object_unref(sortData.model);
+       if(sortData.leftIter) g_object_unref(sortData.leftIter);
+       if(sortData.rightIter) g_object_unref(sortData.rightIter);
+}
+
+/* Model filter functions */
+gboolean xfdashboard_model_is_filtered(XfdashboardModel *self)
+{
+       XfdashboardModelPrivate                 *priv;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(self), FALSE);
+
+       priv=self->priv;
+
+       /* If a filter function is set then return TRUE ... */
+       if(priv->filterCallback) return(TRUE);
+
+       /* ... otherwise FALSE */
+       return(FALSE);
+}
+
+/* Set filter function */
+void xfdashboard_model_set_filter(XfdashboardModel *self,
+                                                                       
XfdashboardModelFilterFunc inFilterCallback,
+                                                                       
gpointer inUserData,
+                                                                       
GDestroyNotify inUserDataDestroyCallback)
+{
+       XfdashboardModelPrivate                 *priv;
+
+       g_return_if_fail(XFDASHBOARD_IS_MODEL(self));
+
+       priv=self->priv;
+
+       /* Set value if changed */
+       if(priv->filterCallback!=inFilterCallback ||
+               priv->filterUserData!=inUserData ||
+               priv->filterUserDataDestroyCallback!=inUserDataDestroyCallback)
+       {
+               gboolean                                oldFilterIsSet;
+               gboolean                                newFilterIsSet;
+
+               /* Get old "filter-set" value. It is used later to determine if 
this
+                * property has changed also.
+                */
+               oldFilterIsSet=xfdashboard_model_is_filtered(self);
+
+               /* Release old values */
+               if(priv->filterUserData &&
+                       priv->filterUserDataDestroyCallback)
+               {
+                       
(priv->filterUserDataDestroyCallback)(priv->filterUserData);
+               }
+               priv->filterUserDataDestroyCallback=NULL;
+               priv->filterUserData=NULL;
+               priv->filterCallback=NULL;
+
+               /* Set value */
+               priv->filterCallback=inFilterCallback;
+               priv->filterUserData=inUserData;
+               priv->filterUserDataDestroyCallback=inUserDataDestroyCallback;
+
+               /* Get new "sort-set" value to determine if this property has
+                * changed also.
+                */
+               newFilterIsSet=xfdashboard_model_is_filtered(self);
+
+               /* Notify about change of 'sort-set' if changed and after model
+                * was sorted.
+                */
+               if(oldFilterIsSet!=newFilterIsSet)
+               {
+                       g_object_notify_by_pspec(G_OBJECT(self), 
XfdashboardModelProperties[PROP_FILTER_SET]);
+               }
+
+               /* Emit signal that filter has changed */
+               g_signal_emit(self, 
XfdashboardModelSignals[SIGNAL_FILTER_CHANGED], 0);
+       }
+}
+
+/* Check if requested row is filtered */
+gboolean xfdashboard_model_filter_row(XfdashboardModel *self, gint inRow)
+{
+       XfdashboardModelPrivate                 *priv;
+       XfdashboardModelIter                    *iter;
+       gboolean                                                isVisible;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(self), FALSE);
+       g_return_val_if_fail(_xfdashboard_model_is_valid_row(self, inRow), 
FALSE);
+
+       priv=self->priv;
+       isVisible=TRUE;
+
+       /* Call user supplied filter callback function to determine if this
+        * row should be filtered or not but only if filter function is set.
+        */
+       if(priv->filterCallback)
+       {
+               /* Create iterator */
+               iter=xfdashboard_model_iter_new_for_row(self, inRow);
+
+               /* Determine if row is filtered */
+               isVisible=(priv->filterCallback)(iter, priv->filterUserData);
+
+               /* Release allocated resources */
+               if(iter) g_object_unref(iter);
+       }
+
+       /* Return filter status */
+       return(isVisible);
+}
+
+/* Create iterator for model */
+XfdashboardModelIter* xfdashboard_model_iter_new(XfdashboardModel *inModel)
+{
+       XfdashboardModelIter                    *iter;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(inModel), NULL);
+
+       /* Create iterator */
+       iter=XFDASHBOARD_MODEL_ITER(g_object_new(XFDASHBOARD_TYPE_MODEL_ITER, 
NULL));
+
+       /* Set up iterator */
+       iter->priv->model=XFDASHBOARD_MODEL(g_object_ref(inModel));
+       iter->priv->iter=NULL;
+
+       /* Return newly created iterator */
+       return(iter);
+}
+
+/* Create iterator for model at requested row */
+XfdashboardModelIter* xfdashboard_model_iter_new_for_row(XfdashboardModel 
*inModel, gint inRow)
+{
+       XfdashboardModelIter                    *iter;
+       XfdashboardModelPrivate                 *modelPriv;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL(inModel), NULL);
+       g_return_val_if_fail(_xfdashboard_model_is_valid_row(inModel, inRow), 
NULL);
+
+       modelPriv=inModel->priv;
+
+       /* Create iterator */
+       iter=XFDASHBOARD_MODEL_ITER(g_object_new(XFDASHBOARD_TYPE_MODEL_ITER, 
NULL));
+
+       /* Set up iterator */
+       iter->priv->model=XFDASHBOARD_MODEL(g_object_ref(inModel));
+       iter->priv->iter=g_sequence_get_iter_at_pos(modelPriv->data, inRow);
+
+       /* Return newly created iterator */
+       return(iter);
+}
+
+/* Create copy of an iterator */
+XfdashboardModelIter* xfdashboard_model_iter_copy(XfdashboardModelIter *self)
+{
+       XfdashboardModelIterPrivate             *priv;
+       XfdashboardModelIter                    *copyIter;
+
+       g_return_val_if_fail(XFDASHBOARD_IS_MODEL_ITER(self), NULL);
+
+       priv=self->priv;
+
+       /* Create iterator */
+       
copyIter=XFDASHBOARD_MODEL_ITER(g_object_new(XFDASHBOARD_TYPE_MODEL_ITER, 
NULL));
+
+       /* Set up iterator to be a copy of given iterator */
+       copyIter->priv->model=XFDASHBOARD_MODEL(g_object_ref(priv->model));
+       copyIter->priv->iter=priv->iter;
+
+       /* Return copy of iterator */
+       return(copyIter);
+}
+
+/* Move iterator to next item in model's data */
+gboolean xfdashboard_model_iter_next(XfdashboardModelIter *self)
+{
+       XfdashboardModelIterPrivate             *priv;
+       XfdashboardModelPrivate                 *modelPriv;
+       GSequenceIter                                   *newIter;
+
+       g_return_val_if_fail(_xfdashboard_model_iter_is_valid(self, FALSE), 
FALSE);
+
+       priv=self->priv;
+       modelPriv=priv->model->priv;
+
+       /* If no iterator was initialized then create an iterator pointing
+        * to begin of model's data ...
+        */
+       if(!priv->iter)
+       {
+               /* Get and set iterator pointing to begin of model's data */
+               newIter=g_sequence_get_begin_iter(modelPriv->data);
+       }
+               /* ... otherwise move iterator to next item in model's data */
+               else
+               {
+                       /* Move iterator to next item in model's data */
+                       newIter=g_sequence_iter_next(priv->iter);
+               }
+
+       /* If iterator is invalid or end of model's data is reached
+        * return FALSE here.
+        */
+       if(!newIter ||
+               g_sequence_iter_is_end(newIter))
+       {
+               return(FALSE);
+       }
+
+       /* New iterator is valid so set it */
+       priv->iter=newIter;
+
+       /* If we get here then all went well and we can return TRUE */
+       return(TRUE);
+}
+
+/* Move iterator to previous item in model's data */
+gboolean xfdashboard_model_iter_prev(XfdashboardModelIter *self)
+{
+       XfdashboardModelIterPrivate             *priv;
+       XfdashboardModelPrivate                 *modelPriv;
+       GSequenceIter                                   *newIter;
+
+       g_return_val_if_fail(_xfdashboard_model_iter_is_valid(self, FALSE), 
FALSE);
+
+       priv=self->priv;
+       modelPriv=priv->model->priv;
+
+       /* If no iterator was initialized then create an iterator pointing
+        * to end of model's data ...
+        */
+       if(!priv->iter)
+       {
+               /* Get and set iterator pointing to end of model's data */
+               newIter=g_sequence_get_end_iter(modelPriv->data);
+       }
+               /* ... otherwise move iterator to previous item in model's data 
*/
+               else
+               {
+                       /* Move iterator to next item in model's data */
+                       newIter=g_sequence_iter_prev(priv->iter);
+               }
+
+       /* If iterator is invalid or begin of model's data is reached
+        * return FALSE here.
+        */
+       if(!newIter ||
+               g_sequence_iter_is_begin(newIter))
+       {
+               return(FALSE);
+       }
+
+       /* New iterator is valid so set it */
+       priv->iter=newIter;
+
+       /* If we get here then all went well and we can return TRUE */
+       return(TRUE);
+}
+
+/* Move iterator to requested row in model's data */
+gboolean xfdashboard_model_iter_move_to_row(XfdashboardModelIter *self, gint 
inRow)
+{
+       XfdashboardModelIterPrivate             *priv;
+       XfdashboardModelPrivate                 *modelPriv;
+
+       g_return_val_if_fail(_xfdashboard_model_iter_is_valid(self, FALSE), 
FALSE);
+
+       priv=self->priv;
+       modelPriv=priv->model->priv;
+
+       /* Check that requested row is within range */
+       g_return_val_if_fail(_xfdashboard_model_is_valid_row(priv->model, 
inRow), FALSE);
+
+       /* Move iterator to requested row */
+       priv->iter=g_sequence_get_iter_at_pos(modelPriv->data, inRow);
+
+       /* If we get here then all went well and we can return TRUE */
+       return(TRUE);
+}
+
+/* Get model to which this iterator belongs to */
+XfdashboardModel* xfdashboard_model_iter_get_model(XfdashboardModelIter *self)
+{
+       g_return_val_if_fail(_xfdashboard_model_iter_is_valid(self, FALSE), 
FALSE);
+
+       return(self->priv->model);
+}
+
+/* Get row at model's data this iterator points to currently */
+guint xfdashboard_model_iter_get_row(XfdashboardModelIter *self)
+{
+       XfdashboardModelIterPrivate             *priv;
+       gint                                                    position;
+
+       g_return_val_if_fail(_xfdashboard_model_iter_is_valid(self, TRUE), 0);
+
+       priv=self->priv;
+
+       /* Get position from iterator */
+       position=g_sequence_iter_get_position(priv->iter);
+       if(position<0) position=0;
+
+       /* Return position (maybe corrected for unsigned integer) */
+       return((guint)position);
+}
+
+/* Get item at position and model of this iterator */
+gpointer xfdashboard_model_iter_get(XfdashboardModelIter *self)
+{
+       XfdashboardModelIterPrivate             *priv;
+
+       g_return_val_if_fail(_xfdashboard_model_iter_is_valid(self, TRUE), 
NULL);
+
+       priv=self->priv;
+
+       /* Get item of model this iterator belongs to */
+       return(g_sequence_get(priv->iter));
+}
+
+/* Set or replace data at iterator */
+gboolean xfdashboard_model_iter_set(XfdashboardModelIter *self, gpointer 
inData)
+{
+       XfdashboardModelIterPrivate             *priv;
+       XfdashboardModelPrivate                 *modelPriv;
+
+       g_return_val_if_fail(_xfdashboard_model_iter_is_valid(self, TRUE), 
FALSE);
+
+       priv=self->priv;
+       modelPriv=priv->model->priv;
+
+       /* If a function at model is provided to free data on removal
+        * then call it now.
+        */
+       if(modelPriv->freeDataCallback)
+       {
+               gpointer                                        oldData;
+
+               /* Get data to remove */
+               oldData=g_sequence_get(priv->iter);
+
+               /* Call function to free data */
+               (modelPriv->freeDataCallback)(oldData);
+       }
+
+       /* Set new data at iterator */
+       g_sequence_set(priv->iter, inData);
+
+       /* Emit signal */
+       g_signal_emit(self, XfdashboardModelSignals[SIGNAL_ROW_CHANGED], 0, 
self);
+
+       /* Return TRUE for success */
+       return(TRUE);
+}
+
+/* Remove data at iterator */
+gboolean xfdashboard_model_iter_remove(XfdashboardModelIter *self)
+{
+       XfdashboardModelIterPrivate             *priv;
+       XfdashboardModelPrivate                 *modelPriv;
+
+       g_return_val_if_fail(_xfdashboard_model_iter_is_valid(self, TRUE), 
FALSE);
+
+       priv=self->priv;
+       modelPriv=priv->model->priv;
+
+       /* Emit signal before removal to give signal handlers a changed
+        * to access the data at iterator a last time.
+        */
+       g_signal_emit(self, XfdashboardModelSignals[SIGNAL_ROW_REMOVED], 0, 
self);
+
+       /* If a function at model is provided to free data on removal
+        * then call it now.
+        */
+       if(modelPriv->freeDataCallback)
+       {
+               gpointer                                        oldData;
+
+               /* Get data to remove */
+               oldData=g_sequence_get(priv->iter);
+
+               /* Call function to free data */
+               (modelPriv->freeDataCallback)(oldData);
+       }
+
+       /* Remove data from model's data */
+       g_sequence_remove(priv->iter);
+
+       /* Return TRUE for success */
+       return(TRUE);
+}
+
+/* Check if row is filtered to which this iterator is pointing to */
+gboolean xfdashboard_model_iter_filter(XfdashboardModelIter *self)
+{
+       XfdashboardModelIterPrivate             *priv;
+       XfdashboardModelPrivate                 *modelPriv;
+       gboolean                                                isVisible;
+
+       g_return_val_if_fail(_xfdashboard_model_iter_is_valid(self, TRUE), 
FALSE);
+
+       priv=self->priv;
+       modelPriv=priv->model->priv;
+       isVisible=TRUE;
+
+       /* Call user supplied filter callback function to determine if this
+        * row should be filtered or not but only if filter function is set.
+        */
+       if(modelPriv->filterCallback)
+       {
+               /* Determine if row is filtered */
+               isVisible=(modelPriv->filterCallback)(self, 
modelPriv->filterUserData);
+       }
+
+       /* Return filter status */
+       return(isVisible);
+}
diff --git a/libxfdashboard/model.h b/libxfdashboard/model.h
new file mode 100644
index 0000000..88eb7f6
--- /dev/null
+++ b/libxfdashboard/model.h
@@ -0,0 +1,196 @@
+/*
+ * model: A simple and generic data model holding one value per row
+ * 
+ * Copyright 2012-2016 Stephan Haller <[email protected]>
+ * 
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program 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 General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ * 
+ * 
+ */
+
+#ifndef __LIBXFDASHBOARD_MODEL__
+#define __LIBXFDASHBOARD_MODEL__
+
+#if !defined(__LIBXFDASHBOARD_H_INSIDE__) && 
!defined(LIBXFDASHBOARD_COMPILATION)
+#error "Only <libxfdashboard/libxfdashboard.h> can be included directly."
+#endif
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/* Object declaration: XfdashboardModelIter */
+#define XFDASHBOARD_TYPE_MODEL_ITER                            
(xfdashboard_model_iter_get_type())
+#define XFDASHBOARD_MODEL_ITER(obj)                            
(G_TYPE_CHECK_INSTANCE_CAST((obj), XFDASHBOARD_TYPE_MODEL_ITER, 
XfdashboardModelIter))
+#define XFDASHBOARD_IS_MODEL_ITER(obj)                 
(G_TYPE_CHECK_INSTANCE_TYPE((obj), XFDASHBOARD_TYPE_MODEL_ITER))
+#define XFDASHBOARD_MODEL_ITER_CLASS(klass)            
(G_TYPE_CHECK_CLASS_CAST((klass), XFDASHBOARD_TYPE_MODEL_ITER, 
XfdashboardModelIterClass))
+#define XFDASHBOARD_IS_MODEL_ITER_CLASS(klass) 
(G_TYPE_CHECK_CLASS_TYPE((klass), XFDASHBOARD_TYPE_MODEL_ITER))
+#define XFDASHBOARD_MODEL_ITER_GET_CLASS(obj)  
(G_TYPE_INSTANCE_GET_CLASS((obj), XFDASHBOARD_TYPE_MODEL_ITER, 
XfdashboardModelIterClass))
+
+typedef struct _XfdashboardModelIter                   XfdashboardModelIter;
+typedef struct _XfdashboardModelIterClass              
XfdashboardModelIterClass;
+typedef struct _XfdashboardModelIterPrivate            
XfdashboardModelIterPrivate;
+
+struct _XfdashboardModelIter
+{
+       /* Parent instance */
+       GObjectClass                                    parent_instance;
+
+       /* Private structure */
+       XfdashboardModelIterPrivate             *priv;
+};
+
+struct _XfdashboardModelIterClass
+{
+       /*< private >*/
+       /* Parent class */
+       GObjectClass                                    parent_class;
+
+       /*< public >*/
+       /* Virtual functions */
+};
+
+
+/* Object declaration: XfdashboardModel */
+#define XFDASHBOARD_TYPE_MODEL                         
(xfdashboard_model_get_type())
+#define XFDASHBOARD_MODEL(obj)                         
(G_TYPE_CHECK_INSTANCE_CAST((obj), XFDASHBOARD_TYPE_MODEL, XfdashboardModel))
+#define XFDASHBOARD_IS_MODEL(obj)                      
(G_TYPE_CHECK_INSTANCE_TYPE((obj), XFDASHBOARD_TYPE_MODEL))
+#define XFDASHBOARD_MODEL_CLASS(klass)         
(G_TYPE_CHECK_CLASS_CAST((klass), XFDASHBOARD_TYPE_MODEL, 
XfdashboardModelClass))
+#define XFDASHBOARD_IS_MODEL_CLASS(klass)      
(G_TYPE_CHECK_CLASS_TYPE((klass), XFDASHBOARD_TYPE_MODEL))
+#define XFDASHBOARD_MODEL_GET_CLASS(obj)       
(G_TYPE_INSTANCE_GET_CLASS((obj), XFDASHBOARD_TYPE_MODEL, 
XfdashboardModelClass))
+
+typedef struct _XfdashboardModel                       XfdashboardModel;
+typedef struct _XfdashboardModelClass          XfdashboardModelClass;
+typedef struct _XfdashboardModelPrivate                XfdashboardModelPrivate;
+
+struct _XfdashboardModel
+{
+       /* Parent instance */
+       GObjectClass                                    parent_instance;
+
+       /* Private structure */
+       XfdashboardModelPrivate                 *priv;
+};
+
+struct _XfdashboardModelClass
+{
+       /*< private >*/
+       /* Parent class */
+       GObjectClass                                    parent_class;
+
+       /*< public >*/
+       /* Virtual functions */
+       void (*row_added)(XfdashboardModel *self,
+                                               XfdashboardModelIter *inIter);
+       void (*row_removed)(XfdashboardModel *self,
+                                               XfdashboardModelIter *inIter);
+       void (*row_changed)(XfdashboardModel *self,
+                                               XfdashboardModelIter *inIter);
+
+       void (*sort_changed)(XfdashboardModel *self);
+
+       void (*filter_changed)(XfdashboardModel *self);
+};
+
+
+/* Public API */
+typedef void (*XfdashboardModelForeachFunc)(XfdashboardModelIter *inIter,
+                                                                               
        gpointer inData,
+                                                                               
        gpointer inUserData);
+typedef gint (*XfdashboardModelSortFunc)(XfdashboardModelIter *inLeftIter,
+                                                                               
        XfdashboardModelIter *inRightIter,
+                                                                               
        gpointer inUserData);
+typedef gboolean (*XfdashboardModelFilterFunc)(XfdashboardModelIter *inIter,
+                                                                               
                gpointer inUserData);
+
+GType xfdashboard_model_get_type(void) G_GNUC_CONST;
+GType xfdashboard_model_iter_get_type(void) G_GNUC_CONST;
+
+/* Model creation functions */
+XfdashboardModel* xfdashboard_model_new(void);
+XfdashboardModel* xfdashboard_model_new_with_free_data(GDestroyNotify 
inFreeDataFunc);
+
+/* Model information functions */
+gint xfdashboard_model_get_rows_count(XfdashboardModel *self);
+
+/* Model access functions */
+gpointer xfdashboard_model_get(XfdashboardModel *self, gint inRow);
+
+/* Model manipulation functions */
+gboolean xfdashboard_model_append(XfdashboardModel *self,
+                                                                       
gpointer inData,
+                                                                       
XfdashboardModelIter **outIter);
+gboolean xfdashboard_model_prepend(XfdashboardModel *self,
+                                                                       
gpointer inData,
+                                                                       
XfdashboardModelIter **outIter);
+gboolean xfdashboard_model_insert(XfdashboardModel *self,
+                                                                       gint 
inRow,
+                                                                       
gpointer inData,
+                                                                       
XfdashboardModelIter **outIter);
+gboolean xfdashboard_model_set(XfdashboardModel *self,
+                                                               gint inRow,
+                                                               gpointer inData,
+                                                               
XfdashboardModelIter **outIter);
+gboolean xfdashboard_model_remove(XfdashboardModel *self, gint inRow);
+void xfdashboard_model_remove_all(XfdashboardModel *self);
+
+/* Model foreach functions */
+void xfdashboard_model_foreach(XfdashboardModel *self,
+                                                               
XfdashboardModelForeachFunc inForeachCallback,
+                                                               gpointer 
inUserData);
+
+/* Model sort functions */
+gboolean xfdashboard_model_is_sorted(XfdashboardModel *self);
+void xfdashboard_model_set_sort(XfdashboardModel *self,
+                                                               
XfdashboardModelSortFunc inSortCallback,
+                                                               gpointer 
inUserData,
+                                                               GDestroyNotify 
inUserDataDestroyCallback);
+void xfdashboard_model_resort(XfdashboardModel *self);
+
+/* Model filter functions */
+gboolean xfdashboard_model_is_filtered(XfdashboardModel *self);
+void xfdashboard_model_set_filter(XfdashboardModel *self,
+                                                                       
XfdashboardModelFilterFunc inFilterCallback,
+                                                                       
gpointer inUserData,
+                                                                       
GDestroyNotify inUserDataDestroyCallback);
+gboolean xfdashboard_model_filter_row(XfdashboardModel *self, gint inRow);
+
+
+/* Model iterator functions */
+XfdashboardModelIter* xfdashboard_model_iter_new(XfdashboardModel *inModel);
+XfdashboardModelIter* xfdashboard_model_iter_new_for_row(XfdashboardModel 
*inModel, gint inRow);
+XfdashboardModelIter* xfdashboard_model_iter_copy(XfdashboardModelIter *self);
+gboolean xfdashboard_model_iter_next(XfdashboardModelIter *self);
+gboolean xfdashboard_model_iter_prev(XfdashboardModelIter *self);
+gboolean xfdashboard_model_iter_move_to_row(XfdashboardModelIter *self, gint 
inRow);
+
+/* Model iterator information functions */
+XfdashboardModel* xfdashboard_model_iter_get_model(XfdashboardModelIter *self);
+guint xfdashboard_model_iter_get_row(XfdashboardModelIter *self);
+
+/* Model iterator access functions */
+gpointer xfdashboard_model_iter_get(XfdashboardModelIter *self);
+
+/* Model iterator manipulation functions */
+gboolean xfdashboard_model_iter_set(XfdashboardModelIter *self, gpointer 
inData);
+gboolean xfdashboard_model_iter_remove(XfdashboardModelIter *self);
+
+/* Model filter functions */
+gboolean xfdashboard_model_iter_filter(XfdashboardModelIter *self);
+
+G_END_DECLS
+
+#endif /* __LIBXFDASHBOARD_MODEL__ */

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.
_______________________________________________
Xfce4-commits mailing list
[email protected]
https://mail.xfce.org/mailman/listinfo/xfce4-commits

Reply via email to