63
63
class Shortcut : public PlacesSimpleTile
66
Shortcut (const char *icon, const char *name, int size)
67
: PlacesSimpleTile (icon, name, size),
66
Shortcut(const char* icon, const char* name, int size)
67
: PlacesSimpleTile(icon, name, size),
73
SetDndEnabled (false, false);
73
SetDndEnabled(false, false);
84
84
guint32 _place_section;
88
PlacesHomeView::PlacesHomeView ()
88
PlacesHomeView::PlacesHomeView()
91
PlacesStyle *style = PlacesStyle::GetDefault ();
93
SetName (_("Shortcuts"));
94
SetIcon (PKGDATADIR"/shortcuts_group_icon.png");
96
_layout = new nux::GridHLayout (NUX_TRACKER_LOCATION);
97
SetChildLayout (_layout);
99
_layout->ForceChildrenSize (true);
100
_layout->SetChildrenSize (style->GetHomeTileWidth (), style->GetHomeTileHeight ());
101
_layout->EnablePartialVisibility (false);
102
_layout->SetHeightMatchContent (true);
103
_layout->SetVerticalExternalMargin (32);
104
_layout->SetHorizontalExternalMargin (32);
105
_layout->SetVerticalInternalMargin (32);
106
_layout->SetHorizontalInternalMargin (32);
107
_layout->SetMinMaxSize ((style->GetHomeTileWidth () * 4) + (32 * 5),
108
(style->GetHomeTileHeight () * 2) + (32 *3));
110
_client = gconf_client_get_default ();
111
gconf_client_add_dir (_client,
113
GCONF_CLIENT_PRELOAD_NONE,
115
gconf_client_add_dir (_client,
117
GCONF_CLIENT_PRELOAD_NONE,
119
gconf_client_add_dir (_client,
121
GCONF_CLIENT_PRELOAD_NONE,
91
PlacesStyle* style = PlacesStyle::GetDefault();
93
SetName(_("Shortcuts"));
94
SetIcon(PKGDATADIR"/shortcuts_group_icon.png");
96
_layout = new nux::GridHLayout(NUX_TRACKER_LOCATION);
97
_layout->SetReconfigureParentLayoutOnGeometryChange(true);
98
SetChildLayout(_layout);
100
_layout->ForceChildrenSize(true);
101
_layout->SetChildrenSize(style->GetHomeTileWidth(), style->GetHomeTileHeight());
102
_layout->EnablePartialVisibility(false);
103
_layout->SetHeightMatchContent(true);
104
_layout->SetVerticalExternalMargin(32);
105
_layout->SetHorizontalExternalMargin(32);
106
_layout->SetVerticalInternalMargin(32);
107
_layout->SetHorizontalInternalMargin(32);
108
_layout->SetMinMaxSize((style->GetHomeTileWidth() * 4) + (32 * 5),
109
(style->GetHomeTileHeight() * 2) + (32 * 3));
111
_client = gconf_client_get_default();
112
gconf_client_add_dir(_client,
114
GCONF_CLIENT_PRELOAD_NONE,
116
gconf_client_add_dir(_client,
118
GCONF_CLIENT_PRELOAD_NONE,
120
gconf_client_add_dir(_client,
122
GCONF_CLIENT_PRELOAD_NONE,
123
124
_browser_gconf_notify = gconf_client_notify_add(_client,
125
126
(GConfClientNotifyFunc)OnKeyChanged,
150
151
_browser_alternatives.push_back("chromium-browser");
151
152
_browser_alternatives.push_back("epiphany-browser");
152
153
_browser_alternatives.push_back("midori");
154
155
_photo_alternatives.push_back("shotwell");
155
156
_photo_alternatives.push_back("f-spot");
156
157
_photo_alternatives.push_back("gthumb");
157
158
_photo_alternatives.push_back("gwenview");
158
159
_photo_alternatives.push_back("eog");
160
161
_email_alternatives.push_back("evolution");
161
162
_email_alternatives.push_back("thunderbird");
162
163
_email_alternatives.push_back("claws-mail");
163
164
_email_alternatives.push_back("kmail");
165
_music_alternatives.push_back("banshee");
166
_music_alternatives.push_back("banshee-1");
166
167
_music_alternatives.push_back("rhythmbox");
167
168
_music_alternatives.push_back("totem");
168
169
_music_alternatives.push_back("vlc");
170
expanded.connect (sigc::mem_fun (this, &PlacesHomeView::Refresh));
171
expanded.connect(sigc::mem_fun(this, &PlacesHomeView::Refresh));
172
SetExpanded (PlacesSettings::GetDefault ()->GetHomeExpanded ());
173
SetExpanded(PlacesSettings::GetDefault()->GetHomeExpanded());
177
PlacesHomeView::~PlacesHomeView ()
178
PlacesHomeView::~PlacesHomeView()
179
g_object_unref (_client);
180
g_object_unref(_client);
181
182
if (_ubus_handle != 0)
182
ubus_server_unregister_interest (ubus_server_get_default (), _ubus_handle);
183
ubus_server_unregister_interest(ubus_server_get_default(), _ubus_handle);
184
185
if (_browser_gconf_notify)
185
gconf_client_notify_remove (_client, _browser_gconf_notify);
186
gconf_client_notify_remove(_client, _browser_gconf_notify);
186
187
if (_mail_gconf_notify)
187
gconf_client_notify_remove (_client, _mail_gconf_notify);
188
gconf_client_notify_remove(_client, _mail_gconf_notify);
188
189
if (_media_gconf_notify)
189
gconf_client_notify_remove (_client, _media_gconf_notify);
190
gconf_client_remove_dir (_client, BROWSER_DIR, NULL);
191
gconf_client_remove_dir (_client, MAIL_DIR, NULL);
192
gconf_client_remove_dir (_client, MEDIA_DIR, NULL);
190
gconf_client_notify_remove(_client, _media_gconf_notify);
191
gconf_client_remove_dir(_client, BROWSER_DIR, NULL);
192
gconf_client_remove_dir(_client, MAIL_DIR, NULL);
193
gconf_client_remove_dir(_client, MEDIA_DIR, NULL);
196
PlacesHomeView::DashVisible (GVariant *data, void *val)
197
PlacesHomeView::DashVisible(GVariant* data, void* val)
198
PlacesHomeView *self = (PlacesHomeView*)val;
199
PlacesHomeView* self = (PlacesHomeView*)val;
200
201
struct timespec event_time, delta;
201
202
clock_gettime(CLOCK_MONOTONIC, &event_time);
202
delta = self->time_diff (self->_last_activate_time, event_time);
203
delta = self->time_diff(self->_last_activate_time, event_time);
204
205
self->_last_activate_time.tv_sec = event_time.tv_sec;
205
206
self->_last_activate_time.tv_nsec = event_time.tv_nsec;
207
208
// FIXME: this should be handled by ubus (not sending the request twice
208
209
// for some selected ones). Too intrusive for now.
209
210
if (!((delta.tv_sec == 0) && (delta.tv_nsec < DELTA_DOUBLE_REQUEST)))
215
PlacesHomeView::OnKeyChanged (GConfClient *client,
218
PlacesHomeView *self)
224
PlacesHomeView::Refresh ()
226
PlacesStyle *style = PlacesStyle::GetDefault ();
227
Shortcut *shortcut = NULL;
228
gchar *markup = NULL;
229
const char *temp = "<big>%s</big>";
230
int icon_size = style->GetHomeTileIconSize ();
234
PlacesSettings::GetDefault ()->SetHomeExpanded (GetExpanded ());
216
PlacesHomeView::OnKeyChanged(GConfClient* client,
219
PlacesHomeView* self)
225
PlacesHomeView::Refresh()
227
PlacesStyle* style = PlacesStyle::GetDefault();
228
Shortcut* shortcut = NULL;
229
gchar* markup = NULL;
230
const char* temp = "<big>%s</big>";
231
int icon_size = style->GetHomeTileIconSize();
235
PlacesSettings::GetDefault()->SetHomeExpanded(GetExpanded());
240
markup = g_strdup_printf (temp, _("Media Apps"));
241
shortcut = new Shortcut (PKGDATADIR"/find_media_apps.png",
241
markup = g_strdup_printf(temp, _("Media Apps"));
242
shortcut = new Shortcut(PKGDATADIR"/find_media_apps.png",
244
245
shortcut->_id = TYPE_PLACE;
245
shortcut->_place_id = g_strdup ("/com/canonical/unity/applicationsplace/applications");
246
shortcut->_place_id = g_strdup("/com/canonical/unity/applicationsplace/applications");
246
247
shortcut->_place_section = 9;
247
_layout->AddView (shortcut, 1, nux::eLeft, nux::eFull);
248
shortcut->sigClick.connect (sigc::mem_fun (this, &PlacesHomeView::OnShortcutClicked));
248
_layout->AddView(shortcut, 1, nux::eLeft, nux::eFull);
249
shortcut->sigClick.connect(sigc::mem_fun(this, &PlacesHomeView::OnShortcutClicked));
252
markup = g_strdup_printf (temp, _("Internet Apps"));
253
shortcut = new Shortcut (PKGDATADIR"/find_internet_apps.png",
253
markup = g_strdup_printf(temp, _("Internet Apps"));
254
shortcut = new Shortcut(PKGDATADIR"/find_internet_apps.png",
256
257
shortcut->_id = TYPE_PLACE;
257
shortcut->_place_id = g_strdup ("/com/canonical/unity/applicationsplace/applications");
258
shortcut->_place_id = g_strdup("/com/canonical/unity/applicationsplace/applications");
258
259
shortcut->_place_section = 8;
259
_layout->AddView (shortcut, 1, nux::eLeft, nux::eFull);
260
shortcut->sigClick.connect (sigc::mem_fun (this, &PlacesHomeView::OnShortcutClicked));
260
_layout->AddView(shortcut, 1, nux::eLeft, nux::eFull);
261
shortcut->sigClick.connect(sigc::mem_fun(this, &PlacesHomeView::OnShortcutClicked));
264
markup = g_strdup_printf (temp, _("More Apps"));
265
shortcut = new Shortcut (PKGDATADIR"/find_more_apps.png",
265
markup = g_strdup_printf(temp, _("More Apps"));
266
shortcut = new Shortcut(PKGDATADIR"/find_more_apps.png",
268
269
shortcut->_id = TYPE_PLACE;
269
shortcut->_place_id = g_strdup ("/com/canonical/unity/applicationsplace/applications");
270
shortcut->_place_id = g_strdup("/com/canonical/unity/applicationsplace/applications");
270
271
shortcut->_place_section = 0;
271
_layout->AddView (shortcut, 1, nux::eLeft, nux::eFull);
272
shortcut->sigClick.connect (sigc::mem_fun (this, &PlacesHomeView::OnShortcutClicked));
272
_layout->AddView(shortcut, 1, nux::eLeft, nux::eFull);
273
shortcut->sigClick.connect(sigc::mem_fun(this, &PlacesHomeView::OnShortcutClicked));
276
markup = g_strdup_printf (temp, _("Find Files"));
277
shortcut = new Shortcut (PKGDATADIR"/find_files.png",
277
markup = g_strdup_printf(temp, _("Find Files"));
278
shortcut = new Shortcut(PKGDATADIR"/find_files.png",
280
281
shortcut->_id = TYPE_PLACE;
281
shortcut->_place_id = g_strdup ("/com/canonical/unity/filesplace/files");
282
shortcut->_place_id = g_strdup("/com/canonical/unity/filesplace/files");
282
283
shortcut->_place_section = 0;
283
_layout->AddView (shortcut, 1, nux::eLeft, nux::eFull);
284
shortcut->sigClick.connect (sigc::mem_fun (this, &PlacesHomeView::OnShortcutClicked));
284
_layout->AddView(shortcut, 1, nux::eLeft, nux::eFull);
285
shortcut->sigClick.connect(sigc::mem_fun(this, &PlacesHomeView::OnShortcutClicked));
288
markup = gconf_client_get_string (_client, BROWSER_DIR"/exec", NULL);
289
CreateShortcutFromExec (markup, _("Browse the Web"), _browser_alternatives);
289
markup = gconf_client_get_string(_client, BROWSER_DIR"/exec", NULL);
290
CreateShortcutFromExec(markup, _("Browse the Web"), _browser_alternatives);
293
294
// FIXME: Need to figure out the default
294
CreateShortcutFromExec ("shotwell", _("View Photos"), _photo_alternatives);
295
CreateShortcutFromExec("shotwell", _("View Photos"), _photo_alternatives);
297
markup = gconf_client_get_string (_client, MAIL_DIR"/command", NULL);
298
markup = gconf_client_get_string(_client, MAIL_DIR"/command", NULL);
298
299
// get the first word on key (the executable name itself)
299
markup = g_strsplit (markup, " ", 0)[0];
300
CreateShortcutFromExec (markup, _("Check Email"), _email_alternatives);
300
markup = g_strsplit(markup, " ", 0)[0];
301
CreateShortcutFromExec(markup, _("Check Email"), _email_alternatives);
304
markup = gconf_client_get_string (_client, MEDIA_DIR"/exec", NULL);
305
CreateShortcutFromExec (markup, _("Listen to Music"), _music_alternatives);
305
markup = gconf_client_get_string(_client, MEDIA_DIR"/exec", NULL);
306
CreateShortcutFromExec(markup, _("Listen to Music"), _music_alternatives);
309
_layout->QueueDraw ();
310
_layout->QueueDraw();
314
PlacesHomeView::CreateShortcutFromExec (const char *exec,
316
std::vector<std::string>& alternatives)
315
PlacesHomeView::CreateShortcutFromExec(const char* exec,
317
std::vector<std::string>& alternatives)
318
PlacesStyle *style = PlacesStyle::GetDefault ();
319
Shortcut *shortcut = NULL;
324
GDesktopAppInfo *info;
319
PlacesStyle* style = PlacesStyle::GetDefault();
320
Shortcut* shortcut = NULL;
325
GDesktopAppInfo* info;
326
markup = g_strdup_printf ("<big>%s</big>", name);
327
markup = g_strdup_printf("<big>%s</big>", name);
328
329
// We're going to try and create a desktop id from a exec string. Now, this is hairy at the
329
330
// best of times but the following is the closest best-guess without having to do D-Bus
330
331
// roundtrips to BAMF.
335
336
if (exec[0] == '/')
336
basename = g_path_get_basename (exec);
337
basename = g_path_get_basename(exec);
338
basename = g_strdup (exec);
340
id = g_strdup_printf ("%s.desktop", basename);
339
basename = g_strdup(exec);
341
id = g_strdup_printf("%s.desktop", basename);
346
id = g_strdup_printf ("%s.desktop", alternatives[0].c_str());
347
id = g_strdup_printf("%s.desktop", alternatives[0].c_str());
349
info = g_desktop_app_info_new (id);
350
info = g_desktop_app_info_new(id);
350
351
std::vector<std::string>::iterator iter = alternatives.begin();
351
352
while (iter != alternatives.end())
353
if (!G_IS_DESKTOP_APP_INFO (info))
354
if (!G_IS_DESKTOP_APP_INFO(info))
355
id = g_strdup_printf ("%s.desktop", (*iter).c_str());
356
info = g_desktop_app_info_new (id);
356
id = g_strdup_printf("%s.desktop", (*iter).c_str());
357
info = g_desktop_app_info_new(id);
360
if (G_IS_DESKTOP_APP_INFO (info))
361
if (G_IS_DESKTOP_APP_INFO(info))
362
icon = g_icon_to_string (g_app_info_get_icon (G_APP_INFO (info)));
363
real_exec = g_strdup (g_app_info_get_executable (G_APP_INFO (info)));
365
shortcut = new Shortcut (icon, markup, style->GetHomeTileIconSize ());
363
icon = g_icon_to_string(g_app_info_get_icon(G_APP_INFO(info)));
364
real_exec = g_strdup(g_app_info_get_executable(G_APP_INFO(info)));
366
shortcut = new Shortcut(icon, markup, style->GetHomeTileIconSize());
366
367
shortcut->_id = TYPE_EXEC;
367
368
shortcut->_exec = real_exec;
368
_layout->AddView (shortcut, 1, nux::eLeft, nux::eFull);
369
shortcut->sigClick.connect (sigc::mem_fun (this, &PlacesHomeView::OnShortcutClicked));
369
_layout->AddView(shortcut, 1, nux::eLeft, nux::eFull);
370
shortcut->sigClick.connect(sigc::mem_fun(this, &PlacesHomeView::OnShortcutClicked));
382
PlacesHomeView::OnShortcutClicked (PlacesTile *tile)
383
PlacesHomeView::OnShortcutClicked(PlacesTile* tile)
384
Shortcut *shortcut = static_cast<Shortcut *> (tile);
385
Shortcut* shortcut = static_cast<Shortcut*>(tile);
385
386
int id = shortcut->_id;
387
388
if (id == TYPE_PLACE)
389
ubus_server_send_message (ubus_server_get_default (),
390
UBUS_PLACE_ENTRY_ACTIVATE_REQUEST,
391
g_variant_new ("(sus)",
393
shortcut->_place_section,
390
ubus_server_send_message(ubus_server_get_default(),
391
UBUS_PLACE_ENTRY_ACTIVATE_REQUEST,
392
g_variant_new("(sus)",
394
shortcut->_place_section,
396
397
else if (id == TYPE_EXEC)
398
GError *error = NULL;
399
GError* error = NULL;
400
if (!g_spawn_command_line_async (shortcut->_exec, &error))
401
if (!g_spawn_command_line_async(shortcut->_exec, &error))
402
g_warning ("%s: Unable to launch %s: %s",
406
g_error_free (error);
403
g_warning("%s: Unable to launch %s: %s",
409
ubus_server_send_message (ubus_server_get_default (),
410
UBUS_PLACE_VIEW_CLOSE_REQUEST,
410
ubus_server_send_message(ubus_server_get_default(),
411
UBUS_PLACE_VIEW_CLOSE_REQUEST,
415
const gchar* PlacesHomeView::GetName ()
416
const gchar* PlacesHomeView::GetName()
417
return "PlacesHomeView";
418
return "PlacesHomeView";
421
PlacesHomeView::GetChildsName ()
422
PlacesHomeView::GetChildsName()
426
void PlacesHomeView::AddProperties (GVariantBuilder *builder)
427
void PlacesHomeView::AddProperties(GVariantBuilder* builder)
428
429
unity::variant::BuilderWrapper(builder).add(GetGeometry());
431
432
// TODO: put that in some "util" toolbox
432
struct timespec PlacesHomeView::time_diff (struct timespec start, struct timespec end)
433
struct timespec PlacesHomeView::time_diff(struct timespec start, struct timespec end)
434
435
struct timespec temp;
435
if ((end.tv_nsec - start.tv_nsec) < 0) {
436
temp.tv_sec = end.tv_sec - start.tv_sec-1;
436
if ((end.tv_nsec - start.tv_nsec) < 0)
438
temp.tv_sec = end.tv_sec - start.tv_sec - 1;
437
439
temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec;
439
443
temp.tv_sec = end.tv_sec - start.tv_sec;
440
444
temp.tv_nsec = end.tv_nsec - start.tv_nsec;