mirror of
https://github.com/rozniak/xfce-winxp-tc.git
synced 2026-01-26 11:39:44 +00:00
Enhancement: Fixes #541, shell / shellext - API for sorting view items
This commit is contained in:
@@ -78,6 +78,8 @@ add_library(
|
||||
public/strings.h
|
||||
src/styles.c
|
||||
public/styles.h
|
||||
src/treemodel.c
|
||||
public/treemodel.h
|
||||
src/version.c
|
||||
public/version.h
|
||||
src/window.c
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "@LIB_HEADER_DIR@/signals.h"
|
||||
#include "@LIB_HEADER_DIR@/strings.h"
|
||||
#include "@LIB_HEADER_DIR@/styles.h"
|
||||
#include "@LIB_HEADER_DIR@/treemodel.h"
|
||||
#include "@LIB_HEADER_DIR@/version.h"
|
||||
#include "@LIB_HEADER_DIR@/window.h"
|
||||
|
||||
|
||||
19
shared/comgtk/public/treemodel.h
Normal file
19
shared/comgtk/public/treemodel.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef __COMGTK_TREEMODEL_H__
|
||||
#define __COMGTK_TREEMODEL_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
gint wintc_tree_model_get_insertion_sort_pos(
|
||||
GtkTreeModel* tree_model,
|
||||
GtkTreeIter* node,
|
||||
gint column,
|
||||
gint data_type,
|
||||
GCompareFunc compare_func,
|
||||
gconstpointer item
|
||||
);
|
||||
|
||||
#endif
|
||||
137
shared/comgtk/src/treemodel.c
Normal file
137
shared/comgtk/src/treemodel.c
Normal file
@@ -0,0 +1,137 @@
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "../public/treemodel.h"
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
gint wintc_tree_model_get_insertion_sort_pos(
|
||||
GtkTreeModel* tree_model,
|
||||
GtkTreeIter* node,
|
||||
gint column,
|
||||
gint data_type,
|
||||
GCompareFunc compare_func,
|
||||
gconstpointer item
|
||||
)
|
||||
{
|
||||
gint n_children = gtk_tree_model_iter_n_children(tree_model, node);
|
||||
|
||||
if (!n_children)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set ourselves up, if we're sorting top level children or children of a
|
||||
// node
|
||||
//
|
||||
GtkTreeIter child;
|
||||
|
||||
gint start = 0;
|
||||
gint middle = n_children / 2;
|
||||
gint end = n_children;
|
||||
|
||||
gint diff = end - start;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
gtk_tree_model_iter_nth_child(
|
||||
tree_model,
|
||||
&child,
|
||||
node,
|
||||
middle
|
||||
);
|
||||
|
||||
// Compare item at this node
|
||||
//
|
||||
gpointer item_ptr;
|
||||
gint item_int;
|
||||
guint item_uint;
|
||||
|
||||
gint result;
|
||||
|
||||
switch (data_type)
|
||||
{
|
||||
case G_TYPE_INT:
|
||||
gtk_tree_model_get(
|
||||
tree_model,
|
||||
&child,
|
||||
column, &item_int,
|
||||
-1
|
||||
);
|
||||
|
||||
result =
|
||||
compare_func(
|
||||
item,
|
||||
GINT_TO_POINTER(item_int)
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case G_TYPE_UINT:
|
||||
gtk_tree_model_get(
|
||||
tree_model,
|
||||
&child,
|
||||
column, &item_uint,
|
||||
-1
|
||||
);
|
||||
|
||||
result =
|
||||
compare_func(
|
||||
item,
|
||||
GUINT_TO_POINTER(item_uint)
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
gtk_tree_model_get(
|
||||
tree_model,
|
||||
&child,
|
||||
column, &item_ptr,
|
||||
-1
|
||||
);
|
||||
|
||||
result =
|
||||
compare_func(
|
||||
item,
|
||||
item_ptr
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// If this is the last iteration, deal with it
|
||||
//
|
||||
if (diff == 1)
|
||||
{
|
||||
if (result > 0)
|
||||
{
|
||||
return middle + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return middle;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, iterate
|
||||
//
|
||||
if (result < 0)
|
||||
{
|
||||
end = middle;
|
||||
}
|
||||
else if (result > 0)
|
||||
{
|
||||
start = middle;
|
||||
}
|
||||
else
|
||||
{
|
||||
start = middle;
|
||||
end = middle;
|
||||
}
|
||||
|
||||
diff = end - start;
|
||||
middle = start + (diff / 2);
|
||||
}
|
||||
}
|
||||
@@ -814,7 +814,7 @@ static void on_browser_load_changed(
|
||||
}
|
||||
|
||||
static void on_current_view_items_added(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WinTCIShextView* view,
|
||||
WinTCShextViewItemsUpdate* update,
|
||||
gpointer user_data
|
||||
)
|
||||
@@ -838,11 +838,29 @@ static void on_current_view_items_added(
|
||||
NULL // FIXME: Error handling
|
||||
);
|
||||
|
||||
// Sort into model
|
||||
//
|
||||
GCompareFunc sort_func = wintc_ishext_view_get_sort_func(view);
|
||||
|
||||
gint item_pos =
|
||||
wintc_tree_model_get_insertion_sort_pos(
|
||||
GTK_TREE_MODEL(behaviour->list_model),
|
||||
NULL,
|
||||
COLUMN_VIEW_HASH,
|
||||
G_TYPE_UINT,
|
||||
sort_func,
|
||||
GUINT_TO_POINTER(item->hash)
|
||||
);
|
||||
|
||||
// Push to model
|
||||
//
|
||||
GtkTreeIter iter;
|
||||
|
||||
gtk_list_store_append(behaviour->list_model, &iter);
|
||||
gtk_list_store_insert(
|
||||
behaviour->list_model,
|
||||
&iter,
|
||||
item_pos
|
||||
);
|
||||
gtk_list_store_set(
|
||||
behaviour->list_model,
|
||||
&iter,
|
||||
|
||||
@@ -19,6 +19,7 @@ enum
|
||||
COLUMN_ICON_NAME = 0,
|
||||
COLUMN_ENTRY_NAME,
|
||||
COLUMN_VIEW_HASH,
|
||||
COLUMN_MAPPED_VIEW,
|
||||
N_COLUMNS
|
||||
};
|
||||
|
||||
@@ -43,8 +44,8 @@ static void wintc_sh_tree_view_behaviour_update_view(
|
||||
WinTCShBrowser* browser
|
||||
);
|
||||
|
||||
static void clear_object_safe(
|
||||
GObject* object
|
||||
static void clear_tree_row_reference(
|
||||
GtkTreeRowReference* row_ref
|
||||
);
|
||||
|
||||
static void on_browser_load_changed(
|
||||
@@ -80,8 +81,7 @@ struct _WinTCShTreeViewBehaviour
|
||||
WinTCShextHost* shext_host;
|
||||
|
||||
GtkTreeStore* tree_model;
|
||||
GHashTable* map_iter_to_view;
|
||||
GHashTable* map_hash_to_iter;
|
||||
GHashTable* map_hash_to_row;
|
||||
|
||||
GtkWidget* tree_view;
|
||||
};
|
||||
@@ -133,7 +133,7 @@ static void wintc_sh_tree_view_behaviour_init(
|
||||
WinTCShTreeViewBehaviour* self
|
||||
)
|
||||
{
|
||||
// Set up maps hash->iter->view
|
||||
// Set up map for hash->row
|
||||
//
|
||||
// The intention of this is to be able to map view/viewitems to a node in
|
||||
// the tree, and then those nodes to a concrete view object
|
||||
@@ -142,18 +142,13 @@ static void wintc_sh_tree_view_behaviour_init(
|
||||
// that are enumerated from a view are akin to placeholders, and a view is
|
||||
// created only when those nodes are expanded/enumerated themselves
|
||||
//
|
||||
self->map_iter_to_view = g_hash_table_new_full(
|
||||
g_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify) clear_object_safe
|
||||
);
|
||||
self->map_hash_to_iter = g_hash_table_new_full(
|
||||
g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL,
|
||||
g_free
|
||||
);
|
||||
self->map_hash_to_row =
|
||||
g_hash_table_new_full(
|
||||
g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL,
|
||||
(GDestroyNotify) clear_tree_row_reference
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -198,10 +193,11 @@ static void wintc_sh_tree_view_behaviour_constructed(
|
||||
|
||||
behaviour->tree_model =
|
||||
gtk_tree_store_new(
|
||||
3,
|
||||
4,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_UINT
|
||||
G_TYPE_UINT,
|
||||
G_TYPE_OBJECT
|
||||
);
|
||||
|
||||
gtk_tree_view_set_headers_visible(
|
||||
@@ -266,8 +262,7 @@ static void wintc_sh_tree_view_behaviour_dispose(
|
||||
g_clear_object(&(behaviour->shext_host));
|
||||
g_clear_object(&(behaviour->tree_view));
|
||||
|
||||
g_hash_table_unref(g_steal_pointer(&(behaviour->map_iter_to_view)));
|
||||
g_hash_table_unref(g_steal_pointer(&(behaviour->map_hash_to_iter)));
|
||||
g_hash_table_unref(g_steal_pointer(&(behaviour->map_hash_to_row)));
|
||||
|
||||
(G_OBJECT_CLASS(wintc_sh_tree_view_behaviour_parent_class))
|
||||
->dispose(object);
|
||||
@@ -336,11 +331,11 @@ static void wintc_sh_tree_view_behaviour_update_view(
|
||||
// Collect up the views back up the tree, until we hit a view we already
|
||||
// have
|
||||
//
|
||||
GError* error = NULL;
|
||||
const gchar* iter_path = NULL;
|
||||
GSList* list_views = NULL;
|
||||
WinTCShextPathInfo path_info = { 0 };
|
||||
WinTCIShextView* view = current_view;
|
||||
GError* error = NULL;
|
||||
GSList* list_views = NULL;
|
||||
WinTCShextPathInfo path_info = { 0 };
|
||||
GtkTreeRowReference* row_ref = NULL;
|
||||
WinTCIShextView* view = current_view;
|
||||
|
||||
while (view)
|
||||
{
|
||||
@@ -350,13 +345,13 @@ static void wintc_sh_tree_view_behaviour_update_view(
|
||||
|
||||
// If there is a node in the tree for the view hash, stop here
|
||||
//
|
||||
iter_path =
|
||||
row_ref =
|
||||
g_hash_table_lookup(
|
||||
behaviour->map_hash_to_iter,
|
||||
behaviour->map_hash_to_row,
|
||||
GUINT_TO_POINTER(wintc_ishext_view_get_unique_hash(view))
|
||||
);
|
||||
|
||||
if (iter_path)
|
||||
if (row_ref)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -431,20 +426,30 @@ static void wintc_sh_tree_view_behaviour_update_view(
|
||||
//
|
||||
if (iter == list_views)
|
||||
{
|
||||
if (iter_path)
|
||||
if (row_ref)
|
||||
{
|
||||
gtk_tree_model_get_iter_from_string(
|
||||
WinTCIShextView* node_view = NULL;
|
||||
GtkTreePath* tree_path;
|
||||
|
||||
tree_path =
|
||||
gtk_tree_row_reference_get_path(row_ref);
|
||||
|
||||
gtk_tree_model_get_iter(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&next,
|
||||
iter_path
|
||||
tree_path
|
||||
);
|
||||
|
||||
if (
|
||||
g_hash_table_contains(
|
||||
behaviour->map_iter_to_view,
|
||||
iter_path
|
||||
)
|
||||
)
|
||||
gtk_tree_model_get(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&next,
|
||||
COLUMN_MAPPED_VIEW, &node_view,
|
||||
-1
|
||||
);
|
||||
|
||||
gtk_tree_path_free(tree_path);
|
||||
|
||||
if (node_view)
|
||||
{
|
||||
WINTC_LOG_DEBUG(
|
||||
"shell: tree - first iter is a mapped view."
|
||||
@@ -475,10 +480,11 @@ static void wintc_sh_tree_view_behaviour_update_view(
|
||||
g_object_ref(view);
|
||||
}
|
||||
|
||||
g_hash_table_insert(
|
||||
behaviour->map_iter_to_view,
|
||||
g_strdup(iter_path),
|
||||
view
|
||||
gtk_tree_store_set(
|
||||
behaviour->tree_model,
|
||||
&next,
|
||||
COLUMN_MAPPED_VIEW, view,
|
||||
-1
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -498,35 +504,36 @@ static void wintc_sh_tree_view_behaviour_update_view(
|
||||
gtk_tree_store_set(
|
||||
behaviour->tree_model,
|
||||
&next,
|
||||
COLUMN_ICON_NAME, wintc_ishext_view_get_icon_name(view),
|
||||
COLUMN_ENTRY_NAME, wintc_ishext_view_get_display_name(view),
|
||||
COLUMN_VIEW_HASH, hash,
|
||||
COLUMN_ICON_NAME, wintc_ishext_view_get_icon_name(view),
|
||||
COLUMN_ENTRY_NAME, wintc_ishext_view_get_display_name(view),
|
||||
COLUMN_VIEW_HASH, hash,
|
||||
COLUMN_MAPPED_VIEW, view,
|
||||
-1
|
||||
);
|
||||
|
||||
// Map the hash<->iter
|
||||
// Map the hash->row
|
||||
//
|
||||
GtkTreePath* tree_path =
|
||||
gtk_tree_model_get_path(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&next
|
||||
);
|
||||
|
||||
if (view == current_view)
|
||||
{
|
||||
g_object_ref(view);
|
||||
}
|
||||
|
||||
g_hash_table_insert(
|
||||
behaviour->map_hash_to_iter,
|
||||
behaviour->map_hash_to_row,
|
||||
GUINT_TO_POINTER(hash),
|
||||
gtk_tree_model_get_string_from_iter(
|
||||
gtk_tree_row_reference_new(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&next
|
||||
tree_path
|
||||
)
|
||||
);
|
||||
g_hash_table_insert(
|
||||
behaviour->map_iter_to_view,
|
||||
gtk_tree_model_get_string_from_iter(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&next
|
||||
),
|
||||
view
|
||||
);
|
||||
|
||||
gtk_tree_path_free(tree_path);
|
||||
}
|
||||
|
||||
last = next; // Copy node iter over
|
||||
@@ -554,28 +561,31 @@ static void wintc_sh_tree_view_behaviour_update_view(
|
||||
gtk_tree_store_set(
|
||||
behaviour->tree_model,
|
||||
&next,
|
||||
COLUMN_ICON_NAME, wintc_ishext_view_get_icon_name(next_view),
|
||||
COLUMN_ENTRY_NAME, wintc_ishext_view_get_display_name(next_view),
|
||||
COLUMN_VIEW_HASH, hash,
|
||||
COLUMN_ICON_NAME, wintc_ishext_view_get_icon_name(next_view),
|
||||
COLUMN_ENTRY_NAME, wintc_ishext_view_get_display_name(next_view),
|
||||
COLUMN_VIEW_HASH, hash,
|
||||
COLUMN_MAPPED_VIEW, next_view,
|
||||
-1
|
||||
);
|
||||
|
||||
g_hash_table_insert(
|
||||
behaviour->map_hash_to_iter,
|
||||
GUINT_TO_POINTER(hash),
|
||||
gtk_tree_model_get_string_from_iter(
|
||||
// Map the hash->row
|
||||
//
|
||||
GtkTreePath* tree_path =
|
||||
gtk_tree_model_get_path(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&next
|
||||
);
|
||||
|
||||
g_hash_table_insert(
|
||||
behaviour->map_hash_to_row,
|
||||
GUINT_TO_POINTER(hash),
|
||||
gtk_tree_row_reference_new(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
tree_path
|
||||
)
|
||||
);
|
||||
g_hash_table_insert(
|
||||
behaviour->map_iter_to_view,
|
||||
gtk_tree_model_get_string_from_iter(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&next
|
||||
),
|
||||
next_view
|
||||
);
|
||||
|
||||
gtk_tree_path_free(tree_path);
|
||||
}
|
||||
|
||||
// Watch for items and refresh if this is a new view
|
||||
@@ -618,14 +628,33 @@ static void wintc_sh_tree_view_behaviour_update_view(
|
||||
//
|
||||
// CALLBACKS
|
||||
//
|
||||
static void clear_object_safe(
|
||||
GObject* object
|
||||
static void clear_tree_row_reference(
|
||||
GtkTreeRowReference* row_ref
|
||||
)
|
||||
{
|
||||
if (object)
|
||||
{
|
||||
g_object_unref(object);
|
||||
}
|
||||
WinTCIShextView* view = NULL;
|
||||
|
||||
GtkTreeModel* tree_model = gtk_tree_row_reference_get_model(row_ref);
|
||||
GtkTreePath* tree_path = gtk_tree_row_reference_get_path(row_ref);
|
||||
|
||||
GtkTreeIter row;
|
||||
|
||||
gtk_tree_model_get_iter(
|
||||
tree_model,
|
||||
&row,
|
||||
tree_path
|
||||
);
|
||||
|
||||
gtk_tree_model_get(
|
||||
tree_model,
|
||||
&row,
|
||||
COLUMN_MAPPED_VIEW, &view,
|
||||
-1
|
||||
);
|
||||
|
||||
g_clear_object(&view);
|
||||
gtk_tree_path_free(tree_path);
|
||||
gtk_tree_row_reference_free(row_ref);
|
||||
}
|
||||
|
||||
static void on_browser_load_changed(
|
||||
@@ -664,17 +693,22 @@ static void on_view_items_added(
|
||||
|
||||
// Locate the parent node
|
||||
//
|
||||
const gchar* iter_path =
|
||||
GtkTreeRowReference* row_ref;
|
||||
GtkTreePath* tree_path;
|
||||
|
||||
row_ref =
|
||||
g_hash_table_lookup(
|
||||
behaviour->map_hash_to_iter,
|
||||
behaviour->map_hash_to_row,
|
||||
GUINT_TO_POINTER(wintc_ishext_view_get_unique_hash(view))
|
||||
);
|
||||
|
||||
tree_path = gtk_tree_row_reference_get_path(row_ref);
|
||||
|
||||
if (
|
||||
!gtk_tree_model_get_iter_from_string(
|
||||
!gtk_tree_model_get_iter(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&parent,
|
||||
iter_path
|
||||
tree_path
|
||||
)
|
||||
)
|
||||
{
|
||||
@@ -682,6 +716,8 @@ static void on_view_items_added(
|
||||
return;
|
||||
}
|
||||
|
||||
gtk_tree_path_free(tree_path);
|
||||
|
||||
// Iterate over the items to append to the tree
|
||||
//
|
||||
WinTCShextViewItem* view_item;
|
||||
@@ -695,7 +731,7 @@ static void on_view_items_added(
|
||||
if (
|
||||
view_item->is_leaf ||
|
||||
g_hash_table_contains(
|
||||
behaviour->map_hash_to_iter,
|
||||
behaviour->map_hash_to_row,
|
||||
GUINT_TO_POINTER(view_item->hash)
|
||||
)
|
||||
)
|
||||
@@ -708,10 +744,27 @@ static void on_view_items_added(
|
||||
GUINT_TO_POINTER(view_item->hash)
|
||||
);
|
||||
|
||||
gtk_tree_store_append(
|
||||
// Sort into model
|
||||
//
|
||||
GCompareFunc sort_func = wintc_ishext_view_get_sort_func(view);
|
||||
|
||||
gint item_pos =
|
||||
wintc_tree_model_get_insertion_sort_pos(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&parent,
|
||||
COLUMN_VIEW_HASH,
|
||||
G_TYPE_UINT,
|
||||
sort_func,
|
||||
GUINT_TO_POINTER(view_item->hash)
|
||||
);
|
||||
|
||||
// Push to model
|
||||
//
|
||||
gtk_tree_store_insert(
|
||||
behaviour->tree_model,
|
||||
&child,
|
||||
&parent
|
||||
&parent,
|
||||
item_pos
|
||||
);
|
||||
gtk_tree_store_set(
|
||||
behaviour->tree_model,
|
||||
@@ -722,14 +775,24 @@ static void on_view_items_added(
|
||||
-1
|
||||
);
|
||||
|
||||
g_hash_table_insert(
|
||||
behaviour->map_hash_to_iter,
|
||||
GUINT_TO_POINTER(view_item->hash),
|
||||
gtk_tree_model_get_string_from_iter(
|
||||
// Map hash-->row
|
||||
//
|
||||
GtkTreePath* tree_path =
|
||||
gtk_tree_model_get_path(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&child
|
||||
);
|
||||
|
||||
g_hash_table_insert(
|
||||
behaviour->map_hash_to_row,
|
||||
GUINT_TO_POINTER(view_item->hash),
|
||||
gtk_tree_row_reference_new(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
tree_path
|
||||
)
|
||||
);
|
||||
|
||||
gtk_tree_path_free(tree_path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -750,34 +813,43 @@ static void on_view_items_removed(
|
||||
{
|
||||
guint item_hash = GPOINTER_TO_UINT(upd_iter->data);
|
||||
|
||||
const gchar* iter_path =
|
||||
// Nav to iter
|
||||
//
|
||||
GtkTreeRowReference* row_ref;
|
||||
GtkTreePath* tree_path;
|
||||
|
||||
row_ref =
|
||||
g_hash_table_lookup(
|
||||
behaviour->map_hash_to_iter,
|
||||
behaviour->map_hash_to_row,
|
||||
GUINT_TO_POINTER(item_hash)
|
||||
);
|
||||
|
||||
if (!iter_path)
|
||||
if (!row_ref)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
gtk_tree_model_get_iter_from_string(
|
||||
tree_path =
|
||||
gtk_tree_row_reference_get_path(row_ref);
|
||||
|
||||
gtk_tree_model_get_iter(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&iter,
|
||||
iter_path
|
||||
tree_path
|
||||
);
|
||||
|
||||
gtk_tree_path_free(tree_path);
|
||||
|
||||
// Delete node and mapping (row ref and view collected up via
|
||||
// clear_tree_row_reference())
|
||||
//
|
||||
gtk_tree_store_remove(
|
||||
behaviour->tree_model,
|
||||
&iter
|
||||
);
|
||||
|
||||
g_hash_table_remove(
|
||||
behaviour->map_iter_to_view,
|
||||
iter_path
|
||||
);
|
||||
g_hash_table_remove(
|
||||
behaviour->map_hash_to_iter,
|
||||
behaviour->map_hash_to_row,
|
||||
GUINT_TO_POINTER(item_hash)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -38,6 +38,11 @@ static gboolean wintc_sh_view_cpl_activate_item(
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
static gint wintc_sh_view_cpl_compare_items(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash1,
|
||||
guint item_hash2
|
||||
);
|
||||
static const gchar* wintc_sh_view_cpl_get_display_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -75,6 +80,11 @@ static WinTCShextOperation* wintc_sh_view_cpl_spawn_operation(
|
||||
GError** error
|
||||
);
|
||||
|
||||
static WinTCShextViewItem* wintc_sh_view_cpl_get_view_item(
|
||||
WinTCShViewCpl* view_cpl,
|
||||
guint item_hash
|
||||
);
|
||||
|
||||
//
|
||||
// GLIB OOP/CLASS INSTANCE DEFINITIONS
|
||||
//
|
||||
@@ -131,6 +141,7 @@ static void wintc_sh_view_cpl_ishext_view_interface_init(
|
||||
)
|
||||
{
|
||||
iface->activate_item = wintc_sh_view_cpl_activate_item;
|
||||
iface->compare_items = wintc_sh_view_cpl_compare_items;
|
||||
iface->get_display_name = wintc_sh_view_cpl_get_display_name;
|
||||
iface->get_icon_name = wintc_sh_view_cpl_get_icon_name;
|
||||
iface->get_operations_for_item = wintc_sh_view_cpl_get_operations_for_item;
|
||||
@@ -206,11 +217,7 @@ static gboolean wintc_sh_view_cpl_activate_item(
|
||||
WinTCShCplApplet* applet;
|
||||
WinTCShextViewItem* item;
|
||||
|
||||
item = (WinTCShextViewItem*)
|
||||
g_hash_table_lookup(
|
||||
view_cpl->map_items,
|
||||
GUINT_TO_POINTER(item_hash)
|
||||
);
|
||||
item = wintc_sh_view_cpl_get_view_item(view_cpl, item_hash);
|
||||
applet = (WinTCShCplApplet*) item->priv;
|
||||
|
||||
if (wintc_sh_cpl_applet_is_executable(applet))
|
||||
@@ -223,6 +230,22 @@ static gboolean wintc_sh_view_cpl_activate_item(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint wintc_sh_view_cpl_compare_items(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash1,
|
||||
guint item_hash2
|
||||
)
|
||||
{
|
||||
WinTCShViewCpl* view_cpl = WINTC_SH_VIEW_CPL(view);
|
||||
|
||||
WinTCShextViewItem* item1 =
|
||||
wintc_sh_view_cpl_get_view_item(view_cpl, item_hash1);
|
||||
WinTCShextViewItem* item2 =
|
||||
wintc_sh_view_cpl_get_view_item(view_cpl, item_hash2);
|
||||
|
||||
return wintc_shext_view_item_compare_by_name(item1, item2);
|
||||
}
|
||||
|
||||
static const gchar* wintc_sh_view_cpl_get_display_name(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
@@ -379,3 +402,19 @@ WinTCIShextView* wintc_sh_view_cpl_new(void)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// PRIVATE FUNCTIONS
|
||||
//
|
||||
static WinTCShextViewItem* wintc_sh_view_cpl_get_view_item(
|
||||
WinTCShViewCpl* view_cpl,
|
||||
guint item_hash
|
||||
)
|
||||
{
|
||||
return
|
||||
(WinTCShextViewItem*)
|
||||
g_hash_table_lookup(
|
||||
view_cpl->map_items,
|
||||
GUINT_TO_POINTER(item_hash)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -79,6 +79,11 @@ static gboolean wintc_sh_view_desktop_activate_item(
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
static gint wintc_sh_view_desktop_compare_items(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash1,
|
||||
guint item_hash2
|
||||
);
|
||||
static const gchar* wintc_sh_view_desktop_get_display_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -201,6 +206,7 @@ static void wintc_sh_view_desktop_ishext_view_interface_init(
|
||||
)
|
||||
{
|
||||
iface->activate_item = wintc_sh_view_desktop_activate_item;
|
||||
iface->compare_items = wintc_sh_view_desktop_compare_items;
|
||||
iface->get_display_name = wintc_sh_view_desktop_get_display_name;
|
||||
iface->get_icon_name = wintc_sh_view_desktop_get_icon_name;
|
||||
iface->get_operations_for_item =
|
||||
@@ -272,6 +278,16 @@ static gboolean wintc_sh_view_desktop_activate_item(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint wintc_sh_view_desktop_compare_items(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(guint item_hash1),
|
||||
WINTC_UNUSED(guint item_hash2)
|
||||
)
|
||||
{
|
||||
// FIXME: Proper implementation
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const gchar* wintc_sh_view_desktop_get_display_name(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
|
||||
@@ -62,6 +62,11 @@ static gboolean wintc_sh_view_drives_activate_item(
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
static gint wintc_sh_view_drives_compare_items(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash1,
|
||||
guint item_hash2
|
||||
);
|
||||
static const gchar* wintc_sh_view_drives_get_display_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -175,6 +180,7 @@ static void wintc_sh_view_drives_ishext_view_interface_init(
|
||||
)
|
||||
{
|
||||
iface->activate_item = wintc_sh_view_drives_activate_item;
|
||||
iface->compare_items = wintc_sh_view_drives_compare_items;
|
||||
iface->get_display_name = wintc_sh_view_drives_get_display_name;
|
||||
iface->get_icon_name = wintc_sh_view_drives_get_icon_name;
|
||||
iface->get_operations_for_item =
|
||||
@@ -242,6 +248,16 @@ static gboolean wintc_sh_view_drives_activate_item(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint wintc_sh_view_drives_compare_items(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(guint item_hash1),
|
||||
WINTC_UNUSED(guint item_hash2)
|
||||
)
|
||||
{
|
||||
// FIXME: Proper implementation
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const gchar* wintc_sh_view_drives_get_display_name(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
|
||||
@@ -68,8 +68,10 @@ static gboolean wintc_sh_view_fs_activate_item(
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
static guint wintc_sh_view_fs_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
static gint wintc_sh_view_fs_compare_items(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash1,
|
||||
guint item_hash2
|
||||
);
|
||||
static const gchar* wintc_sh_view_fs_get_display_name(
|
||||
WinTCIShextView* view
|
||||
@@ -92,6 +94,9 @@ static void wintc_sh_view_fs_get_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
);
|
||||
static guint wintc_sh_view_fs_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static gboolean wintc_sh_view_fs_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -122,6 +127,10 @@ static gboolean real_activate_item(
|
||||
GError** error
|
||||
);
|
||||
|
||||
static WinTCShextViewItem* wintc_sh_view_fs_get_view_item(
|
||||
WinTCShViewFS* view_fs,
|
||||
guint item_hash
|
||||
);
|
||||
static void wintc_sh_view_fs_update_new_templates(
|
||||
WinTCShViewFS* view_fs
|
||||
);
|
||||
@@ -246,6 +255,7 @@ static void wintc_sh_view_fs_ishext_view_interface_init(
|
||||
)
|
||||
{
|
||||
iface->activate_item = wintc_sh_view_fs_activate_item;
|
||||
iface->compare_items = wintc_sh_view_fs_compare_items;
|
||||
iface->get_display_name = wintc_sh_view_fs_get_display_name;
|
||||
iface->get_icon_name = wintc_sh_view_fs_get_icon_name;
|
||||
iface->get_operations_for_item = wintc_sh_view_fs_get_operations_for_item;
|
||||
@@ -396,11 +406,7 @@ static gboolean wintc_sh_view_fs_activate_item(
|
||||
// Retrieve the item itself
|
||||
//
|
||||
WinTCShextViewItem* item =
|
||||
(WinTCShextViewItem*)
|
||||
g_hash_table_lookup(
|
||||
view_fs->fs_map_entries,
|
||||
GUINT_TO_POINTER(item_hash)
|
||||
);
|
||||
wintc_sh_view_fs_get_view_item(view_fs, item_hash);
|
||||
|
||||
if (!item)
|
||||
{
|
||||
@@ -419,6 +425,20 @@ static gboolean wintc_sh_view_fs_activate_item(
|
||||
);
|
||||
}
|
||||
|
||||
static gint wintc_sh_view_fs_compare_items(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash1,
|
||||
guint item_hash2
|
||||
)
|
||||
{
|
||||
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
|
||||
|
||||
return wintc_shext_view_item_compare_by_fs_order(
|
||||
wintc_sh_view_fs_get_view_item(view_fs, item_hash1),
|
||||
wintc_sh_view_fs_get_view_item(view_fs, item_hash2)
|
||||
);
|
||||
}
|
||||
|
||||
static const gchar* wintc_sh_view_fs_get_display_name(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
@@ -453,11 +473,7 @@ static GMenuModel* wintc_sh_view_fs_get_operations_for_item(
|
||||
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
|
||||
|
||||
WinTCShextViewItem* view_item =
|
||||
(WinTCShextViewItem*)
|
||||
g_hash_table_lookup(
|
||||
view_fs->fs_map_entries,
|
||||
GUINT_TO_POINTER(item_hash)
|
||||
);
|
||||
wintc_sh_view_fs_get_view_item(view_fs, item_hash);
|
||||
|
||||
if (!view_item)
|
||||
{
|
||||
@@ -953,6 +969,19 @@ static gboolean real_activate_item(
|
||||
return success;
|
||||
}
|
||||
|
||||
static WinTCShextViewItem* wintc_sh_view_fs_get_view_item(
|
||||
WinTCShViewFS* view_fs,
|
||||
guint item_hash
|
||||
)
|
||||
{
|
||||
return
|
||||
(WinTCShextViewItem*)
|
||||
g_hash_table_lookup(
|
||||
view_fs->fs_map_entries,
|
||||
GUINT_TO_POINTER(item_hash)
|
||||
);
|
||||
}
|
||||
|
||||
static void wintc_sh_view_fs_update_new_templates(
|
||||
WinTCShViewFS* view_fs
|
||||
)
|
||||
|
||||
@@ -44,6 +44,7 @@ add_library(
|
||||
public/if_view.h
|
||||
src/uictl.c
|
||||
public/uictl.h
|
||||
src/viewitem.c
|
||||
public/viewitem.h
|
||||
public/viewops.h
|
||||
)
|
||||
|
||||
@@ -42,6 +42,11 @@ struct _WinTCIShextViewInterface
|
||||
GError** error
|
||||
);
|
||||
|
||||
gint (*compare_items) (
|
||||
WinTCIShextView* view,
|
||||
guint item_hash1,
|
||||
guint item_hash2
|
||||
);
|
||||
const gchar* (*get_display_name) (
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -92,6 +97,11 @@ gboolean wintc_ishext_view_activate_item(
|
||||
GError** error
|
||||
);
|
||||
|
||||
gint wintc_ishext_view_compare_items(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash1,
|
||||
guint item_hash2
|
||||
);
|
||||
void wintc_ishext_view_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -145,6 +155,10 @@ void _wintc_ishext_view_refreshing(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
GCompareFunc wintc_ishext_view_get_sort_func(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
// WinTCShextPathInfo methods
|
||||
//
|
||||
void wintc_shext_path_info_demangle_uri(
|
||||
|
||||
@@ -33,4 +33,16 @@ typedef struct _WinTCShextViewItemsUpdate
|
||||
gboolean done;
|
||||
} WinTCShextViewItemsUpdate;
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
gint wintc_shext_view_item_compare_by_name(
|
||||
const WinTCShextViewItem* item1,
|
||||
const WinTCShextViewItem* item2
|
||||
);
|
||||
gint wintc_shext_view_item_compare_by_fs_order(
|
||||
const WinTCShextViewItem* item1,
|
||||
const WinTCShextViewItem* item2
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -107,6 +107,18 @@ gboolean wintc_ishext_view_activate_item(
|
||||
);
|
||||
}
|
||||
|
||||
gint wintc_ishext_view_compare_items(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash1,
|
||||
guint item_hash2
|
||||
)
|
||||
{
|
||||
WinTCIShextViewInterface* iface =
|
||||
WINTC_ISHEXT_VIEW_GET_IFACE(view);
|
||||
|
||||
return iface->compare_items(view, item_hash1, item_hash2);
|
||||
}
|
||||
|
||||
const gchar* wintc_ishext_view_get_display_name(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
@@ -258,6 +270,40 @@ void _wintc_ishext_view_refreshing(
|
||||
);
|
||||
}
|
||||
|
||||
// HACKY SORT FUNC
|
||||
static WinTCIShextView* S_CUR_VIEW_FOR_SORTING = NULL;
|
||||
|
||||
gint _wintc_ishext_view_sort_func(
|
||||
gconstpointer item_hash1,
|
||||
gconstpointer item_hash2
|
||||
)
|
||||
{
|
||||
if (!S_CUR_VIEW_FOR_SORTING)
|
||||
{
|
||||
g_critical("%s", "shellext: attempting to sort with no view!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return wintc_ishext_view_compare_items(
|
||||
S_CUR_VIEW_FOR_SORTING,
|
||||
GPOINTER_TO_UINT(item_hash1),
|
||||
GPOINTER_TO_UINT(item_hash2)
|
||||
);
|
||||
}
|
||||
|
||||
GCompareFunc wintc_ishext_view_get_sort_func(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
//
|
||||
// FIXME: This is NOT thread-safe!!
|
||||
//
|
||||
S_CUR_VIEW_FOR_SORTING = view;
|
||||
|
||||
return ((GCompareFunc) _wintc_ishext_view_sort_func);
|
||||
}
|
||||
// END HACKY SORT FUNC
|
||||
|
||||
void wintc_shext_path_info_demangle_uri(
|
||||
WinTCShextPathInfo* path_info,
|
||||
const gchar* uri
|
||||
|
||||
27
shared/shellext/src/viewitem.c
Normal file
27
shared/shellext/src/viewitem.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include <glib.h>
|
||||
|
||||
#include "../public/viewitem.h"
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
gint wintc_shext_view_item_compare_by_name(
|
||||
const WinTCShextViewItem* item1,
|
||||
const WinTCShextViewItem* item2
|
||||
)
|
||||
{
|
||||
return g_strcmp0(item1->display_name, item2->display_name);
|
||||
}
|
||||
|
||||
gint wintc_shext_view_item_compare_by_fs_order(
|
||||
const WinTCShextViewItem* item1,
|
||||
const WinTCShextViewItem* item2
|
||||
)
|
||||
{
|
||||
if (item1->is_leaf == item2->is_leaf)
|
||||
{
|
||||
return wintc_shext_view_item_compare_by_name(item1, item2);
|
||||
}
|
||||
|
||||
return item1->is_leaf ? 1 : -1;
|
||||
}
|
||||
@@ -55,6 +55,11 @@ static gboolean wintc_cpl_view_printers_activate_item(
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
static gint wintc_cpl_view_printers_compare_items(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash1,
|
||||
guint item_hash2
|
||||
);
|
||||
static const gchar* wintc_cpl_view_printers_get_display_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -153,6 +158,7 @@ static void wintc_cpl_view_printers_ishext_view_interface_init(
|
||||
)
|
||||
{
|
||||
iface->activate_item = wintc_cpl_view_printers_activate_item;
|
||||
iface->compare_items = wintc_cpl_view_printers_compare_items;
|
||||
iface->get_display_name = wintc_cpl_view_printers_get_display_name;
|
||||
iface->get_icon_name = wintc_cpl_view_printers_get_icon_name;
|
||||
iface->get_operations_for_item =
|
||||
@@ -208,6 +214,16 @@ static gboolean wintc_cpl_view_printers_activate_item(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gint wintc_cpl_view_printers_compare_items(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(guint item_hash1),
|
||||
WINTC_UNUSED(guint item_hash2)
|
||||
)
|
||||
{
|
||||
// FIXME: Proper implementation
|
||||
return -1;
|
||||
}
|
||||
|
||||
static GMenuModel* wintc_cpl_view_printers_get_operations_for_item(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(guint item_hash)
|
||||
|
||||
@@ -45,6 +45,11 @@ static gboolean wintc_view_zip_activate_item(
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
static gint wintc_view_zip_compare_items(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash1,
|
||||
guint item_hash2
|
||||
);
|
||||
static GMenuModel* wintc_view_zip_get_operations_for_item(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash
|
||||
@@ -76,6 +81,11 @@ static void wintc_view_zip_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
static WinTCShextViewItem* wintc_view_zip_get_view_item(
|
||||
WinTCViewZip* view_zip,
|
||||
guint item_hash
|
||||
);
|
||||
|
||||
static guint zip_entry_hash(
|
||||
const gchar* zip_file_path,
|
||||
const gchar* rel_entry_path
|
||||
@@ -173,6 +183,7 @@ static void wintc_view_zip_ishext_view_interface_init(
|
||||
)
|
||||
{
|
||||
iface->activate_item = wintc_view_zip_activate_item;
|
||||
iface->compare_items = wintc_view_zip_compare_items;
|
||||
iface->get_operations_for_item = wintc_view_zip_get_operations_for_item;
|
||||
iface->get_operations_for_view = wintc_view_zip_get_operations_for_view;
|
||||
iface->get_display_name = wintc_view_zip_get_display_name;
|
||||
@@ -272,11 +283,7 @@ static gboolean wintc_view_zip_activate_item(
|
||||
WINTC_SAFE_REF_CLEAR(error);
|
||||
|
||||
WinTCShextViewItem* item =
|
||||
(WinTCShextViewItem*)
|
||||
g_hash_table_lookup(
|
||||
view_zip->map_items,
|
||||
GUINT_TO_POINTER(item_hash)
|
||||
);
|
||||
wintc_view_zip_get_view_item(view_zip, item_hash);
|
||||
|
||||
if (!item)
|
||||
{
|
||||
@@ -312,6 +319,20 @@ static gboolean wintc_view_zip_activate_item(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gint wintc_view_zip_compare_items(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash1,
|
||||
guint item_hash2
|
||||
)
|
||||
{
|
||||
WinTCViewZip* view_zip = WINTC_VIEW_ZIP(view);
|
||||
|
||||
return wintc_shext_view_item_compare_by_fs_order(
|
||||
wintc_view_zip_get_view_item(view_zip, item_hash1),
|
||||
wintc_view_zip_get_view_item(view_zip, item_hash2)
|
||||
);
|
||||
}
|
||||
|
||||
static GMenuModel* wintc_view_zip_get_operations_for_item(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(guint item_hash)
|
||||
@@ -585,6 +606,19 @@ WinTCIShextView* wintc_view_zip_new(
|
||||
//
|
||||
// PRIVATE FUNCTIONS
|
||||
//
|
||||
static WinTCShextViewItem* wintc_view_zip_get_view_item(
|
||||
WinTCViewZip* view_zip,
|
||||
guint item_hash
|
||||
)
|
||||
{
|
||||
return
|
||||
(WinTCShextViewItem*)
|
||||
g_hash_table_lookup(
|
||||
view_zip->map_items,
|
||||
GUINT_TO_POINTER(item_hash)
|
||||
);
|
||||
}
|
||||
|
||||
static guint zip_entry_hash(
|
||||
const gchar* zip_file_path,
|
||||
const gchar* rel_entry_path
|
||||
|
||||
Reference in New Issue
Block a user