Merge lp:~junrrein/pantheon-files/progressuihandler-to-vala into lp:~elementary-apps/pantheon-files/trunk

Proposed by Julián Unrrein
Status: Merged
Approved by: David Gomes
Approved revision: 1350
Merged at revision: 1302
Proposed branch: lp:~junrrein/pantheon-files/progressuihandler-to-vala
Merge into: lp:~elementary-apps/pantheon-files/trunk
Prerequisite: lp:~junrrein/pantheon-files/unity-quicklist-to-vala
Diff against target: 1313 lines (+444/-773)
8 files modified
libcore/marlincore-C.vapi (+23/-0)
src/Application.vala (+1/-1)
src/CMakeLists.txt (+2/-1)
src/ProgressUIHandler.vala (+413/-0)
src/QuicklistHandler.vala (+1/-9)
src/marlin-progress-ui-handler.c (+0/-691)
src/marlin-progress-ui-handler.h (+0/-64)
src/marlin.vapi (+4/-7)
To merge this branch: bzr merge lp:~junrrein/pantheon-files/progressuihandler-to-vala
Reviewer Review Type Date Requested Status
David Gomes (community) Approve
Cody Garver (community) Approve
Review via email: mp+179622@code.launchpad.net

Commit message

Port marlin-progress-ui-handler to Vala, also fixing bug #1208994.

Description of the change

Port marlin-progress-ui-handler to Vala, and fix bug #1208994 in the process.

What needs to be tested is basically the notification policy for in-progress files operations. Taken from the code:

    /* Our policy for showing progress notification is the following:
     * - File operations that end within two seconds do not get notified in any way.
     * - If no file operations are running, and one passes the two seconds
     * timeout, a window is displayed with the progress.
     * - If the window is closed, we show a resident notification, or a status icon, depending on
     * the capabilities of the notification daemon running in the session.
     * - If some file operations are running, and another one passes the two seconds
     * timeout, and the window is showing, we add it to the window directly.
     * - In the same case, but when the window is not showing, we update the resident
     * notification, changing its message, or the status icon's tooltip.
     * - When one file operation finishes, if it's not the last one, we only update the
     * resident notification's message, or the status icon's tooltip.
     * - In the same case, if it's the last one, we close the resident notification,
     * or the status icon, and trigger a transient one.
     * - In the same case, but the window was showing, we just hide the window.
     */

To post a comment you must log in.
Revision history for this message
Cody Garver (codygarver) wrote :

Testing went normally.

review: Approve
Revision history for this message
David Gomes (davidgomes) wrote :

Newline after 360, 381, 431, 441. I'll also be testing this and the other branches under Unity of course.

review: Needs Fixing
Revision history for this message
David Gomes (davidgomes) wrote :

>/home/david/src/pantheon-files/unity-quicklist-to-vala/src/marlin-places-sidebar.c:34:25: fatal error: marlin-vala.h: No such file or directory
compilation terminated.

Doesn't compile for me on Ubuntu 13.04.

Revision history for this message
David Gomes (davidgomes) wrote :

Actually, disregard that last comment it was meant to be posted here - https://code.launchpad.net/~junrrein/pantheon-files/unity-quicklist-to-vala/+merge/178843 (and I just posted it there too).

This branch compiles and runs just fine. I didn't test *everything* but side. Unity displayed the progress of long file operations just fine and there were no bugs regarding that so I'm approving this test-wise. Now all that needs to be done are the code style fixes and it'll be ready to merge.

review: Approve
Revision history for this message
David Gomes (davidgomes) wrote :

It also properly fixes bug 1208994.

1346. By Julián Unrrein

Merge from parent branch.

1347. By Julián Unrrein

Improve code style.

Revision history for this message
Julián Unrrein (junrrein) wrote :

Applied code style suggestions.

See diff lines 266-267. It's the same question I asked in my other branch. Is the list being properly freed?

1348. By Julián Unrrein

Remove unneeded methods from QuicklistHandler.vala.

1349. By Julián Unrrein

Remove redundant ternary operation.

1350. By Julián Unrrein

Remove TODO comment.

Revision history for this message
Julián Unrrein (junrrein) wrote :

Freeing the list explicitly is not necessary - Vala frees it automatically when it is pointed to null.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'libcore/marlincore-C.vapi'
2--- libcore/marlincore-C.vapi 2013-08-06 20:20:44 +0000
3+++ libcore/marlincore-C.vapi 2013-08-16 22:51:52 +0000
4@@ -106,6 +106,29 @@
5 public void undo (UndoFinishCallback? cb);
6 public void redo (UndoFinishCallback? cb);
7 }
8+
9+ [CCode (cheader_filename = "marlin-progress-info.h")]
10+ public class Progress.Info : Object {
11+ public Info ();
12+ public signal void started ();
13+ public signal void finished ();
14+ public signal void progress_changed ();
15+ public void cancel ();
16+ public double get_progress ();
17+ public double get_current ();
18+ public double get_total ();
19+ public bool get_is_finished ();
20+ public bool get_is_paused ();
21+ public Cancellable get_cancellable ();
22+ }
23+
24+ [CCode (cheader_filename = "marlin-progress-info-manager.h")]
25+ public class Progress.InfoManager : Object {
26+ public InfoManager ();
27+ public signal void new_progress_info (Progress.Info info);
28+ public void add_new_info (Progress.Info info);
29+ public unowned List<Progress.Info> get_all_infos ();
30+ }
31 }
32
33 [CCode (cprefix = "MarlinFile", lower_case_cprefix = "marlin_file_", cheader_filename = "marlin-file-changes-queue.h")]
34
35=== modified file 'src/Application.vala'
36--- src/Application.vala 2013-08-16 22:51:52 +0000
37+++ src/Application.vala 2013-08-16 22:51:52 +0000
38@@ -41,7 +41,7 @@
39 application_singleton = this;
40 }
41
42- public static new Application get () {
43+ public static new unowned Application get () {
44 if (application_singleton == null)
45 application_singleton = new Marlin.Application ();
46
47
48=== modified file 'src/CMakeLists.txt'
49--- src/CMakeLists.txt 2013-08-16 22:51:52 +0000
50+++ src/CMakeLists.txt 2013-08-16 22:51:52 +0000
51@@ -42,6 +42,7 @@
52 Application.vala
53 main.vala
54 marlin-deep-count.vala
55+ ProgressUIHandler.vala
56 QuicklistHandler.vala
57 View/DiskRenderer.vala
58 View/DirectoryNotFound.vala
59@@ -86,6 +87,7 @@
60 Application.vala
61 main.vala
62 marlin-deep-count.vala
63+ ProgressUIHandler.vala
64 View/DiskRenderer.vala
65 View/DirectoryNotFound.vala
66 View/Window.vala
67@@ -148,7 +150,6 @@
68 fm-columns-view.c
69 marlin-connect-server-dialog.c
70 marlin-connect-server-operation.c
71- marlin-progress-ui-handler.c
72 marlin-progress-info-widget.c
73 ${VALA_C} )
74
75
76=== added file 'src/ProgressUIHandler.vala'
77--- src/ProgressUIHandler.vala 1970-01-01 00:00:00 +0000
78+++ src/ProgressUIHandler.vala 2013-08-16 22:51:52 +0000
79@@ -0,0 +1,413 @@
80+/***
81+ Copyright (C) 2007, 2011 Red Hat, Inc.
82+ Copyright (C) 2013 Julián Unrrein <junrrein@gmail.com>
83+
84+ This program is free software: you can redistribute it and/or modify it
85+ under the terms of the GNU Lesser General Public License version 3, as published
86+ by the Free Software Foundation.
87+
88+ This program is distributed in the hope that it will be useful, but
89+ WITHOUT ANY WARRANTY; without even the implied warranties of
90+ MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
91+ PURPOSE. See the GNU General Public License for more details.
92+
93+ You should have received a copy of the GNU General Public License along
94+ with this program. If not, see <http://www.gnu.org/licenses/>.
95+
96+ Authors: Alexander Larsson <alexl@redhat.com>
97+ Cosimo Cecchi <cosimoc@redhat.com>
98+ Julián Unrrein <junrrein@gmail.com>
99+***/
100+
101+public class Marlin.Progress.UIHandler : Object {
102+
103+ private Marlin.Progress.InfoManager manager = null;
104+
105+ private Gtk.Widget progress_window = null;
106+ private Gtk.Widget window_vbox = null;
107+ private uint active_infos = 0;
108+
109+ private bool notification_supports_persistence = false;
110+ private Notify.Notification progress_notification = null;
111+ private Gtk.StatusIcon status_icon = null;
112+#if HAVE_UNITY
113+ private Marlin.QuicklistHandler quicklist_handler = null;
114+#endif
115+
116+ private const string ACTION_DETAILS = "details";
117+
118+ /* Our policy for showing progress notification is the following:
119+ * - File operations that end within two seconds do not get notified in any way.
120+ * - If no file operations are running, and one passes the two seconds
121+ * timeout, a window is displayed with the progress.
122+ * - If the window is closed, we show a resident notification, or a status icon, depending on
123+ * the capabilities of the notification daemon running in the session.
124+ * - If some file operations are running, and another one passes the two seconds
125+ * timeout, and the window is showing, we add it to the window directly.
126+ * - In the same case, but when the window is not showing, we update the resident
127+ * notification, changing its message, or the status icon's tooltip.
128+ * - When one file operation finishes, if it's not the last one, we only update the
129+ * resident notification's message, or the status icon's tooltip.
130+ * - In the same case, if it's the last one, we close the resident notification,
131+ * or the status icon, and trigger a transient one.
132+ * - In the same case, but the window was showing, we just hide the window.
133+ */
134+
135+ public UIHandler () {
136+ this.manager = new Marlin.Progress.InfoManager ();
137+
138+ manager.new_progress_info.connect ((info) => {
139+ info.started.connect (progress_info_started_cb);
140+ });
141+
142+ this.notification_supports_persistence = server_has_persistence ();
143+ }
144+
145+ private bool server_has_persistence () {
146+ unowned List<string> cappabilities = Notify.get_server_caps ();
147+
148+ return cappabilities.find ("persistence") != null;
149+ }
150+
151+ private void progress_info_started_cb (Marlin.Progress.Info info) {
152+ var application = Marlin.Application.get ();
153+ application.hold ();
154+
155+ info.finished.connect (() => {
156+ debug ("Release application");
157+ application.release ();
158+ });
159+
160+ Timeout.add_seconds (2, () => {
161+ if (info.get_is_paused ())
162+ return true;
163+
164+ if (!info.get_is_finished ())
165+ handle_new_progress_info (info);
166+
167+ return false;
168+ });
169+ }
170+
171+ private void handle_new_progress_info (Marlin.Progress.Info info) {
172+ info.finished.connect (progress_info_finished_cb);
173+
174+ this.active_infos++;
175+
176+ if (this.active_infos == 1) {
177+ /* This is the only active operation, present the window */
178+ add_to_window (info);
179+ (this.progress_window as Gtk.Window).present ();
180+ } else {
181+ if (this.progress_window.visible)
182+ add_to_window (info);
183+ else
184+ update_notification_or_status ();
185+ }
186+
187+#if HAVE_UNITY
188+ update_unity_launcher (info, true);
189+#endif
190+ }
191+
192+ private void add_to_window (Marlin.Progress.Info info) {
193+ ensure_window ();
194+
195+ var progress_widget = new Marlin.Progress.InfoWidget (info);
196+ (this.window_vbox as Gtk.Box).pack_start (progress_widget, false, false, 6);
197+
198+ progress_widget.show ();
199+ if (this.progress_window.visible)
200+ (this.progress_window as Gtk.Window).present ();
201+ }
202+
203+ private void ensure_window () {
204+ if (this.progress_window != null)
205+ return;
206+
207+ this.progress_window = new Gtk.Window (Gtk.WindowType.TOPLEVEL);
208+
209+ (this.progress_window as Gtk.Window).resizable = false;
210+ (this.progress_window as Gtk.Container).set_border_width (10);
211+ (this.progress_window as Gtk.Window).title = _("File Operations");
212+ (this.progress_window as Gtk.Window).set_wmclass ("file_progress", "Marlin");
213+ (this.progress_window as Gtk.Window).set_position (Gtk.WindowPosition.CENTER);
214+ (this.progress_window as Gtk.Window).icon_name = "system-file-manager";
215+
216+ this.window_vbox = new Gtk.Box (Gtk.Orientation.VERTICAL, 5);
217+
218+ (this.progress_window as Gtk.Container).add (this.window_vbox);
219+ this.window_vbox.show ();
220+
221+ this.progress_window.delete_event.connect ((widget, event) => {
222+ widget.hide ();
223+ update_notification_or_status ();
224+ return true;
225+ });
226+ }
227+
228+ private void update_notification_or_status () {
229+ if (this.notification_supports_persistence)
230+ update_notification ();
231+ else
232+ update_status_icon ();
233+ }
234+
235+ private void progress_info_finished_cb (Marlin.Progress.Info info) {
236+ this.active_infos--;
237+
238+ if (this.active_infos > 0) {
239+ if (!this.progress_window.visible)
240+ update_notification_or_status ();
241+ } else {
242+ if (this.progress_window.visible) {
243+ progress_window.hide ();
244+ } else {
245+ hide_notification_or_status ();
246+ show_complete_notification ();
247+ }
248+ }
249+
250+#if HAVE_UNITY
251+ update_unity_launcher (info, false);
252+#endif
253+ }
254+
255+ private void hide_notification_or_status () {
256+ if (this.status_icon != null)
257+ this.status_icon.visible = false;
258+
259+ if (this.progress_notification != null) {
260+ try {
261+ this.progress_notification.close ();
262+ } catch (Error error) {
263+ warning ("There was an error when showing the notification: %s", error.message);
264+ }
265+
266+ this.progress_notification = null;
267+ }
268+ }
269+
270+ private void show_complete_notification () {
271+ /* Don't display the notification if we'd be using a status icon */
272+ if (!this.notification_supports_persistence)
273+ return;
274+
275+ var complete_notification = new Notify.Notification (_("File Operations"),
276+ _("All file operations have been successfully completed"),
277+ null);
278+ try {
279+ complete_notification.show ();
280+ } catch (Error error) {
281+ warning ("There was an error when showing the notification: %s", error.message);
282+ }
283+ }
284+
285+ private void update_notification () {
286+ ensure_notification ();
287+
288+ string body = ngettext ("%'d file operation active",
289+ "%'d file operations active",
290+ this.active_infos);
291+
292+ this.progress_notification.update (_("File Operations"),
293+ body, "");
294+
295+ try {
296+ this.progress_notification.show ();
297+ } catch (Error error) {
298+ warning ("There was an error when showing the notification: %s", error.message);
299+ }
300+ }
301+
302+ private void ensure_notification () {
303+ if (this.progress_notification != null)
304+ return;
305+
306+ this.progress_notification = new Notify.Notification (_("File Operations"),
307+ null, null);
308+
309+ this.progress_notification.set_category ("transfer");
310+ this.progress_notification.set_hint ("resident", new Variant.boolean (true));
311+ this.progress_notification.add_action (ACTION_DETAILS,
312+ _("Show Details"),
313+ (Notify.ActionCallback) notification_show_details_cb);
314+ }
315+
316+ private void notification_show_details_cb (Notify.Notification notification,
317+ string action_name) {
318+ if (action_name != ACTION_DETAILS)
319+ return;
320+
321+ try {
322+ progress_notification.close ();
323+ } catch (Error error) {
324+ warning ("There was an error when closing the notification: %s", error.message);
325+ }
326+
327+ (progress_window as Gtk.Window).present ();
328+ }
329+
330+ private void update_status_icon () {
331+ ensure_status_icon ();
332+
333+ string tooltip = ngettext ("%'d file operation active",
334+ "%'d file operations active",
335+ this.active_infos);
336+
337+ this.status_icon.set_tooltip_text (tooltip);
338+
339+ this.status_icon.visible = true;
340+ }
341+
342+ private void ensure_status_icon () {
343+ if (this.status_icon != null)
344+ return;
345+
346+ var icon = new ThemedIcon.with_default_fallbacks ("system-file-manager-symbolic");
347+ this.status_icon = new Gtk.StatusIcon.from_gicon (icon);
348+
349+ this.status_icon.activate.connect (() => {
350+ this.status_icon.visible = false;
351+ (this.progress_window as Gtk.Window).present ();
352+ });
353+
354+ this.status_icon.visible = false;
355+ }
356+
357+#if HAVE_UNITY
358+ private void update_unity_launcher (Marlin.Progress.Info info,
359+ bool added) {
360+
361+ if (this.quicklist_handler == null) {
362+ this.quicklist_handler = QuicklistHandler.get_singleton ();
363+
364+ if (this.quicklist_handler == null)
365+ return;
366+
367+ build_unity_quicklist ();
368+ }
369+
370+ foreach (var marlin_lentry in this.quicklist_handler.launcher_entries)
371+ update_unity_launcher_entry (info, marlin_lentry);
372+
373+ if (added)
374+ info.progress_changed.connect (unity_progress_changed);
375+ }
376+
377+ private void build_unity_quicklist () {
378+ /* Create menu items for the quicklist */
379+ foreach (var marlin_lentry in this.quicklist_handler.launcher_entries) {
380+ /* Separator between bookmarks and progress items */
381+ var separator = new Dbusmenu.Menuitem ();
382+
383+ separator.property_set (Dbusmenu.MENUITEM_PROP_TYPE,
384+ Dbusmenu.CLIENT_TYPES_SEPARATOR);
385+ separator.property_set (Dbusmenu.MENUITEM_PROP_LABEL,
386+ "Progress items separator");
387+ marlin_lentry.progress_quicklists.append (separator);
388+
389+ /* "Show progress window" menu item */
390+ var show_menuitem = new Dbusmenu.Menuitem ();
391+
392+ show_menuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL,
393+ _("Show Copy Dialog"));
394+
395+ show_menuitem.item_activated.connect (() => {
396+ (this.progress_window as Gtk.Window).present ();
397+ });
398+
399+ marlin_lentry.progress_quicklists.append (show_menuitem);
400+
401+ /* "Cancel in-progress operations" menu item */
402+ var cancel_menuitem = new Dbusmenu.Menuitem ();
403+
404+ cancel_menuitem.property_set (Dbusmenu.MENUITEM_PROP_LABEL,
405+ _("Cancel All In-progress Actions"));
406+
407+ cancel_menuitem.item_activated.connect (() => {
408+ unowned List<Marlin.Progress.Info> infos = this.manager.get_all_infos ();
409+
410+ foreach (var info in infos)
411+ info.cancel ();
412+ });
413+
414+ marlin_lentry.progress_quicklists.append (cancel_menuitem);
415+ }
416+ }
417+
418+ private void update_unity_launcher_entry (Marlin.Progress.Info info,
419+ Marlin.LauncherEntry marlin_lentry) {
420+ Unity.LauncherEntry unity_lentry = marlin_lentry.entry;
421+
422+ if (this.active_infos > 0) {
423+ unity_lentry.progress_visible = true;
424+ unity_progress_changed ();
425+ show_unity_quicklist (marlin_lentry, true);
426+ } else {
427+ unity_lentry.progress_visible = false;
428+ unity_lentry.progress = 0.0;
429+ show_unity_quicklist (marlin_lentry, false);
430+
431+ Cancellable pc = info.get_cancellable ();
432+
433+ if (!pc.is_cancelled ()) {
434+ unity_lentry.urgent = true;
435+
436+ Timeout.add_seconds (2, () => {
437+ unity_lentry.urgent = false;
438+ return false;
439+ });
440+ }
441+ }
442+ }
443+
444+ private void show_unity_quicklist (Marlin.LauncherEntry marlin_lentry,
445+ bool show) {
446+
447+ Unity.LauncherEntry unity_lentry = marlin_lentry.entry;
448+ Dbusmenu.Menuitem quicklist = unity_lentry.quicklist;
449+
450+ foreach (Dbusmenu.Menuitem menuitem in marlin_lentry.progress_quicklists) {
451+ if (show) {
452+ if (menuitem.get_parent () == null)
453+ quicklist.child_add_position (menuitem, -1);
454+ } else {
455+ quicklist.child_delete (menuitem);
456+ }
457+ }
458+ }
459+
460+ private void unity_progress_changed () {
461+ double progress = 0;
462+ double current = 0;
463+ double total = 0;
464+ unowned List<Marlin.Progress.Info> infos = this.manager.get_all_infos ();
465+
466+ foreach (var _info in infos) {
467+ double c = _info.get_current ();
468+ double t = _info.get_total ();
469+
470+ if (c < 0)
471+ c = 0;
472+
473+ if (t <= 0)
474+ continue;
475+
476+ current += c;
477+ total += t;
478+ }
479+
480+ if (current >= 0 && total > 0)
481+ progress = current / total;
482+
483+ if (progress > 1.0)
484+ progress = 1.0;
485+
486+ foreach (Marlin.LauncherEntry marlin_lentry in this.quicklist_handler.launcher_entries) {
487+ Unity.LauncherEntry unity_lentry = marlin_lentry.entry;
488+ unity_lentry.progress = progress;
489+ }
490+ }
491+#endif
492+}
493
494=== modified file 'src/QuicklistHandler.vala'
495--- src/QuicklistHandler.vala 2013-08-16 22:51:52 +0000
496+++ src/QuicklistHandler.vala 2013-08-16 22:51:52 +0000
497@@ -27,7 +27,7 @@
498
499 public class QuicklistHandler : Object {
500
501- private List<Marlin.LauncherEntry> launcher_entries = null;
502+ public List<Marlin.LauncherEntry> launcher_entries = null;
503
504 private QuicklistHandler () {
505 this.entry_add ("pantheon-files.desktop");
506@@ -52,14 +52,6 @@
507 return quicklisthandler_singleton;
508 }
509
510- public unowned List<Marlin.LauncherEntry> get_launcher_entries () {
511- return this.launcher_entries;
512- }
513-
514- public static Unity.LauncherEntry get_launcher_entry (List<Marlin.LauncherEntry> list) {
515- return list.data.entry;
516- }
517-
518 private void entry_add (string entry_id) {
519 var unity_lentry = Unity.LauncherEntry.get_for_desktop_id (entry_id);
520
521
522=== removed file 'src/marlin-progress-ui-handler.c'
523--- src/marlin-progress-ui-handler.c 2013-08-16 22:51:52 +0000
524+++ src/marlin-progress-ui-handler.c 1970-01-01 00:00:00 +0000
525@@ -1,691 +0,0 @@
526-/*
527- * marlin-progress-ui-handler.c: file operation progress user interface.
528- *
529- * Copyright (C) 2007, 2011 Red Hat, Inc.
530- *
531- * This program is free software; you can redistribute it and/or
532- * modify it under the terms of the GNU General Public License as
533- * published by the Free Software Foundation; either version 2 of the
534- * License, or (at your option) any later version.
535- *
536- * This program is distributed in the hope that it will be useful,
537- * but WITHOUT ANY WARRANTY; without even the implied warranty of
538- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
539- * General Public License for more details.
540- *
541- * You should have received a copy of the GNU General Public
542- * License along with this program; if not, write to the
543- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
544- * Boston, MA 02111-1307, USA.
545- *
546- * Authors: Alexander Larsson <alexl@redhat.com>
547- * Cosimo Cecchi <cosimoc@redhat.com>
548- * Marco Trevisan <3v1n0@ubuntu.com>
549- *
550- */
551-
552-#include "marlin-progress-ui-handler.h"
553-
554-#include "marlin-vala.h"
555-#include "marlin-progress-info-widget.h"
556-
557-#include "marlin-progress-info.h"
558-#include "marlin-progress-info-manager.h"
559-#include "eel-i18n.h"
560-
561-#include <libnotify/notify.h>
562-
563-#ifdef HAVE_UNITY
564-#include <unity.h>
565-#endif
566-
567-struct _MarlinProgressUIHandlerPriv {
568- MarlinProgressInfoManager *manager;
569-
570- GtkWidget *progress_window;
571- GtkWidget *window_vbox;
572- guint active_infos;
573-
574- gboolean notification_supports_persistence;
575- NotifyNotification *progress_notification;
576- GtkStatusIcon *status_icon;
577-#ifdef HAVE_UNITY
578- MarlinQuicklistHandler *unity_quicklist_handler;
579-#endif
580-};
581-
582-G_DEFINE_TYPE (MarlinProgressUIHandler, marlin_progress_ui_handler, G_TYPE_OBJECT);
583-
584-/* Our policy for showing progress notification is the following:
585- * - file operations that end within two seconds do not get notified in any way
586- * - if no file operations are running, and one passes the two seconds
587- * timeout, a window is displayed with the progress
588- * - if the window is closed, we show a resident notification, or a status icon, depending on
589- * the capabilities of the notification daemon running in the session
590- * - if some file operations are running, and another one passes the two seconds
591- * timeout, and the window is showing, we add it to the window directly
592- * - in the same case, but when the window is not showing, we update the resident
593- * notification, changing its message, or the status icon's tooltip
594- * - when one file operation finishes, if it's not the last one, we only update the
595- * resident notification's message, or the status icon's tooltip
596- * - in the same case, if it's the last one, we close the resident notification,
597- * or the status icon, and trigger a transient one
598- * - in the same case, but the window was showing, we just hide the window
599- */
600-
601-#define ACTION_DETAILS "details"
602-
603-static void
604-status_icon_activate_cb (GtkStatusIcon *icon,
605- MarlinProgressUIHandler *self)
606-{
607- gtk_status_icon_set_visible (icon, FALSE);
608- gtk_window_present (GTK_WINDOW (self->priv->progress_window));
609-}
610-
611-static void
612-notification_show_details_cb (NotifyNotification *notification,
613- char *action_name,
614- gpointer user_data)
615-{
616- MarlinProgressUIHandler *self = user_data;
617-
618-
619- if (g_strcmp0 (action_name, ACTION_DETAILS) != 0) {
620- return;
621- }
622-
623- notify_notification_close (self->priv->progress_notification, NULL);
624- gtk_window_present (GTK_WINDOW (self->priv->progress_window));
625-}
626-
627-static void
628-progress_ui_handler_ensure_notification (MarlinProgressUIHandler *self)
629-{
630- NotifyNotification *notify;
631-
632- if (self->priv->progress_notification) {
633- return;
634- }
635-
636- notify = notify_notification_new (_("File Operations"),
637- NULL, NULL);
638- self->priv->progress_notification = notify;
639-
640- notify_notification_set_category (notify, "transfer");
641- notify_notification_set_hint (notify, "resident",
642- g_variant_new_boolean (TRUE));
643-
644- notify_notification_add_action (notify, ACTION_DETAILS,
645- _("Show Details"),
646- notification_show_details_cb,
647- self,
648- NULL);
649-}
650-
651-static void
652-progress_ui_handler_ensure_status_icon (MarlinProgressUIHandler *self)
653-{
654- GIcon *icon;
655- GtkStatusIcon *status_icon;
656-
657- if (self->priv->status_icon != NULL) {
658- return;
659- }
660-
661- icon = g_themed_icon_new_with_default_fallbacks ("system-file-manager-symbolic");
662- status_icon = gtk_status_icon_new_from_gicon (icon);
663- g_signal_connect (status_icon, "activate",
664- (GCallback) status_icon_activate_cb,
665- self);
666-
667- gtk_status_icon_set_visible (status_icon, FALSE);
668- g_object_unref (icon);
669-
670- self->priv->status_icon = status_icon;
671-}
672-
673-static void
674-progress_ui_handler_update_notification (MarlinProgressUIHandler *self)
675-{
676- gchar *body;
677-
678- progress_ui_handler_ensure_notification (self);
679-
680- body = g_strdup_printf (ngettext ("%'d file operation active",
681- "%'d file operations active",
682- self->priv->active_infos),
683- self->priv->active_infos);
684-
685- notify_notification_update (self->priv->progress_notification,
686- _("File Operations"),
687- body,
688- NULL);
689-
690- notify_notification_show (self->priv->progress_notification, NULL);
691-
692- g_free (body);
693-}
694-
695-static void
696-progress_ui_handler_update_status_icon (MarlinProgressUIHandler *self)
697-{
698- gchar *tooltip;
699-
700- progress_ui_handler_ensure_status_icon (self);
701-
702- tooltip = g_strdup_printf (ngettext ("%'d file operation active",
703- "%'d file operations active",
704- self->priv->active_infos),
705- self->priv->active_infos);
706- gtk_status_icon_set_tooltip_text (self->priv->status_icon, tooltip);
707- g_free (tooltip);
708-
709- gtk_status_icon_set_visible (self->priv->status_icon, TRUE);
710-}
711-
712-#ifdef HAVE_UNITY
713-
714-static void
715-progress_ui_handler_unity_progress_changed (MarlinProgressInfo *info,
716- MarlinProgressUIHandler *self)
717-{
718- g_return_if_fail (self);
719- g_return_if_fail (self->priv->unity_quicklist_handler);
720- g_return_if_fail (self->priv->manager);
721-
722- GList *infos, *l;
723- double progress = 0;
724- double c, current = 0;
725- double t, total = 0;
726-
727- infos = marlin_progress_info_manager_get_all_infos (self->priv->manager);
728-
729- for (l = infos; l; l = l->next) {
730- MarlinProgressInfo *i = l->data;
731- c = marlin_progress_info_get_current (i);
732- t = marlin_progress_info_get_total (i);
733-
734- if (c < 0) c = 0;
735- if (t <= 0) continue;
736-
737- total += t;
738- current += c;
739- }
740-
741- if (current >= 0 && total > 0)
742- progress = current / total;
743-
744- if (progress > 1.0)
745- progress = 1.0;
746-
747- for (l = marlin_quicklist_handler_get_launcher_entries (self->priv->unity_quicklist_handler); l; l = l->next) {
748- UnityLauncherEntry *entry = marlin_quicklist_handler_get_launcher_entry (l);
749- unity_launcher_entry_set_progress (entry, progress);
750- }
751-}
752-
753-static gboolean
754-progress_ui_handler_disable_unity_urgency (UnityLauncherEntry *entry)
755-{
756- g_return_if_fail (entry);
757-
758- unity_launcher_entry_set_urgent (entry, FALSE);
759- return FALSE;
760-}
761-
762-static void
763-progress_ui_handler_unity_quicklist_show_activated (DbusmenuMenuitem *menu,
764- guint timestamp,
765- MarlinProgressUIHandler *self)
766-{
767- g_return_if_fail (self);
768-
769- if (!gtk_widget_get_visible (self->priv->progress_window)) {
770- gtk_window_present (GTK_WINDOW (self->priv->progress_window));
771- } else {
772- gtk_window_set_keep_above (GTK_WINDOW (self->priv->progress_window), TRUE);
773- gtk_window_set_keep_above (GTK_WINDOW (self->priv->progress_window), FALSE);
774- }
775-}
776-
777-static void
778-progress_ui_handler_unity_quicklist_cancel_activated (DbusmenuMenuitem *menu,
779- guint timestamp,
780- MarlinProgressUIHandler *self)
781-{
782- g_return_if_fail (self);
783- g_return_if_fail (self->priv->manager);
784-
785- GList *infos, *l;
786- infos = marlin_progress_info_manager_get_all_infos (self->priv->manager);
787-
788- for (l = infos; l; l = l->next) {
789- MarlinProgressInfo *info = l->data;
790- marlin_progress_info_cancel (info);
791- }
792-}
793-
794-static void
795-progress_ui_handler_build_unity_quicklist (MarlinProgressUIHandler *self)
796-{
797- g_return_if_fail (self);
798- GList *l;
799-
800- for (l = marlin_quicklist_handler_get_launcher_entries (self->priv->unity_quicklist_handler); l; l = l->next) {
801- MarlinLauncherEntry *lentry = l->data;
802- UnityLauncherEntry *entry = marlin_quicklist_handler_get_launcher_entry (l);
803- DbusmenuMenuitem *ql = unity_launcher_entry_get_quicklist (entry);
804-
805- DbusmenuMenuitem *quickmenu = dbusmenu_menuitem_new ();
806- dbusmenu_menuitem_property_set (quickmenu,
807- DBUSMENU_MENUITEM_PROP_LABEL,
808- _("Show Copy Dialog"));
809- dbusmenu_menuitem_property_set_bool (quickmenu,
810- DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
811- dbusmenu_menuitem_child_add_position (ql, quickmenu, -1);
812- lentry->progress_quicklists = g_list_prepend (lentry->progress_quicklists, quickmenu);
813- g_signal_connect (quickmenu, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
814- (GCallback) progress_ui_handler_unity_quicklist_show_activated,
815- self);
816-
817- quickmenu = dbusmenu_menuitem_new ();
818- dbusmenu_menuitem_property_set (quickmenu,
819- DBUSMENU_MENUITEM_PROP_LABEL,
820- _("Cancel All In-progress Actions"));
821- dbusmenu_menuitem_property_set_bool (quickmenu,
822- DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE);
823- dbusmenu_menuitem_child_add_position (ql, quickmenu, -1);
824- lentry->progress_quicklists = g_list_prepend (lentry->progress_quicklists, quickmenu);
825- g_signal_connect (quickmenu, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
826- (GCallback) progress_ui_handler_unity_quicklist_cancel_activated,
827- self);
828- }
829-}
830-
831-static void
832-progress_ui_handler_show_unity_quicklist (MarlinProgressUIHandler *self,
833- MarlinLauncherEntry *lentry,
834- gboolean show)
835-{
836- g_return_if_fail (self);
837- g_return_if_fail (lentry);
838-
839- GList *l;
840-
841- for (l = lentry->progress_quicklists; l; l = l->next) {
842- dbusmenu_menuitem_property_set_bool(l->data,
843- DBUSMENU_MENUITEM_PROP_VISIBLE, show);
844- }
845-}
846-
847-static void
848-progress_ui_handler_update_unity_launcher_entry (MarlinProgressUIHandler *self,
849- MarlinProgressInfo *info,
850- MarlinLauncherEntry *lentry)
851-{
852- UnityLauncherEntry *entry = lentry->entry;
853-
854- g_return_if_fail (self);
855- g_return_if_fail (entry);
856-
857- if (self->priv->active_infos > 0) {
858- unity_launcher_entry_set_progress_visible (entry, TRUE);
859- progress_ui_handler_show_unity_quicklist (self, lentry, TRUE);
860- progress_ui_handler_unity_progress_changed (NULL, self);
861- } else {
862- unity_launcher_entry_set_progress_visible (entry, FALSE);
863- unity_launcher_entry_set_progress (entry, 0.0);
864- unity_launcher_entry_set_count_visible (entry, FALSE);
865- progress_ui_handler_show_unity_quicklist (self, lentry, FALSE);
866- GCancellable *pc = marlin_progress_info_get_cancellable (info);
867-
868- if (!g_cancellable_is_cancelled (pc)) {
869- unity_launcher_entry_set_urgent (entry, TRUE);
870-
871- g_timeout_add_seconds (2, (GSourceFunc)
872- progress_ui_handler_disable_unity_urgency,
873- entry);
874- }
875- }
876-}
877-
878-static void
879-progress_ui_handler_update_unity_launcher (MarlinProgressUIHandler *self,
880- MarlinProgressInfo *info,
881- gboolean added)
882-{
883- g_return_if_fail (self);
884- GList *l;
885-
886- if (!self->priv->unity_quicklist_handler) {
887- self->priv->unity_quicklist_handler = marlin_quicklist_handler_get_singleton ();
888- if (!self->priv->unity_quicklist_handler)
889- return;
890-
891- progress_ui_handler_build_unity_quicklist (self);
892- }
893-
894- for (l = marlin_quicklist_handler_get_launcher_entries (self->priv->unity_quicklist_handler); l; l = l->next) {
895- MarlinLauncherEntry *lentry = l->data;
896- UnityLauncherEntry *entry = marlin_quicklist_handler_get_launcher_entry (l);
897- progress_ui_handler_update_unity_launcher_entry (self, info, lentry);
898- }
899-
900- if (added) {
901- g_signal_connect (info, "progress-changed",
902- (GCallback) progress_ui_handler_unity_progress_changed,
903- self);
904- }
905-}
906-#endif
907-
908-
909-static gboolean
910-progress_window_delete_event (GtkWidget *widget,
911- GdkEvent *event,
912- MarlinProgressUIHandler *self)
913-{
914- gtk_widget_hide (widget);
915-
916- if (self->priv->notification_supports_persistence) {
917- progress_ui_handler_update_notification (self);
918- } else {
919- progress_ui_handler_update_status_icon (self);
920- }
921-
922- return TRUE;
923-}
924-
925-static void
926-progress_ui_handler_ensure_window (MarlinProgressUIHandler *self)
927-{
928- GtkWidget *vbox, *progress_window;
929-
930- if (self->priv->progress_window != NULL) {
931- return;
932- }
933-
934- progress_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
935- self->priv->progress_window = progress_window;
936- gtk_window_set_resizable (GTK_WINDOW (progress_window),
937- FALSE);
938- gtk_container_set_border_width (GTK_CONTAINER (progress_window), 10);
939-
940- gtk_window_set_title (GTK_WINDOW (progress_window),
941- _("File Operations"));
942- gtk_window_set_wmclass (GTK_WINDOW (progress_window),
943- "file_progress", "Marlin");
944- gtk_window_set_position (GTK_WINDOW (progress_window),
945- GTK_WIN_POS_CENTER);
946- gtk_window_set_icon_name (GTK_WINDOW (progress_window),
947- "system-file-manager");
948-
949- vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
950- gtk_box_set_spacing (GTK_BOX (vbox), 5);
951- gtk_container_add (GTK_CONTAINER (progress_window),
952- vbox);
953- self->priv->window_vbox = vbox;
954- gtk_widget_show (vbox);
955-
956- g_signal_connect (progress_window,
957- "delete-event",
958- (GCallback) progress_window_delete_event, self);
959-}
960-
961-static void
962-progress_ui_handler_update_notification_or_status (MarlinProgressUIHandler *self)
963-{
964- if (self->priv->notification_supports_persistence) {
965- progress_ui_handler_update_notification (self);
966- } else {
967- progress_ui_handler_update_status_icon (self);
968- }
969-}
970-
971-static void
972-progress_ui_handler_add_to_window (MarlinProgressUIHandler *self,
973- MarlinProgressInfo *info)
974-{
975- GtkWidget *progress;
976-
977- progress = marlin_progress_info_widget_new (info);
978- progress_ui_handler_ensure_window (self);
979-
980- gtk_box_pack_start (GTK_BOX (self->priv->window_vbox),
981- progress,
982- FALSE, FALSE, 6);
983-
984- gtk_widget_show (progress);
985-}
986-
987-static void
988-progress_ui_handler_show_complete_notification (MarlinProgressUIHandler *self)
989-{
990- NotifyNotification *complete_notification;
991-
992- /* don't display the notification if we'd be using a status icon */
993- if (!self->priv->notification_supports_persistence) {
994- return;
995- }
996-
997- complete_notification = notify_notification_new (_("File Operations"),
998- _("All file operations have been successfully completed"),
999- NULL);
1000- notify_notification_show (complete_notification, NULL);
1001-
1002- g_object_unref (complete_notification);
1003-}
1004-
1005-static void
1006-progress_ui_handler_hide_notification_or_status (MarlinProgressUIHandler *self)
1007-{
1008- if (self->priv->status_icon != NULL) {
1009- gtk_status_icon_set_visible (self->priv->status_icon, FALSE);
1010- }
1011-
1012- if (self->priv->progress_notification != NULL) {
1013- notify_notification_close (self->priv->progress_notification, NULL);
1014- g_clear_object (&self->priv->progress_notification);
1015- }
1016-}
1017-
1018-static void
1019-progress_info_finished_cb (MarlinProgressInfo *info,
1020- MarlinProgressUIHandler *self)
1021-{
1022- self->priv->active_infos--;
1023-
1024- if (self->priv->active_infos > 0) {
1025- if (!gtk_widget_get_visible (self->priv->progress_window)) {
1026- progress_ui_handler_update_notification_or_status (self);
1027- }
1028- } else {
1029- if (gtk_widget_get_visible (self->priv->progress_window)) {
1030- gtk_widget_hide (self->priv->progress_window);
1031- } else {
1032- progress_ui_handler_hide_notification_or_status (self);
1033- progress_ui_handler_show_complete_notification (self);
1034- }
1035- }
1036-
1037-#ifdef HAVE_UNITY
1038- progress_ui_handler_update_unity_launcher (self, info, FALSE);
1039-#endif
1040-}
1041-
1042-static void
1043-handle_new_progress_info (MarlinProgressUIHandler *self,
1044- MarlinProgressInfo *info)
1045-{
1046- g_signal_connect (info, "finished",
1047- G_CALLBACK (progress_info_finished_cb), self);
1048-
1049- self->priv->active_infos++;
1050-
1051- if (self->priv->active_infos == 1) {
1052- /* this is the only active operation, present the window */
1053- progress_ui_handler_add_to_window (self, info);
1054- gtk_window_present (GTK_WINDOW (self->priv->progress_window));
1055- } else {
1056- if (gtk_widget_get_visible (self->priv->progress_window)) {
1057- progress_ui_handler_add_to_window (self, info);
1058- } else {
1059- progress_ui_handler_update_notification_or_status (self);
1060- }
1061- }
1062-
1063-#ifdef HAVE_UNITY
1064- progress_ui_handler_update_unity_launcher (self, info, TRUE);
1065-#endif
1066-}
1067-
1068-typedef struct {
1069- MarlinProgressInfo *info;
1070- MarlinProgressUIHandler *self;
1071-} TimeoutData;
1072-
1073-static void
1074-timeout_data_free (TimeoutData *data)
1075-{
1076- g_clear_object (&data->self);
1077- g_clear_object (&data->info);
1078-
1079- g_slice_free (TimeoutData, data);
1080-}
1081-
1082-static TimeoutData *
1083-timeout_data_new (MarlinProgressUIHandler *self,
1084- MarlinProgressInfo *info)
1085-{
1086- TimeoutData *retval;
1087-
1088- retval = g_slice_new0 (TimeoutData);
1089- retval->self = g_object_ref (self);
1090- retval->info = g_object_ref (info);
1091-
1092- return retval;
1093-}
1094-
1095-static gboolean
1096-new_op_started_timeout (TimeoutData *data)
1097-{
1098- MarlinProgressInfo *info = data->info;
1099- MarlinProgressUIHandler *self = data->self;
1100-
1101- if (marlin_progress_info_get_is_paused (info)) {
1102- return TRUE;
1103- }
1104-
1105- if (!marlin_progress_info_get_is_finished (info)) {
1106- handle_new_progress_info (self, info);
1107- }
1108-
1109- timeout_data_free (data);
1110-
1111- return FALSE;
1112-}
1113-
1114-static void
1115-release_application (MarlinProgressInfo *info,
1116- MarlinProgressUIHandler *self)
1117-{
1118- MarlinApplication *app;
1119-
1120- /* release the GApplication hold we acquired */
1121- app = marlin_application_get ();
1122- g_application_release (G_APPLICATION (app));
1123-
1124- //amtest
1125- g_message ("%s", G_STRFUNC);
1126-}
1127-
1128-static void
1129-progress_info_started_cb (MarlinProgressInfo *info,
1130- MarlinProgressUIHandler *self)
1131-{
1132- MarlinApplication *app;
1133- TimeoutData *data;
1134-
1135- /* hold GApplication so we never quit while there's an operation pending */
1136- app = marlin_application_get ();
1137- g_application_hold (G_APPLICATION (app));
1138-
1139- g_signal_connect (info, "finished",
1140- G_CALLBACK (release_application), self);
1141-
1142- data = timeout_data_new (self, info);
1143-
1144- /* timeout for the progress window to appear */
1145- g_timeout_add_seconds (2,
1146- (GSourceFunc) new_op_started_timeout,
1147- data);
1148-}
1149-
1150-static void
1151-new_progress_info_cb (MarlinProgressInfoManager *manager,
1152- MarlinProgressInfo *info,
1153- MarlinProgressUIHandler *self)
1154-{
1155- g_signal_connect (info, "started",
1156- G_CALLBACK (progress_info_started_cb), self);
1157-}
1158-
1159-static void
1160-marlin_progress_ui_handler_dispose (GObject *obj)
1161-{
1162- MarlinProgressUIHandler *self = MARLIN_PROGRESS_UI_HANDLER (obj);
1163-
1164- g_clear_object (&self->priv->manager);
1165-
1166- G_OBJECT_CLASS (marlin_progress_ui_handler_parent_class)->dispose (obj);
1167-}
1168-
1169-static gboolean
1170-server_has_persistence (void)
1171-{
1172- gboolean retval;
1173- GList *caps, *l;
1174-
1175- caps = notify_get_server_caps ();
1176- if (caps == NULL) {
1177- return FALSE;
1178- }
1179-
1180- l = g_list_find_custom (caps, "persistence", (GCompareFunc) g_strcmp0);
1181- retval = (l != NULL);
1182-
1183- g_list_free_full (caps, g_free);
1184-
1185- return retval;
1186-}
1187-
1188-static void
1189-marlin_progress_ui_handler_init (MarlinProgressUIHandler *self)
1190-{
1191- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MARLIN_TYPE_PROGRESS_UI_HANDLER,
1192- MarlinProgressUIHandlerPriv);
1193-
1194- self->priv->manager = marlin_progress_info_manager_new ();
1195- g_signal_connect (self->priv->manager, "new-progress-info",
1196- G_CALLBACK (new_progress_info_cb), self);
1197-
1198- self->priv->notification_supports_persistence = server_has_persistence ();
1199-}
1200-
1201-static void
1202-marlin_progress_ui_handler_class_init (MarlinProgressUIHandlerClass *klass)
1203-{
1204- GObjectClass *oclass;
1205-
1206- oclass = G_OBJECT_CLASS (klass);
1207- oclass->dispose = marlin_progress_ui_handler_dispose;
1208-
1209- g_type_class_add_private (klass, sizeof (MarlinProgressUIHandlerPriv));
1210-}
1211-
1212-MarlinProgressUIHandler *
1213-marlin_progress_ui_handler_new (void)
1214-{
1215- return g_object_new (MARLIN_TYPE_PROGRESS_UI_HANDLER, NULL);
1216-}
1217
1218=== removed file 'src/marlin-progress-ui-handler.h'
1219--- src/marlin-progress-ui-handler.h 2011-07-27 10:29:20 +0000
1220+++ src/marlin-progress-ui-handler.h 1970-01-01 00:00:00 +0000
1221@@ -1,64 +0,0 @@
1222-/*
1223- * marlin-progress-ui-handler.h: file operation progress user interface.
1224- *
1225- * Copyright (C) 2007, 2011 Red Hat, Inc.
1226- *
1227- * This program is free software; you can redistribute it and/or
1228- * modify it under the terms of the GNU General Public License as
1229- * published by the Free Software Foundation; either version 2 of the
1230- * License, or (at your option) any later version.
1231- *
1232- * This program is distributed in the hope that it will be useful,
1233- * but WITHOUT ANY WARRANTY; without even the implied warranty of
1234- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1235- * General Public License for more details.
1236- *
1237- * You should have received a copy of the GNU General Public
1238- * License along with this program; if not, write to the
1239- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1240- * Boston, MA 02111-1307, USA.
1241- *
1242- * Authors: Alexander Larsson <alexl@redhat.com>
1243- * Cosimo Cecchi <cosimoc@redhat.com>
1244- *
1245- */
1246-
1247-#ifndef __MARLIN_PROGRESS_UI_HANDLER_H__
1248-#define __MARLIN_PROGRESS_UI_HANDLER_H__
1249-
1250-#include <glib-object.h>
1251-
1252-G_BEGIN_DECLS
1253-
1254-#define MARLIN_TYPE_PROGRESS_UI_HANDLER marlin_progress_ui_handler_get_type()
1255-#define MARLIN_PROGRESS_UI_HANDLER(obj) \
1256- (G_TYPE_CHECK_INSTANCE_CAST ((obj), MARLIN_TYPE_PROGRESS_UI_HANDLER, MarlinProgressUIHandler))
1257-#define MARLIN_PROGRESS_UI_HANDLER_CLASS(klass) \
1258- (G_TYPE_CHECK_CLASS_CAST ((klass), MARLIN_TYPE_PROGRESS_UI_HANDLER, MarlinProgressUIHandlerClass))
1259-#define MARLIN_IS_PROGRESS_UI_HANDLER(obj) \
1260- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MARLIN_TYPE_PROGRESS_UI_HANDLER))
1261-#define MARLIN_IS_PROGRESS_UI_HANDLER_CLASS(klass) \
1262- (G_TYPE_CHECK_CLASS_TYPE ((klass), MARLIN_TYPE_PROGRESS_UI_HANDLER))
1263-#define MARLIN_PROGRESS_UI_HANDLER_GET_CLASS(obj) \
1264- (G_TYPE_INSTANCE_GET_CLASS ((obj), MARLIN_TYPE_PROGRESS_UI_HANDLER, MarlinProgressUIHandlerClass))
1265-
1266-typedef struct _MarlinProgressUIHandlerPriv MarlinProgressUIHandlerPriv;
1267-
1268-typedef struct {
1269- GObject parent;
1270-
1271- /* private */
1272- MarlinProgressUIHandlerPriv *priv;
1273-} MarlinProgressUIHandler;
1274-
1275-typedef struct {
1276- GObjectClass parent_class;
1277-} MarlinProgressUIHandlerClass;
1278-
1279-GType marlin_progress_ui_handler_get_type (void);
1280-
1281-MarlinProgressUIHandler * marlin_progress_ui_handler_new (void);
1282-
1283-G_END_DECLS
1284-
1285-#endif /* __MARLIN_PROGRESS_UI_HANDLER_H__ */
1286
1287=== modified file 'src/marlin.vapi'
1288--- src/marlin.vapi 2013-08-16 22:51:52 +0000
1289+++ src/marlin.vapi 2013-08-16 22:51:52 +0000
1290@@ -56,7 +56,7 @@
1291 public class Thumbnailer : Object {
1292 public static Thumbnailer get();
1293 public bool queue_file(GOF.File file, int? request, bool large);
1294-
1295+
1296 }
1297 [CCode (cheader_filename = "marlin-bookmark.h")]
1298 public class Bookmark : Object {
1299@@ -118,11 +118,8 @@
1300 [CCode (cheader_filename = "marlin-file-operations.h")]
1301 public void new_folder_with_name_recursive(Gtk.Widget? parent_view, Gdk.Point? target_point, File file, string name, void* callback, void* data_callback);
1302 }
1303- [CCode (cprefix = "MarlinProgress", lower_case_cprefix = "marlin_progress_")]
1304- namespace Progress {
1305- [CCode (cheader_filename = "marlin-progress-ui-handler.h")]
1306- public class UIHandler : Object {
1307- public UIHandler ();
1308- }
1309+ [CCode (cheader_filename = "marlin-progress-info-widget.h")]
1310+ public class Progress.InfoWidget : Gtk.Box {
1311+ public InfoWidget (Marlin.Progress.Info info);
1312 }
1313 }

Subscribers

People subscribed via source and target branches

to all changes: