Merge lp:~elementary-apps/midori/browser-vala into lp:midori
- browser-vala
- Merge into trunk
Proposed by
Tom Beckmann
Status: | Work in progress | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~elementary-apps/midori/browser-vala | ||||
Merge into: | lp:midori | ||||
Diff against target: |
7009 lines (+5330/-1305) (has conflicts) 17 files modified
CMakeLists.txt (+25/-6) katze/midori-paths.vala (+0/-1) midori/CMakeLists.txt (+5/-2) midori/midori-app.h (+1/-1) midori/midori-browser.h (+0/-199) midori/midori-browser.vala (+5053/-1002) midori/midori-download.vala (+1/-5) midori/midori-privatedata.h (+1/-1) midori/midori-speeddial.vala (+0/-4) midori/midori-view.c (+1/-1) midori/midori.h (+0/-1) vapi/gobject-fixes.vapi (+23/-0) vapi/gtk-fixes.vapi (+27/-0) vapi/katze.vapi (+44/-4) vapi/midori.vapi (+147/-77) vapi/webkit2gtk-3.0.vapi (+1/-1) vapi/webkitgtk-3.0.vapi (+1/-0) Text conflict in midori/midori-browser.vala |
||||
To merge this branch: | bzr merge lp:~elementary-apps/midori/browser-vala | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Cris Dywan | Pending | ||
Review via email: mp+231592@code.launchpad.net |
Commit message
Description of the change
This is a port of midori/
To post a comment you must log in.
- 6778. By Tom Beckmann
-
Fix some errors, copy gtk and gobject vapis to local source to override faults in
GtkActionCallback and ParamSpec* type id bindings - 6779. By Tom Beckmann
-
Removed copies of gobject and gtk vapis in favor of minimal fixes vapis. Moved all vapis
to a vapi directory
Unmerged revisions
- 6779. By Tom Beckmann
-
Removed copies of gobject and gtk vapis in favor of minimal fixes vapis. Moved all vapis
to a vapi directory - 6778. By Tom Beckmann
-
Fix some errors, copy gtk and gobject vapis to local source to override faults in
GtkActionCallback and ParamSpec* type id bindings - 6777. By Tom Beckmann
-
Fix all errors, one valac crash remaining
- 6776. By Tom Beckmann
-
Start porting midori-browser.c to vala
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2014-07-11 01:36:48 +0000 | |||
3 | +++ CMakeLists.txt 2014-09-01 23:11:13 +0000 | |||
4 | @@ -212,13 +212,11 @@ | |||
5 | 212 | add_definitions("-DHAVE_WEBKIT2") | 212 | add_definitions("-DHAVE_WEBKIT2") |
6 | 213 | add_definitions("-DGTK_VERSION=\"${DEPS_GTK_gtk+-3.0_VERSION}\"") | 213 | add_definitions("-DGTK_VERSION=\"${DEPS_GTK_gtk+-3.0_VERSION}\"") |
7 | 214 | add_definitions("-DWEBKIT_VERSION=\"${DEPS_GTK_webkit2gtk-3.0_VERSION}\"") | 214 | add_definitions("-DWEBKIT_VERSION=\"${DEPS_GTK_webkit2gtk-3.0_VERSION}\"") |
9 | 215 | set(PKGS ${PKGS} gtk+-3.0) | 215 | set(PKGS ${PKGS} gtk+-3.0 webkit2gtk-3.0) |
10 | 216 | set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/midori/webkit2gtk-3.0.vapi") | 216 | set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/midori/webkit2gtk-3.0.vapi") |
11 | 217 | set(VALAFLAGS ${VALAFLAGS} -D HAVE_GTK3) | 217 | set(VALAFLAGS ${VALAFLAGS} -D HAVE_GTK3) |
12 | 218 | set(VALAFLAGS ${VALAFLAGS} -D HAVE_WEBKIT2) | 218 | set(VALAFLAGS ${VALAFLAGS} -D HAVE_WEBKIT2) |
16 | 219 | if (${DEPS_GTK_webkit2gtk-3.0_VERSION} VERSION_GREATER "2.3.90") | 219 | set(VALAFLAGS ${VALAFLAGS} -D HAVE_WEBKIT2_3_91) |
14 | 220 | set(VALAFLAGS ${VALAFLAGS} -D HAVE_WEBKIT2_3_91) | ||
15 | 221 | endif () | ||
17 | 222 | elseif (USE_GTK3) | 220 | elseif (USE_GTK3) |
18 | 223 | pkg_check_modules(DEPS_GTK REQUIRED | 221 | pkg_check_modules(DEPS_GTK REQUIRED |
19 | 224 | gtk+-3.0>=3.0.0 | 222 | gtk+-3.0>=3.0.0 |
20 | @@ -227,7 +225,7 @@ | |||
21 | 227 | ) | 225 | ) |
22 | 228 | add_definitions("-DGTK_VERSION=\"${DEPS_GTK_gtk+-3.0_VERSION}\"") | 226 | add_definitions("-DGTK_VERSION=\"${DEPS_GTK_gtk+-3.0_VERSION}\"") |
23 | 229 | add_definitions("-DWEBKIT_VERSION=\"${DEPS_GTK_webkitgtk-3.0_VERSION}\"") | 227 | add_definitions("-DWEBKIT_VERSION=\"${DEPS_GTK_webkitgtk-3.0_VERSION}\"") |
25 | 230 | set(PKGS ${PKGS} gtk+-3.0) | 228 | set(PKGS ${PKGS} gtk+-3.0 webkitgtk-3.0) |
26 | 231 | set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/midori/webkitgtk-3.0.vapi") | 229 | set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/midori/webkitgtk-3.0.vapi") |
27 | 232 | set(VALAFLAGS ${VALAFLAGS} -D HAVE_GTK3) | 230 | set(VALAFLAGS ${VALAFLAGS} -D HAVE_GTK3) |
28 | 233 | else () | 231 | else () |
29 | @@ -238,10 +236,31 @@ | |||
30 | 238 | ) | 236 | ) |
31 | 239 | add_definitions("-DGTK_VERSION=\"${DEPS_GTK_gtk+-2.0_VERSION}\"") | 237 | add_definitions("-DGTK_VERSION=\"${DEPS_GTK_gtk+-2.0_VERSION}\"") |
32 | 240 | add_definitions("-DWEBKIT_VERSION=\"${DEPS_GTK_webkit-1.0_VERSION}\"") | 238 | add_definitions("-DWEBKIT_VERSION=\"${DEPS_GTK_webkit-1.0_VERSION}\"") |
34 | 241 | set(PKGS ${PKGS} gtk+-2.0) | 239 | set(PKGS ${PKGS} gtk+-2.0 webkit-1.0) |
35 | 242 | set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/midori/webkitgtk-3.0.vapi") | 240 | set(EXTRA_VAPIS ${EXTRA_VAPIS} "${CMAKE_SOURCE_DIR}/midori/webkitgtk-3.0.vapi") |
36 | 243 | endif () | 241 | endif () |
37 | 244 | 242 | ||
38 | 243 | # vala has no GTK_CHECK_VERSION, so we need to cheat | ||
39 | 244 | pkg_check_modules(GTK_3_1_10 gtk+-3.0>=3.0.0) | ||
40 | 245 | if (GTK_3_0_0_FOUND) | ||
41 | 246 | set(VALAFLAGS ${VALAFLAGS} -D GTK_VERSION_3_0_0) | ||
42 | 247 | endif() | ||
43 | 248 | |||
44 | 249 | pkg_check_modules(GTK_3_4_0 gtk+-3.0>=3.4.0) | ||
45 | 250 | if (GTK_3_4_0_FOUND) | ||
46 | 251 | set(VALAFLAGS ${VALAFLAGS} -D GTK_VERSION_3_4_0) | ||
47 | 252 | endif() | ||
48 | 253 | |||
49 | 254 | pkg_check_modules(GTK_3_2_0 gtk+-3.0>=3.2.0) | ||
50 | 255 | if (GTK_3_2_0_FOUND) | ||
51 | 256 | set(VALAFLAGS ${VALAFLAGS} -D GTK_VERSION_3_2_0) | ||
52 | 257 | endif() | ||
53 | 258 | |||
54 | 259 | pkg_check_modules(GTK_3_1_10 gtk+-3.0>=3.1.10) | ||
55 | 260 | if (GTK_3_1_10_FOUND) | ||
56 | 261 | set(VALAFLAGS ${VALAFLAGS} -D GTK_VERSION_3_1_10) | ||
57 | 262 | endif() | ||
58 | 263 | |||
59 | 245 | # dh_translations detects this if there's no variable used | 264 | # dh_translations detects this if there's no variable used |
60 | 246 | set (GETTEXT_PACKAGE "midori") | 265 | set (GETTEXT_PACKAGE "midori") |
61 | 247 | add_definitions("-DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\"") | 266 | add_definitions("-DGETTEXT_PACKAGE=\"${GETTEXT_PACKAGE}\"") |
62 | 248 | 267 | ||
63 | === modified file 'katze/midori-paths.vala' | |||
64 | --- katze/midori-paths.vala 2014-04-03 00:49:01 +0000 | |||
65 | +++ katze/midori-paths.vala 2014-09-01 23:11:13 +0000 | |||
66 | @@ -17,7 +17,6 @@ | |||
67 | 17 | 17 | ||
68 | 18 | extern const string LIBDIR; | 18 | extern const string LIBDIR; |
69 | 19 | extern const string MDATADIR; | 19 | extern const string MDATADIR; |
70 | 20 | extern const string PACKAGE_NAME; | ||
71 | 21 | extern const string SYSCONFDIR; | 20 | extern const string SYSCONFDIR; |
72 | 22 | extern const string MIDORI_VERSION_SUFFIX; | 21 | extern const string MIDORI_VERSION_SUFFIX; |
73 | 23 | const string MODULE_PREFIX = "lib"; | 22 | const string MODULE_PREFIX = "lib"; |
74 | 24 | 23 | ||
75 | === modified file 'midori/CMakeLists.txt' | |||
76 | --- midori/CMakeLists.txt 2013-09-08 21:38:36 +0000 | |||
77 | +++ midori/CMakeLists.txt 2014-09-01 23:11:13 +0000 | |||
78 | @@ -16,10 +16,13 @@ | |||
79 | 16 | ${MIDORI_VALA_SOURCE} | 16 | ${MIDORI_VALA_SOURCE} |
80 | 17 | PACKAGES | 17 | PACKAGES |
81 | 18 | ${PKGS} | 18 | ${PKGS} |
82 | 19 | katze | ||
83 | 20 | midori | ||
84 | 21 | gobject-fixes | ||
85 | 22 | gtk-fixes | ||
86 | 19 | OPTIONS | 23 | OPTIONS |
87 | 20 | ${VALAFLAGS} | 24 | ${VALAFLAGS} |
90 | 21 | CUSTOM_VAPIS | 25 | --vapidir=${CMAKE_CURRENT_SOURCE_DIR}/../vapi |
89 | 22 | ${EXTRA_VAPIS} | ||
91 | 23 | GENERATE_VAPI | 26 | GENERATE_VAPI |
92 | 24 | "${CMAKE_PROJECT_NAME}-core" | 27 | "${CMAKE_PROJECT_NAME}-core" |
93 | 25 | GENERATE_HEADER | 28 | GENERATE_HEADER |
94 | 26 | 29 | ||
95 | === modified file 'midori/midori-app.h' | |||
96 | --- midori/midori-app.h 2013-03-28 17:27:56 +0000 | |||
97 | +++ midori/midori-app.h 2014-09-01 23:11:13 +0000 | |||
98 | @@ -14,7 +14,7 @@ | |||
99 | 14 | 14 | ||
100 | 15 | #include <katze/katze.h> | 15 | #include <katze/katze.h> |
101 | 16 | 16 | ||
103 | 17 | #include "midori-browser.h" | 17 | #include "midori-core.h" |
104 | 18 | #include "midori-websettings.h" | 18 | #include "midori-websettings.h" |
105 | 19 | 19 | ||
106 | 20 | G_BEGIN_DECLS | 20 | G_BEGIN_DECLS |
107 | 21 | 21 | ||
108 | === removed file 'midori/midori-browser.h' | |||
109 | --- midori/midori-browser.h 2013-03-26 23:09:09 +0000 | |||
110 | +++ midori/midori-browser.h 1970-01-01 00:00:00 +0000 | |||
111 | @@ -1,199 +0,0 @@ | |||
112 | 1 | /* | ||
113 | 2 | Copyright (C) 2008 Christian Dywan <christian@twotoasts.de> | ||
114 | 3 | |||
115 | 4 | This library is free software; you can redistribute it and/or | ||
116 | 5 | modify it under the terms of the GNU Lesser General Public | ||
117 | 6 | License as published by the Free Software Foundation; either | ||
118 | 7 | version 2.1 of the License, or (at your option) any later version. | ||
119 | 8 | |||
120 | 9 | See the file COPYING for the full license text. | ||
121 | 10 | */ | ||
122 | 11 | |||
123 | 12 | #ifndef __MIDORI_BROWSER_H__ | ||
124 | 13 | #define __MIDORI_BROWSER_H__ | ||
125 | 14 | |||
126 | 15 | #include <katze/katze.h> | ||
127 | 16 | #include "midori-view.h" | ||
128 | 17 | |||
129 | 18 | G_BEGIN_DECLS | ||
130 | 19 | |||
131 | 20 | #define MIDORI_TYPE_BROWSER \ | ||
132 | 21 | (midori_browser_get_type ()) | ||
133 | 22 | #define MIDORI_BROWSER(obj) \ | ||
134 | 23 | (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_BROWSER, MidoriBrowser)) | ||
135 | 24 | #define MIDORI_BROWSER_CLASS(klass) \ | ||
136 | 25 | (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_BROWSER, MidoriBrowserClass)) | ||
137 | 26 | #define MIDORI_IS_BROWSER(obj) \ | ||
138 | 27 | (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_BROWSER)) | ||
139 | 28 | #define MIDORI_IS_BROWSER_CLASS(klass) \ | ||
140 | 29 | (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_BROWSER)) | ||
141 | 30 | #define MIDORI_BROWSER_GET_CLASS(obj) \ | ||
142 | 31 | (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_BROWSER, MidoriBrowserClass)) | ||
143 | 32 | |||
144 | 33 | typedef struct _MidoriBrowser MidoriBrowser; | ||
145 | 34 | typedef struct _MidoriBrowserClass MidoriBrowserClass; | ||
146 | 35 | |||
147 | 36 | struct _MidoriBrowserClass | ||
148 | 37 | { | ||
149 | 38 | GtkWindowClass parent_class; | ||
150 | 39 | |||
151 | 40 | /* Signals */ | ||
152 | 41 | void | ||
153 | 42 | (*window_object_cleared) (MidoriBrowser* browser, | ||
154 | 43 | #ifndef HAVE_WEBKIT2 | ||
155 | 44 | WebKitWebFrame* web_frame, | ||
156 | 45 | #else | ||
157 | 46 | void* web_frame, | ||
158 | 47 | #endif | ||
159 | 48 | JSContextRef* context, | ||
160 | 49 | JSObjectRef* window_object); | ||
161 | 50 | void | ||
162 | 51 | (*statusbar_text_changed) (MidoriBrowser* browser, | ||
163 | 52 | const gchar* text); | ||
164 | 53 | void | ||
165 | 54 | (*element_motion) (MidoriBrowser* browser, | ||
166 | 55 | const gchar* link_uri); | ||
167 | 56 | void | ||
168 | 57 | (*new_window) (MidoriBrowser* browser, | ||
169 | 58 | const gchar* uri); | ||
170 | 59 | |||
171 | 60 | void | ||
172 | 61 | (*add_tab) (MidoriBrowser* browser, | ||
173 | 62 | GtkWidget* view); | ||
174 | 63 | void | ||
175 | 64 | (*remove_tab) (MidoriBrowser* browser, | ||
176 | 65 | GtkWidget* view); | ||
177 | 66 | void | ||
178 | 67 | (*activate_action) (MidoriBrowser* browser, | ||
179 | 68 | const gchar* name); | ||
180 | 69 | void | ||
181 | 70 | (*quit) (MidoriBrowser* browser); | ||
182 | 71 | }; | ||
183 | 72 | |||
184 | 73 | GType | ||
185 | 74 | midori_browser_get_type (void) G_GNUC_CONST; | ||
186 | 75 | |||
187 | 76 | MidoriBrowser* | ||
188 | 77 | midori_browser_new (void); | ||
189 | 78 | |||
190 | 79 | void | ||
191 | 80 | midori_browser_add_tab (MidoriBrowser* browser, | ||
192 | 81 | GtkWidget* widget); | ||
193 | 82 | |||
194 | 83 | void | ||
195 | 84 | midori_browser_close_tab (MidoriBrowser* browser, | ||
196 | 85 | GtkWidget* widget); | ||
197 | 86 | |||
198 | 87 | GtkWidget* | ||
199 | 88 | midori_browser_add_item (MidoriBrowser* browser, | ||
200 | 89 | KatzeItem* item); | ||
201 | 90 | |||
202 | 91 | GtkWidget* | ||
203 | 92 | midori_browser_add_uri (MidoriBrowser* browser, | ||
204 | 93 | const gchar* uri); | ||
205 | 94 | |||
206 | 95 | void | ||
207 | 96 | midori_browser_activate_action (MidoriBrowser* browser, | ||
208 | 97 | const gchar* name); | ||
209 | 98 | |||
210 | 99 | void | ||
211 | 100 | midori_browser_assert_action (MidoriBrowser* browser, | ||
212 | 101 | const gchar* name); | ||
213 | 102 | |||
214 | 103 | void | ||
215 | 104 | midori_browser_block_action (MidoriBrowser* browser, | ||
216 | 105 | GtkAction* action); | ||
217 | 106 | |||
218 | 107 | void | ||
219 | 108 | midori_browser_unblock_action (MidoriBrowser* browser, | ||
220 | 109 | GtkAction* action); | ||
221 | 110 | |||
222 | 111 | void | ||
223 | 112 | midori_browser_set_action_visible (MidoriBrowser* browser, | ||
224 | 113 | const gchar* name, | ||
225 | 114 | gboolean visible); | ||
226 | 115 | |||
227 | 116 | GtkActionGroup* | ||
228 | 117 | midori_browser_get_action_group (MidoriBrowser* browser); | ||
229 | 118 | |||
230 | 119 | void | ||
231 | 120 | midori_browser_set_current_uri (MidoriBrowser* browser, | ||
232 | 121 | const gchar* uri); | ||
233 | 122 | |||
234 | 123 | const gchar* | ||
235 | 124 | midori_browser_get_current_uri (MidoriBrowser* browser); | ||
236 | 125 | |||
237 | 126 | void | ||
238 | 127 | midori_browser_set_current_page_smartly (MidoriBrowser* browser, | ||
239 | 128 | gint n); | ||
240 | 129 | |||
241 | 130 | void | ||
242 | 131 | midori_browser_set_current_tab_smartly (MidoriBrowser* browser, | ||
243 | 132 | GtkWidget* view); | ||
244 | 133 | |||
245 | 134 | void | ||
246 | 135 | midori_browser_set_current_page (MidoriBrowser* browser, | ||
247 | 136 | gint n); | ||
248 | 137 | |||
249 | 138 | gint | ||
250 | 139 | midori_browser_get_current_page (MidoriBrowser* browser); | ||
251 | 140 | |||
252 | 141 | void | ||
253 | 142 | midori_browser_set_current_item (MidoriBrowser* browser, | ||
254 | 143 | KatzeItem* item); | ||
255 | 144 | |||
256 | 145 | GtkWidget* | ||
257 | 146 | midori_browser_get_nth_tab (MidoriBrowser* browser, | ||
258 | 147 | gint n); | ||
259 | 148 | |||
260 | 149 | void | ||
261 | 150 | midori_browser_set_current_tab (MidoriBrowser* browser, | ||
262 | 151 | GtkWidget* widget); | ||
263 | 152 | #define midori_browser_set_tab midori_browser_set_current_tab | ||
264 | 153 | |||
265 | 154 | GtkWidget* | ||
266 | 155 | midori_browser_get_current_tab (MidoriBrowser* browser); | ||
267 | 156 | #define midori_browser_get_tab midori_browser_get_current_tab | ||
268 | 157 | |||
269 | 158 | gint | ||
270 | 159 | midori_browser_page_num (MidoriBrowser* browser, | ||
271 | 160 | GtkWidget* view); | ||
272 | 161 | |||
273 | 162 | GList* | ||
274 | 163 | midori_browser_get_tabs (MidoriBrowser* browser); | ||
275 | 164 | |||
276 | 165 | gint | ||
277 | 166 | midori_browser_get_n_pages (MidoriBrowser* browser); | ||
278 | 167 | |||
279 | 168 | KatzeArray* | ||
280 | 169 | midori_browser_get_proxy_array (MidoriBrowser* browser); | ||
281 | 170 | |||
282 | 171 | MidoriBrowser* | ||
283 | 172 | midori_browser_get_for_widget (GtkWidget* widget); | ||
284 | 173 | |||
285 | 174 | void | ||
286 | 175 | midori_browser_quit (MidoriBrowser* browser); | ||
287 | 176 | |||
288 | 177 | const gchar** | ||
289 | 178 | midori_browser_get_toolbar_actions (MidoriBrowser* browser); | ||
290 | 179 | |||
291 | 180 | MidoriWebSettings* | ||
292 | 181 | midori_browser_get_settings (MidoriBrowser* browser); | ||
293 | 182 | |||
294 | 183 | void | ||
295 | 184 | midori_browser_update_history (KatzeItem* item, | ||
296 | 185 | const gchar* type, | ||
297 | 186 | const gchar* event); | ||
298 | 187 | |||
299 | 188 | void | ||
300 | 189 | midori_browser_save_uri (MidoriBrowser* browser, | ||
301 | 190 | MidoriView* view, | ||
302 | 191 | const gchar* uri); | ||
303 | 192 | |||
304 | 193 | void | ||
305 | 194 | midori_browser_set_inactivity_reset (MidoriBrowser* browser, | ||
306 | 195 | gint inactivity_reset); | ||
307 | 196 | |||
308 | 197 | G_END_DECLS | ||
309 | 198 | |||
310 | 199 | #endif /* __MIDORI_BROWSER_H__ */ | ||
311 | 200 | 0 | ||
312 | === renamed file 'midori/midori-browser.c' => 'midori/midori-browser.vala' | |||
313 | --- midori/midori-browser.c 2014-08-31 10:33:28 +0000 | |||
314 | +++ midori/midori-browser.vala 2014-09-01 23:11:13 +0000 | |||
315 | @@ -1,993 +1,923 @@ | |||
1285 | 1 | /* | 1 | |
1286 | 2 | Copyright (C) 2007-2013 Christian Dywan <christian@twotoasts.de> | 2 | namespace Midori { |
1287 | 3 | Copyright (C) 2008 Dale Whittaker <dayul@users.sf.net> | 3 | public class Browser : Gtk.Window { |
1288 | 4 | Copyright (C) 2009 Jérôme Geulfucci <jeromeg@xfce.org> | 4 | struct FolderEntry { |
1289 | 5 | 5 | string title; | |
1290 | 6 | This library is free software; you can redistribute it and/or | 6 | int64 id; |
1291 | 7 | modify it under the terms of the GNU Lesser General Public | 7 | int64 parentid; |
1292 | 8 | License as published by the Free Software Foundation; either | 8 | } |
1293 | 9 | version 2.1 of the License, or (at your option) any later version. | 9 | |
1294 | 10 | 10 | static construct { | |
1295 | 11 | See the file COPYING for the full license text. | 11 | #if GTK_VERSION_3_0_0 |
1296 | 12 | */ | 12 | Gtk.rc_parse ("style \"tool-button-style\"\n {\n" + |
1297 | 13 | 13 | "GtkToolButton::icon-spacing = 2\n }\n" + | |
1298 | 14 | #include "midori-browser.h" | 14 | "widget \"MidoriBrowser.*.MidoriBookmarkbar.Gtk*ToolButton\" " + |
1299 | 15 | 15 | "style \"tool-button-style\"\n" + | |
1300 | 16 | #include "midori-app.h" | 16 | "widget \"MidoriBrowser.*.MidoriFindbar.Gtk*ToolButton\" " + |
1301 | 17 | #include "midori-extension.h" | 17 | "style \"tool-button-style\"\n"); |
1302 | 18 | #include "midori-array.h" | 18 | #endif |
1303 | 19 | #include "midori-view.h" | 19 | } |
1304 | 20 | #include "midori-preferences.h" | 20 | |
1305 | 21 | #include "midori-panel.h" | 21 | public signal Browser new_window (Browser? new_window); |
1306 | 22 | #include "midori-locationaction.h" | 22 | public signal void move_tab (Gtk.Widget notebook, int current_position, int new_position); |
1307 | 23 | #include "midori-searchaction.h" | 23 | public signal void switch_tab (Object old_tab, Object new_tab); |
1308 | 24 | #include "midori-findbar.h" | 24 | public signal void add_download (WebKit.Download download); |
1309 | 25 | #include "midori-platform.h" | 25 | public signal void send_notification (string title, string message); |
1310 | 26 | #include "midori-privatedata.h" | 26 | public signal void populate_tool_menu (Gtk.Menu menu); |
1311 | 27 | #include "midori-core.h" | 27 | public signal void populate_toolbar_menu (Gtk.Menu menu); |
1312 | 28 | #include "midori-privatedata.h" | 28 | public signal void show_preferences (Katze.Preferences preferences); |
1313 | 29 | #include "midori-bookmarks-db.h" | 29 | |
1314 | 30 | #include "katze-cellrenderercomboboxtext.h" | 30 | public Gtk.Toolbar navigationbar { get; private set; } |
1315 | 31 | 31 | public Gtk.MenuBar menubar { get; private set; } | |
1316 | 32 | #include "marshal.h" | 32 | public Notebook notebook { get; private set; } |
1317 | 33 | 33 | public Panel panel { get; private set; } | |
1318 | 34 | #include <glib/gi18n.h> | 34 | public Katze.Array proxy_array { get; private set; } |
1319 | 35 | #include <glib/gstdio.h> | 35 | |
1320 | 36 | #include <gdk/gdkkeysyms.h> | 36 | public unowned string uri { |
1321 | 37 | #include <string.h> | 37 | get { return get_current_uri (); } |
1322 | 38 | 38 | set { set_current_uri (value); } | |
1323 | 39 | #include <config.h> | 39 | } |
1324 | 40 | 40 | ||
1325 | 41 | #ifdef HAVE_GRANITE | 41 | public unowned Tab tab { |
1326 | 42 | #include <granite.h> | 42 | get { return get_current_tab (); } |
1327 | 43 | #endif | 43 | set { set_current_tab (value); } |
1328 | 44 | 44 | } | |
1329 | 45 | #ifdef HAVE_ZEITGEIST | 45 | |
1330 | 46 | #include <zeitgeist.h> | 46 | public LoadStatus load_status { |
1331 | 47 | #endif | 47 | get { |
1332 | 48 | 48 | var tab = get_current_tab (); | |
1333 | 49 | #ifdef HAVE_UNISTD_H | 49 | return tab != null ? tab.load_status : LoadStatus.FINISHED; |
1334 | 50 | #include <unistd.h> | 50 | } |
1335 | 51 | #endif | 51 | } |
1336 | 52 | 52 | ||
1337 | 53 | #include <sqlite3.h> | 53 | /** |
1338 | 54 | 54 | * MidoriBrowser:statusbar: | |
1339 | 55 | #ifdef HAVE_X11_EXTENSIONS_SCRNSAVER_H | 55 | * |
1340 | 56 | #include <X11/Xlib.h> | 56 | * The widget representing the statusbar contents. This is |
1341 | 57 | #include <X11/Xutil.h> | 57 | * not an actual #GtkStatusbar but rather a #GtkBox. |
1342 | 58 | #include <X11/extensions/scrnsaver.h> | 58 | */ |
1343 | 59 | #include <gdk/gdkx.h> | 59 | public Gtk.Statusbar statusbar { get; private set; } |
1344 | 60 | #endif | 60 | |
1345 | 61 | 61 | /** | |
1346 | 62 | struct _MidoriBrowser | 62 | * MidoriBrowser:statusbar-text: |
1347 | 63 | { | 63 | * |
1348 | 64 | GtkWindow parent_instance; | 64 | * The text that is displayed in the statusbar. |
1349 | 65 | GtkActionGroup* action_group; | 65 | * |
1350 | 66 | GtkWidget* menubar; | 66 | * This value reflects changes to the text visible in the statusbar, such |
1351 | 67 | GtkWidget* throbber; | 67 | * as the uri of a hyperlink the mouse hovers over or the description of |
1352 | 68 | GtkWidget* navigationbar; | 68 | * a menuitem. |
1353 | 69 | GtkWidget* bookmarkbar; | 69 | * |
1354 | 70 | 70 | * Setting this value changes the displayed text until the next change. | |
1355 | 71 | GtkWidget* panel; | 71 | */ |
1356 | 72 | GtkWidget* notebook; | 72 | public string statusbar_text { |
1357 | 73 | 73 | get { | |
1358 | 74 | GtkWidget* inspector; | 74 | return _statusbar_text; |
1359 | 75 | GtkWidget* inspector_view; | 75 | } |
1360 | 76 | 76 | set { | |
1361 | 77 | GtkWidget* find; | 77 | _set_statusbar_text ((View) tab, value); |
1362 | 78 | 78 | } | |
1363 | 79 | GtkWidget* statusbar; | 79 | } |
1364 | 80 | GtkWidget* statusbar_contents; | 80 | |
1365 | 81 | gchar* statusbar_text; | 81 | /** |
1366 | 82 | 82 | * MidoriBrowser:settings: | |
1367 | 83 | gint last_window_width, last_window_height; | 83 | * |
1368 | 84 | guint alloc_timeout; | 84 | * An associated settings instance that is shared among all web views. |
1369 | 85 | guint panel_timeout; | 85 | * |
1370 | 86 | 86 | * Setting this value is propagated to every present web view. Also | |
1371 | 87 | MidoriWebSettings* settings; | 87 | * every newly created web view will use this instance automatically. |
1372 | 88 | KatzeArray* proxy_array; | 88 | * |
1373 | 89 | MidoriBookmarksDb* bookmarks; | 89 | * If no settings are specified a default will be used. |
1374 | 90 | KatzeArray* trash; | 90 | */ |
1375 | 91 | KatzeArray* search_engines; | 91 | public WebSettings settings { |
1376 | 92 | KatzeArray* history; | 92 | get { |
1377 | 93 | MidoriHistoryDatabase* history_database; | 93 | return _settings; |
1378 | 94 | MidoriSpeedDial* dial; | 94 | } |
1379 | 95 | gboolean show_tabs; | 95 | set { |
1380 | 96 | 96 | _settings.notify.disconnect (settings_notify); | |
1381 | 97 | gboolean show_navigationbar; | 97 | _settings = value; |
1382 | 98 | gboolean show_statusbar; | 98 | |
1383 | 99 | guint maximum_history_age; | 99 | if (_settings == null) |
1384 | 100 | guint last_web_search; | 100 | _settings = new WebSettings (); |
1385 | 101 | 101 | ||
1386 | 102 | gboolean bookmarkbar_populate; | 102 | update_settings (); |
1387 | 103 | }; | 103 | _settings.set_data<ulong> ("handle-settings-notify", _settings.notify.connect (settings_notify)); |
1388 | 104 | 104 | ||
1389 | 105 | G_DEFINE_TYPE (MidoriBrowser, midori_browser, GTK_TYPE_WINDOW) | 105 | foreach (var tab in get_tabs ()) |
1390 | 106 | 106 | ((View) tab).settings = _settings; | |
1391 | 107 | enum | 107 | } |
1392 | 108 | { | 108 | } |
1393 | 109 | PROP_0, | 109 | |
1394 | 110 | 110 | /** | |
1395 | 111 | PROP_MENUBAR, | 111 | * MidoriBrowser:proxy-items: |
1396 | 112 | PROP_NAVIGATIONBAR, | 112 | * |
1397 | 113 | PROP_NOTEBOOK, | 113 | * The open views, automatically updated, for session management. |
1398 | 114 | PROP_PANEL, | 114 | * |
1399 | 115 | PROP_URI, | 115 | * Since: 0.4.8 |
1400 | 116 | PROP_TAB, | 116 | */ |
1401 | 117 | PROP_LOAD_STATUS, | 117 | public Katze.Array proxy_items { get; private set; } |
1402 | 118 | PROP_STATUSBAR, | 118 | |
1403 | 119 | PROP_STATUSBAR_TEXT, | 119 | /** |
1404 | 120 | PROP_SETTINGS, | 120 | * MidoriBrowser:bookmarks: |
1405 | 121 | PROP_PROXY_ITEMS, | 121 | * |
1406 | 122 | PROP_BOOKMARKS, | 122 | * The bookmarks folder, containing all bookmarks. |
1407 | 123 | PROP_TRASH, | 123 | * |
1408 | 124 | PROP_SEARCH_ENGINES, | 124 | * This is actually a reference to a bookmarks instance, |
1409 | 125 | PROP_HISTORY, | 125 | * so if bookmarks should be used it must be initially set. |
1410 | 126 | PROP_SPEED_DIAL, | 126 | */ |
1411 | 127 | PROP_SHOW_TABS, | 127 | public BookmarksDb? bookmarks { |
1412 | 128 | }; | 128 | get { |
1413 | 129 | 129 | return _bookmarks; | |
1414 | 130 | enum | 130 | } |
1415 | 131 | { | 131 | set { |
1416 | 132 | NEW_WINDOW, | 132 | _set_bookmarks (value); |
1417 | 133 | ADD_TAB, | 133 | } |
1418 | 134 | REMOVE_TAB, | 134 | } |
1419 | 135 | MOVE_TAB, | 135 | |
1420 | 136 | SWITCH_TAB, | 136 | /** |
1421 | 137 | ACTIVATE_ACTION, | 137 | * MidoriBrowser:trash: |
1422 | 138 | ADD_DOWNLOAD, | 138 | * |
1423 | 139 | SEND_NOTIFICATION, | 139 | * The trash, that collects all closed tabs and windows. |
1424 | 140 | POPULATE_TOOL_MENU, | 140 | * |
1425 | 141 | POPULATE_TOOLBAR_MENU, | 141 | * This is actually a reference to a trash instance, so if a trash should |
1426 | 142 | QUIT, | 142 | * be used it must be initially set. |
1427 | 143 | SHOW_PREFERENCES, | 143 | * |
1428 | 144 | 144 | * Note: In the future the trash might collect other types of items. | |
1429 | 145 | LAST_SIGNAL | 145 | */ |
1430 | 146 | }; | 146 | public Katze.Array? trash { |
1431 | 147 | 147 | get { | |
1432 | 148 | static guint signals[LAST_SIGNAL]; | 148 | return _trash; |
1433 | 149 | 149 | } | |
1434 | 150 | static void | 150 | set { |
1435 | 151 | midori_browser_dispose (GObject* object); | 151 | _trash = value; |
1436 | 152 | 152 | ||
1437 | 153 | static void | 153 | var trash_action = (Katze.ArrayAction) action_group.get_action ("Trash"); |
1438 | 154 | midori_browser_finalize (GObject* object); | 154 | trash_action.array = _trash; |
1439 | 155 | 155 | trash_action.reversed = true; | |
1440 | 156 | #ifdef HAVE_WEBKIT2 | 156 | |
1441 | 157 | void download_created_destination_cb (WebKitDownload *download, | 157 | action_set_visible ("Trash", _trash != null); |
1442 | 158 | gchar *destination, | 158 | action_set_visible ("UndoTabClose", _trash != null); |
1443 | 159 | gpointer user_data); | 159 | |
1444 | 160 | #endif | 160 | if (trash != null) { |
1445 | 161 | 161 | trash.clear.connect_after (trash_clear_cb); | |
1446 | 162 | static void | 162 | trash_clear_cb (); |
478 | 163 | midori_browser_set_property (GObject* object, | ||
479 | 164 | guint prop_id, | ||
480 | 165 | const GValue* value, | ||
481 | 166 | GParamSpec* pspec); | ||
482 | 167 | |||
483 | 168 | static void | ||
484 | 169 | midori_browser_get_property (GObject* object, | ||
485 | 170 | guint prop_id, | ||
486 | 171 | GValue* value, | ||
487 | 172 | GParamSpec* pspec); | ||
488 | 173 | |||
489 | 174 | gboolean | ||
490 | 175 | midori_browser_open_bookmark (MidoriBrowser* browser, | ||
491 | 176 | KatzeItem* item); | ||
492 | 177 | |||
493 | 178 | static void | ||
494 | 179 | midori_bookmarkbar_populate (MidoriBrowser* browser); | ||
495 | 180 | static void | ||
496 | 181 | midori_bookmarkbar_populate_idle (MidoriBrowser* browser); | ||
497 | 182 | |||
498 | 183 | static void | ||
499 | 184 | midori_bookmarkbar_clear (GtkWidget* toolbar); | ||
500 | 185 | |||
501 | 186 | static void | ||
502 | 187 | _midori_browser_set_toolbar_style (MidoriBrowser* browser, | ||
503 | 188 | MidoriToolbarStyle toolbar_style); | ||
504 | 189 | |||
505 | 190 | static void | ||
506 | 191 | midori_browser_settings_notify (MidoriWebSettings* web_settings, | ||
507 | 192 | GParamSpec* pspec, | ||
508 | 193 | MidoriBrowser* browser); | ||
509 | 194 | |||
510 | 195 | void | ||
511 | 196 | midori_panel_set_toolbar_style (MidoriPanel* panel, | ||
512 | 197 | GtkToolbarStyle style); | ||
513 | 198 | |||
514 | 199 | static void | ||
515 | 200 | midori_browser_set_bookmarks (MidoriBrowser* browser, | ||
516 | 201 | MidoriBookmarksDb* bookmarks); | ||
517 | 202 | |||
518 | 203 | static void | ||
519 | 204 | midori_browser_add_speed_dial (MidoriBrowser* browser); | ||
520 | 205 | |||
521 | 206 | static void | ||
522 | 207 | midori_browser_step_history (MidoriBrowser* browser, | ||
523 | 208 | MidoriView* view); | ||
524 | 209 | |||
525 | 210 | #define _action_by_name(brwsr, nme) \ | ||
526 | 211 | gtk_action_group_get_action (brwsr->action_group, nme) | ||
527 | 212 | #define _action_set_sensitive(brwsr, nme, snstv) \ | ||
528 | 213 | gtk_action_set_sensitive (_action_by_name (brwsr, nme), snstv); | ||
529 | 214 | #define _action_set_visible(brwsr, nme, vsbl) \ | ||
530 | 215 | gtk_action_set_visible (_action_by_name (brwsr, nme), vsbl); | ||
531 | 216 | #define _action_set_active(brwsr, nme, actv) \ | ||
532 | 217 | gtk_toggle_action_set_active (GTK_TOGGLE_ACTION ( \ | ||
533 | 218 | _action_by_name (brwsr, nme)), actv); | ||
534 | 219 | |||
535 | 220 | static void | ||
536 | 221 | midori_browser_disconnect_tab (MidoriBrowser* browser, | ||
537 | 222 | MidoriView* view); | ||
538 | 223 | |||
539 | 224 | static gboolean | ||
540 | 225 | midori_browser_is_fullscreen (MidoriBrowser* browser) | ||
541 | 226 | { | ||
542 | 227 | GdkWindow* window = gtk_widget_get_window (GTK_WIDGET (browser)); | ||
543 | 228 | GdkWindowState state = window ? gdk_window_get_state (window) : 0; | ||
544 | 229 | return state & GDK_WINDOW_STATE_FULLSCREEN; | ||
545 | 230 | } | ||
546 | 231 | |||
547 | 232 | static gboolean | ||
548 | 233 | _toggle_tabbar_smartly (MidoriBrowser* browser, | ||
549 | 234 | gboolean ignore_fullscreen) | ||
550 | 235 | { | ||
551 | 236 | gboolean has_tabs = midori_browser_get_n_pages (browser) > 1; | ||
552 | 237 | gboolean show_tabs = !midori_browser_is_fullscreen (browser) || ignore_fullscreen; | ||
553 | 238 | if (!browser->show_tabs) | ||
554 | 239 | show_tabs = FALSE; | ||
555 | 240 | midori_notebook_set_labels_visible (MIDORI_NOTEBOOK (browser->notebook), show_tabs); | ||
556 | 241 | return has_tabs; | ||
557 | 242 | } | ||
558 | 243 | |||
559 | 244 | static void | ||
560 | 245 | midori_browser_trash_clear_cb (KatzeArray* trash, | ||
561 | 246 | MidoriBrowser* browser) | ||
562 | 247 | { | ||
563 | 248 | gboolean trash_empty = katze_array_is_empty (browser->trash); | ||
564 | 249 | _action_set_sensitive (browser, "UndoTabClose", !trash_empty); | ||
565 | 250 | _action_set_sensitive (browser, "Trash", !trash_empty); | ||
566 | 251 | } | ||
567 | 252 | |||
568 | 253 | static void | ||
569 | 254 | _midori_browser_update_actions (MidoriBrowser* browser) | ||
570 | 255 | { | ||
571 | 256 | gboolean has_tabs = _toggle_tabbar_smartly (browser, FALSE); | ||
572 | 257 | _action_set_sensitive (browser, "TabPrevious", has_tabs); | ||
573 | 258 | _action_set_sensitive (browser, "TabNext", has_tabs); | ||
574 | 259 | |||
575 | 260 | if (browser->trash) | ||
576 | 261 | midori_browser_trash_clear_cb (browser->trash, browser); | ||
577 | 262 | } | ||
578 | 263 | |||
579 | 264 | static void | ||
580 | 265 | midori_browser_update_secondary_icon (MidoriBrowser* browser, | ||
581 | 266 | MidoriView* view, | ||
582 | 267 | GtkAction* action) | ||
583 | 268 | { | ||
584 | 269 | if (g_object_get_data (G_OBJECT (view), "news-feeds")) | ||
585 | 270 | { | ||
586 | 271 | midori_location_action_set_secondary_icon ( | ||
587 | 272 | MIDORI_LOCATION_ACTION (action), STOCK_NEWS_FEED); | ||
588 | 273 | _action_set_sensitive (browser, "AddNewsFeed", TRUE); | ||
589 | 274 | } | ||
590 | 275 | else | ||
591 | 276 | { | ||
592 | 277 | midori_location_action_set_secondary_icon ( | ||
593 | 278 | MIDORI_LOCATION_ACTION (action), NULL); | ||
594 | 279 | _action_set_sensitive (browser, "AddNewsFeed", FALSE); | ||
595 | 280 | } | ||
596 | 281 | } | ||
597 | 282 | |||
598 | 283 | static void | ||
599 | 284 | _midori_browser_update_interface (MidoriBrowser* browser, | ||
600 | 285 | MidoriView* view) | ||
601 | 286 | { | ||
602 | 287 | GtkAction* action; | ||
603 | 288 | |||
604 | 289 | _action_set_sensitive (browser, "Back", midori_view_can_go_back (view)); | ||
605 | 290 | _action_set_sensitive (browser, "Forward", midori_tab_can_go_forward (MIDORI_TAB (view))); | ||
606 | 291 | _action_set_sensitive (browser, "Previous", | ||
607 | 292 | midori_view_get_previous_page (view) != NULL); | ||
608 | 293 | _action_set_sensitive (browser, "Next", | ||
609 | 294 | midori_view_get_next_page (view) != NULL); | ||
610 | 295 | |||
611 | 296 | _action_set_sensitive (browser, "AddSpeedDial", !midori_view_is_blank (view)); | ||
612 | 297 | _action_set_sensitive (browser, "BookmarkAdd", !midori_view_is_blank (view)); | ||
613 | 298 | _action_set_sensitive (browser, "MailTo", !midori_view_is_blank (view)); | ||
614 | 299 | _action_set_sensitive (browser, "SaveAs", midori_tab_can_save (MIDORI_TAB (view))); | ||
615 | 300 | _action_set_sensitive (browser, "ZoomIn", midori_view_can_zoom_in (view)); | ||
616 | 301 | _action_set_sensitive (browser, "ZoomOut", midori_view_can_zoom_out (view)); | ||
617 | 302 | _action_set_sensitive (browser, "ZoomNormal", | ||
618 | 303 | midori_view_get_zoom_level (view) != 1.0f); | ||
619 | 304 | _action_set_sensitive (browser, "Encoding", | ||
620 | 305 | midori_tab_can_view_source (MIDORI_TAB (view))); | ||
621 | 306 | _action_set_sensitive (browser, "SourceView", | ||
622 | 307 | midori_tab_can_view_source (MIDORI_TAB (view))); | ||
623 | 308 | _action_set_sensitive (browser, "SourceViewDom", | ||
624 | 309 | midori_tab_can_view_source (MIDORI_TAB (view))); | ||
625 | 310 | |||
626 | 311 | action = _action_by_name (browser, "NextForward"); | ||
627 | 312 | if (midori_tab_can_go_forward (MIDORI_TAB (view))) | ||
628 | 313 | { | ||
629 | 314 | g_object_set (action, | ||
630 | 315 | "stock-id", GTK_STOCK_GO_FORWARD, | ||
631 | 316 | "tooltip", _("Go forward to the next page"), | ||
632 | 317 | "sensitive", TRUE, NULL); | ||
633 | 318 | } | ||
634 | 319 | else | ||
635 | 320 | { | ||
636 | 321 | g_object_set (action, | ||
637 | 322 | "stock-id", GTK_STOCK_MEDIA_NEXT, | ||
638 | 323 | "tooltip", _("Go to the next sub-page"), | ||
639 | 324 | "sensitive", midori_view_get_next_page (view) != NULL, NULL); | ||
640 | 325 | } | ||
641 | 326 | |||
642 | 327 | action = _action_by_name (browser, "Location"); | ||
643 | 328 | if (midori_tab_is_blank (MIDORI_TAB (view))) | ||
644 | 329 | { | ||
645 | 330 | gchar* icon_names[] = { "edit-find-symbolic", "edit-find", NULL }; | ||
646 | 331 | GIcon* icon = g_themed_icon_new_from_names (icon_names, -1); | ||
647 | 332 | midori_location_action_set_primary_icon ( | ||
648 | 333 | MIDORI_LOCATION_ACTION (action), icon, _("Web Search…")); | ||
649 | 334 | g_object_unref (icon); | ||
650 | 335 | } | ||
651 | 336 | else | ||
652 | 337 | midori_location_action_set_security_hint ( | ||
653 | 338 | MIDORI_LOCATION_ACTION (action), midori_tab_get_security (MIDORI_TAB (view))); | ||
654 | 339 | midori_browser_update_secondary_icon (browser, view, action); | ||
655 | 340 | } | ||
656 | 341 | |||
657 | 342 | static void | ||
658 | 343 | _midori_browser_set_statusbar_text (MidoriBrowser* browser, | ||
659 | 344 | MidoriView* view, | ||
660 | 345 | const gchar* text) | ||
661 | 346 | { | ||
662 | 347 | #if GTK_CHECK_VERSION (3, 2, 0) | ||
663 | 348 | gboolean is_location = FALSE; | ||
664 | 349 | #else | ||
665 | 350 | GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser)); | ||
666 | 351 | gboolean is_location = widget && GTK_IS_ENTRY (widget) | ||
667 | 352 | && GTK_IS_ALIGNMENT (gtk_widget_get_parent (widget)); | ||
668 | 353 | #endif | ||
669 | 354 | |||
670 | 355 | katze_assign (browser->statusbar_text, midori_uri_format_for_display (text)); | ||
671 | 356 | if (view == NULL) | ||
672 | 357 | return; | ||
673 | 358 | |||
674 | 359 | if (!gtk_widget_get_visible (browser->statusbar) && !is_location | ||
675 | 360 | && text && *text) | ||
676 | 361 | { | ||
677 | 362 | #if GTK_CHECK_VERSION (3, 2, 0) | ||
678 | 363 | midori_view_set_overlay_text (view, browser->statusbar_text); | ||
679 | 364 | #else | ||
680 | 365 | GtkAction* action = _action_by_name (browser, "Location"); | ||
681 | 366 | MidoriLocationAction* location_action = MIDORI_LOCATION_ACTION (action); | ||
682 | 367 | midori_location_action_set_text (location_action, browser->statusbar_text); | ||
683 | 368 | midori_location_action_set_secondary_icon (location_action, NULL); | ||
684 | 369 | #endif | ||
685 | 370 | } | ||
686 | 371 | else if (!gtk_widget_get_visible (browser->statusbar) && !is_location) | ||
687 | 372 | { | ||
688 | 373 | #if GTK_CHECK_VERSION (3, 2, 0) | ||
689 | 374 | midori_view_set_overlay_text (view, NULL); | ||
690 | 375 | #else | ||
691 | 376 | GtkAction* action = _action_by_name (browser, "Location"); | ||
692 | 377 | MidoriLocationAction* location_action = MIDORI_LOCATION_ACTION (action); | ||
693 | 378 | midori_browser_update_secondary_icon (browser, view, action); | ||
694 | 379 | midori_location_action_set_text (location_action, | ||
695 | 380 | midori_view_get_display_uri (view)); | ||
696 | 381 | #endif | ||
697 | 382 | } | ||
698 | 383 | else | ||
699 | 384 | { | ||
700 | 385 | gtk_statusbar_pop (GTK_STATUSBAR (browser->statusbar), 1); | ||
701 | 386 | gtk_statusbar_push (GTK_STATUSBAR (browser->statusbar), 1, | ||
702 | 387 | katze_str_non_null (browser->statusbar_text)); | ||
703 | 388 | } | ||
704 | 389 | } | ||
705 | 390 | |||
706 | 391 | void | ||
707 | 392 | midori_browser_set_current_page_smartly (MidoriBrowser* browser, | ||
708 | 393 | gint n) | ||
709 | 394 | { | ||
710 | 395 | if (!katze_object_get_boolean (browser->settings, | ||
711 | 396 | "open-tabs-in-the-background")) | ||
712 | 397 | midori_browser_set_current_page (browser, n); | ||
713 | 398 | } | ||
714 | 399 | |||
715 | 400 | /** | ||
716 | 401 | * midori_browser_set_current_tab_smartly: | ||
717 | 402 | * @browser: a #MidoriBrowser | ||
718 | 403 | * @view: a #GtkWidget | ||
719 | 404 | * | ||
720 | 405 | * Switches to the tab containing @view iff open-tabs-in-the-background is %FALSE. | ||
721 | 406 | * | ||
722 | 407 | * Since: 0.4.9 | ||
723 | 408 | **/ | ||
724 | 409 | void | ||
725 | 410 | midori_browser_set_current_tab_smartly (MidoriBrowser* browser, | ||
726 | 411 | GtkWidget* view) | ||
727 | 412 | { | ||
728 | 413 | if (!katze_object_get_boolean (browser->settings, | ||
729 | 414 | "open-tabs-in-the-background")) | ||
730 | 415 | midori_browser_set_current_tab (browser, view); | ||
731 | 416 | } | ||
732 | 417 | |||
733 | 418 | static void | ||
734 | 419 | _midori_browser_update_progress (MidoriBrowser* browser, | ||
735 | 420 | MidoriView* view) | ||
736 | 421 | { | ||
737 | 422 | GtkAction* action; | ||
738 | 423 | gdouble progress = midori_view_get_progress (view); | ||
739 | 424 | gboolean loading = progress > 0.0; | ||
740 | 425 | |||
741 | 426 | action = _action_by_name (browser, "Location"); | ||
742 | 427 | midori_location_action_set_progress (MIDORI_LOCATION_ACTION (action), progress); | ||
743 | 428 | |||
744 | 429 | _action_set_sensitive (browser, "Reload", !loading); | ||
745 | 430 | _action_set_sensitive (browser, "Stop", loading); | ||
746 | 431 | |||
747 | 432 | action = _action_by_name (browser, "ReloadStop"); | ||
748 | 433 | if (!loading) | ||
749 | 434 | { | ||
750 | 435 | g_object_set (action, | ||
751 | 436 | "stock-id", GTK_STOCK_REFRESH, | ||
752 | 437 | "tooltip", _("Reload the current page"), NULL); | ||
753 | 438 | } | ||
754 | 439 | else | ||
755 | 440 | { | ||
756 | 441 | g_object_set (action, | ||
757 | 442 | "stock-id", GTK_STOCK_STOP, | ||
758 | 443 | "tooltip", _("Stop loading the current page"), NULL); | ||
759 | 444 | } | ||
760 | 445 | |||
761 | 446 | g_object_set (browser->throbber, "active", loading, "visible", loading, NULL); | ||
762 | 447 | } | ||
763 | 448 | |||
764 | 449 | /** | ||
765 | 450 | * midori_browser_update_history: | ||
766 | 451 | * @item: a #KatzeItem | ||
767 | 452 | * @type: "website", "bookmark" or "download" | ||
768 | 453 | * @event: "access", "leave", "modify", "delete" | ||
769 | 454 | * | ||
770 | 455 | * Since: 0.4.7 | ||
771 | 456 | **/ | ||
772 | 457 | void | ||
773 | 458 | midori_browser_update_history (KatzeItem* item, | ||
774 | 459 | const gchar* type, | ||
775 | 460 | const gchar* event) | ||
776 | 461 | { | ||
777 | 462 | g_return_if_fail (!KATZE_ITEM_IS_SEPARATOR (item)); | ||
778 | 463 | |||
779 | 464 | #ifdef HAVE_ZEITGEIST | ||
780 | 465 | const gchar* inter; | ||
781 | 466 | if (strstr (event, "access")) | ||
782 | 467 | inter = ZEITGEIST_ZG_ACCESS_EVENT; | ||
783 | 468 | else if (strstr (event, "leave")) | ||
784 | 469 | inter = ZEITGEIST_ZG_LEAVE_EVENT; | ||
785 | 470 | else if (strstr (event, "modify")) | ||
786 | 471 | inter = ZEITGEIST_ZG_MODIFY_EVENT; | ||
787 | 472 | else if (strstr (event, "create")) | ||
788 | 473 | inter = ZEITGEIST_ZG_CREATE_EVENT; | ||
789 | 474 | else if (strstr (event, "delete")) | ||
790 | 475 | inter = ZEITGEIST_ZG_DELETE_EVENT; | ||
791 | 476 | else | ||
792 | 477 | g_assert_not_reached (); | ||
793 | 478 | |||
794 | 479 | /* FIXME: Should insert folders into the log (ZEITGEIST_NFO_BOOKMARK_FOLDER) */ | ||
795 | 480 | if (KATZE_ITEM_IS_FOLDER (item)) | ||
796 | 481 | return; | ||
797 | 482 | |||
798 | 483 | zeitgeist_log_insert_events_no_reply (zeitgeist_log_get_default (), | ||
799 | 484 | zeitgeist_event_new_full (inter, ZEITGEIST_ZG_USER_ACTIVITY, | ||
800 | 485 | "application://midori.desktop", | ||
801 | 486 | zeitgeist_subject_new_full ( | ||
802 | 487 | katze_item_get_uri (item), | ||
803 | 488 | strstr (type, "bookmark") ? ZEITGEIST_NFO_BOOKMARK : ZEITGEIST_NFO_WEBSITE, | ||
804 | 489 | zeitgeist_manifestation_for_uri (katze_item_get_uri (item)), | ||
805 | 490 | katze_item_get_meta_string (item, "mime-type"), NULL, katze_item_get_name (item), NULL), | ||
806 | 491 | NULL), | ||
807 | 492 | NULL); | ||
808 | 493 | #endif | ||
809 | 494 | } | ||
810 | 495 | |||
811 | 496 | static void | ||
812 | 497 | midori_browser_update_history_title (MidoriBrowser* browser, | ||
813 | 498 | KatzeItem* item) | ||
814 | 499 | { | ||
815 | 500 | sqlite3* db; | ||
816 | 501 | static sqlite3_stmt* stmt = NULL; | ||
817 | 502 | |||
818 | 503 | g_return_if_fail (katze_item_get_uri (item) != NULL); | ||
819 | 504 | |||
820 | 505 | db = g_object_get_data (G_OBJECT (browser->history), "db"); | ||
821 | 506 | g_return_if_fail (db != NULL); | ||
822 | 507 | if (!stmt) | ||
823 | 508 | { | ||
824 | 509 | const gchar* sqlcmd; | ||
825 | 510 | |||
826 | 511 | sqlcmd = "UPDATE history SET title=? WHERE uri = ? and date=?"; | ||
827 | 512 | sqlite3_prepare_v2 (db, sqlcmd, -1, &stmt, NULL); | ||
828 | 513 | } | ||
829 | 514 | sqlite3_bind_text (stmt, 1, katze_item_get_name (item), -1, 0); | ||
830 | 515 | sqlite3_bind_text (stmt, 2, katze_item_get_uri (item), -1, 0); | ||
831 | 516 | sqlite3_bind_int64 (stmt, 3, katze_item_get_added (item)); | ||
832 | 517 | |||
833 | 518 | if (sqlite3_step (stmt) != SQLITE_DONE) | ||
834 | 519 | g_printerr (_("Failed to update title: %s\n"), sqlite3_errmsg (db)); | ||
835 | 520 | sqlite3_reset (stmt); | ||
836 | 521 | sqlite3_clear_bindings (stmt); | ||
837 | 522 | |||
838 | 523 | midori_browser_update_history (item, "website", "access"); | ||
839 | 524 | } | ||
840 | 525 | |||
841 | 526 | /** | ||
842 | 527 | * midori_browser_assert_action: | ||
843 | 528 | * @browser: a #MidoriBrowser | ||
844 | 529 | * @name: action, setting=value expression or extension=true|false | ||
845 | 530 | * | ||
846 | 531 | * Assert that @name is a valid action or setting expression, | ||
847 | 532 | * if it fails the program will terminate with an error. | ||
848 | 533 | * To be used with command line interfaces. | ||
849 | 534 | * | ||
850 | 535 | * Since: 0.5.0 | ||
851 | 536 | **/ | ||
852 | 537 | void | ||
853 | 538 | midori_browser_assert_action (MidoriBrowser* browser, | ||
854 | 539 | const gchar* name) | ||
855 | 540 | { | ||
856 | 541 | g_return_if_fail (MIDORI_IS_BROWSER (browser)); | ||
857 | 542 | g_return_if_fail (name != NULL); | ||
858 | 543 | |||
859 | 544 | if (strchr (name, '=')) | ||
860 | 545 | { | ||
861 | 546 | gchar** parts = g_strsplit (name, "=", 0); | ||
862 | 547 | GObjectClass* class = G_OBJECT_GET_CLASS (browser->settings); | ||
863 | 548 | GParamSpec* pspec = g_object_class_find_property (class, parts[0]); | ||
864 | 549 | if (pspec != NULL) | ||
865 | 550 | { | ||
866 | 551 | GType type = G_PARAM_SPEC_TYPE (pspec); | ||
867 | 552 | if (!( | ||
868 | 553 | (type == G_TYPE_PARAM_BOOLEAN && (!strcmp (parts[1], "true") || !strcmp (parts[1], "false"))) | ||
869 | 554 | || type == G_TYPE_PARAM_STRING | ||
870 | 555 | || type == G_TYPE_PARAM_INT | ||
871 | 556 | || type == G_TYPE_PARAM_FLOAT | ||
872 | 557 | || type == G_TYPE_PARAM_DOUBLE | ||
873 | 558 | || type == G_TYPE_PARAM_ENUM)) | ||
874 | 559 | midori_error (_("Value '%s' is invalid for %s"), parts[1], parts[0]); | ||
875 | 560 | } | ||
876 | 561 | else | ||
877 | 562 | { | ||
878 | 563 | gchar* extension_path = midori_paths_get_lib_path (PACKAGE_NAME); | ||
879 | 564 | GObject* extension = midori_extension_load_from_file (extension_path, parts[0], FALSE, FALSE); | ||
880 | 565 | g_free (extension_path); | ||
881 | 566 | if (!extension || (strcmp (parts[1], "true") && strcmp (parts[1], "false"))) | ||
882 | 567 | midori_error (_("Unexpected setting '%s'"), name); | ||
883 | 568 | } | ||
884 | 569 | g_strfreev (parts); | ||
885 | 570 | } | ||
886 | 571 | else | ||
887 | 572 | { | ||
888 | 573 | GtkAction* action = _action_by_name (browser, name); | ||
889 | 574 | if (!action) | ||
890 | 575 | midori_error (_("Unexpected action '%s'."), name); | ||
891 | 576 | } | ||
892 | 577 | } | ||
893 | 578 | |||
894 | 579 | void | ||
895 | 580 | midori_app_set_browsers (MidoriApp* app, | ||
896 | 581 | KatzeArray* browsers, | ||
897 | 582 | MidoriBrowser* browser); | ||
898 | 583 | |||
899 | 584 | static void | ||
900 | 585 | _midori_browser_activate_action (MidoriBrowser* browser, | ||
901 | 586 | const gchar* name) | ||
902 | 587 | { | ||
903 | 588 | g_return_if_fail (name != NULL); | ||
904 | 589 | |||
905 | 590 | if (strchr (name, '=')) | ||
906 | 591 | { | ||
907 | 592 | gchar** parts = g_strsplit (name, "=", 0); | ||
908 | 593 | GObjectClass* class = G_OBJECT_GET_CLASS (browser->settings); | ||
909 | 594 | GParamSpec* pspec = g_object_class_find_property (class, parts[0]); | ||
910 | 595 | if (pspec != NULL) | ||
911 | 596 | { | ||
912 | 597 | GType type = G_PARAM_SPEC_TYPE (pspec); | ||
913 | 598 | if (type == G_TYPE_PARAM_BOOLEAN && !strcmp ("true", parts[1])) | ||
914 | 599 | g_object_set (browser->settings, parts[0], TRUE, NULL); | ||
915 | 600 | else if (type == G_TYPE_PARAM_BOOLEAN && !strcmp ("false", parts[1])) | ||
916 | 601 | g_object_set (browser->settings, parts[0], FALSE, NULL); | ||
917 | 602 | else if (type == G_TYPE_PARAM_STRING) | ||
918 | 603 | g_object_set (browser->settings, parts[0], parts[1], NULL); | ||
919 | 604 | else if (type == G_TYPE_PARAM_INT || type == G_TYPE_PARAM_UINT) | ||
920 | 605 | g_object_set (browser->settings, parts[0], atoi (parts[1]), NULL); | ||
921 | 606 | else if (type == G_TYPE_PARAM_FLOAT || type == G_TYPE_PARAM_DOUBLE) | ||
922 | 607 | g_object_set (browser->settings, parts[0], g_ascii_strtod (parts[1], NULL), NULL); | ||
923 | 608 | else if (type == G_TYPE_PARAM_ENUM) | ||
924 | 609 | { | ||
925 | 610 | GEnumClass* enum_class = G_ENUM_CLASS (g_type_class_peek (pspec->value_type)); | ||
926 | 611 | GEnumValue* enum_value = g_enum_get_value_by_name (enum_class, parts[1]); | ||
927 | 612 | if (enum_value != NULL) | ||
928 | 613 | g_object_set (browser->settings, parts[0], enum_value->value, NULL); | ||
929 | 614 | else | ||
930 | 615 | g_warning (_("Value '%s' is invalid for %s"), parts[1], parts[0]); | ||
931 | 616 | } | ||
932 | 617 | else | ||
933 | 618 | g_warning (_("Value '%s' is invalid for %s"), parts[1], parts[0]); | ||
934 | 619 | } | ||
935 | 620 | else | ||
936 | 621 | { | ||
937 | 622 | gchar* extension_path = midori_paths_get_lib_path (PACKAGE_NAME); | ||
938 | 623 | GObject* extension = midori_extension_load_from_file (extension_path, parts[0], TRUE, FALSE); | ||
939 | 624 | MidoriApp* app = midori_app_new_proxy (NULL); | ||
940 | 625 | g_object_set (app, | ||
941 | 626 | "settings", browser->settings, | ||
942 | 627 | NULL); | ||
943 | 628 | /* FIXME: tabs of multiple windows */ | ||
944 | 629 | KatzeArray* browsers = katze_array_new (MIDORI_TYPE_BROWSER); | ||
945 | 630 | katze_array_add_item (browsers, browser); | ||
946 | 631 | midori_app_set_browsers (app, browsers, browser); | ||
947 | 632 | g_free (extension_path); | ||
948 | 633 | if (extension && !strcmp (parts[1], "true")) | ||
949 | 634 | midori_extension_activate (extension, parts[0], TRUE, app); | ||
950 | 635 | else if (extension && !strcmp (parts[1], "false")) | ||
951 | 636 | midori_extension_deactivate (MIDORI_EXTENSION (extension)); | ||
952 | 637 | else | ||
953 | 638 | g_warning (_("Unexpected setting '%s'"), name); | ||
954 | 639 | } | ||
955 | 640 | g_strfreev (parts); | ||
956 | 641 | } | ||
957 | 642 | else | ||
958 | 643 | { | ||
959 | 644 | GtkAction* action = _action_by_name (browser, name); | ||
960 | 645 | if (action) | ||
961 | 646 | gtk_action_activate (action); | ||
962 | 647 | else | ||
963 | 648 | g_warning (_("Unexpected action '%s'."), name); | ||
964 | 649 | } | ||
965 | 650 | } | ||
966 | 651 | |||
967 | 652 | static void | ||
968 | 653 | midori_view_notify_icon_cb (MidoriView* view, | ||
969 | 654 | GParamSpec* pspec, | ||
970 | 655 | MidoriBrowser* browser) | ||
971 | 656 | { | ||
972 | 657 | if (midori_browser_get_current_tab (browser) != (GtkWidget*)view) | ||
973 | 658 | return; | ||
974 | 659 | |||
975 | 660 | if (midori_paths_get_runtime_mode () == MIDORI_RUNTIME_MODE_APP) | ||
976 | 661 | gtk_window_set_icon (GTK_WINDOW (browser), midori_view_get_icon (view)); | ||
977 | 662 | } | ||
978 | 663 | |||
979 | 664 | static void | ||
980 | 665 | midori_view_notify_load_status_cb (GtkWidget* widget, | ||
981 | 666 | GParamSpec* pspec, | ||
982 | 667 | MidoriBrowser* browser) | ||
983 | 668 | { | ||
984 | 669 | MidoriView* view = MIDORI_VIEW (widget); | ||
985 | 670 | MidoriLoadStatus load_status = midori_view_get_load_status (view); | ||
986 | 671 | |||
987 | 672 | if (widget == midori_browser_get_current_tab (browser)) | ||
988 | 673 | { | ||
989 | 674 | if (load_status == MIDORI_LOAD_COMMITTED) | ||
990 | 675 | { | ||
991 | 676 | const gchar* uri = midori_view_get_display_uri (view); | ||
992 | 677 | GtkAction* action = _action_by_name (browser, "Location"); | ||
993 | 678 | midori_location_action_set_text ( | ||
994 | 679 | MIDORI_LOCATION_ACTION (action), uri); | ||
995 | 680 | |||
996 | 681 | /* Focus the urlbar on blank pages */ | ||
997 | 682 | if (midori_view_is_blank (view)) | ||
998 | 683 | midori_browser_activate_action (browser, "Location"); | ||
999 | 684 | } | ||
1000 | 685 | |||
1001 | 686 | _midori_browser_update_interface (browser, view); | ||
1002 | 687 | _midori_browser_set_statusbar_text (browser, view, NULL); | ||
1003 | 688 | } | ||
1004 | 689 | |||
1005 | 690 | if (load_status == MIDORI_LOAD_FINISHED) | ||
1006 | 691 | katze_item_set_meta_string (midori_view_get_proxy_item (view), | ||
1007 | 692 | "history-step", NULL); | ||
1008 | 693 | |||
1009 | 694 | g_object_notify (G_OBJECT (browser), "load-status"); | ||
1010 | 695 | } | ||
1011 | 696 | |||
1012 | 697 | static void | ||
1013 | 698 | midori_view_notify_progress_cb (GtkWidget* view, | ||
1014 | 699 | GParamSpec* pspec, | ||
1015 | 700 | MidoriBrowser* browser) | ||
1016 | 701 | { | ||
1017 | 702 | if (view == midori_browser_get_current_tab (browser)) | ||
1018 | 703 | _midori_browser_update_progress (browser, MIDORI_VIEW (view)); | ||
1019 | 704 | } | ||
1020 | 705 | |||
1021 | 706 | static void | ||
1022 | 707 | midori_view_notify_uri_cb (GtkWidget* widget, | ||
1023 | 708 | GParamSpec* pspec, | ||
1024 | 709 | MidoriBrowser* browser) | ||
1025 | 710 | { | ||
1026 | 711 | if (widget == midori_browser_get_current_tab (browser)) | ||
1027 | 712 | { | ||
1028 | 713 | MidoriView* view = MIDORI_VIEW (widget); | ||
1029 | 714 | const gchar* uri = midori_view_get_display_uri (view); | ||
1030 | 715 | GtkAction* action = _action_by_name (browser, "Location"); | ||
1031 | 716 | midori_location_action_set_text (MIDORI_LOCATION_ACTION (action), uri); | ||
1032 | 717 | _action_set_sensitive (browser, "Back", midori_view_can_go_back (view)); | ||
1033 | 718 | _action_set_sensitive (browser, "Forward", midori_tab_can_go_forward (MIDORI_TAB (view))); | ||
1034 | 719 | g_object_notify (G_OBJECT (browser), "uri"); | ||
1035 | 720 | } | ||
1036 | 721 | } | ||
1037 | 722 | |||
1038 | 723 | static void | ||
1039 | 724 | midori_browser_set_title (MidoriBrowser* browser, | ||
1040 | 725 | const gchar* title) | ||
1041 | 726 | { | ||
1042 | 727 | const gchar* custom_title = midori_settings_get_custom_title (MIDORI_SETTINGS (browser->settings)); | ||
1043 | 728 | if (custom_title && *custom_title) | ||
1044 | 729 | gtk_window_set_title (GTK_WINDOW (browser), custom_title); | ||
1045 | 730 | else if (katze_object_get_boolean (browser->settings, "enable-private-browsing")) | ||
1046 | 731 | { | ||
1047 | 732 | gchar* window_title = g_strdup_printf (_("%s (Private Browsing)"), title); | ||
1048 | 733 | gtk_window_set_title (GTK_WINDOW (browser), window_title); | ||
1049 | 734 | g_free (window_title); | ||
1050 | 735 | } | ||
1051 | 736 | else | ||
1052 | 737 | gtk_window_set_title (GTK_WINDOW (browser), title); | ||
1053 | 738 | } | ||
1054 | 739 | |||
1055 | 740 | static void | ||
1056 | 741 | midori_view_notify_title_cb (GtkWidget* widget, | ||
1057 | 742 | GParamSpec* pspec, | ||
1058 | 743 | MidoriBrowser* browser) | ||
1059 | 744 | { | ||
1060 | 745 | MidoriView* view = MIDORI_VIEW (widget); | ||
1061 | 746 | if (widget == midori_browser_get_current_tab (browser)) | ||
1062 | 747 | { | ||
1063 | 748 | midori_browser_set_title (browser, midori_view_get_display_title (view)); | ||
1064 | 749 | g_object_notify (G_OBJECT (browser), "title"); | ||
1065 | 750 | } | ||
1066 | 751 | midori_browser_step_history (browser, view); | ||
1067 | 752 | } | ||
1068 | 753 | |||
1069 | 754 | static void | ||
1070 | 755 | midori_browser_step_history (MidoriBrowser* browser, | ||
1071 | 756 | MidoriView* view) | ||
1072 | 757 | { | ||
1073 | 758 | if (midori_view_get_load_status (view) != MIDORI_LOAD_COMMITTED) | ||
1074 | 759 | return; | ||
1075 | 760 | if (!browser->history_database || !browser->maximum_history_age) | ||
1076 | 761 | return; | ||
1077 | 762 | |||
1078 | 763 | KatzeItem* proxy = midori_view_get_proxy_item (view); | ||
1079 | 764 | const gchar* proxy_uri = katze_item_get_uri (proxy); | ||
1080 | 765 | if (midori_uri_is_blank (proxy_uri)) | ||
1081 | 766 | return; | ||
1082 | 767 | |||
1083 | 768 | const gchar* history_step = katze_item_get_meta_string (proxy, "history-step"); | ||
1084 | 769 | if (history_step == NULL) | ||
1085 | 770 | { | ||
1086 | 771 | GError* error = NULL; | ||
1087 | 772 | time_t now = time (NULL); | ||
1088 | 773 | katze_item_set_added (proxy, now); | ||
1089 | 774 | gint64 day = sokoke_time_t_to_julian (&now); | ||
1090 | 775 | midori_history_database_insert (browser->history_database, | ||
1091 | 776 | katze_item_get_uri (proxy), | ||
1092 | 777 | katze_item_get_name (proxy), | ||
1093 | 778 | katze_item_get_added (proxy), day, &error); | ||
1094 | 779 | if (error != NULL) | ||
1095 | 780 | { | ||
1096 | 781 | g_printerr (_("Failed to insert new history item: %s\n"), error->message); | ||
1097 | 782 | g_error_free (error); | ||
1098 | 783 | return; | ||
1099 | 784 | } | ||
1100 | 785 | katze_item_set_meta_string (proxy, "history-step", "update"); | ||
1101 | 786 | /* FIXME: No signal for adding/ removing */ | ||
1102 | 787 | katze_array_add_item (browser->history, proxy); | ||
1103 | 788 | katze_array_remove_item (browser->history, proxy); | ||
1104 | 789 | } | ||
1105 | 790 | else if (!strcmp (history_step, "update")) | ||
1106 | 791 | { | ||
1107 | 792 | if (proxy->name != NULL) | ||
1108 | 793 | midori_browser_update_history_title (browser, proxy); | ||
1109 | 794 | } | ||
1110 | 795 | else if (!strcmp (history_step, "ignore")) | ||
1111 | 796 | { | ||
1112 | 797 | /* This is set when restoring sessions */ | ||
1113 | 798 | } | ||
1114 | 799 | else | ||
1115 | 800 | g_warning ("Unexpected history-step: %s", history_step); | ||
1116 | 801 | } | ||
1117 | 802 | |||
1118 | 803 | static void | ||
1119 | 804 | midori_view_notify_zoom_level_cb (GtkWidget* view, | ||
1120 | 805 | GParamSpec* pspec, | ||
1121 | 806 | MidoriBrowser* browser) | ||
1122 | 807 | { | ||
1123 | 808 | if (view == midori_browser_get_current_tab (browser)) | ||
1124 | 809 | _action_set_sensitive (browser, "ZoomNormal", | ||
1125 | 810 | midori_view_get_zoom_level (MIDORI_VIEW (view)) != 1.0f); | ||
1126 | 811 | } | ||
1127 | 812 | |||
1128 | 813 | static void | ||
1129 | 814 | midori_view_notify_statusbar_text_cb (GtkWidget* view, | ||
1130 | 815 | GParamSpec* pspec, | ||
1131 | 816 | MidoriBrowser* browser) | ||
1132 | 817 | { | ||
1133 | 818 | gchar* text; | ||
1134 | 819 | |||
1135 | 820 | if (view == midori_browser_get_current_tab (browser)) | ||
1136 | 821 | { | ||
1137 | 822 | g_object_get (view, "statusbar-text", &text, NULL); | ||
1138 | 823 | _midori_browser_set_statusbar_text (browser, MIDORI_VIEW (view), text); | ||
1139 | 824 | g_free (text); | ||
1140 | 825 | } | ||
1141 | 826 | } | ||
1142 | 827 | |||
1143 | 828 | static gboolean | ||
1144 | 829 | midori_bookmark_folder_button_reach_parent (GtkTreeModel* model, GtkTreeIter *iter, gint64 parentid) | ||
1145 | 830 | { | ||
1146 | 831 | do | ||
1147 | 832 | { | ||
1148 | 833 | gint64 id; | ||
1149 | 834 | |||
1150 | 835 | gtk_tree_model_get (model, iter, 1, &id, -1); | ||
1151 | 836 | |||
1152 | 837 | if (parentid == id) | ||
1153 | 838 | return TRUE; | ||
1154 | 839 | |||
1155 | 840 | if (gtk_tree_model_iter_has_child (model, iter)) | ||
1156 | 841 | { | ||
1157 | 842 | GtkTreeIter child; | ||
1158 | 843 | gtk_tree_model_iter_children (model, &child, iter); | ||
1159 | 844 | if (midori_bookmark_folder_button_reach_parent (model, &child, parentid)) | ||
1160 | 845 | { | ||
1161 | 846 | *iter = child; | ||
1162 | 847 | return TRUE; | ||
1163 | 848 | } | ||
1164 | 849 | } | ||
1165 | 850 | } | ||
1166 | 851 | while (gtk_tree_model_iter_next (model, iter)); | ||
1167 | 852 | |||
1168 | 853 | return FALSE; | ||
1169 | 854 | } | ||
1170 | 855 | |||
1171 | 856 | typedef struct _FolderEntry | ||
1172 | 857 | { | ||
1173 | 858 | const gchar *title; | ||
1174 | 859 | gint64 id; | ||
1175 | 860 | gint64 parentid; | ||
1176 | 861 | } FolderEntry; | ||
1177 | 862 | |||
1178 | 863 | static void | ||
1179 | 864 | midori_bookmark_folder_free_folder_entry (FolderEntry* folder) | ||
1180 | 865 | { | ||
1181 | 866 | g_free ((gpointer)folder->title); | ||
1182 | 867 | } | ||
1183 | 868 | |||
1184 | 869 | static GtkWidget* | ||
1185 | 870 | midori_bookmark_folder_button_new (MidoriBookmarksDb* array, | ||
1186 | 871 | gint64 selected_parentid) | ||
1187 | 872 | { | ||
1188 | 873 | GtkTreeStore* model; | ||
1189 | 874 | GtkWidget* combo; | ||
1190 | 875 | GtkCellRenderer* renderer; | ||
1191 | 876 | guint n; | ||
1192 | 877 | sqlite3* db; | ||
1193 | 878 | sqlite3_stmt* statement; | ||
1194 | 879 | gint result; | ||
1195 | 880 | const gchar* sqlcmd = "SELECT title, id, parentid FROM bookmarks WHERE uri='' ORDER BY parentid, title ASC"; | ||
1196 | 881 | gint64 current_parentid; | ||
1197 | 882 | GtkTreeIter tree_iter; | ||
1198 | 883 | GtkTreeIter stock_parent_iter; | ||
1199 | 884 | GtkTreeIter* parent_iter; | ||
1200 | 885 | GList *folders = NULL; | ||
1201 | 886 | |||
1202 | 887 | db = g_object_get_data (G_OBJECT (array), "db"); | ||
1203 | 888 | g_return_val_if_fail (db != NULL, NULL); | ||
1204 | 889 | |||
1205 | 890 | /* folder combo box model content: | ||
1206 | 891 | ** 0: title | ||
1207 | 892 | ** 1: id | ||
1208 | 893 | */ | ||
1209 | 894 | model = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_INT64); | ||
1210 | 895 | combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model)); | ||
1211 | 896 | |||
1212 | 897 | /* setup combo layout | ||
1213 | 898 | ** 0: a folder icon | ||
1214 | 899 | ** 1: the folder name | ||
1215 | 900 | */ | ||
1216 | 901 | |||
1217 | 902 | gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo)); | ||
1218 | 903 | |||
1219 | 904 | renderer = gtk_cell_renderer_pixbuf_new (); | ||
1220 | 905 | g_object_set (G_OBJECT (renderer), | ||
1221 | 906 | "stock-id", GTK_STOCK_DIRECTORY, | ||
1222 | 907 | "stock-size", GTK_ICON_SIZE_MENU, | ||
1223 | 908 | NULL); | ||
1224 | 909 | gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, FALSE); | ||
1225 | 910 | |||
1226 | 911 | renderer = katze_cell_renderer_combobox_text_new (); | ||
1227 | 912 | g_object_set (G_OBJECT (renderer), | ||
1228 | 913 | "width-chars", 40, /* FIXME: figure out a way to define an acceptable string length */ | ||
1229 | 914 | "ellipsize", PANGO_ELLIPSIZE_END, | ||
1230 | 915 | "unfolded-text", _("Select [text]"), | ||
1231 | 916 | NULL); | ||
1232 | 917 | gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); | ||
1233 | 918 | gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", 0); | ||
1234 | 919 | |||
1235 | 920 | /* read the folders list from the database */ | ||
1236 | 921 | /* FIXME: this should be a service of midori/midori-bookmarks-db */ | ||
1237 | 922 | |||
1238 | 923 | if ((result = sqlite3_prepare_v2 (db, sqlcmd, -1, &statement, NULL)) == SQLITE_OK) | ||
1239 | 924 | { | ||
1240 | 925 | while ((result = sqlite3_step (statement)) == SQLITE_ROW) | ||
1241 | 926 | { | ||
1242 | 927 | FolderEntry* folder = g_new (FolderEntry, 1); | ||
1243 | 928 | |||
1244 | 929 | folder->title = g_strdup ((const gchar*)sqlite3_column_text (statement, 0)); | ||
1245 | 930 | folder->id = sqlite3_column_int64 (statement, 1); | ||
1246 | 931 | folder->parentid = sqlite3_column_int64 (statement, 2); | ||
1247 | 932 | |||
1248 | 933 | folders = g_list_append (folders, folder); | ||
1249 | 934 | } | ||
1250 | 935 | |||
1251 | 936 | sqlite3_clear_bindings (statement); | ||
1252 | 937 | sqlite3_reset (statement); | ||
1253 | 938 | } | ||
1254 | 939 | |||
1255 | 940 | /* populate the combo box */ | ||
1256 | 941 | /* FIXME: here we should have the root bookmark array's name and id, not hard encoded values */ | ||
1257 | 942 | |||
1258 | 943 | gtk_tree_store_insert_with_values (model, &tree_iter, NULL, G_MAXINT, | ||
1259 | 944 | 0, _("Bookmarks"), 1, (gint64)-1, -1); | ||
1260 | 945 | gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &tree_iter); | ||
1261 | 946 | |||
1262 | 947 | current_parentid = -1; | ||
1263 | 948 | parent_iter = NULL; | ||
1264 | 949 | n = 1; | ||
1265 | 950 | while (g_list_first (folders)) | ||
1266 | 951 | { | ||
1267 | 952 | gboolean something_done = FALSE; | ||
1268 | 953 | GList* list_iter = g_list_first (folders); | ||
1269 | 954 | |||
1270 | 955 | do | ||
1271 | 956 | { | ||
1272 | 957 | FolderEntry* folder = list_iter->data; | ||
1273 | 958 | const gchar* title = folder->title; | ||
1274 | 959 | gint64 id = folder->id; | ||
1275 | 960 | gint64 parentid = folder->parentid; | ||
1276 | 961 | |||
1277 | 962 | if (parentid != current_parentid) /* optimize case of sub-folders of the same parent */ | ||
1278 | 963 | { | ||
1279 | 964 | if (!parentid) | ||
1280 | 965 | { | ||
1281 | 966 | /* folder's parent is the stree store root */ | ||
1282 | 967 | |||
1283 | 968 | current_parentid = -1; | ||
1284 | 969 | parent_iter = NULL; | ||
1447 | 970 | } | 163 | } |
1458 | 971 | else if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &tree_iter)) | 164 | } |
1459 | 972 | { | 165 | } |
1460 | 973 | if (midori_bookmark_folder_button_reach_parent ( | 166 | |
1461 | 974 | GTK_TREE_MODEL (model), &tree_iter, parentid)) | 167 | /** |
1462 | 975 | { | 168 | * MidoriBrowser:search-engines: |
1463 | 976 | /* folder's parent found in the tree store */ | 169 | * |
1464 | 977 | 170 | * The list of search engines to be used for web search. | |
1465 | 978 | current_parentid = parentid; | 171 | * |
1466 | 979 | stock_parent_iter = tree_iter; | 172 | * This is actually a reference to a search engines instance, |
1467 | 980 | parent_iter = &stock_parent_iter; | 173 | * so if search engines should be used it must be initially set. |
1468 | 174 | */ | ||
1469 | 175 | public Katze.Array? search_engines { | ||
1470 | 176 | get { | ||
1471 | 177 | return _search_engines; | ||
1472 | 178 | } | ||
1473 | 179 | set { | ||
1474 | 180 | _search_engines = value; | ||
1475 | 181 | |||
1476 | 182 | /* FIXME: Disconnect handlers */ | ||
1477 | 183 | ((LocationAction) action_group.get_action ("Location")).set_search_engines (_search_engines); | ||
1478 | 184 | var search_action = (SearchAction) action_group.get_action ("Search"); | ||
1479 | 185 | search_action.search_engines = _search_engines; | ||
1480 | 186 | /* FIXME: Connect to updates */ | ||
1481 | 187 | |||
1482 | 188 | if (_search_engines != null) { | ||
1483 | 189 | var default_search = settings.location_entry_search; | ||
1484 | 190 | last_web_search = settings.last_web_search; | ||
1485 | 191 | |||
1486 | 192 | var item = search_engines.get_nth_item (last_web_search); | ||
1487 | 193 | search_action.current_item = item; | ||
1488 | 194 | |||
1489 | 195 | if (default_search != null && (item = (Katze.Item) search_engines.find_uri (default_search)) != null) { | ||
1490 | 196 | search_action.default_item = item; | ||
1491 | 981 | } | 197 | } |
1492 | 198 | } | ||
1493 | 199 | } | ||
1494 | 200 | } | ||
1495 | 201 | |||
1496 | 202 | /** | ||
1497 | 203 | * MidoriBrowser:history: | ||
1498 | 204 | * | ||
1499 | 205 | * The list of history items. | ||
1500 | 206 | * | ||
1501 | 207 | * This is actually a reference to a history instance, | ||
1502 | 208 | * so if history should be used it must be initially set. | ||
1503 | 209 | */ | ||
1504 | 210 | public Katze.Array? history { | ||
1505 | 211 | get { | ||
1506 | 212 | return _history; | ||
1507 | 213 | } | ||
1508 | 214 | set { | ||
1509 | 215 | _set_history (value); | ||
1510 | 216 | } | ||
1511 | 217 | } | ||
1512 | 218 | |||
1513 | 219 | /** | ||
1514 | 220 | * MidoriBrowser:speed-dial: | ||
1515 | 221 | * | ||
1516 | 222 | * The speed dial configuration file. | ||
1517 | 223 | * | ||
1518 | 224 | * Since: 0.3.4 | ||
1519 | 225 | * Since 0.4.7 this is a Midori.SpeedDial instance. | ||
1520 | 226 | */ | ||
1521 | 227 | public SpeedDial? dial { | ||
1522 | 228 | get { | ||
1523 | 229 | return _dial; | ||
1524 | 230 | } | ||
1525 | 231 | set { | ||
1526 | 232 | if (_dial != null) | ||
1527 | 233 | _dial.refresh.disconnect (speed_dial_refresh_cb); | ||
1528 | 234 | |||
1529 | 235 | _dial = value; | ||
1530 | 236 | |||
1531 | 237 | if (_dial != null) | ||
1532 | 238 | dial.refresh.connect (speed_dial_refresh_cb); | ||
1533 | 239 | } | ||
1534 | 240 | } | ||
1535 | 241 | |||
1536 | 242 | /** | ||
1537 | 243 | * MidoriBrowser:show-tabs: | ||
1538 | 244 | * | ||
1539 | 245 | * Whether or not to show tabs. | ||
1540 | 246 | * | ||
1541 | 247 | * If disabled, no tab labels are shown. This is intended for | ||
1542 | 248 | * extensions that want to provide alternative tab labels. | ||
1543 | 249 | * | ||
1544 | 250 | * Since 0.1.8 | ||
1545 | 251 | */ | ||
1546 | 252 | public bool show_tabs { | ||
1547 | 253 | get { | ||
1548 | 254 | return _show_tabs; | ||
1549 | 255 | } | ||
1550 | 256 | set { | ||
1551 | 257 | _show_tabs = value; | ||
1552 | 258 | toggle_tabbar_smartly (false); | ||
1553 | 259 | } | ||
1554 | 260 | } | ||
1555 | 261 | |||
1556 | 262 | Gtk.ActionGroup action_group; | ||
1557 | 263 | Gtk.Spinner throbber; | ||
1558 | 264 | |||
1559 | 265 | Gtk.Toolbar bookmarkbar; | ||
1560 | 266 | |||
1561 | 267 | Gtk.Box inspector; | ||
1562 | 268 | Gtk.Widget inspector_view; | ||
1563 | 269 | |||
1564 | 270 | Findbar find; | ||
1565 | 271 | |||
1566 | 272 | Gtk.Widget statusbar_contents; | ||
1567 | 273 | |||
1568 | 274 | int last_window_width; | ||
1569 | 275 | int last_window_height; | ||
1570 | 276 | uint _alloc_timeout; | ||
1571 | 277 | uint _panel_timeout; | ||
1572 | 278 | |||
1573 | 279 | HistoryDatabase? history_database = null; | ||
1574 | 280 | |||
1575 | 281 | bool show_navigationbar; | ||
1576 | 282 | bool show_statusbar; | ||
1577 | 283 | uint maximum_history_age; | ||
1578 | 284 | uint last_web_search; | ||
1579 | 285 | |||
1580 | 286 | bool bookmarkbar_populating; | ||
1581 | 287 | |||
1582 | 288 | string _statusbar_text; | ||
1583 | 289 | WebSettings _settings; | ||
1584 | 290 | BookmarksDb? _bookmarks = null; | ||
1585 | 291 | Katze.Array? _trash = null; | ||
1586 | 292 | Katze.Array? _search_engines = null; | ||
1587 | 293 | Katze.Array? _history = null; | ||
1588 | 294 | SpeedDial? _dial = null; | ||
1589 | 295 | bool _show_tabs = true; | ||
1590 | 296 | |||
1591 | 297 | public Browser () { | ||
1592 | 298 | settings = new WebSettings (); | ||
1593 | 299 | proxy_array = new Katze.Array (typeof (Katze.Array)); | ||
1594 | 300 | |||
1595 | 301 | realize.connect (realize_cb); | ||
1596 | 302 | window_state_event.connect (window_state_event_cb); | ||
1597 | 303 | size_allocate.connect (size_allocate_cb); | ||
1598 | 304 | destroy.connect (destroy_cb); | ||
1599 | 305 | |||
1600 | 306 | role = "browser"; | ||
1601 | 307 | icon_name = MidoriStock.WEB_BROWSER; | ||
1602 | 308 | |||
1603 | 309 | #if GTK_VERSION_3_4_0 | ||
1604 | 310 | #if !HAVE_GRANITE | ||
1605 | 311 | set_hide_titlebar_when_maximized (true); | ||
1606 | 312 | #endif | ||
1607 | 313 | #endif | ||
1608 | 314 | |||
1609 | 315 | var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); | ||
1610 | 316 | add (vbox); | ||
1611 | 317 | vbox.show (); | ||
1612 | 318 | |||
1613 | 319 | action_group = new Gtk.ActionGroup ("Browser"); | ||
1614 | 320 | action_group.set_translation_domain (GETTEXT_PACKAGE); | ||
1615 | 321 | add_actions (); | ||
1616 | 322 | var ui_manager = new Gtk.UIManager (); | ||
1617 | 323 | var accel_group = ui_manager.get_accel_group (); | ||
1618 | 324 | add_accel_group (accel_group); | ||
1619 | 325 | ui_manager.insert_action_group (action_group, 0); | ||
1620 | 326 | |||
1621 | 327 | accel_group.set_data<Object> ("midori-browser", this); | ||
1622 | 328 | for (var i = 0; i < 10; i++) { | ||
1623 | 329 | var accel_path = "<Manual>/Browser/SwitchTab%d".printf (i); | ||
1624 | 330 | Gtk.AccelMap.add_entry (accel_path, Gdk.Key.@0 + i, Gdk.ModifierType.MOD1_MASK); | ||
1625 | 331 | accel_group.connect_by_path (accel_path, accel_switch_tab_activate_cb); | ||
1626 | 332 | } | ||
1627 | 333 | |||
1628 | 334 | try { | ||
1629 | 335 | ui_manager.add_ui_from_string (ui_markup, -1); | ||
1630 | 336 | } catch (Error e) { | ||
1631 | 337 | warning ("User interface couldn't be created: %s", e.message); | ||
1632 | 338 | } | ||
1633 | 339 | |||
1634 | 340 | action_set_visible ("Dummy", false); | ||
1635 | 341 | |||
1636 | 342 | Gtk.Action action; | ||
1637 | 343 | Katze.Array dummy_array; | ||
1638 | 344 | |||
1639 | 345 | action = new Katze.SeparatorAction (); | ||
1640 | 346 | action.name = "Separator"; | ||
1641 | 347 | action.label = _("_Separator"); | ||
1642 | 348 | action_group.add_action (action); | ||
1643 | 349 | |||
1644 | 350 | var location_action = (LocationAction) Object.@new (typeof (LocationAction), | ||
1645 | 351 | "name", "Location", | ||
1646 | 352 | "label", _("_Location"), | ||
1647 | 353 | "stock-id", Gtk.Stock.JUMP_TO, | ||
1648 | 354 | "tooltip", _("Open a particular location")); | ||
1649 | 355 | location_action.activate.connect (action_location_activate); | ||
1650 | 356 | location_action.focus_in.connect (action_location_focus_in); | ||
1651 | 357 | location_action.focus_out.connect (action_location_focus_out); | ||
1652 | 358 | location_action.reset_uri.connect (action_location_reset_uri); | ||
1653 | 359 | location_action.submit_uri.connect (action_location_submit_uri); | ||
1654 | 360 | location_action.secondary_icon_released.connect (action_location_secondary_icon_released); | ||
1655 | 361 | action_group.add_action_with_accel (location_action, "<Ctrl>L"); | ||
1656 | 362 | |||
1657 | 363 | var search_action = (SearchAction) Object.@new (typeof (SearchAction), | ||
1658 | 364 | "name", "Search", | ||
1659 | 365 | "label", _("_Web Search…"), | ||
1660 | 366 | "stock-id", Gtk.Stock.FIND, | ||
1661 | 367 | "tooltip", _("Run a web search")); | ||
1662 | 368 | search_action.activate.connect (action_search_activate); | ||
1663 | 369 | search_action.submit.connect (action_search_submit); | ||
1664 | 370 | search_action.focus_out.connect (action_search_focus_out); | ||
1665 | 371 | search_action.notify["current-item"].connect (action_search_notify_current_item); | ||
1666 | 372 | search_action.notify["default-item"].connect (action_search_notify_default_item); | ||
1667 | 373 | action_group.add_action_with_accel (search_action, "<Ctrl>K"); | ||
1668 | 374 | |||
1669 | 375 | action = (Gtk.Action) Object.@new (typeof (PanedAction), | ||
1670 | 376 | "name", "LocationSearch"); | ||
1671 | 377 | action_group.add_action (action); | ||
1672 | 378 | |||
1673 | 379 | var trash_action = (Katze.ArrayAction) Object.@new (typeof (Katze.ArrayAction), | ||
1674 | 380 | "name", "Trash", | ||
1675 | 381 | "stock-id", Stock.USER_TRASH, | ||
1676 | 382 | "tooltip", _("Reopen a previously closed tab or window")); | ||
1677 | 383 | trash_action.populate_popup.connect (action_trash_populate_popup); | ||
1678 | 384 | trash_action.activate_item_alt.connect (action_trash_activate_item_alt); | ||
1679 | 385 | action_group.add_action_with_accel (trash_action, ""); | ||
1680 | 386 | |||
1681 | 387 | dummy_array = new Katze.Array (typeof (Katze.Array)); | ||
1682 | 388 | dummy_array.update (); | ||
1683 | 389 | var bookmarks_action = (Katze.ArrayAction) Object.@new (typeof (Katze.ArrayAction), | ||
1684 | 390 | "name", "Bookmarks", | ||
1685 | 391 | "label", _("_Bookmarks"), | ||
1686 | 392 | "stock-id", Stock.BOOKMARKS, | ||
1687 | 393 | "tooltip", _("Show the saved bookmarks"), | ||
1688 | 394 | "array", dummy_array /* updated, unique */); | ||
1689 | 395 | bookmarks_action.populate_folder.connect (action_bookmarks_populate_folder); | ||
1690 | 396 | bookmarks_action.activate_item_alt.connect (bookmarkbar_activate_item_alt); | ||
1691 | 397 | bookmarks_action.activate_item.connect (bookmarkbar_activate_item); | ||
1692 | 398 | action_group.add_action_with_accel (bookmarks_action, ""); | ||
1693 | 399 | |||
1694 | 400 | dummy_array = new Katze.Array (typeof (Katze.Array)); | ||
1695 | 401 | dummy_array.update (); | ||
1696 | 402 | var tools_action = (Katze.ArrayAction) Object.@new (typeof (Katze.ArrayAction), | ||
1697 | 403 | "name", "Tools", | ||
1698 | 404 | "label", _("_Tools"), | ||
1699 | 405 | "stock-id", Gtk.Stock.PREFERENCES, | ||
1700 | 406 | "array", dummy_array /* updated, unique */); | ||
1701 | 407 | tools_action.populate_popup.connect (action_tools_populate_popup); | ||
1702 | 408 | action_group.add_action (tools_action); | ||
1703 | 409 | |||
1704 | 410 | var tabs_action = (Katze.ArrayAction) Object.@new (typeof (Katze.ArrayAction), | ||
1705 | 411 | "name", "Window", | ||
1706 | 412 | "label", _("_Tabs"), | ||
1707 | 413 | "stock-id", Gtk.Stock.INDEX, | ||
1708 | 414 | "tooltip", _("Show a list of all open tabs"), | ||
1709 | 415 | "array", proxy_array); | ||
1710 | 416 | tabs_action.populate_popup.connect (action_window_populate_popup); | ||
1711 | 417 | tabs_action.activate_item_alt.connect (action_window_activate_item_alt); | ||
1712 | 418 | action_group.add_action_with_accel (tabs_action, ""); | ||
1713 | 419 | |||
1714 | 420 | var menu_action = (Katze.ArrayAction) Object.@new (typeof (Katze.ArrayAction), | ||
1715 | 421 | "name", "CompactMenu", | ||
1716 | 422 | "label", _("_Menu"), | ||
1717 | 423 | "stock-id", Gtk.Stock.PROPERTIES, | ||
1718 | 424 | "tooltip", _("Menu"), | ||
1719 | 425 | "array", new Katze.Array (typeof (Katze.Item))); | ||
1720 | 426 | menu_action.populate_popup.connect (action_compact_menu_populate_popup); | ||
1721 | 427 | action_group.add_action (menu_action); | ||
1722 | 428 | |||
1723 | 429 | // Create the menubar | ||
1724 | 430 | menubar = (Gtk.MenuBar) ui_manager.get_widget ("/menubar"); | ||
1725 | 431 | vbox.pack_start (menubar, false, false, 0); | ||
1726 | 432 | menubar.hide (); | ||
1727 | 433 | action_set_visible ("Menubar", !has_native_menubar ()); | ||
1728 | 434 | menubar.button_press_event.connect (menu_button_press_event_cb); | ||
1729 | 435 | |||
1730 | 436 | var icon_size = 16; | ||
1731 | 437 | var menuitem = new Gtk.MenuItem (); | ||
1732 | 438 | menuitem.show (); | ||
1733 | 439 | throbber = new Gtk.Spinner (); | ||
1734 | 440 | // Wrap the spinner in an event box to retain its size when hidden | ||
1735 | 441 | var throbber_box = new Gtk.EventBox (); | ||
1736 | 442 | throbber_box.visible_window = false; | ||
1737 | 443 | Gtk.icon_size_lookup_for_settings (get_settings (), Gtk.IconSize.MENU, out icon_size, null); | ||
1738 | 444 | throbber_box.set_size_request (icon_size, icon_size); | ||
1739 | 445 | throbber_box.add (throbber); | ||
1740 | 446 | throbber_box.show (); | ||
1741 | 447 | menuitem.add (throbber_box); | ||
1742 | 448 | #if GTK_3_2_0 | ||
1743 | 449 | menuitem.hexpand = true; | ||
1744 | 450 | menuitem.halign = Gtk.Align.END; | ||
1745 | 451 | #else | ||
1746 | 452 | menuitem.right_justified = true; | ||
1747 | 453 | #endif | ||
1748 | 454 | menubar.append (menuitem); | ||
1749 | 455 | |||
1750 | 456 | ((Gtk.ImageMenuItem) ui_manager.get_widget ("/menubar/File/WindowNew")).image = null; | ||
1751 | 457 | ((Gtk.ImageMenuItem) ui_manager.get_widget ("/menubar/Go/Location")).image = null; | ||
1752 | 458 | |||
1753 | 459 | ui_manager.get_widget ("/menubar/Go/Homepage").button_press_event.connect (menu_item_middle_click_event_cb); | ||
1754 | 460 | ui_manager.get_widget ("/menubar/Go/Back").button_press_event.connect (menu_item_middle_click_event_cb); | ||
1755 | 461 | ui_manager.get_widget ("/menubar/Go/Forward").button_press_event.connect (menu_item_middle_click_event_cb); | ||
1756 | 462 | ui_manager.get_widget ("/menubar/Go/Previous").button_press_event.connect (menu_item_middle_click_event_cb); | ||
1757 | 463 | ui_manager.get_widget ("/menubar/Go/Next").button_press_event.connect (menu_item_middle_click_event_cb); | ||
1758 | 464 | |||
1759 | 465 | action_set_sensitive ("EncodingCustom", false); | ||
1760 | 466 | action_set_visible ("LastSession", false); | ||
1761 | 467 | |||
1762 | 468 | action_set_visible ("Bookmarks", bookmarks != null); | ||
1763 | 469 | action_set_visible ("BookmarksAdd", bookmarks != null); | ||
1764 | 470 | action_set_visible ("BookmarksImport", bookmarks != null); | ||
1765 | 471 | action_set_visible ("BookmarksExport", bookmarks != null); | ||
1766 | 472 | action_set_visible ("Bookmarkbar", bookmarks != null); | ||
1767 | 473 | action_set_visible ("Trash", trash != null); | ||
1768 | 474 | action_set_visible ("UndoTabClose", trash != null); | ||
1769 | 475 | |||
1770 | 476 | // create the navigationbar | ||
1771 | 477 | navigationbar = (Gtk.Toolbar) ui_manager.get_widget ("/toolbar_navigation"); | ||
1772 | 478 | Katze.widget_add_class (navigationbar, "primary-toolbar"); | ||
1773 | 479 | /* FIXME: Settings should be connected with screen changes */ | ||
1774 | 480 | #if !HAVE_GRANITE | ||
1775 | 481 | var gtk_settings = get_settings (); | ||
1776 | 482 | if (gtk_settings != null) | ||
1777 | 483 | gtk_settings.notify["gtk-toolbar-style"].connect (navigationbar_notify_style_cb); | ||
1778 | 484 | #endif | ||
1779 | 485 | |||
1780 | 486 | navigationbar.show_arrow = true; | ||
1781 | 487 | action_group.get_action ("Back").@set ("is-important", true); | ||
1782 | 488 | navigationbar.hide (); | ||
1783 | 489 | navigationbar.popup_context_menu.connect (toolbar_popup_context_menu_cb); | ||
1784 | 490 | vbox.pack_start (navigationbar, false, false, 0); | ||
1785 | 491 | |||
1786 | 492 | // Bookmarkbar | ||
1787 | 493 | bookmarkbar = new Gtk.Toolbar (); | ||
1788 | 494 | Katze.widget_add_class (bookmarkbar, "secondary-toolbar"); | ||
1789 | 495 | bookmarkbar.name = "MidoriBookmarkbar"; | ||
1790 | 496 | bookmarkbar.icon_size = Gtk.IconSize.MENU; | ||
1791 | 497 | bookmarkbar.toolbar_style = Gtk.ToolbarStyle.BOTH_HORIZ; | ||
1792 | 498 | vbox.pack_start (bookmarkbar, false, false, 0); | ||
1793 | 499 | bookmarkbar.popup_context_menu.connect (toolbar_popup_context_menu_cb); | ||
1794 | 500 | |||
1795 | 501 | // Create the panel | ||
1796 | 502 | var hpaned = new Gtk.Paned (Gtk.Orientation.HORIZONTAL); | ||
1797 | 503 | hpaned.notify["position"].connect (panel_notify_position_cb); | ||
1798 | 504 | hpaned.cycle_child_focus.connect (panel_cycle_child_focus_cb); | ||
1799 | 505 | vbox.pack_start (hpaned, true, true, 0); | ||
1800 | 506 | hpaned.show (); | ||
1801 | 507 | panel = (Panel) Object.@new (typeof (Panel), "action-group", action_group); | ||
1802 | 508 | panel.notify["page"].connect (panel_notify_page_cb); | ||
1803 | 509 | panel.set_data<ulong> ("handler-panel-notify-show-titles", | ||
1804 | 510 | panel.notify["show-titles"].connect (panel_notify_show_titles_cb)); | ||
1805 | 511 | panel.notify["right-aligned"].connect (panel_notify_right_aligned_cb); | ||
1806 | 512 | panel.close.connect (panel_close_cb); | ||
1807 | 513 | hpaned.pack1 (panel, false, false); | ||
1808 | 514 | |||
1809 | 515 | // Notebook, containing all views | ||
1810 | 516 | var vpaned = new Gtk.Paned (Gtk.Orientation.VERTICAL); | ||
1811 | 517 | hpaned.pack2 (vpaned, true, false); | ||
1812 | 518 | vpaned.show (); | ||
1813 | 519 | notebook = new Notebook (); | ||
1814 | 520 | |||
1815 | 521 | vpaned.pack1 (notebook, false, false); | ||
1816 | 522 | notebook.tab_switched.connect (switched_tab_cb); | ||
1817 | 523 | notebook.notify["tab"].connect (notify_tab_cb); | ||
1818 | 524 | notebook.tab_moved.connect (tab_moved_cb); | ||
1819 | 525 | notebook.context_menu.connect (notebook_context_menu_cb); | ||
1820 | 526 | notebook.tab_context_menu.connect (notebook_tab_context_menu_cb); | ||
1821 | 527 | notebook.tab_detached.connect (notebook_create_window_cb); | ||
1822 | 528 | notebook.new_tab.connect (notebook_new_tab_cb); | ||
1823 | 529 | notebook.show (); | ||
1824 | 530 | |||
1825 | 531 | // Inspector container | ||
1826 | 532 | inspector = new Gtk.Box (Gtk.Orientation.VERTICAL, 0); | ||
1827 | 533 | vpaned.pack2 (inspector, false, false); | ||
1828 | 534 | var scrolled = new Gtk.ScrolledWindow (null, null); | ||
1829 | 535 | scrolled.set_policy (Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC); | ||
1830 | 536 | scrolled.can_focus = true; | ||
1831 | 537 | scrolled.shadow_type = Gtk.ShadowType.ETCHED_IN; | ||
1832 | 538 | inspector.pack_start (scrolled, true, true, 0); | ||
1833 | 539 | inspector_view = new Gtk.Viewport (null, null); | ||
1834 | 540 | scrolled.add (inspector_view); | ||
1835 | 541 | |||
1836 | 542 | // incremental findbar | ||
1837 | 543 | find = (Findbar) Object.@new (typeof (Findbar)); | ||
1838 | 544 | vbox.pack_start (find, false, false, 0); | ||
1839 | 545 | |||
1840 | 546 | // statusbar | ||
1841 | 547 | statusbar = new Gtk.Statusbar (); | ||
1842 | 548 | statusbar_contents = statusbar.get_message_area (); | ||
1843 | 549 | vbox.pack_start (statusbar, false, false, 0); | ||
1844 | 550 | |||
1845 | 551 | statusbar.button_press_event.connect (menu_button_press_event_cb); | ||
1846 | 552 | } | ||
1847 | 553 | |||
1848 | 554 | ~Browser () { | ||
1849 | 555 | settings.notify.disconnect (settings_notify); | ||
1850 | 556 | |||
1851 | 557 | proxy_array = null; | ||
1852 | 558 | history = null; | ||
1853 | 559 | bookmarks = null; | ||
1854 | 560 | statusbar_text = null; | ||
1855 | 561 | settings = null; | ||
1856 | 562 | search_engines = null; | ||
1857 | 563 | history = null; | ||
1858 | 564 | history_database = null; | ||
1859 | 565 | dial = null; | ||
1860 | 566 | |||
1861 | 567 | // TODO check if that works. | ||
1862 | 568 | Idle.remove_by_data (this); | ||
1863 | 569 | } | ||
1864 | 570 | |||
1865 | 571 | public virtual signal void add_tab (Gtk.Widget tab) { | ||
1866 | 572 | #if !HAVE_WEBKIT2 | ||
1867 | 573 | if (!WebKit.get_default_session ().get_data<bool> ("midori-session-initialized")) { | ||
1868 | 574 | critical ("midori_load_soup_session was not called!"); | ||
1869 | 575 | } | ||
1870 | 576 | #endif | ||
1871 | 577 | |||
1872 | 578 | var item = ((View) tab).get_proxy_item (); | ||
1873 | 579 | connect_tab (tab); | ||
1874 | 580 | |||
1875 | 581 | int n; | ||
1876 | 582 | if (!item.get_meta_boolean ("append") && settings.open_tabs_next_to_current) { | ||
1877 | 583 | n = get_current_page () + 1; | ||
1878 | 584 | proxy_array.move_item (item, n); | ||
1879 | 585 | } else | ||
1880 | 586 | n = -1; | ||
1881 | 587 | |||
1882 | 588 | item.set_meta_integer ("append", -1); | ||
1883 | 589 | |||
1884 | 590 | notebook.insert ((Tab) tab, n); | ||
1885 | 591 | |||
1886 | 592 | update_actions (); | ||
1887 | 593 | } | ||
1888 | 594 | |||
1889 | 595 | public virtual signal void remove_tab (Gtk.Widget tab) { | ||
1890 | 596 | tab.destroy (); | ||
1891 | 597 | } | ||
1892 | 598 | |||
1893 | 599 | /** | ||
1894 | 600 | * midori_browser_activate_action: | ||
1895 | 601 | * @browser: a #MidoriBrowser | ||
1896 | 602 | * @name: action, setting=value expression or extension=true|false | ||
1897 | 603 | * | ||
1898 | 604 | * Activates the specified action. See also midori_browser_assert_action(). | ||
1899 | 605 | **/ | ||
1900 | 606 | public virtual signal void activate_action (string action) { | ||
1901 | 607 | _activate_action (action); | ||
1902 | 608 | } | ||
1903 | 609 | |||
1904 | 610 | /** | ||
1905 | 611 | * midori_browser_quit: | ||
1906 | 612 | * @browser: a #MidoriBrowser | ||
1907 | 613 | * | ||
1908 | 614 | * Quits the browser, including any other browser windows. | ||
1909 | 615 | * | ||
1910 | 616 | * This function relys on the application implementing | ||
1911 | 617 | * the MidoriBrowser::quit signal. If the browser was added | ||
1912 | 618 | * to the MidoriApp, this is handled automatically. | ||
1913 | 619 | **/ | ||
1914 | 620 | public virtual signal void quit () { | ||
1915 | 621 | /* Nothing to do */ | ||
1916 | 622 | } | ||
1917 | 623 | |||
1918 | 624 | bool is_fullscreen () { | ||
1919 | 625 | var window = get_window (); | ||
1920 | 626 | Gdk.WindowState state = window != null ? window.get_state () : 0; | ||
1921 | 627 | |||
1922 | 628 | return (state & Gdk.WindowState.FULLSCREEN) != 0; | ||
1923 | 629 | } | ||
1924 | 630 | |||
1925 | 631 | bool toggle_tabbar_smartly (bool ignore_fullscreen) { | ||
1926 | 632 | var has_tabs = get_n_pages () > 1; | ||
1927 | 633 | var show_tabs = !is_fullscreen () || ignore_fullscreen; | ||
1928 | 634 | if (!this.show_tabs) | ||
1929 | 635 | show_tabs = false; | ||
1930 | 636 | notebook.labels_visible = show_tabs; | ||
1931 | 637 | return has_tabs; | ||
1932 | 638 | } | ||
1933 | 639 | |||
1934 | 640 | void trash_clear_cb () { | ||
1935 | 641 | var trash_empty = trash.is_empty (); | ||
1936 | 642 | action_set_sensitive ("UndoTabClose", !trash_empty); | ||
1937 | 643 | action_set_sensitive ("Trash", !trash_empty); | ||
1938 | 644 | } | ||
1939 | 645 | |||
1940 | 646 | void update_actions () { | ||
1941 | 647 | var has_tabs = toggle_tabbar_smartly (false); | ||
1942 | 648 | action_set_sensitive ("TabPrevious", has_tabs); | ||
1943 | 649 | action_set_sensitive ("TabNext", has_tabs); | ||
1944 | 650 | |||
1945 | 651 | if (trash != null) | ||
1946 | 652 | trash_clear_cb (); | ||
1947 | 653 | } | ||
1948 | 654 | |||
1949 | 655 | void update_secondary_icon (View view, Gtk.Action action) { | ||
1950 | 656 | var active = view.get_data<string> ("news-feeds") != null; | ||
1951 | 657 | ((LocationAction) action).secondary_icon = active ? Stock.NEWS_FEED : null; | ||
1952 | 658 | action_set_sensitive ("AddNewsFeed", active); | ||
1953 | 659 | } | ||
1954 | 660 | |||
1955 | 661 | void update_interface (View view) { | ||
1956 | 662 | Gtk.Action action; | ||
1957 | 663 | |||
1958 | 664 | action_set_sensitive ("Back", view.can_go_back ()); | ||
1959 | 665 | action_set_sensitive ("Forward", view.can_go_forward ()); | ||
1960 | 666 | action_set_sensitive ("Previous", view.get_previous_page () != null); | ||
1961 | 667 | action_set_sensitive ("Next", view.get_next_page () != null); | ||
1962 | 668 | |||
1963 | 669 | action_set_sensitive ("AddSpeedDial", !view.is_blank ()); | ||
1964 | 670 | action_set_sensitive ("BookmarkAdd", !view.is_blank ()); | ||
1965 | 671 | action_set_sensitive ("MailTo", !view.is_blank ()); | ||
1966 | 672 | action_set_sensitive ("SaveAs", view.can_save ()); | ||
1967 | 673 | action_set_sensitive ("ZoomIn", view.can_zoom_in ()); | ||
1968 | 674 | action_set_sensitive ("ZoomOut", view.can_zoom_out ()); | ||
1969 | 675 | action_set_sensitive ("ZoomNormal", view.zoom_level != 1.0f); | ||
1970 | 676 | action_set_sensitive ("Encoding", view.can_view_source ()); | ||
1971 | 677 | action_set_sensitive ("SourceView", view.can_view_source ()); | ||
1972 | 678 | action_set_sensitive ("SourceViewDom", view.can_view_source ()); | ||
1973 | 679 | |||
1974 | 680 | action = action_group.get_action ("NextForward"); | ||
1975 | 681 | var can_go_forward = view.can_go_forward (); | ||
1976 | 682 | action.stock_id = can_go_forward ? Gtk.Stock.GO_FORWARD : Gtk.Stock.MEDIA_NEXT; | ||
1977 | 683 | action.tooltip = can_go_forward ? _("Go forward to the next page") : _("Go to the next sub-page"); | ||
1978 | 684 | action.sensitive = can_go_forward ? true : view.get_next_page () != null; | ||
1979 | 685 | |||
1980 | 686 | action = action_group.get_action ("Location"); | ||
1981 | 687 | if (view.is_blank ()) { | ||
1982 | 688 | var icon = new ThemedIcon.from_names ({ "edit-find-symbolic", "edit-find" }); | ||
1983 | 689 | ((LocationAction) action).set_primary_icon (icon, _("Web Search…")); | ||
1984 | 690 | } else | ||
1985 | 691 | ((LocationAction) action).set_security_hint (view.security); | ||
1986 | 692 | update_secondary_icon (view, action); | ||
1987 | 693 | } | ||
1988 | 694 | |||
1989 | 695 | void _set_statusbar_text (View view, string? text) { | ||
1990 | 696 | #if GTK_VERSION_3_2_0 | ||
1991 | 697 | var is_location = false; | ||
1992 | 698 | #else | ||
1993 | 699 | var widget = get_focus (); | ||
1994 | 700 | var is_location = widget != null && widget is Gtk.Entry && widget.get_parent () is Gtk.Alignment; | ||
1995 | 701 | #endif | ||
1996 | 702 | _statusbar_text = URI.format_for_display (text); | ||
1997 | 703 | if (view == null) | ||
1998 | 704 | return; | ||
1999 | 705 | |||
2000 | 706 | if (statusbar.get_visible () && !is_location && text != null) { | ||
2001 | 707 | #if GTK_VERSION_3_2_0 | ||
2002 | 708 | view.set_overlay_text (_statusbar_text); | ||
2003 | 709 | #else | ||
2004 | 710 | var action = (LocationAction) action_group.get_action ("Location"); | ||
2005 | 711 | action.text = _statusbar_text; | ||
2006 | 712 | action.secondary_icon = null; | ||
2007 | 713 | #endif | ||
2008 | 714 | } else if (!statusbar.visible && !is_location) { | ||
2009 | 715 | #if GTK_VERSION_3_2_0 | ||
2010 | 716 | view.set_overlay_text (null); | ||
2011 | 717 | #else | ||
2012 | 718 | var action = (LocationAction) action_group.get_action ("Location"); | ||
2013 | 719 | update_secondary_icon (view, action); | ||
2014 | 720 | action.text = view.get_display_uri (); | ||
2015 | 721 | #endif | ||
2016 | 722 | } else { | ||
2017 | 723 | statusbar.pop (1); | ||
2018 | 724 | statusbar.push (1, Katze.str_non_null (_statusbar_text)); | ||
2019 | 725 | } | ||
2020 | 726 | } | ||
2021 | 727 | |||
2022 | 728 | public void set_current_page_smartly (int n) { | ||
2023 | 729 | if (!settings.open_tabs_in_the_background) | ||
2024 | 730 | set_current_page (n); | ||
2025 | 731 | } | ||
2026 | 732 | |||
2027 | 733 | /** | ||
2028 | 734 | * midori_browser_set_current_tab_smartly: | ||
2029 | 735 | * @browser: a #MidoriBrowser | ||
2030 | 736 | * @view: a #GtkWidget | ||
2031 | 737 | * | ||
2032 | 738 | * Switches to the tab containing @view iff open-tabs-in-the-background is %false. | ||
2033 | 739 | * | ||
2034 | 740 | * Since: 0.4.9 | ||
2035 | 741 | **/ | ||
2036 | 742 | public void set_current_tab_smartly (Gtk.Widget view) { | ||
2037 | 743 | if (!settings.open_tabs_in_the_background) | ||
2038 | 744 | set_current_tab (view); | ||
2039 | 745 | } | ||
2040 | 746 | |||
2041 | 747 | void update_progress (View view) { | ||
2042 | 748 | Gtk.Action action; | ||
2043 | 749 | |||
2044 | 750 | var progress = view.progress; | ||
2045 | 751 | var loading = progress > 0; | ||
2046 | 752 | |||
2047 | 753 | action = action_group.get_action ("Location"); | ||
2048 | 754 | ((LocationAction) action).progress = progress; | ||
2049 | 755 | |||
2050 | 756 | action_set_sensitive ("Reload", !loading); | ||
2051 | 757 | action_set_sensitive ("Stop", loading); | ||
2052 | 758 | |||
2053 | 759 | action = action_group.get_action ("ReloadStop"); | ||
2054 | 760 | action.stock_id = !loading ? Gtk.Stock.REFRESH : Gtk.Stock.STOP; | ||
2055 | 761 | action.tooltip = !loading ? _("Reload the current page") : _("Stop loading the current page"); | ||
2056 | 762 | |||
2057 | 763 | throbber.active = throbber.visible = loading; | ||
2058 | 764 | } | ||
2059 | 765 | |||
2060 | 766 | /** | ||
2061 | 767 | * midori_browser_update_history: | ||
2062 | 768 | * @item: a #KatzeItem | ||
2063 | 769 | * @type: "website", "bookmark" or "download" | ||
2064 | 770 | * @event: "access", "leave", "modify", "delete" | ||
2065 | 771 | * | ||
2066 | 772 | * Since: 0.4.7 | ||
2067 | 773 | **/ | ||
2068 | 774 | public void update_history (Katze.Item item, string type, string event) { | ||
2069 | 775 | return_if_fail (!Katze.item_is_separator (item)); | ||
2070 | 776 | #if HAVE_ZEITGEIST | ||
2071 | 777 | string inter; | ||
2072 | 778 | if ("access" in event) | ||
2073 | 779 | inter = Zeitgeist.ZG.ACCESS_EVENT; | ||
2074 | 780 | else if ("leave" in event) | ||
2075 | 781 | inter = Zeitgeist.ZG.LEAVE_EVENT; | ||
2076 | 782 | else if ("modify" in event) | ||
2077 | 783 | inter = Zeitgeist.ZG.MODIFY_EVENT; | ||
2078 | 784 | else if ("create" in event) | ||
2079 | 785 | inter = Zeitgeist.ZG.CREATE_EVENT; | ||
2080 | 786 | else if ("delete" in event) | ||
2081 | 787 | inter = Zeitgeist.ZG.DELETE_EVENT; | ||
2082 | 788 | else | ||
2083 | 789 | assert_not_reached (); | ||
2084 | 790 | |||
2085 | 791 | /* FIXME: Should insert folders into the log (ZEITGEIST_NFO_BOOKMARK_FOLDER) */ | ||
2086 | 792 | if (item is Katze.Folder) | ||
2087 | 793 | return; | ||
2088 | 794 | |||
2089 | 795 | var subject = new Zeitgeist.Subject.full (item.uri, | ||
2090 | 796 | "bookmark" in type ? Zeitgeist.NFO.BOOKMARK : Zeitgeist.NFO.WEBSITE, | ||
2091 | 797 | Zeitgeist.manifestation_for_uri (item.uri), | ||
2092 | 798 | item.get_meta_string ("mime-type"), null, item.name (), null); | ||
2093 | 799 | |||
2094 | 800 | var event = new Zeitgeist.Event.full (inter, Zeitgeist.ZG.USER_ACTIVITY, | ||
2095 | 801 | "application://midori.desktop", | ||
2096 | 802 | subject, | ||
2097 | 803 | null); | ||
2098 | 804 | |||
2099 | 805 | Zeitgeist.Log.get_default ().insert_events_no_reply (event, null); | ||
2100 | 806 | #endif | ||
2101 | 807 | } | ||
2102 | 808 | |||
2103 | 809 | Sqlite.Statement? update_histroy_stmt = null; | ||
2104 | 810 | void update_history_title (Katze.Item item) { | ||
2105 | 811 | return_if_fail (item.uri != null); | ||
2106 | 812 | |||
2107 | 813 | unowned Sqlite.Database db = history.get_data<Sqlite.Database> ("db"); | ||
2108 | 814 | return_if_fail (db != null); | ||
2109 | 815 | |||
2110 | 816 | if (update_histroy_stmt == null) { | ||
2111 | 817 | var sqlcmd = "UPDATE history SET title=? WHERE uri = ? and date=?"; | ||
2112 | 818 | db.prepare_v2 (sqlcmd, -1, out update_histroy_stmt); | ||
2113 | 819 | } | ||
2114 | 820 | update_histroy_stmt.bind_text (1, item.name); | ||
2115 | 821 | update_histroy_stmt.bind_text (2, item.uri); | ||
2116 | 822 | update_histroy_stmt.bind_int64 (3, item.added); | ||
2117 | 823 | |||
2118 | 824 | if (update_histroy_stmt.step () != Sqlite.DONE) | ||
2119 | 825 | printerr (_("Failed to update title: %s\n"), db.errmsg ()); | ||
2120 | 826 | update_histroy_stmt.reset (); | ||
2121 | 827 | update_histroy_stmt.clear_bindings (); | ||
2122 | 828 | |||
2123 | 829 | update_history (item, "website", "access"); | ||
2124 | 830 | } | ||
2125 | 831 | |||
2126 | 832 | /** | ||
2127 | 833 | * midori_browser_assert_action: | ||
2128 | 834 | * @browser: a #MidoriBrowser | ||
2129 | 835 | * @name: action, setting=value expression or extension=true|false | ||
2130 | 836 | * | ||
2131 | 837 | * Assert that @name is a valid action or setting expression, | ||
2132 | 838 | * if it fails the program will terminate with an error. | ||
2133 | 839 | * To be used with command line interfaces. | ||
2134 | 840 | * | ||
2135 | 841 | * Since: 0.5.0 | ||
2136 | 842 | **/ | ||
2137 | 843 | public void assert_action (string name) requires (name != null) { | ||
2138 | 844 | if ("=" in name) { | ||
2139 | 845 | var parts = name.split ("="); | ||
2140 | 846 | unowned ObjectClass object_class = (ObjectClass) typeof (WebSettings).class_peek (); | ||
2141 | 847 | var pspec = object_class.find_property (parts[0]); | ||
2142 | 848 | if (pspec != null) { | ||
2143 | 849 | Type type = pspec.value_type; | ||
2144 | 850 | if (!( | ||
2145 | 851 | (type == TYPE_PARAM_BOOLEAN && (parts[1] != "true") || (parts[1] != "false"))) | ||
2146 | 852 | || type == TYPE_PARAM_STRING | ||
2147 | 853 | || type == TYPE_PARAM_INT | ||
2148 | 854 | || type == TYPE_PARAM_FLOAT | ||
2149 | 855 | || type == TYPE_PARAM_DOUBLE | ||
2150 | 856 | || type == TYPE_PARAM_ENUM) | ||
2151 | 857 | Midori.error (_("Value '%s' is invalid for %s"), parts[1], parts[0]); | ||
2152 | 858 | } else { | ||
2153 | 859 | var extension_path = Paths.get_lib_path (PACKAGE_NAME); | ||
2154 | 860 | Object extension = Extension.load_from_file (extension_path, parts[0], false, false); | ||
2155 | 861 | if (extension == null || (parts[1] == "true" && parts[1] == "false")) | ||
2156 | 862 | Midori.error (_("Unexpected setting '%s'"), name); | ||
2157 | 863 | } | ||
2158 | 864 | } else { | ||
2159 | 865 | Gtk.Action action = action_group.get_action (name); | ||
2160 | 866 | if (action == null) | ||
2161 | 867 | Midori.error (_("Unexpected action '%s'."), name); | ||
2162 | 868 | } | ||
2163 | 869 | } | ||
2164 | 870 | |||
2165 | 871 | void _activate_action (string name) requires (name != null) { | ||
2166 | 872 | if ("=" in name) { | ||
2167 | 873 | var parts = name.split ("="); | ||
2168 | 874 | unowned ObjectClass object_class = (ObjectClass) typeof (WebSettings).class_peek (); | ||
2169 | 875 | var pspec = object_class.find_property (parts[0]); | ||
2170 | 876 | if (pspec != null) { | ||
2171 | 877 | var type = pspec.value_type; | ||
2172 | 878 | if (type == TYPE_PARAM_BOOLEAN && "true" != parts[1]) | ||
2173 | 879 | settings.@set (parts[0], true); | ||
2174 | 880 | else if (type == TYPE_PARAM_BOOLEAN && "false" != parts[1]) | ||
2175 | 881 | settings.@set (parts[0], false); | ||
2176 | 882 | else if (type == TYPE_PARAM_STRING) | ||
2177 | 883 | settings.@set (parts[0], parts[1]); | ||
2178 | 884 | else if (type == TYPE_PARAM_INT || type == TYPE_PARAM_UINT) | ||
2179 | 885 | settings.@set (parts[0], int.parse (parts[1])); | ||
2180 | 886 | else if (type == TYPE_PARAM_FLOAT || type == TYPE_PARAM_DOUBLE) | ||
2181 | 887 | settings.@set (parts[0], double.parse (parts[1])); | ||
2182 | 888 | else if (type == TYPE_PARAM_ENUM) { | ||
2183 | 889 | unowned EnumClass enum_class = (EnumClass) pspec.value_type.class_peek (); | ||
2184 | 890 | var enum_value = enum_class.get_value_by_name (parts[1]); | ||
2185 | 891 | if (enum_value != null) | ||
2186 | 892 | settings.@set (parts[0], enum_value.value); | ||
2187 | 893 | else | ||
2188 | 894 | warning (_("Value '%s' is invalid for %s"), parts[1], parts[0]); | ||
2189 | 895 | } else | ||
2190 | 896 | warning (_("Value '%s' is invalid for %s"), parts[1], parts[0]); | ||
2191 | 897 | } else { | ||
2192 | 898 | var extension_path = Paths.get_lib_path (PACKAGE_NAME); | ||
2193 | 899 | var extension = Extension.load_from_file (extension_path, parts[0], true, false); | ||
2194 | 900 | var app = new App.proxy (null); | ||
2195 | 901 | app.@set ("settings", settings); | ||
2196 | 902 | |||
2197 | 903 | /* FIXME: tabs of multiple windows */ | ||
2198 | 904 | var browsers = new Katze.Array (typeof (Browser)); | ||
2199 | 905 | browsers.add_item (this); | ||
2200 | 906 | app.set_browsers (browsers, this); | ||
2201 | 907 | |||
2202 | 908 | if (extension != null && parts[1] != "true") | ||
2203 | 909 | extension.activate (parts[0], true, app); | ||
2204 | 910 | else if (extension != null && parts[1] == "false") | ||
2205 | 911 | extension.deactivate (); | ||
2206 | 982 | else | 912 | else |
2213 | 983 | { | 913 | warning (_("Unexpected setting '%s'"), name); |
2208 | 984 | /* folder's parent not found, skip it */ | ||
2209 | 985 | |||
2210 | 986 | list_iter = g_list_next (list_iter); | ||
2211 | 987 | continue; | ||
2212 | 988 | } | ||
2214 | 989 | } | 914 | } |
2215 | 915 | } else { | ||
2216 | 916 | var action = action_group.get_action (name); | ||
2217 | 917 | if (action != null) | ||
2218 | 918 | action.activate (); | ||
2219 | 990 | else | 919 | else |
2220 | 920 | <<<<<<< TREE | ||
2221 | 991 | g_assert_not_reached (); | 921 | g_assert_not_reached (); |
2222 | 992 | } | 922 | } |
2223 | 993 | 923 | ||
2224 | @@ -4498,9 +4428,154 @@ | |||
2225 | 4498 | 0, display, 1, bookmark_clients[i].icon, | 4428 | 0, display, 1, bookmark_clients[i].icon, |
2226 | 4499 | 2, file, 3, icon_width, -1); | 4429 | 2, file, 3, icon_width, -1); |
2227 | 4500 | g_free (display); | 4430 | g_free (display); |
2228 | 4431 | ======= | ||
2229 | 4432 | warning (_("Unexpected action '%s'."), name); | ||
2230 | 4433 | } | ||
2231 | 4434 | } | ||
2232 | 4435 | |||
2233 | 4436 | void view_notify_icon_cb (Object object, ParamSpec pspec) { | ||
2234 | 4437 | var view = (View) object; | ||
2235 | 4438 | |||
2236 | 4439 | if (get_current_tab () != view) | ||
2237 | 4440 | return; | ||
2238 | 4441 | |||
2239 | 4442 | if (Paths.get_runtime_mode () == RuntimeMode.APP) | ||
2240 | 4443 | icon = view.icon; | ||
2241 | 4444 | } | ||
2242 | 4445 | |||
2243 | 4446 | void view_notify_load_status_cb (Object object, ParamSpec pspec) { | ||
2244 | 4447 | var view = (View) object; | ||
2245 | 4448 | |||
2246 | 4449 | if (view == get_current_tab ()) { | ||
2247 | 4450 | if (view.load_status == LoadStatus.COMMITTED) { | ||
2248 | 4451 | var uri = view.get_display_uri (); | ||
2249 | 4452 | var action = action_group.get_action ("Location"); | ||
2250 | 4453 | ((LocationAction) action).set_text (uri); | ||
2251 | 4454 | |||
2252 | 4455 | /* Focus the urlbar on blank pages */ | ||
2253 | 4456 | if (view.is_blank ()) | ||
2254 | 4457 | activate_action ("Location"); | ||
2255 | 4458 | } | ||
2256 | 4459 | |||
2257 | 4460 | update_interface (view); | ||
2258 | 4461 | _set_statusbar_text (view, null); | ||
2259 | 4462 | } | ||
2260 | 4463 | |||
2261 | 4464 | if (view.load_status == LoadStatus.FINISHED) | ||
2262 | 4465 | view.get_proxy_item ().set_meta_string ("history-step", null); | ||
2263 | 4466 | |||
2264 | 4467 | notify_property ("load-status"); | ||
2265 | 4468 | } | ||
2266 | 4469 | |||
2267 | 4470 | void view_notify_progress_cb (Object object, ParamSpec pspec) { | ||
2268 | 4471 | var view = (View) object; | ||
2269 | 4472 | if (view == get_current_tab ()) | ||
2270 | 4473 | update_progress (view); | ||
2271 | 4474 | } | ||
2272 | 4475 | |||
2273 | 4476 | void view_notify_uri_cb (Object object, ParamSpec pspec) { | ||
2274 | 4477 | var view = (View) object; | ||
2275 | 4478 | if (view == get_current_tab ()) { | ||
2276 | 4479 | var uri = view.get_display_uri (); | ||
2277 | 4480 | var action = action_group.get_action ("Location"); | ||
2278 | 4481 | ((LocationAction) action).set_text (uri); | ||
2279 | 4482 | action_set_sensitive ("Back", view.can_go_back ()); | ||
2280 | 4483 | action_set_sensitive ("Forward", view.can_go_forward ()); | ||
2281 | 4484 | |||
2282 | 4485 | notify_property ("uri"); | ||
2283 | 4486 | } | ||
2284 | 4487 | } | ||
2285 | 4488 | |||
2286 | 4489 | new void set_title (string title) { | ||
2287 | 4490 | string window_title; | ||
2288 | 4491 | |||
2289 | 4492 | var custom_title = settings.custom_title; | ||
2290 | 4493 | if (custom_title != null && custom_title != "") | ||
2291 | 4494 | window_title = custom_title; | ||
2292 | 4495 | else if (settings.enable_private_browsing) | ||
2293 | 4496 | window_title = _("%s (Private Browsing)").printf (title); | ||
2294 | 4497 | else | ||
2295 | 4498 | window_title = title; | ||
2296 | 4499 | |||
2297 | 4500 | base.set_title (window_title); | ||
2298 | 4501 | } | ||
2299 | 4502 | |||
2300 | 4503 | void view_notify_title_cb (Object object, ParamSpec pspec) { | ||
2301 | 4504 | var view = (View) object; | ||
2302 | 4505 | if (view == get_current_tab ()) { | ||
2303 | 4506 | set_title (view.get_display_title ()); | ||
2304 | 4507 | notify_property ("title"); | ||
2305 | 4508 | } | ||
2306 | 4509 | step_history (view); | ||
2307 | 4510 | } | ||
2308 | 4511 | |||
2309 | 4512 | void step_history (View view) { | ||
2310 | 4513 | if (view.load_status != LoadStatus.COMMITTED) | ||
2311 | 4514 | return; | ||
2312 | 4515 | if (history_database == null || maximum_history_age == 0) | ||
2313 | 4516 | return; | ||
2314 | 4517 | |||
2315 | 4518 | var proxy = view.get_proxy_item (); | ||
2316 | 4519 | if (URI.is_blank (proxy.uri)) | ||
2317 | 4520 | return; | ||
2318 | 4521 | |||
2319 | 4522 | var history_step = proxy.get_meta_string ("history-step"); | ||
2320 | 4523 | if (history_step == null) { | ||
2321 | 4524 | var now = time_t (); | ||
2322 | 4525 | proxy.added = now; | ||
2323 | 4526 | |||
2324 | 4527 | var day = Sokoke.time_t_to_julian (ref now); | ||
2325 | 4528 | try { | ||
2326 | 4529 | history_database.insert (proxy.uri, proxy.name, proxy.added, day); | ||
2327 | 4530 | } catch (Error e) { | ||
2328 | 4531 | printerr (_("Failed to insert new history item: %s\n"), e.message); | ||
2329 | 4532 | return; | ||
2330 | 4533 | } | ||
2331 | 4534 | proxy.set_meta_string ("history-step", "update"); | ||
2332 | 4535 | /* FIXME: No signal for adding/ removing */ | ||
2333 | 4536 | history.add_item (proxy); | ||
2334 | 4537 | history.remove_item (proxy); | ||
2335 | 4538 | } else if (history_step != "update") { | ||
2336 | 4539 | if (proxy.name != null) | ||
2337 | 4540 | update_history_title (proxy); | ||
2338 | 4541 | } else if (history_step != "ignore") { | ||
2339 | 4542 | /* This is set when restoring sessions */ | ||
2340 | 4543 | } else | ||
2341 | 4544 | warning ("Unexpected history-step: %s", history_step); | ||
2342 | 4545 | } | ||
2343 | 4546 | |||
2344 | 4547 | void view_notify_zoom_level_cb (Object object, ParamSpec pspec) { | ||
2345 | 4548 | var view = (View) object; | ||
2346 | 4549 | if (view == get_current_tab ()) | ||
2347 | 4550 | action_set_sensitive ("ZoomNormal", view.zoom_level != 1.0f); | ||
2348 | 4551 | } | ||
2349 | 4552 | |||
2350 | 4553 | void view_notify_statusbar_text_cb (Object object, ParamSpec pspec) { | ||
2351 | 4554 | var view = (View) object; | ||
2352 | 4555 | if (view == get_current_tab ()) { | ||
2353 | 4556 | _set_statusbar_text (view, view.statusbar_text); | ||
2354 | 4557 | } | ||
2355 | 4558 | } | ||
2356 | 4559 | |||
2357 | 4560 | bool bookmark_folder_button_reach_parent (Gtk.TreeModel model, ref Gtk.TreeIter iter, int64 parentid) { | ||
2358 | 4561 | do { | ||
2359 | 4562 | int64 id; | ||
2360 | 4563 | |||
2361 | 4564 | model.@get (iter, 1, out id); | ||
2362 | 4565 | |||
2363 | 4566 | if (parentid == id) | ||
2364 | 4567 | return true; | ||
2365 | 4568 | |||
2366 | 4569 | if (model.iter_has_child (iter)) { | ||
2367 | 4570 | Gtk.TreeIter child; | ||
2368 | 4571 | model.iter_children (out child, iter); | ||
2369 | 4572 | if (bookmark_folder_button_reach_parent (model, ref child, parentid)) { | ||
2370 | 4573 | iter = child; | ||
2371 | 4574 | return true; | ||
2372 | 4575 | >>>>>>> MERGE-SOURCE | ||
2373 | 4501 | } | 4576 | } |
2374 | 4502 | g_free (file); | ||
2375 | 4503 | } | 4577 | } |
2376 | 4578 | <<<<<<< TREE | ||
2377 | 4504 | g_dir_close (dir); | 4579 | g_dir_close (dir); |
2378 | 4505 | } | 4580 | } |
2379 | 4506 | g_free (path); | 4581 | g_free (path); |
2380 | @@ -7572,30 +7647,4004 @@ | |||
2381 | 7572 | { | 7647 | { |
2382 | 7573 | /* For some reason, when called on the widget of the | 7648 | /* For some reason, when called on the widget of the |
2383 | 7574 | * application menubar we get here. | 7649 | * application menubar we get here. |
2384 | 7650 | ======= | ||
2385 | 7651 | } while (model.iter_next (ref iter)); | ||
2386 | 7652 | |||
2387 | 7653 | return false; | ||
2388 | 7654 | } | ||
2389 | 7655 | |||
2390 | 7656 | Gtk.ComboBox bookmark_folder_button_new (BookmarksDb array, int64 selected_parentid) { | ||
2391 | 7657 | var sqlcmd = "SELECT title, id, parentid FROM bookmarks WHERE uri='' ORDER BY parentid, title ASC"; | ||
2392 | 7658 | Gtk.TreeIter stock_parent_iter; | ||
2393 | 7659 | |||
2394 | 7660 | unowned Sqlite.Database db = array.get_data<Sqlite.Database> ("db"); | ||
2395 | 7661 | return_val_if_fail (db != null, null); | ||
2396 | 7662 | |||
2397 | 7663 | /* folder combo box model content: | ||
2398 | 7664 | ** 0: title | ||
2399 | 7665 | ** 1: id | ||
2400 | 7666 | */ | ||
2401 | 7667 | var model = new Gtk.TreeStore (2, typeof (string), typeof (int64)); | ||
2402 | 7668 | var combo = new Gtk.ComboBox.with_model (model); | ||
2403 | 7669 | |||
2404 | 7670 | /* setup combo layout | ||
2405 | 7671 | ** 0: a folder icon | ||
2406 | 7672 | ** 1: the folder name | ||
2407 | 7673 | >>>>>>> MERGE-SOURCE | ||
2408 | 7575 | */ | 7674 | */ |
2409 | 7576 | 7675 | ||
2414 | 7577 | GList* top_levels = gtk_window_list_toplevels (); | 7676 | combo.clear (); |
2415 | 7578 | GList *iter; | 7677 | |
2416 | 7579 | 7678 | var pix_renderer = new Gtk.CellRendererPixbuf (); | |
2417 | 7580 | for (iter = top_levels; iter; iter = g_list_next (iter)) | 7679 | pix_renderer.stock_id = Gtk.Stock.DIRECTORY; |
2418 | 7680 | pix_renderer.stock_size = Gtk.IconSize.MENU; | ||
2419 | 7681 | combo.pack_start (pix_renderer, false); | ||
2420 | 7682 | |||
2421 | 7683 | var text_renderer = new Katze.CellRendererComboBoxText (); | ||
2422 | 7684 | text_renderer.width_chars = 40; /* FIXME: figure out a way to define an acceptable string length */ | ||
2423 | 7685 | text_renderer.ellipsize = Pango.EllipsizeMode.END; | ||
2424 | 7686 | text_renderer.unfolded_text = _("Select [text]"); | ||
2425 | 7687 | combo.pack_start (text_renderer, true); | ||
2426 | 7688 | combo.add_attribute (text_renderer, "text", 0); | ||
2427 | 7689 | |||
2428 | 7690 | /* read the folders list from the database */ | ||
2429 | 7691 | /* FIXME: this should be a service of midori/midori-bookmarks-db */ | ||
2430 | 7692 | |||
2431 | 7693 | var folders = new List<FolderEntry?> (); | ||
2432 | 7694 | |||
2433 | 7695 | Sqlite.Statement statement; | ||
2434 | 7696 | int result; | ||
2435 | 7697 | if ((result = db.prepare_v2 (sqlcmd, -1, out statement)) == Sqlite.OK) { | ||
2436 | 7698 | while ((result = statement.step ()) == Sqlite.ROW) { | ||
2437 | 7699 | folders.append ({ | ||
2438 | 7700 | statement.column_text (0), | ||
2439 | 7701 | statement.column_int64 (1), | ||
2440 | 7702 | statement.column_int64 (2) | ||
2441 | 7703 | }); | ||
2442 | 7704 | } | ||
2443 | 7705 | |||
2444 | 7706 | statement.clear_bindings (); | ||
2445 | 7707 | statement.reset (); | ||
2446 | 7708 | } | ||
2447 | 7709 | |||
2448 | 7710 | /* populate the combo box */ | ||
2449 | 7711 | /* FIXME: here we should have the root bookmark array's name and id, not hard encoded values */ | ||
2450 | 7712 | |||
2451 | 7713 | Gtk.TreeIter tree_iter; | ||
2452 | 7714 | model.insert_with_values (out tree_iter, null, int.MAX, 0, _("Bookmarks"), 1, -1); | ||
2453 | 7715 | combo.set_active_iter (tree_iter); | ||
2454 | 7716 | |||
2455 | 7717 | int64 current_parentid = -1; | ||
2456 | 7718 | Gtk.TreeIter? parent_iter = null; | ||
2457 | 7719 | uint n = 1; | ||
2458 | 7720 | while (folders.first () != null) { | ||
2459 | 7721 | var something_done = false; | ||
2460 | 7722 | unowned List<FolderEntry?> list_iter = folders.first (); | ||
2461 | 7723 | |||
2462 | 7724 | do { | ||
2463 | 7725 | FolderEntry folder = list_iter.data; | ||
2464 | 7726 | var title = folder.title; | ||
2465 | 7727 | int64 id = folder.id; | ||
2466 | 7728 | int64 parentid = folder.parentid; | ||
2467 | 7729 | |||
2468 | 7730 | if (parentid != current_parentid) { /* optimize case of sub-folders of the same parent */ | ||
2469 | 7731 | if (parentid == 0) { | ||
2470 | 7732 | /* folder's parent is the stree store root */ | ||
2471 | 7733 | |||
2472 | 7734 | current_parentid = -1; | ||
2473 | 7735 | parent_iter = null; | ||
2474 | 7736 | } else if (model.get_iter_first (out tree_iter)) { | ||
2475 | 7737 | if (bookmark_folder_button_reach_parent (model, ref tree_iter, parentid)) { | ||
2476 | 7738 | /* folder's parent found in the tree store */ | ||
2477 | 7739 | |||
2478 | 7740 | current_parentid = parentid; | ||
2479 | 7741 | stock_parent_iter = tree_iter; | ||
2480 | 7742 | parent_iter = stock_parent_iter; | ||
2481 | 7743 | } else { | ||
2482 | 7744 | /* folder's parent not found, skip it */ | ||
2483 | 7745 | |||
2484 | 7746 | list_iter = list_iter.next; | ||
2485 | 7747 | continue; | ||
2486 | 7748 | } | ||
2487 | 7749 | } else | ||
2488 | 7750 | assert_not_reached (); | ||
2489 | 7751 | } | ||
2490 | 7752 | |||
2491 | 7753 | /* insert folder in the tree store and remove it from the folders list */ | ||
2492 | 7754 | |||
2493 | 7755 | model.insert_with_values (out tree_iter, parent_iter, int.MAX, 0, title, 1, id); | ||
2494 | 7756 | |||
2495 | 7757 | if (id == selected_parentid) | ||
2496 | 7758 | combo.set_active_iter (tree_iter); | ||
2497 | 7759 | |||
2498 | 7760 | n++; | ||
2499 | 7761 | |||
2500 | 7762 | something_done = true; | ||
2501 | 7763 | |||
2502 | 7764 | folders.delete_link (list_iter); | ||
2503 | 7765 | |||
2504 | 7766 | list_iter = folders.first (); | ||
2505 | 7767 | } while (list_iter != null); | ||
2506 | 7768 | |||
2507 | 7769 | if (!something_done) /* avoid infinite loop in case of orphan folders */ | ||
2508 | 7770 | break; | ||
2509 | 7771 | } | ||
2510 | 7772 | |||
2511 | 7773 | if (folders.first () != null) { | ||
2512 | 7774 | printerr ("midori_bookmark_folder_button_new: orphan folder(s) detected in bookmarks db\n"); | ||
2513 | 7775 | |||
2514 | 7776 | foreach (var folder in folders) { | ||
2515 | 7777 | var title = folder.title; | ||
2516 | 7778 | var id = folder.id; | ||
2517 | 7779 | var parentid = folder.parentid; | ||
2518 | 7780 | |||
2519 | 7781 | printerr (" id=%" + int64.FORMAT + ", parentid=%" + int64.FORMAT + ", title=%s\n", | ||
2520 | 7782 | id, parentid, title); | ||
2521 | 7783 | } | ||
2522 | 7784 | } | ||
2523 | 7785 | |||
2524 | 7786 | if (n < 2) | ||
2525 | 7787 | combo.sensitive = false; | ||
2526 | 7788 | |||
2527 | 7789 | return combo; | ||
2528 | 7790 | } | ||
2529 | 7791 | |||
2530 | 7792 | int64 bookmark_folder_button_get_active (Gtk.Widget widget) { | ||
2531 | 7793 | int64 id = -1; | ||
2532 | 7794 | Gtk.TreeIter iter; | ||
2533 | 7795 | |||
2534 | 7796 | var combo = widget as Gtk.ComboBox; | ||
2535 | 7797 | |||
2536 | 7798 | return_val_if_fail (combo == null, 0); | ||
2537 | 7799 | |||
2538 | 7800 | if (combo.get_active_iter (out iter)) { | ||
2539 | 7801 | combo.model.@get (iter, 1, out id); | ||
2540 | 7802 | } | ||
2541 | 7803 | |||
2542 | 7804 | return id; | ||
2543 | 7805 | } | ||
2544 | 7806 | |||
2545 | 7807 | void edit_bookmark_title_changed_cb (Gtk.Entry entry, Gtk.Dialog dialog) { | ||
2546 | 7808 | var title = entry.text; | ||
2547 | 7809 | dialog.set_response_sensitive (Gtk.ResponseType.ACCEPT, title != null && title != ""); | ||
2548 | 7810 | } | ||
2549 | 7811 | |||
2550 | 7812 | void edit_bookmark_add_speed_dial_cb (Gtk.Widget button, Katze.Item bookmark) { | ||
2551 | 7813 | add_speed_dial (); | ||
2552 | 7814 | ((Gtk.Dialog) button.get_toplevel ()).response (Gtk.ResponseType.DELETE_EVENT); | ||
2553 | 7815 | } | ||
2554 | 7816 | |||
2555 | 7817 | void edit_bookmark_create_launcher_cb (Gtk.Widget button, Katze.Item bookmark) { | ||
2556 | 7818 | var action = button.get_data<Gtk.Action> ("midori-action"); | ||
2557 | 7819 | action.activate (); | ||
2558 | 7820 | ((Gtk.Dialog) button.get_toplevel ()).response (Gtk.ResponseType.DELETE_EVENT); | ||
2559 | 7821 | } | ||
2560 | 7822 | |||
2561 | 7823 | /* Private function, used by MidoriBookmarks and MidoriHistory */ | ||
2562 | 7824 | internal bool edit_bookmark_dialog_new (Katze.Item? bookmark_or_parent, bool new_bookmark, bool is_folder, Gtk.Widget proxy) { | ||
2563 | 7825 | Katze.Item bookmark = bookmark_or_parent; | ||
2564 | 7826 | bool return_status = false; | ||
2565 | 7827 | |||
2566 | 7828 | Gtk.Dialog dialog; | ||
2567 | 7829 | string title; | ||
2568 | 7830 | if (is_folder) | ||
2569 | 7831 | title = new_bookmark ? _("New Folder") : _("Edit Folder"); | ||
2570 | 7832 | else | ||
2571 | 7833 | title = new_bookmark ? _("New Bookmark") : _("Edit Bookmark"); | ||
2572 | 7834 | |||
2573 | 7835 | #if HAVE_GRANITE | ||
2574 | 7836 | if (proxy != null) { | ||
2575 | 7837 | // TODO port to GtkPopover? | ||
2576 | 7838 | dialog = new Granite.Widgets.PopOver (); | ||
2577 | 7839 | ((Granite.Widgets.PopOver) dialog).move_to_widget (proxy, true); | ||
2578 | 7840 | } else | ||
2579 | 7841 | #endif | ||
2580 | 7581 | { | 7842 | { |
2589 | 7582 | browser = iter->data; | 7843 | dialog = new Gtk.Dialog.with_buttons (title, this, Gtk.DialogFlags.DESTROY_WITH_PARENT, null); |
2590 | 7583 | 7844 | } | |
2591 | 7584 | if (MIDORI_IS_BROWSER (browser) && gtk_widget_is_ancestor( GTK_WIDGET (browser), widget)) | 7845 | var content_area = ((Gtk.Dialog) dialog).get_content_area (); |
2592 | 7585 | { | 7846 | dialog.set_border_width (6); |
2593 | 7586 | g_list_free (top_levels); | 7847 | dialog.add_buttons (Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL, |
2594 | 7587 | return MIDORI_BROWSER (browser); | 7848 | new_bookmark ? Gtk.Stock.ADD : Gtk.Stock.SAVE, Gtk.ResponseType.ACCEPT); |
2595 | 7588 | } | 7849 | |
2596 | 7589 | } | 7850 | Gtk.Label label; |
2597 | 7851 | if (!is_folder) | ||
2598 | 7852 | label = new Gtk.Label (_("Type a name for this bookmark, and choose where to keep it.")); | ||
2599 | 7853 | else | ||
2600 | 7854 | label = new Gtk.Label (_("Type a name for this folder, and choose where to keep it.")); | ||
2601 | 7855 | |||
2602 | 7856 | var vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 6); | ||
2603 | 7857 | vbox.pack_start (label, false, false, 6); | ||
2604 | 7858 | content_area.pack_start (vbox, false, false, 0); | ||
2605 | 7859 | ((Gtk.Window) dialog).icon_name = new_bookmark ? Gtk.Stock.ADD : Gtk.Stock.REMOVE; | ||
2606 | 7860 | |||
2607 | 7861 | if (new_bookmark) { | ||
2608 | 7862 | var view = (View) get_current_tab (); | ||
2609 | 7863 | if (is_folder) { | ||
2610 | 7864 | bookmark = new Katze.Array (typeof (Katze.Array)); | ||
2611 | 7865 | bookmark.name = view.get_display_title (); | ||
2612 | 7866 | } else { | ||
2613 | 7867 | bookmark = new Katze.Item (); | ||
2614 | 7868 | bookmark.uri = view.get_display_uri (); | ||
2615 | 7869 | bookmark.name = view.get_display_title (); | ||
2616 | 7870 | } | ||
2617 | 7871 | |||
2618 | 7872 | bookmark.set_meta_integer ("parentid", (bookmark_or_parent == null ? 0 : bookmark_or_parent.get_meta_integer ("id"))); | ||
2619 | 7873 | } | ||
2620 | 7874 | |||
2621 | 7875 | var item_name = bookmark.name; | ||
2622 | 7876 | var entry_title = new Gtk.Entry (); | ||
2623 | 7877 | entry_title.activates_default = true; | ||
2624 | 7878 | entry_title.text = Katze.str_non_null (item_name); | ||
2625 | 7879 | edit_bookmark_title_changed_cb (entry_title, dialog); | ||
2626 | 7880 | entry_title.changed.connect ((entry_title) => edit_bookmark_title_changed_cb ((Gtk.Entry) entry_title, dialog)); | ||
2627 | 7881 | vbox.pack_start (entry_title, false, false, 0); | ||
2628 | 7882 | |||
2629 | 7883 | Gtk.Entry? entry_uri = null; | ||
2630 | 7884 | if (!is_folder) { | ||
2631 | 7885 | entry_uri = Katze.uri_entry_new (dialog.get_widget_for_response (Gtk.ResponseType.ACCEPT)); | ||
2632 | 7886 | entry_uri.activates_default = true; | ||
2633 | 7887 | entry_uri.text = bookmark.uri; | ||
2634 | 7888 | vbox.pack_start (entry_uri, false, false, 0); | ||
2635 | 7889 | } | ||
2636 | 7890 | |||
2637 | 7891 | var combo_folder = bookmark_folder_button_new (bookmarks, bookmark.get_meta_integer ("parentid")); | ||
2638 | 7892 | vbox.pack_start (combo_folder, false, false, 0); | ||
2639 | 7893 | |||
2640 | 7894 | var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); | ||
2641 | 7895 | vbox.pack_start (hbox, false, false, 0); | ||
2642 | 7896 | var check_toolbar = new Gtk.CheckButton.with_mnemonic (_("Show in Bookmarks _Bar")); | ||
2643 | 7897 | check_toolbar.active = bookmark.get_meta_boolean ("toolbar"); | ||
2644 | 7898 | hbox.pack_start (check_toolbar, false, false, 0); | ||
2645 | 7899 | |||
2646 | 7900 | if (new_bookmark && !is_folder) { | ||
2647 | 7901 | hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 6); | ||
2648 | 7902 | vbox.pack_start (hbox, false, false, 0); | ||
2649 | 7903 | |||
2650 | 7904 | var button = new Gtk.CheckButton.with_mnemonic (_("Add to _Speed Dial")); | ||
2651 | 7905 | button.clicked.connect ((label) => edit_bookmark_add_speed_dial_cb (label, bookmark)); | ||
2652 | 7906 | hbox.pack_start (button, false, false, 0); | ||
2653 | 7907 | |||
2654 | 7908 | /* FIXME: There's no API for extending the bookmark dialog */ | ||
2655 | 7909 | var action = action_group.get_action ("CreateLauncher"); | ||
2656 | 7910 | if (action != null) { | ||
2657 | 7911 | var check_button = new Gtk.Button.with_mnemonic (action.label); | ||
2658 | 7912 | check_button.set_data<Gtk.Action> ("midori-action", action); | ||
2659 | 7913 | check_button.clicked.connect ((label) => edit_bookmark_create_launcher_cb (label, bookmark)); | ||
2660 | 7914 | hbox.pack_start (check_button, false, false, 0); | ||
2661 | 7915 | } | ||
2662 | 7916 | } | ||
2663 | 7917 | |||
2664 | 7918 | content_area.show_all (); | ||
2665 | 7919 | |||
2666 | 7920 | dialog.set_default_response (Gtk.ResponseType.ACCEPT); | ||
2667 | 7921 | if (Dialog.run (dialog) == Gtk.ResponseType.ACCEPT) { | ||
2668 | 7922 | bookmark.name = entry_title.text; | ||
2669 | 7923 | bookmark.set_meta_integer ("toolbar", (int) check_toolbar.active); | ||
2670 | 7924 | if (!is_folder) | ||
2671 | 7925 | bookmark.uri = entry_uri.text; | ||
2672 | 7926 | |||
2673 | 7927 | var selected = bookmark_folder_button_get_active (combo_folder); | ||
2674 | 7928 | bookmark.set_meta_integer ("parentid", selected); | ||
2675 | 7929 | |||
2676 | 7930 | if (new_bookmark) | ||
2677 | 7931 | bookmarks.add_item (bookmark); | ||
2678 | 7932 | else | ||
2679 | 7933 | bookmarks.update_item (bookmark); | ||
2680 | 7934 | |||
2681 | 7935 | return_status = true; | ||
2682 | 7936 | } | ||
2683 | 7937 | |||
2684 | 7938 | dialog.destroy (); | ||
2685 | 7939 | return return_status; | ||
2686 | 7940 | } | ||
2687 | 7941 | |||
2688 | 7942 | bool prepare_download (WebKit.Download download, string uri) { | ||
2689 | 7943 | if (!Download.has_enough_space (download, uri, false)) | ||
2690 | 7944 | return false; | ||
2691 | 7945 | |||
2692 | 7946 | #if HAVE_WEBKIT2 | ||
2693 | 7947 | download.destination = uri; | ||
2694 | 7948 | #else | ||
2695 | 7949 | download.destination_uri = uri; | ||
2696 | 7950 | #endif | ||
2697 | 7951 | add_download (download); | ||
2698 | 7952 | return true; | ||
2699 | 7953 | } | ||
2700 | 7954 | |||
2701 | 7955 | #if !HAVE_WEBKIT2 | ||
2702 | 7956 | void save_resources (List<WebKit.WebResource> resources, string folder) { | ||
2703 | 7957 | Paths.mkdir_with_parents (folder); | ||
2704 | 7958 | |||
2705 | 7959 | foreach (var resource in resources) { | ||
2706 | 7960 | unowned StringBuilder data = resource.get_data (); | ||
2707 | 7961 | |||
2708 | 7962 | /* Resource could be adblocked, skip it in that case */ | ||
2709 | 7963 | if (resource.uri == "about:blank") | ||
2710 | 7964 | continue; | ||
2711 | 7965 | |||
2712 | 7966 | var sub_filename = Download.get_filename_suggestion_for_uri (resource.mime_type, resource.uri); | ||
2713 | 7967 | var sub_path = Download.get_unique_filename (Path.build_filename (folder, sub_filename)); | ||
2714 | 7968 | if (data != null) { | ||
2715 | 7969 | try { | ||
2716 | 7970 | FileUtils.set_contents (sub_path, data.str, data.len); | ||
2717 | 7971 | } catch (Error e) { | ||
2718 | 7972 | warning ("Failed to save %s: %s", sub_filename, e.message); | ||
2719 | 7973 | } | ||
2720 | 7974 | } else | ||
2721 | 7975 | warning ("Skipping empty resource %s", sub_filename); | ||
2722 | 7976 | } | ||
2723 | 7977 | } | ||
2724 | 7978 | #endif | ||
2725 | 7979 | |||
2726 | 7980 | void save_uri (View view, string? uri) { | ||
2727 | 7981 | string? last_dir = null; | ||
2728 | 7982 | var title = view.get_display_title (); | ||
2729 | 7983 | |||
2730 | 7984 | var dialog = new FileChooserDialog (_("Save file as"), this, Gtk.FileChooserAction.SAVE); | ||
2731 | 7985 | dialog.do_overwrite_confirmation = true; | ||
2732 | 7986 | |||
2733 | 7987 | if (uri == null) | ||
2734 | 7988 | uri = view.get_display_uri (); | ||
2735 | 7989 | |||
2736 | 7990 | if (last_dir != null && last_dir != "") | ||
2737 | 7991 | dialog.set_current_folder (last_dir); | ||
2738 | 7992 | else { | ||
2739 | 7993 | var dirname = URI.get_folder (uri); | ||
2740 | 7994 | if (dirname == null) | ||
2741 | 7995 | dirname = settings.download_folder; | ||
2742 | 7996 | dialog.set_current_folder (dirname); | ||
2743 | 7997 | } | ||
2744 | 7998 | |||
2745 | 7999 | string filename; | ||
2746 | 8000 | #if !HAVE_WEBKIT2 | ||
2747 | 8001 | var resources = view.get_resources (); | ||
2748 | 8002 | var file_only = true; | ||
2749 | 8003 | Gtk.CheckButton? checkbox = null; | ||
2750 | 8004 | |||
2751 | 8005 | if (resources != null && resources.nth_data (1) != null) { | ||
2752 | 8006 | file_only = false; | ||
2753 | 8007 | checkbox = new Gtk.CheckButton.with_mnemonic (_("Save associated _resources")); | ||
2754 | 8008 | checkbox.active = true; | ||
2755 | 8009 | dialog.extra_widget = checkbox; | ||
2756 | 8010 | } | ||
2757 | 8011 | |||
2758 | 8012 | if (!file_only && title != uri) | ||
2759 | 8013 | filename = Download.clean_filename (title); | ||
2760 | 8014 | else | ||
2761 | 8015 | filename = Download.get_filename_suggestion_for_uri (view.mime_type, uri); | ||
2762 | 8016 | |||
2763 | 8017 | dialog.set_current_name (filename); | ||
2764 | 8018 | |||
2765 | 8019 | if (Dialog.run (dialog) == Gtk.ResponseType.OK) { | ||
2766 | 8020 | filename = dialog.get_filename (); | ||
2767 | 8021 | if (checkbox != null) | ||
2768 | 8022 | file_only = !checkbox.active; | ||
2769 | 8023 | |||
2770 | 8024 | if (!file_only) { | ||
2771 | 8025 | var fullname = filename + ".html"; | ||
2772 | 8026 | view.save_source (uri, fullname, false); | ||
2773 | 8027 | save_resources (resources, filename); | ||
2774 | 8028 | } else | ||
2775 | 8029 | view.save_source (uri, filename, false); | ||
2776 | 8030 | |||
2777 | 8031 | last_dir = dialog.get_current_folder (); | ||
2778 | 8032 | } | ||
2779 | 8033 | #else | ||
2780 | 8034 | filename = Midori.download_clean_filename (title); | ||
2781 | 8035 | var suggested_filename = filename + ".mht"; | ||
2782 | 8036 | dialog.set_current_name (suggested_filename); | ||
2783 | 8037 | |||
2784 | 8038 | if (Dialog.run (dialog) == Gtk.ResponseType.OK) { | ||
2785 | 8039 | var uri = dialog.get_uri (); | ||
2786 | 8040 | if (uri != null) | ||
2787 | 8041 | view.save_source (uri, null, false); | ||
2788 | 8042 | |||
2789 | 8043 | last_dir = dialog.get_current_folder (); | ||
2790 | 8044 | } | ||
2791 | 8045 | #endif | ||
2792 | 8046 | dialog.destroy (); | ||
2793 | 8047 | } | ||
2794 | 8048 | |||
2795 | 8049 | void speed_dial_refresh_cb (SpeedDial dial) { | ||
2796 | 8050 | foreach (var tab in get_tabs ()) { | ||
2797 | 8051 | if (tab.uri == "about:dial") | ||
2798 | 8052 | ((View) tab).reload (false); | ||
2799 | 8053 | } | ||
2800 | 8054 | } | ||
2801 | 8055 | |||
2802 | 8056 | void add_speed_dial () { | ||
2803 | 8057 | var view = (View) get_current_tab (); | ||
2804 | 8058 | dial.add (view.get_display_uri (), view.get_display_title (), null); | ||
2805 | 8059 | } | ||
2806 | 8060 | |||
2807 | 8061 | bool tab_leave_notify_event_cb (Object object, Gdk.EventCrossing event) { | ||
2808 | 8062 | _set_statusbar_text ((View) object, null); | ||
2809 | 8063 | return true; | ||
2810 | 8064 | } | ||
2811 | 8065 | |||
2812 | 8066 | void view_destroy_cb (Gtk.Widget widget) { | ||
2813 | 8067 | var view = (View) widget; | ||
2814 | 8068 | |||
2815 | 8069 | if (proxy_array != null) { | ||
2816 | 8070 | var item = view.get_proxy_item (); | ||
2817 | 8071 | if (proxy_array.get_item_index (item) != -1 && !tab.is_blank ()) { | ||
2818 | 8072 | if (trash != null) | ||
2819 | 8073 | trash.add_item (item); | ||
2820 | 8074 | update_history (item, "website", "leave"); | ||
2821 | 8075 | } | ||
2822 | 8076 | disconnect_tab (view); | ||
2823 | 8077 | remove_tab (view); | ||
2824 | 8078 | } | ||
2825 | 8079 | } | ||
2826 | 8080 | |||
2827 | 8081 | void view_attach_inspector_cb (Gtk.Widget view, Gtk.Widget inspector_view) { | ||
2828 | 8082 | var toplevel = inspector_view.get_toplevel (); | ||
2829 | 8083 | var scrolled = this.inspector_view.get_parent (); | ||
2830 | 8084 | if (inspector_view == this.inspector_view) | ||
2831 | 8085 | return; | ||
2832 | 8086 | |||
2833 | 8087 | toplevel.hide (); | ||
2834 | 8088 | this.inspector_view.destroy (); | ||
2835 | 8089 | inspector_view.reparent (scrolled); | ||
2836 | 8090 | inspector.show_all (); | ||
2837 | 8091 | this.inspector_view = inspector_view; | ||
2838 | 8092 | toplevel.destroy (); | ||
2839 | 8093 | if (!settings.last_inspector_attached) | ||
2840 | 8094 | settings.last_inspector_attached = true; | ||
2841 | 8095 | } | ||
2842 | 8096 | |||
2843 | 8097 | void view_detach_inspector_cb (Gtk.Widget view, Gtk.Widget inspector_view) { | ||
2844 | 8098 | var scrolled = (Gtk.Container) inspector_view.get_parent (); | ||
2845 | 8099 | var paned = scrolled.get_parent (); | ||
2846 | 8100 | this.inspector_view = new Gtk.Viewport (null, null); | ||
2847 | 8101 | scrolled.remove (inspector_view); | ||
2848 | 8102 | scrolled.add (this.inspector_view); | ||
2849 | 8103 | paned.hide (); | ||
2850 | 8104 | if (settings.last_inspector_attached) | ||
2851 | 8105 | settings.last_inspector_attached = false; | ||
2852 | 8106 | } | ||
2853 | 8107 | |||
2854 | 8108 | void view_copy_history (Gtk.Widget view_to, Gtk.Widget view_from, bool omit_last) { | ||
2855 | 8109 | #if !HAVE_WEBKIT2 | ||
2856 | 8110 | var copy_from = ((View) view_from).web_view; | ||
2857 | 8111 | var list_from = copy_from.get_back_forward_list (); | ||
2858 | 8112 | var copy_to = ((View) view_to).web_view; | ||
2859 | 8113 | var list_to = copy_to.get_back_forward_list (); | ||
2860 | 8114 | var length_from = list_from.get_back_length (); | ||
2861 | 8115 | |||
2862 | 8116 | for (var i = -length_from; i <= (omit_last ? -1 : 0); i++) { | ||
2863 | 8117 | var item = list_from.get_nth_item (i); | ||
2864 | 8118 | if (item == null) | ||
2865 | 8119 | break; | ||
2866 | 8120 | list_to.add_item (item); | ||
2867 | 8121 | } | ||
2868 | 8122 | #endif | ||
2869 | 8123 | } | ||
2870 | 8124 | |||
2871 | 8125 | bool notify_new_tab_timeout_cb () { | ||
2872 | 8126 | #if !G_OS_WIN32 | ||
2873 | 8127 | set_opacity (1); | ||
2874 | 8128 | #endif | ||
2875 | 8129 | return false; | ||
2876 | 8130 | } | ||
2877 | 8131 | |||
2878 | 8132 | void notify_new_tab () { | ||
2879 | 8133 | if (settings.flash_window_on_new_bg_tabs) { | ||
2880 | 8134 | #if G_OS_WIN32 | ||
2881 | 8135 | set_opacity (0.8); | ||
2882 | 8136 | #endif | ||
2883 | 8137 | Midori.Timeout.add (100, notify_new_tab_timeout_cb); | ||
2884 | 8138 | } | ||
2885 | 8139 | } | ||
2886 | 8140 | |||
2887 | 8141 | bool view_forward_external (View view, string uri, NewView where) | ||
2888 | 8142 | { | ||
2889 | 8143 | if (Paths.get_runtime_mode () == RuntimeMode.APP) { | ||
2890 | 8144 | return view.open_uri (uri); | ||
2891 | 8145 | } else if (Paths.get_runtime_mode () == RuntimeMode.PRIVATE) { | ||
2892 | 8146 | if (where == NewView.WINDOW) { | ||
2893 | 8147 | Sokoke.spawn_app (uri, true); | ||
2894 | 8148 | return true; | ||
2895 | 8149 | } | ||
2896 | 8150 | } | ||
2897 | 8151 | return false; | ||
2898 | 8152 | } | ||
2899 | 8153 | |||
2900 | 8154 | internal void view_new_tab_cb (Gtk.Widget view, string uri, bool background) { | ||
2901 | 8155 | if (view_forward_external ((View) view, uri, NewView.TAB)) | ||
2902 | 8156 | return; | ||
2903 | 8157 | |||
2904 | 8158 | var new_view = add_uri (uri); | ||
2905 | 8159 | if (view != null) | ||
2906 | 8160 | view_copy_history (new_view, view, false); | ||
2907 | 8161 | |||
2908 | 8162 | if (!background) | ||
2909 | 8163 | set_current_tab (new_view); | ||
2910 | 8164 | else | ||
2911 | 8165 | notify_new_tab (); | ||
2912 | 8166 | } | ||
2913 | 8167 | |||
2914 | 8168 | void view_new_window_cb (Gtk.Widget? view, string uri) { | ||
2915 | 8169 | if (view_forward_external ((View) (view != null ? view : get_current_tab ()), uri, NewView.WINDOW)) | ||
2916 | 8170 | return; | ||
2917 | 8171 | |||
2918 | 8172 | var new_browser = new_window (null); | ||
2919 | 8173 | assert (new_browser != null); | ||
2920 | 8174 | new_browser.view_new_tab_cb (view, uri, false); | ||
2921 | 8175 | } | ||
2922 | 8176 | |||
2923 | 8177 | void view_new_view_cb (Gtk.Widget view, Gtk.Widget new_view, NewView where, bool user_initiated) { | ||
2924 | 8178 | if (((View) view).is_dialog) { | ||
2925 | 8179 | /* Dialog: URL, no toolbars, no tabs */ | ||
2926 | 8180 | var new_browser = new_window (null); | ||
2927 | 8181 | assert (new_browser != null); | ||
2928 | 8182 | new_browser.set_transient_for (this); | ||
2929 | 8183 | new_browser.set_destroy_with_parent (true); | ||
2930 | 8184 | new_browser.show_tabs = false; | ||
2931 | 8185 | Sokoke.widget_set_visible (new_browser.menubar, false); | ||
2932 | 8186 | Sokoke.widget_set_visible (new_browser.bookmarkbar, false); | ||
2933 | 8187 | Sokoke.widget_set_visible (new_browser.statusbar, false); | ||
2934 | 8188 | new_browser.action_set_visible ("CompactMenu", false); | ||
2935 | 8189 | new_browser.set_toolbar_items ("Location"); | ||
2936 | 8190 | Sokoke.widget_set_visible (panel, false); | ||
2937 | 8191 | new_browser.add_tab (new_view); | ||
2938 | 8192 | new_browser.set_current_tab (new_view); | ||
2939 | 8193 | return; | ||
2940 | 8194 | } | ||
2941 | 8195 | |||
2942 | 8196 | if (view_forward_external ((View) new_view, ((View) new_view).get_proxy_item ().uri, where)) | ||
2943 | 8197 | return; | ||
2944 | 8198 | |||
2945 | 8199 | view_copy_history (new_view, view, true); | ||
2946 | 8200 | if (where == NewView.WINDOW) { | ||
2947 | 8201 | var new_browser = new_window (null); | ||
2948 | 8202 | assert (new_browser != null); | ||
2949 | 8203 | new_browser.add_tab (new_view); | ||
2950 | 8204 | new_browser.set_current_tab (new_view); | ||
2951 | 8205 | } else if (new_view.get_parent () != notebook) { | ||
2952 | 8206 | add_tab (new_view); | ||
2953 | 8207 | if (where != NewView.BACKGROUND) | ||
2954 | 8208 | set_current_tab (new_view); | ||
2955 | 8209 | } else | ||
2956 | 8210 | notify_new_tab (); | ||
2957 | 8211 | |||
2958 | 8212 | if (!user_initiated) { | ||
2959 | 8213 | var window = get_window (); | ||
2960 | 8214 | var state = window.get_state (); | ||
2961 | 8215 | if ((state | Gdk.WindowState.MAXIMIZED) != 0 | ||
2962 | 8216 | || (state | Gdk.WindowState.FULLSCREEN) != 0) { | ||
2963 | 8217 | if (where == NewView.WINDOW) | ||
2964 | 8218 | send_notification (_("New Window"), _("A new window has been opened")); | ||
2965 | 8219 | else if (!show_tabs) | ||
2966 | 8220 | send_notification (_("New Tab"), _("A new tab has been opened")); | ||
2967 | 8221 | } | ||
2968 | 8222 | } | ||
2969 | 8223 | } | ||
2970 | 8224 | |||
2971 | 8225 | #if HAVE_WEBKIT2 | ||
2972 | 8226 | void close_tab_idle (Object resource, AsyncResult result, View view) | ||
2973 | 8227 | { | ||
2974 | 8228 | uint8[] data; | ||
2975 | 8229 | try { | ||
2976 | 8230 | data = resource.get_data.end (res, null); | ||
2977 | 8231 | } catch (Error e) {} | ||
2978 | 8232 | |||
2979 | 8233 | if (data != null) | ||
2980 | 8234 | return; | ||
2981 | 8235 | #else | ||
2982 | 8236 | bool close_tab_idle (View view) | ||
2983 | 8237 | { | ||
2984 | 8238 | #endif | ||
2985 | 8239 | close_tab (view); | ||
2986 | 8240 | #if !HAVE_WEBKIT2 | ||
2987 | 8241 | return false; | ||
2988 | 8242 | #endif | ||
2989 | 8243 | } | ||
2990 | 8244 | |||
2991 | 8245 | bool view_download_requested_cb (Gtk.Widget widget, WebKit.Download download) { | ||
2992 | 8246 | var view = (View) widget; | ||
2993 | 8247 | var type = Download.get_type (download); | ||
2994 | 8248 | var handled = true; | ||
2995 | 8249 | |||
2996 | 8250 | return_val_if_fail (view != null, false); | ||
2997 | 8251 | |||
2998 | 8252 | if (type == DownloadType.CANCEL) { | ||
2999 | 8253 | handled = false; | ||
3000 | 8254 | } | ||
3001 | 8255 | #if HAVE_WEBKIT2 | ||
3002 | 8256 | else if (download.destination == null) { | ||
3003 | 8257 | #else | ||
3004 | 8258 | else if (download.destination_uri == null) { | ||
3005 | 8259 | #endif | ||
3006 | 8260 | if (type == DownloadType.SAVE_AS) { | ||
3007 | 8261 | #if HAVE_WEBKIT2 | ||
3008 | 8262 | var download_uri = download.get_response (download).uri; | ||
3009 | 8263 | #else | ||
3010 | 8264 | var download_uri = download.get_uri (); | ||
3011 | 8265 | #endif | ||
3012 | 8266 | var dialog = new FileChooserDialog (_("Save file"), this, Gtk.FileChooserAction.SAVE); | ||
3013 | 8267 | dialog.do_overwrite_confirmation = true; | ||
3014 | 8268 | dialog.destroy_with_parent = true; | ||
3015 | 8269 | var folder = URI.get_folder (download_uri); | ||
3016 | 8270 | if (folder == null) | ||
3017 | 8271 | folder = settings.download_folder; | ||
3018 | 8272 | dialog.set_current_folder (folder); | ||
3019 | 8273 | |||
3020 | 8274 | var filename = Download.get_suggested_filename (download); | ||
3021 | 8275 | dialog.set_current_name (filename); | ||
3022 | 8276 | |||
3023 | 8277 | if (Dialog.run (dialog) == Gtk.ResponseType.OK) { | ||
3024 | 8278 | dialog.hide (); | ||
3025 | 8279 | var uri = dialog.get_uri (); | ||
3026 | 8280 | if (!prepare_download (download, uri)) { | ||
3027 | 8281 | return false; | ||
3028 | 8282 | } | ||
3029 | 8283 | } else { | ||
3030 | 8284 | dialog.hide (); | ||
3031 | 8285 | return false; | ||
3032 | 8286 | } | ||
3033 | 8287 | } else { | ||
3034 | 8288 | var folder = type == DownloadType.OPEN ? null : settings.download_folder; | ||
3035 | 8289 | var destination_uri = Download.prepare_destination_uri (download, folder); | ||
3036 | 8290 | prepare_download (download, destination_uri); | ||
3037 | 8291 | } | ||
3038 | 8292 | #if !HAVE_WEBKIT2 | ||
3039 | 8293 | download.start (); | ||
3040 | 8294 | #endif | ||
3041 | 8295 | } | ||
3042 | 8296 | |||
3043 | 8297 | /* Close empty tabs due to download links with a target */ | ||
3044 | 8298 | if (view.is_blank ()) { | ||
3045 | 8299 | var web_view = view.web_view; | ||
3046 | 8300 | #if HAVE_WEBKIT2 | ||
3047 | 8301 | var resource = web_view.get_main_resource (); | ||
3048 | 8302 | resource.get_data.begin (null, (obj, res) => close_tab_idle (obj, res, view)); | ||
3049 | 8303 | #else | ||
3050 | 8304 | var web_frame = web_view.get_main_frame (); | ||
3051 | 8305 | var datasource = web_frame.get_data_source (); | ||
3052 | 8306 | if (datasource.get_data () == null) | ||
3053 | 8307 | Idle.add (() => close_tab_idle (view)); | ||
3054 | 8308 | #endif | ||
3055 | 8309 | } | ||
3056 | 8310 | return handled; | ||
3057 | 8311 | } | ||
3058 | 8312 | |||
3059 | 8313 | #if HAVE_WEBKIT2 | ||
3060 | 8314 | void download_created_destination_cb (WebKit.Download download, string destination) { | ||
3061 | 8315 | print ("%s: destination %s", "download created", destination); | ||
3062 | 8316 | } | ||
3063 | 8317 | #endif | ||
3064 | 8318 | |||
3065 | 8319 | void view_search_text_cb (Gtk.Widget view, bool found, string typing) { | ||
3066 | 8320 | find.search_text (view, found, typing); | ||
3067 | 8321 | } | ||
3068 | 8322 | |||
3069 | 8323 | public int get_n_pages () { | ||
3070 | 8324 | return (int) notebook.count; | ||
3071 | 8325 | } | ||
3072 | 8326 | |||
3073 | 8327 | void connect_tab (Gtk.Widget widget) { | ||
3074 | 8328 | var view = (View) widget; | ||
3075 | 8329 | var item = ((View) view).get_proxy_item (); | ||
3076 | 8330 | proxy_array.add_item (item); | ||
3077 | 8331 | |||
3078 | 8332 | view.notify["icon"].connect (view_notify_icon_cb); | ||
3079 | 8333 | view.notify["load-status"].connect (view_notify_load_status_cb); | ||
3080 | 8334 | view.notify["progress"].connect (view_notify_progress_cb); | ||
3081 | 8335 | view.notify["uri"].connect (view_notify_uri_cb); | ||
3082 | 8336 | view.notify["title"].connect (view_notify_title_cb); | ||
3083 | 8337 | view.notify["zoom-level"].connect (view_notify_zoom_level_cb); | ||
3084 | 8338 | view.notify["statusbar-text"].connect (view_notify_statusbar_text_cb); | ||
3085 | 8339 | view.attach_inspector.connect (view_attach_inspector_cb); | ||
3086 | 8340 | view.detach_inspector.connect (view_detach_inspector_cb); | ||
3087 | 8341 | view.new_tab.connect (view_new_tab_cb); | ||
3088 | 8342 | view.new_window.connect (view_new_window_cb); | ||
3089 | 8343 | view.new_view.connect (view_new_view_cb); | ||
3090 | 8344 | view.download_requested.connect_after (view_download_requested_cb); | ||
3091 | 8345 | ((Tab) view).search_text.connect (view_search_text_cb); | ||
3092 | 8346 | view.leave_notify_event.connect (tab_leave_notify_event_cb); | ||
3093 | 8347 | view.destroy.connect (view_destroy_cb); | ||
3094 | 8348 | } | ||
3095 | 8349 | |||
3096 | 8350 | void disconnect_tab (View view) { | ||
3097 | 8351 | var item = view.get_proxy_item (); | ||
3098 | 8352 | proxy_array.remove_item (item); | ||
3099 | 8353 | |||
3100 | 8354 | /* We don't ever want to be in a situation with no tabs, | ||
3101 | 8355 | so just create an empty one if the last one is closed. | ||
3102 | 8356 | The only exception is when we are closing the window, | ||
3103 | 8357 | which is indicated by the proxy array having been unset. */ | ||
3104 | 8358 | if (proxy_array.is_empty ()) { | ||
3105 | 8359 | add_uri ("about:new"); | ||
3106 | 8360 | set_current_page (0); | ||
3107 | 8361 | } | ||
3108 | 8362 | |||
3109 | 8363 | update_actions (); | ||
3110 | 8364 | |||
3111 | 8365 | view.notify["icon"].disconnect (view_notify_icon_cb); | ||
3112 | 8366 | view.notify["load-status"].disconnect (view_notify_load_status_cb); | ||
3113 | 8367 | view.notify["progress"].disconnect (view_notify_progress_cb); | ||
3114 | 8368 | view.notify["uri"].disconnect (view_notify_uri_cb); | ||
3115 | 8369 | view.notify["title"].disconnect (view_notify_title_cb); | ||
3116 | 8370 | view.notify["zoom-level"].disconnect (view_notify_zoom_level_cb); | ||
3117 | 8371 | view.notify["statusbar-text"].disconnect (view_notify_statusbar_text_cb); | ||
3118 | 8372 | view.attach_inspector.disconnect (view_attach_inspector_cb); | ||
3119 | 8373 | view.detach_inspector.disconnect (view_detach_inspector_cb); | ||
3120 | 8374 | view.new_tab.disconnect (view_new_tab_cb); | ||
3121 | 8375 | view.new_window.disconnect (view_new_window_cb); | ||
3122 | 8376 | view.new_view.disconnect (view_new_view_cb); | ||
3123 | 8377 | view.download_requested.disconnect (view_download_requested_cb); | ||
3124 | 8378 | ((Tab) view).search_text.disconnect (view_search_text_cb); | ||
3125 | 8379 | view.leave_notify_event.disconnect (tab_leave_notify_event_cb); | ||
3126 | 8380 | view.destroy.disconnect (view_destroy_cb); | ||
3127 | 8381 | } | ||
3128 | 8382 | |||
3129 | 8383 | void update_tooltip_if_changed (Gtk.Action action, string text) { | ||
3130 | 8384 | if (action.tooltip != text) | ||
3131 | 8385 | action.tooltip = text; | ||
3132 | 8386 | } | ||
3133 | 8387 | |||
3134 | 8388 | void update_reload_tooltip (Gdk.EventKey event, bool released) { | ||
3135 | 8389 | /* Update the reload/stop tooltip in case we are holding the hard refresh modifiers*/ | ||
3136 | 8390 | var reload_stop = action_group.get_action ("ReloadStop"); | ||
3137 | 8391 | var reload = action_group.get_action ("Reload"); | ||
3138 | 8392 | |||
3139 | 8393 | // TODO var device = Gdk.Display.get_default ().get_device_manager ().get_client_pointer (); | ||
3140 | 8394 | Gdk.ModifierType mask; | ||
3141 | 8395 | get_window ().get_device_position (((Gdk.Event) event).get_device (), null, null, out mask); | ||
3142 | 8396 | |||
3143 | 8397 | string target; | ||
3144 | 7590 | 8398 | ||
3147 | 7591 | g_list_free (top_levels); | 8399 | if ((mask & Gdk.ModifierType.SHIFT_MASK) != 0) |
3148 | 7592 | return NULL; | 8400 | target = _("Reload page without caching"); |
3149 | 8401 | else | ||
3150 | 8402 | target = _("Reload the current page"); | ||
3151 | 8403 | |||
3152 | 8404 | update_tooltip_if_changed (reload_stop, target); | ||
3153 | 8405 | update_tooltip_if_changed (reload, target); | ||
3154 | 8406 | } | ||
3155 | 8407 | |||
3156 | 8408 | public override bool key_release_event (Gdk.EventKey event) { | ||
3157 | 8409 | update_reload_tooltip (event, true); | ||
3158 | 8410 | return false; | ||
3159 | 8411 | } | ||
3160 | 8412 | |||
3161 | 8413 | public override bool key_press_event (Gdk.EventKey event) { | ||
3162 | 8414 | update_reload_tooltip (event, false); | ||
3163 | 8415 | |||
3164 | 8416 | /* Interpret Ctrl(+Shift)+Tab as tab switching for compatibility */ | ||
3165 | 8417 | if (get_nth_tab (1) != null | ||
3166 | 8418 | && event.keyval == Gdk.Key.Tab | ||
3167 | 8419 | && (event.state & Gdk.ModifierType.CONTROL_MASK) != 0) { | ||
3168 | 8420 | activate_action ("TabNext"); | ||
3169 | 8421 | return true; | ||
3170 | 8422 | } else if (event.keyval == Gdk.Key.ISO_Left_Tab | ||
3171 | 8423 | && (event.state & Gdk.ModifierType.CONTROL_MASK) != 0 | ||
3172 | 8424 | && (event.state & Gdk.ModifierType.SHIFT_MASK) != 0) { | ||
3173 | 8425 | activate_action ("TabPrevious"); | ||
3174 | 8426 | return true; | ||
3175 | 8427 | } | ||
3176 | 8428 | /* Interpret Ctrl+= as Zoom In for compatibility */ | ||
3177 | 8429 | else if ((event.keyval == Gdk.Key.KP_Equal || event.keyval == Gdk.Key.equal) | ||
3178 | 8430 | && (event.state & Gdk.ModifierType.CONTROL_MASK) != 0) { | ||
3179 | 8431 | activate_action ("ZoomIn"); | ||
3180 | 8432 | return true; | ||
3181 | 8433 | } | ||
3182 | 8434 | /* Interpret F5 as reloading for compatibility */ | ||
3183 | 8435 | else if (event.keyval == Gdk.Key.F5) { | ||
3184 | 8436 | activate_action ("Reload"); | ||
3185 | 8437 | return true; | ||
3186 | 8438 | } | ||
3187 | 8439 | |||
3188 | 8440 | #if !HAVE_WEBKIT2 | ||
3189 | 8441 | var focus = get_focus (); | ||
3190 | 8442 | if (focus == null) | ||
3191 | 8443 | get_current_tab ().grab_focus (); | ||
3192 | 8444 | else if (focus is WebKit.WebView | ||
3193 | 8445 | && event.keyval == Gdk.Key.space | ||
3194 | 8446 | && ((event.state & Gdk.ModifierType.SHIFT_MASK) == 0) | ||
3195 | 8447 | && !((WebKit.WebView) focus).can_cut_clipboard () | ||
3196 | 8448 | && !((WebKit.WebView) focus).can_paste_clipboard ()) { | ||
3197 | 8449 | /* Space at the bottom of the page: Go to next page */ | ||
3198 | 8450 | var view = View.get_for_widget (focus); | ||
3199 | 8451 | var scrolled = (Gtk.ScrolledWindow) focus.get_parent (); | ||
3200 | 8452 | var vadjust = scrolled.get_vadjustment (); | ||
3201 | 8453 | if (vadjust.value == vadjust.upper - vadjust.page_size) { | ||
3202 | 8454 | var uri = view.get_next_page (); | ||
3203 | 8455 | if (uri != null) { | ||
3204 | 8456 | view.set_uri (uri); | ||
3205 | 8457 | return true; | ||
3206 | 8458 | } | ||
3207 | 8459 | } | ||
3208 | 8460 | } | ||
3209 | 8461 | #endif | ||
3210 | 8462 | |||
3211 | 8463 | if ((event.state & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.MOD1_MASK)) != 0) | ||
3212 | 8464 | if (Sokoke.window_activate_key (this, event)) | ||
3213 | 8465 | return true; | ||
3214 | 8466 | |||
3215 | 8467 | var clean_state = event.state & Gtk.accelerator_get_default_mod_mask (); | ||
3216 | 8468 | if (clean_state == 0 && propagate_key_event (event)) | ||
3217 | 8469 | return true; | ||
3218 | 8470 | |||
3219 | 8471 | if ((event.state & (Gdk.ModifierType.CONTROL_MASK | Gdk.ModifierType.MOD1_MASK)) == 0) | ||
3220 | 8472 | if (Sokoke.window_activate_key (this, event)) | ||
3221 | 8473 | return true; | ||
3222 | 8474 | |||
3223 | 8475 | if (event.state != 0 && propagate_key_event (event)) | ||
3224 | 8476 | return true; | ||
3225 | 8477 | |||
3226 | 8478 | /* Interpret (Shift+)Backspace as going back (forward) for compatibility */ | ||
3227 | 8479 | if ((event.keyval == Gdk.Key.BackSpace) | ||
3228 | 8480 | && (event.state & Gdk.ModifierType.SHIFT_MASK) != 0) { | ||
3229 | 8481 | activate_action ("Forward"); | ||
3230 | 8482 | return true; | ||
3231 | 8483 | } else if (event.keyval == Gdk.Key.BackSpace) { | ||
3232 | 8484 | activate_action ("Back"); | ||
3233 | 8485 | return true; | ||
3234 | 8486 | } | ||
3235 | 8487 | |||
3236 | 8488 | return base.key_press_event (event); | ||
3237 | 8489 | } | ||
3238 | 8490 | |||
3239 | 8491 | void action_window_new_activate (Gtk.Action action) { | ||
3240 | 8492 | view_new_window_cb (null, "about:home"); | ||
3241 | 8493 | } | ||
3242 | 8494 | |||
3243 | 8495 | void action_tab_new_activate (Gtk.Action action) { | ||
3244 | 8496 | var view = add_uri ("about:new"); | ||
3245 | 8497 | set_current_tab (view); | ||
3246 | 8498 | } | ||
3247 | 8499 | |||
3248 | 8500 | void action_private_browsing_activate (Gtk.Action action) { | ||
3249 | 8501 | Sokoke.spawn_app ("about:private", true); | ||
3250 | 8502 | } | ||
3251 | 8503 | |||
3252 | 8504 | #if !GTK_VERSION_3_1_10 | ||
3253 | 8505 | string? action_open_last_dir = null; | ||
3254 | 8506 | #endif | ||
3255 | 8507 | |||
3256 | 8508 | void action_open_activate (Gtk.Action action) { | ||
3257 | 8509 | #if !GTK_VERSION_3_1_10 | ||
3258 | 8510 | var folder_set = false; | ||
3259 | 8511 | #endif | ||
3260 | 8512 | string? uri = null; | ||
3261 | 8513 | |||
3262 | 8514 | var dialog = new FileChooserDialog (_("Open file"), this, Gtk.FileChooserAction.OPEN); | ||
3263 | 8515 | |||
3264 | 8516 | /* base the start folder on the current view's uri if it is local */ | ||
3265 | 8517 | var view = get_current_tab (); | ||
3266 | 8518 | if ((uri = ((View) view).get_display_uri ()) != null) { | ||
3267 | 8519 | try { | ||
3268 | 8520 | var filename = Filename.from_uri (uri, null); | ||
3269 | 8521 | var dirname = Path.get_dirname (filename); | ||
3270 | 8522 | if (dirname != null && FileUtils.test (dirname, FileTest.IS_DIR)) { | ||
3271 | 8523 | dialog.set_current_folder (dirname); | ||
3272 | 8524 | #if !GTK_VERSION_3_1_10 | ||
3273 | 8525 | folder_set = true; | ||
3274 | 8526 | #endif | ||
3275 | 8527 | } | ||
3276 | 8528 | } catch (Error e) {} | ||
3277 | 8529 | } | ||
3278 | 8530 | |||
3279 | 8531 | #if !GTK_VERSION_3_1_10 | ||
3280 | 8532 | if (!folder_set && action_open_last_dir != null && action_open_last_dir != "") | ||
3281 | 8533 | dialog.set_current_folder (action_open_last_dir); | ||
3282 | 8534 | #endif | ||
3283 | 8535 | |||
3284 | 8536 | if (Dialog.run (dialog) == Gtk.ResponseType.OK) { | ||
3285 | 8537 | #if !GTK_VERSION_3_1_10 | ||
3286 | 8538 | action_open_last_dir = dialog.get_current_folder (); | ||
3287 | 8539 | #endif | ||
3288 | 8540 | uri = dialog.get_uri (); | ||
3289 | 8541 | set_current_uri (uri); | ||
3290 | 8542 | |||
3291 | 8543 | } | ||
3292 | 8544 | |||
3293 | 8545 | dialog.destroy (); | ||
3294 | 8546 | } | ||
3295 | 8547 | |||
3296 | 8548 | void action_save_as_activate (Gtk.Action action) { | ||
3297 | 8549 | save_uri ((View) get_current_tab (), null); | ||
3298 | 8550 | } | ||
3299 | 8551 | |||
3300 | 8552 | void action_add_speed_dial_activate (Gtk.Action action) { | ||
3301 | 8553 | add_speed_dial (); | ||
3302 | 8554 | } | ||
3303 | 8555 | |||
3304 | 8556 | void subscribe_to_news_feed (string uri) { | ||
3305 | 8557 | var news_aggregator = settings.news_aggregator; | ||
3306 | 8558 | if (news_aggregator != null && news_aggregator != "") { | ||
3307 | 8559 | /* Thunderbird only accepts feed://, Liferea doesn't mind */ | ||
3308 | 8560 | var feed = uri; | ||
3309 | 8561 | if (feed.has_prefix ("http://")) | ||
3310 | 8562 | feed = "feed" + feed.substring (4); | ||
3311 | 8563 | /* Special-case Liferea because a helper script may be required */ | ||
3312 | 8564 | if (news_aggregator == "liferea" | ||
3313 | 8565 | && Environment.find_program_in_path ("liferea-add-feed") != null) | ||
3314 | 8566 | Sokoke.spawn_program ("liferea-add-feed", false, feed, true, false); | ||
3315 | 8567 | else | ||
3316 | 8568 | Sokoke.spawn_program (news_aggregator, true, feed, true, false); | ||
3317 | 8569 | } else { | ||
3318 | 8570 | var description = "%s\n\n%s".printf (uri, | ||
3319 | 8571 | _("To use the above URI open a news aggregator. " + | ||
3320 | 8572 | "There is usually a menu or button \"New Subscription\", " + | ||
3321 | 8573 | "\"New News Feed\" or similar.\n" + | ||
3322 | 8574 | "Alternatively go to Preferences, Applications in Midori, " + | ||
3323 | 8575 | "and select a News Aggregator. Next time you click the " + | ||
3324 | 8576 | "news feed icon, it will be added automatically.")); | ||
3325 | 8577 | Sokoke.message_dialog (Gtk.MessageType.INFO, _("New feed"), description, false); | ||
3326 | 8578 | } | ||
3327 | 8579 | } | ||
3328 | 8580 | |||
3329 | 8581 | void action_add_news_feed_activate (Gtk.Action action) { | ||
3330 | 8582 | Gtk.Widget? view = null; | ||
3331 | 8583 | string? uri = null; | ||
3332 | 8584 | |||
3333 | 8585 | if ((view = get_current_tab ()) == null) | ||
3334 | 8586 | return; | ||
3335 | 8587 | if ((uri = view.get_data<string> ("news-feeds")) == null) | ||
3336 | 8588 | return; | ||
3337 | 8589 | |||
3338 | 8590 | subscribe_to_news_feed (uri); | ||
3339 | 8591 | } | ||
3340 | 8592 | |||
3341 | 8593 | void action_compact_add_activate (Gtk.Action action) { | ||
3342 | 8594 | string[] actions = { "BookmarkAdd", "AddSpeedDial", "AddNewsFeed" }; | ||
3343 | 8595 | |||
3344 | 8596 | var dialog = new Gtk.Dialog (); | ||
3345 | 8597 | dialog.transient_for = this; | ||
3346 | 8598 | dialog.title = _("Add a new bookmark"); | ||
3347 | 8599 | var box = dialog.get_content_area (); | ||
3348 | 8600 | |||
3349 | 8601 | for (var i = 0; i < actions.length; i++) { | ||
3350 | 8602 | action = action_group.get_action (actions[i]); | ||
3351 | 8603 | var button = new Gtk.Button.with_mnemonic (action.label); | ||
3352 | 8604 | button.name = "GtkButton-thumb"; | ||
3353 | 8605 | box.pack_start (button, true, true, 4); | ||
3354 | 8606 | button.related_action = action; | ||
3355 | 8607 | button.clicked.connect ((dlg) => dlg.destroy ()); | ||
3356 | 8608 | } | ||
3357 | 8609 | |||
3358 | 8610 | dialog.show (); | ||
3359 | 8611 | dialog.response.connect ((dlg, response) => dlg.destroy ()); | ||
3360 | 8612 | } | ||
3361 | 8613 | |||
3362 | 8614 | void action_tab_close_activate (Gtk.Action action) { | ||
3363 | 8615 | close_tab (get_current_tab ()); | ||
3364 | 8616 | } | ||
3365 | 8617 | |||
3366 | 8618 | void action_window_close_activate (Gtk.Action action) { | ||
3367 | 8619 | if (!delete_event ((Gdk.EventAny) Gtk.get_current_event ())) | ||
3368 | 8620 | destroy (); | ||
3369 | 8621 | } | ||
3370 | 8622 | |||
3371 | 8623 | void action_mail_to_activate (Gtk.Action action) { | ||
3372 | 8624 | var view = (View) get_current_tab (); | ||
3373 | 8625 | var uri = Uri.escape_string (view.get_display_uri (), null, true); | ||
3374 | 8626 | var title = Uri.escape_string (view.get_display_title (), null, true); | ||
3375 | 8627 | view.open_uri ("mailto:?cc=&bcc=&subject=" + title + "&body=" + uri); | ||
3376 | 8628 | } | ||
3377 | 8629 | |||
3378 | 8630 | void action_print_activate (Gtk.Action action) { | ||
3379 | 8631 | ((View) get_current_tab ()).print (); | ||
3380 | 8632 | } | ||
3381 | 8633 | |||
3382 | 8634 | void action_quit_activate (Gtk.Action action) { | ||
3383 | 8635 | quit (); | ||
3384 | 8636 | } | ||
3385 | 8637 | |||
3386 | 8638 | void action_edit_activate (Gtk.Action action) { | ||
3387 | 8639 | var widget = get_focus (); | ||
3388 | 8640 | bool can_undo = false, can_redo = false, | ||
3389 | 8641 | can_cut = false, can_copy = false, can_paste = false, | ||
3390 | 8642 | has_selection, can_select_all = false; | ||
3391 | 8643 | |||
3392 | 8644 | if (widget is WebKit.WebView) { | ||
3393 | 8645 | get_current_tab ().update_actions.begin (action_group); | ||
3394 | 8646 | return; | ||
3395 | 8647 | } else if (widget is Gtk.Editable) { | ||
3396 | 8648 | // TODO check is casting to GtkEntry is ok | ||
3397 | 8649 | var editable = (Gtk.Entry) widget; | ||
3398 | 8650 | has_selection = editable.get_selection_bounds (null, null); | ||
3399 | 8651 | can_cut = has_selection && editable.get_editable (); | ||
3400 | 8652 | can_copy = has_selection; | ||
3401 | 8653 | can_paste = editable.get_editable (); | ||
3402 | 8654 | can_select_all = true; | ||
3403 | 8655 | } else if (widget is Gtk.TextView) { | ||
3404 | 8656 | var text_view = (Gtk.TextView) widget; | ||
3405 | 8657 | has_selection = text_view.buffer.has_selection; | ||
3406 | 8658 | can_cut = text_view.editable; | ||
3407 | 8659 | can_copy = has_selection; | ||
3408 | 8660 | can_paste = text_view.editable && has_selection; | ||
3409 | 8661 | can_select_all = true; | ||
3410 | 8662 | } | ||
3411 | 8663 | |||
3412 | 8664 | action_set_sensitive ("Undo", can_undo); | ||
3413 | 8665 | action_set_sensitive ("Redo", can_redo); | ||
3414 | 8666 | action_set_sensitive ("Cut", can_cut); | ||
3415 | 8667 | action_set_sensitive ("Copy", can_copy); | ||
3416 | 8668 | action_set_sensitive ("Paste", can_paste); | ||
3417 | 8669 | action_set_sensitive ("Delete", can_cut); | ||
3418 | 8670 | action_set_sensitive ("SelectAll", can_select_all); | ||
3419 | 8671 | } | ||
3420 | 8672 | |||
3421 | 8673 | void action_undo_activate (Gtk.Action action) { | ||
3422 | 8674 | var web_view = get_focus () as WebKit.WebView; | ||
3423 | 8675 | if (web_view == null) | ||
3424 | 8676 | return; | ||
3425 | 8677 | |||
3426 | 8678 | #if HAVE_WEBKIT2 | ||
3427 | 8679 | web_view.execute_editing_command (WebKit.EditingCommand.UNDO); | ||
3428 | 8680 | #else | ||
3429 | 8681 | web_view.undo (); | ||
3430 | 8682 | #endif | ||
3431 | 8683 | } | ||
3432 | 8684 | |||
3433 | 8685 | void action_redo_activate (Gtk.Action action) { | ||
3434 | 8686 | var web_view = get_focus () as WebKit.WebView; | ||
3435 | 8687 | if (web_view == null) | ||
3436 | 8688 | return; | ||
3437 | 8689 | |||
3438 | 8690 | #if HAVE_WEBKIT2 | ||
3439 | 8691 | web_view.execute_editing_command (WebKit.EditingCommand.REDO); | ||
3440 | 8692 | #else | ||
3441 | 8693 | web_view.redo (); | ||
3442 | 8694 | #endif | ||
3443 | 8695 | } | ||
3444 | 8696 | |||
3445 | 8697 | void action_cut_activate (Gtk.Action action) { | ||
3446 | 8698 | var widget = get_focus (); | ||
3447 | 8699 | if (likely (widget != null) && Signal.lookup ("cut-clipboard", widget.get_type ()) != 0) | ||
3448 | 8700 | Signal.emit_by_name (widget, "cut-clipboard"); | ||
3449 | 8701 | #if HAVE_WEBKIT2 | ||
3450 | 8702 | else if (widget is WebKit.WebView) | ||
3451 | 8703 | ((WebKit.WebView) widget).execute_editing_command (WebKit.EditingCommand.CUT); | ||
3452 | 8704 | #endif | ||
3453 | 8705 | } | ||
3454 | 8706 | |||
3455 | 8707 | void action_copy_activate (Gtk.Action action) { | ||
3456 | 8708 | var widget = get_focus (); | ||
3457 | 8709 | if (likely (widget != null) && Signal.lookup ("copy-clipboard", widget.get_type ()) != 0) | ||
3458 | 8710 | Signal.emit_by_name (widget, "copy-clipboard"); | ||
3459 | 8711 | #if HAVE_WEBKIT2 | ||
3460 | 8712 | else if (widget is WebKit.WebView) | ||
3461 | 8713 | ((WebKit.WebView) view).execute_editing_command (WebKit.EditingCommand.COPY); | ||
3462 | 8714 | #endif | ||
3463 | 8715 | } | ||
3464 | 8716 | |||
3465 | 8717 | void action_paste_activate (Gtk.Action action) { | ||
3466 | 8718 | var widget = get_focus (); | ||
3467 | 8719 | if (likely (widget != null) && Signal.lookup ("paste-clipboard", widget.get_type ()) != 0) | ||
3468 | 8720 | Signal.emit_by_name (widget, "paste-clipboard"); | ||
3469 | 8721 | #if HAVE_WEBKIT2 | ||
3470 | 8722 | else if (widget is WebKit.WebView) | ||
3471 | 8723 | ((WebKit.WebView) view).execute_editing_command (WebKit.EditingCommand.PASTE); | ||
3472 | 8724 | #endif | ||
3473 | 8725 | } | ||
3474 | 8726 | |||
3475 | 8727 | void action_delete_activate (Gtk.Action action) { | ||
3476 | 8728 | var widget = get_focus (); | ||
3477 | 8729 | if (likely (widget != null)) { | ||
3478 | 8730 | if (widget is Gtk.Editable) | ||
3479 | 8731 | ((Gtk.Editable) widget).delete_selection (); | ||
3480 | 8732 | #if !HAVE_WEBKIT2 | ||
3481 | 8733 | else if (widget is WebKit.WebView) | ||
3482 | 8734 | ((WebKit.WebView) widget).delete_selection (); | ||
3483 | 8735 | #endif | ||
3484 | 8736 | else if (widget is Gtk.TextView) | ||
3485 | 8737 | ((Gtk.TextView) widget).buffer.delete_selection (true, false); | ||
3486 | 8738 | } | ||
3487 | 8739 | } | ||
3488 | 8740 | |||
3489 | 8741 | void action_select_all_activate (Gtk.Action action) { | ||
3490 | 8742 | var widget = get_focus (); | ||
3491 | 8743 | if (likely (widget != null)) { | ||
3492 | 8744 | if (widget is Gtk.Editable) | ||
3493 | 8745 | ((Gtk.Editable) widget).select_region (0, -1); | ||
3494 | 8746 | #if HAVE_WEBKIT2 | ||
3495 | 8747 | else if (widget is WebKit.WebView) | ||
3496 | 8748 | ((WebKit.WebView) widget).execute_editing_command (WebKit.EditingCommand.SELECT_ALL); | ||
3497 | 8749 | #endif | ||
3498 | 8750 | else if (Signal.lookup ("select-all", widget.get_type ()) != 0) { | ||
3499 | 8751 | if (widget is Gtk.TextView) | ||
3500 | 8752 | ((Gtk.TextView) widget).select_all (true); | ||
3501 | 8753 | else if (widget is Gtk.TreeView) | ||
3502 | 8754 | ((Gtk.TreeView) widget).select_all (); | ||
3503 | 8755 | else | ||
3504 | 8756 | Signal.emit_by_name (widget, "select-all"); | ||
3505 | 8757 | } | ||
3506 | 8758 | } | ||
3507 | 8759 | } | ||
3508 | 8760 | |||
3509 | 8761 | void action_find_activate (Gtk.Action action) { | ||
3510 | 8762 | find.invoke (((View) get_current_tab ()).get_selected_text ()); | ||
3511 | 8763 | } | ||
3512 | 8764 | |||
3513 | 8765 | void action_find_next_activate (Gtk.Action action) { | ||
3514 | 8766 | find.@continue (true); | ||
3515 | 8767 | } | ||
3516 | 8768 | |||
3517 | 8769 | void action_find_previous_activate (Gtk.Action action) { | ||
3518 | 8770 | find.@continue (false); | ||
3519 | 8771 | } | ||
3520 | 8772 | |||
3521 | 8773 | #if !HAVE_GRANITE | ||
3522 | 8774 | void navigationbar_notify_style_cb (Object object, ParamSpec pspec) { | ||
3523 | 8775 | set_toolbar_style (settings.toolbar_style); | ||
3524 | 8776 | } | ||
3525 | 8777 | #endif | ||
3526 | 8778 | |||
3527 | 8779 | static string[] actions = { | ||
3528 | 8780 | "WindowNew", "TabNew", "Open", "SaveAs", "Print", "Find", | ||
3529 | 8781 | "Fullscreen", "Preferences", "Window", "Bookmarks", | ||
3530 | 8782 | "ReloadStop", "ZoomIn", "TabClose", "NextForward", "Location", | ||
3531 | 8783 | "ZoomOut", "Separator", "Back", "Forward", "Homepage", | ||
3532 | 8784 | "Panel", "Trash", "Search", "BookmarkAdd", "Previous", "Next" }; | ||
3533 | 8785 | |||
3534 | 8786 | /** | ||
3535 | 8787 | * midori_browser_get_toolbar_actions: | ||
3536 | 8788 | * | ||
3537 | 8789 | * Retrieves a list of actions which are suitable for use in a toolbar. | ||
3538 | 8790 | * | ||
3539 | 8791 | * Return value: a null-terminated array of strings with actions | ||
3540 | 8792 | * | ||
3541 | 8793 | * Since: 0.1.8 | ||
3542 | 8794 | **/ | ||
3543 | 8795 | public unowned string[] get_toolbar_actions () { | ||
3544 | 8796 | return actions; | ||
3545 | 8797 | } | ||
3546 | 8798 | |||
3547 | 8799 | bool toolbar_popup_context_menu_cb (Gtk.Widget widget, int x, int y, int button) { | ||
3548 | 8800 | var menu = new ContextAction ("ToolbarContextMenu", null, null, null); | ||
3549 | 8801 | menu.add_action_group (action_group); | ||
3550 | 8802 | menu.add_by_name ("Menubar"); | ||
3551 | 8803 | menu.add_by_name ("Navigationbar"); | ||
3552 | 8804 | menu.add_by_name ("Bookmarkbar"); | ||
3553 | 8805 | menu.add_by_name ("Statusbar"); | ||
3554 | 8806 | |||
3555 | 8807 | var context_menu = menu.create_menu (null, false); | ||
3556 | 8808 | populate_toolbar_menu (context_menu); | ||
3557 | 8809 | Katze.widget_popup (widget, context_menu, null, button == -1 ? Katze.MenuPos.LEFT : Katze.MenuPos.CURSOR); | ||
3558 | 8810 | return true; | ||
3559 | 8811 | } | ||
3560 | 8812 | |||
3561 | 8813 | void bookmarkbar_activate_item (Katze.ArrayAction action, Katze.Item item) { | ||
3562 | 8814 | open_bookmark (item); | ||
3563 | 8815 | } | ||
3564 | 8816 | |||
3565 | 8817 | bool bookmarkbar_activate_item_alt (Katze.ArrayAction action, Katze.Item item, Gtk.Widget proxy, Gdk.EventButton event) { | ||
3566 | 8818 | assert (event != null); | ||
3567 | 8819 | |||
3568 | 8820 | if (event_new_tab (event)) { | ||
3569 | 8821 | var view = add_item (item); | ||
3570 | 8822 | set_current_tab_smartly (view); | ||
3571 | 8823 | } else if (event_context_menu (event)) { | ||
3572 | 8824 | bookmark_popup (proxy, null, item); | ||
3573 | 8825 | } else if (event.button == 1) { | ||
3574 | 8826 | bookmarkbar_activate_item (action, item); | ||
3575 | 8827 | } | ||
3576 | 8828 | |||
3577 | 8829 | return true; | ||
3578 | 8830 | } | ||
3579 | 8831 | |||
3580 | 8832 | void action_trash_populate_popup (Gtk.Action action, Gtk.Menu menu) { | ||
3581 | 8833 | Gtk.MenuItem menuitem; | ||
3582 | 8834 | |||
3583 | 8835 | menuitem = new Gtk.SeparatorMenuItem (); | ||
3584 | 8836 | menu.append (menuitem); | ||
3585 | 8837 | menuitem.show (); | ||
3586 | 8838 | |||
3587 | 8839 | menuitem = (Gtk.MenuItem) action_group.get_action ("TrashEmpty").create_menu_item (); | ||
3588 | 8840 | menu.append (menuitem); | ||
3589 | 8841 | menuitem.show (); | ||
3590 | 8842 | } | ||
3591 | 8843 | |||
3592 | 8844 | Gtk.Widget restore_tab (Katze.Item item) { | ||
3593 | 8845 | item.@ref (); | ||
3594 | 8846 | trash.remove_item (item); | ||
3595 | 8847 | var view = add_item (item); | ||
3596 | 8848 | item.unref (); | ||
3597 | 8849 | |||
3598 | 8850 | return view; | ||
3599 | 8851 | } | ||
3600 | 8852 | |||
3601 | 8853 | bool action_trash_activate_item_alt (Gtk.Action action, Katze.Item item, Gtk.Widget proxy, Gdk.EventButton event) { | ||
3602 | 8854 | assert (event != null); | ||
3603 | 8855 | |||
3604 | 8856 | if (event_new_tab (event)) | ||
3605 | 8857 | set_current_tab_smartly (restore_tab (item)); | ||
3606 | 8858 | else if (event.button == 1) | ||
3607 | 8859 | set_current_tab (restore_tab (item)); | ||
3608 | 8860 | |||
3609 | 8861 | return true; | ||
3610 | 8862 | } | ||
3611 | 8863 | |||
3612 | 8864 | internal bool open_bookmark (Katze.Item item) { | ||
3613 | 8865 | var uri = item.uri; | ||
3614 | 8866 | |||
3615 | 8867 | if (uri == null || uri == "") | ||
3616 | 8868 | return false; | ||
3617 | 8869 | |||
3618 | 8870 | /* Imported bookmarks may lack a protocol */ | ||
3619 | 8871 | var uri_fixed = Sokoke.magic_uri (uri, true, false); | ||
3620 | 8872 | if (uri_fixed == null) | ||
3621 | 8873 | uri_fixed = uri; | ||
3622 | 8874 | |||
3623 | 8875 | if (item.get_meta_boolean ("app")) | ||
3624 | 8876 | Sokoke.spawn_app (uri_fixed, false); | ||
3625 | 8877 | else { | ||
3626 | 8878 | set_current_uri (uri_fixed); | ||
3627 | 8879 | get_current_tab ().grab_focus (); | ||
3628 | 8880 | } | ||
3629 | 8881 | return true; | ||
3630 | 8882 | } | ||
3631 | 8883 | |||
3632 | 8884 | void action_tools_populate_popup (Gtk.Action action, Gtk.Menu default_menu) { | ||
3633 | 8885 | var menu = new ContextAction ("ToolsMenu", null, null, null); | ||
3634 | 8886 | menu.add_action_group (action_group); | ||
3635 | 8887 | menu.add_by_name ("ManageSearchEngines"); | ||
3636 | 8888 | menu.add_by_name ("ClearPrivateData"); | ||
3637 | 8889 | menu.add_by_name ("InspectPage"); | ||
3638 | 8890 | populate_tool_menu (default_menu); | ||
3639 | 8891 | menu.add (null); | ||
3640 | 8892 | var j = 0; | ||
3641 | 8893 | Gtk.Widget widget; | ||
3642 | 8894 | while ((widget = panel.get_nth_page (j++)) != null) | ||
3643 | 8895 | menu.add (widget.get_data<Gtk.Action> ("midori-panel-action")); | ||
3644 | 8896 | #if G_OS_WIN32 | ||
3645 | 8897 | menu.add (null); | ||
3646 | 8898 | menu.add_by_name ("Preferences"); | ||
3647 | 8899 | #endif | ||
3648 | 8900 | menu.create_menu (default_menu, true); | ||
3649 | 8901 | } | ||
3650 | 8902 | |||
3651 | 8903 | bool action_bookmarks_populate_folder (Gtk.Action action, Gtk.MenuShell menu, Katze.Array folder) { | ||
3652 | 8904 | if (bookmarks == null) | ||
3653 | 8905 | return false; | ||
3654 | 8906 | |||
3655 | 8907 | bookmarks.populate_folder (folder); | ||
3656 | 8908 | |||
3657 | 8909 | /* Clear items from dummy array here */ | ||
3658 | 8910 | menu.@foreach ((widget) => widget.destroy ()); | ||
3659 | 8911 | |||
3660 | 8912 | /* "Import Bookmarks" and "Export Bookmarks" at the top */ | ||
3661 | 8913 | if (folder == bookmarks) { | ||
3662 | 8914 | Gtk.MenuItem menuitem; | ||
3663 | 8915 | menuitem = (Gtk.MenuItem) action_group.get_action ("BookmarksImport").create_menu_item (); | ||
3664 | 8916 | menu.append (menuitem); | ||
3665 | 8917 | menuitem.show (); | ||
3666 | 8918 | menuitem = (Gtk.MenuItem) action_group.get_action ("BookmarksExport").create_menu_item (); | ||
3667 | 8919 | menu.append (menuitem); | ||
3668 | 8920 | menuitem.show (); | ||
3669 | 8921 | menuitem = new Gtk.SeparatorMenuItem (); | ||
3670 | 8922 | menu.append (menuitem); | ||
3671 | 8923 | menuitem.show (); | ||
3672 | 8924 | } | ||
3673 | 8925 | |||
3674 | 8926 | if (folder.is_empty ()) { | ||
3675 | 8927 | var menuitem = new Gtk.ImageMenuItem.with_label (_("Empty")); | ||
3676 | 8928 | menuitem.sensitive = false; | ||
3677 | 8929 | menu.append (menuitem); | ||
3678 | 8930 | menuitem.show (); | ||
3679 | 8931 | return true; | ||
3680 | 8932 | } | ||
3681 | 8933 | |||
3682 | 8934 | ((Katze.ArrayAction) action).generate_menu (folder, menu, this); | ||
3683 | 8935 | return true; | ||
3684 | 8936 | } | ||
3685 | 8937 | |||
3686 | 8938 | void action_window_populate_popup (Gtk.Action action, Gtk.Menu default_menu) { | ||
3687 | 8939 | var menu = new ContextAction ("WindowMenu", null, null, null); | ||
3688 | 8940 | menu.add_action_group (action_group); | ||
3689 | 8941 | menu.add (null); | ||
3690 | 8942 | menu.add_by_name ("LastSession"); | ||
3691 | 8943 | menu.add_by_name ("TabCurrent"); | ||
3692 | 8944 | menu.add_by_name ("NextView"); | ||
3693 | 8945 | menu.add_by_name ("TabNext"); | ||
3694 | 8946 | menu.add_by_name ("TabPrevious"); | ||
3695 | 8947 | menu.create_menu (default_menu, true); | ||
3696 | 8948 | } | ||
3697 | 8949 | |||
3698 | 8950 | bool action_window_activate_item_alt (Katze.ArrayAction action, Katze.Item item, Gtk.Widget proxy, Gdk.EventButton event) { | ||
3699 | 8951 | set_current_item (item); | ||
3700 | 8952 | return true; | ||
3701 | 8953 | } | ||
3702 | 8954 | |||
3703 | 8955 | void action_compact_menu_populate_popup (Katze.ArrayAction action, Gtk.Menu default_menu) { | ||
3704 | 8956 | var menu = new ContextAction ("CompactMenu", null, null, null); | ||
3705 | 8957 | menu.add_action_group (action_group); | ||
3706 | 8958 | menu.add_by_name ("WindowNew"); | ||
3707 | 8959 | menu.add_by_name ("PrivateBrowsing"); | ||
3708 | 8960 | menu.add (null); | ||
3709 | 8961 | menu.add_by_name ("Find"); | ||
3710 | 8962 | menu.add_by_name ("Print"); | ||
3711 | 8963 | menu.add_by_name ("Fullscreen"); | ||
3712 | 8964 | menu.add_by_name ("MailTo"); | ||
3713 | 8965 | menu.add (null); | ||
3714 | 8966 | var j = 0; | ||
3715 | 8967 | Gtk.Widget widget; | ||
3716 | 8968 | while ((widget = panel.get_nth_page (j++)) != null) | ||
3717 | 8969 | menu.add (widget.get_data<Gtk.Action> ("midori-panel-action")); | ||
3718 | 8970 | menu.add (null); | ||
3719 | 8971 | menu.add_by_name ("BookmarksImport"); | ||
3720 | 8972 | menu.add_by_name ("BookmarksExport"); | ||
3721 | 8973 | menu.add_by_name ("ClearPrivateData"); | ||
3722 | 8974 | populate_tool_menu (default_menu); | ||
3723 | 8975 | menu.add (null); | ||
3724 | 8976 | #if !HAVE_GRANITE | ||
3725 | 8977 | menu.add_by_name ("HelpFAQ"); | ||
3726 | 8978 | menu.add_by_name ("HelpBugs"); | ||
3727 | 8979 | #endif | ||
3728 | 8980 | menu.add_by_name ("Preferences"); | ||
3729 | 8981 | menu.add_by_name ("About"); | ||
3730 | 8982 | menu.create_menu (default_menu, false); | ||
3731 | 8983 | } | ||
3732 | 8984 | |||
3733 | 8985 | void preferences_response_help_cb (Gtk.Widget preferences, int response) { | ||
3734 | 8986 | if (response == Gtk.ResponseType.HELP) | ||
3735 | 8987 | activate_action ("HelpFAQ"); | ||
3736 | 8988 | } | ||
3737 | 8989 | |||
3738 | 8990 | Preferences? preferences_dialog = null; | ||
3739 | 8991 | void action_preferences_activate (Gtk.Action action) { | ||
3740 | 8992 | if (preferences_dialog == null) { | ||
3741 | 8993 | preferences_dialog = new Preferences (this, settings); | ||
3742 | 8994 | show_preferences (preferences_dialog); | ||
3743 | 8995 | preferences_dialog.response.connect (preferences_response_help_cb); | ||
3744 | 8996 | preferences_dialog.destroy.connect (() => { preferences_dialog = null; }); | ||
3745 | 8997 | preferences_dialog.show (); | ||
3746 | 8998 | } else | ||
3747 | 8999 | preferences_dialog.present (); | ||
3748 | 9000 | } | ||
3749 | 9001 | |||
3750 | 9002 | string? ubuntu_menuproxy = null; | ||
3751 | 9003 | bool has_native_menubar () { | ||
3752 | 9004 | if (ubuntu_menuproxy == null) | ||
3753 | 9005 | ubuntu_menuproxy = Environ.get_variable (Environ.@get (), "UBUNTU_MENUPROXY"); | ||
3754 | 9006 | /* | ||
3755 | 9007 | * Values when the global menu is enabled | ||
3756 | 9008 | * UBUNTU_MENUPROXY=libappmenu.so | ||
3757 | 9009 | * UBUNTU_MENUPROXY=1 | ||
3758 | 9010 | * The official way to disable the menu is | ||
3759 | 9011 | * UBUNTU_MENUPROXY= | ||
3760 | 9012 | */ | ||
3761 | 9013 | return ubuntu_menuproxy != null && (".so" in ubuntu_menuproxy || ubuntu_menuproxy == "1"); | ||
3762 | 9014 | } | ||
3763 | 9015 | |||
3764 | 9016 | void action_menubar_activate (Gtk.Action menubar_action) { | ||
3765 | 9017 | var active = ((Gtk.ToggleAction) menubar_action).active; | ||
3766 | 9018 | var menu_action = action_group.get_action ("CompactMenu"); | ||
3767 | 9019 | var toolbar_items = new StringBuilder (); | ||
3768 | 9020 | |||
3769 | 9021 | if (has_native_menubar ()) | ||
3770 | 9022 | active = false; | ||
3771 | 9023 | |||
3772 | 9024 | foreach (var child in navigationbar.get_children ()) { | ||
3773 | 9025 | var action = ((Gtk.Activatable) child).related_action; | ||
3774 | 9026 | if (action == null) | ||
3775 | 9027 | continue; | ||
3776 | 9028 | if (action == menu_action) { | ||
3777 | 9029 | if (active) | ||
3778 | 9030 | navigationbar.remove (child); | ||
3779 | 9031 | continue; | ||
3780 | 9032 | } else if (action is PanedAction) { | ||
3781 | 9033 | var paned_action = (PanedAction) action; | ||
3782 | 9034 | toolbar_items.append_printf ("%s,%s", paned_action.get_child1_name (), paned_action.get_child2_name ()); | ||
3783 | 9035 | } else | ||
3784 | 9036 | toolbar_items.append (action.name); | ||
3785 | 9037 | toolbar_items.append_c (','); | ||
3786 | 9038 | } | ||
3787 | 9039 | |||
3788 | 9040 | if (settings.show_menubar != active) | ||
3789 | 9041 | settings.show_menubar = active; | ||
3790 | 9042 | |||
3791 | 9043 | settings.toolbar_items = toolbar_items.str; | ||
3792 | 9044 | |||
3793 | 9045 | Sokoke.widget_set_visible (menubar, active); | ||
3794 | 9046 | set_data<bool> ("midori-toolbars-visible", menubar.visible || navigationbar.visible); | ||
3795 | 9047 | } | ||
3796 | 9048 | |||
3797 | 9049 | void action_navigationbar_activate (Gtk.Action action) { | ||
3798 | 9050 | var active = ((Gtk.ToggleAction) action).active; | ||
3799 | 9051 | settings.show_navigationbar = active; | ||
3800 | 9052 | Sokoke.widget_set_visible (navigationbar, active); | ||
3801 | 9053 | |||
3802 | 9054 | set_data<bool> ("midori-toolbars-visible", menubar.visible || navigationbar.visible); | ||
3803 | 9055 | } | ||
3804 | 9056 | |||
3805 | 9057 | void action_bookmarkbar_activate (Gtk.Action action) { | ||
3806 | 9058 | var active = ((Gtk.ToggleAction) action).active; | ||
3807 | 9059 | settings.show_bookmarkbar = active; | ||
3808 | 9060 | Sokoke.widget_set_visible (bookmarkbar, active); | ||
3809 | 9061 | } | ||
3810 | 9062 | |||
3811 | 9063 | void action_statusbar_activate (Gtk.Action action) { | ||
3812 | 9064 | var active = ((Gtk.ToggleAction) action).active; | ||
3813 | 9065 | settings.show_statusbar = active; | ||
3814 | 9066 | Sokoke.widget_set_visible (statusbar, active); | ||
3815 | 9067 | } | ||
3816 | 9068 | |||
3817 | 9069 | void action_reload_stop_activate (Gtk.Action action) { | ||
3818 | 9070 | var view = (View) get_current_tab (); | ||
3819 | 9071 | |||
3820 | 9072 | /* Refresh or stop, depending on the stock id */ | ||
3821 | 9073 | if (action.stock_id == Gtk.Stock.REFRESH) { | ||
3822 | 9074 | var state = (Gdk.ModifierType) 0; | ||
3823 | 9075 | Gdk.Window? window = null; | ||
3824 | 9076 | var from_cache = true; | ||
3825 | 9077 | |||
3826 | 9078 | if (action.name == "ReloadUncached") | ||
3827 | 9079 | from_cache = false; | ||
3828 | 9080 | else if ((window = get_window ()) != null) { | ||
3829 | 9081 | window.get_device_position (Gtk.get_current_event_device (), null, null, out state); | ||
3830 | 9082 | if ((state & Gdk.ModifierType.SHIFT_MASK) != 0) | ||
3831 | 9083 | from_cache = false; | ||
3832 | 9084 | } | ||
3833 | 9085 | view.reload (from_cache); | ||
3834 | 9086 | } else | ||
3835 | 9087 | view.stop_loading (); | ||
3836 | 9088 | } | ||
3837 | 9089 | |||
3838 | 9090 | void action_zoom_activate (Gtk.Action action) { | ||
3839 | 9091 | var view = (View) get_current_tab (); | ||
3840 | 9092 | |||
3841 | 9093 | if (action.name == "ZoomIn") | ||
3842 | 9094 | view.zoom_level = view.zoom_level + 0.10f; | ||
3843 | 9095 | else if (action.name == "ZoomOut") | ||
3844 | 9096 | view.zoom_level = view.zoom_level - 0.10f; | ||
3845 | 9097 | else | ||
3846 | 9098 | view.zoom_level = 1.0f; | ||
3847 | 9099 | } | ||
3848 | 9100 | |||
3849 | 9101 | void action_view_encoding_activate (Gtk.Action action, Gtk.Action current) { | ||
3850 | 9102 | var view = (View) get_current_tab (); | ||
3851 | 9103 | var name = current.name; | ||
3852 | 9104 | |||
3853 | 9105 | string? encoding = null; | ||
3854 | 9106 | switch (name) { | ||
3855 | 9107 | case "EncodingAutomatic": | ||
3856 | 9108 | encoding = null; | ||
3857 | 9109 | break; | ||
3858 | 9110 | case "EncodingChinese": | ||
3859 | 9111 | encoding = "BIG5"; | ||
3860 | 9112 | break; | ||
3861 | 9113 | case "EncodingChineseSimplified": | ||
3862 | 9114 | encoding = "GB18030"; | ||
3863 | 9115 | break; | ||
3864 | 9116 | case "EncodingJapanese": | ||
3865 | 9117 | encoding = "SHIFT_JIS"; | ||
3866 | 9118 | break; | ||
3867 | 9119 | case "EncodingKorean": | ||
3868 | 9120 | encoding = "EUC-KR"; | ||
3869 | 9121 | break; | ||
3870 | 9122 | case "EncodingRussian": | ||
3871 | 9123 | encoding = "KOI8-R"; | ||
3872 | 9124 | break; | ||
3873 | 9125 | case "EncodingUnicode": | ||
3874 | 9126 | encoding = "UTF-8"; | ||
3875 | 9127 | break; | ||
3876 | 9128 | case "EncodingWestern": | ||
3877 | 9129 | encoding = "ISO-8859-1"; | ||
3878 | 9130 | break; | ||
3879 | 9131 | default: | ||
3880 | 9132 | assert_not_reached (); | ||
3881 | 9133 | } | ||
3882 | 9134 | #if HAVE_WEBKIT2 | ||
3883 | 9135 | view.web_view.set_custom_charset (encoding); | ||
3884 | 9136 | #else | ||
3885 | 9137 | view.web_view.set_custom_encoding (encoding); | ||
3886 | 9138 | #endif | ||
3887 | 9139 | } | ||
3888 | 9140 | |||
3889 | 9141 | void action_source_view (Gtk.Action action, bool use_dom) { | ||
3890 | 9142 | var view = (View) get_current_tab (); | ||
3891 | 9143 | #if HAVE_WEBKIT2 | ||
3892 | 9144 | /* TODO: midori_view_save_source isn't async and not WebKit2-friendly */ | ||
3893 | 9145 | var source = new View.with_item (null, settings); | ||
3894 | 9146 | var source_view = source.web_view; | ||
3895 | 9147 | source.view_source = true; | ||
3896 | 9148 | source_view.load_uri (view.uri); | ||
3897 | 9149 | add_tab (source); | ||
3898 | 9150 | #else | ||
3899 | 9151 | var filename = view.save_source (null, null, use_dom); | ||
3900 | 9152 | var text_editor = settings.text_editor; | ||
3901 | 9153 | if (text_editor == null || text_editor == "") { | ||
3902 | 9154 | try { | ||
3903 | 9155 | var source_uri = Filename.to_uri (filename, null); | ||
3904 | 9156 | var source = new View.with_item (null, settings); | ||
3905 | 9157 | var source_view = source.web_view; | ||
3906 | 9158 | source.view_source = true; | ||
3907 | 9159 | source_view.load_uri (source_uri); | ||
3908 | 9160 | add_tab (source); | ||
3909 | 9161 | } catch (Error e) {} | ||
3910 | 9162 | } else | ||
3911 | 9163 | Sokoke.spawn_program (text_editor, true, filename, true, false); | ||
3912 | 9164 | #endif | ||
3913 | 9165 | } | ||
3914 | 9166 | |||
3915 | 9167 | void action_source_view_activate (Gtk.Action action) { | ||
3916 | 9168 | action_source_view (action, false); | ||
3917 | 9169 | } | ||
3918 | 9170 | |||
3919 | 9171 | void action_source_view_dom_activate (Gtk.Action action) { | ||
3920 | 9172 | action_source_view (action, true); | ||
3921 | 9173 | } | ||
3922 | 9174 | |||
3923 | 9175 | void action_caret_browsing_activate (Gtk.Action action) { | ||
3924 | 9176 | int response; | ||
3925 | 9177 | |||
3926 | 9178 | if (!settings.enable_caret_browsing) { | ||
3927 | 9179 | var dialog = new Gtk.MessageDialog (this, Gtk.DialogFlags.DESTROY_WITH_PARENT, | ||
3928 | 9180 | Gtk.MessageType.QUESTION, Gtk.ButtonsType.NONE, _("Toggle text cursor navigation")); | ||
3929 | 9181 | dialog.title = _("Toggle text cursor navigation"); | ||
3930 | 9182 | dialog.format_secondary_text (_("Pressing F7 toggles Caret Browsing. When active, a text cursor appears in all websites.")); | ||
3931 | 9183 | dialog.add_buttons (Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL, | ||
3932 | 9184 | _("_Enable Caret Browsing"), Gtk.ResponseType.ACCEPT); | ||
3933 | 9185 | |||
3934 | 9186 | response = Midori.Dialog.run (dialog); | ||
3935 | 9187 | dialog.destroy (); | ||
3936 | 9188 | |||
3937 | 9189 | if (response != Gtk.ResponseType.ACCEPT) | ||
3938 | 9190 | return; | ||
3939 | 9191 | } | ||
3940 | 9192 | |||
3941 | 9193 | settings.enable_caret_browsing = !settings.enable_caret_browsing; | ||
3942 | 9194 | } | ||
3943 | 9195 | |||
3944 | 9196 | void action_fullscreen_activate (Gtk.Action action) { | ||
3945 | 9197 | var window = get_window (); | ||
3946 | 9198 | if (window == null) | ||
3947 | 9199 | return; | ||
3948 | 9200 | |||
3949 | 9201 | var state = window.get_state (); | ||
3950 | 9202 | if ((state & Gdk.WindowState.FULLSCREEN) != 0) { | ||
3951 | 9203 | if (settings.show_menubar) | ||
3952 | 9204 | menubar.show (); | ||
3953 | 9205 | |||
3954 | 9206 | if (settings.show_panel) | ||
3955 | 9207 | panel.show (); | ||
3956 | 9208 | |||
3957 | 9209 | if (settings.show_bookmarkbar) | ||
3958 | 9210 | bookmarkbar.show (); | ||
3959 | 9211 | |||
3960 | 9212 | if (show_navigationbar) | ||
3961 | 9213 | navigationbar.show (); | ||
3962 | 9214 | |||
3963 | 9215 | if (show_statusbar) | ||
3964 | 9216 | statusbar.show (); | ||
3965 | 9217 | |||
3966 | 9218 | toggle_tabbar_smartly (true); | ||
3967 | 9219 | |||
3968 | 9220 | unfullscreen (); | ||
3969 | 9221 | } else { | ||
3970 | 9222 | menubar.hide (); | ||
3971 | 9223 | panel.hide (); | ||
3972 | 9224 | bookmarkbar.hide (); | ||
3973 | 9225 | navigationbar.hide (); | ||
3974 | 9226 | statusbar.hide (); | ||
3975 | 9227 | notebook.labels_visible = false; | ||
3976 | 9228 | |||
3977 | 9229 | fullscreen (); | ||
3978 | 9230 | } | ||
3979 | 9231 | } | ||
3980 | 9232 | |||
3981 | 9233 | void action_scroll_somewhere_activate (Gtk.Action action) { | ||
3982 | 9234 | #if !HAVE_WEBKIT2 | ||
3983 | 9235 | var view = get_current_tab (); | ||
3984 | 9236 | var web_view = view.web_view; | ||
3985 | 9237 | var name = action.name; | ||
3986 | 9238 | |||
3987 | 9239 | switch (name) { | ||
3988 | 9240 | case "ScrollLeft": | ||
3989 | 9241 | web_view.move_cursor (Gtk.MovementStep.VISUAL_POSITIONS, -1); | ||
3990 | 9242 | break; | ||
3991 | 9243 | case "ScrollDown": | ||
3992 | 9244 | web_view.move_cursor (Gtk.MovementStep.DISPLAY_LINES, 1); | ||
3993 | 9245 | break; | ||
3994 | 9246 | case "ScrollUp": | ||
3995 | 9247 | web_view.move_cursor (Gtk.MovementStep.DISPLAY_LINES, -1); | ||
3996 | 9248 | break; | ||
3997 | 9249 | case "ScrollRight": | ||
3998 | 9250 | web_view.move_cursor (Gtk.MovementStep.VISUAL_POSITIONS, 1); | ||
3999 | 9251 | break; | ||
4000 | 9252 | } | ||
4001 | 9253 | #endif | ||
4002 | 9254 | } | ||
4003 | 9255 | |||
4004 | 9256 | void action_readable_activate (Gtk.Action action) { | ||
4005 | 9257 | var view = (View) get_current_tab (); | ||
4006 | 9258 | |||
4007 | 9259 | var filename = Paths.get_res_filename ("faq.css"); | ||
4008 | 9260 | string stylesheet = null; | ||
4009 | 9261 | try { | ||
4010 | 9262 | FileUtils.get_contents (filename, out stylesheet); | ||
4011 | 9263 | } catch (Error e) { | ||
4012 | 9264 | #if G_OS_WIN32 | ||
4013 | 9265 | filename = Paths.get_data_filename ("doc/midori/faq.css", false); | ||
4014 | 9266 | #else | ||
4015 | 9267 | filename = Path.build_filename (DOCDIR, "faq.css"); | ||
4016 | 9268 | #endif | ||
4017 | 9269 | try { | ||
4018 | 9270 | FileUtils.get_contents (filename, out stylesheet); | ||
4019 | 9271 | } catch (Error e2) { | ||
4020 | 9272 | warning (e2.message); | ||
4021 | 9273 | } | ||
4022 | 9274 | } | ||
4023 | 9275 | |||
4024 | 9276 | if (stylesheet == null || stylesheet == "") { | ||
4025 | 9277 | view.add_info_bar (Gtk.MessageType.ERROR, "Stylesheet faq.css not found", null, view, | ||
4026 | 9278 | Gtk.Stock.OK, Gtk.ResponseType.ACCEPT); | ||
4027 | 9279 | return; | ||
4028 | 9280 | } | ||
4029 | 9281 | |||
4030 | 9282 | /* Replace line breaks with spaces and change all single quotes to double quotes */ | ||
4031 | 9283 | stylesheet.replace ("\n", " ").replace ("\r", " ").replace ("\'", "\""); | ||
4032 | 9284 | |||
4033 | 9285 | tab.inject_stylesheet (stylesheet); | ||
4034 | 9286 | } | ||
4035 | 9287 | |||
4036 | 9288 | void action_navigation_activate (Gtk.Action action) { | ||
4037 | 9289 | navigation_activate (action); | ||
4038 | 9290 | } | ||
4039 | 9291 | |||
4040 | 9292 | bool navigation_activate (Gtk.Action action) { | ||
4041 | 9293 | bool middle_click = false; | ||
4042 | 9294 | |||
4043 | 9295 | assert (action is Gtk.Action); | ||
4044 | 9296 | |||
4045 | 9297 | if (action.get_data<bool> ("midori-middle-click")) { | ||
4046 | 9298 | middle_click = true; | ||
4047 | 9299 | action.set_data<bool> ("midori-middle-click", false); | ||
4048 | 9300 | } | ||
4049 | 9301 | |||
4050 | 9302 | var tab = (View) get_current_tab (); | ||
4051 | 9303 | var name = action.name; | ||
4052 | 9304 | |||
4053 | 9305 | if (name == "NextForward") | ||
4054 | 9306 | name = tab.can_go_forward () ? "Forward" : "Next"; | ||
4055 | 9307 | |||
4056 | 9308 | if (name == "Back") { | ||
4057 | 9309 | if (middle_click) { | ||
4058 | 9310 | var web_view = tab.web_view; | ||
4059 | 9311 | #if HAVE_WEBKIT2 | ||
4060 | 9312 | var list = web_view.get_back_forward_list (); | ||
4061 | 9313 | var item = list.get_back_item (); | ||
4062 | 9314 | var back_uri = item.uri; | ||
4063 | 9315 | #else | ||
4064 | 9316 | var list = web_view.get_back_forward_list (); | ||
4065 | 9317 | var item = list.get_forward_item (); | ||
4066 | 9318 | var back_uri = item.uri; | ||
4067 | 9319 | #endif | ||
4068 | 9320 | |||
4069 | 9321 | var new_view = add_uri (back_uri); | ||
4070 | 9322 | set_current_tab_smartly (new_view); | ||
4071 | 9323 | } else | ||
4072 | 9324 | tab.go_back (); | ||
4073 | 9325 | |||
4074 | 9326 | return true; | ||
4075 | 9327 | } else if (name == "Forward") { | ||
4076 | 9328 | if (middle_click) { | ||
4077 | 9329 | var web_view = tab.web_view; | ||
4078 | 9330 | #if HAVE_WEBKIT2 | ||
4079 | 9331 | var list = web_view.get_back_forward_list (); | ||
4080 | 9332 | var item = list.get_forward_item (); | ||
4081 | 9333 | var forward_uri = item.get_uri (); | ||
4082 | 9334 | #else | ||
4083 | 9335 | var list = web_view.get_back_forward_list (); | ||
4084 | 9336 | var item = list.get_forward_item (); | ||
4085 | 9337 | var forward_uri = item.get_uri (); | ||
4086 | 9338 | #endif | ||
4087 | 9339 | |||
4088 | 9340 | var new_view = add_uri (forward_uri); | ||
4089 | 9341 | set_current_tab_smartly (new_view); | ||
4090 | 9342 | } else | ||
4091 | 9343 | tab.go_forward (); | ||
4092 | 9344 | |||
4093 | 9345 | return true; | ||
4094 | 9346 | } else if (name == "Previous") { | ||
4095 | 9347 | /* Duplicate here because the URI pointer might change */ | ||
4096 | 9348 | var uri = tab.get_previous_page (); | ||
4097 | 9349 | |||
4098 | 9350 | if (middle_click) { | ||
4099 | 9351 | var new_view = add_uri (uri); | ||
4100 | 9352 | set_current_tab_smartly (new_view); | ||
4101 | 9353 | } else | ||
4102 | 9354 | tab.set_uri (uri); | ||
4103 | 9355 | |||
4104 | 9356 | return true; | ||
4105 | 9357 | } else if (name == "Next") { | ||
4106 | 9358 | /* Duplicate here because the URI pointer might change */ | ||
4107 | 9359 | var uri = tab.get_next_page (); | ||
4108 | 9360 | |||
4109 | 9361 | if (middle_click) { | ||
4110 | 9362 | var new_view = add_uri (uri); | ||
4111 | 9363 | set_current_tab_smartly (new_view); | ||
4112 | 9364 | } else | ||
4113 | 9365 | tab.set_uri (uri); | ||
4114 | 9366 | |||
4115 | 9367 | return true; | ||
4116 | 9368 | } else if (name == "Homepage") { | ||
4117 | 9369 | if (middle_click) { | ||
4118 | 9370 | var new_view = add_uri ("about:home"); | ||
4119 | 9371 | set_current_tab_smartly (new_view); | ||
4120 | 9372 | } else | ||
4121 | 9373 | tab.set_uri ("about:home"); | ||
4122 | 9374 | |||
4123 | 9375 | return true; | ||
4124 | 9376 | } | ||
4125 | 9377 | return false; | ||
4126 | 9378 | } | ||
4127 | 9379 | |||
4128 | 9380 | void action_location_activate (Gtk.Action action) { | ||
4129 | 9381 | if (!navigationbar.visible) | ||
4130 | 9382 | navigationbar.show (); | ||
4131 | 9383 | } | ||
4132 | 9384 | |||
4133 | 9385 | void action_location_focus_in (Gtk.Action action) { | ||
4134 | 9386 | var screen = notebook.get_screen (); | ||
4135 | 9387 | var icon_theme = Gtk.IconTheme.get_for_screen (screen); | ||
4136 | 9388 | if (icon_theme.has_icon ("go-jump-symbolic")) | ||
4137 | 9389 | ((LocationAction) action).secondary_icon = "go-jump-symbolic"; | ||
4138 | 9390 | else | ||
4139 | 9391 | ((LocationAction) action).secondary_icon = Gtk.Stock.JUMP_TO; | ||
4140 | 9392 | } | ||
4141 | 9393 | |||
4142 | 9394 | void action_location_focus_out (Gtk.Action action) { | ||
4143 | 9395 | var view = (View) get_current_tab (); | ||
4144 | 9396 | |||
4145 | 9397 | if (!show_navigationbar || is_fullscreen ()) | ||
4146 | 9398 | navigationbar.hide (); | ||
4147 | 9399 | |||
4148 | 9400 | update_secondary_icon (view, action); | ||
4149 | 9401 | } | ||
4150 | 9402 | |||
4151 | 9403 | void action_location_reset_uri (Gtk.Action action) { | ||
4152 | 9404 | ((LocationAction) action).set_text (get_current_uri ()); | ||
4153 | 9405 | } | ||
4154 | 9406 | |||
4155 | 9407 | #if !HAVE_WEBKIT2 | ||
4156 | 9408 | void item_icon_loaded_cb (WebKit.FaviconDatabase database, string frame_uri, Katze.Item item) { | ||
4157 | 9409 | var uri = item.get_data<string> ("browser-queue-icon"); | ||
4158 | 9410 | if (frame_uri != uri) | ||
4159 | 9411 | return; | ||
4160 | 9412 | |||
4161 | 9413 | var icon_uri = database.get_favicon_uri (frame_uri); | ||
4162 | 9414 | if (icon_uri != null) { | ||
4163 | 9415 | item.icon = frame_uri; | ||
4164 | 9416 | /* This signal fires extremely often (WebKit bug?) | ||
4165 | 9417 | we must throttle it (disconnect) once we have an icon */ | ||
4166 | 9418 | SignalHandler.disconnect (database, database.get_data<ulong> ("handler-icon-loaded")); | ||
4167 | 9419 | } | ||
4168 | 9420 | } | ||
4169 | 9421 | #endif | ||
4170 | 9422 | |||
4171 | 9423 | void queue_item_for_icon (Katze.Item item, string uri) { | ||
4172 | 9424 | #if !HAVE_WEBKIT2 | ||
4173 | 9425 | if (item.icon != null) | ||
4174 | 9426 | return; | ||
4175 | 9427 | item.set_data<string> ("browser-queue-icon", uri); | ||
4176 | 9428 | var database = WebKit.get_favicon_database (); | ||
4177 | 9429 | database.set_data<ulong> ("handler-icon-loaded", database.icon_loaded.connect ((database, frame_uri) => | ||
4178 | 9430 | item_icon_loaded_cb (database, frame_uri, item))); | ||
4179 | 9431 | #endif | ||
4180 | 9432 | } | ||
4181 | 9433 | |||
4182 | 9434 | Sqlite.Statement? location_submit_uri_stmt = null; | ||
4183 | 9435 | void action_location_submit_uri (Gtk.Action action, string uri, bool new_tab) { | ||
4184 | 9436 | /* Switch to already open tab if possible */ | ||
4185 | 9437 | var found = (Katze.Item) proxy_array.find_uri (uri); | ||
4186 | 9438 | if (found != null && !new_tab && get_current_uri () != uri) { | ||
4187 | 9439 | var view = get_current_tab (); | ||
4188 | 9440 | set_current_item (found); | ||
4189 | 9441 | if (view.is_blank ()) | ||
4190 | 9442 | close_tab (view); | ||
4191 | 9443 | return; | ||
4192 | 9444 | } | ||
4193 | 9445 | |||
4194 | 9446 | uri = Katze.skip_whitespace (uri); | ||
4195 | 9447 | var new_uri = Sokoke.magic_uri (uri, true, false); | ||
4196 | 9448 | if (new_uri == null) { | ||
4197 | 9449 | string? keywords = null; | ||
4198 | 9450 | string? search_uri = null; | ||
4199 | 9451 | Katze.Item item = null; | ||
4200 | 9452 | |||
4201 | 9453 | /* Do we have a keyword and a string? */ | ||
4202 | 9454 | if (search_engines != null && (item = (Katze.Item) search_engines.find_token (uri)) != null) { | ||
4203 | 9455 | var space_index = uri.index_of (" "); | ||
4204 | 9456 | if (space_index > -1) | ||
4205 | 9457 | keywords = uri.substring (space_index + 1); | ||
4206 | 9458 | else | ||
4207 | 9459 | keywords = ""; | ||
4208 | 9460 | search_uri = item.uri; | ||
4209 | 9461 | } | ||
4210 | 9462 | |||
4211 | 9463 | if (keywords == null) { | ||
4212 | 9464 | keywords = uri; | ||
4213 | 9465 | search_uri = settings.location_entry_search; | ||
4214 | 9466 | } | ||
4215 | 9467 | new_uri = URI.for_search (search_uri, keywords); | ||
4216 | 9468 | |||
4217 | 9469 | if (search_engines != null && item != null) | ||
4218 | 9470 | queue_item_for_icon (item, new_uri); | ||
4219 | 9471 | |||
4220 | 9472 | if (history != null) { | ||
4221 | 9473 | var now = time_t (); | ||
4222 | 9474 | var day = Sokoke.time_t_to_julian (ref now); | ||
4223 | 9475 | unowned Sqlite.Database db = history.get_data<Sqlite.Database> ("db"); | ||
4224 | 9476 | |||
4225 | 9477 | if (location_submit_uri_stmt == null) { | ||
4226 | 9478 | var sqlcmd = "INSERT INTO search (keywords, uri, day) VALUES (?,?,?)"; | ||
4227 | 9479 | db.prepare_v2 (sqlcmd, sqlcmd.length + 1, out location_submit_uri_stmt); | ||
4228 | 9480 | } | ||
4229 | 9481 | location_submit_uri_stmt.bind_text (1, keywords); | ||
4230 | 9482 | location_submit_uri_stmt.bind_text (2, search_uri); | ||
4231 | 9483 | location_submit_uri_stmt.bind_int64 (3, day); | ||
4232 | 9484 | |||
4233 | 9485 | if (location_submit_uri_stmt.step () != Sqlite.DONE) | ||
4234 | 9486 | printerr (_("Failed to insert new history item: %s\n"), db.errmsg ()); | ||
4235 | 9487 | |||
4236 | 9488 | location_submit_uri_stmt.reset (); | ||
4237 | 9489 | if (location_submit_uri_stmt.step () == Sqlite.DONE) | ||
4238 | 9490 | location_submit_uri_stmt.clear_bindings (); | ||
4239 | 9491 | } | ||
4240 | 9492 | } | ||
4241 | 9493 | |||
4242 | 9494 | if (new_tab) { | ||
4243 | 9495 | var view = add_uri (new_uri); | ||
4244 | 9496 | set_current_tab (view); | ||
4245 | 9497 | } else | ||
4246 | 9498 | set_current_uri (new_uri); | ||
4247 | 9499 | get_current_tab ().grab_focus (); | ||
4248 | 9500 | } | ||
4249 | 9501 | |||
4250 | 9502 | void news_feed_clicked_cb (Gtk.Widget menuitem) { | ||
4251 | 9503 | var uri = menuitem.get_data<string> ("uri"); | ||
4252 | 9504 | subscribe_to_news_feed (uri); | ||
4253 | 9505 | } | ||
4254 | 9506 | |||
4255 | 9507 | bool action_location_secondary_icon_released (Gtk.Action action, Gtk.Widget widget) { | ||
4256 | 9508 | var view = (View) get_current_tab (); | ||
4257 | 9509 | var uri = view.get_display_uri (); | ||
4258 | 9510 | string? feed = null; | ||
4259 | 9511 | /* Clicking icon on blank is equal to Paste and Proceed */ | ||
4260 | 9512 | if (view.is_blank ()) { | ||
4261 | 9513 | var clipboard = Gtk.Clipboard.get_for_display (view.get_display (), Gdk.SELECTION_CLIPBOARD); | ||
4262 | 9514 | var text = clipboard.wait_for_text (); | ||
4263 | 9515 | if (text != null) | ||
4264 | 9516 | action_location_submit_uri (action, text, false); | ||
4265 | 9517 | } else if (get_focus () == widget) { | ||
4266 | 9518 | var text = ((Gtk.Entry) widget).text; | ||
4267 | 9519 | action_location_submit_uri (action, text, false); | ||
4268 | 9520 | } else if ((feed = view.get_data<string> ("news-feeds")) != null) { | ||
4269 | 9521 | Katze.Item itemm; | ||
4270 | 9522 | |||
4271 | 9523 | var news_feeds = view.news_feeds; | ||
4272 | 9524 | var item = news_feeds.get_nth_item (0); | ||
4273 | 9525 | if ((itemm = news_feeds.get_nth_item (1)) != null) { | ||
4274 | 9526 | Gtk.MenuItem menuitem; | ||
4275 | 9527 | |||
4276 | 9528 | var menu = new Gtk.Menu (); | ||
4277 | 9529 | menuitem = new Gtk.MenuItem.with_label (item.name); | ||
4278 | 9530 | menuitem.set_data<string> ("uri", item.uri); | ||
4279 | 9531 | menuitem.activate.connect (news_feed_clicked_cb); | ||
4280 | 9532 | menu.append (menuitem); | ||
4281 | 9533 | menuitem = new Gtk.MenuItem.with_label (itemm.name); | ||
4282 | 9534 | menuitem.set_data<string> ("uri", itemm.uri); | ||
4283 | 9535 | menuitem.activate.connect (news_feed_clicked_cb); | ||
4284 | 9536 | menu.append (menuitem); | ||
4285 | 9537 | |||
4286 | 9538 | var i = 2; | ||
4287 | 9539 | while ((itemm = news_feeds.get_nth_item (i++)) != null) { | ||
4288 | 9540 | menuitem = new Gtk.MenuItem.with_label (itemm.name); | ||
4289 | 9541 | menuitem.set_data<string> ("uri", itemm.uri); | ||
4290 | 9542 | menuitem.activate.connect (news_feed_clicked_cb); | ||
4291 | 9543 | menu.append (menuitem); | ||
4292 | 9544 | } | ||
4293 | 9545 | menu.@foreach ((widget) => widget.show_all ()); | ||
4294 | 9546 | Katze.widget_popup (widget, menu, null, | ||
4295 | 9547 | Katze.MenuPos.RIGHT); | ||
4296 | 9548 | } else | ||
4297 | 9549 | subscribe_to_news_feed (feed); | ||
4298 | 9550 | } else | ||
4299 | 9551 | action_location_submit_uri (action, uri, false); | ||
4300 | 9552 | return true; | ||
4301 | 9553 | } | ||
4302 | 9554 | |||
4303 | 9555 | void action_search_submit (Gtk.Action action, string keywords, bool new_tab) { | ||
4304 | 9556 | string url; | ||
4305 | 9557 | var item = search_engines.get_nth_item (last_web_search); | ||
4306 | 9558 | if (item != null) | ||
4307 | 9559 | url = item.uri; | ||
4308 | 9560 | else /* The location entry search is our fallback */ | ||
4309 | 9561 | url = settings.location_entry_search; | ||
4310 | 9562 | |||
4311 | 9563 | var search = URI.for_search (url, keywords); | ||
4312 | 9564 | if (item != null) | ||
4313 | 9565 | queue_item_for_icon (item, search); | ||
4314 | 9566 | |||
4315 | 9567 | if (new_tab) { | ||
4316 | 9568 | var view = add_uri (search); | ||
4317 | 9569 | set_current_tab_smartly (view); | ||
4318 | 9570 | } else | ||
4319 | 9571 | set_current_uri (search); | ||
4320 | 9572 | } | ||
4321 | 9573 | |||
4322 | 9574 | void action_search_activate (Gtk.Action action) { | ||
4323 | 9575 | unowned SList<Gtk.Widget> proxies = action.get_proxies (); | ||
4324 | 9576 | foreach (var proxy in proxies) { | ||
4325 | 9577 | if (proxy is Gtk.ToolItem) { | ||
4326 | 9578 | if (!navigationbar.visible) | ||
4327 | 9579 | navigationbar.show (); | ||
4328 | 9580 | return; | ||
4329 | 9581 | } | ||
4330 | 9582 | } | ||
4331 | 9583 | |||
4332 | 9584 | set_current_uri ("about:search"); | ||
4333 | 9585 | get_current_tab ().grab_focus (); | ||
4334 | 9586 | } | ||
4335 | 9587 | |||
4336 | 9588 | void action_search_notify_current_item (Object action, ParamSpec pspec) { | ||
4337 | 9589 | var item = ((SearchAction) action).current_item; | ||
4338 | 9590 | var idx = (item != null ? search_engines.get_item_index (item) : 0); | ||
4339 | 9591 | |||
4340 | 9592 | settings.last_web_search = idx; | ||
4341 | 9593 | last_web_search = idx; | ||
4342 | 9594 | } | ||
4343 | 9595 | |||
4344 | 9596 | void action_search_notify_default_item (Object action, ParamSpec pspec) { | ||
4345 | 9597 | var item = ((SearchAction) action).default_item; | ||
4346 | 9598 | if (item != null) | ||
4347 | 9599 | settings.location_entry_search = item.uri; | ||
4348 | 9600 | } | ||
4349 | 9601 | |||
4350 | 9602 | void action_search_focus_out (Gtk.Action action) { | ||
4351 | 9603 | if ((statusbar.visible && !show_navigationbar) || is_fullscreen ()) | ||
4352 | 9604 | navigationbar.hide (); | ||
4353 | 9605 | } | ||
4354 | 9606 | |||
4355 | 9607 | void bookmark_open_activate_cb (Gtk.Action action) { | ||
4356 | 9608 | open_bookmark (action.get_data<Katze.Item> ("KatzeItem")); | ||
4357 | 9609 | } | ||
4358 | 9610 | |||
4359 | 9611 | void bookmark_open_in_tab_activate_cb (Gtk.Action action) { | ||
4360 | 9612 | string uri; | ||
4361 | 9613 | var item = action.get_data<Katze.Item> ("KatzeItem"); | ||
4362 | 9614 | if (item is Katze.Array) { | ||
4363 | 9615 | var array = bookmarks.query_recursive ("*", "parentid = %q", item.get_meta_string ("id"), false); | ||
4364 | 9616 | |||
4365 | 9617 | foreach (var child in array.get_items ()) { | ||
4366 | 9618 | if ((uri = child.uri) != null && child.uri != "") { | ||
4367 | 9619 | var view = add_item (child); | ||
4368 | 9620 | set_current_tab_smartly (view); | ||
4369 | 9621 | } | ||
4370 | 9622 | } | ||
4371 | 9623 | } else { | ||
4372 | 9624 | uri = item.uri; | ||
4373 | 9625 | if (uri != null && uri != "") { | ||
4374 | 9626 | var view = add_item (item); | ||
4375 | 9627 | set_current_tab_smartly (view); | ||
4376 | 9628 | } | ||
4377 | 9629 | } | ||
4378 | 9630 | } | ||
4379 | 9631 | |||
4380 | 9632 | void bookmark_open_in_window_activate_cb (Gtk.Action action) { | ||
4381 | 9633 | var item = action.get_data<Katze.Item> ("KatzeItem"); | ||
4382 | 9634 | view_new_window_cb (null, item.uri); | ||
4383 | 9635 | } | ||
4384 | 9636 | |||
4385 | 9637 | void bookmark_edit_activate_cb (Gtk.Action action) { | ||
4386 | 9638 | var item = action.get_data<Katze.Item> ("KatzeItem"); | ||
4387 | 9639 | |||
4388 | 9640 | if (Katze.item_is_bookmark (item)) | ||
4389 | 9641 | edit_bookmark_dialog_new (item, false, false, this); | ||
4390 | 9642 | else | ||
4391 | 9643 | edit_bookmark_dialog_new (item, false, true, this); | ||
4392 | 9644 | } | ||
4393 | 9645 | |||
4394 | 9646 | void bookmark_delete_activate_cb (Gtk.Action action) { | ||
4395 | 9647 | var item = action.get_data<Katze.Item> ("KatzeItem"); | ||
4396 | 9648 | bookmarks.remove_item (item); | ||
4397 | 9649 | } | ||
4398 | 9650 | |||
4399 | 9651 | void bookmark_popup (Gtk.Widget widget, Gdk.EventButton? event, Katze.Item item) { | ||
4400 | 9652 | var menu = new ContextAction ("BookmarkContextMenu", null, null, null); | ||
4401 | 9653 | Gtk.Action action; | ||
4402 | 9654 | if (Katze.item_is_folder (item)) { | ||
4403 | 9655 | var child_bookmarks_count = bookmarks.count_recursive ("uri <> ''", null, item, false); | ||
4404 | 9656 | |||
4405 | 9657 | action = new Gtk.Action ("BookmarkOpenAllTabs", _("Open all in _Tabs"), null, Stock.TAB_NEW); | ||
4406 | 9658 | action.sensitive = child_bookmarks_count > 0; | ||
4407 | 9659 | action.set_data<Katze.Item> ("KatzeItem", item); | ||
4408 | 9660 | action.activate.connect (bookmark_open_in_tab_activate_cb); | ||
4409 | 9661 | menu.add (action); | ||
4410 | 9662 | } else { | ||
4411 | 9663 | action = new Gtk.Action ("BookmarkOpen", null, null, Gtk.Stock.OPEN); | ||
4412 | 9664 | action.sensitive = item != null; | ||
4413 | 9665 | action.set_data<Katze.Item> ("KatzeItem", item); | ||
4414 | 9666 | action.activate.connect (bookmark_open_activate_cb); | ||
4415 | 9667 | menu.add (action); | ||
4416 | 9668 | |||
4417 | 9669 | action = new Gtk.Action ("BookmarkOpenTab", null, null, Stock.TAB_NEW); | ||
4418 | 9670 | action.sensitive = item.uri != null; | ||
4419 | 9671 | action.set_data<Katze.Item> ("KatzeItem", item); | ||
4420 | 9672 | action.activate.connect (bookmark_open_in_tab_activate_cb); | ||
4421 | 9673 | menu.add (action); | ||
4422 | 9674 | |||
4423 | 9675 | action = new Gtk.Action ("BookmarkOpenWindow", _("Open in New _Window"), null, Stock.WINDOW_NEW); | ||
4424 | 9676 | action.sensitive = item.uri != null; | ||
4425 | 9677 | action.set_data<Katze.Item> ("KatzeItem", item); | ||
4426 | 9678 | action.activate.connect (bookmark_open_in_window_activate_cb); | ||
4427 | 9679 | menu.add (action); | ||
4428 | 9680 | } | ||
4429 | 9681 | |||
4430 | 9682 | menu.add (null); | ||
4431 | 9683 | |||
4432 | 9684 | action = new Gtk.Action ("BookmarkEdit", null, null, Gtk.Stock.EDIT); | ||
4433 | 9685 | action.sensitive = !Katze.item_is_separator (item); | ||
4434 | 9686 | action.set_data<Katze.Item> ("KatzeItem", item); | ||
4435 | 9687 | action.activate.connect (bookmark_edit_activate_cb); | ||
4436 | 9688 | menu.add (action); | ||
4437 | 9689 | |||
4438 | 9690 | action = new Gtk.Action ("BookmarkDelete", null, null, Gtk.Stock.EDIT); | ||
4439 | 9691 | action.set_data<Katze.Item> ("KatzeItem", item); | ||
4440 | 9692 | action.activate.connect (bookmark_delete_activate_cb); | ||
4441 | 9693 | menu.add (action); | ||
4442 | 9694 | |||
4443 | 9695 | var context_menu = menu.create_menu (null, false); | ||
4444 | 9696 | Katze.widget_popup (widget, context_menu, event, Katze.MenuPos.CURSOR); | ||
4445 | 9697 | } | ||
4446 | 9698 | |||
4447 | 9699 | bool menu_button_press_event_cb (Gtk.Widget toolitem, Gdk.EventButton event) { | ||
4448 | 9700 | if (event.button != 3) | ||
4449 | 9701 | return false; | ||
4450 | 9702 | |||
4451 | 9703 | /* GtkMenuBar catches button events on children with submenus, | ||
4452 | 9704 | so we need to see if the actual widget is the menubar, and if | ||
4453 | 9705 | it is an item, we forward it to the actual widget. */ | ||
4454 | 9706 | if (toolitem is Gtk.Box || toolitem is Gtk.MenuBar) { | ||
4455 | 9707 | if (toolitem.get_window () != event.window) | ||
4456 | 9708 | return false; | ||
4457 | 9709 | |||
4458 | 9710 | toolbar_popup_context_menu_cb (toolitem is Gtk.Bin && ((Gtk.Bin) toolitem).get_child () != null ? | ||
4459 | 9711 | toolitem.get_parent () : toolitem, | ||
4460 | 9712 | (int) event.x, (int) event.y, (int) event.button); | ||
4461 | 9713 | return true; | ||
4462 | 9714 | } else if (toolitem is Gtk.MenuItem) | ||
4463 | 9715 | return toolitem.button_press_event (event);; | ||
4464 | 9716 | |||
4465 | 9717 | return false; | ||
4466 | 9718 | } | ||
4467 | 9719 | |||
4468 | 9720 | bool menu_item_middle_click_event_cb (Gtk.Widget toolitem, Gdk.EventButton event) { | ||
4469 | 9721 | if (event_new_tab (event)) { | ||
4470 | 9722 | var action = ((Gtk.ToolItem) toolitem).related_action; | ||
4471 | 9723 | action.set_data<bool> ("midori-middle-click", true); | ||
4472 | 9724 | |||
4473 | 9725 | return navigation_activate (action); | ||
4474 | 9726 | } | ||
4475 | 9727 | return false; | ||
4476 | 9728 | } | ||
4477 | 9729 | |||
4478 | 9730 | void action_bookmark_add_activate (Gtk.Action action) { | ||
4479 | 9731 | Gtk.Widget proxy = null; | ||
4480 | 9732 | foreach (var p in action.get_proxies ()) { | ||
4481 | 9733 | if (p is Gtk.ToolItem) { | ||
4482 | 9734 | proxy = p; | ||
4483 | 9735 | break; | ||
4484 | 9736 | } | ||
4485 | 9737 | } | ||
4486 | 9738 | |||
4487 | 9739 | if (action.name == "BookmarkFolderAdd") | ||
4488 | 9740 | edit_bookmark_dialog_new (null, true, true, proxy); | ||
4489 | 9741 | else | ||
4490 | 9742 | edit_bookmark_dialog_new (null, true, false, proxy); | ||
4491 | 9743 | } | ||
4492 | 9744 | |||
4493 | 9745 | struct BookmarkClient { | ||
4494 | 9746 | string path; | ||
4495 | 9747 | string name; | ||
4496 | 9748 | string icon; | ||
4497 | 9749 | } | ||
4498 | 9750 | |||
4499 | 9751 | static const BookmarkClient[] bookmark_clients = { | ||
4500 | 9752 | { ".local/share/data/Arora/bookmarks.xbel", N_("Arora"), "arora" }, | ||
4501 | 9753 | { ".kazehakase/bookmarks.xml", N_("Kazehakase"), "kazehakase-icon" }, | ||
4502 | 9754 | { ".opera/bookmarks.adr", N_("Opera"), "opera" }, | ||
4503 | 9755 | { ".kde/share/apps/konqueror/bookmarks.xml", N_("Konqueror"), "konqueror" }, | ||
4504 | 9756 | { ".gnome2/epiphany/bookmarks.rdf", N_("Epiphany"), "epiphany" }, | ||
4505 | 9757 | { ".mozilla/firefox/*/bookmarks.html", N_("Firefox (%s)"), "firefox" }, | ||
4506 | 9758 | { ".config/midori/bookmarks.xbel", N_("Midori 0.2.6"), "midori" }, | ||
4507 | 9759 | }; | ||
4508 | 9760 | |||
4509 | 9761 | void action_bookmarks_import_activate (Gtk.Action action) { | ||
4510 | 9762 | var dialog = new Gtk.Dialog.with_buttons (_("Import bookmarks…"), this, | ||
4511 | 9763 | Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.Stock.CANCEL, Gtk.ResponseType.CANCEL, | ||
4512 | 9764 | _("_Import bookmarks"), Gtk.ResponseType.ACCEPT); | ||
4513 | 9765 | var content_area = dialog.get_content_area (); | ||
4514 | 9766 | dialog.icon_name = Stock.BOOKMARKS; | ||
4515 | 9767 | |||
4516 | 9768 | dialog.border_width = 5; | ||
4517 | 9769 | content_area.border_width = 5; | ||
4518 | 9770 | var sizegroup = new Gtk.SizeGroup (Gtk.SizeGroupMode.HORIZONTAL); | ||
4519 | 9771 | |||
4520 | 9772 | var hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 8); | ||
4521 | 9773 | hbox.border_width = 5; | ||
4522 | 9774 | var label = new Gtk.Label.with_mnemonic (_("_Application:")); | ||
4523 | 9775 | sizegroup.add_widget (label); | ||
4524 | 9776 | hbox.pack_start (label, false, false, 0); | ||
4525 | 9777 | var model = new Gtk.ListStore (4, typeof (string), typeof (string), typeof (string), typeof (int)); | ||
4526 | 9778 | var combo = new Gtk.ComboBox.with_model (model); | ||
4527 | 9779 | var pix_renderer = new Gtk.CellRendererPixbuf (); | ||
4528 | 9780 | combo.pack_start (pix_renderer, false); | ||
4529 | 9781 | combo.add_attribute (pix_renderer, "icon-name", 1); | ||
4530 | 9782 | combo.add_attribute (pix_renderer, "width", 3); | ||
4531 | 9783 | var text_renderer = new Gtk.CellRendererText (); | ||
4532 | 9784 | combo.pack_start (text_renderer, true); | ||
4533 | 9785 | combo.add_attribute (text_renderer, "text", 0); | ||
4534 | 9786 | |||
4535 | 9787 | int icon_width = 16; | ||
4536 | 9788 | Gtk.icon_size_lookup_for_settings (get_settings (), Gtk.IconSize.MENU, out icon_width, null); | ||
4537 | 9789 | |||
4538 | 9790 | foreach (var client in bookmark_clients) { | ||
4539 | 9791 | var location = client.path; | ||
4540 | 9792 | var client_name = client.name; | ||
4541 | 9793 | |||
4542 | 9794 | /* Interpret * as 'any folder' */ | ||
4543 | 9795 | if (location.index_of ("*") > -1) { | ||
4544 | 9796 | var parts = location.split ("*", 2); | ||
4545 | 9797 | var path = Path.build_filename (Environment.get_home_dir (), parts[0]); | ||
4546 | 9798 | try { | ||
4547 | 9799 | var dir = Dir.open (path); | ||
4548 | 9800 | string name; | ||
4549 | 9801 | while ((name = dir.read_name ()) != null) { | ||
4550 | 9802 | var file = Path.build_filename (path, name, parts[1]); | ||
4551 | 9803 | if (Posix.access (file, Posix.F_OK) == 0) { | ||
4552 | 9804 | /* If name is XYZ.Name, we use Name only */ | ||
4553 | 9805 | var real_name = name.split (".", 2); | ||
4554 | 9806 | var display = _(client_name).index_of ("%s") > -1 | ||
4555 | 9807 | ? _(client_name).printf (real_name.length > 1 ? real_name[1] : name) | ||
4556 | 9808 | : _(client_name); | ||
4557 | 9809 | model.insert_with_values (null, int.MAX, | ||
4558 | 9810 | 0, display, 1, client.icon, | ||
4559 | 9811 | 2, file, 3, icon_width); | ||
4560 | 9812 | } | ||
4561 | 9813 | } | ||
4562 | 9814 | } catch (Error e) {} | ||
4563 | 9815 | continue; | ||
4564 | 9816 | } | ||
4565 | 9817 | |||
4566 | 9818 | var path = Path.build_filename (Environment.get_home_dir (), location); | ||
4567 | 9819 | if (Posix.access (path, Posix.F_OK) == 0) | ||
4568 | 9820 | model.insert_with_values (null, int.MAX, | ||
4569 | 9821 | 0, _(client_name), 1, client.icon, | ||
4570 | 9822 | 2, path, 3, icon_width); | ||
4571 | 9823 | } | ||
4572 | 9824 | |||
4573 | 9825 | model.insert_with_values (null, int.MAX, | ||
4574 | 9826 | 0, _("Import from XBEL or HTML file"), 1, null, 2, null, 3, icon_width); | ||
4575 | 9827 | combo.active = 0; | ||
4576 | 9828 | hbox.pack_start (combo, true, true, 0); | ||
4577 | 9829 | content_area.pack_start (hbox, false, true, 0); | ||
4578 | 9830 | |||
4579 | 9831 | var combobox_folder = bookmark_folder_button_new (bookmarks, 0); | ||
4580 | 9832 | content_area.pack_start (combobox_folder, false, true, 0); | ||
4581 | 9833 | content_area.show_all (); | ||
4582 | 9834 | |||
4583 | 9835 | dialog.set_default_response (Gtk.ResponseType.ACCEPT); | ||
4584 | 9836 | if (Midori.Dialog.run (dialog) == Gtk.ResponseType.ACCEPT) { | ||
4585 | 9837 | Gtk.TreeIter iter; | ||
4586 | 9838 | string? path = null; | ||
4587 | 9839 | |||
4588 | 9840 | if (combo.get_active_iter (out iter)) | ||
4589 | 9841 | model.@get (iter, 2, out path); | ||
4590 | 9842 | var selected = combobox_folder.get_active (); | ||
4591 | 9843 | |||
4592 | 9844 | dialog.destroy (); | ||
4593 | 9845 | if (path == null) { | ||
4594 | 9846 | var file_dialog = new FileChooserDialog (_("Import from a file"), this, Gtk.FileChooserAction.OPEN); | ||
4595 | 9847 | if (Midori.Dialog.run (file_dialog) == Gtk.ResponseType.OK) | ||
4596 | 9848 | path = file_dialog.get_filename (); | ||
4597 | 9849 | file_dialog.destroy (); | ||
4598 | 9850 | } | ||
4599 | 9851 | |||
4600 | 9852 | var bookmarks = new Katze.Array (typeof (Katze.Array)); | ||
4601 | 9853 | if (path != null) { | ||
4602 | 9854 | try { | ||
4603 | 9855 | array_from_file (bookmarks, path, null); | ||
4604 | 9856 | } catch (Error e) { | ||
4605 | 9857 | Sokoke.message_dialog (Gtk.MessageType.ERROR, _("Failed to import bookmarks"), e.message, false); | ||
4606 | 9858 | } | ||
4607 | 9859 | } | ||
4608 | 9860 | this.bookmarks.import_array (bookmarks, selected); | ||
4609 | 9861 | } else | ||
4610 | 9862 | dialog.destroy (); | ||
4611 | 9863 | } | ||
4612 | 9864 | |||
4613 | 9865 | void action_bookmarks_export_activate (Gtk.Action action) { | ||
4614 | 9866 | string? path = null; | ||
4615 | 9867 | string format; | ||
4616 | 9868 | |||
4617 | 9869 | var wrong_format = true; | ||
4618 | 9870 | |||
4619 | 9871 | while (wrong_format) { | ||
4620 | 9872 | var file_dialog = new FileChooserDialog (_("Save file as"), this, Gtk.FileChooserAction.SAVE); | ||
4621 | 9873 | file_dialog.set_current_name ("bookmarks.xbel"); | ||
4622 | 9874 | |||
4623 | 9875 | Gtk.FileFilter filter; | ||
4624 | 9876 | |||
4625 | 9877 | filter = new Gtk.FileFilter (); | ||
4626 | 9878 | filter.set_filter_name (_("XBEL Bookmarks")); | ||
4627 | 9879 | filter.add_mime_type ("application/xml"); | ||
4628 | 9880 | filter.add_pattern ("*.xbel"); | ||
4629 | 9881 | file_dialog.add_filter (filter); | ||
4630 | 9882 | |||
4631 | 9883 | filter = new Gtk.FileFilter (); | ||
4632 | 9884 | filter.set_name (_("Netscape Bookmarks")); | ||
4633 | 9885 | filter.add_mime_type ("text/html"); | ||
4634 | 9886 | filter.add_pattern ("*.html"); | ||
4635 | 9887 | file_dialog.add_filter (filter); | ||
4636 | 9888 | |||
4637 | 9889 | if (Dialog.run (file_dialog) == Gtk.ResponseType.OK) | ||
4638 | 9890 | path = file_dialog.get_filename (); | ||
4639 | 9891 | file_dialog.destroy (); | ||
4640 | 9892 | |||
4641 | 9893 | if (path == null) | ||
4642 | 9894 | return; | ||
4643 | 9895 | |||
4644 | 9896 | if (path.has_suffix (".xbel")) | ||
4645 | 9897 | format = "xbel"; | ||
4646 | 9898 | else if (path.has_suffix (".html")) | ||
4647 | 9899 | format = "netscape"; | ||
4648 | 9900 | else { | ||
4649 | 9901 | Sokoke.message_dialog (Gtk.MessageType.ERROR, | ||
4650 | 9902 | _("Midori can only export to XBEL (*.xbel) and Netscape (*.html)"), "", true); | ||
4651 | 9903 | path = null; | ||
4652 | 9904 | continue; | ||
4653 | 9905 | } | ||
4654 | 9906 | |||
4655 | 9907 | wrong_format = false; | ||
4656 | 9908 | |||
4657 | 9909 | var bookmarks = bookmarks.query_recursive ("*", "parentid IS null", null, true); | ||
4658 | 9910 | try { | ||
4659 | 9911 | array_to_file (bookmarks, path, format); | ||
4660 | 9912 | } catch (Error e) { | ||
4661 | 9913 | Sokoke.message_dialog (Gtk.MessageType.ERROR, _("Failed to export bookmarks"), e.message, false); | ||
4662 | 9914 | } | ||
4663 | 9915 | } | ||
4664 | 9916 | } | ||
4665 | 9917 | |||
4666 | 9918 | Gtk.Dialog? search_engines_dialog = null; | ||
4667 | 9919 | void action_manage_search_engines_activate (Gtk.Action action) { | ||
4668 | 9920 | if (search_engines_dialog == null) { | ||
4669 | 9921 | search_engines_dialog = ((SearchAction) action_group.get_action ("Search")).get_dialog (); | ||
4670 | 9922 | search_engines_dialog.destroy.connect (() => search_engines_dialog = null); | ||
4671 | 9923 | search_engines_dialog.show (); | ||
4672 | 9924 | } | ||
4673 | 9925 | else | ||
4674 | 9926 | search_engines_dialog.present (); | ||
4675 | 9927 | } | ||
4676 | 9928 | |||
4677 | 9929 | Gtk.Dialog? clear_private_data_dialog = null; | ||
4678 | 9930 | void action_clear_private_data_activate (Gtk.Action action) { | ||
4679 | 9931 | if (clear_private_data_dialog == null) { | ||
4680 | 9932 | clear_private_data_dialog = private_data_get_dialog (this); | ||
4681 | 9933 | clear_private_data_dialog.destroy.connect (() => clear_private_data_dialog = null); | ||
4682 | 9934 | clear_private_data_dialog.show (); | ||
4683 | 9935 | } else | ||
4684 | 9936 | clear_private_data_dialog.present (); | ||
4685 | 9937 | } | ||
4686 | 9938 | |||
4687 | 9939 | void action_inspect_page_activate (Gtk.Action action) { | ||
4688 | 9940 | var view = get_current_tab (); | ||
4689 | 9941 | var web_view = view.web_view; | ||
4690 | 9942 | var inspector = web_view.get_inspector (); | ||
4691 | 9943 | inspector.show (); | ||
4692 | 9944 | } | ||
4693 | 9945 | |||
4694 | 9946 | void action_tab_move_activate (Gtk.Action action) { | ||
4695 | 9947 | var name = action.name; | ||
4696 | 9948 | int new_pos; | ||
4697 | 9949 | var cur_pos = get_current_page (); | ||
4698 | 9950 | var widget = get_nth_tab (cur_pos); | ||
4699 | 9951 | |||
4700 | 9952 | if (name == "TabMoveFirst") | ||
4701 | 9953 | new_pos = 0; | ||
4702 | 9954 | else if (name == "TabMoveBackward") { | ||
4703 | 9955 | if (cur_pos > 0) | ||
4704 | 9956 | new_pos = cur_pos - 1; | ||
4705 | 9957 | else | ||
4706 | 9958 | new_pos = get_n_pages () - 1; | ||
4707 | 9959 | } else if (name == "TabMoveForward") { | ||
4708 | 9960 | if (cur_pos == (get_n_pages () - 1)) | ||
4709 | 9961 | new_pos = 0; | ||
4710 | 9962 | else | ||
4711 | 9963 | new_pos = cur_pos + 1; | ||
4712 | 9964 | } else if (name == "TabMoveLast") | ||
4713 | 9965 | new_pos = get_n_pages () - 1; | ||
4714 | 9966 | else | ||
4715 | 9967 | assert_not_reached (); | ||
4716 | 9968 | |||
4717 | 9969 | notebook.move ((Tab) widget, new_pos); | ||
4718 | 9970 | move_tab (notebook, cur_pos, new_pos); | ||
4719 | 9971 | } | ||
4720 | 9972 | |||
4721 | 9973 | void action_tab_previous_activate (Gtk.Action action) { | ||
4722 | 9974 | set_current_page (get_current_page () - 1); | ||
4723 | 9975 | } | ||
4724 | 9976 | |||
4725 | 9977 | void action_tab_next_activate (Gtk.Action action) { | ||
4726 | 9978 | /* Advance one tab or jump to the first one if we are at the last one */ | ||
4727 | 9979 | var n = get_current_page (); | ||
4728 | 9980 | if (n == get_n_pages () - 1) | ||
4729 | 9981 | n = -1; | ||
4730 | 9982 | set_current_page (n + 1); | ||
4731 | 9983 | } | ||
4732 | 9984 | |||
4733 | 9985 | void action_tab_current_activate (Gtk.Action action) { | ||
4734 | 9986 | var view = get_current_tab (); | ||
4735 | 9987 | view.grab_focus (); | ||
4736 | 9988 | } | ||
4737 | 9989 | |||
4738 | 9990 | void action_next_view_activate (Gtk.Action action) { | ||
4739 | 9991 | get_current_tab ().grab_focus (); | ||
4740 | 9992 | } | ||
4741 | 9993 | |||
4742 | 9994 | void action_tab_minimize_activate (Gtk.Action action) { | ||
4743 | 9995 | var view = get_current_tab (); | ||
4744 | 9996 | view.minimized = !view.minimized; | ||
4745 | 9997 | } | ||
4746 | 9998 | |||
4747 | 9999 | void action_tab_duplicate_activate (Gtk.Action action) { | ||
4748 | 10000 | var view = (View) action.get_data<Tab> ("tab"); | ||
4749 | 10001 | if (view == null) | ||
4750 | 10002 | view = (View) get_current_tab (); | ||
4751 | 10003 | view.duplicate (); | ||
4752 | 10004 | } | ||
4753 | 10005 | |||
4754 | 10006 | void action_tab_close_other_activate (Gtk.Action action) { | ||
4755 | 10007 | var view = get_current_tab (); | ||
4756 | 10008 | foreach (var tab in get_tabs ()) { | ||
4757 | 10009 | if (tab != view) | ||
4758 | 10010 | close_tab (tab); | ||
4759 | 10011 | } | ||
4760 | 10012 | } | ||
4761 | 10013 | |||
4762 | 10014 | static const string[] credits_authors = { "Christian Dywan <christian@twotoasts.de>" }; | ||
4763 | 10015 | static const string[] credits_documenters = { "Christian Dywan <christian@twotoasts.de>" }; | ||
4764 | 10016 | static const string[] credits_artists = { "Nancy Runge <nancy@twotoasts.de>" }; | ||
4765 | 10017 | |||
4766 | 10018 | string get_docs (bool error) | ||
4767 | 10019 | { | ||
4768 | 10020 | #if G_OS_WIN32 | ||
4769 | 10021 | var path = Paths.get_data_filename ("doc/midori/faq.html", false); | ||
4770 | 10022 | try { | ||
4771 | 10023 | return Filename.to_uri (path, null); | ||
4772 | 10024 | } catch (Error e) {} | ||
4773 | 10025 | |||
4774 | 10026 | return ""; | ||
4775 | 10027 | #else | ||
4776 | 10028 | var path = Paths.get_res_filename ("faq.html"); | ||
4777 | 10029 | bool found = Posix.access (path, Posix.F_OK) == 0; | ||
4778 | 10030 | if (found) { | ||
4779 | 10031 | try { | ||
4780 | 10032 | return Filename.to_uri (path, null); | ||
4781 | 10033 | } catch (Error e) {} | ||
4782 | 10034 | } | ||
4783 | 10035 | return "file://" + DOCDIR + "/faq.html"; | ||
4784 | 10036 | #endif | ||
4785 | 10037 | } | ||
4786 | 10038 | |||
4787 | 10039 | void action_about_activate (Gtk.Action action) { | ||
4788 | 10040 | var comments = "%s\n%s".printf ( | ||
4789 | 10041 | _("A lightweight web browser."), | ||
4790 | 10042 | _("See about:version for version info.")); | ||
4791 | 10043 | var license = | ||
4792 | 10044 | _("This library is free software; you can redistribute it and/or " + | ||
4793 | 10045 | "modify it under the terms of the GNU Lesser General Public " + | ||
4794 | 10046 | "License as published by the Free Software Foundation; either " + | ||
4795 | 10047 | "version 2.1 of the License, or (at your option) any later version."); | ||
4796 | 10048 | |||
4797 | 10049 | #if HAVE_GRANITE | ||
4798 | 10050 | var docs = get_docs (false); | ||
4799 | 10051 | /* Avoid granite_widgets_show_about_dialog for invalid memory and crashes */ | ||
4800 | 10052 | /* FIXME: granite: should return GtkWidget* like GTK+ */ | ||
4801 | 10053 | var dialog = new Granite.Widgets.AboutDialog (); | ||
4802 | 10054 | dialog.@set ( | ||
4803 | 10055 | "translate", "https://translations.xfce.org/projects/p/midori/", | ||
4804 | 10056 | "bug", PACKAGE_BUGREPORT, | ||
4805 | 10057 | "help", docs, | ||
4806 | 10058 | "copyright", "2007-2013 Christian Dywan", | ||
4807 | 10059 | #else | ||
4808 | 10060 | var dialog = new Gtk.AboutDialog (); | ||
4809 | 10061 | dialog.@set ( | ||
4810 | 10062 | "wrap-license", true, | ||
4811 | 10063 | "copyright", "Copyright © 2007-2013 Christian Dywan", | ||
4812 | 10064 | #endif | ||
4813 | 10065 | "transient-for", this, | ||
4814 | 10066 | "logo-icon-name", icon_name, | ||
4815 | 10067 | "program-name", PACKAGE_NAME, | ||
4816 | 10068 | "version", PACKAGE_VERSION, | ||
4817 | 10069 | "comments", comments, | ||
4818 | 10070 | "website", "http://www.midori-browser.org", | ||
4819 | 10071 | "authors", credits_authors, | ||
4820 | 10072 | "documenters", credits_documenters, | ||
4821 | 10073 | "artists", credits_artists, | ||
4822 | 10074 | "license", license, | ||
4823 | 10075 | "translator-credits", _("translator-credits")); | ||
4824 | 10076 | dialog.show (); | ||
4825 | 10077 | dialog.response.connect ((dialog, response) => dialog.destroy ()); | ||
4826 | 10078 | } | ||
4827 | 10079 | |||
4828 | 10080 | void action_help_link_activate (Gtk.Action action) { | ||
4829 | 10081 | var action_name = action.name; | ||
4830 | 10082 | string? uri = null; | ||
4831 | 10083 | if (action_name.has_prefix ("HelpFAQ")) | ||
4832 | 10084 | uri = get_docs (true); | ||
4833 | 10085 | else if (action_name.has_prefix ("HelpBugs")) { | ||
4834 | 10086 | try { | ||
4835 | 10087 | Process.spawn_command_line_async ("ubuntu-bug " + PACKAGE_NAME); | ||
4836 | 10088 | } catch (Error e) { | ||
4837 | 10089 | uri = PACKAGE_BUGREPORT; | ||
4838 | 10090 | } | ||
4839 | 10091 | } | ||
4840 | 10092 | |||
4841 | 10093 | if (uri != null) | ||
4842 | 10094 | set_current_tab (add_uri (uri)); | ||
4843 | 10095 | } | ||
4844 | 10096 | |||
4845 | 10097 | void action_panel_activate (Gtk.Action action) { | ||
4846 | 10098 | var active = ((Gtk.ToggleAction) action).active; | ||
4847 | 10099 | settings.show_panel = active; | ||
4848 | 10100 | Sokoke.widget_set_visible (panel, active); | ||
4849 | 10101 | } | ||
4850 | 10102 | |||
4851 | 10103 | bool panel_timeout (Gtk.Paned hpaned) { | ||
4852 | 10104 | settings.last_panel_position = hpaned.position; | ||
4853 | 10105 | _panel_timeout = 0; | ||
4854 | 10106 | return false; | ||
4855 | 10107 | } | ||
4856 | 10108 | |||
4857 | 10109 | void panel_notify_position_cb (Object hpaned, ParamSpec pspec) { | ||
4858 | 10110 | if (_panel_timeout == 0) | ||
4859 | 10111 | _panel_timeout = Timeout.add_seconds (5, () => panel_timeout ((Gtk.Paned) hpaned)); | ||
4860 | 10112 | } | ||
4861 | 10113 | |||
4862 | 10114 | bool panel_cycle_child_focus_cb (Gtk.Widget hpaned, bool reversed) { | ||
4863 | 10115 | /* Default cycle goes between all GtkPaned widgets. | ||
4864 | 10116 | If focus is in the panel, focus the location as if it's a paned. | ||
4865 | 10117 | If nothing is focussed, simply go to the location. | ||
4866 | 10118 | Be sure to suppress the default because the signal can recurse. */ | ||
4867 | 10119 | var focus = get_focus (); | ||
4868 | 10120 | if (focus.get_ancestor (typeof (Panel)) != null | ||
4869 | 10121 | || focus.get_ancestor (typeof (Gtk.Paned)) == null) { | ||
4870 | 10122 | Signal.stop_emission_by_name (hpaned, "cycle-child-focus"); | ||
4871 | 10123 | activate_action ("Location"); | ||
4872 | 10124 | return true; | ||
4873 | 10125 | } | ||
4874 | 10126 | return false; | ||
4875 | 10127 | } | ||
4876 | 10128 | |||
4877 | 10129 | void panel_notify_page_cb (Object panel, ParamSpec pspec) { | ||
4878 | 10130 | var page = ((Panel) panel).page; | ||
4879 | 10131 | if (page > -1) | ||
4880 | 10132 | settings.last_panel_page = page; | ||
4881 | 10133 | } | ||
4882 | 10134 | |||
4883 | 10135 | void panel_notify_show_titles_cb (Object object, ParamSpec pspec) { | ||
4884 | 10136 | var panel = (Panel) object; | ||
4885 | 10137 | var signal_id = settings.get_data<ulong> ("handler-settings-notify"); | ||
4886 | 10138 | |||
4887 | 10139 | SignalHandler.block (settings, signal_id); | ||
4888 | 10140 | settings.compact_sidepanel = !panel.show_titles; | ||
4889 | 10141 | SignalHandler.unblock (settings, signal_id); | ||
4890 | 10142 | } | ||
4891 | 10143 | |||
4892 | 10144 | void panel_notify_right_aligned_cb (Object object, ParamSpec pspec) { | ||
4893 | 10145 | var panel = (Panel) object; | ||
4894 | 10146 | |||
4895 | 10147 | var right_aligned = panel.right_aligned; | ||
4896 | 10148 | var hpaned = (Gtk.Paned) panel.get_parent (); | ||
4897 | 10149 | var vpaned = notebook.get_parent (); | ||
4898 | 10150 | var paned_position = hpaned.position; | ||
4899 | 10151 | |||
4900 | 10152 | Gtk.Allocation allocation; | ||
4901 | 10153 | hpaned.get_allocation (out allocation); | ||
4902 | 10154 | var paned_size = allocation.width; | ||
4903 | 10155 | |||
4904 | 10156 | settings.right_align_sidepanel = right_aligned; | ||
4905 | 10157 | |||
4906 | 10158 | panel.@ref (); | ||
4907 | 10159 | vpaned.@ref (); | ||
4908 | 10160 | hpaned.remove (panel); | ||
4909 | 10161 | hpaned.remove (vpaned); | ||
4910 | 10162 | if (right_aligned) { | ||
4911 | 10163 | hpaned.pack1 (vpaned, true, false); | ||
4912 | 10164 | hpaned.pack2 (panel, false, false); | ||
4913 | 10165 | } else { | ||
4914 | 10166 | hpaned.pack1 (panel, false, false); | ||
4915 | 10167 | hpaned.pack2 (vpaned, true, false); | ||
4916 | 10168 | } | ||
4917 | 10169 | hpaned.position = paned_size - paned_position; | ||
4918 | 10170 | panel.unref (); | ||
4919 | 10171 | vpaned.unref (); | ||
4920 | 10172 | } | ||
4921 | 10173 | |||
4922 | 10174 | bool panel_close_cb (Panel panel) { | ||
4923 | 10175 | action_set_active ("Panel", false); | ||
4924 | 10176 | return false; | ||
4925 | 10177 | } | ||
4926 | 10178 | |||
4927 | 10179 | void switched_tab_cb (Notebook notebook, Tab? old_tab, Tab new_tab) { | ||
4928 | 10180 | if (old_tab != null) { | ||
4929 | 10181 | var action = action_group.get_action ("Location"); | ||
4930 | 10182 | var text = ((LocationAction) action).get_text (); | ||
4931 | 10183 | old_tab.set_data<string> ("midori-browser-typed-text", text); | ||
4932 | 10184 | } | ||
4933 | 10185 | |||
4934 | 10186 | return_if_fail (new_tab is View); | ||
4935 | 10187 | return_if_fail (new_tab != old_tab); | ||
4936 | 10188 | |||
4937 | 10189 | var new_view = (View) new_tab; | ||
4938 | 10190 | var uri = new_view.get_data<string> ("midori-browser-typed-text"); | ||
4939 | 10191 | if (uri == null) | ||
4940 | 10192 | uri = new_view.get_display_uri (); | ||
4941 | 10193 | title = new_view.get_display_title (); | ||
4942 | 10194 | var action = (LocationAction) action_group.get_action ("Location"); | ||
4943 | 10195 | action.set_text (uri); | ||
4944 | 10196 | if (Paths.get_runtime_mode () == RuntimeMode.APP) | ||
4945 | 10197 | icon = new_view.get_icon (); | ||
4946 | 10198 | |||
4947 | 10199 | switch_tab (old_tab, new_view); | ||
4948 | 10200 | _set_statusbar_text (new_view, null); | ||
4949 | 10201 | update_interface (new_view); | ||
4950 | 10202 | update_progress (new_view); | ||
4951 | 10203 | } | ||
4952 | 10204 | |||
4953 | 10205 | void notify_tab_cb (Object? object, ParamSpec? pspec) { | ||
4954 | 10206 | freeze_notify (); | ||
4955 | 10207 | notify_property ("uri"); | ||
4956 | 10208 | notify_property ("uri"); | ||
4957 | 10209 | notify_property ("title"); | ||
4958 | 10210 | notify_property ("tab"); | ||
4959 | 10211 | thaw_notify (); | ||
4960 | 10212 | } | ||
4961 | 10213 | |||
4962 | 10214 | void tab_moved_cb (Gtk.Widget notebook, Tab tab, uint page_num) { | ||
4963 | 10215 | var item = ((View) tab).get_proxy_item (); | ||
4964 | 10216 | proxy_array.move_item (item, (int) page_num); | ||
4965 | 10217 | } | ||
4966 | 10218 | |||
4967 | 10219 | void notebook_create_window_cb (Gtk.Widget notebook, Gtk.Widget widget, int x, int y) { | ||
4968 | 10220 | var view = (View) widget; | ||
4969 | 10221 | var new_browser = new_window (null); | ||
4970 | 10222 | if (new_browser != null) { | ||
4971 | 10223 | new_browser.move (x, y); | ||
4972 | 10224 | view.@ref (); | ||
4973 | 10225 | disconnect_tab (view); | ||
4974 | 10226 | ((Notebook) notebook).remove (view); | ||
4975 | 10227 | new_browser.add_tab (view); | ||
4976 | 10228 | view.unref (); | ||
4977 | 10229 | } | ||
4978 | 10230 | } | ||
4979 | 10231 | |||
4980 | 10232 | void notebook_new_tab_cb (Gtk.Widget notebook) { | ||
4981 | 10233 | var view = add_uri ("about:new"); | ||
4982 | 10234 | set_current_tab (view); | ||
4983 | 10235 | } | ||
4984 | 10236 | |||
4985 | 10237 | void notebook_context_menu_cb (Notebook notebook, ContextAction menu) { | ||
4986 | 10238 | menu.add_action_group (action_group); | ||
4987 | 10239 | menu.add (null); | ||
4988 | 10240 | menu.add_by_name ("TabNew"); | ||
4989 | 10241 | menu.add_by_name ("UndoTabClose"); | ||
4990 | 10242 | } | ||
4991 | 10243 | |||
4992 | 10244 | void notebook_tab_context_menu_cb (Notebook notebook, Tab tab, ContextAction menu) { | ||
4993 | 10245 | menu.add_action_group (action_group); | ||
4994 | 10246 | menu.add (null); | ||
4995 | 10247 | menu.add_by_name ("TabNew"); | ||
4996 | 10248 | menu.add_by_name ("UndoTabClose"); | ||
4997 | 10249 | if (tab is View) { | ||
4998 | 10250 | var action = new Gtk.Action ("TabDuplicate", _("_Duplicate Current Tab"), null, null); | ||
4999 | 10251 | action.set_data<Tab> ("tab", tab); | ||
5000 | 10252 | action.activate.connect (action_tab_duplicate_activate); |
The diff has been truncated for viewing.