:pserver:cvs@pserver.samba.org:/cvsroot - gnokii - Fri Dec 14 20:46 CET 2001
[gnokii.git] / xgnokii / xgnokii_speed.c
1 /*
2
3   X G N O K I I
4
5   A Linux/Unix GUI for Nokia mobile phones.
6   Copyright (C) 1999 Pavel Janík ml., Hugh Blemings
7   & Ján Derfiòák <ja@mail.upjs.sk>.
8
9   Released under the terms of the GNU GPL, see file COPYING for more details.
10
11   Last modification: Sun Apr 30 2000
12   Modified by Jan Derfinak
13
14 */
15
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <pthread.h>
20 #include <gtk/gtk.h>
21 #include "xgnokii_contacts.h"
22 #include "xgnokii.h"
23 #include "xgnokii_lowlevel.h"
24 #include "xgnokii_common.h"
25 #include "xgnokii_speed.h"
26 #include "xpm/Read.xpm"
27 #include "xpm/Send.xpm"
28 #include "xpm/Open.xpm"
29 #include "xpm/Save.xpm"
30 #include "xpm/Edit.xpm"
31 #include "xpm/quest.xpm"
32
33
34 static GtkWidget *GUI_SpeedDialWindow;
35 static ErrorDialog errorDialog = {NULL, NULL};
36 static InfoDialog infoDialog = {NULL, NULL};
37 static ExportDialogData exportDialogData = {NULL};
38 static GtkWidget *clist;
39 static QuestMark questMark;
40 static gint selectedKey;
41 static bool speedDialInitialized;
42
43
44 static inline void Help1 (GtkWidget *w, gpointer data)
45 {
46   gchar *indx = g_strdup_printf ("/help/%s/windows/speeddial/index.html", xgnokiiConfig.locale);
47   Help (w, indx);
48   g_free (indx);
49 }
50
51
52 static void CloseSpeedDial (GtkWidget *w, gpointer data)
53 {
54   gtk_widget_hide (GUI_SpeedDialWindow);
55 }
56
57
58 static inline void DestroyCListData (gpointer data)
59 {
60   if (data)
61     g_free ((D_SpeedDial *) data);
62 }
63
64
65 static void DeleteSelectContactDialog (GtkWidget *widget, GdkEvent *event,
66                                        SelectContactData *data)
67 {
68   gtk_widget_destroy (GTK_WIDGET (data->clist));
69   gtk_widget_destroy (GTK_WIDGET (data->clistScrolledWindow));
70   gtk_widget_destroy (GTK_WIDGET (widget));
71 }
72
73
74 static void CancelSelectContactDialog (GtkWidget *widget,
75                                        SelectContactData *data)
76 {
77   gtk_widget_destroy (GTK_WIDGET (data->clist));
78   gtk_widget_destroy (GTK_WIDGET (data->clistScrolledWindow));
79   gtk_widget_destroy (GTK_WIDGET (data->dialog));
80 }
81
82
83 static void OkSelectContactDialog (GtkWidget *widget,
84                                    SelectContactData *data)
85 {
86   GList *sel;
87   PhonebookEntry *pbEntry;
88   gchar *key;
89
90   if ((sel = GTK_CLIST (data->clist)->selection) != NULL)
91   {
92     D_SpeedDial *d = (D_SpeedDial *) g_malloc (sizeof (D_SpeedDial));
93
94     gtk_clist_freeze (GTK_CLIST (clist));
95
96     pbEntry = gtk_clist_get_row_data (GTK_CLIST (data->clist),
97                                       GPOINTER_TO_INT (sel->data));
98
99     gtk_clist_get_text (GTK_CLIST (clist), selectedKey, 0, &key);
100
101     gtk_clist_set_text (GTK_CLIST (clist), selectedKey, 1, pbEntry->entry.Name);
102     gtk_clist_set_text (GTK_CLIST (clist), selectedKey, 2, pbEntry->entry.Number);
103
104     d->entry.Number = *key - '0';
105     d->entry.MemoryType = pbEntry->entry.MemoryType + 2;
106     d->entry.Location = pbEntry->entry.Location;
107
108     gtk_clist_set_row_data_full (GTK_CLIST (clist), selectedKey,
109                                  (gpointer) d, DestroyCListData);
110
111     gtk_clist_sort (GTK_CLIST (clist));
112     gtk_clist_thaw (GTK_CLIST (clist));
113   }
114
115   gtk_widget_destroy (GTK_WIDGET (data->clist));
116   gtk_widget_destroy (GTK_WIDGET (data->clistScrolledWindow));
117   gtk_widget_destroy (GTK_WIDGET (data->dialog));
118 }
119
120 static void ShowSelectContactsDialog (void)
121 {
122   SelectContactData *r;
123
124   if (!GUI_ContactsIsIntialized ())
125     GUI_ReadContacts ();
126
127   if ((r = GUI_SelectContactDialog ()) == NULL)
128     return;
129
130   gtk_signal_connect (GTK_OBJECT (r->dialog), "delete_event",
131                       GTK_SIGNAL_FUNC (DeleteSelectContactDialog), (gpointer) r);
132
133   gtk_signal_connect (GTK_OBJECT (r->okButton), "clicked",
134                       GTK_SIGNAL_FUNC (OkSelectContactDialog), (gpointer) r);
135   gtk_signal_connect (GTK_OBJECT (r->cancelButton), "clicked",
136                       GTK_SIGNAL_FUNC (CancelSelectContactDialog), (gpointer) r);
137 }
138
139
140 static inline void EditKey (void)
141 {
142   GList *sel;
143
144   if ((sel = GTK_CLIST (clist)->selection) != NULL)
145   {
146     selectedKey = GPOINTER_TO_INT (sel->data);
147     ShowSelectContactsDialog ();
148   }
149 }
150
151
152 static inline void ClickEntry (GtkWidget      *clist,
153                  gint            row,
154                  gint            column,
155                  GdkEventButton *event,
156                  gpointer        data )
157 {
158   if(event && event->type == GDK_2BUTTON_PRESS)
159   {
160     selectedKey = row;
161     ShowSelectContactsDialog ();
162   }
163 }
164
165
166 static void ReadSpeedDial (void)
167 {
168   PhonebookEntry *pbEntry;
169   D_SpeedDial *d;
170   PhoneEvent *e;
171   gchar *row[3];
172   gchar buf[2] = " ";
173   gint location;
174   register gint i, row_i = 0;
175
176
177   if (!GUI_ContactsIsIntialized ())
178     GUI_ReadContacts ();
179
180   gtk_label_set_text (GTK_LABEL (infoDialog.text), _("Reading data ..."));
181   gtk_widget_show_now (infoDialog.dialog);
182   GUI_Refresh ();
183
184   gtk_clist_freeze (GTK_CLIST (clist));
185   gtk_clist_clear (GTK_CLIST (clist));
186
187   for (i = 1; i < 10; i++)
188   {
189     if ((d = (D_SpeedDial *) g_malloc (sizeof (D_SpeedDial))) == NULL)
190     {
191       g_print (_("Cannot allocate memory!"));
192       return;
193     }
194     d->entry.Number = i;
195     if ((e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent))) == NULL)
196     {
197       g_print (_("Cannot allocate memory!"));
198       g_free (d);
199       return;   
200     }
201     e->event = Event_GetSpeedDial;
202     e->data = d;
203     GUI_InsertEvent (e);
204     pthread_mutex_lock (&speedDialMutex);
205     pthread_cond_wait (&speedDialCond, &speedDialMutex);
206     pthread_mutex_unlock (&speedDialMutex);
207
208     if (d->status != GE_NONE)
209       g_print ("Cannot read speed dial key %d!\n", i);
210     else
211     {
212       if (d->entry.Location == 0)
213         location = i;
214       else
215         location = d->entry.Location;
216       if ((pbEntry = GUI_GetEntry (d->entry.MemoryType - 2, location)) == NULL)
217       {
218         g_free (d);
219         continue;
220       }
221       *buf = i + '0';
222       row[0] = buf;
223       row[1] = pbEntry->entry.Name;
224       row[2] = pbEntry->entry.Number;
225
226       gtk_clist_append (GTK_CLIST (clist), row);
227       gtk_clist_set_row_data_full (GTK_CLIST (clist), row_i++,
228                                    (gpointer) d, DestroyCListData);
229     }
230     //GUI_Refresh ();
231     gtk_widget_hide (infoDialog.dialog);
232   }
233
234   gtk_clist_sort (GTK_CLIST (clist));
235   gtk_clist_thaw (GTK_CLIST (clist));
236   speedDialInitialized = TRUE;
237 }
238
239
240 static void SaveSpeedDial (void)
241 {
242   //gchar buf[80];
243   D_SpeedDial *d;
244   PhoneEvent *e;
245   register gint i;
246
247   if (speedDialInitialized)
248     for(i = 1; i < 10; i++)
249     {
250       if ((d = (D_SpeedDial *) gtk_clist_get_row_data (GTK_CLIST (clist), i - 1)))
251       {
252         if (d->entry.Location == 0)
253           continue;
254         if ((e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent))) == NULL)
255         {
256           g_print (_("Cannot allocate memory!"));
257           return;   
258         }
259         e->event = Event_SendSpeedDial;
260         e->data = d;
261         GUI_InsertEvent (e);
262 /*        pthread_mutex_lock (&speedDialMutex);
263         pthread_cond_wait (&speedDialCond, &speedDialMutex);
264         pthread_mutex_unlock (&speedDialMutex);
265
266         if (d->status != GE_NONE)
267         {
268           g_snprintf (buf, 80, _("Error writing speed\ndial for key %d!\n"),
269                       d->entry.Number);
270           gtk_label_set_text (GTK_LABEL (errorDialog.text), buf);
271           gtk_widget_show (errorDialog.dialog);
272         } */
273       }
274 //      GUI_Refresh ();
275     }
276 }
277
278
279 static bool ParseLine (D_SpeedDial *d, gchar *buf)
280 {
281   gchar **strings = g_strsplit (buf, ";", 3);
282
283   d->entry.Number = *strings[0] - '0';
284   if (d->entry.Number < 1 || d->entry.Number > 9)
285   {
286     g_strfreev (strings);
287     return FALSE;
288   }
289
290   d->entry.MemoryType = *strings[1] - '0';
291   if (d->entry.MemoryType < 2 || d->entry.MemoryType > 3)
292   {
293     g_strfreev (strings);
294     return FALSE;
295   }
296
297   d->entry.Location = atoi (strings[2]);
298   if (d->entry.Location == LONG_MIN || d->entry.Location == LONG_MAX ||
299       d->entry.Location < 0)
300   {
301     g_strfreev (strings);
302     return FALSE;
303   }
304
305   g_strfreev (strings);
306   return TRUE;
307 }
308
309
310 static void OkImportDialog (GtkWidget *w, GtkFileSelection *fs)
311 {
312   FILE *f;
313   D_SpeedDial *d;
314   PhonebookEntry *pbEntry;
315   gchar buf[IO_BUF_LEN];
316   gchar *row[3];
317   gchar *fileName;
318   gint location;
319   register gint i, row_i = 0;
320
321   fileName = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
322   gtk_widget_hide (GTK_WIDGET (fs));
323
324   if ((f = fopen (fileName, "r")) == NULL)
325   {
326     g_snprintf (buf, IO_BUF_LEN, _("Can't open file %s for reading!"), fileName);
327     gtk_label_set_text (GTK_LABEL(errorDialog.text), buf);
328     gtk_widget_show (errorDialog.dialog);
329     return;
330   }
331
332   if (!GUI_ContactsIsIntialized ())
333     GUI_ReadContacts ();
334
335   gtk_clist_freeze (GTK_CLIST (clist));
336   gtk_clist_clear (GTK_CLIST (clist));
337   speedDialInitialized = FALSE;
338
339   i = 0;
340   while (fgets (buf, IO_BUF_LEN, f) && i++ < 9)
341   {
342     if ((d = (D_SpeedDial *) g_malloc (sizeof (D_SpeedDial))) == NULL)
343     {
344       g_print (_("Cannot allocate memory!\n"));
345       gtk_clist_clear (GTK_CLIST (clist));
346       gtk_clist_sort (GTK_CLIST (clist));
347       gtk_clist_thaw (GTK_CLIST (clist));
348       return;
349     }
350     if (ParseLine (d, buf))
351     {
352       if (d->entry.Number != i)
353       {
354         g_free (d);
355         gtk_clist_clear (GTK_CLIST (clist));
356         gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Error reading file!"));
357         gtk_widget_show (errorDialog.dialog);
358         gtk_clist_sort (GTK_CLIST (clist));
359         gtk_clist_thaw (GTK_CLIST (clist));
360         return;
361       }
362       if (d->entry.Location == 0)
363         location = i;
364       else
365         location = d->entry.Location;
366       if ((pbEntry = GUI_GetEntry (d->entry.MemoryType - 2, location)) == NULL)
367       {
368         g_free (d);
369         continue;
370       }
371       *buf = i + '0';
372       *(buf + 1) = '\0';
373       row[0] = buf;
374       row[1] = pbEntry->entry.Name;
375       row[2] = pbEntry->entry.Number;
376       gtk_clist_append (GTK_CLIST (clist), row);
377       gtk_clist_set_row_data_full (GTK_CLIST (clist), row_i++,
378                                    (gpointer) d, DestroyCListData);
379     }
380     else
381     {
382       g_free (d);
383       gtk_clist_clear (GTK_CLIST (clist));
384       gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Error reading file!"));
385       gtk_widget_show (errorDialog.dialog);
386       gtk_clist_sort (GTK_CLIST (clist));
387       gtk_clist_thaw (GTK_CLIST (clist));
388       return;
389     }
390   }
391
392   gtk_clist_sort (GTK_CLIST (clist));
393   gtk_clist_thaw (GTK_CLIST (clist));
394   speedDialInitialized = TRUE;
395 }
396
397
398 static void ImportSpeedDial (void)
399 {
400   static GtkWidget *fileDialog = NULL;
401
402   if (fileDialog == NULL)
403   {
404     fileDialog = gtk_file_selection_new (_("Import"));
405     gtk_signal_connect (GTK_OBJECT (fileDialog), "delete_event",
406                         GTK_SIGNAL_FUNC (DeleteEvent), NULL);
407     gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (fileDialog)->ok_button),
408                         "clicked", GTK_SIGNAL_FUNC (OkImportDialog), (gpointer) fileDialog);
409     gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (fileDialog)->cancel_button),
410                         "clicked", GTK_SIGNAL_FUNC (CancelDialog), (gpointer) fileDialog);
411   }  
412
413   gtk_widget_show (fileDialog);
414 }
415
416
417 static void ExportSpeedDialMain (gchar *name)
418 {
419   FILE *f;
420   D_SpeedDial *d;
421   gchar buf[IO_BUF_LEN];
422   register gint i;
423
424   if ((f = fopen( name, "w")) == NULL)
425   {
426     g_snprintf (buf, IO_BUF_LEN, _("Can't open file %s for writing!"), name);
427     gtk_label_set_text (GTK_LABEL (errorDialog.text), buf);
428     gtk_widget_show (errorDialog.dialog);
429     return;
430   }
431
432   for(i = 1; i < 10; i++)
433   {
434     if ((d = (D_SpeedDial *) gtk_clist_get_row_data (GTK_CLIST (clist), i - 1)))
435     {
436       sprintf (buf, "%d;%d;%d;", d->entry.Number, d->entry.MemoryType, d->entry.Location);
437       fprintf (f, "%s\n", buf);
438     }
439   }
440
441   fclose(f);
442 }
443
444
445 static void YesExportDialog (GtkWidget *w, gpointer data)
446 {
447   gtk_widget_hide (GTK_WIDGET (data));
448   ExportSpeedDialMain (exportDialogData.fileName);
449 }
450
451
452 static void OkExportDialog (GtkWidget *w, GtkFileSelection *fs)
453 {
454   static YesNoDialog dialog = { NULL, NULL};
455   FILE *f;
456   gchar err[80];
457
458
459   exportDialogData.fileName = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
460   gtk_widget_hide (GTK_WIDGET (fs));
461
462   if ((f = fopen (exportDialogData.fileName, "r")) != NULL)
463   {
464     fclose (f);
465     if (dialog.dialog == NULL)
466     {
467       CreateYesNoDialog (&dialog, YesExportDialog, CancelDialog, GUI_SpeedDialWindow);
468       gtk_window_set_title (GTK_WINDOW (dialog.dialog), _("Overwrite file?"));
469       g_snprintf ( err, 80, _("File %s already exist.\nOverwrite?"), exportDialogData.fileName); 
470       gtk_label_set_text (GTK_LABEL(dialog.text), err);
471     }
472     gtk_widget_show (dialog.dialog);
473   }
474   else
475     ExportSpeedDialMain (exportDialogData.fileName);
476 }    
477
478
479 static void ExportSpeedDial (void)
480 {
481   static GtkWidget *fileDialog = NULL;
482
483   if (speedDialInitialized)
484   {
485     if (fileDialog == NULL)
486     {
487       fileDialog = gtk_file_selection_new (_("Export"));
488       gtk_signal_connect (GTK_OBJECT (fileDialog), "delete_event",
489                           GTK_SIGNAL_FUNC (DeleteEvent), NULL);
490       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (fileDialog)->ok_button),
491                           "clicked", GTK_SIGNAL_FUNC (OkExportDialog), (gpointer) fileDialog);
492       gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (fileDialog)->cancel_button),
493                           "clicked", GTK_SIGNAL_FUNC (CancelDialog), (gpointer) fileDialog);
494     }
495
496     gtk_widget_show (fileDialog);
497   }
498 }
499
500
501 inline void GUI_ShowSpeedDial (void)
502 {
503   ReadSpeedDial ();
504   gtk_widget_show (GUI_SpeedDialWindow);
505 }
506
507
508 static GtkItemFactoryEntry menu_items[] = {
509   { NULL,               NULL,           NULL, 0, "<Branch>"},
510   { NULL,               "<control>R",   ReadSpeedDial, 0, NULL},
511   { NULL,               "<control>S",   SaveSpeedDial, 0, NULL},
512   { NULL,               NULL,           NULL, 0, "<Separator>"},
513   { NULL, "<control>I", ImportSpeedDial, 0, NULL},
514   { NULL, "<control>E", ExportSpeedDial, 0, NULL},
515   { NULL,               NULL,           NULL, 0, "<Separator>"},
516   { NULL,               "<control>W",   CloseSpeedDial, 0, NULL},
517   { NULL,               NULL,           NULL, 0, "<Branch>"},
518   { NULL,               NULL,           EditKey, 0, NULL},
519   { NULL,               NULL,           NULL, 0, "<LastBranch>"},
520   { NULL,               NULL,           Help1, 0, NULL},
521   { NULL,               NULL,           GUI_ShowAbout, 0, NULL},
522 };
523
524
525 static void InitMainMenu (void)
526 {
527   menu_items[0].path = g_strdup (_("/_File"));
528   menu_items[1].path = g_strdup (_("/File/_Read from phone"));
529   menu_items[2].path = g_strdup (_("/File/_Save to phone"));
530   menu_items[3].path = g_strdup (_("/File/Sep1"));
531   menu_items[4].path = g_strdup (_("/File/_Import from file"));
532   menu_items[5].path = g_strdup (_("/File/_Export to file"));
533   menu_items[6].path = g_strdup (_("/File/Sep2"));
534   menu_items[7].path = g_strdup (_("/File/_Close"));
535   menu_items[8].path = g_strdup (_("/_Edit"));
536   menu_items[9].path = g_strdup (_("/Edit/_Edit"));
537   menu_items[10].path = g_strdup (_("/_Help"));
538   menu_items[11].path = g_strdup (_("/Help/_Help"));
539   menu_items[12].path = g_strdup (_("/Help/_About"));
540 }
541
542
543 void GUI_CreateSpeedDialWindow (void)
544 {
545   int nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
546   GtkItemFactory *item_factory;
547   GtkAccelGroup *accel_group;
548   SortColumn *sColumn;
549   GtkWidget *menubar;
550   GtkWidget *main_vbox;
551   GtkWidget *toolbar;
552   GtkWidget *clistScrolledWindow;
553   register gint i;
554   gchar *titles[3] = {_("Key"), _("Name"), _("Number")};
555
556
557   InitMainMenu ();
558   GUI_SpeedDialWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
559   gtk_window_set_wmclass (GTK_WINDOW (GUI_SpeedDialWindow), "SpeedDialWindow", "Xgnokii");
560   gtk_window_set_title (GTK_WINDOW (GUI_SpeedDialWindow), _("Speed Dial"));
561   gtk_widget_set_usize (GTK_WIDGET (GUI_SpeedDialWindow), 332, 220);
562   //gtk_container_set_border_width (GTK_CONTAINER (GUI_SpeedDialWindow), 10);
563   gtk_signal_connect (GTK_OBJECT (GUI_SpeedDialWindow), "delete_event",
564                       GTK_SIGNAL_FUNC (DeleteEvent), NULL);
565   gtk_widget_realize (GUI_SpeedDialWindow);
566
567   accel_group = gtk_accel_group_new ();
568   item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>", 
569                                        accel_group);
570
571   gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
572
573   gtk_accel_group_attach (accel_group, GTK_OBJECT (GUI_SpeedDialWindow));
574
575   /* Finally, return the actual menu bar created by the item factory. */ 
576   menubar = gtk_item_factory_get_widget (item_factory, "<main>");
577
578   main_vbox = gtk_vbox_new (FALSE, 1);
579   gtk_container_border_width (GTK_CONTAINER (main_vbox), 1);
580   gtk_container_add (GTK_CONTAINER (GUI_SpeedDialWindow), main_vbox);
581   gtk_widget_show (main_vbox);
582
583   gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, FALSE, 0);
584   gtk_widget_show (menubar);
585
586   /* Create the toolbar */
587
588   toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS);
589   gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NORMAL);
590
591   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Read from phone"), NULL,
592                            NewPixmap(Read_xpm, GUI_SpeedDialWindow->window,
593                            &GUI_SpeedDialWindow->style->bg[GTK_STATE_NORMAL]),
594                            (GtkSignalFunc) ReadSpeedDial, NULL);
595   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Save to phone"), NULL,
596                            NewPixmap(Send_xpm, GUI_SpeedDialWindow->window,
597                            &GUI_SpeedDialWindow->style->bg[GTK_STATE_NORMAL]),
598                            (GtkSignalFunc) SaveSpeedDial, NULL);
599
600   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
601
602   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Import from file"), NULL,
603                            NewPixmap(Open_xpm, GUI_SpeedDialWindow->window,
604                            &GUI_SpeedDialWindow->style->bg[GTK_STATE_NORMAL]),
605                            (GtkSignalFunc) ImportSpeedDial, NULL);
606   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Export to file"), NULL,
607                            NewPixmap(Save_xpm, GUI_SpeedDialWindow->window,
608                            &GUI_SpeedDialWindow->style->bg[GTK_STATE_NORMAL]),
609                            (GtkSignalFunc) ExportSpeedDial, NULL);
610
611   gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
612
613   gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Edit entry"), NULL,
614                            NewPixmap(Edit_xpm, GUI_SpeedDialWindow->window,
615                            &GUI_SpeedDialWindow->style->bg[GTK_STATE_NORMAL]),
616                            (GtkSignalFunc) EditKey, NULL);
617
618   gtk_box_pack_start (GTK_BOX (main_vbox), toolbar, FALSE, FALSE, 0);
619   gtk_widget_show (toolbar);
620
621   clist = gtk_clist_new_with_titles (3, titles);
622   gtk_clist_set_shadow_type (GTK_CLIST (clist), GTK_SHADOW_OUT);
623 //  gtk_clist_set_compare_func (GTK_CLIST (clist), CListCompareFunc);
624   gtk_clist_set_sort_column (GTK_CLIST (clist), 0);
625   gtk_clist_set_sort_type (GTK_CLIST (clist), GTK_SORT_ASCENDING);
626   gtk_clist_set_auto_sort (GTK_CLIST (clist), FALSE);
627   //gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_EXTENDED);
628
629   gtk_clist_set_column_width (GTK_CLIST (clist), 1, 150);
630   gtk_clist_set_column_width (GTK_CLIST (clist), 2, 115);
631   gtk_clist_set_column_justification (GTK_CLIST (clist), 0, GTK_JUSTIFY_CENTER);
632 //  gtk_clist_set_column_visibility (GTK_CLIST (clist), 3, xgnokiiConfig.callerGroupsSupported);
633
634   for (i = 0; i < 3; i++)
635   {
636     if ((sColumn = g_malloc (sizeof (SortColumn))) == NULL)
637     {
638       g_print (_("Error: %s: line %d: Can't allocate memory!\n"), __FILE__, __LINE__);
639       gtk_main_quit ();
640     }
641     sColumn->clist = clist;
642     sColumn->column = i;
643     gtk_signal_connect (GTK_OBJECT (GTK_CLIST (clist)->column[i].button), "clicked",
644                         GTK_SIGNAL_FUNC (SetSortColumn), (gpointer) sColumn);
645   }
646
647   gtk_signal_connect (GTK_OBJECT (clist), "select_row",
648                       GTK_SIGNAL_FUNC (ClickEntry), NULL);
649
650   clistScrolledWindow = gtk_scrolled_window_new (NULL, NULL);
651   gtk_container_add (GTK_CONTAINER (clistScrolledWindow), clist);
652   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clistScrolledWindow),
653                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
654   gtk_box_pack_start (GTK_BOX (main_vbox), clistScrolledWindow, 
655                       TRUE, TRUE, 0);
656
657   gtk_widget_show (clist);
658   gtk_widget_show (clistScrolledWindow);
659
660   questMark.pixmap = gdk_pixmap_create_from_xpm_d (GUI_SpeedDialWindow->window,
661                          &questMark.mask,
662                          &GUI_SpeedDialWindow->style->bg[GTK_STATE_NORMAL],
663                          quest_xpm);
664
665   CreateErrorDialog (&errorDialog, GUI_SpeedDialWindow);
666   CreateInfoDialog (&infoDialog, GUI_SpeedDialWindow);
667   speedDialInitialized = FALSE;
668 }