static gboolean remote_server_client_cb(GIOChannel *source, GIOCondition condition, gpointer data)
{
- RemoteClient *client = data;
+ RemoteClient *client = static_cast<RemoteClient *>(data);
RemoteConnection *rc;
GIOStatus status = G_IO_STATUS_NORMAL;
client->fd = fd;
channel = g_io_channel_unix_new(fd);
- client->channel_id = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, G_IO_IN | G_IO_HUP,
+ client->channel_id = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, static_cast<GIOCondition>(G_IO_IN | G_IO_HUP),
remote_server_client_cb, client, NULL);
g_io_channel_unref(channel);
{
while (rc->clients)
{
- RemoteClient *client = rc->clients->data;
+ RemoteClient *client = static_cast<RemoteClient *>(rc->clients->data);
rc->clients = g_list_remove(rc->clients, client);
static gboolean remote_server_read_cb(GIOChannel *UNUSED(source), GIOCondition UNUSED(condition), gpointer data)
{
- RemoteConnection *rc = data;
+ RemoteConnection *rc = static_cast<RemoteConnection *>(data);
gint fd;
guint alen;
layout_set_path(lw_id, pwd);
}
-static gboolean gr_close_window_cb()
+static gboolean gr_close_window_cb(gpointer UNUSED(data))
{
if (!layout_valid(&lw_id)) return FALSE;
static void gr_close_window(const gchar *UNUSED(text), GIOChannel *UNUSED(channel), gpointer UNUSED(data))
{
- g_idle_add(gr_close_window_cb, NULL);
+ g_idle_add((gr_close_window_cb), NULL);
}
static void gr_image_prev(const gchar *UNUSED(text), GIOChannel *UNUSED(channel), gpointer UNUSED(data))
work = list;
while (work)
{
- fd = work->data;
+ fd = static_cast<FileData *>(work->data);
g_string_append_printf(out_string, "%s", fd->path);
format_class = filter_file_get_class(fd->path);
file_data_unref(dir_fd);
}
-static void gr_get_selection(const gchar *UNUSED(text), GIOChannel *channel, gboolean UNUSED(data))
+static void gr_get_selection(const gchar *UNUSED(text), GIOChannel *channel, gpointer UNUSED(data))
{
if (!layout_valid(&lw_id)) return;
GList *work = selected;
while (work)
{
- FileData *fd = work->data;
+ FileData *fd = static_cast<FileData *>(work->data);
g_assert(fd->magick == FD_MAGICK);
g_string_append_printf(out_string, "%s %s\n",
g_string_free(out_string, TRUE);
}
+static void gr_selection_add(const gchar *text, GIOChannel *UNUSED(channel), gpointer UNUSED(data))
+{
+ if (!layout_valid(&lw_id)) return;
+
+ FileData *fd_to_select = NULL;
+ if (strcmp(text, "") == 0)
+ {
+ // No file specified, use current fd.
+ fd_to_select = layout_image_get_fd(lw_id);
+ }
+ else
+ {
+ // Search through the current file list for a file matching the specified path.
+ // "Match" is either a basename match or a file path match.
+ gchar *path = expand_tilde(text);
+ gchar *filename = g_path_get_basename(path);
+ gchar *slash_plus_filename = g_strdup_printf("%s%s", G_DIR_SEPARATOR_S, filename);
+
+ GList *file_list = layout_list(lw_id);
+ for (GList *work = file_list; work && !fd_to_select; work = work->next)
+ {
+ FileData *fd = static_cast<FileData *>(work->data);
+ if (!strcmp(path, fd->path) || g_str_has_suffix(fd->path, slash_plus_filename))
+ {
+ fd_to_select = file_data_ref(fd);
+ continue; // will exit loop.
+ }
+
+ for (GList *sidecar = fd->sidecar_files; sidecar && !fd_to_select; sidecar = sidecar->next)
+ {
+ FileData *side_fd = static_cast<FileData *>(sidecar->data);
+ if (!strcmp(path, side_fd->path)
+ || g_str_has_suffix(side_fd->path, slash_plus_filename))
+ {
+ fd_to_select = file_data_ref(side_fd);
+ continue; // will exit both nested loops.
+ }
+ }
+ }
+
+ if (!fd_to_select)
+ {
+ log_printf("remote sent --selection-add filename that could not be found: \"%s\"\n",
+ filename);
+ }
+
+ filelist_free(file_list);
+ g_free(slash_plus_filename);
+ g_free(filename);
+ g_free(path);
+ }
+
+ if (fd_to_select)
+ {
+ GList *to_select = g_list_append(NULL, fd_to_select);
+ // Using the "_list" variant doesn't clear the existing selection.
+ layout_select_list(lw_id, to_select);
+ filelist_free(to_select);
+ }
+}
+
+static void gr_selection_clear(const gchar *UNUSED(text), GIOChannel *UNUSED(channel), gpointer UNUSED(data))
+{
+ layout_select_none(lw_id); // Checks lw_id validity internally.
+}
+
+static void gr_selection_remove(const gchar *text, GIOChannel *UNUSED(channel), gpointer UNUSED(data))
+{
+ if (!layout_valid(&lw_id)) return;
+
+ GList *selected = layout_selection_list(lw_id); // Keep copy to free.
+ if (!selected)
+ {
+ log_printf("remote sent --selection-remove with empty selection.");
+ return;
+ }
+
+ FileData *fd_to_deselect = NULL;
+ gchar *path = NULL;
+ gchar *filename = NULL;
+ gchar *slash_plus_filename = NULL;
+ if (strcmp(text, "") == 0)
+ {
+ // No file specified, use current fd.
+ fd_to_deselect = layout_image_get_fd(lw_id);
+ if (!fd_to_deselect)
+ {
+ log_printf("remote sent \"--selection-remove:\" with no current image");
+ filelist_free(selected);
+ return;
+ }
+ }
+ else
+ {
+ // Search through the selection list for a file matching the specified path.
+ // "Match" is either a basename match or a file path match.
+ path = expand_tilde(text);
+ filename = g_path_get_basename(path);
+ slash_plus_filename = g_strdup_printf("%s%s", G_DIR_SEPARATOR_S, filename);
+ }
+
+ GList *prior_link = NULL; // Stash base for link removal to avoid a second traversal.
+ GList *link_to_remove = NULL;
+ for (GList *work = selected; work; prior_link = work, work = work->next)
+ {
+ FileData *fd = static_cast<FileData *>(work->data);
+ if (fd_to_deselect)
+ {
+ if (fd == fd_to_deselect)
+ {
+ link_to_remove = work;
+ break;
+ }
+ }
+ else
+ {
+ // path, filename, and slash_plus_filename should be defined.
+
+ if (!strcmp(path, fd->path) || g_str_has_suffix(fd->path, slash_plus_filename))
+ {
+ link_to_remove = work;
+ break;
+ }
+ }
+ }
+
+ if (!link_to_remove)
+ {
+ if (fd_to_deselect)
+ {
+ log_printf("remote sent \"--selection-remove:\" but current image is not selected");
+ }
+ else
+ {
+ log_printf("remote sent \"--selection-remove:%s\" but that filename is not selected",
+ filename);
+ }
+ }
+ else
+ {
+ if (link_to_remove == selected)
+ {
+ // Remove first link.
+ selected = g_list_remove_link(selected, link_to_remove);
+ filelist_free(link_to_remove);
+ link_to_remove = NULL;
+ }
+ else
+ {
+ // Remove a subsequent link.
+ prior_link = g_list_remove_link(prior_link, link_to_remove);
+ filelist_free(link_to_remove);
+ link_to_remove = NULL;
+ }
+
+ // Re-select all but the deselected item.
+ layout_select_none(lw_id);
+ layout_select_list(lw_id, selected);
+ }
+
+ filelist_free(selected);
+ file_data_unref(fd_to_deselect);
+ g_free(slash_plus_filename);
+ g_free(filename);
+ g_free(path);
+}
+
static void gr_collection(const gchar *text, GIOChannel *channel, gpointer UNUSED(data))
{
GString *contents = g_string_new(NULL);
work = collection_list;
while (work)
{
- const gchar *collection_name = work->data;
+ const gchar *collection_name = static_cast<const gchar *>(work->data);
out_string = g_string_append(out_string, g_strdup(collection_name));
out_string = g_string_append(out_string, "\n");
while (work)
{
- fd = work->data;
+ fd = static_cast<FileData *>(work->data);
work = work->next;
g_io_channel_write_chars(channel, fd->path, -1, NULL, NULL);
g_io_channel_write_chars(channel, "<gq_end_of_command>", -1, NULL, NULL);
static void gr_list_clear(const gchar *UNUSED(text), GIOChannel *UNUSED(channel), gpointer data)
{
- RemoteData *remote_data = data;
+ RemoteData *remote_data = static_cast<RemoteData *>(data);
remote_data->command_collection = NULL;
remote_data->file_list = NULL;
static void gr_list_add(const gchar *text, GIOChannel *UNUSED(channel), gpointer data)
{
- RemoteData *remote_data = data;
+ RemoteData *remote_data = static_cast<RemoteData *>(data);
gboolean is_new = TRUE;
gchar *path = NULL;
FileData *fd;
typedef struct _RemoteCommandEntry RemoteCommandEntry;
struct _RemoteCommandEntry {
- gchar *opt_s;
- gchar *opt_l;
+ const gchar *opt_s;
+ const gchar *opt_l;
void (*func)(const gchar *text, GIOChannel *channel, gpointer data);
gboolean needs_extra;
gboolean prefer_command_line;
- gchar *parameter;
- gchar *description;
+ const gchar *parameter;
+ const gchar *description;
};
static RemoteCommandEntry remote_commands[] = {
{ "-q", "--quit", gr_quit, FALSE, FALSE, NULL, N_("quit") },
{ NULL, "--raise", gr_raise, FALSE, FALSE, NULL, N_("bring the Geeqie window to the top") },
{ NULL, "raise", gr_raise, FALSE, FALSE, NULL, N_("bring the Geeqie window to the top") },
+ { NULL, "--selection-add:", gr_selection_add, TRUE, FALSE, N_("[<FILE>]"), N_("adds the current file (or the specified file) to the current selection") },
+ { NULL, "--selection-clear", gr_selection_clear, FALSE, FALSE, NULL, N_("clears the current selection") },
+ { NULL, "--selection-remove:", gr_selection_remove, TRUE, FALSE, N_("[<FILE>]"), N_("removes the current file (or the specified file) from the current selection") },
{ "-s", "--slideshow", gr_slideshow_toggle, FALSE, TRUE, NULL, N_("toggle slide show") },
{ NULL, "--slideshow-recurse:", gr_slideshow_start_rec, TRUE, FALSE, N_("<FOLDER>"), N_("start recursive slide show in FOLDER") },
{ "-ss","--slideshow-start", gr_slideshow_start, FALSE, FALSE, NULL, N_("start slide show") },
gchar *text;
RemoteCommandEntry *entry;
- text = work->data;
+ text = static_cast<gchar *>(work->data);
work = work->next;
entry = remote_command_find(text, NULL);
gchar *text;
RemoteCommandEntry *entry;
- text = work->data;
+ text = static_cast<gchar *>(work->data);
work = work->next;
entry = remote_command_find(text, NULL);
const gchar *name;
gchar *text;
- name = work->data;
+ name = static_cast<const gchar *>(work->data);
work = work->next;
text = g_strdup_printf("file:%s", name);