Dne čtvrtek 12 únor 2009 Vladimir Nadvornik napsal(a):
> Dne neděle 08 únor 2009 Vladimir Nadvornik napsal(a):
> > Hi,
> >
> > The current implementation of sidebars has several problems:
> >
> > - Keywords bar needs more entries, like Title or Copyright
> > - Advanced exif is too wide
> > - Exif and Keywords together are too wide
> > - some possible new entries does not fit anywhere in the existing
> > sidebars (for example Histogram), adding new sidebars would cause more
> > problems with multiple sidebars together
> > - Sort manager is OK, even in combination with another sidebar
> >
> >
> > Proposal:
> > - Combine Exif and Keywords into one sidebar, which will be typically
> > longer than main window, with a scrollbar and expanders. Any additional
> > entries (Histogram) will go there too.
> > - Advanced exif will be in a separate window
> > - Sort manager will stay unchanged
> > - Edit/Properties will be dropped
> >
> >
> > The attached patch is a proof of concept that adds more entries with
> > expanders to the Keywords bar.
>
> Here is another experimental patch, that implements an interface
> for sidebar panes and a simple text pane for editing metadata.
> Right-clicking on the expander opens a popup menu that allows further
> configuration (move pane up or down for now).
>
Second try ;)
Index: bar_comment.c
===================================================================
--- bar_comment.c (revision 0)
+++ bar_comment.c (revision 0)
@@ -0,0 +1,189 @@
+/*
+ * Geeqie
+ * (C) 2004 John Ellis
+ * Copyright (C) 2008 - 2009 The Geeqie Team
+ *
+ * Author: John Ellis
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+
+#include "main.h"
+#include "bar_comment.h"
+
+#include "bar.h"
+#include "metadata.h"
+#include "filedata.h"
+
+static void bar_pane_comment_changed(GtkTextBuffer *buffer, gpointer data);
+
+/*
+ *-------------------------------------------------------------------
+ * keyword / comment utils
+ *-------------------------------------------------------------------
+ */
+
+
+static gchar *comment_pull(GtkWidget *textview)
+{
+ GtkTextBuffer *buffer;
+ GtkTextIter start, end;
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+
+ return gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
+}
+
+
+typedef struct _PaneCommentData PaneCommentData;
+struct _PaneCommentData
+{
+ PaneData pane;
+ GtkWidget *widget;
+ GtkWidget *comment_view;
+ FileData *fd;
+ gchar *key;
+};
+
+
+static void bar_pane_comment_write(PaneCommentData *pcd)
+{
+ gchar *comment;
+
+ if (!pcd->fd) return;
+
+ comment = comment_pull(pcd->comment_view);
+ metadata_write_string(pcd->fd, pcd->key, comment);
+ g_free(comment);
+}
+
+
+static void bar_pane_comment_update(PaneCommentData *pcd)
+{
+ gchar *comment = NULL;
+ GtkTextBuffer *comment_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pcd->comment_view));
+
+ g_signal_handlers_block_by_func(comment_buffer, bar_pane_comment_changed, pcd);
+
+ comment = metadata_read_string(pcd->fd, pcd->key, METADATA_PLAIN);
+ gtk_text_buffer_set_text(comment_buffer,
+ (comment) ? comment : "", -1);
+ g_free(comment);
+
+ g_signal_handlers_unblock_by_func(comment_buffer, bar_pane_comment_changed, pcd);
+
+ gtk_widget_set_sensitive(pcd->comment_view, (pcd->fd != NULL));
+}
+
+static void bar_pane_comment_set_fd(GtkWidget *bar, FileData *fd)
+{
+ PaneCommentData *pcd;
+
+ pcd = g_object_get_data(G_OBJECT(bar), "pane_data");
+ if (!pcd) return;
+
+ file_data_unref(pcd->fd);
+ pcd->fd = file_data_ref(fd);
+
+ bar_pane_comment_update(pcd);
+}
+
+gint bar_pane_comment_event(GtkWidget *bar, GdkEvent *event)
+{
+ PaneCommentData *pcd;
+
+ pcd = g_object_get_data(G_OBJECT(bar), "pane_data");
+ if (!pcd) return FALSE;
+
+ if (GTK_WIDGET_HAS_FOCUS(pcd->comment_view)) return gtk_widget_event(pcd->comment_view, event);
+
+ return FALSE;
+}
+
+static void bar_pane_comment_notify_cb(FileData *fd, NotifyType type, gpointer data)
+{
+ PaneCommentData *pcd = data;
+ if (fd == pcd->fd) bar_pane_comment_update(pcd);
+}
+
+static void bar_pane_comment_changed(GtkTextBuffer *buffer, gpointer data)
+{
+ PaneCommentData *pcd = data;
+
+ file_data_unregister_notify_func(bar_pane_comment_notify_cb, pcd);
+ bar_pane_comment_write(pcd);
+ file_data_register_notify_func(bar_pane_comment_notify_cb, pcd, NOTIFY_PRIORITY_LOW);
+}
+
+static void bar_pane_comment_close(GtkWidget *bar)
+{
+ PaneCommentData *pcd;
+
+ pcd = g_object_get_data(G_OBJECT(bar), "pane_data");
+ if (!pcd) return;
+
+ gtk_widget_destroy(pcd->comment_view);
+}
+
+static void bar_pane_comment_destroy(GtkWidget *widget, gpointer data)
+{
+ PaneCommentData *pcd = data;
+
+ file_data_unregister_notify_func(bar_pane_comment_notify_cb, pcd);
+
+ file_data_unref(pcd->fd);
+ g_free(pcd->pane.title);
+ g_free(pcd->key);
+
+
+ g_free(pcd);
+}
+
+
+GtkWidget *bar_pane_comment_new(const gchar *title, const gchar *key, gint height)
+{
+ PaneCommentData *pcd;
+ GtkWidget *scrolled;
+ GtkTextBuffer *buffer;
+
+ pcd = g_new0(PaneCommentData, 1);
+
+ pcd->pane.pane_set_fd = bar_pane_comment_set_fd;
+ pcd->pane.pane_event = bar_pane_comment_event;
+ pcd->pane.title = g_strdup(title);
+
+ pcd->key = g_strdup(key);
+
+ scrolled = gtk_scrolled_window_new(NULL, NULL);
+
+ pcd->widget = scrolled;
+ g_object_set_data(G_OBJECT(pcd->widget), "pane_data", pcd);
+ g_signal_connect(G_OBJECT(pcd->widget), "destroy",
+ G_CALLBACK(bar_pane_comment_destroy), pcd);
+
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ gtk_widget_set_size_request(scrolled, -1, height);
+ gtk_widget_show(scrolled);
+
+ pcd->comment_view = gtk_text_view_new();
+ gtk_container_add(GTK_CONTAINER(scrolled), pcd->comment_view);
+ gtk_widget_show(pcd->comment_view);
+
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(pcd->comment_view));
+ g_signal_connect(G_OBJECT(buffer), "changed",
+ G_CALLBACK(bar_pane_comment_changed), pcd);
+
+
+ file_data_register_notify_func(bar_pane_comment_notify_cb, pcd, NOTIFY_PRIORITY_LOW);
+
+ return pcd->widget;
+}
+
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
Index: bar_comment.h
===================================================================
--- bar_comment.h (revision 0)
+++ bar_comment.h (revision 0)
@@ -0,0 +1,20 @@
+/*
+ * Geeqie
+ * (C) 2004 John Ellis
+ * Copyright (C) 2008 - 2009 The Geeqie Team
+ *
+ * Author: Vladimir Nadvornik
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+
+#ifndef BAR_COMMENT_H
+#define BAR_COMMENT_H
+
+GtkWidget *bar_pane_comment_new(const gchar *title, const gchar *key, gint height);
+
+#endif
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
Index: bar.c
===================================================================
--- bar.c (revision 0)
+++ bar.c (revision 0)
@@ -0,0 +1,210 @@
+/*
+ * Geeqie
+ * (C) 2004 John Ellis
+ * Copyright (C) 2008 - 2009 The Geeqie Team
+ *
+ * Author: Vladimir Nadvornik
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+
+#include "main.h"
+#include "bar.h"
+
+#include "filedata.h"
+#include "history_list.h"
+#include "info.h"
+#include "metadata.h"
+#include "misc.h"
+#include "ui_fileops.h"
+#include "ui_misc.h"
+#include "ui_utildlg.h"
+
+#include "ui_menu.h"
+#include "bar_comment.h"
+
+
+typedef struct _BarData BarData;
+struct _BarData
+{
+ GtkWidget *widget;
+ GtkWidget *vbox;
+};
+
+static void bar_expander_move(GtkWidget *widget, gpointer data, gboolean up)
+{
+ GtkWidget *expander = data;
+ GtkWidget *box;
+ gint pos;
+ if (!expander) return;
+ box = gtk_widget_get_ancestor(expander, GTK_TYPE_BOX);
+ if (!box) return;
+
+ gtk_container_child_get(GTK_CONTAINER(box), expander, "position", &pos, NULL);
+
+ pos = up ? (pos - 1) : (pos + 1);
+ if (pos < 0) pos = 0;
+
+ gtk_box_reorder_child(GTK_BOX(box), expander, pos);
+}
+
+
+static void bar_expander_move_up_cb(GtkWidget *widget, gpointer data)
+{
+ bar_expander_move(widget, data, TRUE);
+}
+
+static void bar_expander_move_down_cb(GtkWidget *widget, gpointer data)
+{
+ bar_expander_move(widget, data, FALSE);
+}
+
+
+static void bar_expander_menu_popup(GtkWidget *data)
+{
+ GtkWidget *menu;
+ GtkWidget *item;
+
+ menu = popup_menu_short_lived();
+
+ menu_item_add_stock(menu, _("Move _up"), GTK_STOCK_GO_UP, G_CALLBACK(bar_expander_move_up_cb), data);
+ menu_item_add_stock(menu, _("Move _down"), GTK_STOCK_GO_DOWN, G_CALLBACK(bar_expander_move_down_cb), data);
+ gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, data, 0, GDK_CURRENT_TIME);
+}
+
+
+static gboolean bar_expander_menu_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data)
+{
+ BarData *bd = data;
+ if (bevent->button == MOUSE_BUTTON_RIGHT)
+ {
+ bar_expander_menu_popup(widget);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+void bar_pane_set_fd_cb(GtkWidget *expander, gpointer data)
+{
+ GtkWidget *widget = gtk_bin_get_child(GTK_BIN(expander));
+ PaneData *pd = g_object_get_data(G_OBJECT(widget), "pane_data");
+ if (!pd) return;
+ if (pd->pane_set_fd) pd->pane_set_fd(widget, data);
+}
+
+void bar_set_fd(GtkWidget *bar, FileData *fd)
+{
+ BarData *bd;
+ bd = g_object_get_data(G_OBJECT(bar), "bar_data");
+ if (!bd) return;
+
+ gtk_container_foreach(bd->vbox, bar_pane_set_fd_cb, fd);
+}
+
+void bar_pane_event_cb(GtkWidget *expander, gpointer data)
+{
+ GtkWidget *widget = gtk_bin_get_child(GTK_BIN(expander));
+ PaneData *pd = g_object_get_data(G_OBJECT(widget), "pane_data");
+ if (!pd) return;
+
+ if (pd->pane_event) pd->pane_event(widget, data);
+}
+
+gint bar_event(GtkWidget *bar, GdkEvent *event)
+{
+ BarData *bd;
+ bd = g_object_get_data(G_OBJECT(bar), "bar_data");
+ if (!bd) return;
+
+ gtk_container_foreach(bd->vbox, bar_pane_event_cb, event);
+}
+
+
+
+
+
+
+static void bar_add(GtkWidget *bar, GtkWidget *pane)
+{
+ GtkWidget *expander;
+ GtkWidget *hbox;
+ GtkWidget *label;
+ GtkWidget *button;
+ BarData *bd = g_object_get_data(G_OBJECT(bar), "bar_data");
+ PaneData *pd = g_object_get_data(G_OBJECT(pane), "pane_data");
+
+
+ if (!bd || !pd) return;
+
+ expander = gtk_expander_new(pd->title);
+ gtk_box_pack_start(bd->vbox, expander, FALSE, TRUE, 0);
+
+ g_signal_connect(expander, "button_press_event", G_CALLBACK(bar_expander_menu_cb), bd);
+
+ label = gtk_expander_get_label_widget(expander);
+// gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
+ pref_label_bold(label, TRUE, FALSE);
+
+ gtk_container_add (GTK_CONTAINER (expander), pane);
+
+ gtk_widget_show(expander);
+}
+
+static void bar_destroy(GtkWidget *widget, gpointer data)
+{
+ BarData *bd = data;
+
+ g_free(bd);
+}
+
+GtkWidget *bar_new(GtkWidget *bounding_widget)
+{
+ BarData *bd;
+// GtkWidget *box;
+// GtkWidget *hbox;
+// GtkWidget *table;
+ GtkWidget *scrolled;
+ GtkWidget *label;
+ GtkWidget *widget;
+
+ bd = g_new0(BarData, 1);
+
+ bd->widget = gtk_vbox_new(FALSE, PREF_PAD_GAP);
+ g_object_set_data(G_OBJECT(bd->widget), "bar_data", bd);
+ g_signal_connect(G_OBJECT(bd->widget), "destroy",
+ G_CALLBACK(bar_destroy), bd);
+
+
+ scrolled = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_box_pack_start(GTK_BOX(bd->widget), scrolled, TRUE, TRUE, 0);
+ gtk_widget_show(scrolled);
+
+
+ bd->vbox = gtk_vbox_new(FALSE, 0);
+ gtk_scrolled_window_add_with_viewport(scrolled, bd->vbox);
+ gtk_viewport_set_shadow_type(gtk_bin_get_child(scrolled), GTK_SHADOW_NONE);
+
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_NONE);
+ gtk_widget_show(bd->vbox);
+
+
+ widget = bar_pane_comment_new("Title", "Xmp.dc.title", 30);
+ bar_add(bd->widget, widget);
+
+ widget = bar_pane_comment_new("Comment (dc.description)", "Xmp.dc.description", 300);
+ bar_add(bd->widget, widget);
+
+ widget = bar_pane_comment_new("Comment (exif.UserComment)", "Xmp.exif.UserComment", 300);
+ bar_add(bd->widget, widget);
+
+ return bd->widget;
+}
+
+
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
Index: bar.h
===================================================================
--- bar.h (revision 0)
+++ bar.h (revision 0)
@@ -0,0 +1,34 @@
+/*
+ * Geeqie
+ * (C) 2004 John Ellis
+ * Copyright (C) 2008 - 2009 The Geeqie Team
+ *
+ * Author: Vladimir Nadvornik
+ *
+ * This software is released under the GNU General Public License (GNU GPL).
+ * Please read the included file COPYING for more information.
+ * This software comes with no warranty of any kind, use at your own risk!
+ */
+
+
+#ifndef BAR_H
+#define BAR_H
+
+typedef struct _PaneData PaneData;
+
+struct _PaneData {
+ void (*pane_set_fd)(GtkWidget *pane, FileData *fd);
+ gint (*pane_event)(GtkWidget *pane, GdkEvent *event);
+ gchar *title;
+};
+
+
+
+GtkWidget *bar_new(GtkWidget *bounding_widget);
+
+void bar_set_fd(GtkWidget *bar, FileData *fd);
+gint bar_event(GtkWidget *bar, GdkEvent *event);
+
+
+#endif
+/* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */
Index: Makefile.am
===================================================================
--- Makefile.am (revision 1386)
+++ Makefile.am (working copy)
@@ -76,6 +76,10 @@
$(module_SLIK) \
ClayRGB1998.icc \
ClayRGB1998_icc.h \
+ bar.c \
+ bar.h \
+ bar_comment.c \
+ bar+comment.h \
bar_info.c \
bar_info.h \
bar_exif.c \
Index: remote.c
===================================================================
--- remote.c (revision 1386)
+++ remote.c (working copy)
@@ -235,6 +235,8 @@
rc->clients = NULL;
channel = g_io_channel_unix_new(rc->fd);
+ g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
+
rc->channel_id = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, G_IO_IN,
remote_server_read_cb, rc, NULL);
g_io_channel_unref(channel);
Index: view_file_list.c
===================================================================
--- view_file_list.c (revision 1386)
+++ view_file_list.c (working copy)
@@ -14,6 +14,7 @@
#include "view_file_list.h"
#include "bar_info.h"
+#include "bar.h"
#include "cache_maint.h"
#include "dnd.h"
#include "editors.h"
@@ -327,7 +328,7 @@
string_list_free(kw_list);
g_free(str);
if (vf->layout && vf->layout->bar_info) {
- bar_info_set(vf->layout->bar_info, fd);
+ bar_set_fd(vf->layout->bar_info, fd);
}
}
}
Index: layout_util.c
===================================================================
--- layout_util.c (revision 1386)
+++ layout_util.c (working copy)
@@ -17,6 +17,7 @@
#include "bar_exif.h"
#include "bar_info.h"
#include "bar_sort.h"
+#include "bar.h"
#include "cache_maint.h"
#include "collect.h"
#include "collect-dlg.h"
@@ -105,7 +106,7 @@
return TRUE;
}
if (lw->bar_info &&
- bar_info_event(lw->bar_info, (GdkEvent *)event))
+ bar_event(lw->bar_info, (GdkEvent *)event))
{
return TRUE;
}
@@ -1991,9 +1992,10 @@
{
if (!lw->utility_box) return;
- lw->bar_info = bar_info_new(layout_image_get_fd(lw), FALSE, lw->utility_box);
- bar_info_set_selection_func(lw->bar_info, layout_bar_info_list_cb, lw);
- bar_info_selection(lw->bar_info, layout_selection_count(lw, NULL) - 1);
+// lw->bar_info = bar_info_new(layout_image_get_fd(lw), FALSE, lw->utility_box);
+ lw->bar_info = bar_new(lw->utility_box);
+// bar_info_set_selection_func(lw->bar_info, layout_bar_info_list_cb, lw);
+// bar_info_selection(lw->bar_info, layout_selection_count(lw, NULL) - 1);
g_signal_connect(G_OBJECT(lw->bar_info), "destroy",
G_CALLBACK(layout_bar_info_destroyed), lw);
g_signal_connect(G_OBJECT(lw->bar_info), "size_allocate",
@@ -2010,7 +2012,8 @@
{
if (lw->bar_info)
{
- bar_info_close(lw->bar_info);
+// bar_info_close(lw->bar_info);
+// bar_close(lw->bar_info);
lw->bar_info = NULL;
}
options->panels.info.enabled = lw->bar_info_enabled = FALSE;
@@ -2032,7 +2035,7 @@
{
if (!lw->bar_info || !lw->bar_info_enabled) return;
- bar_info_set(lw->bar_info, layout_image_get_fd(lw));
+ bar_set_fd(lw->bar_info, layout_image_get_fd(lw));
}
static void layout_bar_info_new_selection(LayoutWindow *lw, gint count)
Index: view_file_icon.c
===================================================================
--- view_file_icon.c (revision 1386)
+++ view_file_icon.c (working copy)
@@ -14,6 +14,7 @@
#include "view_file_icon.h"
#include "bar_info.h"
+#include "bar.h"
#include "cellrenderericon.h"
#include "collect.h"
#include "collect-io.h"
@@ -572,7 +573,7 @@
string_list_free(kw_list);
g_free(str);
if (vf->layout && vf->layout->bar_info) {
- bar_info_set(vf->layout->bar_info, id->fd);
+ bar_set_fd(vf->layout->bar_info, id->fd);
}
}
}
------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Geeqie-devel mailing list
Geeqie-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geeqie-devel