Merge lp:~cando/unity/trash_quicklist into lp:unity

Proposed by Stefano Candori
Status: Merged
Approved by: Alex Launi
Approved revision: no longer in the source branch.
Merged at revision: 808
Proposed branch: lp:~cando/unity/trash_quicklist
Merge into: lp:unity
Diff against target: 186 lines (+127/-2)
2 files modified
src/TrashLauncherIcon.cpp (+119/-2)
src/TrashLauncherIcon.h (+8/-0)
To merge this branch: bzr merge lp:~cando/unity/trash_quicklist
Reviewer Review Type Date Requested Status
Alex Launi (community) Needs Fixing
Jason Smith (community) Approve
Review via email: mp+47780@code.launchpad.net

Description of the change

In this branch I've fixed bug #688407 adding a quicklist menu to the trash bin.
It recursively delete trash files running in a different thread.
I've also fixed what Mikkel Kamstrup Erlandsen asked me in the old merge proposal.

To post a comment you must log in.
Revision history for this message
Jason Smith (jassmith) wrote :

+1 great work

review: Approve
Revision history for this message
Alex Launi (alexlauni) wrote :

There are still some small translation issues. You have an untranslatable string in this patch.
79 + gtk_dialog_add_button (GTK_DIALOG (dialog), "Empty Trash", GTK_RESPONSE_OK );

review: Needs Fixing
Revision history for this message
Alex Launi (alexlauni) wrote :

Looks good but before we merge it we need you to sign the Canonical contributer agreement. It's a quick, but necessary step to getting your code into the tree. Luckily you only need to sign it once and it will apply to all other Canonical project contributions you may make in the future. http://www.canonical.com/contributors Make sure to CC David Barth when you send it in.

Revision history for this message
Stefano Candori (cando) wrote :

Hi Alex! This is not my first contribution so i've already signed the Canonical contributer agreement... :)..Is there anything else that i have to do?

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/TrashLauncherIcon.cpp'
2--- src/TrashLauncherIcon.cpp 2011-01-26 17:47:05 +0000
3+++ src/TrashLauncherIcon.cpp 2011-01-28 10:19:53 +0000
4@@ -18,6 +18,11 @@
5 */
6
7 #include "TrashLauncherIcon.h"
8+#include "Launcher.h"
9+#include "Nux/WindowCompositor.h"
10+
11+#include "QuicklistManager.h"
12+#include "QuicklistMenuItemLabel.h"
13
14 #include <gio/gio.h>
15 #include <glib/gi18n-lib.h>
16@@ -62,6 +67,29 @@
17 }
18
19 void
20+TrashLauncherIcon::EnsureMenuItemsReady ()
21+{
22+ DbusmenuMenuitem *menu_item;
23+
24+ /* Empty Trash */
25+ if (_menu_items.find ("Empty") == _menu_items.end ())
26+ {
27+ menu_item = dbusmenu_menuitem_new ();
28+ g_object_ref (menu_item);
29+
30+ dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Empty Trash"));
31+ dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
32+ dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_VISIBLE, true);
33+
34+ g_signal_connect (menu_item,
35+ DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
36+ (GCallback)&TrashLauncherIcon::OnEmptyTrash, this);
37+
38+ _menu_items["Empty"] = menu_item;
39+ }
40+}
41+
42+void
43 TrashLauncherIcon::OnMouseClick (int button)
44 {
45 SimpleLauncherIcon::OnMouseClick (button);
46@@ -75,6 +103,90 @@
47 if (error)
48 g_error_free (error);
49 }
50+ else if (button == 3 && _empty == FALSE)
51+ {
52+ EnsureMenuItemsReady ();
53+
54+ _quicklist->RemoveAllMenuItem ();
55+ QuicklistMenuItemLabel* item = new QuicklistMenuItemLabel (_menu_items["Empty"], NUX_TRACKER_LOCATION);
56+ _quicklist->AddMenuItem (item);
57+
58+ int tip_x = _launcher->GetBaseWidth () + 1; //icon_x + icon_w;
59+ nux::Point3 center = GetCenter ();
60+ int tip_y = center.y;
61+ QuicklistManager::Default ()->ShowQuicklist (_quicklist, tip_x, tip_y);
62+ nux::GetWindowCompositor ().SetAlwaysOnFrontWindow (_quicklist);
63+ }
64+}
65+
66+void
67+TrashLauncherIcon::OnEmptyTrash(DbusmenuMenuitem *item, int time, TrashLauncherIcon *self)
68+{
69+ GtkWidget *dialog;
70+ dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
71+ GTK_MESSAGE_WARNING,
72+ GTK_BUTTONS_CANCEL,
73+ NULL);
74+
75+ g_object_set (GTK_DIALOG (dialog),
76+ "text", _("Empty all items from Trash?"),
77+ "secondary-text", _("All items in the Trash will be permanently deleted."),
78+ NULL);
79+ gtk_dialog_add_button (GTK_DIALOG (dialog), "Empty Trash", GTK_RESPONSE_OK );
80+
81+ QuicklistManager::Default ()->HideQuicklist (self->_quicklist);
82+
83+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
84+ g_thread_create ((GThreadFunc)&TrashLauncherIcon::EmptyTrashAction, NULL, FALSE, NULL);
85+
86+ gtk_widget_destroy (dialog);
87+
88+}
89+
90+void
91+TrashLauncherIcon::EmptyTrashAction()
92+{
93+ // This function runs in a different thread
94+ // created in TrashLauncherIcon::OnEmptyTrash
95+ GFile *location;
96+ location = g_file_new_for_uri ("trash:///");
97+
98+ RecursiveDelete (location);
99+
100+ g_object_unref (location);
101+
102+}
103+void
104+TrashLauncherIcon::RecursiveDelete(GFile *location)
105+{
106+
107+ GFileInfo *info;
108+ GFile *child;
109+ GFileEnumerator *enumerator;
110+
111+ enumerator = g_file_enumerate_children (location,
112+ G_FILE_ATTRIBUTE_STANDARD_NAME ","
113+ G_FILE_ATTRIBUTE_STANDARD_TYPE,
114+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
115+ NULL,
116+ NULL);
117+ if (enumerator)
118+ {
119+ while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL)
120+ {
121+ child = g_file_get_child (location, g_file_info_get_name (info));
122+ if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY) RecursiveDelete (child);
123+
124+ g_file_delete (child, NULL, NULL);
125+ g_object_unref (child);
126+ g_object_unref (info);
127+
128+ }
129+
130+ g_file_enumerator_close (enumerator, NULL, NULL);
131+ g_object_unref (enumerator);
132+ }
133+
134 }
135
136 void
137@@ -91,7 +203,7 @@
138 &TrashLauncherIcon::UpdateTrashIconCb,
139 this);
140
141- g_object_unref(location);
142+ g_object_unref (location);
143 }
144
145 void
146@@ -102,12 +214,17 @@
147 TrashLauncherIcon *self = (TrashLauncherIcon*) data;
148 GFileInfo *info;
149 GIcon *icon;
150+ gchar *icon_name;
151
152 info = g_file_query_info_finish (G_FILE (source), res, NULL);
153
154 if (info != NULL) {
155 icon = g_file_info_get_icon (info);
156- self->SetIconName (g_icon_to_string (icon));
157+ icon_name = g_icon_to_string (icon);
158+ self->SetIconName (icon_name);
159+
160+ if (g_strcmp0 (icon_name, "user-trash") == 0) self->_empty = TRUE;
161+ else self->_empty = FALSE;
162
163 g_object_unref(info);
164 }
165
166=== modified file 'src/TrashLauncherIcon.h'
167--- src/TrashLauncherIcon.h 2011-01-07 16:37:51 +0000
168+++ src/TrashLauncherIcon.h 2011-01-28 10:19:53 +0000
169@@ -37,10 +37,18 @@
170 void UpdateTrashIcon ();
171
172 private:
173+ std::map<std::string, DbusmenuMenuitem *> _menu_items;
174 GFileMonitor *m_TrashMonitor;
175+ gboolean _empty;
176+
177+ void EnsureMenuItemsReady ();
178+
179 static void UpdateTrashIconCb (GObject *source, GAsyncResult *res, gpointer data);
180 static void OnTrashChanged (GFileMonitor *monitor, GFile *file, GFile *other_file,
181 GFileMonitorEvent event_type, gpointer data);
182+ static void OnEmptyTrash (DbusmenuMenuitem *item, int time, TrashLauncherIcon *self);
183+ static void EmptyTrashAction ();
184+ static void RecursiveDelete (GFile *location);
185
186 };
187