]> www.fi.muni.cz Git - evince.git/blob - libmisc/ev-page-action.c
[dualscreen] fix crash on ctrl+w and fix control window closing
[evince.git] / libmisc / ev-page-action.c
1 /*
2  *  Copyright (C) 2003, 2004 Marco Pesenti Gritti
3  *  Copyright (C) 2003, 2004 Christian Persch
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include <glib/gi18n.h>
29 #include <gtk/gtk.h>
30
31 #include "ev-page-action.h"
32 #include "ev-page-action-widget.h"
33
34 struct _EvPageActionPrivate
35 {
36         EvDocumentModel *doc_model;
37         GtkTreeModel *model;
38 };
39
40
41 static void ev_page_action_init       (EvPageAction *action);
42 static void ev_page_action_class_init (EvPageActionClass *class);
43
44 enum
45 {
46         ACTIVATE_LINK,
47         N_SIGNALS
48 };
49
50 static guint signals[N_SIGNALS] = {0, };
51
52 G_DEFINE_TYPE (EvPageAction, ev_page_action, GTK_TYPE_ACTION)
53
54 #define EV_PAGE_ACTION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_PAGE_ACTION, EvPageActionPrivate))
55
56 enum {
57         PROP_0,
58         PROP_MODEL
59 };
60
61 static GtkWidget *
62 create_tool_item (GtkAction *action)
63 {
64         GtkWidget *proxy;
65
66         proxy = g_object_new (EV_TYPE_PAGE_ACTION_WIDGET, NULL);
67
68         return proxy;
69 }
70
71 static void
72 update_model (EvPageAction *page, GParamSpec *pspec, EvPageActionWidget *proxy)
73 {
74         ev_page_action_widget_update_links_model (proxy, page->priv->model);
75 }
76
77 static void
78 activate_link_cb (EvPageActionWidget *proxy, EvLink *link, EvPageAction *action)
79 {
80         g_signal_emit (action, signals[ACTIVATE_LINK], 0, link);
81 }
82
83 static void
84 connect_proxy (GtkAction *action, GtkWidget *proxy)
85 {
86         EvPageAction *page = EV_PAGE_ACTION (action);
87
88         if (GTK_IS_TOOL_ITEM (proxy)) {
89                 ev_page_action_widget_set_model (EV_PAGE_ACTION_WIDGET (proxy),
90                                                  page->priv->doc_model);
91                 g_signal_connect (proxy, "activate_link",
92                                   G_CALLBACK (activate_link_cb),
93                                   action);
94                 g_signal_connect_object (action, "notify::model",
95                                          G_CALLBACK (update_model),
96                                          proxy, 0);
97         }
98
99         GTK_ACTION_CLASS (ev_page_action_parent_class)->connect_proxy (action, proxy);
100 }
101
102 static void
103 ev_page_action_dispose (GObject *object)
104 {
105         EvPageAction *page = EV_PAGE_ACTION (object);
106
107         if (page->priv->model) {
108                 g_object_unref (page->priv->model);
109                 page->priv->model = NULL;
110         }
111
112         page->priv->doc_model = NULL;
113
114         G_OBJECT_CLASS (ev_page_action_parent_class)->dispose (object);
115 }
116
117 static void
118 ev_page_action_set_property (GObject      *object,
119                              guint         prop_id,
120                              const GValue *value,
121                              GParamSpec   *pspec)
122 {
123         EvPageAction *page = EV_PAGE_ACTION (object);
124
125         switch (prop_id)
126         {
127         case PROP_MODEL:
128                 ev_page_action_set_links_model (page, g_value_get_object (value));
129                 break;
130         default:
131                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
132                 break;
133         }
134 }
135
136 static void
137 ev_page_action_get_property (GObject    *object,
138                              guint       prop_id,
139                              GValue     *value,
140                              GParamSpec *pspec)
141 {
142         EvPageAction *page = EV_PAGE_ACTION (object);
143
144         switch (prop_id)
145         {
146         case PROP_MODEL:
147                 g_value_set_object (value, page->priv->model);
148                 break;
149         default:
150                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
151                 break;
152         }
153 }
154
155 void
156 ev_page_action_set_model (EvPageAction    *page,
157                           EvDocumentModel *model)
158 {
159         g_return_if_fail (EV_IS_PAGE_ACTION (page));
160         g_return_if_fail (EV_IS_DOCUMENT_MODEL (model));
161
162         if (page->priv->doc_model == model)
163                 return;
164
165         page->priv->doc_model = model;
166 }
167
168 void
169 ev_page_action_set_links_model (EvPageAction *page,
170                                 GtkTreeModel *links_model)
171 {
172         g_return_if_fail (EV_IS_PAGE_ACTION (page));
173         g_return_if_fail (GTK_IS_TREE_MODEL (links_model));
174
175         if (page->priv->model == links_model)
176                 return;
177
178         if (page->priv->model)
179                 g_object_unref (page->priv->model);
180         page->priv->model = g_object_ref (links_model);
181
182         g_object_notify (G_OBJECT (page), "model");
183 }
184
185 void
186 ev_page_action_grab_focus (EvPageAction *page_action)
187 {
188         GSList *proxies;
189
190         proxies = gtk_action_get_proxies (GTK_ACTION (page_action));
191         for (; proxies != NULL; proxies = proxies->next) {
192                 EvPageActionWidget *proxy;
193
194                 proxy = EV_PAGE_ACTION_WIDGET (proxies->data);
195
196                 if (gtk_widget_get_mapped (GTK_WIDGET (proxy)))
197                         ev_page_action_widget_grab_focus (proxy);
198         }
199 }
200
201 static void
202 ev_page_action_init (EvPageAction *page)
203 {
204         page->priv = EV_PAGE_ACTION_GET_PRIVATE (page);
205 }
206
207 static void
208 ev_page_action_class_init (EvPageActionClass *class)
209 {
210         GObjectClass *object_class = G_OBJECT_CLASS (class);
211         GtkActionClass *action_class = GTK_ACTION_CLASS (class);
212
213         object_class->dispose = ev_page_action_dispose;
214         object_class->set_property = ev_page_action_set_property;
215         object_class->get_property = ev_page_action_get_property;
216
217         action_class->toolbar_item_type = GTK_TYPE_TOOL_ITEM;
218         action_class->create_tool_item = create_tool_item;
219         action_class->connect_proxy = connect_proxy;
220
221         signals[ACTIVATE_LINK] = g_signal_new ("activate_link",
222                                                G_OBJECT_CLASS_TYPE (object_class),
223                                                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
224                                                G_STRUCT_OFFSET (EvPageActionClass, activate_link),
225                                                NULL, NULL,
226                                                g_cclosure_marshal_VOID__OBJECT,
227                                                G_TYPE_NONE, 1,
228                                                G_TYPE_OBJECT);
229
230         g_object_class_install_property (object_class,
231                                          PROP_MODEL,
232                                          g_param_spec_object ("model",
233                                                               "Model",
234                                                               "Current Links Model",
235                                                               GTK_TYPE_TREE_MODEL,
236                                                               G_PARAM_READWRITE));
237
238         g_type_class_add_private (object_class, sizeof (EvPageActionPrivate));
239 }