*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
*/
#ifdef HAVE_CONFIG_H
#include "gtk/logwindow.h"
#include "timing.h"
+#ifdef MAEMO
+//#include <hildon-widgets/hildon-program.h>
+//#include <gtk/gtkmain.h>
+#include <libosso.h>
+#include <osso-mime.h>
+#endif
+
typedef enum
{
COL_MIMETYPE = 0,
MimeInfo *partinfo,
gboolean automatic);
static void mimeview_select_next_part (MimeView *mimeview);
+static void mimeview_select_prev_part (MimeView *mimeview);
static void mimeview_view_file (const gchar *filename,
MimeInfo *partinfo,
const gchar *cmd,
static gint icon_key_pressed (GtkWidget *button,
GdkEventKey *event,
MimeView *mimeview);
-static void toggle_icon (GtkToggleButton *button,
- MimeView *mimeview);
static void icon_list_append_icon (MimeView *mimeview,
MimeInfo *mimeinfo);
static void icon_list_create (MimeView *mimeview,
static void icon_list_clear (MimeView *mimeview);
static void icon_list_toggle_by_mime_info (MimeView *mimeview,
MimeInfo *mimeinfo);
-static gboolean icon_list_select_by_number(MimeView *mimeview,
- gint number);
-static void mime_toggle_button_cb (GtkWidget *button,
- MimeView *mimeview);
+static gint mime_toggle_button_cb(GtkWidget *button, GdkEventButton *event,
+ MimeView *mimeview);
static gboolean part_button_pressed (MimeView *mimeview,
GdkEventButton *event,
MimeInfo *partinfo);
static GtkItemFactoryEntry mimeview_popup_entries[] =
{
{N_("/_Open (l)"), NULL, mimeview_launch_cb, 0, NULL},
+#ifndef MAEMO
{N_("/Open _with (o)..."), NULL, mimeview_open_with, 0, NULL},
+#endif
{N_("/_Display as text (t)"), NULL, mimeview_display_as_text, 0, NULL},
{N_("/_Save as (y)..."), NULL, mimeview_save_as, 0, NULL},
{N_("/Save _all..."), NULL, mimeview_save_all, 0, NULL},
GSList *mimeviewer_factories;
GSList *mimeviews;
+static GdkCursor *hand_cursor = NULL;
+
+static gboolean mimeview_visi_notify(GtkWidget *widget,
+ GdkEventVisibility *event,
+ MimeView *mimeview)
+{
+ gdk_window_set_cursor(widget->window, hand_cursor);
+ return FALSE;
+}
+
+static gboolean mimeview_leave_notify(GtkWidget *widget,
+ GdkEventCrossing *event,
+ MimeView *mimeview)
+{
+ gdk_window_set_cursor(widget->window, NULL);
+ return FALSE;
+}
+
+static gboolean mimeview_enter_notify(GtkWidget *widget,
+ GdkEventCrossing *event,
+ MimeView *mimeview)
+{
+ gdk_window_set_cursor(widget->window, hand_cursor);
+ return FALSE;
+}
+
MimeView *mimeview_create(MainWindow *mainwin)
{
MimeView *mimeview;
gint n_entries;
gint i;
+ if (!hand_cursor)
+ hand_cursor = gdk_cursor_new(GDK_HAND2);
+
debug_print("Creating MIME view...\n");
mimeview = g_new0(MimeView, 1);
g_signal_connect(G_OBJECT(icon_scroll), "scroll_event",
G_CALLBACK(mimeview_scrolled), mimeview);
- mime_toggle = gtk_toggle_button_new();
+ mime_toggle = gtk_event_box_new();
+ gtk_event_box_set_visible_window(GTK_EVENT_BOX(mime_toggle), FALSE);
+
+ g_signal_connect(G_OBJECT(mime_toggle), "visibility-notify-event",
+ G_CALLBACK(mimeview_visi_notify), mimeview);
+ g_signal_connect(G_OBJECT(mime_toggle), "motion-notify-event",
+ G_CALLBACK(mimeview_visi_notify), mimeview);
+ g_signal_connect(G_OBJECT(mime_toggle), "leave-notify-event",
+ G_CALLBACK(mimeview_leave_notify), mimeview);
+ g_signal_connect(G_OBJECT(mime_toggle), "enter-notify-event",
+ G_CALLBACK(mimeview_enter_notify), mimeview);
+
+ gtk_container_set_border_width(GTK_CONTAINER(mime_toggle), 2);
gtk_widget_show(mime_toggle);
+ mimeview->ctree_mode = FALSE;
arrow = gtk_arrow_new(GTK_ARROW_LEFT, GTK_SHADOW_NONE);
gtk_widget_show(arrow);
gtk_container_add(GTK_CONTAINER(mime_toggle), arrow);
- g_signal_connect(G_OBJECT(mime_toggle), "toggled",
+ g_signal_connect(G_OBJECT(mime_toggle), "button_release_event",
G_CALLBACK(mime_toggle_button_cb), mimeview);
icon_mainbox = gtk_vbox_new(FALSE, 0);
gtk_widget_show(icon_mainbox);
+ gtk_widget_set_size_request(icon_mainbox, 32, -1);
gtk_box_pack_start(GTK_BOX(icon_mainbox), mime_toggle, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(icon_mainbox), icon_scroll, TRUE, TRUE, 3);
gtk_box_pack_end(GTK_BOX(icon_mainbox), scrollbutton, FALSE, FALSE, 0);
gtk_widget_show(hbox);
gtk_widget_hide(ctree_mainbox);
-
+#ifdef MAEMO
+ gtk_widget_set_size_request(mime_toggle, -1, arrow->requisition.height + 8);
+#endif
mimeview->hbox = hbox;
mimeview->paned = paned;
mimeview->scrolledwin = scrolledwin;
static void mimeview_select_next_part(MimeView *mimeview)
{
- gboolean is_next = FALSE;
+ GtkCTree *ctree = GTK_CTREE(mimeview->ctree);
+ GtkCTreeNode *node = mimeview->opened;
+ MimeInfo *partinfo = NULL;
+
+skip:
+ node = GTK_CTREE_NODE_NEXT(node);
+ if (!node)
+ node = gtk_ctree_node_nth(GTK_CTREE(ctree), 0);
- GList *child = gtk_container_children(GTK_CONTAINER(mimeview->icon_vbox));
- for (; child != NULL; child = g_list_next(child)) {
- if (GTK_IS_TOGGLE_BUTTON(child->data) &&
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(child->data))) {
- is_next = TRUE;
- } else if (GTK_IS_TOGGLE_BUTTON(child->data) &&
- is_next) {
- toggle_icon(GTK_TOGGLE_BUTTON(child->data), mimeview);
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON(child->data), TRUE);
- icon_selected(mimeview, -1,
- (MimeInfo *)g_object_get_data(G_OBJECT(child->data),
- "partinfo"));
- is_next = FALSE;
- break;
- }
+ if (node) {
+ partinfo = gtk_ctree_node_get_row_data(ctree, node);
+ if (partinfo->type == MIMETYPE_MULTIPART)
+ goto skip;
+ gtk_sctree_unselect_all(GTK_SCTREE(ctree));
+ gtk_sctree_select(GTK_SCTREE(ctree), node);
+ icon_list_toggle_by_mime_info(mimeview, partinfo);
}
- if (is_next) {
- /* we were on the last one, go to first */
- child = gtk_container_children(GTK_CONTAINER(mimeview->icon_vbox));
- for (; child != NULL; child = g_list_next(child)) {
- if (GTK_IS_TOGGLE_BUTTON(child->data)) {
- toggle_icon(GTK_TOGGLE_BUTTON(child->data), mimeview);
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON(child->data), TRUE);
- icon_selected(mimeview, -1,
- (MimeInfo *)g_object_get_data(G_OBJECT(child->data),
- "partinfo"));
- break;
- }
- }
+}
+
+static void mimeview_select_prev_part(MimeView *mimeview)
+{
+ GtkCTree *ctree = GTK_CTREE(mimeview->ctree);
+ GtkCTreeNode *node = mimeview->opened;
+ MimeInfo *partinfo = NULL;
+
+skip:
+ node = GTK_CTREE_NODE_PREV(node);
+ if (!node)
+ node = gtk_ctree_node_nth(GTK_CTREE(ctree), GTK_CLIST(ctree)->rows - 1);
+
+ if (node) {
+ partinfo = gtk_ctree_node_get_row_data(ctree, node);
+ if (partinfo->type == MIMETYPE_MULTIPART)
+ goto skip;
+ gtk_sctree_unselect_all(GTK_SCTREE(ctree));
+ gtk_sctree_select(GTK_SCTREE(ctree), node);
+ icon_list_toggle_by_mime_info(mimeview, partinfo);
}
}
{
SummaryView *summaryview;
GtkCTree *ctree = GTK_CTREE(widget);
- GtkCTreeNode *node;
if (!event) return FALSE;
if (!mimeview->opened) return FALSE;
if (mimeview_scroll_page(mimeview, FALSE))
return TRUE;
- node = GTK_CTREE_NODE_NEXT(mimeview->opened);
- if (node) {
- gtk_sctree_unselect_all(GTK_SCTREE(ctree));
- gtk_sctree_select(GTK_SCTREE(ctree), node);
- return TRUE;
- }
- break;
+ mimeview_select_next_part(mimeview);
+ return TRUE;
+
case GDK_BackSpace:
mimeview_scroll_page(mimeview, TRUE);
return TRUE;
case GDK_Return:
+ case GDK_KP_Enter:
mimeview_scroll_one_line(mimeview,
(event->state & GDK_MOD1_MASK) != 0);
return TRUE;
case GDK_n:
case GDK_N:
BREAK_ON_MODIFIER_KEY();
- if (!GTK_CTREE_NODE_NEXT(mimeview->opened)) break;
- KEY_PRESS_EVENT_STOP();
- g_signal_emit_by_name(G_OBJECT(ctree), "scroll_vertical",
- GTK_SCROLL_STEP_FORWARD, 0.0);
+ mimeview_select_next_part(mimeview);
return TRUE;
+
case GDK_p:
case GDK_P:
BREAK_ON_MODIFIER_KEY();
- if (!GTK_CTREE_NODE_PREV(mimeview->opened)) break;
- KEY_PRESS_EVENT_STOP();
- g_signal_emit_by_name(G_OBJECT(ctree), "scroll_vertical",
- GTK_SCROLL_STEP_BACKWARD, 0.0);
+ mimeview_select_prev_part(mimeview);
return TRUE;
+
case GDK_y:
BREAK_ON_MODIFIER_KEY();
KEY_PRESS_EVENT_STOP();
mimeview_open_part_with(mimeview, partinfo, FALSE);
}
+#ifdef MAEMO
+osso_context_t *get_osso_context(void);
+#endif
static void mimeview_open_part_with(MimeView *mimeview, MimeInfo *partinfo, gboolean automatic)
{
gchar *filename;
gchar *mime_command = NULL;
gchar *content_type = NULL;
gint err;
+#ifdef MAEMO
+ DBusConnection *dbusconn;
+ gchar *uri;
+ int r = 0;
+#endif
g_return_if_fail(partinfo != NULL);
filename = procmime_get_tmp_file_name(partinfo);
g_free(filename);
return;
}
-
+
if (!prefs_common.mime_open_cmd_history)
prefs_common.mime_open_cmd_history =
add_history(NULL, prefs_common.mime_open_cmd);
partinfo->subtype);
}
+#ifdef MAEMO
+ if (content_type != NULL) {
+ uri = g_strconcat ("file://", filename, NULL);
+ dbusconn = osso_get_dbus_connection (get_osso_context());
+ r = osso_mime_open_file_with_mime_type (dbusconn, uri, content_type);
+ g_free(uri);
+ }
+ if (r != 1) {
+ alertpanel_error(_("No registered viewer for this file type."));
+ }
+ goto out;
+#endif
+
if ((partinfo->type == MIMETYPE_TEXT && !strcmp(partinfo->subtype, "html"))
&& prefs_common.uri_cmd && prefs_common.uri_cmd[0]) {
mime_command = g_strdup(prefs_common.uri_cmd);
prefs_common.mime_open_cmd_history =
add_history(prefs_common.mime_open_cmd_history, cmd);
}
+out:
g_free(content_type);
g_free(filename);
}
if (event->button == 1) {
icon_selected(mimeview, num, partinfo);
gtk_widget_grab_focus(button);
- if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
- toggle_icon(GTK_TOGGLE_BUTTON(button), mimeview);
- }
}
part_button_pressed(mimeview, event, partinfo);
+ icon_list_toggle_by_mime_info(mimeview, partinfo);
return FALSE;
}
icon_selected(mimeview, -1, partinfo);
}
-#undef KEY_PRESS_EVENT_STOP
-#define KEY_PRESS_EVENT_STOP() \
- g_signal_stop_emission_by_name(G_OBJECT(button), \
- "key_press_event");
-
static gint icon_key_pressed(GtkWidget *button, GdkEventKey *event,
MimeView *mimeview)
{
switch (event->keyval) {
case GDK_space:
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
- /* stop the button being untoggled */
- KEY_PRESS_EVENT_STOP();
- if (mimeview_scroll_page(mimeview, FALSE))
- return TRUE;
-
- if (icon_list_select_by_number(mimeview, num + 1))
- return TRUE;
- } else {
- icon_selected(mimeview, num, partinfo);
- toggle_icon(GTK_TOGGLE_BUTTON(button), mimeview);
+ if (mimeview_scroll_page(mimeview, FALSE))
return TRUE;
- }
+
+ mimeview_select_next_part(mimeview);
+ return TRUE;
break;
case GDK_BackSpace:
mimeview_scroll_page(mimeview, TRUE);
return TRUE;
case GDK_Return:
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
- KEY_PRESS_EVENT_STOP();
- mimeview_scroll_one_line(mimeview,
- (event->state & GDK_MOD1_MASK) != 0);
- return TRUE;
- } else {
- icon_selected(mimeview, num, partinfo);
- toggle_icon(GTK_TOGGLE_BUTTON(button), mimeview);
- return TRUE;
- }
+ case GDK_KP_Enter:
+ mimeview_scroll_one_line(mimeview,
+ (event->state & GDK_MOD1_MASK) != 0);
+ return TRUE;
case GDK_n:
case GDK_N:
BREAK_ON_MODIFIER_KEY();
- if (icon_list_select_by_number(mimeview, num + 1)) {
- KEY_PRESS_EVENT_STOP();
- return TRUE;
- }
- break;
+ mimeview_select_next_part(mimeview);
+ return TRUE;
case GDK_p:
case GDK_P:
BREAK_ON_MODIFIER_KEY();
- if (icon_list_select_by_number(mimeview, num - 1)) {
- KEY_PRESS_EVENT_STOP();
- return TRUE;
- }
+ mimeview_select_prev_part(mimeview);
break;
case GDK_y:
BREAK_ON_MODIFIER_KEY();
- KEY_PRESS_EVENT_STOP();
mimeview_save_as(mimeview);
return TRUE;
case GDK_t:
BREAK_ON_MODIFIER_KEY();
- KEY_PRESS_EVENT_STOP();
mimeview_display_as_text(mimeview);
return TRUE;
case GDK_l:
BREAK_ON_MODIFIER_KEY();
- KEY_PRESS_EVENT_STOP();
mimeview_launch(mimeview, NULL);
return TRUE;
case GDK_o:
BREAK_ON_MODIFIER_KEY();
- KEY_PRESS_EVENT_STOP();
mimeview_open_with(mimeview);
return TRUE;
case GDK_c:
BREAK_ON_MODIFIER_KEY();
- KEY_PRESS_EVENT_STOP();
mimeview_check_signature(mimeview);
return TRUE;
case GDK_a:
BREAK_ON_MODIFIER_KEY();
- KEY_PRESS_EVENT_STOP();
mimeview_select_next_part(mimeview);
return TRUE;
default:
return summary_pass_key_press_event(summaryview, event);
}
-static void toggle_icon(GtkToggleButton *button, MimeView *mimeview)
-{
- GList *child;
-
- child = gtk_container_get_children(GTK_CONTAINER(mimeview->icon_vbox));
- for (; child != NULL; child = g_list_next(child)) {
- if (GTK_IS_TOGGLE_BUTTON(child->data) &&
- GTK_TOGGLE_BUTTON(child->data) != button &&
- gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(child->data)))
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON(child->data),
- FALSE);
- }
-}
-
static gboolean icon_popup_menu(GtkWidget *widget, gpointer data)
{
MimeView *mimeview = (MimeView *)data;
vbox = mimeview->icon_vbox;
mimeview->icon_count++;
- button = gtk_toggle_button_new();
- gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
+ button = gtk_event_box_new();
+
+ g_signal_connect(G_OBJECT(button), "visibility-notify-event",
+ G_CALLBACK(mimeview_visi_notify), mimeview);
+ g_signal_connect(G_OBJECT(button), "motion-notify-event",
+ G_CALLBACK(mimeview_visi_notify), mimeview);
+ g_signal_connect(G_OBJECT(button), "leave-notify-event",
+ G_CALLBACK(mimeview_leave_notify), mimeview);
+ g_signal_connect(G_OBJECT(button), "enter-notify-event",
+ G_CALLBACK(mimeview_enter_notify), mimeview);
+
+ gtk_container_set_border_width(GTK_CONTAINER(button), 2);
g_object_set_data(G_OBJECT(button), "icon_number",
GINT_TO_POINTER(mimeview->icon_count));
g_object_set_data(G_OBJECT(button), "partinfo",
OVERLAY_NONE, 6, 3);
}
gtk_container_add(GTK_CONTAINER(button), pixmap);
-
if (!desc) {
if (prefs_common.attach_desc)
desc = get_part_description(mimeinfo);
g_signal_connect(G_OBJECT(button), "drag_data_get",
G_CALLBACK(mimeview_drag_data_get), mimeview);
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+#ifdef MAEMO
+ gtk_widget_set_size_request(vbox, -1, pixmap->requisition.height + 8);
+ gtk_widget_set_size_request(button, -1, pixmap->requisition.height + 4);
+#endif
}
gtk_adjustment_set_value(adj, adj->lower);
}
-static void icon_list_toggle_by_mime_info(MimeView *mimeview,
- MimeInfo *mimeinfo)
-{
- GList *child;
-
- child = gtk_container_children(GTK_CONTAINER(mimeview->icon_vbox));
- for (; child != NULL; child = g_list_next(child)) {
- if (GTK_IS_TOGGLE_BUTTON(child->data) &&
- g_object_get_data(G_OBJECT(child->data),
- "partinfo") == (gpointer)mimeinfo) {
- toggle_icon(GTK_TOGGLE_BUTTON(child->data), mimeview);
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON(child->data), TRUE);
- }
- }
-}
-
/*!
*\brief Used to 'click' the next or previous icon.
*
*\return true if the icon 'number' exists and was selected.
*/
-static gboolean icon_list_select_by_number(MimeView *mimeview,
- gint number)
-{
- GList *child;
-
- if (number == 0) return FALSE;
- child = gtk_container_children(GTK_CONTAINER(mimeview->icon_vbox));
- for (; child != NULL; child = g_list_next(child)) {
- if (GTK_IS_TOGGLE_BUTTON(child->data) &&
- GPOINTER_TO_INT(g_object_get_data(G_OBJECT(child->data),
- "icon_number")) == number) {
- icon_selected(mimeview, number,
- (MimeInfo*)g_object_get_data(G_OBJECT(child->data),
- "partinfo"));
- toggle_icon(GTK_TOGGLE_BUTTON(child->data), mimeview);
- gtk_toggle_button_set_active
- (GTK_TOGGLE_BUTTON(child->data), TRUE);
- gtk_widget_grab_focus(GTK_WIDGET(child->data));
-
- return TRUE;
- }
- }
- return FALSE;
-}
-
static void icon_scroll_size_allocate_cb(GtkWidget *widget,
GtkAllocation *size, MimeView *mimeview)
{
gtk_widget_set_size_request(mimeview->icon_mainbox,
size.width, -1);
}
+}
+static void icon_list_toggle_by_mime_info (MimeView *mimeview,
+ MimeInfo *mimeinfo)
+{
+ GList *child;
+
+ child = gtk_container_children(GTK_CONTAINER(mimeview->icon_vbox));
+ for (; child != NULL; child = g_list_next(child)) {
+ if (!GTK_IS_EVENT_BOX(child->data))
+ continue;
+ if(g_object_get_data(G_OBJECT(child->data),
+ "partinfo") == (gpointer)mimeinfo) {
+ gboolean *highlight = NULL;
+ GtkWidget *icon = gtk_bin_get_child(GTK_BIN(child->data));
+ highlight = g_object_get_data(G_OBJECT(icon), "highlight");
+ *highlight = TRUE;
+ gtk_widget_queue_draw(icon);
+ } else {
+ gint *highlight = NULL;
+ GtkWidget *icon = gtk_bin_get_child(GTK_BIN(child->data));
+ highlight = g_object_get_data(G_OBJECT(icon), "highlight");
+ *highlight = FALSE;
+ gtk_widget_queue_draw(icon);
+ }
+ }
}
-static void mime_toggle_button_cb (GtkWidget *button, MimeView *mimeview)
+static gint mime_toggle_button_cb(GtkWidget *button, GdkEventButton *event,
+ MimeView *mimeview)
{
gtk_widget_ref(button);
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) {
+ mimeview_leave_notify(button, NULL, NULL);
+
+ mimeview->ctree_mode = !mimeview->ctree_mode;
+ if (mimeview->ctree_mode) {
gtk_arrow_set(GTK_ARROW(GTK_BIN(button)->child), GTK_ARROW_RIGHT,
GTK_SHADOW_NONE);
gtk_widget_hide(mimeview->icon_mainbox);
gtk_paned_set_gutter_size(GTK_PANED(mimeview->paned), 0);
}
- gtk_widget_grab_focus(button);
gtk_widget_unref(button);
-
+ return TRUE;
}
void mimeview_update (MimeView *mimeview) {
} else if (!strcmp(cmd, "sc://menu_attachment") && data != NULL) {
mimeview->spec_part = (MimeInfo *)data;
part_button_pressed(mimeview, event, (MimeInfo *)data);
+ } else if (!strncmp(cmd, "sc://search_tags:", strlen("sc://search_tags:"))) {
+ const gchar *tagname = cmd + strlen("sc://search_tags:");
+ gchar *buf = g_strdup_printf("tag matchcase \"%s\"", tagname);
+ gtk_toggle_button_set_active(
+ GTK_TOGGLE_BUTTON(mimeview->messageview->mainwin->summaryview->toggle_search),
+ TRUE);
+ quicksearch_set(mimeview->messageview->mainwin->summaryview->quicksearch,
+ QUICK_SEARCH_EXTENDED, buf);
+ g_free(buf);
}
}