mirror of
https://github.com/rozniak/xfce-winxp-tc.git
synced 2026-01-26 11:39:44 +00:00
Enhancement: Fixes #385, shell/shellext - implement operations on views
This commit is contained in:
@@ -24,6 +24,7 @@ include(../../packaging/cmake-inc/libraries/CMakeLists.txt)
|
||||
include(../../packaging/cmake-inc/linking/CMakeLists.txt)
|
||||
include(../../packaging/cmake-inc/packaging/CMakeLists.txt)
|
||||
|
||||
wintc_resolve_library(gio-2.0 GIO)
|
||||
wintc_resolve_library(glib-2.0 GLIB)
|
||||
wintc_resolve_library(gtk+-3.0 GTK3)
|
||||
|
||||
@@ -50,6 +51,8 @@ add_library(
|
||||
public/marshal.h
|
||||
src/memory.c
|
||||
public/memory.h
|
||||
src/menu.c
|
||||
public/menu.h
|
||||
src/msgbox.c
|
||||
public/msgbox.h
|
||||
src/profile.c
|
||||
@@ -85,18 +88,21 @@ target_include_directories(
|
||||
libwintc-comgtk
|
||||
SYSTEM
|
||||
BEFORE
|
||||
PRIVATE ${GIO_INCLUDE_DIRS}
|
||||
PRIVATE ${GLIB_INCLUDE_DIRS}
|
||||
PRIVATE ${GTK3_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_directories(
|
||||
libwintc-comgtk
|
||||
PRIVATE ${GIO_LIBRARY_DIRS}
|
||||
PRIVATE ${GLIB_LIBRARY_DIRS}
|
||||
PRIVATE ${GTK3_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
libwintc-comgtk
|
||||
PRIVATE ${GIO_LIBRARIES}
|
||||
PRIVATE ${GLIB_LIBRARIES}
|
||||
PRIVATE ${GTK3_LIBRARIES}
|
||||
)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "@LIB_HEADER_DIR@/list.h"
|
||||
#include "@LIB_HEADER_DIR@/marshal.h"
|
||||
#include "@LIB_HEADER_DIR@/memory.h"
|
||||
#include "@LIB_HEADER_DIR@/menu.h"
|
||||
#include "@LIB_HEADER_DIR@/msgbox.h"
|
||||
#include "@LIB_HEADER_DIR@/profile.h"
|
||||
#include "@LIB_HEADER_DIR@/regex.h"
|
||||
|
||||
25
shared/comgtk/public/menu.h
Normal file
25
shared/comgtk/public/menu.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/** @file */
|
||||
|
||||
#ifndef __COMGTK_MENU_H__
|
||||
#define __COMGTK_MENU_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <glib.h>
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
|
||||
/**
|
||||
* Merges multiple menu models to create a new one.
|
||||
*
|
||||
* @param menu1 The first menu.
|
||||
* @param ... The other menus to merge, followed by NULL.
|
||||
* @return A new menu, created by merging the provided ones.
|
||||
*/
|
||||
GMenuModel* wintc_menu_model_merge(
|
||||
GMenuModel* menu1,
|
||||
...
|
||||
);
|
||||
|
||||
#endif
|
||||
71
shared/comgtk/src/menu.c
Normal file
71
shared/comgtk/src/menu.c
Normal file
@@ -0,0 +1,71 @@
|
||||
#include <gio/gio.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "../public/menu.h"
|
||||
|
||||
//
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
static void menu_merge_model(
|
||||
GMenu* menu,
|
||||
GMenuModel* menu_model
|
||||
);
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
GMenuModel* wintc_menu_model_merge(
|
||||
GMenuModel* menu1,
|
||||
...
|
||||
)
|
||||
{
|
||||
GMenu* menu = g_menu_new();
|
||||
|
||||
menu_merge_model(menu, menu1);
|
||||
|
||||
// Iterate over models
|
||||
//
|
||||
va_list ap;
|
||||
GMenuModel* next_model;
|
||||
|
||||
va_start(ap, menu1);
|
||||
|
||||
next_model = va_arg(ap, GMenuModel*);
|
||||
|
||||
while (next_model)
|
||||
{
|
||||
menu_merge_model(menu, next_model);
|
||||
|
||||
next_model = va_arg(ap, GMenuModel*);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
|
||||
return G_MENU_MODEL(menu);
|
||||
}
|
||||
|
||||
//
|
||||
// PRIVATE FUNCTIONS
|
||||
//
|
||||
static void menu_merge_model(
|
||||
GMenu* menu,
|
||||
GMenuModel* menu_model
|
||||
)
|
||||
{
|
||||
// This seems really dumb... but in order to merge menus you essentially
|
||||
// have to copy TWICE - first to copy out into a new item, then copy that
|
||||
// item into the target menu
|
||||
//
|
||||
// I would've thought there be a better way, but I am not sure there is
|
||||
//
|
||||
gint n_items = g_menu_model_get_n_items(menu_model);
|
||||
|
||||
for (gint i = 0; i < n_items; i++)
|
||||
{
|
||||
GMenuItem* menu_item = g_menu_item_new_from_model(menu_model, i);
|
||||
|
||||
g_menu_append_item(menu, menu_item);
|
||||
|
||||
g_object_unref(menu_item);
|
||||
}
|
||||
}
|
||||
@@ -90,6 +90,10 @@ gboolean wintc_launch_command(
|
||||
if (error != NULL)
|
||||
{
|
||||
g_propagate_error(out_error, error);
|
||||
|
||||
g_free(real_cmdline);
|
||||
g_free(tmp_cmdline);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -188,8 +192,10 @@ static gboolean parse_file_in_cmdline(
|
||||
{
|
||||
g_propagate_error(out_error, error);
|
||||
}
|
||||
|
||||
g_clear_error(&error);
|
||||
else
|
||||
{
|
||||
g_clear_error(&error);
|
||||
}
|
||||
|
||||
WINTC_SAFE_REF_SET(out_cmdline, g_strdup(cmdline));
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@ wintc_resolve_library(wintc-comgtk WINTC_COMGTK)
|
||||
wintc_resolve_library(wintc-exec WINTC_EXEC)
|
||||
wintc_resolve_library(wintc-shcommon WINTC_SHCOMMON)
|
||||
wintc_resolve_library(wintc-shellext WINTC_SHELLEXT)
|
||||
wintc_resolve_library(wintc-shlang WINTC_SHLANG)
|
||||
|
||||
wintc_compile_resources()
|
||||
|
||||
add_library(
|
||||
libwintc-shell
|
||||
@@ -39,6 +42,7 @@ add_library(
|
||||
public/error.h
|
||||
src/icnvwbeh.c
|
||||
public/icnvwbeh.h
|
||||
src/resources.c
|
||||
src/trevwbeh.c
|
||||
public/trevwbeh.h
|
||||
src/nmspace.c
|
||||
@@ -76,6 +80,7 @@ target_include_directories(
|
||||
PRIVATE ${WINTC_EXEC_INCLUDE_DIRS}
|
||||
PRIVATE ${WINTC_SHCOMMON_INCLUDE_DIRS}
|
||||
PRIVATE ${WINTC_SHELLEXT_INCLUDE_DIRS}
|
||||
PRIVATE ${WINTC_SHLANG_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_directories(
|
||||
@@ -87,6 +92,7 @@ target_link_directories(
|
||||
PRIVATE ${WINTC_EXEC_LIBRARY_DIRS}
|
||||
PRIVATE ${WINTC_SHCOMMON_LIBRARY_DIRS}
|
||||
PRIVATE ${WINTC_SHELLEXT_LIBRARY_DIRS}
|
||||
PRIVATE ${WINTC_SHLANG_LIBRARY_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
@@ -98,6 +104,7 @@ target_link_libraries(
|
||||
PRIVATE ${WINTC_EXEC_LIBRARIES}
|
||||
PRIVATE ${WINTC_SHCOMMON_LIBRARIES}
|
||||
PRIVATE ${WINTC_SHELLEXT_LIBRARIES}
|
||||
PRIVATE ${WINTC_SHLANG_LIBRARIES}
|
||||
)
|
||||
|
||||
# Installation
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <glib.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <wintc/comgtk.h>
|
||||
#include <wintc/shlang.h>
|
||||
|
||||
#include "../public/browser.h"
|
||||
#include "../public/icnvwbeh.h"
|
||||
@@ -30,12 +31,38 @@ static void wintc_sh_icon_view_behaviour_set_property(
|
||||
GParamSpec* pspec
|
||||
);
|
||||
|
||||
static void action_view_operation(
|
||||
GSimpleAction* action,
|
||||
GVariant* parameter,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
static gboolean on_icon_view_button_press_event(
|
||||
GtkIconView* self,
|
||||
GdkEventButton* event,
|
||||
gpointer user_data
|
||||
);
|
||||
static void on_icon_view_item_activated(
|
||||
GtkIconView* self,
|
||||
GtkTreePath* path,
|
||||
gpointer user_data
|
||||
);
|
||||
|
||||
//
|
||||
// STATIC DATA
|
||||
//
|
||||
static GSimpleAction* s_action_noop = NULL;
|
||||
|
||||
static GActionEntry s_actions[] = {
|
||||
{
|
||||
.name = "view-op",
|
||||
.activate = action_view_operation,
|
||||
.parameter_type = "i",
|
||||
.state = NULL,
|
||||
.change_state = NULL
|
||||
}
|
||||
};
|
||||
|
||||
//
|
||||
// GTK OOP CLASS/INSTANCE DEFINITIONS
|
||||
//
|
||||
@@ -115,6 +142,40 @@ static void wintc_sh_icon_view_behaviour_constructed(
|
||||
return;
|
||||
}
|
||||
|
||||
// Define GActions
|
||||
//
|
||||
GSimpleActionGroup* action_group = g_simple_action_group_new();
|
||||
|
||||
if (!s_action_noop)
|
||||
{
|
||||
s_action_noop =
|
||||
g_simple_action_new("no-op", NULL);
|
||||
|
||||
g_simple_action_set_enabled(
|
||||
s_action_noop,
|
||||
FALSE
|
||||
);
|
||||
}
|
||||
|
||||
g_action_map_add_action_entries(
|
||||
G_ACTION_MAP(action_group),
|
||||
s_actions,
|
||||
G_N_ELEMENTS(s_actions),
|
||||
behaviour
|
||||
);
|
||||
g_action_map_add_action(
|
||||
G_ACTION_MAP(action_group),
|
||||
G_ACTION(s_action_noop)
|
||||
);
|
||||
|
||||
gtk_widget_insert_action_group(
|
||||
behaviour->icon_view,
|
||||
"control",
|
||||
G_ACTION_GROUP(action_group)
|
||||
);
|
||||
|
||||
g_object_unref(action_group);
|
||||
|
||||
// Attach stuff to view
|
||||
//
|
||||
gtk_icon_view_set_model(
|
||||
@@ -130,8 +191,19 @@ static void wintc_sh_icon_view_behaviour_constructed(
|
||||
1
|
||||
);
|
||||
|
||||
gtk_icon_view_set_selection_mode(
|
||||
GTK_ICON_VIEW(behaviour->icon_view),
|
||||
GTK_SELECTION_MULTIPLE
|
||||
);
|
||||
|
||||
// Attach signals
|
||||
//
|
||||
g_signal_connect(
|
||||
behaviour->icon_view,
|
||||
"button-press-event",
|
||||
G_CALLBACK(on_icon_view_button_press_event),
|
||||
behaviour
|
||||
);
|
||||
g_signal_connect(
|
||||
behaviour->icon_view,
|
||||
"item-activated",
|
||||
@@ -150,6 +222,13 @@ static void wintc_sh_icon_view_behaviour_dispose(
|
||||
WinTCShIconViewBehaviour* behaviour =
|
||||
WINTC_SH_ICON_VIEW_BEHAVIOUR(object);
|
||||
|
||||
// Cheeky? Deselect items from the icon view, otherwise it might throw
|
||||
// GTK-Critical errors during destruction (?)
|
||||
//
|
||||
gtk_icon_view_unselect_all(
|
||||
GTK_ICON_VIEW(behaviour->icon_view)
|
||||
);
|
||||
|
||||
g_clear_object(&(behaviour->browser));
|
||||
g_clear_object(&(behaviour->icon_view));
|
||||
|
||||
@@ -204,6 +283,266 @@ WinTCShIconViewBehaviour* wintc_sh_icon_view_behaviour_new(
|
||||
//
|
||||
// CALLBACKS
|
||||
//
|
||||
static void action_view_operation(
|
||||
WINTC_UNUSED(GSimpleAction* action),
|
||||
GVariant* parameter,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCShIconViewBehaviour* behaviour =
|
||||
WINTC_SH_ICON_VIEW_BEHAVIOUR(user_data);
|
||||
|
||||
WINTC_LOG_DEBUG("op selected: %d", g_variant_get_int32(parameter));
|
||||
|
||||
// Prepare items - need to convert the selected items to their hashes
|
||||
//
|
||||
GList* item_hashes = NULL;
|
||||
GtkTreeModel* model = gtk_icon_view_get_model(
|
||||
GTK_ICON_VIEW(behaviour->icon_view)
|
||||
);
|
||||
GList* selected_items = gtk_icon_view_get_selected_items(
|
||||
GTK_ICON_VIEW(behaviour->icon_view)
|
||||
);
|
||||
GtkTreeIter tree_iter;
|
||||
|
||||
for (GList* iter = selected_items; iter; iter = iter->next)
|
||||
{
|
||||
guint hash;
|
||||
|
||||
gtk_tree_model_get_iter(
|
||||
model,
|
||||
&tree_iter,
|
||||
(GtkTreePath*) iter->data
|
||||
);
|
||||
|
||||
gtk_tree_model_get(
|
||||
model,
|
||||
&tree_iter,
|
||||
2, &hash,
|
||||
-1
|
||||
);
|
||||
|
||||
WINTC_LOG_DEBUG("shell: icnvw - append item to op: %u", hash);
|
||||
|
||||
item_hashes =
|
||||
g_list_prepend(
|
||||
item_hashes,
|
||||
GUINT_TO_POINTER(hash)
|
||||
);
|
||||
}
|
||||
|
||||
item_hashes = g_list_reverse(item_hashes);
|
||||
|
||||
g_list_free_full(
|
||||
selected_items,
|
||||
(GDestroyNotify) gtk_tree_path_free
|
||||
);
|
||||
|
||||
// Ask the view to spawn the operation
|
||||
//
|
||||
GError* error = NULL;
|
||||
WinTCShextOperation* operation;
|
||||
gint operation_id = g_variant_get_int32(parameter);
|
||||
WinTCIShextView* view = wintc_sh_browser_get_current_view(
|
||||
behaviour->browser
|
||||
);
|
||||
|
||||
operation =
|
||||
wintc_ishext_view_spawn_operation(
|
||||
view,
|
||||
operation_id,
|
||||
item_hashes, // Ownership transferred
|
||||
&error
|
||||
);
|
||||
|
||||
// g_list_free(item_hashes);
|
||||
|
||||
if (!operation)
|
||||
{
|
||||
wintc_display_error_and_clear(&error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Execute!
|
||||
//
|
||||
GtkWidget* toplevel = gtk_widget_get_toplevel(behaviour->icon_view);
|
||||
GtkWindow* wnd = NULL;
|
||||
|
||||
if (GTK_IS_WINDOW(toplevel))
|
||||
{
|
||||
wnd = GTK_WINDOW(toplevel);
|
||||
}
|
||||
|
||||
if (!(operation->func) (view, operation, wnd, &error))
|
||||
{
|
||||
wintc_display_error_and_clear(&error);
|
||||
}
|
||||
|
||||
g_free(operation);
|
||||
}
|
||||
|
||||
static gboolean on_icon_view_button_press_event(
|
||||
GtkIconView* self,
|
||||
GdkEventButton* event,
|
||||
gpointer user_data
|
||||
)
|
||||
{
|
||||
WinTCShIconViewBehaviour* behaviour =
|
||||
WINTC_SH_ICON_VIEW_BEHAVIOUR(user_data);
|
||||
|
||||
if (event->button == GDK_BUTTON_SECONDARY)
|
||||
{
|
||||
// We need to update the hit test target ourselves, since this signal
|
||||
// always runs before the icon view handles clicks
|
||||
//
|
||||
gboolean found = FALSE;
|
||||
GList* selected_items = gtk_icon_view_get_selected_items(self);
|
||||
GtkTreePath* target_item = gtk_icon_view_get_path_at_pos(
|
||||
self,
|
||||
event->x,
|
||||
event->y
|
||||
);
|
||||
|
||||
if (target_item)
|
||||
{
|
||||
// See if the item is in the selected items, otherwise we must
|
||||
// select this one
|
||||
//
|
||||
for (GList* iter = selected_items; iter; iter = iter->next)
|
||||
{
|
||||
GtkTreePath* check_item = (GtkTreePath*) iter->data;
|
||||
|
||||
if (gtk_tree_path_compare(target_item, check_item) == 0)
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
gtk_icon_view_unselect_all(self);
|
||||
gtk_icon_view_select_path(self, target_item);
|
||||
}
|
||||
}
|
||||
|
||||
g_list_free_full(
|
||||
selected_items,
|
||||
(GDestroyNotify) gtk_tree_path_free
|
||||
);
|
||||
|
||||
// Determine the target...
|
||||
// the view itself?
|
||||
// single view item?
|
||||
// multiple view items?
|
||||
//
|
||||
GtkWidget* menu = NULL;
|
||||
GMenuModel* menu_model = NULL;
|
||||
|
||||
if (!target_item) // The view itself
|
||||
{
|
||||
menu_model =
|
||||
wintc_ishext_view_get_operations_for_view(
|
||||
wintc_sh_browser_get_current_view(
|
||||
behaviour->browser
|
||||
)
|
||||
);
|
||||
|
||||
if (menu_model)
|
||||
{
|
||||
// We merge the common context menu with this one
|
||||
//
|
||||
GtkBuilder* builder;
|
||||
GMenuModel* menu_model_cmn;
|
||||
GMenuModel* menu_model_merged;
|
||||
|
||||
builder =
|
||||
gtk_builder_new_from_resource(
|
||||
"/uk/oddmatics/wintc/shell/menuctx.ui"
|
||||
);
|
||||
|
||||
wintc_lc_builder_preprocess_widget_text(builder);
|
||||
|
||||
menu_model_cmn =
|
||||
G_MENU_MODEL(
|
||||
g_object_ref(
|
||||
gtk_builder_get_object(builder, "menu")
|
||||
)
|
||||
);
|
||||
|
||||
menu_model_merged =
|
||||
wintc_menu_model_merge(
|
||||
menu_model_cmn,
|
||||
menu_model,
|
||||
NULL
|
||||
);
|
||||
|
||||
// Now create the actual popup menu
|
||||
//
|
||||
menu = gtk_menu_new_from_model(menu_model_merged);
|
||||
|
||||
g_object_unref(builder);
|
||||
g_object_unref(menu_model);
|
||||
g_object_unref(menu_model_cmn);
|
||||
}
|
||||
}
|
||||
else // Item(s)
|
||||
{
|
||||
// Always use the menu for the target item, nothing fancy required
|
||||
//
|
||||
guint item_hash;
|
||||
GtkTreeIter iter;
|
||||
GtkTreeModel* model = gtk_icon_view_get_model(self);
|
||||
|
||||
gtk_tree_model_get_iter(
|
||||
model,
|
||||
&iter,
|
||||
target_item
|
||||
);
|
||||
|
||||
gtk_tree_model_get(
|
||||
model,
|
||||
&iter,
|
||||
2, &item_hash,
|
||||
-1
|
||||
);
|
||||
|
||||
menu_model =
|
||||
wintc_ishext_view_get_operations_for_item(
|
||||
wintc_sh_browser_get_current_view(behaviour->browser),
|
||||
item_hash
|
||||
);
|
||||
|
||||
if (menu_model)
|
||||
{
|
||||
menu = gtk_menu_new_from_model(menu_model);
|
||||
|
||||
g_object_unref(menu_model);
|
||||
}
|
||||
|
||||
gtk_tree_path_free(target_item);
|
||||
}
|
||||
|
||||
if (menu)
|
||||
{
|
||||
gtk_menu_attach_to_widget(
|
||||
GTK_MENU(menu),
|
||||
behaviour->icon_view,
|
||||
NULL
|
||||
);
|
||||
|
||||
gtk_menu_popup_at_pointer(
|
||||
GTK_MENU(menu),
|
||||
(GdkEvent*) event
|
||||
);
|
||||
}
|
||||
|
||||
return GDK_EVENT_STOP;
|
||||
}
|
||||
|
||||
return GDK_EVENT_PROPAGATE;
|
||||
}
|
||||
|
||||
static void on_icon_view_item_activated(
|
||||
GtkIconView* self,
|
||||
GtkTreePath* path,
|
||||
|
||||
18
shared/shell/src/res/menuctx.ui
Normal file
18
shared/shell/src/res/menuctx.ui
Normal file
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label">View</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="label">Arrange Icons By</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="label">Refresh</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
||||
33
shared/shell/src/res/menufs.ui
Normal file
33
shared/shell/src/res/menufs.ui
Normal file
@@ -0,0 +1,33 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Customize This Folder...</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Paste</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Paste Shortcut</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">New</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Properties</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
||||
52
shared/shell/src/res/menufslf.ui
Normal file
52
shared/shell/src/res/menufslf.ui
Normal file
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.view-op</attribute>
|
||||
<attribute name="label">Open</attribute>
|
||||
<attribute name="target" type="i">1</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Open With</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Send To</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Cut</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Copy</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Create Shortcut</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Delete</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Rename</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Properties</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
||||
62
shared/shell/src/res/menufsvw.ui
Normal file
62
shared/shell/src/res/menufsvw.ui
Normal file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<interface>
|
||||
<menu id="menu">
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.view-op</attribute>
|
||||
<attribute name="label">Open</attribute>
|
||||
<attribute name="target" type="i">1</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Explore</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Search</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Sharing and Security...</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Send To</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Cut</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Copy</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Create Shortcut</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Delete</attribute>
|
||||
</item>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Rename</attribute>
|
||||
</item>
|
||||
</section>
|
||||
<section>
|
||||
<item>
|
||||
<attribute name="action">control.no-op</attribute>
|
||||
<attribute name="label">Properties</attribute>
|
||||
</item>
|
||||
</section>
|
||||
</menu>
|
||||
</interface>
|
||||
10
shared/shell/src/res/resources.xml
Normal file
10
shared/shell/src/res/resources.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<gresources>
|
||||
<gresource prefix="/uk/oddmatics/wintc/shell">
|
||||
<!-- MENUS -->
|
||||
<file>menuctx.ui</file>
|
||||
<file>menufs.ui</file>
|
||||
<file>menufslf.ui</file>
|
||||
<file>menufsvw.ui</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
@@ -38,22 +38,19 @@ static gboolean wintc_sh_view_cpl_activate_item(
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
static void wintc_sh_view_cpl_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_sh_view_cpl_get_actions_for_item(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextViewItem* item
|
||||
);
|
||||
static void wintc_sh_view_cpl_get_actions_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static const gchar* wintc_sh_view_cpl_get_display_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static const gchar* wintc_sh_view_cpl_get_icon_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static GMenuModel* wintc_sh_view_cpl_get_operations_for_item(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash
|
||||
);
|
||||
static GMenuModel* wintc_sh_view_cpl_get_operations_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_sh_view_cpl_get_parent_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
@@ -68,6 +65,15 @@ static guint wintc_sh_view_cpl_get_unique_hash(
|
||||
static gboolean wintc_sh_view_cpl_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_sh_view_cpl_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static WinTCShextOperation* wintc_sh_view_cpl_spawn_operation(
|
||||
WinTCIShextView* view,
|
||||
gint operation_id,
|
||||
GList* targets,
|
||||
GError** error
|
||||
);
|
||||
|
||||
//
|
||||
// GLIB OOP/CLASS INSTANCE DEFINITIONS
|
||||
@@ -124,16 +130,17 @@ static void wintc_sh_view_cpl_ishext_view_interface_init(
|
||||
WinTCIShextViewInterface* iface
|
||||
)
|
||||
{
|
||||
iface->activate_item = wintc_sh_view_cpl_activate_item;
|
||||
iface->refresh_items = wintc_sh_view_cpl_refresh_items;
|
||||
iface->get_actions_for_item = wintc_sh_view_cpl_get_actions_for_item;
|
||||
iface->get_actions_for_view = wintc_sh_view_cpl_get_actions_for_view;
|
||||
iface->get_display_name = wintc_sh_view_cpl_get_display_name;
|
||||
iface->get_icon_name = wintc_sh_view_cpl_get_icon_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;
|
||||
iface->activate_item = wintc_sh_view_cpl_activate_item;
|
||||
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;
|
||||
iface->get_operations_for_view = wintc_sh_view_cpl_get_operations_for_view;
|
||||
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;
|
||||
iface->refresh_items = wintc_sh_view_cpl_refresh_items;
|
||||
iface->spawn_operation = wintc_sh_view_cpl_spawn_operation;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -216,6 +223,75 @@ static gboolean wintc_sh_view_cpl_activate_item(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const gchar* wintc_sh_view_cpl_get_display_name(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
// FIXME: Localisation
|
||||
//
|
||||
return "Control Panel";
|
||||
}
|
||||
|
||||
static const gchar* wintc_sh_view_cpl_get_icon_name(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
return "preferences-other";
|
||||
}
|
||||
|
||||
static GMenuModel* wintc_sh_view_cpl_get_operations_for_item(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(guint item_hash)
|
||||
)
|
||||
{
|
||||
g_warning("%s Not Implemented", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GMenuModel* wintc_sh_view_cpl_get_operations_for_view(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
g_warning("%s Not Implemented", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void wintc_sh_view_cpl_get_parent_path(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WinTCShextPathInfo* path_info
|
||||
)
|
||||
{
|
||||
path_info->base_path =
|
||||
g_strdup(
|
||||
wintc_sh_get_place_path(WINTC_SH_PLACE_DRIVES)
|
||||
);
|
||||
}
|
||||
|
||||
static void wintc_sh_view_cpl_get_path(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WinTCShextPathInfo* path_info
|
||||
)
|
||||
{
|
||||
path_info->base_path =
|
||||
g_strdup(
|
||||
wintc_sh_get_place_path(WINTC_SH_PLACE_CONTROLPANEL)
|
||||
);
|
||||
}
|
||||
|
||||
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)
|
||||
)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void wintc_sh_view_cpl_refresh_items(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
@@ -280,71 +356,15 @@ static void wintc_sh_view_cpl_refresh_items(
|
||||
g_list_free(items);
|
||||
}
|
||||
|
||||
static void wintc_sh_view_cpl_get_actions_for_item(
|
||||
static WinTCShextOperation* wintc_sh_view_cpl_spawn_operation(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(WinTCShextViewItem* item)
|
||||
WINTC_UNUSED(gint operation_id),
|
||||
WINTC_UNUSED(GList* targets),
|
||||
WINTC_UNUSED(GError** error)
|
||||
)
|
||||
{
|
||||
g_critical("%s Not Implemented", __func__);
|
||||
}
|
||||
|
||||
static void wintc_sh_view_cpl_get_actions_for_view(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
g_critical("%s Not Implemented", __func__);
|
||||
}
|
||||
|
||||
static const gchar* wintc_sh_view_cpl_get_display_name(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
// FIXME: Localisation
|
||||
//
|
||||
return "Control Panel";
|
||||
}
|
||||
|
||||
static const gchar* wintc_sh_view_cpl_get_icon_name(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
return "preferences-other";
|
||||
}
|
||||
|
||||
static void wintc_sh_view_cpl_get_parent_path(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WinTCShextPathInfo* path_info
|
||||
)
|
||||
{
|
||||
path_info->base_path =
|
||||
g_strdup(
|
||||
wintc_sh_get_place_path(WINTC_SH_PLACE_DRIVES)
|
||||
);
|
||||
}
|
||||
|
||||
static void wintc_sh_view_cpl_get_path(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WinTCShextPathInfo* path_info
|
||||
)
|
||||
{
|
||||
path_info->base_path =
|
||||
g_strdup(
|
||||
wintc_sh_get_place_path(WINTC_SH_PLACE_CONTROLPANEL)
|
||||
);
|
||||
}
|
||||
|
||||
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)
|
||||
)
|
||||
{
|
||||
return TRUE;
|
||||
g_critical("Not implemented %s", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -75,22 +75,19 @@ static gboolean wintc_sh_view_desktop_activate_item(
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
static void wintc_sh_view_desktop_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_sh_view_desktop_get_actions_for_item(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextViewItem* item
|
||||
);
|
||||
static void wintc_sh_view_desktop_get_actions_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static const gchar* wintc_sh_view_desktop_get_display_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static const gchar* wintc_sh_view_desktop_get_icon_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static GMenuModel* wintc_sh_view_desktop_get_operations_for_item(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash
|
||||
);
|
||||
static GMenuModel* wintc_sh_view_desktop_get_operations_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_sh_view_desktop_get_parent_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
@@ -105,6 +102,15 @@ static guint wintc_sh_view_desktop_get_unique_hash(
|
||||
static gboolean wintc_sh_view_desktop_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_sh_view_desktop_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static WinTCShextOperation* wintc_sh_view_desktop_spawn_operation(
|
||||
WinTCIShextView* view,
|
||||
gint operation_id,
|
||||
GList* targets,
|
||||
GError** error
|
||||
);
|
||||
|
||||
//
|
||||
// GLIB OOP CLASS/INSTANCE DEFINITIONS
|
||||
@@ -190,16 +196,19 @@ static void wintc_sh_view_desktop_ishext_view_interface_init(
|
||||
WinTCIShextViewInterface* iface
|
||||
)
|
||||
{
|
||||
iface->activate_item = wintc_sh_view_desktop_activate_item;
|
||||
iface->refresh_items = wintc_sh_view_desktop_refresh_items;
|
||||
iface->get_actions_for_item = wintc_sh_view_desktop_get_actions_for_item;
|
||||
iface->get_actions_for_view = wintc_sh_view_desktop_get_actions_for_view;
|
||||
iface->get_display_name = wintc_sh_view_desktop_get_display_name;
|
||||
iface->get_icon_name = wintc_sh_view_desktop_get_icon_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;
|
||||
iface->activate_item = wintc_sh_view_desktop_activate_item;
|
||||
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 =
|
||||
wintc_sh_view_desktop_get_operations_for_item;
|
||||
iface->get_operations_for_view =
|
||||
wintc_sh_view_desktop_get_operations_for_view;
|
||||
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;
|
||||
iface->refresh_items = wintc_sh_view_desktop_refresh_items;
|
||||
iface->spawn_operation = wintc_sh_view_desktop_spawn_operation;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -259,44 +268,6 @@ static gboolean wintc_sh_view_desktop_activate_item(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void wintc_sh_view_desktop_refresh_items(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WINTC_LOG_DEBUG("%s", "shell: refresh desktop view");
|
||||
|
||||
_wintc_ishext_view_refreshing(view);
|
||||
|
||||
// Just emit the default items for now
|
||||
// TODO: Should aggregate with user desktop files
|
||||
//
|
||||
WinTCShextViewItemsUpdate update = { 0 };
|
||||
|
||||
GList* items = g_hash_table_get_values(s_desktop_map);
|
||||
|
||||
update.data = items;
|
||||
update.done = TRUE;
|
||||
|
||||
_wintc_ishext_view_items_added(view, &update);
|
||||
|
||||
g_list_free(items);
|
||||
}
|
||||
|
||||
static void wintc_sh_view_desktop_get_actions_for_item(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(WinTCShextViewItem* item)
|
||||
)
|
||||
{
|
||||
g_critical("%s Not Implemented", __func__);
|
||||
}
|
||||
|
||||
static void wintc_sh_view_desktop_get_actions_for_view(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
g_critical("%s Not Implemented", __func__);
|
||||
}
|
||||
|
||||
static const gchar* wintc_sh_view_desktop_get_display_name(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
@@ -312,6 +283,23 @@ static const gchar* wintc_sh_view_desktop_get_icon_name(
|
||||
return "user-desktop";
|
||||
}
|
||||
|
||||
static GMenuModel* wintc_sh_view_desktop_get_operations_for_item(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(guint item_hash)
|
||||
)
|
||||
{
|
||||
g_warning("%s Not Implemented", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GMenuModel* wintc_sh_view_desktop_get_operations_for_view(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
g_warning("%s Not Implemented", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void wintc_sh_view_desktop_get_parent_path(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(WinTCShextPathInfo* path_info)
|
||||
@@ -342,6 +330,40 @@ static gboolean wintc_sh_view_desktop_has_parent(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void wintc_sh_view_desktop_refresh_items(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WINTC_LOG_DEBUG("%s", "shell: refresh desktop view");
|
||||
|
||||
_wintc_ishext_view_refreshing(view);
|
||||
|
||||
// Just emit the default items for now
|
||||
// TODO: Should aggregate with user desktop files
|
||||
//
|
||||
WinTCShextViewItemsUpdate update = { 0 };
|
||||
|
||||
GList* items = g_hash_table_get_values(s_desktop_map);
|
||||
|
||||
update.data = items;
|
||||
update.done = TRUE;
|
||||
|
||||
_wintc_ishext_view_items_added(view, &update);
|
||||
|
||||
g_list_free(items);
|
||||
}
|
||||
|
||||
static WinTCShextOperation* wintc_sh_view_desktop_spawn_operation(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(gint operation_id),
|
||||
WINTC_UNUSED(GList* targets),
|
||||
WINTC_UNUSED(GError** error)
|
||||
)
|
||||
{
|
||||
g_critical("Not implemented %s", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
|
||||
@@ -48,22 +48,19 @@ static gboolean wintc_sh_view_drives_activate_item(
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
static void wintc_sh_view_drives_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_sh_view_drives_get_actions_for_item(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextViewItem* item
|
||||
);
|
||||
static void wintc_sh_view_drives_get_actions_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static const gchar* wintc_sh_view_drives_get_display_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static const gchar* wintc_sh_view_drives_get_icon_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static GMenuModel* wintc_sh_view_drives_get_operations_for_item(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash
|
||||
);
|
||||
static GMenuModel* wintc_sh_view_drives_get_operations_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_sh_view_drives_get_parent_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
@@ -78,6 +75,15 @@ static guint wintc_sh_view_drives_get_unique_hash(
|
||||
static gboolean wintc_sh_view_drives_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_sh_view_drives_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static WinTCShextOperation* wintc_sh_view_drives_spawn_operation(
|
||||
WinTCIShextView* view,
|
||||
gint operation_id,
|
||||
GList* targets,
|
||||
GError** error
|
||||
);
|
||||
|
||||
//
|
||||
// GLIB OOP/CLASS INSTANCE DEFINITIONS
|
||||
@@ -154,16 +160,19 @@ static void wintc_sh_view_drives_ishext_view_interface_init(
|
||||
WinTCIShextViewInterface* iface
|
||||
)
|
||||
{
|
||||
iface->activate_item = wintc_sh_view_drives_activate_item;
|
||||
iface->refresh_items = wintc_sh_view_drives_refresh_items;
|
||||
iface->get_actions_for_item = wintc_sh_view_drives_get_actions_for_item;
|
||||
iface->get_actions_for_view = wintc_sh_view_drives_get_actions_for_view;
|
||||
iface->get_display_name = wintc_sh_view_drives_get_display_name;
|
||||
iface->get_icon_name = wintc_sh_view_drives_get_icon_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;
|
||||
iface->activate_item = wintc_sh_view_drives_activate_item;
|
||||
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 =
|
||||
wintc_sh_view_drives_get_operations_for_item;
|
||||
iface->get_operations_for_view =
|
||||
wintc_sh_view_drives_get_operations_for_view;
|
||||
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;
|
||||
iface->refresh_items = wintc_sh_view_drives_refresh_items;
|
||||
iface->spawn_operation = wintc_sh_view_drives_spawn_operation;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -219,44 +228,6 @@ static gboolean wintc_sh_view_drives_activate_item(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void wintc_sh_view_drives_refresh_items(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WINTC_LOG_DEBUG("%s", "shell: refresh drives view");
|
||||
|
||||
_wintc_ishext_view_refreshing(view);
|
||||
|
||||
// Emit only the root '/' for now
|
||||
// TODO: Basically everything in My Computer!
|
||||
//
|
||||
WinTCShextViewItemsUpdate update = { 0 };
|
||||
|
||||
GList* items = g_hash_table_get_values(s_drives_map);
|
||||
|
||||
update.data = items;
|
||||
update.done = TRUE;
|
||||
|
||||
_wintc_ishext_view_items_added(view, &update);
|
||||
|
||||
g_list_free(items);
|
||||
}
|
||||
|
||||
static void wintc_sh_view_drives_get_actions_for_item(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(WinTCShextViewItem* item)
|
||||
)
|
||||
{
|
||||
g_critical("%s Not Implemented", __func__);
|
||||
}
|
||||
|
||||
static void wintc_sh_view_drives_get_actions_for_view(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
g_critical("%s Not Implemented", __func__);
|
||||
}
|
||||
|
||||
static const gchar* wintc_sh_view_drives_get_display_name(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
@@ -273,6 +244,23 @@ static const gchar* wintc_sh_view_drives_get_icon_name(
|
||||
return "computer";
|
||||
}
|
||||
|
||||
static GMenuModel* wintc_sh_view_drives_get_operations_for_item(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(guint item_hash)
|
||||
)
|
||||
{
|
||||
g_warning("%s Not Implemented", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static GMenuModel* wintc_sh_view_drives_get_operations_for_view(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
g_warning("%s Not Implemented", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void wintc_sh_view_drives_get_parent_path(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WinTCShextPathInfo* path_info
|
||||
@@ -309,6 +297,40 @@ static gboolean wintc_sh_view_drives_has_parent(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void wintc_sh_view_drives_refresh_items(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WINTC_LOG_DEBUG("%s", "shell: refresh drives view");
|
||||
|
||||
_wintc_ishext_view_refreshing(view);
|
||||
|
||||
// Emit only the root '/' for now
|
||||
// TODO: Basically everything in My Computer!
|
||||
//
|
||||
WinTCShextViewItemsUpdate update = { 0 };
|
||||
|
||||
GList* items = g_hash_table_get_values(s_drives_map);
|
||||
|
||||
update.data = items;
|
||||
update.done = TRUE;
|
||||
|
||||
_wintc_ishext_view_items_added(view, &update);
|
||||
|
||||
g_list_free(items);
|
||||
}
|
||||
|
||||
static WinTCShextOperation* wintc_sh_view_drives_spawn_operation(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(gint operation_id),
|
||||
WINTC_UNUSED(GList* targets),
|
||||
WINTC_UNUSED(GError** error)
|
||||
)
|
||||
{
|
||||
g_critical("Not implemented %s", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <wintc/exec.h>
|
||||
#include <wintc/shcommon.h>
|
||||
#include <wintc/shellext.h>
|
||||
#include <wintc/shlang.h>
|
||||
|
||||
#include "../public/vwfs.h"
|
||||
|
||||
@@ -49,16 +50,6 @@ static gboolean wintc_sh_view_fs_activate_item(
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
static void wintc_sh_view_fs_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_sh_view_fs_get_actions_for_item(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextViewItem* item
|
||||
);
|
||||
static void wintc_sh_view_fs_get_actions_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static guint wintc_sh_view_fs_get_unique_hash(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
@@ -68,6 +59,13 @@ static const gchar* wintc_sh_view_fs_get_display_name(
|
||||
static const gchar* wintc_sh_view_fs_get_icon_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static GMenuModel* wintc_sh_view_fs_get_operations_for_item(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash
|
||||
);
|
||||
static GMenuModel* wintc_sh_view_fs_get_operations_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_sh_view_fs_get_parent_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
@@ -79,11 +77,34 @@ static void wintc_sh_view_fs_get_path(
|
||||
static gboolean wintc_sh_view_fs_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_sh_view_fs_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static WinTCShextOperation* wintc_sh_view_fs_spawn_operation(
|
||||
WinTCIShextView* view,
|
||||
gint operation_id,
|
||||
GList* targets,
|
||||
GError** error
|
||||
);
|
||||
|
||||
static void clear_view_item(
|
||||
WinTCShextViewItem* item
|
||||
);
|
||||
|
||||
static gboolean real_activate_item(
|
||||
WinTCShViewFS* view_fs,
|
||||
WinTCShextViewItem* item,
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
|
||||
static gboolean shopr_open(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextOperation* operation,
|
||||
GtkWindow* wnd,
|
||||
GError** error
|
||||
);
|
||||
|
||||
static void on_file_monitor_changed(
|
||||
GFileMonitor* self,
|
||||
GFile* file,
|
||||
@@ -177,16 +198,17 @@ static void wintc_sh_view_fs_ishext_view_interface_init(
|
||||
WinTCIShextViewInterface* iface
|
||||
)
|
||||
{
|
||||
iface->activate_item = wintc_sh_view_fs_activate_item;
|
||||
iface->refresh_items = wintc_sh_view_fs_refresh_items;
|
||||
iface->get_actions_for_item = wintc_sh_view_fs_get_actions_for_item;
|
||||
iface->get_actions_for_view = wintc_sh_view_fs_get_actions_for_view;
|
||||
iface->get_display_name = wintc_sh_view_fs_get_display_name;
|
||||
iface->get_icon_name = wintc_sh_view_fs_get_icon_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;
|
||||
iface->activate_item = wintc_sh_view_fs_activate_item;
|
||||
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;
|
||||
iface->get_operations_for_view = wintc_sh_view_fs_get_operations_for_view;
|
||||
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;
|
||||
iface->refresh_items = wintc_sh_view_fs_refresh_items;
|
||||
iface->spawn_operation = wintc_sh_view_fs_spawn_operation;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -295,8 +317,7 @@ static gboolean wintc_sh_view_fs_activate_item(
|
||||
GError** error
|
||||
)
|
||||
{
|
||||
GError* local_error = NULL;
|
||||
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
|
||||
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
|
||||
|
||||
WINTC_SAFE_REF_CLEAR(error);
|
||||
|
||||
@@ -318,51 +339,160 @@ static gboolean wintc_sh_view_fs_activate_item(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Retrieve MIME for the item
|
||||
//
|
||||
gchar* next_path = g_build_path(
|
||||
G_DIR_SEPARATOR_S,
|
||||
view_fs->path,
|
||||
item->display_name,
|
||||
NULL
|
||||
);
|
||||
gchar* mime_type = wintc_query_mime_for_file(
|
||||
next_path,
|
||||
&local_error
|
||||
);
|
||||
return real_activate_item(
|
||||
view_fs,
|
||||
item,
|
||||
path_info,
|
||||
error
|
||||
);
|
||||
}
|
||||
|
||||
if (!mime_type)
|
||||
static const gchar* wintc_sh_view_fs_get_display_name(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
|
||||
|
||||
if (g_strcmp0(view_fs->path, "/") == 0)
|
||||
{
|
||||
g_propagate_error(error, local_error);
|
||||
return FALSE;
|
||||
return view_fs->path;
|
||||
}
|
||||
|
||||
// Handle the item based on MIME, if it's a directory then we can set that
|
||||
// as our next location - otherwise, it depends if there is a shell
|
||||
// extension for handling the MIME type or not
|
||||
// FIXME: This could be broken if the path itself contains an escaped dir
|
||||
// separator, cba for now
|
||||
//
|
||||
if (g_strcmp0(mime_type, "inode/directory") == 0)
|
||||
return g_strrstr(view_fs->path, G_DIR_SEPARATOR_S) + 1;
|
||||
}
|
||||
|
||||
static const gchar* wintc_sh_view_fs_get_icon_name(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
return "inode-directory";
|
||||
}
|
||||
|
||||
static GMenuModel* wintc_sh_view_fs_get_operations_for_item(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash
|
||||
)
|
||||
{
|
||||
// Retrieve the view item itself
|
||||
//
|
||||
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)
|
||||
);
|
||||
|
||||
if (!view_item)
|
||||
{
|
||||
path_info->base_path = g_strdup_printf("file://%s", next_path);
|
||||
g_critical("%s", "shell: fs - no such item for menu");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FIXME: Extremely simplistic for now, does not cover shell extensions or
|
||||
// anything!
|
||||
//
|
||||
GtkBuilder* builder;
|
||||
GMenuModel* menu;
|
||||
|
||||
builder =
|
||||
gtk_builder_new_from_resource(
|
||||
view_item->is_leaf ?
|
||||
"/uk/oddmatics/wintc/shell/menufslf.ui" :
|
||||
"/uk/oddmatics/wintc/shell/menufsvw.ui"
|
||||
);
|
||||
|
||||
wintc_lc_builder_preprocess_widget_text(builder);
|
||||
|
||||
menu =
|
||||
G_MENU_MODEL(
|
||||
g_object_ref(
|
||||
gtk_builder_get_object(builder, "menu")
|
||||
)
|
||||
);
|
||||
|
||||
g_object_unref(builder);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
static GMenuModel* wintc_sh_view_fs_get_operations_for_view(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
GtkBuilder* builder;
|
||||
GMenuModel* menu;
|
||||
|
||||
builder =
|
||||
gtk_builder_new_from_resource(
|
||||
"/uk/oddmatics/wintc/shell/menufs.ui"
|
||||
);
|
||||
|
||||
wintc_lc_builder_preprocess_widget_text(builder);
|
||||
|
||||
menu =
|
||||
G_MENU_MODEL(
|
||||
g_object_ref(
|
||||
gtk_builder_get_object(builder, "menu")
|
||||
)
|
||||
);
|
||||
|
||||
g_object_unref(builder);
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
static void wintc_sh_view_fs_get_parent_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
)
|
||||
{
|
||||
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
|
||||
|
||||
if (view_fs->parent_path)
|
||||
{
|
||||
path_info->base_path =
|
||||
g_strdup_printf("file://%s", view_fs->parent_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wintc_shext_host_has_view_for_mime(view_fs->shext_host, mime_type))
|
||||
{
|
||||
path_info->base_path = g_strdup_printf("file://%s", next_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!wintc_launch_command(next_path, &local_error))
|
||||
{
|
||||
g_propagate_error(error, local_error);
|
||||
}
|
||||
}
|
||||
path_info->base_path =
|
||||
g_strdup(
|
||||
wintc_sh_get_place_path(
|
||||
WINTC_SH_PLACE_DRIVES
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
g_free(mime_type);
|
||||
g_free(next_path);
|
||||
static void wintc_sh_view_fs_get_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
)
|
||||
{
|
||||
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
|
||||
|
||||
path_info->base_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)
|
||||
)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -478,93 +608,37 @@ static void wintc_sh_view_fs_refresh_items(
|
||||
g_list_free(items);
|
||||
}
|
||||
|
||||
static void wintc_sh_view_fs_get_actions_for_item(
|
||||
static WinTCShextOperation* wintc_sh_view_fs_spawn_operation(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(WinTCShextViewItem* item)
|
||||
gint operation_id,
|
||||
GList* targets,
|
||||
WINTC_UNUSED(GError** error)
|
||||
)
|
||||
{
|
||||
g_critical("%s Not Implemented", __func__);
|
||||
}
|
||||
|
||||
static void wintc_sh_view_fs_get_actions_for_view(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
g_critical("%s Not Implemented", __func__);
|
||||
}
|
||||
|
||||
static const gchar* wintc_sh_view_fs_get_display_name(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
|
||||
|
||||
if (g_strcmp0(view_fs->path, "/") == 0)
|
||||
if (operation_id > WINTC_SHEXT_KNOWN_OP_OPEN)
|
||||
{
|
||||
return view_fs->path;
|
||||
g_critical("Not implemented %s", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FIXME: This could be broken if the path itself contains an escaped dir
|
||||
// separator, cba for now
|
||||
// Spawn op
|
||||
//
|
||||
return g_strrstr(view_fs->path, G_DIR_SEPARATOR_S) + 1;
|
||||
}
|
||||
WinTCShextOperation* ret = g_new(WinTCShextOperation, 1);
|
||||
|
||||
static const gchar* wintc_sh_view_fs_get_icon_name(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
return "inode-directory";
|
||||
}
|
||||
|
||||
static void wintc_sh_view_fs_get_parent_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
)
|
||||
{
|
||||
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
|
||||
|
||||
if (view_fs->parent_path)
|
||||
switch (operation_id)
|
||||
{
|
||||
path_info->base_path =
|
||||
g_strdup_printf("file://%s", view_fs->parent_path);
|
||||
case WINTC_SHEXT_KNOWN_OP_OPEN:
|
||||
ret->func = shopr_open;
|
||||
ret->priv = targets;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_free(ret);
|
||||
g_critical("%s", "shell: fs - invalid op");
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
path_info->base_path =
|
||||
g_strdup(
|
||||
wintc_sh_get_place_path(
|
||||
WINTC_SH_PLACE_DRIVES
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void wintc_sh_view_fs_get_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
)
|
||||
{
|
||||
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
|
||||
|
||||
path_info->base_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)
|
||||
)
|
||||
{
|
||||
return TRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -596,6 +670,136 @@ static void clear_view_item(
|
||||
g_free(item);
|
||||
}
|
||||
|
||||
static gboolean real_activate_item(
|
||||
WinTCShViewFS* view_fs,
|
||||
WinTCShextViewItem* item,
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
)
|
||||
{
|
||||
// If the target is a dir or has a shell extension then set that as
|
||||
// the target path
|
||||
//
|
||||
gchar* next_path = g_build_path(
|
||||
G_DIR_SEPARATOR_S,
|
||||
view_fs->path,
|
||||
item->display_name,
|
||||
NULL
|
||||
);
|
||||
gchar* target_path = NULL;
|
||||
|
||||
if (!(item->is_leaf))
|
||||
{
|
||||
target_path = g_strdup_printf("file://%s", next_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar* mime_type = wintc_query_mime_for_file(next_path, error);
|
||||
|
||||
if (!mime_type)
|
||||
{
|
||||
g_free(next_path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (wintc_shext_host_has_view_for_mime(view_fs->shext_host, mime_type))
|
||||
{
|
||||
target_path = g_strdup_printf("file://%s", next_path);
|
||||
}
|
||||
}
|
||||
|
||||
// If there is a target path, then either navigate there, or open a new
|
||||
// window to navigate there
|
||||
//
|
||||
// Otherwise just run the command
|
||||
//
|
||||
gboolean success = TRUE;
|
||||
|
||||
if (target_path)
|
||||
{
|
||||
if (path_info)
|
||||
{
|
||||
path_info->base_path = target_path;
|
||||
}
|
||||
else
|
||||
{
|
||||
success = wintc_launch_command(target_path, error);
|
||||
|
||||
g_free(target_path);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = wintc_launch_command(next_path, error);
|
||||
}
|
||||
|
||||
g_free(next_path);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static gboolean shopr_open(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextOperation* operation,
|
||||
WINTC_UNUSED(GtkWindow* wnd),
|
||||
GError** error
|
||||
)
|
||||
{
|
||||
WinTCShViewFS* view_fs = WINTC_SH_VIEW_FS(view);
|
||||
|
||||
GList* targets = operation->priv;
|
||||
|
||||
if (!targets)
|
||||
{
|
||||
g_warning("%s", "shell: fs open op - no files specified?");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Iterate over to activate the items
|
||||
//
|
||||
GError* local_error = NULL;
|
||||
gboolean success = TRUE;
|
||||
|
||||
for (GList* iter = targets; iter; iter = iter->next)
|
||||
{
|
||||
WinTCShextViewItem* item =
|
||||
g_hash_table_lookup(
|
||||
view_fs->fs_map_entries,
|
||||
iter->data
|
||||
);
|
||||
|
||||
if (!item)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Valid - attempt launch
|
||||
//
|
||||
// Only store the first error
|
||||
//
|
||||
if (
|
||||
!real_activate_item(
|
||||
view_fs,
|
||||
item,
|
||||
NULL,
|
||||
local_error ? NULL : &local_error
|
||||
)
|
||||
)
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!success && local_error)
|
||||
{
|
||||
g_propagate_error(error, local_error);
|
||||
}
|
||||
|
||||
g_list_free(targets);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
static void on_file_monitor_changed(
|
||||
WINTC_UNUSED(GFileMonitor* self),
|
||||
GFile* file,
|
||||
|
||||
@@ -41,6 +41,7 @@ add_library(
|
||||
src/if_view.c
|
||||
public/if_view.h
|
||||
public/viewitem.h
|
||||
public/viewops.h
|
||||
)
|
||||
|
||||
set_target_properties(
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "viewitem.h"
|
||||
#include "viewops.h"
|
||||
|
||||
//
|
||||
// PUBLIC STRUCTURES
|
||||
@@ -41,20 +42,19 @@ struct _WinTCIShextViewInterface
|
||||
GError** error
|
||||
);
|
||||
|
||||
void (*get_actions_for_item) (
|
||||
WinTCIShextView* view,
|
||||
WinTCShextViewItem* item
|
||||
);
|
||||
void (*get_actions_for_view) (
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
const gchar* (*get_display_name) (
|
||||
WinTCIShextView* view
|
||||
);
|
||||
const gchar* (*get_icon_name) (
|
||||
WinTCIShextView* view
|
||||
);
|
||||
GMenuModel* (*get_operations_for_item) (
|
||||
WinTCIShextView* view,
|
||||
guint item_hash
|
||||
);
|
||||
GMenuModel* (*get_operations_for_view) (
|
||||
WinTCIShextView* view
|
||||
);
|
||||
void (*get_parent_path) (
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
@@ -73,6 +73,13 @@ struct _WinTCIShextViewInterface
|
||||
void (*refresh_items) (
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
WinTCShextOperation* (*spawn_operation) (
|
||||
WinTCIShextView* view,
|
||||
gint operation_id,
|
||||
GList* targets,
|
||||
GError** error
|
||||
);
|
||||
};
|
||||
|
||||
//
|
||||
@@ -89,20 +96,19 @@ void wintc_ishext_view_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
void wintc_ishext_view_get_actions_for_item(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextViewItem* item
|
||||
);
|
||||
void wintc_ishext_view_get_actions_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
const gchar* wintc_ishext_view_get_display_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
const gchar* wintc_ishext_view_get_icon_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
GMenuModel* wintc_ishext_view_get_operations_for_item(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash
|
||||
);
|
||||
GMenuModel* wintc_ishext_view_get_operations_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
void wintc_ishext_view_get_parent_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
@@ -117,6 +123,12 @@ guint wintc_ishext_view_get_unique_hash(
|
||||
gboolean wintc_ishext_view_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
WinTCShextOperation* wintc_ishext_view_spawn_operation(
|
||||
WinTCIShextView* view,
|
||||
gint operation_id,
|
||||
GList* targets,
|
||||
GError** error
|
||||
);
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
#include "@LIB_HEADER_DIR@/host.h"
|
||||
#include "@LIB_HEADER_DIR@/if_view.h"
|
||||
#include "@LIB_HEADER_DIR@/viewitem.h"
|
||||
#include "@LIB_HEADER_DIR@/viewops.h"
|
||||
|
||||
#endif
|
||||
|
||||
62
shared/shellext/public/viewops.h
Normal file
62
shared/shellext/public/viewops.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/** @file */
|
||||
|
||||
#ifndef __SHELLEXT_VIEWOPS_H__
|
||||
#define __SHELLEXT_VIEWOPS_H__
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
//
|
||||
// FORWARD DECLARATIONS
|
||||
//
|
||||
typedef struct _WinTCIShextView WinTCIShextView;
|
||||
typedef struct _WinTCShextOperation WinTCShextOperation;
|
||||
|
||||
//
|
||||
// PUBLIC ENUMS
|
||||
//
|
||||
typedef enum
|
||||
{
|
||||
WINTC_SHEXT_OP_PRIORITY_NONE,
|
||||
WINTC_SHEXT_OP_PRIORITY_PRIMARY,
|
||||
WINTC_SHEXT_OP_PRIORITY_SECONDARY
|
||||
} WinTCShextOperationPriority;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
WINTC_SHEXT_OP_INVALID = 0,
|
||||
|
||||
WINTC_SHEXT_KNOWN_OP_OPEN = 1,
|
||||
WINTC_SHEXT_KNOWN_OP_OPEN_WITH,
|
||||
WINTC_SHEXT_KNOWN_OP_RUN_AS,
|
||||
WINTC_SHEXT_KNOWN_OP_CUT,
|
||||
WINTC_SHEXT_KNOWN_OP_COPY,
|
||||
WINTC_SHEXT_KNOWN_OP_PASTE,
|
||||
WINTC_SHEXT_KNOWN_OP_PASTE_SHORTCUT,
|
||||
WINTC_SHEXT_KNOWN_OP_CREATE_SHORTCUT,
|
||||
WINTC_SHEXT_KNOWN_OP_DELETE,
|
||||
WINTC_SHEXT_KNOWN_OP_RENAME,
|
||||
WINTC_SHEXT_KNOWN_OP_SEND_TO,
|
||||
WINTC_SHEXT_KNOWN_OP_MOVE_TO,
|
||||
WINTC_SHEXT_KNOWN_OP_COPY_TO,
|
||||
WINTC_SHEXT_KNOWN_OP_PROPERTIES,
|
||||
|
||||
WINTC_SHEXT_OP_CUSTOM = 100
|
||||
} WinTCShextOperationId;
|
||||
|
||||
//
|
||||
// PUBLIC STRUCTURES
|
||||
//
|
||||
typedef gboolean (*WinTCShextOperationFunc) (
|
||||
WinTCIShextView* view,
|
||||
WinTCShextOperation* operation,
|
||||
GtkWindow* wnd,
|
||||
GError** error
|
||||
);
|
||||
|
||||
struct _WinTCShextOperation
|
||||
{
|
||||
WinTCShextOperationFunc func;
|
||||
gpointer priv;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -107,27 +107,6 @@ gboolean wintc_ishext_view_activate_item(
|
||||
);
|
||||
}
|
||||
|
||||
void wintc_ishext_view_get_actions_for_item(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextViewItem* item
|
||||
)
|
||||
{
|
||||
WinTCIShextViewInterface* iface =
|
||||
WINTC_ISHEXT_VIEW_GET_IFACE(view);
|
||||
|
||||
iface->get_actions_for_item(view, item);
|
||||
}
|
||||
|
||||
void wintc_ishext_view_get_actions_for_view(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WinTCIShextViewInterface* iface =
|
||||
WINTC_ISHEXT_VIEW_GET_IFACE(view);
|
||||
|
||||
iface->get_actions_for_view(view);
|
||||
}
|
||||
|
||||
const gchar* wintc_ishext_view_get_display_name(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
@@ -148,6 +127,27 @@ const gchar* wintc_ishext_view_get_icon_name(
|
||||
return iface->get_icon_name(view);
|
||||
}
|
||||
|
||||
GMenuModel* wintc_ishext_view_get_operations_for_item(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash
|
||||
)
|
||||
{
|
||||
WinTCIShextViewInterface* iface =
|
||||
WINTC_ISHEXT_VIEW_GET_IFACE(view);
|
||||
|
||||
return iface->get_operations_for_item(view, item_hash);
|
||||
}
|
||||
|
||||
GMenuModel* wintc_ishext_view_get_operations_for_view(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WinTCIShextViewInterface* iface =
|
||||
WINTC_ISHEXT_VIEW_GET_IFACE(view);
|
||||
|
||||
return iface->get_operations_for_view(view);
|
||||
}
|
||||
|
||||
void wintc_ishext_view_get_parent_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
@@ -200,6 +200,24 @@ void wintc_ishext_view_refresh_items(
|
||||
iface->refresh_items(view);
|
||||
}
|
||||
|
||||
WinTCShextOperation* wintc_ishext_view_spawn_operation(
|
||||
WinTCIShextView* view,
|
||||
gint operation_id,
|
||||
GList* targets,
|
||||
GError** error
|
||||
)
|
||||
{
|
||||
WinTCIShextViewInterface* iface =
|
||||
WINTC_ISHEXT_VIEW_GET_IFACE(view);
|
||||
|
||||
return iface->spawn_operation(
|
||||
view,
|
||||
operation_id,
|
||||
targets,
|
||||
error
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
|
||||
@@ -48,22 +48,19 @@ static gboolean wintc_cpl_view_printers_activate_item(
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
static void wintc_cpl_view_printers_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_cpl_view_printers_get_actions_for_item(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextViewItem* item
|
||||
);
|
||||
static void wintc_cpl_view_printers_get_actions_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static const gchar* wintc_cpl_view_printers_get_display_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static const gchar* wintc_cpl_view_printers_get_icon_name(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static GMenuModel* wintc_cpl_view_printers_get_operations_for_item(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash
|
||||
);
|
||||
static GMenuModel* wintc_cpl_view_printers_get_operations_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_cpl_view_printers_get_parent_path(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextPathInfo* path_info
|
||||
@@ -78,6 +75,9 @@ static guint wintc_cpl_view_printers_get_unique_hash(
|
||||
static gboolean wintc_cpl_view_printers_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_cpl_view_printers_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
//
|
||||
// GLIB OOP/CLASS INSTANCE DEFINITIONS
|
||||
@@ -145,16 +145,18 @@ static void wintc_cpl_view_printers_ishext_view_interface_init(
|
||||
WinTCIShextViewInterface* iface
|
||||
)
|
||||
{
|
||||
iface->activate_item = wintc_cpl_view_printers_activate_item;
|
||||
iface->refresh_items = wintc_cpl_view_printers_refresh_items;
|
||||
iface->get_actions_for_item = wintc_cpl_view_printers_get_actions_for_item;
|
||||
iface->get_actions_for_view = wintc_cpl_view_printers_get_actions_for_view;
|
||||
iface->get_display_name = wintc_cpl_view_printers_get_display_name;
|
||||
iface->get_icon_name = wintc_cpl_view_printers_get_icon_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;
|
||||
iface->activate_item = wintc_cpl_view_printers_activate_item;
|
||||
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 =
|
||||
wintc_cpl_view_printers_get_operations_for_item;
|
||||
iface->get_operations_for_view =
|
||||
wintc_cpl_view_printers_get_operations_for_view;
|
||||
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;
|
||||
iface->refresh_items = wintc_cpl_view_printers_refresh_items;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -199,42 +201,21 @@ static gboolean wintc_cpl_view_printers_activate_item(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void wintc_cpl_view_printers_refresh_items(
|
||||
WinTCIShextView* view
|
||||
static GMenuModel* wintc_cpl_view_printers_get_operations_for_item(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(guint item_hash)
|
||||
)
|
||||
{
|
||||
WINTC_LOG_DEBUG("%s", "cpl-prntrs: refresh printers view");
|
||||
|
||||
_wintc_ishext_view_refreshing(view);
|
||||
|
||||
// Emit the FPO printer for now
|
||||
// TODO: Implement this!
|
||||
//
|
||||
WinTCShextViewItemsUpdate update = { 0 };
|
||||
|
||||
GList* items = g_hash_table_get_values(s_printers_map);
|
||||
|
||||
update.data = items;
|
||||
update.done = TRUE;
|
||||
|
||||
_wintc_ishext_view_items_added(view, &update);
|
||||
|
||||
g_list_free(items);
|
||||
g_warning("%s Not Implemented", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void wintc_cpl_view_printers_get_actions_for_item(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(WinTCShextViewItem* item)
|
||||
)
|
||||
{
|
||||
g_critical("%s Not Implemented", __func__);
|
||||
}
|
||||
|
||||
static void wintc_cpl_view_printers_get_actions_for_view(
|
||||
static GMenuModel* wintc_cpl_view_printers_get_operations_for_view(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
g_critical("%s Not Implemented", __func__);
|
||||
g_warning("%s Not Implemented", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const gchar* wintc_cpl_view_printers_get_display_name(
|
||||
@@ -289,6 +270,29 @@ static gboolean wintc_cpl_view_printers_has_parent(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void wintc_cpl_view_printers_refresh_items(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WINTC_LOG_DEBUG("%s", "cpl-prntrs: refresh printers view");
|
||||
|
||||
_wintc_ishext_view_refreshing(view);
|
||||
|
||||
// Emit the FPO printer for now
|
||||
// TODO: Implement this!
|
||||
//
|
||||
WinTCShextViewItemsUpdate update = { 0 };
|
||||
|
||||
GList* items = g_hash_table_get_values(s_printers_map);
|
||||
|
||||
update.data = items;
|
||||
update.done = TRUE;
|
||||
|
||||
_wintc_ishext_view_items_added(view, &update);
|
||||
|
||||
g_list_free(items);
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
|
||||
@@ -45,14 +45,11 @@ static gboolean wintc_view_zip_activate_item(
|
||||
WinTCShextPathInfo* path_info,
|
||||
GError** error
|
||||
);
|
||||
static void wintc_view_zip_refresh_items(
|
||||
WinTCIShextView* view
|
||||
static GMenuModel* wintc_view_zip_get_operations_for_item(
|
||||
WinTCIShextView* view,
|
||||
guint item_hash
|
||||
);
|
||||
static void wintc_view_zip_get_actions_for_item(
|
||||
WinTCIShextView* view,
|
||||
WinTCShextViewItem* item
|
||||
);
|
||||
static void wintc_view_zip_get_actions_for_view(
|
||||
static GMenuModel* wintc_view_zip_get_operations_for_view(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static const gchar* wintc_view_zip_get_display_name(
|
||||
@@ -75,6 +72,9 @@ static guint wintc_view_zip_get_unique_hash(
|
||||
static gboolean wintc_view_zip_has_parent(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
static void wintc_view_zip_refresh_items(
|
||||
WinTCIShextView* view
|
||||
);
|
||||
|
||||
static guint zip_entry_hash(
|
||||
const gchar* zip_file_path,
|
||||
@@ -172,16 +172,16 @@ static void wintc_view_zip_ishext_view_interface_init(
|
||||
WinTCIShextViewInterface* iface
|
||||
)
|
||||
{
|
||||
iface->activate_item = wintc_view_zip_activate_item;
|
||||
iface->refresh_items = wintc_view_zip_refresh_items;
|
||||
iface->get_actions_for_item = wintc_view_zip_get_actions_for_item;
|
||||
iface->get_actions_for_view = wintc_view_zip_get_actions_for_view;
|
||||
iface->get_display_name = wintc_view_zip_get_display_name;
|
||||
iface->get_icon_name = wintc_view_zip_get_icon_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;
|
||||
iface->activate_item = wintc_view_zip_activate_item;
|
||||
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;
|
||||
iface->get_icon_name = wintc_view_zip_get_icon_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;
|
||||
iface->refresh_items = wintc_view_zip_refresh_items;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -312,120 +312,21 @@ static gboolean wintc_view_zip_activate_item(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void wintc_view_zip_refresh_items(
|
||||
WinTCIShextView* view
|
||||
static GMenuModel* wintc_view_zip_get_operations_for_item(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(guint item_hash)
|
||||
)
|
||||
{
|
||||
WinTCViewZip* view_zip = WINTC_VIEW_ZIP(view);
|
||||
|
||||
WINTC_LOG_DEBUG("%s", "shext-zip: refresh zip view");
|
||||
|
||||
_wintc_ishext_view_refreshing(view);
|
||||
|
||||
if (view_zip->map_items)
|
||||
{
|
||||
g_hash_table_destroy(
|
||||
g_steal_pointer(&(view_zip->map_items))
|
||||
);
|
||||
}
|
||||
|
||||
view_zip->map_items =
|
||||
g_hash_table_new_full(
|
||||
g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL,
|
||||
(GDestroyNotify) clear_view_item
|
||||
);
|
||||
|
||||
// Open the archive
|
||||
//
|
||||
const gchar* path = view_zip->zip_uri + strlen("file://");
|
||||
|
||||
gint zip_error = 0;
|
||||
zip_t* zip_file = zip_open(path, 0, &zip_error);
|
||||
|
||||
if (!zip_file)
|
||||
{
|
||||
zip_error_t zip_error_st;
|
||||
|
||||
zip_error_init_with_code(&zip_error_st, zip_error);
|
||||
|
||||
// FIXME: Need a proper way of returning error to caller!
|
||||
g_critical(
|
||||
"shext-zip: can't open %s , %s",
|
||||
path,
|
||||
zip_error_strerror(&zip_error_st)
|
||||
);
|
||||
|
||||
zip_error_fini(&zip_error_st);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Read through the entries
|
||||
// FIXME: Probably want to cap max num of entries? Check zip bombs to see
|
||||
// what happens - don't want to get nuked by a crazy zip archive
|
||||
//
|
||||
gint64 n_entries = zip_get_num_entries(zip_file, 0);
|
||||
|
||||
for (gint64 i = 0; i < n_entries; i++)
|
||||
{
|
||||
const gchar* entry_name = zip_get_name(zip_file, (guint64) i, 0);
|
||||
|
||||
// Only want to add the entries in the current relative dir
|
||||
//
|
||||
gint name_offset = 0;
|
||||
|
||||
if (!zip_entry_is_in_dir(view_zip->rel_path, entry_name, &name_offset))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
gchar* entry_copy = g_strdup(entry_name);
|
||||
WinTCShextViewItem* item = g_new(WinTCShextViewItem, 1);
|
||||
|
||||
item->display_name = entry_copy + name_offset;
|
||||
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;
|
||||
|
||||
g_hash_table_insert(
|
||||
view_zip->map_items,
|
||||
GUINT_TO_POINTER(item->hash),
|
||||
item
|
||||
);
|
||||
}
|
||||
|
||||
zip_close(zip_file);
|
||||
|
||||
// Emit the entries
|
||||
//
|
||||
WinTCShextViewItemsUpdate update = { 0 };
|
||||
|
||||
GList* items = g_hash_table_get_values(view_zip->map_items);
|
||||
|
||||
update.data = items;
|
||||
update.done = TRUE;
|
||||
|
||||
_wintc_ishext_view_items_added(view, &update);
|
||||
|
||||
g_list_free(items);
|
||||
g_warning("%s Not Implemented", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void wintc_view_zip_get_actions_for_item(
|
||||
WINTC_UNUSED(WinTCIShextView* view),
|
||||
WINTC_UNUSED(WinTCShextViewItem* item)
|
||||
)
|
||||
{
|
||||
g_critical("%s Not Implemented", __func__);
|
||||
}
|
||||
|
||||
static void wintc_view_zip_get_actions_for_view(
|
||||
static GMenuModel* wintc_view_zip_get_operations_for_view(
|
||||
WINTC_UNUSED(WinTCIShextView* view)
|
||||
)
|
||||
{
|
||||
g_critical("%s Not Implemented", __func__);
|
||||
g_warning("%s Not Implemented", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const gchar* wintc_view_zip_get_display_name(
|
||||
@@ -562,6 +463,107 @@ static gboolean wintc_view_zip_has_parent(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void wintc_view_zip_refresh_items(
|
||||
WinTCIShextView* view
|
||||
)
|
||||
{
|
||||
WinTCViewZip* view_zip = WINTC_VIEW_ZIP(view);
|
||||
|
||||
WINTC_LOG_DEBUG("%s", "shext-zip: refresh zip view");
|
||||
|
||||
_wintc_ishext_view_refreshing(view);
|
||||
|
||||
if (view_zip->map_items)
|
||||
{
|
||||
g_hash_table_destroy(
|
||||
g_steal_pointer(&(view_zip->map_items))
|
||||
);
|
||||
}
|
||||
|
||||
view_zip->map_items =
|
||||
g_hash_table_new_full(
|
||||
g_direct_hash,
|
||||
g_direct_equal,
|
||||
NULL,
|
||||
(GDestroyNotify) clear_view_item
|
||||
);
|
||||
|
||||
// Open the archive
|
||||
//
|
||||
const gchar* path = view_zip->zip_uri + strlen("file://");
|
||||
|
||||
gint zip_error = 0;
|
||||
zip_t* zip_file = zip_open(path, 0, &zip_error);
|
||||
|
||||
if (!zip_file)
|
||||
{
|
||||
zip_error_t zip_error_st;
|
||||
|
||||
zip_error_init_with_code(&zip_error_st, zip_error);
|
||||
|
||||
// FIXME: Need a proper way of returning error to caller!
|
||||
g_critical(
|
||||
"shext-zip: can't open %s , %s",
|
||||
path,
|
||||
zip_error_strerror(&zip_error_st)
|
||||
);
|
||||
|
||||
zip_error_fini(&zip_error_st);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Read through the entries
|
||||
// FIXME: Probably want to cap max num of entries? Check zip bombs to see
|
||||
// what happens - don't want to get nuked by a crazy zip archive
|
||||
//
|
||||
gint64 n_entries = zip_get_num_entries(zip_file, 0);
|
||||
|
||||
for (gint64 i = 0; i < n_entries; i++)
|
||||
{
|
||||
const gchar* entry_name = zip_get_name(zip_file, (guint64) i, 0);
|
||||
|
||||
// Only want to add the entries in the current relative dir
|
||||
//
|
||||
gint name_offset = 0;
|
||||
|
||||
if (!zip_entry_is_in_dir(view_zip->rel_path, entry_name, &name_offset))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
gchar* entry_copy = g_strdup(entry_name);
|
||||
WinTCShextViewItem* item = g_new(WinTCShextViewItem, 1);
|
||||
|
||||
item->display_name = entry_copy + name_offset;
|
||||
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;
|
||||
|
||||
g_hash_table_insert(
|
||||
view_zip->map_items,
|
||||
GUINT_TO_POINTER(item->hash),
|
||||
item
|
||||
);
|
||||
}
|
||||
|
||||
zip_close(zip_file);
|
||||
|
||||
// Emit the entries
|
||||
//
|
||||
WinTCShextViewItemsUpdate update = { 0 };
|
||||
|
||||
GList* items = g_hash_table_get_values(view_zip->map_items);
|
||||
|
||||
update.data = items;
|
||||
update.done = TRUE;
|
||||
|
||||
_wintc_ishext_view_items_added(view, &update);
|
||||
|
||||
g_list_free(items);
|
||||
}
|
||||
|
||||
//
|
||||
// PUBLIC FUNCTIONS
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user