2 * connectnow home widget for the maemo desktop.
3 * Copyright (C) 2010 Nicolai Hess
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <hildon/hildon.h>
22 #include <libhildondesktop/libhildondesktop.h>
23 #include <mce/dbus-names.h>
24 #include <mce/mode-names.h>
25 #include <icd/osso-ic-ui-dbus.h>
26 #include <icd/osso-ic-dbus.h>
30 #include "connectnow-home-widget.h"
31 #include "connectnow-settings-dialog.h"
32 #include "connectnow-load-and-store.h"
35 HD_DEFINE_PLUGIN_MODULE(ConnectNowHomePlugin, connect_now_home_plugin, HD_TYPE_HOME_PLUGIN_ITEM)
41 GtkWidget *contents = gtk_event_box_new();
42 gtk_event_box_set_visible_window(GTK_EVENT_BOX(contents), FALSE);
43 gtk_container_set_border_width(GTK_CONTAINER(contents), 0);
44 gtk_widget_show_all(GTK_WIDGET(contents));
45 return GTK_WIDGET(contents);
50 connect_now_settings_connection_changed(HildonPickerButton* button,
53 gtk_entry_set_text(GTK_ENTRY(data), hildon_button_get_value(HILDON_BUTTON(button)));
57 init_connection_list(ConnectNowHomePlugin* desktop_plugin,
58 GtkListStore* connection_list,
66 iap_list = con_ic_connection_get_all_iaps(desktop_plugin->con);
67 for (iap_entry = iap_list; iap_entry!=NULL ; iap_entry=g_slist_next(iap_entry))
69 ConIcIap* item = iap_entry->data;
70 const gchar* iap = con_ic_iap_get_id(item);
71 const gchar* name = con_ic_iap_get_name(item);
73 gtk_list_store_append (connection_list, &iter);
74 gtk_list_store_set(connection_list, &iter, 0, name, 1, iap, -1);
75 if(g_strcmp0(iap, desktop_plugin->connection_id)==0)
77 hildon_touch_selector_select_iter(HILDON_TOUCH_SELECTOR(selector),
81 hildon_button_set_value(HILDON_BUTTON(button), name);
85 g_slist_free(iap_list);
90 toggle_display_name_entry(GtkWidget* toggle_button, GtkWidget* entry)
92 if(hildon_check_button_get_active(HILDON_CHECK_BUTTON(toggle_button)))
94 gtk_widget_set_sensitive(entry, TRUE);
98 gtk_widget_set_sensitive(entry, FALSE);
103 connect_now_create_icon_data(ConnectNowHomePlugin* desktop_plugin)
105 icon_data_t* icon_data = g_new0(icon_data_t, 1);
106 icon_data->connect_name = g_strdup(desktop_plugin->connectedImageName);
107 icon_data->disconnect_name = g_strdup(desktop_plugin->disconnectedImageName);
108 icon_data->connect_icon = gtk_image_new_from_pixbuf(desktop_plugin->connectedImage);
109 icon_data->disconnect_icon = gtk_image_new_from_pixbuf(desktop_plugin->disconnectedImage);
114 connect_now_show_settings_dialog(GtkWidget* widget, gpointer data)
116 ConnectNowHomePlugin *desktop_plugin = CONNECT_NOW_HOME_PLUGIN(widget);
119 GtkCellRenderer *renderer;
121 GtkListStore *connection_list;
122 GtkWidget* icon_size_scale;
123 HildonTouchSelectorColumn* column;
124 GtkWidget* connection_button;
125 GtkWidget* display_name_entry;
126 GtkWidget* display_name_check_button;
127 GtkWidget* icon_button;
129 GtkWidget* display_name_box;
130 GtkWidget* connection_name_box;
131 GtkWidget* connection_name_label;
133 // Connection Setting
134 connection_button = hildon_picker_button_new(HILDON_SIZE_THUMB_HEIGHT,
135 HILDON_BUTTON_ARRANGEMENT_VERTICAL);
137 selector = hildon_touch_selector_new();
138 connection_list = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
140 renderer = gtk_cell_renderer_text_new();
141 column = hildon_touch_selector_append_column(HILDON_TOUCH_SELECTOR(selector),
142 GTK_TREE_MODEL(connection_list),
143 renderer, "text", 0, NULL);
145 hildon_touch_selector_column_set_text_column(column, 0);
146 hildon_touch_selector_set_column_selection_mode (HILDON_TOUCH_SELECTOR (selector),
147 HILDON_TOUCH_SELECTOR_SELECTION_MODE_SINGLE);
149 hildon_picker_button_set_selector(HILDON_PICKER_BUTTON(connection_button),
150 HILDON_TOUCH_SELECTOR(selector));
152 init_connection_list(desktop_plugin, connection_list, selector, connection_button);
154 connection_name_box = gtk_hbox_new(TRUE, 3);
155 connection_name_label = gtk_label_new("Connection:");
157 gtk_box_pack_start(GTK_BOX(connection_name_box), connection_name_label, TRUE, TRUE, 3);
158 gtk_box_pack_end(GTK_BOX(connection_name_box), connection_button, TRUE, TRUE, 3);
162 display_name_entry = hildon_entry_new(HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH);
163 if(desktop_plugin->connection_name!=NULL)
164 gtk_entry_set_text(GTK_ENTRY(display_name_entry),
165 desktop_plugin->connection_name);
167 display_name_check_button = hildon_check_button_new(HILDON_SIZE_AUTO);
168 hildon_check_button_set_active(HILDON_CHECK_BUTTON(display_name_check_button),
169 !desktop_plugin->hide_connection_name);
171 gtk_button_set_label(GTK_BUTTON(display_name_check_button),
173 g_signal_connect(display_name_check_button, "toggled", G_CALLBACK(toggle_display_name_entry),
177 display_name_box = gtk_hbox_new(TRUE, 3);
178 gtk_box_pack_start(GTK_BOX(display_name_box), display_name_check_button, TRUE, TRUE, 3);
179 gtk_box_pack_end(GTK_BOX(display_name_box), display_name_entry, TRUE, TRUE, 3);
181 g_signal_connect(G_OBJECT(connection_button),"value-changed",
182 G_CALLBACK(connect_now_settings_connection_changed),
186 icon_button = hildon_button_new_with_text(HILDON_SIZE_THUMB_HEIGHT,
187 HILDON_BUTTON_ARRANGEMENT_VERTICAL,
191 icon_data_t* icon_data = connect_now_create_icon_data(desktop_plugin);
193 icon_box = gtk_hbox_new(FALSE, 3);
194 GtkWidget* icon_box2 = gtk_hbox_new(TRUE, 3);
195 gtk_box_pack_start(GTK_BOX(icon_box2), icon_data->connect_icon, TRUE, TRUE, 0);
196 gtk_box_pack_start(GTK_BOX(icon_box2), icon_data->disconnect_icon, TRUE, TRUE, 0);
197 gtk_box_pack_start(GTK_BOX(icon_box), icon_box2, TRUE, FALSE, 0);
198 gtk_box_pack_start(GTK_BOX(icon_box), icon_button, TRUE, TRUE, 0);
200 g_signal_connect(G_OBJECT(icon_button), "clicked",
201 G_CALLBACK(connect_now_show_icon_selector), icon_data);
205 icon_size_scale = gtk_hscale_new_with_range(50, 200, 10);
206 gtk_scale_set_digits(GTK_SCALE(icon_size_scale), 0);
207 gtk_range_set_value(GTK_RANGE(icon_size_scale), desktop_plugin->widget_size);
210 dialog = gtk_dialog_new_with_buttons("Settings",
213 dgettext("hildon-libs", "wdgt_bd_done"),
217 gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), icon_box, FALSE, FALSE, 3);
218 gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), display_name_box, FALSE, FALSE, 3);
219 gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), connection_name_box, FALSE, FALSE, 3);
220 gtk_box_pack_end(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), icon_size_scale, FALSE, FALSE, 3);
222 gtk_widget_show_all(dialog);
224 if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
226 const gchar* displayName = hildon_entry_get_text(HILDON_ENTRY(display_name_entry));
227 const gchar* connection_name = hildon_button_get_value(HILDON_BUTTON(connection_button));
228 g_free(desktop_plugin->connection_name);
230 if(g_strcmp0(desktop_plugin->connectedImageName, icon_data->connect_name)!=0)
232 g_free(desktop_plugin->connectedImageName);
233 desktop_plugin->connectedImageName = g_strdup(icon_data->connect_name);
234 g_object_unref(desktop_plugin->connectedImage);
235 desktop_plugin->connectedImage = load_image(icon_data->connect_name);
238 if(g_strcmp0(desktop_plugin->disconnectedImageName, icon_data->disconnect_name)!=0)
240 g_free(desktop_plugin->disconnectedImageName);
241 desktop_plugin->disconnectedImageName = g_strdup(icon_data->disconnect_name);
242 g_object_unref(desktop_plugin->disconnectedImage);
243 desktop_plugin->disconnectedImage = load_image(icon_data->disconnect_name);
246 if(displayName!=NULL && displayName[0]!='\0')
248 desktop_plugin->connection_name = g_strdup(displayName);
252 desktop_plugin->connection_name = g_strdup(connection_name);
255 gboolean selected = hildon_touch_selector_get_selected(HILDON_TOUCH_SELECTOR(selector),
260 gtk_tree_model_get(GTK_TREE_MODEL(connection_list),
264 g_free(desktop_plugin->connection_id);
265 desktop_plugin->connection_id = iap;
267 desktop_plugin->widget_size = gtk_range_get_value(GTK_RANGE(icon_size_scale));
268 gtk_window_resize(GTK_WINDOW(desktop_plugin),
269 (int)(desktop_plugin->widget_size),
270 (int)(desktop_plugin->widget_size));
272 if(g_strcmp0(desktop_plugin->current_connection_id,
273 desktop_plugin->connection_id)==0)
275 desktop_plugin->this_connection_state = CON_IC_STATUS_CONNECTED;
279 desktop_plugin->this_connection_state = CON_IC_STATUS_DISCONNECTED;
281 desktop_plugin->hide_connection_name =
282 !hildon_check_button_get_active(HILDON_CHECK_BUTTON(display_name_check_button));
284 connect_now_save_settings(desktop_plugin);
285 gtk_widget_queue_draw(GTK_WIDGET(desktop_plugin));
287 g_free(icon_data->connect_name);
288 g_free(icon_data->disconnect_name);
290 gtk_widget_destroy (dialog);
291 g_object_unref(connection_list);
294 gboolean connect_now_connection_changed(ConIcConnection *connection, ConIcConnectionEvent *event, ConnectNowHomePlugin *desktop_plugin)
296 const gchar* iap_id = con_ic_event_get_iap_id((ConIcEvent*) event);
298 if(con_ic_connection_event_get_status(event) == CON_IC_STATUS_CONNECTED)
300 if(desktop_plugin->connection_id == NULL)
302 desktop_plugin->connection_id = g_strdup(iap_id);
303 ConIcIap* iap = con_ic_connection_get_iap(desktop_plugin->con, iap_id);
304 desktop_plugin->connection_name = g_strdup(con_ic_iap_get_name(iap));
307 g_free(desktop_plugin->current_connection_id);
308 desktop_plugin->current_connection_id = NULL;
309 desktop_plugin->current_connection_id = g_strdup(iap_id);
313 g_free(desktop_plugin->current_connection_id);
314 desktop_plugin->current_connection_id = NULL;
316 if(g_strcmp0(desktop_plugin->connection_id, iap_id)==0)
318 desktop_plugin->this_connection_state = con_ic_connection_event_get_status(event);
320 if(con_ic_connection_event_get_status(event) == CON_IC_STATUS_CONNECTED &&
321 desktop_plugin->connect_now)
323 desktop_plugin->connect_now = FALSE;
325 gtk_widget_queue_draw(GTK_WIDGET(desktop_plugin));
328 if(con_ic_connection_event_get_status(event) == CON_IC_STATUS_DISCONNECTED)
330 g_free(desktop_plugin->current_connection_id);
331 desktop_plugin->current_connection_id = NULL;
332 if(desktop_plugin->connect_now)
334 con_ic_connection_connect_by_id(desktop_plugin->con,
335 desktop_plugin->connection_id,
336 CON_IC_CONNECT_FLAG_NONE);
338 desktop_plugin->connect_now = FALSE;
345 connect_now_disconnect_current_connection(ConnectNowHomePlugin* desktop_plugin)
347 DBusGConnection* dbus_conn = hd_home_plugin_item_get_dbus_g_connection(&desktop_plugin->hitem,
350 DBusGProxy *proxy = dbus_g_proxy_new_for_name(dbus_conn,
353 ICD_UI_DBUS_INTERFACE);
354 gboolean disconnect = TRUE;
355 DBusMessage* message = dbus_message_new_signal(ICD_UI_DBUS_PATH,
356 ICD_UI_DBUS_INTERFACE,
357 ICD_UI_DISCONNECT_SIG);
358 dbus_message_append_args(message,
359 DBUS_TYPE_BOOLEAN, &disconnect,
363 dbus_g_proxy_send(proxy,
367 g_object_unref(proxy);
368 dbus_g_connection_unref(dbus_conn);
369 dbus_message_unref(message);
373 connect_now_switch_normal_mode(ConnectNowHomePlugin* desktop_plugin)
375 DBusGConnection* dbus_conn = hd_home_plugin_item_get_dbus_g_connection(HD_HOME_PLUGIN_ITEM(desktop_plugin),
378 DBusGProxy *proxy = dbus_g_proxy_new_for_name(dbus_conn,
383 gchar* dev_mode = NULL;
384 dbus_g_proxy_call(proxy,
392 if(g_str_equal(dev_mode, MCE_FLIGHT_MODE))
393 dbus_g_proxy_call_no_reply(proxy,
394 MCE_DEVICE_MODE_CHANGE_REQ,
396 MCE_NORMAL_MODE MCE_CONFIRM_SUFFIX,
400 g_object_unref(proxy);
401 dbus_g_connection_unref(dbus_conn);
405 connect_now_button_press(GtkWidget* widget, GdkEventButton *event, ConnectNowHomePlugin* desktop_plugin)
407 if(desktop_plugin->connection_name == NULL)
409 con_ic_connection_connect(desktop_plugin->con,
410 CON_IC_CONNECT_FLAG_NONE);
411 desktop_plugin->connect_now = FALSE;
415 if(desktop_plugin->current_connection_id != NULL)
417 if(g_strcmp0(desktop_plugin->current_connection_id,
418 desktop_plugin->connection_id) != 0)
421 if(desktop_plugin->this_connection_state == CON_IC_STATUS_DISCONNECTED)
423 desktop_plugin->connect_now = TRUE;
427 desktop_plugin->connect_now = FALSE;
430 connect_now_disconnect_current_connection(desktop_plugin);
434 connect_now_switch_normal_mode(desktop_plugin);
435 con_ic_connection_connect_by_id(desktop_plugin->con,
436 desktop_plugin->connection_id,
437 CON_IC_CONNECT_FLAG_NONE);
438 desktop_plugin->connect_now = FALSE;
440 gtk_widget_queue_draw(GTK_WIDGET(desktop_plugin));
445 connect_now_home_plugin_init(ConnectNowHomePlugin *desktop_plugin)
447 desktop_plugin->connection_name = NULL;
448 desktop_plugin->connection_id = NULL;
449 desktop_plugin->current_connection_id = NULL;
450 desktop_plugin->connectedImageName = NULL;
451 desktop_plugin->disconnectedImageName = NULL;
453 desktop_plugin->this_connection_state = CON_IC_STATUS_DISCONNECTED;
454 desktop_plugin->connect_now = FALSE;
455 desktop_plugin->con = con_ic_connection_new();
456 desktop_plugin->widget_size = CONNECTNOW_DEFAULT_WIDGET_WIDTH;
457 desktop_plugin->hide_connection_name = FALSE;
458 g_signal_connect(desktop_plugin->con, "connection-event", G_CALLBACK(connect_now_connection_changed), desktop_plugin);
459 g_object_set(desktop_plugin->con, "automatic-connection-events", TRUE);
461 GtkWidget *contents = build_ui();
463 gtk_widget_set_size_request(contents, desktop_plugin->widget_size, desktop_plugin->widget_size);
464 gtk_container_add(GTK_CONTAINER(desktop_plugin), contents);
465 hd_home_plugin_item_set_settings (HD_HOME_PLUGIN_ITEM (desktop_plugin), TRUE);
466 g_signal_connect(GTK_CONTAINER(contents), "button-press-event", G_CALLBACK(connect_now_button_press), desktop_plugin);
467 g_signal_connect(desktop_plugin, "show-settings", G_CALLBACK(connect_now_show_settings_dialog), NULL);
471 connect_now_realize(GtkWidget* widget)
473 GdkScreen *screen = gtk_widget_get_screen(widget);
474 gtk_widget_set_colormap(widget, gdk_screen_get_rgba_colormap(screen));
475 gtk_widget_set_app_paintable(widget, TRUE);
476 ConnectNowHomePlugin *desktop_plugin = CONNECT_NOW_HOME_PLUGIN(widget);
477 desktop_plugin->iD = hd_home_plugin_item_get_applet_id (HD_HOME_PLUGIN_ITEM (widget));
478 read_settings(desktop_plugin);
479 if(desktop_plugin->connectedImage == NULL)
481 desktop_plugin->connectedImageName = g_strdup(GENERAL_CONNECTED);
482 desktop_plugin->connectedImage = load_image(desktop_plugin->connectedImageName);
484 if(desktop_plugin->disconnectedImage == NULL)
486 desktop_plugin->disconnectedImageName = g_strdup(GENERAL_DISCONNECTED);
487 desktop_plugin->disconnectedImage = load_image(desktop_plugin->disconnectedImageName);
489 gtk_window_resize(GTK_WINDOW(widget),
490 desktop_plugin->widget_size,
491 desktop_plugin->widget_size);
493 GTK_WIDGET_CLASS(connect_now_home_plugin_parent_class)->realize(widget);
497 connect_now_expose(GtkWidget* widget, GdkEventExpose *event)
500 PangoLayout *pangoLayout;
501 PangoFontDescription *fontDescription;
503 cr = gdk_cairo_create(GDK_DRAWABLE(widget->window));
504 gdk_cairo_region(cr, event->region);
506 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
507 int width = CONNECT_NOW_HOME_PLUGIN(widget)->widget_size;
508 cairo_scale(cr, width/100.0, width/100.0);
511 GdkPixbuf* image = NULL;
512 if(CONNECT_NOW_HOME_PLUGIN(widget)->this_connection_state == CON_IC_STATUS_CONNECTED)
514 image = CONNECT_NOW_HOME_PLUGIN(widget)->connectedImage;
518 image = CONNECT_NOW_HOME_PLUGIN(widget)->disconnectedImage;
520 gdk_cairo_set_source_pixbuf(cr, image, 0.0, 0.0);
523 if(!CONNECT_NOW_HOME_PLUGIN(widget)->hide_connection_name)
526 pangoLayout = pango_cairo_create_layout(cr);
527 if(CONNECT_NOW_HOME_PLUGIN(widget)->connection_name)
528 pango_layout_set_text(pangoLayout, CONNECT_NOW_HOME_PLUGIN(widget)->connection_name, -1);
529 const char* font = "Sans 12";
530 fontDescription = pango_font_description_from_string(font);
531 pango_layout_set_font_description(pangoLayout, fontDescription);
532 pango_font_description_free(fontDescription);
535 pango_layout_get_pixel_size(pangoLayout, &width, &height);
537 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
538 cairo_pattern_t* linear_pattern = cairo_pattern_create_linear(0.0, 0.0, CONNECTNOW_DEFAULT_WIDGET_WIDTH, 0);
539 cairo_pattern_add_color_stop_rgba(linear_pattern, 0.0, 0.0, 0.0, 0.0, 0.0);
540 cairo_pattern_add_color_stop_rgba(linear_pattern, 0.25, 0.0, 0.0, 0.0, 0.35);
541 cairo_pattern_add_color_stop_rgba(linear_pattern, 0.75, 0.0, 0.0, 0.0, 0.35);
542 cairo_pattern_add_color_stop_rgba(linear_pattern, 1.0, 0.0, 0.0, 0.0, 0.0);
544 cairo_set_source(cr, linear_pattern);
545 cairo_rectangle(cr, 0, CONNECTNOW_DEFAULT_WIDGET_WIDTH - (1.25 * height), CONNECTNOW_DEFAULT_WIDGET_WIDTH, 1.25*height);
547 cairo_pattern_destroy(linear_pattern);
548 if(width>CONNECTNOW_DEFAULT_WIDGET_WIDTH)
550 double factor = (double)CONNECTNOW_DEFAULT_WIDGET_WIDTH/width;
551 cairo_scale(cr, factor, factor);
552 cairo_move_to(cr, 0, (CONNECTNOW_DEFAULT_WIDGET_WIDTH/factor)-(1.25*height));
556 cairo_move_to(cr, (CONNECTNOW_DEFAULT_WIDGET_WIDTH - width)/2.0, CONNECTNOW_DEFAULT_WIDGET_WIDTH-(1.25*height));
558 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
559 pango_cairo_show_layout(cr, pangoLayout);
562 return GTK_WIDGET_CLASS(connect_now_home_plugin_parent_class)->expose_event(widget, event);
567 connect_now_plugin_finalize(GObject *object)
569 ConnectNowHomePlugin *desktop_plugin = CONNECT_NOW_HOME_PLUGIN(object);
570 g_object_unref (desktop_plugin->con);
571 g_free(desktop_plugin->connection_id);
572 g_free(desktop_plugin->current_connection_id);
573 g_free(desktop_plugin->connection_name);
574 g_free(desktop_plugin->connectedImageName);
575 g_free(desktop_plugin->disconnectedImageName);
576 g_free(desktop_plugin->iD);
577 if(desktop_plugin->connectedImage)
578 g_object_unref(desktop_plugin->connectedImage);
579 if(desktop_plugin->disconnectedImage)
580 g_object_unref(desktop_plugin->disconnectedImage);
581 G_OBJECT_CLASS (connect_now_home_plugin_parent_class)->finalize (object);
585 connect_now_home_plugin_class_init(ConnectNowHomePluginClass *klass)
587 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
588 widget_class->realize = connect_now_realize;
589 widget_class->expose_event = connect_now_expose;
591 G_OBJECT_CLASS(klass)->finalize = connect_now_plugin_finalize;
595 connect_now_home_plugin_class_finalize(ConnectNowHomePluginClass *class)