replaced 0 with NULL where appropriate: shut the compiler up
[simple-launcher] / simple-launcher.cc
1 // This file is a part of Simple Launcher
2 //
3 // Copyright (C) 2006, Mikhail Sobolev
4 //
5 // Simple Launcher is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License version 2 as published by
7 // the Free Software Foundation.
8 //
9 // This program is distributed in the hope that it will be useful, but WITHOUT
10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12 // more details.
13 //
14 // You should have received a copy of the GNU General Public License along with
15 // this program; if not, write to the Free Software Foundation, Inc., 51
16 // Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
18 #include <string>
19 #include <vector>
20
21 #include <gtk/gtk.h>
22
23 #include <hildon-home-plugin/hildon-home-plugin-interface.h>
24 #include <libosso.h>
25
26 #include "launcher-item.h"
27 #include "sla-list.h"
28 #include "launchable-item.h"
29
30 #define SL_APPLET_DBUS_NAME  "simple-launcher"
31 #define SL_APPLET_VERSION    "0.0"
32 #define SL_APPLET_ICON_SIZE  26
33 #define SL_APPLET_BORDER_SIZE  14
34 #define SL_APPLET_CANVAS_SIZE  (SL_APPLET_BORDER_SIZE+SL_APPLET_BORDER_SIZE)
35
36 class SimpleLauncherApplet {
37 public:
38   SimpleLauncherApplet();
39  ~SimpleLauncherApplet();
40
41   bool doInit(void *state_data, int *state_size);
42
43   void background() {}
44   void foreground() {}
45   int saveState(void **state_data, int *state_size);
46   GtkWidget *settings(GtkWindow *parent);
47
48   GtkWidget *getWidget() { return myWidget; }
49
50 private:
51   bool initWidget();
52
53   void buttonClicked(GtkToolButton *);
54   void runDialog();
55
56   static void _button_clicked(GtkToolButton *, void *);
57   static void _run_dialog(GtkMenuItem *, void *);
58
59 private:
60   osso_context_t *myContext;
61   GtkWidget *myWidget;
62   GtkWindow *myParent;
63
64   LauncherItems myItems;
65
66   static char *ourFiles[];
67 };
68
69 // Hildon home applet interface functions
70
71 void *hildon_home_applet_lib_initialize(void *state_data, int *state_size, GtkWidget **widget) {
72   SimpleLauncherApplet *applet = new SimpleLauncherApplet();
73
74   if (applet != NULL) {
75     if (applet->doInit(state_data, state_size)) {
76       *widget = applet->getWidget();
77     } else {
78       delete applet;
79       applet = NULL;
80     }
81   }
82
83   return (void*)applet;
84 }
85
86 void hildon_home_applet_lib_deinitialize(void *applet_data) {
87   SimpleLauncherApplet *applet = (SimpleLauncherApplet *)applet_data;
88
89   delete applet;
90 }
91
92 void hildon_home_applet_lib_background(void *applet_data) {
93   ((SimpleLauncherApplet *)applet_data)->background();
94 }
95
96 void hildon_home_applet_lib_foreground (void *applet_data) {
97   ((SimpleLauncherApplet *)applet_data)->foreground();
98 }
99
100 GtkWidget *hildon_home_applet_lib_settings(void *applet_data, GtkWindow *parent) {
101   return ((SimpleLauncherApplet *)applet_data)->settings(parent);
102 }
103
104 int hildon_home_applet_lib_save_state (void *applet_data, void **state_data, int *state_size) {
105   return ((SimpleLauncherApplet *)applet_data)->saveState(state_data, state_size);
106 }
107
108 // SimpleLauncherApplet implementation
109
110 char *SimpleLauncherApplet::ourFiles[] = {
111   "/usr/share/applications/hildon/FBReader.desktop",
112   "/usr/share/applications/hildon/mp_ui.desktop",
113   "/usr/share/applications/hildon/osso-xterm.desktop",
114   "/usr/share/applications/hildon/filemanager.desktop",
115   "/usr/share/applications/hildon/osso-application-installer.desktop",
116   "/usr/share/applications/hildon/hildon-control-panel.desktop",
117   NULL
118 };
119
120 SimpleLauncherApplet::SimpleLauncherApplet(): myContext(NULL), myWidget(NULL), myParent(NULL) {
121 }
122
123 bool SimpleLauncherApplet::doInit(void *state_data, int *state_size) {
124   if ((myContext = osso_initialize(SL_APPLET_DBUS_NAME, SL_APPLET_VERSION, FALSE, NULL)) == NULL) {
125     g_debug("sla-applet: failed to initialize the osso layer");
126     return false;
127   }
128
129   for (int i = 0 ; ourFiles[i] != NULL ; ++i) {
130     LaunchableItem *item = new LaunchableItem();
131
132     if (item->load(ourFiles[i])) {
133       myItems.push_back(std::pair<std::string, LauncherItem *>(ourFiles[i], item));
134     } else {
135       delete item;
136     }
137   }
138
139   if (!initWidget()) {
140     return false;
141   }
142
143   gtk_widget_show_all(myWidget);
144
145   return true;
146 }
147
148 SimpleLauncherApplet::~SimpleLauncherApplet() {
149   for (LauncherItems::iterator it = myItems.begin(); it != myItems.end(); ++it) {
150     if (it->second != NULL) {
151       delete it->second;
152       it->second = NULL;
153     }
154   }
155
156   myItems.resize(0);
157
158   if (myWidget != NULL) {
159     gtk_widget_destroy(myWidget);
160     myWidget = NULL;
161   }
162
163   if (myContext != NULL) {
164     osso_deinitialize(myContext);
165     myContext = NULL;
166   }
167 }
168
169 bool SimpleLauncherApplet::initWidget() {
170   int button_no = 0;
171
172   GtkToolbar *toolbar = GTK_TOOLBAR(gtk_toolbar_new());
173
174   for (LauncherItems::const_iterator it = myItems.begin(); it != myItems.end(); ++it) {
175     GtkToolItem *button = gtk_tool_button_new(gtk_image_new_from_pixbuf(it->second->getIcon(SL_APPLET_ICON_SIZE)), NULL);
176
177     gtk_object_set_user_data(GTK_OBJECT(button), it->second);
178     g_signal_connect(button, "clicked", G_CALLBACK(_button_clicked), this);
179
180     gtk_toolbar_insert(toolbar, button, -1);
181
182     ++button_no;
183   }
184
185   if (button_no) {
186     myWidget = gtk_frame_new(NULL);
187     gtk_frame_set_shadow_type(GTK_FRAME(myWidget), GTK_SHADOW_ETCHED_IN);
188     gtk_widget_set_size_request(myWidget, button_no*(SL_APPLET_ICON_SIZE+SL_APPLET_CANVAS_SIZE), SL_APPLET_ICON_SIZE+SL_APPLET_CANVAS_SIZE);
189     gtk_container_add(GTK_CONTAINER(myWidget), GTK_WIDGET(toolbar));
190   } else {
191     gtk_widget_destroy(GTK_WIDGET(toolbar));
192   }
193
194   return myWidget != NULL;
195 }
196
197 void SimpleLauncherApplet::_button_clicked(GtkToolButton *button, void *self) {
198   ((SimpleLauncherApplet *)self)->buttonClicked(button);
199 }
200
201 void SimpleLauncherApplet::buttonClicked(GtkToolButton *button) {
202   if (button != NULL) {
203     LaunchableItem *item = (LaunchableItem *)gtk_object_get_user_data(GTK_OBJECT(button));
204
205     if (item != NULL) {
206       item->activate(myContext);
207     }
208   }
209 }
210
211 int SimpleLauncherApplet::saveState(void **state_data, int *state_size) {
212   if (state_data != NULL) {
213     *state_data = NULL;
214   }
215
216   if (state_size != NULL) {
217     *state_size = NULL;
218   }
219
220   return 1;
221 }
222
223 GtkWidget *SimpleLauncherApplet::settings(GtkWindow *parent) {
224   // TODO: in case we want SimpleLauncherApplet to be configurable, this method
225   // should return a gtk_menu_item that would be included in home settings
226   // menu.  Method should make sure that when we activate that item, a
227   // corresponding dialog appears.
228   myParent = parent;  // FIXME: Ugly piece of code :(
229
230   GtkWidget *menuItem = gtk_menu_item_new_with_label("Launcher settings...");
231
232   g_signal_connect(menuItem, "activate", G_CALLBACK(_run_dialog), this);
233
234   return menuItem;
235 }
236
237 void SimpleLauncherApplet::_run_dialog(GtkMenuItem *, void *self) {
238   ((SimpleLauncherApplet *)self)->runDialog();
239 }
240
241 void SimpleLauncherApplet::runDialog() {
242   SLAList list(SL_APPLET_ICON_SIZE, myItems);
243
244   GtkDialog *dialog = GTK_DIALOG(gtk_dialog_new_with_buttons("Launcher Settings", myParent, (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), "OK", GTK_RESPONSE_OK, "Cancel", GTK_RESPONSE_CANCEL, NULL));
245
246   gtk_container_add(GTK_CONTAINER(dialog->vbox), list.getWidget());
247
248   gtk_widget_set_size_request(GTK_WIDGET(dialog), 540, 257);
249
250   int response = gtk_dialog_run(dialog);
251
252   gtk_widget_destroy(GTK_WIDGET(dialog));
253
254   switch (response) {
255     case GTK_RESPONSE_OK:
256       break;
257
258     case GTK_RESPONSE_CANCEL:
259       break;
260
261     default:
262       ;     // FIXME: do I want to do anything in here?
263   }
264 }
265
266 // vim:ts=2:sw=2:et