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>.
9 Released under the terms of the GNU GPL, see file COPYING for more details.
11 Last modification: Sun Apr 30 2000
12 Modified by Jan Derfinak
21 #include "xgnokii_contacts.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"
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;
44 static inline void Help1 (GtkWidget *w, gpointer data)
46 gchar *indx = g_strdup_printf ("/help/%s/windows/speeddial/index.html", xgnokiiConfig.locale);
52 static void CloseSpeedDial (GtkWidget *w, gpointer data)
54 gtk_widget_hide (GUI_SpeedDialWindow);
58 static inline void DestroyCListData (gpointer data)
61 g_free ((D_SpeedDial *) data);
65 static void DeleteSelectContactDialog (GtkWidget *widget, GdkEvent *event,
66 SelectContactData *data)
68 gtk_widget_destroy (GTK_WIDGET (data->clist));
69 gtk_widget_destroy (GTK_WIDGET (data->clistScrolledWindow));
70 gtk_widget_destroy (GTK_WIDGET (widget));
74 static void CancelSelectContactDialog (GtkWidget *widget,
75 SelectContactData *data)
77 gtk_widget_destroy (GTK_WIDGET (data->clist));
78 gtk_widget_destroy (GTK_WIDGET (data->clistScrolledWindow));
79 gtk_widget_destroy (GTK_WIDGET (data->dialog));
83 static void OkSelectContactDialog (GtkWidget *widget,
84 SelectContactData *data)
87 PhonebookEntry *pbEntry;
90 if ((sel = GTK_CLIST (data->clist)->selection) != NULL)
92 D_SpeedDial *d = (D_SpeedDial *) g_malloc (sizeof (D_SpeedDial));
94 gtk_clist_freeze (GTK_CLIST (clist));
96 pbEntry = gtk_clist_get_row_data (GTK_CLIST (data->clist),
97 GPOINTER_TO_INT (sel->data));
99 gtk_clist_get_text (GTK_CLIST (clist), selectedKey, 0, &key);
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);
104 d->entry.Number = *key - '0';
105 d->entry.MemoryType = pbEntry->entry.MemoryType + 2;
106 d->entry.Location = pbEntry->entry.Location;
108 gtk_clist_set_row_data_full (GTK_CLIST (clist), selectedKey,
109 (gpointer) d, DestroyCListData);
111 gtk_clist_sort (GTK_CLIST (clist));
112 gtk_clist_thaw (GTK_CLIST (clist));
115 gtk_widget_destroy (GTK_WIDGET (data->clist));
116 gtk_widget_destroy (GTK_WIDGET (data->clistScrolledWindow));
117 gtk_widget_destroy (GTK_WIDGET (data->dialog));
120 static void ShowSelectContactsDialog (void)
122 SelectContactData *r;
124 if (!GUI_ContactsIsIntialized ())
127 if ((r = GUI_SelectContactDialog ()) == NULL)
130 gtk_signal_connect (GTK_OBJECT (r->dialog), "delete_event",
131 GTK_SIGNAL_FUNC (DeleteSelectContactDialog), (gpointer) r);
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);
140 static inline void EditKey (void)
144 if ((sel = GTK_CLIST (clist)->selection) != NULL)
146 selectedKey = GPOINTER_TO_INT (sel->data);
147 ShowSelectContactsDialog ();
152 static inline void ClickEntry (GtkWidget *clist,
155 GdkEventButton *event,
158 if(event && event->type == GDK_2BUTTON_PRESS)
161 ShowSelectContactsDialog ();
166 static void ReadSpeedDial (void)
168 PhonebookEntry *pbEntry;
174 register gint i, row_i = 0;
177 if (!GUI_ContactsIsIntialized ())
180 gtk_label_set_text (GTK_LABEL (infoDialog.text), _("Reading data ..."));
181 gtk_widget_show_now (infoDialog.dialog);
184 gtk_clist_freeze (GTK_CLIST (clist));
185 gtk_clist_clear (GTK_CLIST (clist));
187 for (i = 1; i < 10; i++)
189 if ((d = (D_SpeedDial *) g_malloc (sizeof (D_SpeedDial))) == NULL)
191 g_print (_("Cannot allocate memory!"));
195 if ((e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent))) == NULL)
197 g_print (_("Cannot allocate memory!"));
201 e->event = Event_GetSpeedDial;
204 pthread_mutex_lock (&speedDialMutex);
205 pthread_cond_wait (&speedDialCond, &speedDialMutex);
206 pthread_mutex_unlock (&speedDialMutex);
208 if (d->status != GE_NONE)
209 g_print ("Cannot read speed dial key %d!\n", i);
212 if (d->entry.Location == 0)
215 location = d->entry.Location;
216 if ((pbEntry = GUI_GetEntry (d->entry.MemoryType - 2, location)) == NULL)
223 row[1] = pbEntry->entry.Name;
224 row[2] = pbEntry->entry.Number;
226 gtk_clist_append (GTK_CLIST (clist), row);
227 gtk_clist_set_row_data_full (GTK_CLIST (clist), row_i++,
228 (gpointer) d, DestroyCListData);
231 gtk_widget_hide (infoDialog.dialog);
234 gtk_clist_sort (GTK_CLIST (clist));
235 gtk_clist_thaw (GTK_CLIST (clist));
236 speedDialInitialized = TRUE;
240 static void SaveSpeedDial (void)
247 if (speedDialInitialized)
248 for(i = 1; i < 10; i++)
250 if ((d = (D_SpeedDial *) gtk_clist_get_row_data (GTK_CLIST (clist), i - 1)))
252 if (d->entry.Location == 0)
254 if ((e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent))) == NULL)
256 g_print (_("Cannot allocate memory!"));
259 e->event = Event_SendSpeedDial;
262 /* pthread_mutex_lock (&speedDialMutex);
263 pthread_cond_wait (&speedDialCond, &speedDialMutex);
264 pthread_mutex_unlock (&speedDialMutex);
266 if (d->status != GE_NONE)
268 g_snprintf (buf, 80, _("Error writing speed\ndial for key %d!\n"),
270 gtk_label_set_text (GTK_LABEL (errorDialog.text), buf);
271 gtk_widget_show (errorDialog.dialog);
279 static bool ParseLine (D_SpeedDial *d, gchar *buf)
281 gchar **strings = g_strsplit (buf, ";", 3);
283 d->entry.Number = *strings[0] - '0';
284 if (d->entry.Number < 1 || d->entry.Number > 9)
286 g_strfreev (strings);
290 d->entry.MemoryType = *strings[1] - '0';
291 if (d->entry.MemoryType < 2 || d->entry.MemoryType > 3)
293 g_strfreev (strings);
297 d->entry.Location = atoi (strings[2]);
298 if (d->entry.Location == LONG_MIN || d->entry.Location == LONG_MAX ||
299 d->entry.Location < 0)
301 g_strfreev (strings);
305 g_strfreev (strings);
310 static void OkImportDialog (GtkWidget *w, GtkFileSelection *fs)
314 PhonebookEntry *pbEntry;
315 gchar buf[IO_BUF_LEN];
319 register gint i, row_i = 0;
321 fileName = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
322 gtk_widget_hide (GTK_WIDGET (fs));
324 if ((f = fopen (fileName, "r")) == NULL)
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);
332 if (!GUI_ContactsIsIntialized ())
335 gtk_clist_freeze (GTK_CLIST (clist));
336 gtk_clist_clear (GTK_CLIST (clist));
337 speedDialInitialized = FALSE;
340 while (fgets (buf, IO_BUF_LEN, f) && i++ < 9)
342 if ((d = (D_SpeedDial *) g_malloc (sizeof (D_SpeedDial))) == NULL)
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));
350 if (ParseLine (d, buf))
352 if (d->entry.Number != i)
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));
362 if (d->entry.Location == 0)
365 location = d->entry.Location;
366 if ((pbEntry = GUI_GetEntry (d->entry.MemoryType - 2, location)) == NULL)
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);
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));
392 gtk_clist_sort (GTK_CLIST (clist));
393 gtk_clist_thaw (GTK_CLIST (clist));
394 speedDialInitialized = TRUE;
398 static void ImportSpeedDial (void)
400 static GtkWidget *fileDialog = NULL;
402 if (fileDialog == NULL)
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);
413 gtk_widget_show (fileDialog);
417 static void ExportSpeedDialMain (gchar *name)
421 gchar buf[IO_BUF_LEN];
424 if ((f = fopen( name, "w")) == NULL)
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);
432 for(i = 1; i < 10; i++)
434 if ((d = (D_SpeedDial *) gtk_clist_get_row_data (GTK_CLIST (clist), i - 1)))
436 sprintf (buf, "%d;%d;%d;", d->entry.Number, d->entry.MemoryType, d->entry.Location);
437 fprintf (f, "%s\n", buf);
445 static void YesExportDialog (GtkWidget *w, gpointer data)
447 gtk_widget_hide (GTK_WIDGET (data));
448 ExportSpeedDialMain (exportDialogData.fileName);
452 static void OkExportDialog (GtkWidget *w, GtkFileSelection *fs)
454 static YesNoDialog dialog = { NULL, NULL};
459 exportDialogData.fileName = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs));
460 gtk_widget_hide (GTK_WIDGET (fs));
462 if ((f = fopen (exportDialogData.fileName, "r")) != NULL)
465 if (dialog.dialog == NULL)
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);
472 gtk_widget_show (dialog.dialog);
475 ExportSpeedDialMain (exportDialogData.fileName);
479 static void ExportSpeedDial (void)
481 static GtkWidget *fileDialog = NULL;
483 if (speedDialInitialized)
485 if (fileDialog == NULL)
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);
496 gtk_widget_show (fileDialog);
501 inline void GUI_ShowSpeedDial (void)
504 gtk_widget_show (GUI_SpeedDialWindow);
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},
525 static void InitMainMenu (void)
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"));
543 void GUI_CreateSpeedDialWindow (void)
545 int nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]);
546 GtkItemFactory *item_factory;
547 GtkAccelGroup *accel_group;
550 GtkWidget *main_vbox;
552 GtkWidget *clistScrolledWindow;
554 gchar *titles[3] = {_("Key"), _("Name"), _("Number")};
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);
567 accel_group = gtk_accel_group_new ();
568 item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "<main>",
571 gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL);
573 gtk_accel_group_attach (accel_group, GTK_OBJECT (GUI_SpeedDialWindow));
575 /* Finally, return the actual menu bar created by the item factory. */
576 menubar = gtk_item_factory_get_widget (item_factory, "<main>");
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);
583 gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, FALSE, 0);
584 gtk_widget_show (menubar);
586 /* Create the toolbar */
588 toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS);
589 gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NORMAL);
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);
600 gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
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);
611 gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));
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);
618 gtk_box_pack_start (GTK_BOX (main_vbox), toolbar, FALSE, FALSE, 0);
619 gtk_widget_show (toolbar);
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);
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);
634 for (i = 0; i < 3; i++)
636 if ((sColumn = g_malloc (sizeof (SortColumn))) == NULL)
638 g_print (_("Error: %s: line %d: Can't allocate memory!\n"), __FILE__, __LINE__);
641 sColumn->clist = clist;
643 gtk_signal_connect (GTK_OBJECT (GTK_CLIST (clist)->column[i].button), "clicked",
644 GTK_SIGNAL_FUNC (SetSortColumn), (gpointer) sColumn);
647 gtk_signal_connect (GTK_OBJECT (clist), "select_row",
648 GTK_SIGNAL_FUNC (ClickEntry), NULL);
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,
657 gtk_widget_show (clist);
658 gtk_widget_show (clistScrolledWindow);
660 questMark.pixmap = gdk_pixmap_create_from_xpm_d (GUI_SpeedDialWindow->window,
662 &GUI_SpeedDialWindow->style->bg[GTK_STATE_NORMAL],
665 CreateErrorDialog (&errorDialog, GUI_SpeedDialWindow);
666 CreateInfoDialog (&infoDialog, GUI_SpeedDialWindow);
667 speedDialInitialized = FALSE;