mirror of
https://github.com/rozniak/xfce-winxp-tc.git
synced 2026-01-26 11:39:44 +00:00
Enhancement: Fixes #376, explorer/shell - implement default tree view behaviour
This commit is contained in:
@@ -39,6 +39,7 @@ add_library(
|
||||
public/error.h
|
||||
src/icnvwbeh.c
|
||||
public/icnvwbeh.h
|
||||
src/trevwbeh.c
|
||||
public/trevwbeh.h
|
||||
src/nmspace.c
|
||||
public/nmspace.h
|
||||
|
||||
@@ -52,6 +52,10 @@ gboolean wintc_sh_browser_can_navigate_to_parent(
|
||||
WinTCShBrowser* browser
|
||||
);
|
||||
|
||||
WinTCIShextView* wintc_sh_browser_get_current_view(
|
||||
WinTCShBrowser* browser
|
||||
);
|
||||
|
||||
void wintc_sh_browser_get_location(
|
||||
WinTCShBrowser* browser,
|
||||
WinTCShextPathInfo* path_info
|
||||
@@ -61,6 +65,10 @@ GtkTreeModel* wintc_sh_browser_get_model(
|
||||
WinTCShBrowser* browser
|
||||
);
|
||||
|
||||
WinTCShextHost* wintc_sh_browser_get_shext_host(
|
||||
WinTCShBrowser* browser
|
||||
);
|
||||
|
||||
const gchar* wintc_sh_browser_get_view_display_name(
|
||||
WinTCShBrowser* browser
|
||||
);
|
||||
|
||||
@@ -27,7 +27,7 @@ GType wintc_sh_tree_view_behaviour_get_type(void) G_GNUC_CONST;
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
WinTCShTreeViewBehaviour* wintc_sh_tree_view_behaviour_new(
|
||||
GtkTreeView* icon_view,
|
||||
GtkTreeView* tree_view,
|
||||
WinTCShBrowser* browser
|
||||
);
|
||||
|
||||
|
||||
@@ -284,6 +284,13 @@ gboolean wintc_sh_browser_can_navigate_to_parent(
|
||||
return wintc_ishext_view_has_parent(browser->current_view);
|
||||
}
|
||||
|
||||
WinTCIShextView* wintc_sh_browser_get_current_view(
|
||||
WinTCShBrowser* browser
|
||||
)
|
||||
{
|
||||
return browser->current_view;
|
||||
}
|
||||
|
||||
void wintc_sh_browser_get_location(
|
||||
WinTCShBrowser* browser,
|
||||
WinTCShextPathInfo* path_info
|
||||
@@ -307,6 +314,13 @@ GtkTreeModel* wintc_sh_browser_get_model(
|
||||
return GTK_TREE_MODEL(browser->view_model);
|
||||
}
|
||||
|
||||
WinTCShextHost* wintc_sh_browser_get_shext_host(
|
||||
WinTCShBrowser* browser
|
||||
)
|
||||
{
|
||||
return browser->shext_host;
|
||||
}
|
||||
|
||||
const gchar* wintc_sh_browser_get_view_display_name(
|
||||
WinTCShBrowser* browser
|
||||
)
|
||||
|
||||
680
shared/shell/src/trevwbeh.c
Normal file
680
shared/shell/src/trevwbeh.c
Normal file
@@ -0,0 +1,680 @@
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <wintc/comgtk.h>
|
||||
|
||||
#include "../public/browser.h"
|
||||
#include "../public/trevwbeh.h"
|
||||
|
||||
//
|
||||
// PRIVATE ENUMS
|
||||
//
|
||||
enum
|
||||
{
|
||||
PROP_BROWSER = 1,
|
||||
PROP_TREE_VIEW
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
COL_ICON_NAME = 0,
|
||||
COL_ENTRY_NAME,
|
||||
COL_VIEW_HASH,
|
||||
NUM_COLS
|
||||
};
|
||||
|
||||
//
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
static void wintc_sh_tree_view_behaviour_constructed(
|
||||
GObject* object
|
||||
);
|
||||
static void wintc_sh_tree_view_behaviour_dispose(
|
||||
GObject* object
|
||||
);
|
||||
static void wintc_sh_tree_view_behaviour_set_property(
|
||||
GObject* object,
|
||||
guint prop_id,
|
||||
const GValue* value,
|
||||
GParamSpec* pspec
|
||||
);
|
||||
|
||||
static void on_browser_load_changed(
|
||||
WinTCShBrowser* self,
|
||||
WinTCShBrowserLoadEvent load_event,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
static void on_view_items_added(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextViewItemsAddedData* items_data,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
//
|
||||
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||
//
|
||||
struct _WinTCShTreeViewBehaviourClass
|
||||
{
|
||||
GObjectClass __parent__;
|
||||
};
|
||||
|
||||
struct _WinTCShTreeViewBehaviour
|
||||
{
|
||||
GObject __parent__;
|
||||
|
||||
WinTCShBrowser* browser;
|
||||
WinTCShextHost* shext_host;
|
||||
|
||||
GtkTreeStore* tree_model;
|
||||
GHashTable* map_iter_to_view;
|
||||
GHashTable* map_hash_to_iter;
|
||||
|
||||
GtkWidget* tree_view;
|
||||
};
|
||||
|
||||
//
|
||||
// GTK TYPE DEFINITIONS & CTORS
|
||||
//
|
||||
G_DEFINE_TYPE(
|
||||
WinTCShTreeViewBehaviour,
|
||||
wintc_sh_tree_view_behaviour,
|
||||
G_TYPE_OBJECT
|
||||
)
|
||||
|
||||
static void wintc_sh_tree_view_behaviour_class_init(
|
||||
WinTCShTreeViewBehaviourClass* klass
|
||||
)
|
||||
{
|
||||
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
object_class->constructed = wintc_sh_tree_view_behaviour_constructed;
|
||||
object_class->dispose = wintc_sh_tree_view_behaviour_dispose;
|
||||
object_class->set_property = wintc_sh_tree_view_behaviour_set_property;
|
||||
|
||||
g_object_class_install_property(
|
||||
object_class,
|
||||
PROP_BROWSER,
|
||||
g_param_spec_object(
|
||||
"browser",
|
||||
"Browser",
|
||||
"The shell browser instance to bind to.",
|
||||
WINTC_TYPE_SH_BROWSER,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
|
||||
)
|
||||
);
|
||||
g_object_class_install_property(
|
||||
object_class,
|
||||
PROP_TREE_VIEW,
|
||||
g_param_spec_object(
|
||||
"tree-view",
|
||||
"TreeView",
|
||||
"The tree view to manage.",
|
||||
GTK_TYPE_TREE_VIEW,
|
||||
G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
static void wintc_sh_tree_view_behaviour_init(
|
||||
WinTCShTreeViewBehaviour* self
|
||||
)
|
||||
{
|
||||
// Set up maps hash->iter->view
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// This is such that views can be essentially lazy-loaded - view items
|
||||
// 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,
|
||||
g_object_unref
|
||||
);
|
||||
self->map_hash_to_iter = g_hash_table_new_full(
|
||||
g_direct_hash,
|
||||
g_direct_equal,
|
||||
g_free,
|
||||
g_free
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// CLASS VIRTUAL METHODS
|
||||
//
|
||||
static void wintc_sh_tree_view_behaviour_constructed(
|
||||
GObject* object
|
||||
)
|
||||
{
|
||||
WinTCShTreeViewBehaviour* behaviour =
|
||||
WINTC_SH_TREE_VIEW_BEHAVIOUR(object);
|
||||
|
||||
if (!behaviour->browser || !behaviour->tree_view)
|
||||
{
|
||||
g_critical("%s", "ShTreeViewBehaviour: Must have a browser and view!");
|
||||
return;
|
||||
}
|
||||
|
||||
behaviour->shext_host =
|
||||
g_object_ref(wintc_sh_browser_get_shext_host(behaviour->browser));
|
||||
|
||||
// Clear out tree view in case for some reason there's already stuff in it
|
||||
//
|
||||
GList* columns = gtk_tree_view_get_columns(
|
||||
GTK_TREE_VIEW(behaviour->tree_view)
|
||||
);
|
||||
|
||||
for (GList* iter = columns; iter; iter = iter->next)
|
||||
{
|
||||
gtk_tree_view_remove_column(
|
||||
GTK_TREE_VIEW(behaviour->tree_view),
|
||||
GTK_TREE_VIEW_COLUMN(iter->data)
|
||||
);
|
||||
}
|
||||
|
||||
g_list_free(columns);
|
||||
|
||||
// Set up tree view
|
||||
//
|
||||
GtkTreeViewColumn* new_column;
|
||||
GtkCellRenderer* new_cell;
|
||||
|
||||
behaviour->tree_model =
|
||||
gtk_tree_store_new(
|
||||
3,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_STRING,
|
||||
G_TYPE_UINT
|
||||
);
|
||||
|
||||
gtk_tree_view_set_headers_visible(
|
||||
GTK_TREE_VIEW(behaviour->tree_view),
|
||||
FALSE
|
||||
);
|
||||
gtk_tree_view_set_model(
|
||||
GTK_TREE_VIEW(behaviour->tree_view),
|
||||
GTK_TREE_MODEL(behaviour->tree_model)
|
||||
);
|
||||
|
||||
new_column = gtk_tree_view_column_new();
|
||||
new_cell = gtk_cell_renderer_pixbuf_new();
|
||||
|
||||
gtk_tree_view_column_pack_start(new_column, new_cell, FALSE);
|
||||
gtk_tree_view_column_add_attribute(
|
||||
new_column,
|
||||
new_cell,
|
||||
"icon-name",
|
||||
COL_ICON_NAME
|
||||
);
|
||||
|
||||
new_cell = gtk_cell_renderer_text_new();
|
||||
|
||||
gtk_tree_view_column_pack_end(new_column, new_cell, TRUE);
|
||||
gtk_tree_view_column_add_attribute(
|
||||
new_column,
|
||||
new_cell,
|
||||
"text",
|
||||
COL_ENTRY_NAME
|
||||
);
|
||||
|
||||
gtk_tree_view_append_column(
|
||||
GTK_TREE_VIEW(behaviour->tree_view),
|
||||
new_column
|
||||
);
|
||||
|
||||
// TEST: Attachment to browser to monitor for view switches
|
||||
g_signal_connect(
|
||||
behaviour->browser,
|
||||
"load-changed",
|
||||
G_CALLBACK(on_browser_load_changed),
|
||||
behaviour
|
||||
);
|
||||
|
||||
(G_OBJECT_CLASS(wintc_sh_tree_view_behaviour_parent_class))
|
||||
->constructed(object);
|
||||
}
|
||||
|
||||
static void wintc_sh_tree_view_behaviour_dispose(
|
||||
GObject* object
|
||||
)
|
||||
{
|
||||
WinTCShTreeViewBehaviour* behaviour =
|
||||
WINTC_SH_TREE_VIEW_BEHAVIOUR(object);
|
||||
|
||||
g_clear_object(&(behaviour->browser));
|
||||
g_clear_object(&(behaviour->map_iter_to_view));
|
||||
g_clear_object(&(behaviour->map_hash_to_iter));
|
||||
g_clear_object(&(behaviour->shext_host));
|
||||
g_clear_object(&(behaviour->tree_view));
|
||||
|
||||
(G_OBJECT_CLASS(wintc_sh_tree_view_behaviour_parent_class))
|
||||
->dispose(object);
|
||||
}
|
||||
|
||||
static void wintc_sh_tree_view_behaviour_set_property(
|
||||
GObject* object,
|
||||
guint prop_id,
|
||||
const GValue* value,
|
||||
GParamSpec* pspec
|
||||
)
|
||||
{
|
||||
WinTCShTreeViewBehaviour* behaviour =
|
||||
WINTC_SH_TREE_VIEW_BEHAVIOUR(object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_BROWSER:
|
||||
behaviour->browser = g_value_dup_object(value);
|
||||
break;
|
||||
|
||||
case PROP_TREE_VIEW:
|
||||
behaviour->tree_view = g_value_dup_object(value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
WinTCShTreeViewBehaviour* wintc_sh_tree_view_behaviour_new(
|
||||
GtkTreeView* tree_view,
|
||||
WinTCShBrowser* browser
|
||||
)
|
||||
{
|
||||
return WINTC_SH_TREE_VIEW_BEHAVIOUR(
|
||||
g_object_new(
|
||||
WINTC_TYPE_SH_TREE_VIEW_BEHAVIOUR,
|
||||
"browser", browser,
|
||||
"tree-view", tree_view,
|
||||
NULL
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// CALLBACKS
|
||||
//
|
||||
static void on_browser_load_changed(
|
||||
WinTCShBrowser* self,
|
||||
WinTCShBrowserLoadEvent load_event,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCShTreeViewBehaviour* behaviour =
|
||||
WINTC_SH_TREE_VIEW_BEHAVIOUR(user_data);
|
||||
|
||||
WinTCIShextView* current_view = wintc_sh_browser_get_current_view(self);
|
||||
|
||||
if (!current_view || load_event != WINTC_SH_BROWSER_LOAD_STARTED)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
while (view)
|
||||
{
|
||||
// Collect this view
|
||||
//
|
||||
list_views = g_slist_append(list_views, view);
|
||||
|
||||
// If there is a node in the tree for the view hash, stop here
|
||||
//
|
||||
iter_path =
|
||||
g_hash_table_lookup(
|
||||
behaviour->map_hash_to_iter,
|
||||
GUINT_TO_POINTER(wintc_ishext_view_get_unique_hash(view))
|
||||
);
|
||||
|
||||
if (iter_path)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// See if there's a parent to step up to
|
||||
//
|
||||
if (wintc_ishext_view_has_parent(view))
|
||||
{
|
||||
wintc_ishext_view_get_parent_path(view, &path_info);
|
||||
|
||||
view =
|
||||
wintc_shext_host_get_view_for_path(
|
||||
behaviour->shext_host,
|
||||
&path_info,
|
||||
&error
|
||||
);
|
||||
|
||||
wintc_shext_path_info_free_data(&path_info);
|
||||
|
||||
if (!view)
|
||||
{
|
||||
wintc_log_error_and_clear(&error);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
view = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse list (bottom up) and append items in the tree
|
||||
//
|
||||
// NOTE ON REFERENCES:
|
||||
// Since the list contains the view owned by the browser as well as views
|
||||
// instantiated by this function, g_object_ref() needs to only be called on
|
||||
// the former (so only one ref is owned by the hash table and will get
|
||||
// binned during dispose())
|
||||
//
|
||||
guint hash;
|
||||
gboolean new_view;
|
||||
GtkTreeIter next;
|
||||
WinTCIShextView* next_view;
|
||||
GtkTreeIter last = { 0 };
|
||||
gboolean should_delete;
|
||||
|
||||
list_views = g_slist_reverse(list_views);
|
||||
|
||||
for (GSList* iter = list_views; iter; iter = iter->next)
|
||||
{
|
||||
view = WINTC_ISHEXT_VIEW(iter->data);
|
||||
|
||||
new_view = TRUE;
|
||||
should_delete = FALSE;
|
||||
|
||||
WINTC_LOG_DEBUG(
|
||||
"shell: tree - iterate view %s",
|
||||
wintc_ishext_view_get_display_name(view)
|
||||
);
|
||||
|
||||
// Special handling for the first item
|
||||
// - If there's no iter_path, then we need to create the root node
|
||||
// - If there is an iter path:
|
||||
// - If a node exists but no view, map the view
|
||||
// - If a node exists and already has a view, continue as usual
|
||||
// but do not add another signal to the view
|
||||
//
|
||||
// FOR YOUR INFORMATION:
|
||||
// The case where a node exists and already has a view can happen when:
|
||||
// - An already opened view is opened again (going up one parent)
|
||||
// - A leaf node has gained children (eg. ZIP files opened in the ZIP
|
||||
// shell extension
|
||||
//
|
||||
if (iter == list_views)
|
||||
{
|
||||
if (iter_path)
|
||||
{
|
||||
gtk_tree_model_get_iter_from_string(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&next,
|
||||
iter_path
|
||||
);
|
||||
|
||||
if (
|
||||
g_hash_table_contains(
|
||||
behaviour->map_iter_to_view,
|
||||
iter_path
|
||||
)
|
||||
)
|
||||
{
|
||||
WINTC_LOG_DEBUG(
|
||||
"shell: tree - first iter is a mapped view."
|
||||
);
|
||||
|
||||
// Opposite case here, because we are not mapping this
|
||||
// view, we need to make sure it gets binned if it is not
|
||||
// owned by the browser
|
||||
//
|
||||
// Of course, we can't bin it until we're done with it at
|
||||
// the end of the iteration
|
||||
//
|
||||
if (view != current_view)
|
||||
{
|
||||
should_delete = TRUE;
|
||||
}
|
||||
|
||||
new_view = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
WINTC_LOG_DEBUG(
|
||||
"shell: tree - first iter is a view item."
|
||||
);
|
||||
|
||||
if (view == current_view)
|
||||
{
|
||||
g_object_ref(view);
|
||||
}
|
||||
|
||||
g_hash_table_insert(
|
||||
behaviour->map_iter_to_view,
|
||||
g_strdup(iter_path),
|
||||
view
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WINTC_LOG_DEBUG("shell: tree - creating top level.");
|
||||
|
||||
hash = wintc_ishext_view_get_unique_hash(view);
|
||||
|
||||
// Create root node
|
||||
//
|
||||
gtk_tree_store_append(
|
||||
behaviour->tree_model,
|
||||
&next,
|
||||
NULL
|
||||
);
|
||||
gtk_tree_store_set(
|
||||
behaviour->tree_model,
|
||||
&next,
|
||||
COL_ICON_NAME, "inode-directory",
|
||||
COL_ENTRY_NAME, wintc_ishext_view_get_display_name(view),
|
||||
COL_VIEW_HASH, hash,
|
||||
-1
|
||||
);
|
||||
|
||||
// Map the hash<->iter
|
||||
//
|
||||
if (view == current_view)
|
||||
{
|
||||
g_object_ref(view);
|
||||
}
|
||||
|
||||
g_hash_table_insert(
|
||||
behaviour->map_hash_to_iter,
|
||||
GUINT_TO_POINTER(hash),
|
||||
gtk_tree_model_get_string_from_iter(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&next
|
||||
)
|
||||
);
|
||||
g_hash_table_insert(
|
||||
behaviour->map_iter_to_view,
|
||||
gtk_tree_model_get_string_from_iter(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&next
|
||||
),
|
||||
view
|
||||
);
|
||||
}
|
||||
|
||||
last = next; // Copy node iter over
|
||||
}
|
||||
|
||||
// If there's a descendant view below this one, create the node
|
||||
// immediately
|
||||
//
|
||||
if (iter->next)
|
||||
{
|
||||
next_view = WINTC_ISHEXT_VIEW(iter->next->data);
|
||||
|
||||
hash = wintc_ishext_view_get_unique_hash(next_view);
|
||||
|
||||
if (next_view == current_view)
|
||||
{
|
||||
g_object_ref(next_view);
|
||||
}
|
||||
|
||||
gtk_tree_store_append(
|
||||
behaviour->tree_model,
|
||||
&next,
|
||||
&last
|
||||
);
|
||||
gtk_tree_store_set(
|
||||
behaviour->tree_model,
|
||||
&next,
|
||||
COL_ICON_NAME, "inode-directory",
|
||||
COL_ENTRY_NAME, wintc_ishext_view_get_display_name(next_view),
|
||||
COL_VIEW_HASH, hash,
|
||||
-1
|
||||
);
|
||||
|
||||
g_hash_table_insert(
|
||||
behaviour->map_hash_to_iter,
|
||||
GUINT_TO_POINTER(hash),
|
||||
gtk_tree_model_get_string_from_iter(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&next
|
||||
)
|
||||
);
|
||||
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
|
||||
);
|
||||
}
|
||||
|
||||
// Watch for items and refresh if this is a new view
|
||||
//
|
||||
if (new_view)
|
||||
{
|
||||
g_signal_connect(
|
||||
view,
|
||||
"items-added",
|
||||
G_CALLBACK(on_view_items_added),
|
||||
behaviour
|
||||
);
|
||||
|
||||
wintc_ishext_view_refresh_items(view);
|
||||
}
|
||||
|
||||
// Delete the view if needed
|
||||
//
|
||||
if (should_delete)
|
||||
{
|
||||
g_object_unref(view);
|
||||
}
|
||||
|
||||
// Chain for next iteration
|
||||
//
|
||||
last = next;
|
||||
}
|
||||
|
||||
g_slist_free(list_views);
|
||||
}
|
||||
|
||||
static void on_view_items_added(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextViewItemsAddedData* items_data,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCShTreeViewBehaviour* behaviour =
|
||||
WINTC_SH_TREE_VIEW_BEHAVIOUR(user_data);
|
||||
|
||||
GtkTreeIter parent;
|
||||
GtkTreeIter child;
|
||||
|
||||
WINTC_LOG_DEBUG(
|
||||
"shell: tree - items added to %p",
|
||||
GUINT_TO_POINTER(wintc_ishext_view_get_unique_hash(view))
|
||||
);
|
||||
|
||||
// Locate the parent node
|
||||
//
|
||||
const gchar* iter_path =
|
||||
g_hash_table_lookup(
|
||||
behaviour->map_hash_to_iter,
|
||||
GUINT_TO_POINTER(wintc_ishext_view_get_unique_hash(view))
|
||||
);
|
||||
|
||||
if (
|
||||
!gtk_tree_model_get_iter_from_string(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&parent,
|
||||
iter_path
|
||||
)
|
||||
)
|
||||
{
|
||||
g_critical("shell: tree - somehow unable to find parent!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Iterate over the items to append to the tree
|
||||
//
|
||||
WinTCShextViewItem* view_item;
|
||||
|
||||
for (gint i = 0; i < items_data->num_items; i++)
|
||||
{
|
||||
view_item = &(items_data->items[i]);
|
||||
|
||||
// Skip leaf nodes and nodes that already exist
|
||||
//
|
||||
if (
|
||||
view_item->is_leaf ||
|
||||
g_hash_table_contains(
|
||||
behaviour->map_hash_to_iter,
|
||||
GUINT_TO_POINTER(view_item->hash)
|
||||
)
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
WINTC_LOG_DEBUG(
|
||||
"shell: tree adding item %p",
|
||||
GUINT_TO_POINTER(view_item->hash)
|
||||
);
|
||||
|
||||
gtk_tree_store_append(
|
||||
behaviour->tree_model,
|
||||
&child,
|
||||
&parent
|
||||
);
|
||||
gtk_tree_store_set(
|
||||
behaviour->tree_model,
|
||||
&child,
|
||||
COL_ICON_NAME, "inode-directory",
|
||||
COL_ENTRY_NAME, view_item->display_name,
|
||||
COL_VIEW_HASH, view_item->hash,
|
||||
-1
|
||||
);
|
||||
|
||||
g_hash_table_insert(
|
||||
behaviour->map_hash_to_iter,
|
||||
GUINT_TO_POINTER(view_item->hash),
|
||||
gtk_tree_model_get_string_from_iter(
|
||||
GTK_TREE_MODEL(behaviour->tree_model),
|
||||
&child
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -52,6 +52,10 @@ static void wintc_sh_view_cpl_get_path(
|
||||
WinTCShextPathInfo* path_info
|
||||
);
|
||||
|
||||
static guint wintc_sh_view_cpl_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
static gboolean wintc_sh_view_cpl_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -114,6 +118,7 @@ static void wintc_sh_view_cpl_ishext_view_interface_init(
|
||||
iface->get_display_name = wintc_sh_view_cpl_get_display_name;
|
||||
iface->get_parent_path = wintc_sh_view_cpl_get_parent_path;
|
||||
iface->get_path = wintc_sh_view_cpl_get_path;
|
||||
iface->get_unique_hash = wintc_sh_view_cpl_get_unique_hash;
|
||||
iface->has_parent = wintc_sh_view_cpl_has_parent;
|
||||
}
|
||||
|
||||
@@ -200,6 +205,7 @@ static void wintc_sh_view_cpl_refresh_items(
|
||||
applet->icon_name :
|
||||
"image-missing";
|
||||
view_item->is_leaf = wintc_sh_cpl_applet_is_executable(applet);
|
||||
view_item->hash = g_str_hash(applet->exec);
|
||||
view_item->priv = applet;
|
||||
|
||||
i++;
|
||||
@@ -266,6 +272,13 @@ static void wintc_sh_view_cpl_get_path(
|
||||
);
|
||||
}
|
||||
|
||||
static guint wintc_sh_view_cpl_get_unique_hash(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
return g_str_hash(wintc_sh_get_place_path(WINTC_SH_PLACE_CONTROLPANEL));
|
||||
}
|
||||
|
||||
static gboolean wintc_sh_view_cpl_has_parent(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
|
||||
@@ -17,24 +17,28 @@ static WinTCShextViewItem s_desktop_items[] = {
|
||||
"My Computer",
|
||||
"computer",
|
||||
FALSE,
|
||||
0,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"My Documents",
|
||||
"folder-documents",
|
||||
FALSE,
|
||||
0,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"My Network Places",
|
||||
"network-workgroup",
|
||||
FALSE,
|
||||
0,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"Recycle Bin",
|
||||
"user-trash",
|
||||
FALSE,
|
||||
0,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
@@ -80,6 +84,10 @@ static void wintc_sh_view_desktop_get_path(
|
||||
WinTCShextPathInfo* path_info
|
||||
);
|
||||
|
||||
static guint wintc_sh_view_desktop_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
static gboolean wintc_sh_view_desktop_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -118,6 +126,26 @@ static void wintc_sh_view_desktop_class_init(
|
||||
// whatever
|
||||
//
|
||||
s_desktop_items[0].priv = wintc_sh_path_for_guid(WINTC_SH_GUID_DRIVES);
|
||||
|
||||
// Assign hashes
|
||||
//
|
||||
for (gulong i = 0; i < G_N_ELEMENTS(s_desktop_items); i++)
|
||||
{
|
||||
// FIXME: Temporary hack until the implementations are finished
|
||||
//
|
||||
if (s_desktop_items[i].priv)
|
||||
{
|
||||
s_desktop_items[i].hash = g_str_hash(s_desktop_items[i].priv);
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar* temp = g_strdup_printf("desktop%d", g_random_int());
|
||||
|
||||
s_desktop_items[i].hash = g_str_hash(temp);
|
||||
|
||||
g_free(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void wintc_sh_view_desktop_init(
|
||||
@@ -135,6 +163,7 @@ static void wintc_sh_view_desktop_ishext_view_interface_init(
|
||||
iface->get_display_name = wintc_sh_view_desktop_get_display_name;
|
||||
iface->get_parent_path = wintc_sh_view_desktop_get_parent_path;
|
||||
iface->get_path = wintc_sh_view_desktop_get_path;
|
||||
iface->get_unique_hash = wintc_sh_view_desktop_get_unique_hash;
|
||||
iface->has_parent = wintc_sh_view_desktop_has_parent;
|
||||
}
|
||||
|
||||
@@ -220,6 +249,13 @@ static void wintc_sh_view_desktop_get_path(
|
||||
);
|
||||
}
|
||||
|
||||
static guint wintc_sh_view_desktop_get_unique_hash(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
return g_str_hash(wintc_sh_get_place_path(WINTC_SH_PLACE_DESKTOP));
|
||||
}
|
||||
|
||||
static gboolean wintc_sh_view_desktop_has_parent(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
// FIXME: Temporary - only item is the drive root atm
|
||||
//
|
||||
static WinTCShextViewItem s_temp_items[] = {
|
||||
{ "/", "drive-harddisk", FALSE, "file:///" },
|
||||
{ "Control Panel", "preferences-other", FALSE, NULL }
|
||||
{ "/", "drive-harddisk", FALSE, 0, "file:///" },
|
||||
{ "Control Panel", "preferences-other", FALSE, 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
@@ -57,6 +57,10 @@ static void wintc_sh_view_drives_get_path(
|
||||
WinTCShextPathInfo* path_info
|
||||
);
|
||||
|
||||
static guint wintc_sh_view_drives_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
static gboolean wintc_sh_view_drives_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -94,6 +98,11 @@ static void wintc_sh_view_drives_class_init(
|
||||
// TEMP: Assign CPL view path
|
||||
//
|
||||
s_temp_items[1].priv = wintc_sh_path_for_guid(WINTC_SH_GUID_CPL);
|
||||
|
||||
// TEMP: Assign hashes
|
||||
//
|
||||
s_temp_items[0].hash = g_str_hash("/");
|
||||
s_temp_items[1].hash = g_str_hash(s_temp_items[1].priv);
|
||||
}
|
||||
|
||||
static void wintc_sh_view_drives_init(
|
||||
@@ -111,6 +120,7 @@ static void wintc_sh_view_drives_ishext_view_interface_init(
|
||||
iface->get_display_name = wintc_sh_view_drives_get_display_name;
|
||||
iface->get_parent_path = wintc_sh_view_drives_get_parent_path;
|
||||
iface->get_path = wintc_sh_view_drives_get_path;
|
||||
iface->get_unique_hash = wintc_sh_view_drives_get_unique_hash;
|
||||
iface->has_parent = wintc_sh_view_drives_has_parent;
|
||||
}
|
||||
|
||||
@@ -197,6 +207,13 @@ static void wintc_sh_view_drives_get_path(
|
||||
);
|
||||
}
|
||||
|
||||
static guint wintc_sh_view_drives_get_unique_hash(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
return g_str_hash(wintc_sh_get_place_path(WINTC_SH_PLACE_DRIVES));
|
||||
}
|
||||
|
||||
static gboolean wintc_sh_view_drives_has_parent(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
|
||||
@@ -61,6 +61,10 @@ static void wintc_sh_view_fs_get_actions_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
static guint wintc_sh_view_fs_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
static const gchar* wintc_sh_view_fs_get_display_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -175,6 +179,7 @@ static void wintc_sh_view_fs_ishext_view_interface_init(
|
||||
iface->get_display_name = wintc_sh_view_fs_get_display_name;
|
||||
iface->get_parent_path = wintc_sh_view_fs_get_parent_path;
|
||||
iface->get_path = wintc_sh_view_fs_get_path;
|
||||
iface->get_unique_hash = wintc_sh_view_fs_get_unique_hash;
|
||||
iface->has_parent = wintc_sh_view_fs_has_parent;
|
||||
}
|
||||
|
||||
@@ -380,6 +385,7 @@ static void wintc_sh_view_fs_refresh_items(
|
||||
item->display_name = (gchar*) g_steal_pointer(&(iter->data));
|
||||
item->icon_name = is_dir ? "inode-directory" : "empty";
|
||||
item->is_leaf = !is_dir;
|
||||
item->hash = g_str_hash(entry_path);
|
||||
|
||||
g_free(entry_path);
|
||||
|
||||
@@ -469,6 +475,15 @@ static void wintc_sh_view_fs_get_path(
|
||||
g_strdup_printf("file://%s", view_fs->path);
|
||||
}
|
||||
|
||||
static guint wintc_sh_view_fs_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
|
||||
|
||||
return g_str_hash(view_fs->path);
|
||||
}
|
||||
|
||||
static gboolean wintc_sh_view_fs_has_parent(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
|
||||
@@ -60,6 +60,9 @@ struct _WinTCIShextViewInterface
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
);
|
||||
guint (*get_unique_hash) (
|
||||
WinTCIShextView* view
|
||||
);
|
||||
gboolean (*has_parent) (
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -102,6 +105,9 @@ void wintc_ishext_view_get_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
);
|
||||
guint wintc_ishext_view_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
gboolean wintc_ishext_view_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -130,4 +136,12 @@ void wintc_shext_path_info_move(
|
||||
WinTCShextPathInfo* src
|
||||
);
|
||||
|
||||
guint wintc_shext_path_info_hash(
|
||||
gconstpointer v
|
||||
);
|
||||
gboolean wintc_shext_path_info_equal(
|
||||
gconstpointer v1,
|
||||
gconstpointer v2
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -13,6 +13,7 @@ typedef struct _WinTCShextViewItem
|
||||
gchar* display_name;
|
||||
gchar* icon_name;
|
||||
gboolean is_leaf;
|
||||
guint hash;
|
||||
gpointer priv;
|
||||
} WinTCShextViewItem;
|
||||
|
||||
|
||||
@@ -136,6 +136,16 @@ void wintc_ishext_view_get_path(
|
||||
return iface->get_path(view, path_info);
|
||||
}
|
||||
|
||||
guint wintc_ishext_view_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WinTCIShextViewInterface* iface =
|
||||
WINTC_ISHEXT_VIEW_GET_IFACE(view);
|
||||
|
||||
return iface->get_unique_hash(view);
|
||||
}
|
||||
|
||||
gboolean wintc_ishext_view_has_parent(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
@@ -228,3 +238,37 @@ void wintc_shext_path_info_move(
|
||||
dst->base_path = g_steal_pointer(&(src->base_path));
|
||||
dst->extended_path = g_steal_pointer(&(src->extended_path));
|
||||
}
|
||||
|
||||
guint wintc_shext_path_info_hash(
|
||||
gconstpointer v
|
||||
)
|
||||
{
|
||||
const WinTCShextPathInfo* path_info = (WinTCShextPathInfo*) v;
|
||||
|
||||
// Not sure if this reduces the effectiveness of the hash... think it
|
||||
// should be okay?
|
||||
//
|
||||
guint hash1 = g_str_hash(
|
||||
path_info->base_path ?
|
||||
path_info->base_path : ""
|
||||
);
|
||||
guint hash2 = g_str_hash(
|
||||
path_info->extended_path ?
|
||||
path_info->extended_path : ""
|
||||
);
|
||||
|
||||
return hash1 * 33 + hash2;
|
||||
}
|
||||
|
||||
gboolean wintc_shext_path_info_equal(
|
||||
gconstpointer v1,
|
||||
gconstpointer v2
|
||||
)
|
||||
{
|
||||
const WinTCShextPathInfo* path_info1 = (WinTCShextPathInfo*) v1;
|
||||
const WinTCShextPathInfo* path_info2 = (WinTCShextPathInfo*) v2;
|
||||
|
||||
return
|
||||
g_strcmp0(path_info1->base_path, path_info2->base_path) == 0 &&
|
||||
g_strcmp0(path_info1->extended_path, path_info2->extended_path) == 0;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// FIXME: Temporary, until we display printers
|
||||
//
|
||||
static WinTCShextViewItem s_temp_items[] = {
|
||||
{ "FPO", "printer", TRUE, NULL }
|
||||
{ "FPO", "printer", TRUE, 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
@@ -57,6 +57,10 @@ static void wintc_cpl_view_printers_get_path(
|
||||
WinTCShextPathInfo* path_info
|
||||
);
|
||||
|
||||
static guint wintc_cpl_view_printers_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
static gboolean wintc_cpl_view_printers_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -89,7 +93,14 @@ G_DEFINE_TYPE_WITH_CODE(
|
||||
|
||||
static void wintc_cpl_view_printers_class_init(
|
||||
WINTC_UNUSED(WinTCCplViewPrintersClass* klass)
|
||||
) {}
|
||||
)
|
||||
{
|
||||
gchar* temp = g_strdup_printf("printers%d", g_random_int());
|
||||
|
||||
s_temp_items[0].hash = g_str_hash(temp);
|
||||
|
||||
g_free(temp);
|
||||
}
|
||||
|
||||
static void wintc_cpl_view_printers_init(
|
||||
WINTC_UNUSED(WinTCCplViewPrinters* self)
|
||||
@@ -106,6 +117,7 @@ static void wintc_cpl_view_printers_ishext_view_interface_init(
|
||||
iface->get_display_name = wintc_cpl_view_printers_get_display_name;
|
||||
iface->get_parent_path = wintc_cpl_view_printers_get_parent_path;
|
||||
iface->get_path = wintc_cpl_view_printers_get_path;
|
||||
iface->get_unique_hash = wintc_cpl_view_printers_get_unique_hash;
|
||||
iface->has_parent = wintc_cpl_view_printers_has_parent;
|
||||
}
|
||||
|
||||
@@ -188,6 +200,13 @@ static void wintc_cpl_view_printers_get_path(
|
||||
);
|
||||
}
|
||||
|
||||
static guint wintc_cpl_view_printers_get_unique_hash(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
return g_str_hash(wintc_sh_get_place_path(WINTC_SH_PLACE_PRINTERS));
|
||||
}
|
||||
|
||||
static gboolean wintc_cpl_view_printers_has_parent(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
|
||||
@@ -46,9 +46,17 @@
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkTreeView">
|
||||
<object class="GtkScrolledWindow">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
<property name="can-focus">True</property>
|
||||
<property name="shadow-type">in</property>
|
||||
|
||||
<child>
|
||||
<object class="GtkTreeView" id="tree-view">
|
||||
<property name="visible">True</property>
|
||||
<property name="can-focus">False</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <wintc/comgtk.h>
|
||||
#include <wintc/shell.h>
|
||||
|
||||
#include "../sidebar.h"
|
||||
#include "../window.h"
|
||||
@@ -10,6 +11,15 @@
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
static void wintc_exp_folders_sidebar_constructed(
|
||||
GObject* object
|
||||
);
|
||||
static void wintc_exp_folders_sidebar_dispose(
|
||||
GObject* object
|
||||
);
|
||||
|
||||
static void on_explorer_window_mode_changed(
|
||||
WinTCExplorerWindow* self,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
//
|
||||
@@ -23,6 +33,14 @@ struct _WinTCExpFoldersSidebarClass
|
||||
struct _WinTCExpFoldersSidebar
|
||||
{
|
||||
WinTCExplorerSidebar __parent__;
|
||||
|
||||
// Logic stuff
|
||||
//
|
||||
WinTCShTreeViewBehaviour* behaviour_tree;
|
||||
|
||||
// UI
|
||||
//
|
||||
GtkWidget* tree_view;
|
||||
};
|
||||
|
||||
//
|
||||
@@ -41,6 +59,7 @@ static void wintc_exp_folders_sidebar_class_init(
|
||||
GObjectClass* object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
object_class->constructed = wintc_exp_folders_sidebar_constructed;
|
||||
object_class->dispose = wintc_exp_folders_sidebar_dispose;
|
||||
}
|
||||
|
||||
static void wintc_exp_folders_sidebar_init(
|
||||
@@ -61,6 +80,13 @@ static void wintc_exp_folders_sidebar_init(
|
||||
)
|
||||
);
|
||||
|
||||
self->tree_view =
|
||||
GTK_WIDGET(
|
||||
g_object_ref(
|
||||
gtk_builder_get_object(builder, "tree-view")
|
||||
)
|
||||
);
|
||||
|
||||
g_object_unref(builder);
|
||||
}
|
||||
|
||||
@@ -68,8 +94,57 @@ static void wintc_exp_folders_sidebar_init(
|
||||
// CLASS VIRTUAL METHODS
|
||||
//
|
||||
static void wintc_exp_folders_sidebar_constructed(
|
||||
WINTC_UNUSED(GObject* object)
|
||||
) {}
|
||||
GObject* object
|
||||
)
|
||||
{
|
||||
WinTCExplorerSidebar* sidebar =
|
||||
WINTC_EXPLORER_SIDEBAR(object);
|
||||
WinTCExpFoldersSidebar* sidebar_folders =
|
||||
WINTC_EXP_FOLDERS_SIDEBAR(object);
|
||||
|
||||
// Potentially may need to delay loading the tree view behaviour depending
|
||||
// on the state of the explorer window
|
||||
//
|
||||
if (
|
||||
wintc_explorer_window_get_mode(
|
||||
WINTC_EXPLORER_WINDOW(sidebar->owner_explorer_wnd)
|
||||
) == WINTC_EXPLORER_WINDOW_MODE_LOCAL
|
||||
)
|
||||
{
|
||||
sidebar_folders->behaviour_tree =
|
||||
wintc_sh_tree_view_behaviour_new(
|
||||
GTK_TREE_VIEW(sidebar_folders->tree_view),
|
||||
wintc_explorer_window_get_browser(
|
||||
WINTC_EXPLORER_WINDOW(sidebar->owner_explorer_wnd)
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_signal_connect(
|
||||
sidebar->owner_explorer_wnd,
|
||||
"mode-changed",
|
||||
G_CALLBACK(on_explorer_window_mode_changed),
|
||||
object
|
||||
);
|
||||
}
|
||||
|
||||
(G_OBJECT_CLASS(wintc_exp_folders_sidebar_parent_class))
|
||||
->constructed(object);
|
||||
}
|
||||
|
||||
static void wintc_exp_folders_sidebar_dispose(
|
||||
GObject* object
|
||||
)
|
||||
{
|
||||
WinTCExpFoldersSidebar* sidebar_folders =
|
||||
WINTC_EXP_FOLDERS_SIDEBAR(object);
|
||||
|
||||
g_clear_object(&(sidebar_folders->behaviour_tree));
|
||||
|
||||
(G_OBJECT_CLASS(wintc_exp_folders_sidebar_parent_class))
|
||||
->dispose(object);
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
@@ -86,3 +161,34 @@ WinTCExplorerSidebar* wintc_exp_folders_sidebar_new(
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// CALLBACKS
|
||||
//
|
||||
static void on_explorer_window_mode_changed(
|
||||
WinTCExplorerWindow* self,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCExpFoldersSidebar* sidebar_folders =
|
||||
WINTC_EXP_FOLDERS_SIDEBAR(user_data);
|
||||
|
||||
if (sidebar_folders->behaviour_tree)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
wintc_explorer_window_get_mode(self) !=
|
||||
WINTC_EXPLORER_WINDOW_MODE_LOCAL
|
||||
)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sidebar_folders->behaviour_tree =
|
||||
wintc_sh_tree_view_behaviour_new(
|
||||
GTK_TREE_VIEW(sidebar_folders->tree_view),
|
||||
wintc_explorer_window_get_browser(self)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -39,10 +39,10 @@ enum
|
||||
static void wintc_explorer_window_constructed(
|
||||
GObject* object
|
||||
);
|
||||
static void wintc_explorer_window_finalize(
|
||||
static void wintc_explorer_window_dispose(
|
||||
GObject* object
|
||||
);
|
||||
static void wintc_explorer_window_dispose(
|
||||
static void wintc_explorer_window_finalize(
|
||||
GObject* object
|
||||
);
|
||||
static void wintc_explorer_window_set_property(
|
||||
@@ -473,6 +473,13 @@ GtkWidget* wintc_explorer_window_new(
|
||||
);
|
||||
}
|
||||
|
||||
WinTCShBrowser* wintc_explorer_window_get_browser(
|
||||
WinTCExplorerWindow* wnd
|
||||
)
|
||||
{
|
||||
return wnd->browser;
|
||||
}
|
||||
|
||||
void wintc_explorer_window_get_location(
|
||||
WinTCExplorerWindow* wnd,
|
||||
WinTCShextPathInfo* path_info
|
||||
@@ -521,8 +528,9 @@ static void do_navigation(
|
||||
const gchar* specified_path
|
||||
)
|
||||
{
|
||||
GError* error = NULL;
|
||||
const GRegex* regex_looks_webish = NULL;
|
||||
static GRegex* regex_looks_webish = NULL;
|
||||
|
||||
GError* error = NULL;
|
||||
|
||||
if (!regex_looks_webish)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <wintc/shell.h>
|
||||
#include <wintc/shellext.h>
|
||||
|
||||
#include "application.h"
|
||||
@@ -41,6 +42,9 @@ GtkWidget* wintc_explorer_window_new(
|
||||
const gchar* initial_path
|
||||
);
|
||||
|
||||
WinTCShBrowser* wintc_explorer_window_get_browser(
|
||||
WinTCExplorerWindow* wnd
|
||||
);
|
||||
void wintc_explorer_window_get_location(
|
||||
WinTCExplorerWindow* wnd,
|
||||
WinTCShextPathInfo* path_info
|
||||
|
||||
@@ -66,10 +66,18 @@ static void wintc_view_zip_get_path(
|
||||
WinTCShextPathInfo* path_info
|
||||
);
|
||||
|
||||
static guint wintc_view_zip_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
static gboolean wintc_view_zip_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
static guint zip_entry_hash(
|
||||
const gchar* zip_file_path,
|
||||
const gchar* rel_entry_path
|
||||
);
|
||||
static gboolean zip_entry_is_in_dir(
|
||||
const gchar* this_dir,
|
||||
const gchar* entry,
|
||||
@@ -169,6 +177,7 @@ static void wintc_view_zip_ishext_view_interface_init(
|
||||
iface->get_display_name = wintc_view_zip_get_display_name;
|
||||
iface->get_parent_path = wintc_view_zip_get_parent_path;
|
||||
iface->get_path = wintc_view_zip_get_path;
|
||||
iface->get_unique_hash = wintc_view_zip_get_unique_hash;
|
||||
iface->has_parent = wintc_view_zip_has_parent;
|
||||
}
|
||||
|
||||
@@ -323,8 +332,9 @@ static void wintc_view_zip_refresh_items(
|
||||
);
|
||||
|
||||
item->display_name = entry_copy + name_offset;
|
||||
item->icon_name = g_str_has_suffix(entry_name, G_DIR_SEPARATOR_S) ?
|
||||
"inode-directory" : "empty";
|
||||
item->is_leaf = !g_str_has_suffix(entry_name, G_DIR_SEPARATOR_S);
|
||||
item->icon_name = item->is_leaf ? "empty" : "inode-directory";
|
||||
item->hash = zip_entry_hash(path, entry_name);
|
||||
item->priv = entry_copy;
|
||||
|
||||
n_local_entries++;
|
||||
@@ -474,6 +484,19 @@ static void wintc_view_zip_get_path(
|
||||
path_info->extended_path = g_strdup(view_zip->rel_path);
|
||||
}
|
||||
|
||||
static guint wintc_view_zip_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WinTCViewZip* view_zip = WINTC_VIEW_ZIP(view);
|
||||
|
||||
return
|
||||
zip_entry_hash(
|
||||
(view_zip->zip_uri + strlen("file://")),
|
||||
view_zip->rel_path
|
||||
);
|
||||
}
|
||||
|
||||
static gboolean wintc_view_zip_has_parent(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
@@ -502,6 +525,21 @@ WinTCIShextView* wintc_view_zip_new(
|
||||
//
|
||||
// PRIVATE FUNCTIONS
|
||||
//
|
||||
static guint zip_entry_hash(
|
||||
const gchar* zip_file_path,
|
||||
const gchar* rel_entry_path
|
||||
)
|
||||
{
|
||||
guint hash = g_str_hash(zip_file_path);
|
||||
|
||||
if (rel_entry_path)
|
||||
{
|
||||
hash = hash * 33 + g_str_hash(rel_entry_path);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static gboolean zip_entry_is_in_dir(
|
||||
const gchar* this_dir,
|
||||
const gchar* entry,
|
||||
|
||||
@@ -14,7 +14,7 @@ gtk3-->rt-->gtk3
|
||||
lightdm-->bt-->lightdm-gobject-devel
|
||||
lightdm-->rt-->lightdm-gobject
|
||||
msgfmt-->bt,rt-->gettext
|
||||
networkmanager-->bt-->NetworkManager-libnm
|
||||
networkmanager-->bt-->NetworkManager-libnm-devel
|
||||
networkmanager-->rt-->NetworkManager
|
||||
plymouth-->bt,rt-->plymouth
|
||||
pulseaudio-->bt-->pulseaudio-libs-devel
|
||||
|
||||
Reference in New Issue
Block a user