Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
authorCarlos Garcia Campos <carlosgc@gnome.org>2010-07-20 15:01:56 (GMT)
committer Carlos Garcia Campos <carlosgc@gnome.org>2010-07-20 15:07:40 (GMT)
commit584f014b63c56fe3770cba9682fc21c31e09a2e9 (patch)
treede1a6a07ff5bd7b8a52e176e72af12a8172b5ed9 /shell
parentdfed06b88fae63bbd0460e43df977c0d33ef1045 (diff)
Preliminary support for adding new annotations
At the moment only Text annotations can be added. See bug #168304.
Diffstat (limited to 'shell')
-rw-r--r--shell/Makefile.am2
-rw-r--r--shell/ev-annotation-properties-dialog.c327
-rw-r--r--shell/ev-annotation-properties-dialog.h54
-rw-r--r--shell/ev-sidebar-annotations.c177
-rw-r--r--shell/ev-sidebar-annotations.h14
-rw-r--r--shell/ev-window.c126
6 files changed, 673 insertions, 27 deletions
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 523d299..8336230 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -32,6 +32,8 @@ endif
evince_SOURCES= \
eggfindbar.c \
eggfindbar.h \
+ ev-annotation-properties-dialog.h \
+ ev-annotation-properties-dialog.c \
ev-application.c \
ev-application.h \
ev-file-monitor.h \
diff --git a/shell/ev-annotation-properties-dialog.c b/shell/ev-annotation-properties-dialog.c
new file mode 100644
index 0000000..0f5c6e1
--- /dev/null
+++ b/shell/ev-annotation-properties-dialog.c
@@ -0,0 +1,327 @@
+/* ev-annotation-properties-dialog.c
+ * this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2010 Carlos Garcia Campos <carlosgc@gnome.org>
+ *
+ * Evince 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
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+
+#include <glib/gi18n.h>
+
+#include "ev-annotation-properties-dialog.h"
+
+enum {
+ PROP_0,
+ PROP_ANNOT_TYPE
+};
+
+struct _EvAnnotationPropertiesDialog {
+ GtkDialog base_instance;
+
+ EvAnnotationType annot_type;
+ EvAnnotation *annot;
+
+ GtkWidget *table;
+
+ GtkWidget *author;
+ GtkWidget *color;
+ GtkWidget *opacity;
+ GtkWidget *popup_state;
+
+ /* Text Annotations */
+ GtkWidget *icon;
+};
+
+struct _EvAnnotationPropertiesDialogClass {
+ GtkDialogClass base_class;
+};
+
+G_DEFINE_TYPE (EvAnnotationPropertiesDialog, ev_annotation_properties_dialog, GTK_TYPE_DIALOG)
+
+static void
+ev_annotation_properties_dialog_dispose (GObject *object)
+{
+ EvAnnotationPropertiesDialog *dialog = EV_ANNOTATION_PROPERTIES_DIALOG (object);
+
+ if (dialog->annot) {
+ g_object_unref (dialog->annot);
+ dialog->annot = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_annotation_properties_dialog_parent_class)->dispose (object);
+}
+
+static void
+ev_annotation_properties_dialog_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EvAnnotationPropertiesDialog *dialog = EV_ANNOTATION_PROPERTIES_DIALOG (object);
+
+ switch (prop_id) {
+ case PROP_ANNOT_TYPE:
+ dialog->annot_type = g_value_get_enum (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ev_annotation_properties_dialog_constructed (GObject *object)
+{
+ EvAnnotationPropertiesDialog *dialog = EV_ANNOTATION_PROPERTIES_DIALOG (object);
+ GtkWidget *contant_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ GtkWidget *table = dialog->table;
+ GtkWidget *label;
+
+ contant_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+
+ switch (dialog->annot_type) {
+ case EV_ANNOTATION_TYPE_TEXT:
+ label = gtk_label_new (_("Icon:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0., 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 5, 6,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ dialog->icon = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->icon), _("Note"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->icon), _("Comment"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->icon), _("Key"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->icon), _("Help"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->icon), _("New Paragraph"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->icon), _("Paragraph"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->icon), _("Insert"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->icon), _("Cross"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->icon), _("Circle"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (dialog->icon), _("Unknown"));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->icon), 0);
+ gtk_table_attach (GTK_TABLE (table), dialog->icon,
+ 1, 2, 5, 6,
+ GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+ gtk_widget_show (dialog->icon);
+
+ break;
+ case EV_ANNOTATION_TYPE_ATTACHMENT:
+ /* TODO */
+ default:
+ break;
+ }
+}
+
+static void
+ev_annotation_properties_dialog_init (EvAnnotationPropertiesDialog *annot_dialog)
+{
+ GtkDialog *dialog = GTK_DIALOG (annot_dialog);
+ GtkWidget *content_area;
+ GtkWidget *label;
+ GtkWidget *table;
+ GtkWidget *hbox;
+ gchar *markup;
+ GdkColor color = { 0, 65535, 65535, 0 };
+
+ gtk_window_set_title (GTK_WINDOW (annot_dialog), _("Annotation Properties"));
+ gtk_window_set_destroy_with_parent (GTK_WINDOW (annot_dialog), TRUE);
+ gtk_container_set_border_width (GTK_CONTAINER (annot_dialog), 5);
+ gtk_dialog_set_has_separator (dialog, FALSE);
+ gtk_dialog_add_buttons (dialog,
+ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+ GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
+ NULL);
+ gtk_dialog_set_default_response (dialog, GTK_RESPONSE_APPLY);
+
+ content_area = gtk_dialog_get_content_area (dialog);
+ gtk_box_set_spacing (GTK_BOX (content_area), 2);
+
+ table = gtk_table_new (5, 2, FALSE);
+ annot_dialog->table = table;
+ gtk_table_set_col_spacings (GTK_TABLE (table), 12);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 12);
+ gtk_box_pack_start (GTK_BOX (content_area), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ label = gtk_label_new (_("Author:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0., 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ annot_dialog->author = gtk_entry_new ();
+ gtk_entry_set_text (GTK_ENTRY (annot_dialog->author), g_get_real_name ());
+ gtk_table_attach (GTK_TABLE (table), annot_dialog->author,
+ 1, 2, 0, 1,
+ GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+ gtk_widget_show (annot_dialog->author);
+
+ label = gtk_label_new (_("Color:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0., 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 1, 2,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ annot_dialog->color = gtk_color_button_new_with_color (&color);
+ gtk_table_attach (GTK_TABLE (table), annot_dialog->color,
+ 1, 2, 1, 2,
+ GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+ gtk_widget_show (annot_dialog->color);
+
+ label = gtk_label_new (_("Style:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0., 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 2, 3,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ annot_dialog->opacity = gtk_hscale_new_with_range (0, 100, 5);
+ gtk_range_set_value (GTK_RANGE (annot_dialog->opacity), 100);
+ gtk_table_attach (GTK_TABLE (table), annot_dialog->opacity,
+ 1, 2, 2, 3,
+ GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+ gtk_widget_show (annot_dialog->opacity);
+
+ hbox = gtk_hbox_new (FALSE, 6);
+
+ label = gtk_label_new (NULL);
+ markup = g_strdup_printf ("<small>%s</small>", _("Transparent"));
+ gtk_label_set_markup (GTK_LABEL (label), markup);
+ g_free (markup);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ label = gtk_label_new (NULL);
+ markup = g_strdup_printf ("<small>%s</small>", _("Opaque"));
+ gtk_label_set_markup (GTK_LABEL (label), markup);
+ g_free (markup);
+ gtk_box_pack_end (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_widget_show (label);
+
+ gtk_table_attach (GTK_TABLE (table), hbox,
+ 1, 2, 3, 4,
+ GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+ gtk_widget_show (hbox);
+
+ label = gtk_label_new (_("Initial window state:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0., 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 0, 1, 4, 5,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ annot_dialog->popup_state = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (annot_dialog->popup_state), _("Open"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (annot_dialog->popup_state), _("Close"));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (annot_dialog->popup_state), 1);
+ gtk_table_attach (GTK_TABLE (table), annot_dialog->popup_state,
+ 1, 2, 4, 5,
+ GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
+ gtk_widget_show (annot_dialog->popup_state);
+}
+
+static void
+ev_annotation_properties_dialog_class_init (EvAnnotationPropertiesDialogClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = ev_annotation_properties_dialog_dispose;
+ object_class->constructed = ev_annotation_properties_dialog_constructed;
+ object_class->set_property = ev_annotation_properties_dialog_set_property;
+
+ g_object_class_install_property (object_class,
+ PROP_ANNOT_TYPE,
+ g_param_spec_enum ("annot-type",
+ "AnnotType",
+ "The type of annotation",
+ EV_TYPE_ANNOTATION_TYPE,
+ EV_ANNOTATION_TYPE_TEXT,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+GtkWidget *
+ev_annotation_properties_dialog_new (EvAnnotationType annot_type)
+{
+ return GTK_WIDGET (g_object_new (EV_TYPE_ANNOTATION_PROPERTIES_DIALOG,
+ "annot-type", annot_type,
+ NULL));
+}
+
+GtkWidget *
+ev_annotation_properties_dialog_new_with_annotation (EvAnnotation *annot)
+{
+ EvAnnotationPropertiesDialog *dialog;
+ const gchar *label;
+ gdouble opacity;
+ gboolean is_open;
+ GdkColor color;
+
+ dialog = (EvAnnotationPropertiesDialog *)ev_annotation_properties_dialog_new (ev_annotation_get_annotation_type (annot));
+ dialog->annot = g_object_ref (annot);
+
+ label = ev_annotation_markup_get_label (EV_ANNOTATION_MARKUP (annot));
+ if (label)
+ gtk_entry_set_text (GTK_ENTRY (dialog->author), label);
+
+ ev_annotation_get_color (annot, &color);
+ gtk_color_button_set_color (GTK_COLOR_BUTTON (dialog->color), &color);
+
+ opacity = ev_annotation_markup_get_opacity (EV_ANNOTATION_MARKUP (annot));
+ gtk_range_set_value (GTK_RANGE (dialog->opacity), opacity * 100);
+
+ is_open = ev_annotation_markup_get_popup_is_open (EV_ANNOTATION_MARKUP (annot));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->popup_state),
+ is_open ? 0 : 1);
+
+ if (EV_IS_ANNOTATION_TEXT (annot)) {
+ EvAnnotationText *annot_text = EV_ANNOTATION_TEXT (annot);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->icon),
+ ev_annotation_text_get_icon (annot_text));
+ }
+
+ return GTK_WIDGET (dialog);
+}
+
+const gchar *
+ev_annotation_properties_dialog_get_author (EvAnnotationPropertiesDialog *dialog)
+{
+ return gtk_entry_get_text (GTK_ENTRY (dialog->author));
+}
+
+void
+ev_annotation_properties_dialog_get_color (EvAnnotationPropertiesDialog *dialog,
+ GdkColor *color)
+{
+ gtk_color_button_get_color (GTK_COLOR_BUTTON (dialog->color), color);
+}
+
+gdouble
+ev_annotation_properties_dialog_get_opacity (EvAnnotationPropertiesDialog *dialog)
+{
+ return gtk_range_get_value (GTK_RANGE (dialog->opacity)) / 100;
+}
+
+gboolean
+ev_annotation_properties_dialog_get_popup_is_open (EvAnnotationPropertiesDialog *dialog)
+{
+ return gtk_combo_box_get_active (GTK_COMBO_BOX (dialog->popup_state)) == 0;
+}
+
+EvAnnotationTextIcon
+ev_annotation_properties_dialog_get_text_icon (EvAnnotationPropertiesDialog *dialog)
+{
+ return gtk_combo_box_get_active (GTK_COMBO_BOX (dialog->icon));
+}
diff --git a/shell/ev-annotation-properties-dialog.h b/shell/ev-annotation-properties-dialog.h
new file mode 100644
index 0000000..e21a883
--- /dev/null
+++ b/shell/ev-annotation-properties-dialog.h
@@ -0,0 +1,54 @@
+/* ev-annotation-properties-dialog.h
+ * this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2010 Carlos Garcia Campos <carlosgc@gnome.org>
+ *
+ * Evince 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
+ * (at your option) any later version.
+ *
+ * Evince is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EV_ANNOTATION_PROPERTIES_DIALOG_H__
+#define __EV_ANNOTATION_PROPERTIES_DIALOG_H__
+
+#include <gtk/gtk.h>
+#include <glib-object.h>
+
+#include <evince-document.h>
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_ANNOTATION_PROPERTIES_DIALOG (ev_annotation_properties_dialog_get_type())
+#define EV_ANNOTATION_PROPERTIES_DIALOG(o) (G_TYPE_CHECK_INSTANCE_CAST((o), EV_TYPE_ANNOTATION_PROPERTIES_DIALOG, EvAnnotationPropertiesDialog))
+#define EV_ANNOTATION_PROPERTIES_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_ANNOTATION_PROPERTIES_DIALOG, EvAnnotationPropertiesDialogClass))
+#define EV_IS_ANNOTATION_PROPERTIES_DIALOG(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), EV_TYPE_ANNOTATION_PROPERTIES_DIALOG))
+#define EV_IS_ANNOTATION_PROPERTIES_DIALOG_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE((k), EV_TYPE_ANNOTATION_PROPERTIES_DIALOG))
+#define EV_ANNOTATION_PROPERTIES_DIALOG_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), EV_TYPE_ANNOTATION_PROPERTIES_DIALOG, EvAnnotationPropertiesDialogClass))
+
+typedef struct _EvAnnotationPropertiesDialog EvAnnotationPropertiesDialog;
+typedef struct _EvAnnotationPropertiesDialogClass EvAnnotationPropertiesDialogClass;
+
+GType ev_annotation_properties_dialog_get_type (void) G_GNUC_CONST;
+GtkWidget *ev_annotation_properties_dialog_new (EvAnnotationType annot_type);
+GtkWidget *ev_annotation_properties_dialog_new_with_annotation (EvAnnotation *annot);
+
+const gchar *ev_annotation_properties_dialog_get_author (EvAnnotationPropertiesDialog *dialog);
+void ev_annotation_properties_dialog_get_color (EvAnnotationPropertiesDialog *dialog,
+ GdkColor *color);
+gdouble ev_annotation_properties_dialog_get_opacity (EvAnnotationPropertiesDialog *dialog);
+gboolean ev_annotation_properties_dialog_get_popup_is_open (EvAnnotationPropertiesDialog *dialog);
+EvAnnotationTextIcon ev_annotation_properties_dialog_get_text_icon (EvAnnotationPropertiesDialog *dialog);
+
+G_END_DECLS
+
+#endif /* __EV_ANNOTATION_PROPERTIES_DIALOG_H__ */
diff --git a/shell/ev-sidebar-annotations.c b/shell/ev-sidebar-annotations.c
index b1f0848..ec544fa 100644
--- a/shell/ev-sidebar-annotations.c
+++ b/shell/ev-sidebar-annotations.c
@@ -43,18 +43,25 @@ enum {
enum {
ANNOT_ACTIVATED,
+ BEGIN_ANNOT_ADD,
+ ANNOT_ADD_CANCELLED,
N_SIGNALS
};
struct _EvSidebarAnnotationsPrivate {
- GtkWidget *notebook;
- GtkWidget *tree_view;
+ EvDocument *document;
- EvJob *job;
- guint selection_changed_id;
+ GtkWidget *notebook;
+ GtkWidget *tree_view;
+ GtkWidget *palette;
+ GtkToolItem *annot_text_item;
+
+ EvJob *job;
+ guint selection_changed_id;
};
static void ev_sidebar_annotations_page_iface_init (EvSidebarPageInterface *iface);
+static void ev_sidebar_annotations_load (EvSidebarAnnotations *sidebar_annots);
static guint signals[N_SIGNALS];
@@ -68,6 +75,20 @@ G_DEFINE_TYPE_EXTENDED (EvSidebarAnnotations,
#define EV_SIDEBAR_ANNOTATIONS_GET_PRIVATE(object) \
(G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_SIDEBAR_ANNOTATIONS, EvSidebarAnnotationsPrivate))
+static void
+ev_sidebar_annotations_dispose (GObject *object)
+{
+ EvSidebarAnnotations *sidebar_annots = EV_SIDEBAR_ANNOTATIONS (object);
+ EvSidebarAnnotationsPrivate *priv = sidebar_annots->priv;
+
+ if (priv->document) {
+ g_object_unref (priv->document);
+ priv->document = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_sidebar_annotations_parent_class)->dispose (object);
+}
+
static GtkTreeModel *
ev_sidebar_annotations_create_simple_model (const gchar *message)
{
@@ -100,6 +121,7 @@ ev_sidebar_annotations_add_annots_list (EvSidebarAnnotations *ev_annots)
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
GtkTreeSelection *selection;
+ GtkWidget *label;
swindow = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
@@ -136,8 +158,71 @@ ev_sidebar_annotations_add_annots_list (EvSidebarAnnotations *ev_annots)
gtk_container_add (GTK_CONTAINER (swindow), ev_annots->priv->tree_view);
gtk_widget_show (ev_annots->priv->tree_view);
+ label = gtk_label_new (_("List"));
+ gtk_notebook_append_page (GTK_NOTEBOOK (ev_annots->priv->notebook),
+ swindow, label);
+ gtk_widget_show (label);
+
+ gtk_widget_show (swindow);
+}
+
+static void
+ev_sidebar_annotations_text_annot_button_toggled (GtkToggleToolButton *toolbutton,
+ EvSidebarAnnotations *sidebar_annots)
+{
+ EvAnnotationType annot_type;
+
+ if (!gtk_toggle_tool_button_get_active (toolbutton)) {
+ g_signal_emit (sidebar_annots, signals[ANNOT_ADD_CANCELLED], 0, NULL);
+ return;
+ }
+
+ if (GTK_TOOL_ITEM (toolbutton) == sidebar_annots->priv->annot_text_item)
+ annot_type = EV_ANNOTATION_TYPE_TEXT;
+ else
+ annot_type = EV_ANNOTATION_TYPE_UNKNOWN;
+
+ g_signal_emit (sidebar_annots, signals[BEGIN_ANNOT_ADD], 0, annot_type);
+}
+
+static void
+ev_sidebar_annotations_add_annots_palette (EvSidebarAnnotations *ev_annots)
+{
+ GtkWidget *swindow;
+ GtkWidget *group;
+ GtkToolItem *item;
+ GtkWidget *label;
+
+ swindow = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swindow),
+ GTK_SHADOW_IN);
+
+ ev_annots->priv->palette = gtk_tool_palette_new ();
+ group = gtk_tool_item_group_new (_("Annotations"));
+ gtk_container_add (GTK_CONTAINER (ev_annots->priv->palette), group);
+
+ /* FIXME: use a better icon than EDIT */
+ item = gtk_toggle_tool_button_new ();
+ gtk_tool_button_set_icon_name (GTK_TOOL_BUTTON (item), GTK_STOCK_EDIT);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), _("Text"));
+ gtk_widget_set_tooltip_text (GTK_WIDGET (item), _("Add text annotation"));
+ ev_annots->priv->annot_text_item = item;
+ g_signal_connect (item, "toggled",
+ G_CALLBACK (ev_sidebar_annotations_text_annot_button_toggled),
+ ev_annots);
+ gtk_tool_item_group_insert (GTK_TOOL_ITEM_GROUP (group), item, -1);
+ gtk_widget_show (GTK_WIDGET (item));
+
+ gtk_container_add (GTK_CONTAINER (swindow), ev_annots->priv->palette);
+ gtk_widget_show (ev_annots->priv->palette);
+
+ label = gtk_label_new (_("Add"));
gtk_notebook_append_page (GTK_NOTEBOOK (ev_annots->priv->notebook),
- swindow, NULL);
+ swindow, label);
+ gtk_widget_show (label);
+
gtk_widget_show (swindow);
}
@@ -150,6 +235,7 @@ ev_sidebar_annotations_init (EvSidebarAnnotations *ev_annots)
gtk_notebook_set_show_tabs (GTK_NOTEBOOK (ev_annots->priv->notebook), FALSE);
gtk_notebook_set_show_border (GTK_NOTEBOOK (ev_annots->priv->notebook), FALSE);
ev_sidebar_annotations_add_annots_list (ev_annots);
+ ev_sidebar_annotations_add_annots_palette (ev_annots);
gtk_container_add (GTK_CONTAINER (ev_annots), ev_annots->priv->notebook);
gtk_widget_show (ev_annots->priv->notebook);
}
@@ -180,6 +266,7 @@ ev_sidebar_annotations_class_init (EvSidebarAnnotationsClass *klass)
GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
g_object_class->get_property = ev_sidebar_annotations_get_property;
+ g_object_class->dispose = ev_sidebar_annotations_dispose;
g_type_class_add_private (g_object_class, sizeof (EvSidebarAnnotationsPrivate));
@@ -194,6 +281,24 @@ ev_sidebar_annotations_class_init (EvSidebarAnnotationsClass *klass)
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
+ signals[BEGIN_ANNOT_ADD] =
+ g_signal_new ("begin-annot-add",
+ G_TYPE_FROM_CLASS (g_object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EvSidebarAnnotationsClass, begin_annot_add),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1,
+ EV_TYPE_ANNOTATION_TYPE);
+ signals[ANNOT_ADD_CANCELLED] =
+ g_signal_new ("annot-add-cancelled",
+ G_TYPE_FROM_CLASS (g_object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EvSidebarAnnotationsClass, annot_add_cancelled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0,
+ G_TYPE_NONE);
}
GtkWidget *
@@ -202,6 +307,26 @@ ev_sidebar_annotations_new (void)
return GTK_WIDGET (g_object_new (EV_TYPE_SIDEBAR_ANNOTATIONS, NULL));
}
+void
+ev_sidebar_annotations_annot_added (EvSidebarAnnotations *sidebar_annots,
+ EvAnnotation *annot)
+{
+ GtkToggleToolButton *toolbutton;
+
+ if (EV_IS_ANNOTATION_TEXT (annot)) {
+ toolbutton = GTK_TOGGLE_TOOL_BUTTON (sidebar_annots->priv->annot_text_item);
+ g_signal_handlers_block_by_func (toolbutton,
+ ev_sidebar_annotations_text_annot_button_toggled,
+ sidebar_annots);
+ gtk_toggle_tool_button_set_active (toolbutton, FALSE);
+ g_signal_handlers_unblock_by_func (toolbutton,
+ ev_sidebar_annotations_text_annot_button_toggled,
+ sidebar_annots);
+ }
+
+ ev_sidebar_annotations_load (sidebar_annots);
+}
+
static void
selection_changed_cb (GtkTreeSelection *selection,
EvSidebarAnnotations *sidebar_annots)
@@ -278,7 +403,8 @@ job_finished_callback (EvJobAnnots *job,
for (ll = ev_mapping_list_get_list (mapping_list); ll; ll = g_list_next (ll)) {
EvAnnotation *annot;
- gchar *label;
+ const gchar *label;
+ const gchar *modified;
gchar *markup;
GtkTreeIter child_iter;
GdkPixbuf *pixbuf = NULL;
@@ -288,13 +414,13 @@ job_finished_callback (EvJobAnnots *job,
continue;
label = ev_annotation_markup_get_label (EV_ANNOTATION_MARKUP (annot));
- if (annot->modified) {
+ modified = ev_annotation_get_modified (annot);
+ if (modified) {
markup = g_strdup_printf ("<span weight=\"bold\">%s</span>\n%s",
- label, annot->modified);
+ label, modified);
} else {
markup = g_strdup_printf ("<span weight=\"bold\">%s</span>", label);
}
- g_free (label);
if (EV_IS_ANNOTATION_TEXT (annot)) {
if (!text_icon) {
@@ -342,18 +468,11 @@ job_finished_callback (EvJobAnnots *job,
priv->job = NULL;
}
-
static void
-ev_sidebar_annotations_document_changed_cb (EvDocumentModel *model,
- GParamSpec *pspec,
- EvSidebarAnnotations *sidebar_annots)
+ev_sidebar_annotations_load (EvSidebarAnnotations *sidebar_annots)
{
- EvDocument *document = ev_document_model_get_document (model);
EvSidebarAnnotationsPrivate *priv = sidebar_annots->priv;
- if (!EV_IS_DOCUMENT_ANNOTATIONS (document))
- return;
-
if (priv->job) {
g_signal_handlers_disconnect_by_func (priv->job,
job_finished_callback,
@@ -361,7 +480,7 @@ ev_sidebar_annotations_document_changed_cb (EvDocumentModel *model,
g_object_unref (priv->job);
}
- priv->job = ev_job_annots_new (document);
+ priv->job = ev_job_annots_new (priv->document);
g_signal_connect (priv->job, "finished",
G_CALLBACK (job_finished_callback),
sidebar_annots);
@@ -369,6 +488,28 @@ ev_sidebar_annotations_document_changed_cb (EvDocumentModel *model,
ev_job_scheduler_push_job (priv->job, EV_JOB_PRIORITY_NONE);
}
+static void
+ev_sidebar_annotations_document_changed_cb (EvDocumentModel *model,
+ GParamSpec *pspec,
+ EvSidebarAnnotations *sidebar_annots)
+{
+ EvDocument *document = ev_document_model_get_document (model);
+ EvSidebarAnnotationsPrivate *priv = sidebar_annots->priv;
+ gboolean show_tabs;
+
+ if (!EV_IS_DOCUMENT_ANNOTATIONS (document))
+ return;
+
+ if (priv->document)
+ g_object_unref (priv->document);
+ priv->document = g_object_ref (document);
+
+ show_tabs = ev_document_annotations_can_add_annotation (EV_DOCUMENT_ANNOTATIONS (document));
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), show_tabs);
+
+ ev_sidebar_annotations_load (sidebar_annots);
+}
+
/* EvSidebarPageIface */
static void
ev_sidebar_annotations_set_model (EvSidebarPage *sidebar_page,
diff --git a/shell/ev-sidebar-annotations.h b/shell/ev-sidebar-annotations.h
index 8762d78..544fc24 100644
--- a/shell/ev-sidebar-annotations.h
+++ b/shell/ev-sidebar-annotations.h
@@ -46,13 +46,17 @@ struct _EvSidebarAnnotations {
struct _EvSidebarAnnotationsClass {
GtkVBoxClass base_class;
- void (* annot_activated) (EvSidebarAnnotations *sidebar_annots,
- EvMapping *mapping);
+ void (* annot_activated) (EvSidebarAnnotations *sidebar_annots,
+ EvMapping *mapping);
+ void (* begin_annot_add) (EvSidebarAnnotations *sidebar_annots,
+ EvAnnotationType annot_type);
+ void (* annot_add_cancelled) (EvSidebarAnnotations *sidebar_annots);
};
-GType ev_sidebar_annotations_get_type (void) G_GNUC_CONST;
-GtkWidget *ev_sidebar_annotations_new (void);
-
+GType ev_sidebar_annotations_get_type (void) G_GNUC_CONST;
+GtkWidget *ev_sidebar_annotations_new (void);
+void ev_sidebar_annotations_annot_added (EvSidebarAnnotations *sidebar_annots,
+ EvAnnotation *annot);
G_END_DECLS
#endif /* __EV_SIDEBAR_ANNOTATIONS_H__ */
diff --git a/shell/ev-window.c b/shell/ev-window.c
index c7e9c6d..ece97c7 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -95,6 +95,7 @@
#include "ev-window-title.h"
#include "ev-print-operation.h"
#include "ev-progress-message-area.h"
+#include "ev-annotation-properties-dialog.h"
#ifdef ENABLE_DBUS
#include "ev-media-player-keys.h"
@@ -172,9 +173,10 @@ struct _EvWindowPrivate {
GtkWidget *fullscreen_toolbar;
/* Popup view */
- GtkWidget *view_popup;
- EvLink *link;
- EvImage *image;
+ GtkWidget *view_popup;
+ EvLink *link;
+ EvImage *image;
+ EvAnnotation *annot;
/* Popup attachment */
GtkWidget *attachment_popup;
@@ -317,6 +319,8 @@ static void ev_view_popup_cmd_save_image_as (GtkAction *actio
EvWindow *window);
static void ev_view_popup_cmd_copy_image (GtkAction *action,
EvWindow *window);
+static void ev_view_popup_cmd_annot_properties (GtkAction *action,
+ EvWindow *window);
static void ev_attachment_popup_cmd_open_attachment (GtkAction *action,
EvWindow *window);
static void ev_attachment_popup_cmd_save_attachment_as (GtkAction *action,
@@ -3307,6 +3311,8 @@ ev_window_cmd_file_close_window (GtkAction *action, EvWindow *ev_window)
ev_document_model_set_page (ev_window->priv->model, current_page);
}
+ /* TODO: warn about form fields, and annots not saved */
+
n_print_jobs = ev_window->priv->print_queue ?
g_queue_get_length (ev_window->priv->print_queue) : 0;
@@ -4536,9 +4542,18 @@ view_menu_annot_popup (EvWindow *ev_window,
GtkAction *action;
gboolean show_annot = FALSE;
+ if (ev_window->priv->annot)
+ g_object_unref (ev_window->priv->annot);
+ ev_window->priv->annot = (annot) ? g_object_ref (annot) : NULL;
+
+ action = gtk_action_group_get_action (ev_window->priv->view_popup_action_group,
+ "AnnotProperties");
+ gtk_action_set_visible (action, (annot != NULL && EV_IS_ANNOTATION_MARKUP (annot)));
+
if (annot && EV_IS_ANNOTATION_ATTACHMENT (annot)) {
- EvAttachment *attachment = EV_ANNOTATION_ATTACHMENT (annot)->attachment;
+ EvAttachment *attachment;
+ attachment = ev_annotation_attachment_get_attachment (EV_ANNOTATION_ATTACHMENT (annot));
if (attachment) {
show_annot = TRUE;
if (ev_window->priv->attach_list) {
@@ -5029,6 +5044,11 @@ ev_window_dispose (GObject *object)
priv->image = NULL;
}
+ if (priv->annot) {
+ g_object_unref (priv->annot);
+ priv->annot = NULL;
+ }
+
if (priv->attach_list) {
g_list_foreach (priv->attach_list,
(GFunc) g_object_unref,
@@ -5338,6 +5358,8 @@ static const GtkActionEntry view_popup_entries [] = {
NULL, G_CALLBACK (ev_view_popup_cmd_save_image_as) },
{ "CopyImage", NULL, N_("Copy _Image"), NULL,
NULL, G_CALLBACK (ev_view_popup_cmd_copy_image) },
+ { "AnnotProperties", NULL, N_("Annotation Properties…"), NULL,
+ NULL, G_CALLBACK (ev_view_popup_cmd_annot_properties) }
};
static const GtkActionEntry attachment_popup_entries [] = {
@@ -5384,6 +5406,30 @@ sidebar_annots_annot_activated_cb (EvSidebarAnnotations *sidebar_annots,
}
static void
+sidebar_annots_begin_annot_add (EvSidebarAnnotations *sidebar_annots,
+ EvAnnotationType annot_type,
+ EvWindow *window)
+{
+ ev_view_begin_add_annotation (EV_VIEW (window->priv->view), annot_type);
+}
+
+static void
+view_annot_added (EvView *view,
+ EvAnnotation *annot,
+ EvWindow *window)
+{
+ ev_sidebar_annotations_annot_added (EV_SIDEBAR_ANNOTATIONS (window->priv->sidebar_annots),
+ annot);
+}
+
+static void
+sidebar_annots_annot_add_cancelled (EvSidebarAnnotations *sidebar_annots,
+ EvWindow *window)
+{
+ ev_view_cancel_add_annotation (EV_VIEW (window->priv->view));
+}
+
+static void
register_custom_actions (EvWindow *window, GtkActionGroup *group)
{
GtkAction *action;
@@ -5995,6 +6041,67 @@ ev_view_popup_cmd_copy_image (GtkAction *action, EvWindow *window)
}
static void
+ev_view_popup_cmd_annot_properties (GtkAction *action,
+ EvWindow *window)
+{
+ const gchar *author;
+ GdkColor color;
+ gdouble opacity;
+ gboolean popup_is_open;
+ EvAnnotationPropertiesDialog *dialog;
+ EvAnnotation *annot = window->priv->annot;
+ EvAnnotationsSaveMask mask = EV_ANNOTATIONS_SAVE_NONE;
+
+ if (!annot)
+ return;
+
+ dialog = EV_ANNOTATION_PROPERTIES_DIALOG (ev_annotation_properties_dialog_new_with_annotation (window->priv->annot));
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_APPLY) {
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+
+ return;
+ }
+
+ /* Set annotations changes */
+ author = ev_annotation_properties_dialog_get_author (dialog);
+ if (ev_annotation_markup_set_label (EV_ANNOTATION_MARKUP (annot), author))
+ mask |= EV_ANNOTATIONS_SAVE_LABEL;
+
+ ev_annotation_properties_dialog_get_color (dialog, &color);
+ if (ev_annotation_set_color (annot, &color))
+ mask |= EV_ANNOTATIONS_SAVE_COLOR;
+
+ opacity = ev_annotation_properties_dialog_get_opacity (dialog);
+ if (ev_annotation_markup_set_opacity (EV_ANNOTATION_MARKUP (annot), opacity))
+ mask |= EV_ANNOTATIONS_SAVE_OPACITY;
+
+ popup_is_open = ev_annotation_properties_dialog_get_popup_is_open (dialog);
+ if (ev_annotation_markup_set_popup_is_open (EV_ANNOTATION_MARKUP (annot), popup_is_open))
+ mask |= EV_ANNOTATIONS_SAVE_POPUP_IS_OPEN;
+
+ if (EV_IS_ANNOTATION_TEXT (annot)) {
+ EvAnnotationTextIcon icon;
+
+ icon = ev_annotation_properties_dialog_get_text_icon (dialog);
+ if (ev_annotation_text_set_icon (EV_ANNOTATION_TEXT (annot), icon))
+ mask |= EV_ANNOTATIONS_SAVE_TEXT_ICON;
+ }
+
+ if (mask != EV_ANNOTATIONS_SAVE_NONE) {
+ ev_document_doc_mutex_lock ();
+ ev_document_annotations_save_annotation (EV_DOCUMENT_ANNOTATIONS (window->priv->document),
+ window->priv->annot,
+ mask);
+ ev_document_doc_mutex_unlock ();
+
+ /* FIXME: update annot region only */
+ ev_view_reload (EV_VIEW (window->priv->view));
+ }
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
ev_attachment_popup_cmd_open_attachment (GtkAction *action, EvWindow *window)
{
GList *l;
@@ -6553,6 +6660,14 @@ ev_window_init (EvWindow *ev_window)
"annot_activated",
G_CALLBACK (sidebar_annots_annot_activated_cb),
ev_window);
+ g_signal_connect (sidebar_widget,
+ "begin_annot_add",
+ G_CALLBACK (sidebar_annots_begin_annot_add),
+ ev_window);
+ g_signal_connect (sidebar_widget,
+ "annot_add_cancelled",
+ G_CALLBACK (sidebar_annots_annot_add_cancelled),
+ ev_window);
gtk_widget_show (sidebar_widget);
ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
sidebar_widget);
@@ -6598,6 +6713,9 @@ ev_window_init (EvWindow *ev_window)
g_signal_connect_object (ev_window->priv->view, "selection-changed",
G_CALLBACK (view_selection_changed_cb),
ev_window, 0);
+ g_signal_connect_object (ev_window->priv->view, "annot-added",
+ G_CALLBACK (view_annot_added),
+ ev_window, 0);
#ifdef ENABLE_DBUS
g_signal_connect_swapped (ev_window->priv->view, "sync-source",
G_CALLBACK (ev_window_sync_source),