X-Git-Url: http://git.jankratochvil.net/?p=gnokii.git;a=blobdiff_plain;f=xgnokii%2Fxgnokii_contacts.c;fp=xgnokii%2Fxgnokii_contacts.c;h=d7c5f78f65a66cf07bbdcadb9c97312f7b47fc69;hp=0000000000000000000000000000000000000000;hb=833e1c7c90e13ceaba3dde8e7a36fcc8dfb1db3c;hpb=2e0972b02d101bb0d8e9d3e15d2ac80def491a63 diff --git a/xgnokii/xgnokii_contacts.c b/xgnokii/xgnokii_contacts.c new file mode 100644 index 0000000..d7c5f78 --- /dev/null +++ b/xgnokii/xgnokii_contacts.c @@ -0,0 +1,3433 @@ +/* + + X G N O K I I + + A Linux/Unix GUI for Nokia mobile phones. + + Released under the terms of the GNU GPL, see file COPYING for more details. + + $Id$ + +*/ + + +#include "misc.h" + +#include +#include + +#ifndef WIN32 +# include +#else +# include +# define sleep(x) Sleep((x) * 1000) +# define usleep(x) Sleep(((x) < 1000) ? 1 : ((x) / 1000)) +# define index strchr +#endif + +#include +#include +#if __unices__ +# include +#endif +#include + +#include "gsm-api.h" +#include "gsm-common.h" +#include "xgnokii_contacts.h" +#include "xgnokii_lowlevel.h" +#include "xgnokii.h" +#include "xgnokii_common.h" +#include "xgnokii_lowlevel.h" +#include "xgnokii_sms.h" +#include "xpm/Read.xpm" +#include "xpm/Send.xpm" +#include "xpm/Open.xpm" +#include "xpm/Save.xpm" +#include "xpm/New.xpm" +#include "xpm/Duplicate.xpm" +#include "xpm/Edit.xpm" +#include "xpm/Delete.xpm" +#include "xpm/Dial.xpm" +#include "xpm/sim.xpm" +#include "xpm/phone.xpm" +#include "xpm/quest.xpm" + + +typedef struct { + GtkWidget *dialog; + GtkWidget *entry; +} DialVoiceDialog; + +typedef struct { + GtkWidget *dialog; + GtkWidget *entry; + gint row; + GtkWidget *gbutton; + GtkWidget *mbutton; + GtkWidget *wbutton; + GtkWidget *fbutton; + GtkWidget *hbutton; + PhonebookEntry *pbEntry; +} ExtPbkDialog; + +static GtkWidget *GUI_ContactsWindow; +static bool fbus3810; +static bool contactsMemoryInitialized; +static MemoryStatus memoryStatus; +static ContactsMemory contactsMemory; /* Hold contacts. */ +static GtkWidget *clist; +static StatusInfo statusInfo; +static ProgressDialog progressDialog = {NULL, NULL, NULL}; +static ErrorDialog errorDialog = {NULL, NULL}; +static FindEntryStruct findEntryStruct = { "", 0}; +static ExportDialogData exportDialogData = {NULL}; +static MemoryPixmaps memoryPixmaps; +static QuestMark questMark; +static EditEntryData newEditEntryData = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; +static EditEntryData editEditEntryData = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; +static EditEntryData duplicateEditEntryData = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; +static EditNumbersData editNumbersData = {NULL, NULL}; + +/* return != 0 if user has unsaved changes in contacts memory */ +inline gint GUI_ContactsIsChanged (void) +{ + return statusInfo.ch_ME | statusInfo.ch_SM; +} + + +/* return TRUE if Contacts memory was read from phone or from file */ +inline bool GUI_ContactsIsIntialized (void) +{ + return contactsMemoryInitialized; +} + + +static inline void Help1 (GtkWidget *w, gpointer data) +{ + gchar *indx = g_strdup_printf ("/help/%s/windows/contacts/index.html", xgnokiiConfig.locale); + Help (w, indx); + g_free (indx); +} + + +void RefreshStatusInfo (void) +{ + char p,s; + + if (statusInfo.ch_ME) + p = '*'; + else + p = ' '; + + if (statusInfo.ch_SM) + s = '*'; + else + s = ' '; + g_snprintf(statusInfo.text, STATUS_INFO_LENGTH, "SIM: %d/%d%c Phone: %d/%d%c", + memoryStatus.UsedSM, memoryStatus.MaxSM, s, + memoryStatus.UsedME, memoryStatus.MaxME, p); + gtk_label_set_text(GTK_LABEL (statusInfo.label), statusInfo.text); +} + + +static inline void SetGroup0 (GtkWidget *item, gpointer data) +{ + ((EditEntryData *) data)->newGroup = 0; +} + + +static inline void SetGroup1 (GtkWidget *item, gpointer data) +{ + ((EditEntryData *) data)->newGroup = 1; +} + + +static inline void SetGroup2 (GtkWidget *item, gpointer data) +{ + ((EditEntryData *) data)->newGroup = 2; +} + + +static inline void SetGroup3 (GtkWidget *item, gpointer data) +{ + ((EditEntryData *) data)->newGroup = 3; +} + + +static inline void SetGroup4 (GtkWidget *item, gpointer data) +{ + ((EditEntryData *) data)->newGroup = 4; +} + + +static inline void SetGroup5 (GtkWidget *item, gpointer data) +{ + ((EditEntryData *) data)->newGroup = 5; +} + + +PhonebookEntry *FindFreeEntry (GSM_MemoryType type) +{ + PhonebookEntry *entry; + gint start, end; + register gint i; + + if (type == GMT_ME) + { + if (memoryStatus.FreeME == 0) + return NULL; + start = 0; + end = memoryStatus.MaxME; + } + else + { + if (memoryStatus.FreeSM == 0) + return NULL; + start = memoryStatus.MaxME; + end = memoryStatus.MaxME + memoryStatus.MaxSM; + } + + for(i = start; i < end; i++) + { + entry = g_ptr_array_index(contactsMemory, i); + if (entry->status == E_Empty || entry->status == E_Deleted) + return entry; + } + + return NULL; +} + + +inline PhonebookEntry *GUI_GetEntry (GSM_MemoryType type, gint nr) +{ + if ((type == GMT_ME && (nr < 1 || nr >= memoryStatus.MaxME)) || + (type == GMT_SM && (nr < 1 || nr >= memoryStatus.MaxSM))) + return NULL; + + if (type == GMT_ME) + return g_ptr_array_index (contactsMemory, nr - 1); + else + return g_ptr_array_index (contactsMemory, nr + memoryStatus.MaxME - 1); +} + + +static void CloseContacts (GtkWidget *w, gpointer data) +{ + gtk_widget_hide (GUI_ContactsWindow); +} + + +/* I don't want to allow window to close */ +static void ProgressDialogDeleteEvent (GtkWidget *w, gpointer data) +{ + return; +} + + +static void CancelEditDialog (GtkWidget *widget, gpointer data ) +{ + gtk_widget_hide(GTK_WIDGET(((EditEntryData*) data)->dialog)); +} + + + +static void OkEditEntryDialog (GtkWidget *widget, gpointer data) +{ + gchar *clist_row[4]; + PhonebookEntry *entry; + + if (GTK_TOGGLE_BUTTON(((EditEntryData*) data)->memoryTypePhone)->active && + ((EditEntryData*) data)->pbEntry->entry.MemoryType == GMT_SM) + { + if ((entry = FindFreeEntry(GMT_ME)) == NULL) + { + gtk_label_set_text(GTK_LABEL(errorDialog.text), _("Can't change memory type!")); + gtk_widget_show (errorDialog.dialog); + return; + } + strncpy(entry->entry.Name, + gtk_entry_get_text(GTK_ENTRY (((EditEntryData*) data)->name)), + max_phonebook_name_length); + entry->entry.Name[max_phonebook_name_length] = '\0'; + + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + { + } + else + { + strncpy(entry->entry.Number, + gtk_entry_get_text (GTK_ENTRY(((EditEntryData*) data)->number)), + max_phonebook_number_length); + entry->entry.Name[max_phonebook_number_length] = '\0'; + } + + entry->entry.Group = ((EditEntryData*) data)->newGroup; + + entry->status = E_Changed; + + ((EditEntryData*) data)->pbEntry->status = E_Deleted; + + memoryStatus.UsedME++; + memoryStatus.FreeME--; + memoryStatus.UsedSM--; + memoryStatus.FreeSM++; + statusInfo.ch_ME = statusInfo.ch_SM = 1; + + ((EditEntryData*) data)->pbEntry = entry; + } + else if (GTK_TOGGLE_BUTTON(((EditEntryData*) data)->memoryTypeSIM)->active && + ((EditEntryData*) data)->pbEntry->entry.MemoryType == GMT_ME) + { + if ((entry = FindFreeEntry(GMT_SM)) == NULL) + { + gtk_label_set_text(GTK_LABEL (errorDialog.text), _("Can't change memory type!")); + gtk_widget_show (errorDialog.dialog); + return; + } + strncpy(entry->entry.Name, + gtk_entry_get_text(GTK_ENTRY (((EditEntryData*) data)->name)), + max_phonebook_sim_name_length); + entry->entry.Name[max_phonebook_sim_name_length] = '\0'; + + if (strlen(gtk_entry_get_text(GTK_ENTRY (((EditEntryData*) data)->name))) > max_phonebook_sim_name_length) + { + gtk_label_set_text( GTK_LABEL (errorDialog.text), _("Sorry, phonebook name will be truncated,\n\ +because you save it into SIM memory!")); + gtk_widget_show (errorDialog.dialog); + } + + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + { + } + else + { + strncpy(entry->entry.Number, + gtk_entry_get_text (GTK_ENTRY(((EditEntryData*) data)->number)), + max_phonebook_sim_number_length); + entry->entry.Name[max_phonebook_sim_number_length] = '\0'; + } + + entry->entry.Group = ((EditEntryData*) data)->newGroup; + + entry->status = E_Changed; + + ((EditEntryData*) data)->pbEntry->status = E_Deleted; + + memoryStatus.UsedME--; + memoryStatus.FreeME++; + memoryStatus.UsedSM++; + memoryStatus.FreeSM--; + statusInfo.ch_ME = statusInfo.ch_SM = 1; + + ((EditEntryData*) data)->pbEntry = entry; + } + else + { + if (GTK_TOGGLE_BUTTON(((EditEntryData*) data)->memoryTypePhone)->active) + { + strncpy(((EditEntryData*) data)->pbEntry->entry.Name, + gtk_entry_get_text(GTK_ENTRY (((EditEntryData*) data)->name)), + max_phonebook_name_length); + ((EditEntryData*) data)->pbEntry->entry.Name[max_phonebook_name_length] = '\0'; + + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + { + } + else + { + strncpy(((EditEntryData*) data)->pbEntry->entry.Number, + gtk_entry_get_text (GTK_ENTRY(((EditEntryData*) data)->number)), + max_phonebook_number_length); + ((EditEntryData*) data)->pbEntry->entry.Name[max_phonebook_number_length] = '\0'; + } + } + else + { + strncpy(((EditEntryData*) data)->pbEntry->entry.Name, + gtk_entry_get_text(GTK_ENTRY (((EditEntryData*) data)->name)), + max_phonebook_sim_name_length); + ((EditEntryData*) data)->pbEntry->entry.Name[max_phonebook_sim_name_length] = '\0'; + + if (strlen(gtk_entry_get_text(GTK_ENTRY (((EditEntryData*) data)->name))) > max_phonebook_sim_name_length) + { + gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Sorry, phonebook name will be truncated,\n\ +because you save it into SIM memory!")); + gtk_widget_show (errorDialog.dialog); + } + + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + { + } + else + { + strncpy(((EditEntryData*) data)->pbEntry->entry.Number, + gtk_entry_get_text (GTK_ENTRY(((EditEntryData*) data)->number)), + max_phonebook_sim_number_length); + ((EditEntryData*) data)->pbEntry->entry.Name[max_phonebook_sim_number_length] = '\0'; + } + } + + ((EditEntryData*) data)->pbEntry->entry.Group = ((EditEntryData*) data)->newGroup; + + ((EditEntryData*) data)->pbEntry->status = E_Changed; + + if (((EditEntryData*) data)->pbEntry->entry.MemoryType == GMT_ME) + statusInfo.ch_ME = 1; + else + statusInfo.ch_SM = 1; + } + + gtk_widget_hide (GTK_WIDGET(((EditEntryData*) data)->dialog)); + + RefreshStatusInfo (); + + gtk_clist_freeze (GTK_CLIST (clist)); + gtk_clist_remove (GTK_CLIST (clist), ((EditEntryData*) data)->row); + + clist_row[0] = ((EditEntryData*) data)->pbEntry->entry.Name; + + clist_row[1] = ((EditEntryData*) data)->pbEntry->entry.Number; + + if( ((EditEntryData*) data)->pbEntry->entry.MemoryType == GMT_ME) + clist_row[2] = "P"; + else + clist_row[2] = "S"; + if (GetModelFeature(FN_CALLERGROUPS)!=0) + clist_row[3] = xgnokiiConfig.callerGroups[((EditEntryData*) data)->pbEntry->entry.Group]; + else + clist_row[3] = ""; + gtk_clist_insert(GTK_CLIST (clist), ((EditEntryData*) data)->row, clist_row); + if (((EditEntryData*) data)->pbEntry->entry.MemoryType == GMT_ME) + gtk_clist_set_pixmap( GTK_CLIST (clist), ((EditEntryData*) data)->row, 2, + memoryPixmaps.phoneMemPix, memoryPixmaps.mask); + else + gtk_clist_set_pixmap( GTK_CLIST (clist), ((EditEntryData*) data)->row, 2, + memoryPixmaps.simMemPix, memoryPixmaps.mask); + + gtk_clist_set_row_data(GTK_CLIST (clist), ((EditEntryData*) data)->row, (gpointer) ((EditEntryData*) data)->pbEntry); + + gtk_clist_sort(GTK_CLIST (clist)); + gtk_clist_thaw(GTK_CLIST (clist)); +} + + +static void OkDeleteEntryDialog(GtkWidget *widget, gpointer data ) +{ + PhonebookEntry *pbEntry; + GList *sel; + gint row; + + sel = GTK_CLIST (clist)->selection; + + gtk_clist_freeze(GTK_CLIST (clist)); + + while (sel != NULL) + { + row = GPOINTER_TO_INT(sel->data); + pbEntry = (PhonebookEntry *) gtk_clist_get_row_data(GTK_CLIST (clist), row); + sel = sel->next; + + pbEntry->status = E_Deleted; + + if (pbEntry->entry.MemoryType == GMT_ME) + { + memoryStatus.UsedME--; + memoryStatus.FreeME++; + statusInfo.ch_ME = 1; + } + else + { + memoryStatus.UsedSM--; + memoryStatus.FreeSM++; + statusInfo.ch_SM = 1; + } + + gtk_clist_remove(GTK_CLIST (clist), row); + } + + RefreshStatusInfo (); + + gtk_widget_hide(GTK_WIDGET (data)); + + gtk_clist_thaw(GTK_CLIST (clist)); +} + + +static void OkNewEntryDialog(GtkWidget *widget, gpointer data ) +{ + gchar *clist_row[4]; + PhonebookEntry *entry; + + if (GTK_TOGGLE_BUTTON(((EditEntryData*) data)->memoryTypePhone)->active && + ((EditEntryData*) data)->pbEntry->entry.MemoryType == GMT_SM) + { + if ((entry = FindFreeEntry (GMT_ME)) == NULL) + { + gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Can't change memory type!")); + gtk_widget_show (errorDialog.dialog); + return; + } + strncpy(entry->entry.Name, + gtk_entry_get_text(GTK_ENTRY (((EditEntryData*) data)->name)), + max_phonebook_name_length); + entry->entry.Name[max_phonebook_name_length] = '\0'; + + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + { + } + else + { + strncpy(entry->entry.Number, + gtk_entry_get_text (GTK_ENTRY(((EditEntryData*) data)->number)), + max_phonebook_number_length); + entry->entry.Name[max_phonebook_number_length] = '\0'; + } + + entry->entry.Group = ((EditEntryData*) data)->newGroup; + + entry->status = E_Changed; + + ((EditEntryData*) data)->pbEntry = entry; + } + else if (GTK_TOGGLE_BUTTON(((EditEntryData*) data)->memoryTypeSIM)->active && + ((EditEntryData*) data)->pbEntry->entry.MemoryType == GMT_ME) + { + if ((entry = FindFreeEntry (GMT_SM)) == NULL) + { + gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Can't change memory type!")); + gtk_widget_show (errorDialog.dialog); + return; + } + strncpy(entry->entry.Name, + gtk_entry_get_text (GTK_ENTRY (((EditEntryData*) data)->name)), + max_phonebook_sim_name_length); + entry->entry.Name[max_phonebook_sim_name_length] = '\0'; + + if (strlen(gtk_entry_get_text (GTK_ENTRY (((EditEntryData*) data)->name))) > max_phonebook_sim_name_length) + { + gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Sorry, phonebook name will be truncated\n\ +because you save it into SIM memory!")); + gtk_widget_show (errorDialog.dialog); + } + + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + { + } + else + { + strncpy(entry->entry.Number, + gtk_entry_get_text (GTK_ENTRY(((EditEntryData*) data)->number)), + max_phonebook_sim_number_length); + entry->entry.Name[max_phonebook_sim_number_length] = '\0'; + } + + entry->entry.Group = ((EditEntryData*) data)->newGroup; + + entry->status = E_Changed; + + ((EditEntryData*) data)->pbEntry = entry; + } + else + { + if (GTK_TOGGLE_BUTTON(((EditEntryData*) data)->memoryTypePhone)->active) + { + strncpy(((EditEntryData*) data)->pbEntry->entry.Name, + gtk_entry_get_text(GTK_ENTRY (((EditEntryData*) data)->name)), + max_phonebook_name_length); + ((EditEntryData*) data)->pbEntry->entry.Name[max_phonebook_name_length] = '\0'; + + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + { + } + else + { + strncpy(((EditEntryData*) data)->pbEntry->entry.Number, + gtk_entry_get_text (GTK_ENTRY(((EditEntryData*) data)->number)), + max_phonebook_number_length); + ((EditEntryData*) data)->pbEntry->entry.Name[max_phonebook_number_length] = '\0'; + } + } + else + { + strncpy (((EditEntryData*) data)->pbEntry->entry.Name, + gtk_entry_get_text(GTK_ENTRY (((EditEntryData*) data)->name)), + max_phonebook_sim_name_length); + ((EditEntryData*) data)->pbEntry->entry.Name[max_phonebook_sim_name_length] = '\0'; + + if (strlen(gtk_entry_get_text (GTK_ENTRY (((EditEntryData*) data)->name))) > max_phonebook_sim_name_length) + { + gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Sorry, phonebook name will be truncated\n\ +because you save it into SIM memory!")); + gtk_widget_show (errorDialog.dialog); + } + + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + { + } + else + { + strncpy (((EditEntryData*) data)->pbEntry->entry.Number, + gtk_entry_get_text (GTK_ENTRY(((EditEntryData*) data)->number)), + max_phonebook_sim_number_length); + ((EditEntryData*) data)->pbEntry->entry.Name[max_phonebook_sim_number_length] = '\0'; + } + } + + ((EditEntryData*) data)->pbEntry->entry.Group = ((EditEntryData*) data)->newGroup; + + ((EditEntryData*) data)->pbEntry->status = E_Changed; + } + + if (((EditEntryData*) data)->pbEntry->entry.MemoryType == GMT_ME) + { + memoryStatus.UsedME++; + memoryStatus.FreeME--; + statusInfo.ch_ME = 1; + } + else + { + memoryStatus.UsedSM++; + memoryStatus.FreeSM--; + statusInfo.ch_SM = 1; + } + + gtk_widget_hide(GTK_WIDGET(((EditEntryData*) data)->dialog)); + + RefreshStatusInfo (); + + gtk_clist_freeze (GTK_CLIST (clist)); + clist_row[0] = ((EditEntryData*) data)->pbEntry->entry.Name; + + clist_row[1] = ((EditEntryData*) data)->pbEntry->entry.Number; + + if( ((EditEntryData*) data)->pbEntry->entry.MemoryType == GMT_ME) + clist_row[2] = "P"; + else + clist_row[2] = "S"; + if (GetModelFeature(FN_CALLERGROUPS)!=0) + clist_row[3] = xgnokiiConfig.callerGroups[((EditEntryData*) data)->pbEntry->entry.Group]; + else + clist_row[3] = ""; + gtk_clist_insert (GTK_CLIST (clist), 1, clist_row); + + if (((EditEntryData*) data)->pbEntry->entry.MemoryType == GMT_ME) + gtk_clist_set_pixmap (GTK_CLIST (clist), 1, 2, + memoryPixmaps.phoneMemPix, memoryPixmaps.mask); + else + gtk_clist_set_pixmap (GTK_CLIST (clist), 1, 2, + memoryPixmaps.simMemPix, memoryPixmaps.mask); + + gtk_clist_set_row_data (GTK_CLIST (clist), 1, (gpointer) ((EditEntryData*) data)->pbEntry); + + gtk_clist_sort (GTK_CLIST (clist)); + gtk_clist_thaw (GTK_CLIST (clist)); +} + + +static void OkChangeEntryDialog( GtkWidget *widget, gpointer data) +{ + gchar *clist_row[4]; + gint row; + PhonebookEntry *oldPbEntry, *newPbEntry; + GList *sel; + gchar string[100]; + + sel = GTK_CLIST (clist)->selection; + + gtk_widget_hide(GTK_WIDGET (data)); + + gtk_clist_freeze(GTK_CLIST (clist)); + + while (sel != NULL) + { + row = GPOINTER_TO_INT (sel->data); + oldPbEntry = (PhonebookEntry *) gtk_clist_get_row_data(GTK_CLIST (clist), row); + + sel = sel->next; + + if (oldPbEntry->entry.MemoryType == GMT_SM) + { + if ((newPbEntry = FindFreeEntry (GMT_ME)) == NULL) + { + gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Can't change memory type!")); + gtk_widget_show (errorDialog.dialog); + return; + } + + newPbEntry->entry = oldPbEntry->entry; + newPbEntry->entry.MemoryType = GMT_ME; + + newPbEntry->status = E_Changed; + oldPbEntry->status = E_Deleted; + + memoryStatus.UsedME++; + memoryStatus.FreeME--; + memoryStatus.UsedSM--; + memoryStatus.FreeSM++; + statusInfo.ch_ME = statusInfo.ch_SM = 1; + + } + else + { + if ((newPbEntry = FindFreeEntry(GMT_SM)) == NULL) + { + gtk_label_set_text(GTK_LABEL (errorDialog.text), _("Can't change memory type!")); + gtk_widget_show (errorDialog.dialog); + return; + } + + newPbEntry->entry = oldPbEntry->entry; + newPbEntry->entry.Name[max_phonebook_sim_name_length] = '\0'; + newPbEntry->entry.MemoryType = GMT_SM; + + newPbEntry->status = E_Changed; + oldPbEntry->status = E_Deleted; + + memoryStatus.UsedME--; + memoryStatus.FreeME++; + memoryStatus.UsedSM++; + memoryStatus.FreeSM--; + statusInfo.ch_ME = statusInfo.ch_SM = 1; + } + + gtk_clist_remove(GTK_CLIST (clist), row); + + clist_row[0] = newPbEntry->entry.Name; + + if (newPbEntry->entry.SubEntriesCount>0) { + snprintf(string,100,"%s *",newPbEntry->entry.Number); + clist_row[1]=string; + } else clist_row[1] = newPbEntry->entry.Number; + + if( newPbEntry->entry.MemoryType == GMT_ME) + clist_row[2] = "P"; + else + clist_row[2] = "S"; + if (GetModelFeature(FN_CALLERGROUPS)!=0) + clist_row[3] = xgnokiiConfig.callerGroups[newPbEntry->entry.Group]; + else + clist_row[3] = ""; + gtk_clist_insert (GTK_CLIST (clist), row, clist_row); + if (newPbEntry->entry.MemoryType == GMT_ME) + gtk_clist_set_pixmap (GTK_CLIST (clist), row, 2, + memoryPixmaps.phoneMemPix, memoryPixmaps.mask); + else + gtk_clist_set_pixmap (GTK_CLIST (clist), row, 2, + memoryPixmaps.simMemPix, memoryPixmaps.mask); + + gtk_clist_set_row_data (GTK_CLIST (clist), row, (gpointer) newPbEntry); + } + + RefreshStatusInfo (); + gtk_clist_sort (GTK_CLIST (clist)); + gtk_clist_thaw (GTK_CLIST (clist)); +} + + +static void SearchEntry (void) +{ + gchar *buf; + gchar *entry; + gint i; + + if (!contactsMemoryInitialized || *findEntryStruct.pattern == '\0') + return; + + gtk_clist_unselect_all( GTK_CLIST (clist)); + g_strup(findEntryStruct.pattern); + + gtk_clist_get_text( GTK_CLIST (clist), findEntryStruct.lastRow, + findEntryStruct.type, &entry); + i = (findEntryStruct.lastRow + 1) % (memoryStatus.MaxME + memoryStatus.MaxSM); + + while (findEntryStruct.lastRow != i) + { + buf = g_strdup (entry); + g_strup (buf); + + if (strstr( buf, findEntryStruct.pattern)) + { + g_free(buf); + findEntryStruct.lastRow = i; + gtk_clist_select_row( GTK_CLIST (clist), + (i + memoryStatus.MaxME + memoryStatus.MaxSM - 1) + % (memoryStatus.MaxME + memoryStatus.MaxSM), + findEntryStruct.type); + gtk_clist_moveto( GTK_CLIST (clist), + (i + memoryStatus.MaxME + memoryStatus.MaxSM - 1) + % (memoryStatus.MaxME + memoryStatus.MaxSM), + findEntryStruct.type, 0.5, 0.5); + return; + } + g_free(buf); + gtk_clist_get_text (GTK_CLIST (clist), i, findEntryStruct.type, &entry); + + i = (i + 1) % (memoryStatus.MaxME + memoryStatus.MaxSM); + } + + gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Can't find pattern!")); + gtk_widget_show (errorDialog.dialog); +} + + +static void OkFindEntryDialog (GtkWidget *widget, gpointer data) +{ + if (GTK_TOGGLE_BUTTON (((FindEntryData*) data)->nameB)->active) + findEntryStruct.type = FIND_NAME; + else + findEntryStruct.type = FIND_NUMBER; + + strncpy(findEntryStruct.pattern, + gtk_entry_get_text (GTK_ENTRY (((FindEntryData*) data)->pattern)), + max_phonebook_number_length); + findEntryStruct.pattern[max_phonebook_number_length] = '\0'; + + findEntryStruct.lastRow = 0; + + gtk_widget_hide( ((FindEntryData*) data)->dialog); + + SearchEntry (); +} + + +void CreateGroupMenu (EditEntryData *data) +{ + GtkWidget *item; + + if (data->groupMenu) + { + gtk_option_menu_remove_menu (GTK_OPTION_MENU (data->group)); + if (GTK_IS_WIDGET (data->groupMenu)) + gtk_widget_destroy (GTK_WIDGET (data->groupMenu)); + data->groupMenu = NULL; + } + + data->groupMenu = gtk_menu_new (); + + item = gtk_menu_item_new_with_label (xgnokiiConfig.callerGroups[0]); + gtk_signal_connect (GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (SetGroup0), + (gpointer) data); + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (data->groupMenu), item); + + item = gtk_menu_item_new_with_label (xgnokiiConfig.callerGroups[1]); + gtk_signal_connect (GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (SetGroup1), + (gpointer) data); + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (data->groupMenu), item); + + item = gtk_menu_item_new_with_label (xgnokiiConfig.callerGroups[2]); + gtk_signal_connect (GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (SetGroup2), + (gpointer) data); + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (data->groupMenu), item); + + item = gtk_menu_item_new_with_label (xgnokiiConfig.callerGroups[3]); + gtk_signal_connect (GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (SetGroup3), + (gpointer) data); + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (data->groupMenu), item); + + item = gtk_menu_item_new_with_label (xgnokiiConfig.callerGroups[4]); + gtk_signal_connect (GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (SetGroup4), + (gpointer) data); + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (data->groupMenu), item); + + item = gtk_menu_item_new_with_label (xgnokiiConfig.callerGroups[5]); + gtk_signal_connect (GTK_OBJECT (item), "activate", + GTK_SIGNAL_FUNC (SetGroup5), + (gpointer) data); + gtk_widget_show (item); + gtk_menu_append (GTK_MENU (data->groupMenu), item); + + gtk_option_menu_set_menu (GTK_OPTION_MENU (data->group), data->groupMenu); +} + + +inline void GUI_RefreshGroupMenu (void) +{ + if (newEditEntryData.group) + CreateGroupMenu (&newEditEntryData); + + if (editEditEntryData.group) + CreateGroupMenu (&editEditEntryData); + + if (duplicateEditEntryData.group) + CreateGroupMenu (&duplicateEditEntryData); +} + + +static void EditSubEntries (GtkWidget *clist, + gint row, + gint column, + GdkEventButton *event, + gpointer data ) +{ + if(event && event->type == GDK_2BUTTON_PRESS) +// EditPbEntry((PhonebookEntry *) gtk_clist_get_row_data(GTK_CLIST (clist), row), +// row); + { + gchar *buf; + + gtk_clist_get_text (GTK_CLIST (clist), row, 1, &buf); + g_print (buf); + } +} + + +static void EditNumbers (GtkWidget *widget, void *data) +{ + GtkWidget *button, *clistScrolledWindow; + gchar *row[3]; + register gint i; + + + if (editNumbersData.dialog == NULL) + { + editNumbersData.dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (editNumbersData.dialog), _("Numbers")); + gtk_window_set_modal (GTK_WINDOW (editNumbersData.dialog), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (editNumbersData.dialog), 10); + gtk_signal_connect (GTK_OBJECT (editNumbersData.dialog), "delete_event", + GTK_SIGNAL_FUNC (DeleteEvent), NULL); + + button = gtk_button_new_with_label (_("Ok")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (editNumbersData.dialog)->action_area), + button, TRUE, TRUE, 10); +// gtk_signal_connect (GTK_OBJECT (button), "clicked", +// GTK_SIGNAL_FUNC (okFunc), (gpointer) editEntryData); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_widget_grab_default (button); + gtk_widget_show (button); + + button = gtk_button_new_with_label (_("New")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (editNumbersData.dialog)->action_area), + button, TRUE, TRUE, 10); +// gtk_signal_connect (GTK_OBJECT (button), "clicked", +// GTK_SIGNAL_FUNC (okFunc), (gpointer) editEntryData); + gtk_widget_show (button); + + button = gtk_button_new_with_label (_("Cancel")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (editNumbersData.dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (CancelDialog), (gpointer) editNumbersData.dialog); + gtk_widget_show (button); + + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (editNumbersData.dialog)->vbox), 5); + + editNumbersData.clist = gtk_clist_new (3); + gtk_clist_set_shadow_type (GTK_CLIST (editNumbersData.clist), GTK_SHADOW_OUT); + + gtk_clist_set_column_width (GTK_CLIST (editNumbersData.clist), 0, 4); + gtk_clist_set_column_width (GTK_CLIST (editNumbersData.clist), 1, 115); + gtk_clist_set_column_width (GTK_CLIST (editNumbersData.clist), 2, 10); + //gtk_clist_set_column_justification (GTK_CLIST (editNumbersData.clist), 2, GTK_JUSTIFY_CENTER); + + gtk_signal_connect (GTK_OBJECT (editNumbersData.clist), "select_row", + GTK_SIGNAL_FUNC (EditSubEntries), NULL); + + clistScrolledWindow = gtk_scrolled_window_new (NULL, NULL); + gtk_container_add (GTK_CONTAINER (clistScrolledWindow), editNumbersData.clist); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clistScrolledWindow), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (editNumbersData.dialog)->vbox), + clistScrolledWindow); + + gtk_widget_show (editNumbersData.clist); + gtk_widget_show (clistScrolledWindow); + } + + gtk_clist_freeze (GTK_CLIST (editNumbersData.clist)); + gtk_clist_clear (GTK_CLIST (editNumbersData.clist)); + + for(i = 0; i < editNumbersData.pbEntry->entry.SubEntriesCount; i++) + { + if (strcmp (editNumbersData.pbEntry->entry.Number, + editNumbersData.pbEntry->entry.SubEntries[i].data.Number) == 0) + row[0] = "*"; + else + row[0] = ""; + + row[1] = editNumbersData.pbEntry->entry.SubEntries[i].data.Number; + + switch (editNumbersData.pbEntry->entry.SubEntries[i].EntryType) + { + case GSM_Number: + switch (editNumbersData.pbEntry->entry.SubEntries[i].NumberType) + { + case GSM_General: + row[2] = "General"; + break; + + case GSM_Mobile: + row[2] = "Mobile"; + break; + + case GSM_Work: + row[2] = "Work"; + break; + + case GSM_Fax: + row[2] = "Fax"; + break; + + case GSM_Home: + row[2] = "Home"; + break; + + default: + row[2] = "Unknown"; + break; + } + break; + + case GSM_Note: + row[2] = "Note"; + break; + + case GSM_Postal: + row[2] = "Postal"; + break; + + case GSM_Email: + row[2] = "E-Mail"; + break; + + case GSM_Name: + row[2] = "Name"; + break; + + default: + row[2] = "Unknown"; + break; + } + + gtk_clist_append (GTK_CLIST (editNumbersData.clist), row); +/* if (pbEntry->entry.MemoryType == GMT_ME) + gtk_clist_set_pixmap (GTK_CLIST (clist), row_i, 2, + memoryPixmaps.phoneMemPix, memoryPixmaps.mask); + else + gtk_clist_set_pixmap (GTK_CLIST (clist), row_i, 2, + memoryPixmaps.simMemPix, memoryPixmaps.mask); +*/ + } + + gtk_clist_thaw (GTK_CLIST (editNumbersData.clist)); + + gtk_widget_show (editNumbersData.dialog); +} + + +static void CreateEditDialog (EditEntryData *editEntryData, gchar *title, + GtkSignalFunc okFunc) +{ + GtkWidget *button, *label, *hbox; + + editEntryData->dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (editEntryData->dialog), title); + gtk_window_set_modal (GTK_WINDOW (editEntryData->dialog), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (editEntryData->dialog), 10); + gtk_signal_connect (GTK_OBJECT (editEntryData->dialog), "delete_event", + GTK_SIGNAL_FUNC (DeleteEvent), NULL); + + button = gtk_button_new_with_label (_("Ok")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (editEntryData->dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (okFunc), (gpointer) editEntryData); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_widget_grab_default (button); + gtk_widget_show (button); + button = gtk_button_new_with_label (_("Cancel")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (editEntryData->dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (CancelEditDialog), (gpointer) editEntryData); + gtk_widget_show (button); + + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (editEntryData->dialog)->vbox), 5); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (editEntryData->dialog)->vbox), hbox); + gtk_widget_show (hbox); + + label = gtk_label_new (_("Name:")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); + gtk_widget_show (label); + + editEntryData->name = gtk_entry_new_with_max_length (100); + + gtk_box_pack_end(GTK_BOX(hbox), editEntryData->name, FALSE, FALSE, 2); + gtk_widget_show (editEntryData->name); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (editEntryData->dialog)->vbox), hbox); + gtk_widget_show (hbox); + + label = gtk_label_new (_("Number:")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); + gtk_widget_show (label); + + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + { + button = gtk_button_new (); + editEntryData->number = gtk_label_new (""); + + gtk_container_add (GTK_CONTAINER (button), editEntryData->number); + + gtk_box_pack_end(GTK_BOX(hbox), button, TRUE, TRUE, 2); + + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (EditNumbers), NULL); + gtk_widget_show_all (button); + } + else + { + editEntryData->number = gtk_entry_new_with_max_length (max_phonebook_number_length); + gtk_box_pack_end(GTK_BOX(hbox), editEntryData->number, FALSE, FALSE, 2); + gtk_widget_show (editEntryData->number); + } + +/* if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) { + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (editEntryData->dialog)->vbox), hbox); +// gtk_widget_show (hbox); + + label = gtk_label_new (_("Extended:")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); +// gtk_widget_show (label); + + editEntryData->extended = gtk_combo_new(); + gtk_box_pack_end(GTK_BOX(hbox), editEntryData->extended, FALSE, FALSE, 2); +// gtk_widget_show (editEntryData->extended); + + gtk_signal_connect (GTK_OBJECT (GTK_COMBO(editEntryData->extended)->entry), "activate", + GTK_SIGNAL_FUNC (ExtPbkChanged), (gpointer) editEntryData); + } +*/ + + editEntryData->memoryBox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (editEntryData->dialog)->vbox), + editEntryData->memoryBox); + + label = gtk_label_new (_("Memory:")); + gtk_box_pack_start(GTK_BOX (editEntryData->memoryBox), label, FALSE, FALSE, 2); + gtk_widget_show (label); + + editEntryData->memoryTypePhone = gtk_radio_button_new_with_label (NULL, _("phone")); + gtk_box_pack_end (GTK_BOX (editEntryData->memoryBox), editEntryData->memoryTypePhone, TRUE, FALSE, 2); + gtk_widget_show (editEntryData->memoryTypePhone); + + editEntryData->memoryTypeSIM = gtk_radio_button_new_with_label( + gtk_radio_button_group (GTK_RADIO_BUTTON (editEntryData->memoryTypePhone)), "SIM"); + gtk_box_pack_end(GTK_BOX (editEntryData->memoryBox), editEntryData->memoryTypeSIM, TRUE, FALSE, 2); + gtk_widget_show (editEntryData->memoryTypeSIM); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (editEntryData->dialog)->vbox), hbox); + gtk_widget_show (hbox); + + editEntryData->groupLabel = gtk_label_new (_("Caller group:")); + gtk_box_pack_start (GTK_BOX (hbox), editEntryData->groupLabel, FALSE, FALSE, 2); + + editEntryData->group = gtk_option_menu_new (); + + CreateGroupMenu (editEntryData); + + gtk_box_pack_start (GTK_BOX (hbox), editEntryData->group, TRUE, TRUE, 0); +} + + +static void EditPbEntry(PhonebookEntry *pbEntry, gint row) +{ + if (editEditEntryData.dialog == NULL) + CreateEditDialog(&editEditEntryData, _("Edit entry"), OkEditEntryDialog); + + editEditEntryData.pbEntry = pbEntry; + editEditEntryData.newGroup = pbEntry->entry.Group; + editEditEntryData.row = row; + editNumbersData.pbEntry = pbEntry; + + gtk_entry_set_text (GTK_ENTRY (editEditEntryData.name), pbEntry->entry.Name); + + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + gtk_label_set_text (GTK_LABEL (editEditEntryData.number), pbEntry->entry.Number); + else + gtk_entry_set_text (GTK_ENTRY (editEditEntryData.number), pbEntry->entry.Number); + + if (pbEntry->entry.MemoryType == GMT_ME) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (editEditEntryData.memoryTypePhone), TRUE); + else + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (editEditEntryData.memoryTypeSIM), TRUE); + + gtk_option_menu_set_history( GTK_OPTION_MENU (editEditEntryData.group), + pbEntry->entry.Group); + + if (GetModelFeature(FN_CALLERGROUPS)!=0) + { + gtk_widget_show (editEditEntryData.group); + gtk_widget_show (editEditEntryData.groupLabel); + } + else + { + gtk_widget_hide (editEditEntryData.group); + gtk_widget_hide (editEditEntryData.groupLabel); + } + + if (memoryStatus.MaxME > 0) + gtk_widget_show (GTK_WIDGET (editEditEntryData.memoryBox)); + else + gtk_widget_hide (GTK_WIDGET (editEditEntryData.memoryBox)); + + gtk_widget_show (GTK_WIDGET (editEditEntryData.dialog)); +} + + +void DeletePbEntry (void) +{ + static GtkWidget *dialog = NULL; + GtkWidget *button, *hbox, *label, *pixmap; + + if (dialog == NULL) + { + dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (dialog), _("Delete entries")); + gtk_window_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); + gtk_window_set_modal(GTK_WINDOW (dialog), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 10); + gtk_signal_connect (GTK_OBJECT (dialog), "delete_event", + GTK_SIGNAL_FUNC (DeleteEvent), NULL); + + button = gtk_button_new_with_label (_("Ok")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (OkDeleteEntryDialog), (gpointer) dialog); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_widget_grab_default (button); + gtk_widget_show (button); + button = gtk_button_new_with_label (_("Cancel")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (CancelDialog), (gpointer) dialog); + gtk_widget_show (button); + + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox); + gtk_widget_show (hbox); + + pixmap = gtk_pixmap_new (questMark.pixmap, questMark.mask); + gtk_box_pack_start(GTK_BOX(hbox), pixmap, FALSE, FALSE, 10); + gtk_widget_show(pixmap); + + label = gtk_label_new(_("Do you want to delete selected entries?")); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 10); + gtk_widget_show(label); + } + + gtk_widget_show(GTK_WIDGET (dialog)); +} + + +void NewPbEntry(PhonebookEntry *pbEntry) +{ + if (newEditEntryData.dialog == NULL) + CreateEditDialog (&newEditEntryData, _("New entry"), OkNewEntryDialog); + + newEditEntryData.pbEntry = pbEntry; + newEditEntryData.newGroup = 5; + editNumbersData.pbEntry = pbEntry; + + gtk_entry_set_text (GTK_ENTRY (newEditEntryData.name), ""); + + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + gtk_label_set_text (GTK_LABEL (newEditEntryData.number), ""); + else + gtk_entry_set_text (GTK_ENTRY (newEditEntryData.number), ""); + + if (pbEntry->entry.MemoryType == GMT_ME) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (newEditEntryData.memoryTypePhone), TRUE); + else + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (newEditEntryData.memoryTypeSIM), TRUE); + + gtk_option_menu_set_history( GTK_OPTION_MENU (newEditEntryData.group), + pbEntry->entry.Group); + + if (GetModelFeature(FN_CALLERGROUPS)!=0) + { + gtk_widget_show (newEditEntryData.group); + gtk_widget_show (newEditEntryData.groupLabel); + } + else + { + gtk_widget_hide (newEditEntryData.group); + gtk_widget_hide (newEditEntryData.groupLabel); + } + + if (memoryStatus.MaxME > 0) + gtk_widget_show (GTK_WIDGET (newEditEntryData.memoryBox)); + else + gtk_widget_hide (GTK_WIDGET (newEditEntryData.memoryBox)); + + gtk_widget_show(GTK_WIDGET (newEditEntryData.dialog)); +} + + +void DuplicatePbEntry (PhonebookEntry *pbEntry) +{ + if (duplicateEditEntryData.dialog == NULL) + CreateEditDialog (&duplicateEditEntryData, _("Duplicate entry"), OkNewEntryDialog); + + duplicateEditEntryData.pbEntry = pbEntry; + duplicateEditEntryData.newGroup = pbEntry->entry.Group; + editNumbersData.pbEntry = pbEntry; + + gtk_entry_set_text (GTK_ENTRY (duplicateEditEntryData.name), pbEntry->entry.Name); + + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + gtk_label_set_text (GTK_LABEL (duplicateEditEntryData.number), pbEntry->entry.Number); + else + gtk_entry_set_text (GTK_ENTRY (duplicateEditEntryData.number), pbEntry->entry.Number); + + if (pbEntry->entry.MemoryType == GMT_ME) + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (duplicateEditEntryData.memoryTypePhone), TRUE); + else + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (duplicateEditEntryData.memoryTypeSIM), TRUE); + + gtk_option_menu_set_history( GTK_OPTION_MENU (duplicateEditEntryData.group), + pbEntry->entry.Group); + + if (GetModelFeature(FN_CALLERGROUPS)!=0) + { + gtk_widget_show (duplicateEditEntryData.group); + gtk_widget_show (duplicateEditEntryData.groupLabel); + } + else + { + gtk_widget_hide (duplicateEditEntryData.group); + gtk_widget_hide (duplicateEditEntryData.groupLabel); + } + + if (memoryStatus.MaxME > 0) + gtk_widget_show (GTK_WIDGET (duplicateEditEntryData.memoryBox)); + else + gtk_widget_hide (GTK_WIDGET (duplicateEditEntryData.memoryBox)); + + gtk_widget_show(GTK_WIDGET (duplicateEditEntryData.dialog)); +} + + +static void EditEntry (void) +{ + if (contactsMemoryInitialized) + { + if (GTK_CLIST (clist)->selection == NULL) + return; + + EditPbEntry((PhonebookEntry *) gtk_clist_get_row_data(GTK_CLIST (clist), + GPOINTER_TO_INT(GTK_CLIST (clist)->selection->data)), + GPOINTER_TO_INT(GTK_CLIST (clist)->selection->data)); + } +} + + +static void DuplicateEntry (void) +{ + PhonebookEntry *new, *old; + + if (contactsMemoryInitialized) + { + if (GTK_CLIST (clist)->selection == NULL) + return; + + old = (PhonebookEntry *) gtk_clist_get_row_data (GTK_CLIST (clist), GPOINTER_TO_INT(GTK_CLIST (clist)->selection->data)); + + if ( old->entry.MemoryType == GMT_ME) + { + if ((new = FindFreeEntry (GMT_ME)) == NULL) + if ((new = FindFreeEntry (GMT_SM)) == NULL) + { + gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Can't find free memory.")); + gtk_widget_show (errorDialog.dialog); + return; + } + } + else + { + if ((new = FindFreeEntry(GMT_SM)) == NULL) + if ((new = FindFreeEntry(GMT_ME)) == NULL) + { + gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Can't find free memory.")); + gtk_widget_show (errorDialog.dialog); + return; + } + } + + new->entry = old->entry; + + DuplicatePbEntry (new); + } +} + + +static void NewEntry (void) +{ + PhonebookEntry *entry; + + if (contactsMemoryInitialized) + { + if ((entry = FindFreeEntry (GMT_SM)) != NULL) + NewPbEntry(entry); + else if ((entry = FindFreeEntry (GMT_ME)) != NULL) + NewPbEntry(entry); + else + { + gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Can't find free memory.")); + gtk_widget_show (errorDialog.dialog); + } + } +} + + +static inline void ClickEntry (GtkWidget *clist, + gint row, + gint column, + GdkEventButton *event, + gpointer data ) +{ + if(event && event->type == GDK_2BUTTON_PRESS) + EditPbEntry((PhonebookEntry *) gtk_clist_get_row_data(GTK_CLIST (clist), row), + row); +} + + +static inline void DeleteEntry (void) +{ + if (contactsMemoryInitialized) + { + if (GTK_CLIST (clist)->selection == NULL) + return; + + DeletePbEntry (); + } +} + + +static void ChMemType (void) +{ + static GtkWidget *dialog = NULL; + GtkWidget *button, *hbox, *label; + + if (contactsMemoryInitialized) + { + if (GTK_CLIST (clist)->selection == NULL) + return; + + if (dialog == NULL) + { + dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (dialog), _("Changing memory type")); + gtk_window_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); + gtk_window_set_modal(GTK_WINDOW (dialog), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); + gtk_signal_connect (GTK_OBJECT (dialog), "delete_event", + GTK_SIGNAL_FUNC (DeleteEvent), NULL); + + button = gtk_button_new_with_label (_("Continue")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), + button, FALSE, FALSE, 0); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (OkChangeEntryDialog), (gpointer) dialog); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_widget_grab_default (button); + gtk_widget_show (button); + + button = gtk_button_new_with_label (_("Cancel")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), + button, FALSE, FALSE, 0); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (CancelDialog), (gpointer) dialog); + gtk_widget_show (button); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox); + gtk_widget_show (hbox); + + label = gtk_label_new (_("If you change from phone memory to SIM memory\nsome entries may be truncated.")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 10); + gtk_widget_show (label); + } + + gtk_widget_show (dialog); + } +} + + +static void FindFirstEntry (void) +{ + static FindEntryData findEntryData = { NULL }; + GtkWidget *button, *label, *hbox; + + if (contactsMemoryInitialized) + { + if (findEntryData.dialog == NULL) + { + findEntryData.dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (findEntryData.dialog), _("Find")); + gtk_window_set_modal (GTK_WINDOW (findEntryData.dialog), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (findEntryData.dialog), 10); + gtk_signal_connect (GTK_OBJECT (findEntryData.dialog), "delete_event", + GTK_SIGNAL_FUNC (DeleteEvent), NULL); + + button = gtk_button_new_with_label (_("Find")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (findEntryData.dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (OkFindEntryDialog), (gpointer) &findEntryData); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_widget_grab_default (button); + gtk_widget_show (button); + + button = gtk_button_new_with_label (_("Cancel")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (findEntryData.dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (CancelEditDialog), (gpointer) &findEntryData); + gtk_widget_show (button); + + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (findEntryData.dialog)->vbox), 5); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (findEntryData.dialog)->vbox), hbox); + gtk_widget_show (hbox); + + label = gtk_label_new (_("Pattern:")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2); + gtk_widget_show (label); + + findEntryData.pattern = gtk_entry_new_with_max_length (max_phonebook_name_length); + + gtk_box_pack_end (GTK_BOX (hbox), findEntryData.pattern, FALSE, FALSE, 2); + gtk_widget_show (findEntryData.pattern); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (findEntryData.dialog)->vbox), hbox); + gtk_widget_show (hbox); + + findEntryData.nameB = gtk_radio_button_new_with_label (NULL, _("Name")); + gtk_box_pack_start (GTK_BOX (hbox), findEntryData.nameB, TRUE, FALSE, 2); + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (findEntryData.nameB), TRUE); + gtk_widget_show (findEntryData.nameB); + + findEntryData.numberB = gtk_radio_button_new_with_label ( + gtk_radio_button_group (GTK_RADIO_BUTTON (findEntryData.nameB)), _("Number")); + gtk_box_pack_start (GTK_BOX(hbox), findEntryData.numberB, TRUE, FALSE, 2); + gtk_widget_show (findEntryData.numberB); + } + + gtk_widget_show (findEntryData.dialog); + } +} + + +static inline void SelectAll (void) +{ + gtk_clist_select_all (GTK_CLIST (clist)); +} + + +static inline void OkDialVoiceDialog (GtkWidget *w, gpointer data) +{ + PhoneEvent *e; + gchar *buf = g_strdup (gtk_entry_get_text (GTK_ENTRY (((DialVoiceDialog *) data)->entry))); + + if (strlen (buf) > 0) + { + e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent)); + e->event = Event_DialVoice; + e->data = buf; + GUI_InsertEvent (e); + } + else + g_free (buf); + + gtk_widget_hide (((DialVoiceDialog *) data)->dialog); +} + + +static void DialVoice (void) +{ + static DialVoiceDialog dialVoiceDialog = {NULL, NULL}; + GtkWidget *button, *label; + PhonebookEntry *pbEntry; + + if (dialVoiceDialog.dialog == NULL) + { + dialVoiceDialog.dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (dialVoiceDialog.dialog), _("Dial voice")); + gtk_window_set_modal(GTK_WINDOW (dialVoiceDialog.dialog), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (dialVoiceDialog.dialog), 10); + gtk_signal_connect (GTK_OBJECT (dialVoiceDialog.dialog), "delete_event", + GTK_SIGNAL_FUNC (DeleteEvent), NULL); + + button = gtk_button_new_with_label (_("Ok")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialVoiceDialog.dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (OkDialVoiceDialog), (gpointer) &dialVoiceDialog); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_widget_grab_default (button); + gtk_widget_show (button); + + button = gtk_button_new_with_label (_("Cancel")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialVoiceDialog.dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (CancelDialog), (gpointer) dialVoiceDialog.dialog); + gtk_widget_show (button); + + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialVoiceDialog.dialog)->vbox), 5); + + label = gtk_label_new (_("Number:")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialVoiceDialog.dialog)->vbox), label, FALSE, FALSE, 5); + gtk_widget_show (label); + + dialVoiceDialog.entry = gtk_entry_new_with_max_length (GSM_MAX_PHONEBOOK_NUMBER_LENGTH); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialVoiceDialog.dialog)->vbox), dialVoiceDialog.entry, FALSE, FALSE, 5); + gtk_widget_show (dialVoiceDialog.entry); + } + + if (GTK_CLIST (clist)->selection != NULL) + { + pbEntry = (PhonebookEntry *) gtk_clist_get_row_data (GTK_CLIST (clist), + GPOINTER_TO_INT (GTK_CLIST (clist)->selection->data)); + + gtk_entry_set_text (GTK_ENTRY (dialVoiceDialog.entry), pbEntry->entry.Number); + } + + gtk_widget_show (dialVoiceDialog.dialog); +} + + +static gint CListCompareFunc (GtkCList *clist, gconstpointer ptr1, gconstpointer ptr2) +{ + static gchar phoneText[] = "B"; + static gchar simText[] = "A"; + char *text1 = NULL; + char *text2 = NULL; + gint ret; + + GtkCListRow *row1 = (GtkCListRow *) ptr1; + GtkCListRow *row2 = (GtkCListRow *) ptr2; + + switch (row1->cell[clist->sort_column].type) + { + case GTK_CELL_TEXT: + text1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text; + break; + case GTK_CELL_PIXTEXT: + text1 = GTK_CELL_PIXTEXT (row1->cell[clist->sort_column])->text; + break; + default: + break; + } + switch (row2->cell[clist->sort_column].type) + { + case GTK_CELL_TEXT: + text2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text; + break; + case GTK_CELL_PIXTEXT: + text2 = GTK_CELL_PIXTEXT (row2->cell[clist->sort_column])->text; + break; + default: + break; + } + + if (clist->sort_column == 2) + { + if (((PhonebookEntry *) row1->data)->entry.MemoryType == GMT_ME) + text1 = phoneText; + else + text1 = simText; + if (((PhonebookEntry *) row2->data)->entry.MemoryType == GMT_ME) + text2 = phoneText; + else + text2 = simText; + } + + if (!text2) + return (text1 != NULL); + + if (!text1) + return -1; + + if ((ret = g_strcasecmp (text1, text2)) == 0) + { + if (((PhonebookEntry *) row1->data)->entry.MemoryType < ((PhonebookEntry *) row2->data)->entry.MemoryType) + ret = -1; + else if (((PhonebookEntry *) row1->data)->entry.MemoryType > ((PhonebookEntry *) row2->data)->entry.MemoryType) + ret = 1; + } + + return ret; +} + + +static void CreateProgressDialog (gint maxME, gint maxSM) +{ + GtkWidget *vbox, *label; + GtkAdjustment *adj; + + progressDialog.dialog = gtk_window_new (GTK_WINDOW_DIALOG); + gtk_window_position (GTK_WINDOW (progressDialog.dialog), GTK_WIN_POS_MOUSE); + gtk_window_set_modal (GTK_WINDOW (progressDialog.dialog), TRUE); + gtk_signal_connect (GTK_OBJECT (progressDialog.dialog), "delete_event", + GTK_SIGNAL_FUNC (ProgressDialogDeleteEvent), NULL); + + vbox = gtk_vbox_new (FALSE, 10); + gtk_container_set_border_width (GTK_CONTAINER (vbox), 5); + gtk_container_add (GTK_CONTAINER (progressDialog.dialog), vbox); + + gtk_widget_show (vbox); + + label = gtk_label_new (_("Phone memory...")); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + + gtk_widget_show (label); + + adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, maxME, 0, 0, 0); + progressDialog.pbarME = gtk_progress_bar_new_with_adjustment (adj); + + gtk_box_pack_start (GTK_BOX (vbox), progressDialog.pbarME, FALSE, FALSE, 0); + gtk_widget_show (progressDialog.pbarME); + + label = gtk_label_new (_("SIM memory...")); + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); + + gtk_widget_show (label); + + adj = (GtkAdjustment *) gtk_adjustment_new (0, 1, maxSM, 0, 0, 0); + progressDialog.pbarSM = gtk_progress_bar_new_with_adjustment (adj); + + gtk_box_pack_start (GTK_BOX (vbox), progressDialog.pbarSM, FALSE, FALSE, 0); + gtk_widget_show (progressDialog.pbarSM); +} + + +static void SaveContacts (void) +{ + register gint i; + PhonebookEntry *pbEntry; + PhoneEvent *e; + D_MemoryLocation *ml; + + if (progressDialog.dialog == NULL) + { + CreateProgressDialog (memoryStatus.MaxME, memoryStatus.MaxSM); + } + + if (contactsMemoryInitialized && progressDialog.dialog) + { + gtk_progress_set_value (GTK_PROGRESS (progressDialog.pbarME), 0); + gtk_progress_set_value (GTK_PROGRESS (progressDialog.pbarSM), 0); + gtk_window_set_title (GTK_WINDOW (progressDialog.dialog), _("Saving entries")); + gtk_widget_show_now (progressDialog.dialog); + + /* Save Phone memory */ + for(i = 0; i < memoryStatus.MaxME; i++) + { + pbEntry = g_ptr_array_index(contactsMemory, i); +#ifdef XDEBUG + g_print ("%d;%s;%s;%d;%d;%d\n", pbEntry->entry.Empty, pbEntry->entry.Name, + pbEntry->entry.Number, (int) pbEntry->entry.MemoryType, pbEntry->entry.Group, + (int) pbEntry->status); +#endif + if (pbEntry->status == E_Changed || pbEntry->status == E_Deleted) + { + if (pbEntry->status == E_Deleted) + { + pbEntry->entry.Name[0] = '\0'; + pbEntry->entry.Number[0] = '\0'; + pbEntry->entry.Group = 5; + } + + pbEntry->entry.Location = i + 1; + ml = (D_MemoryLocation *) g_malloc (sizeof (D_MemoryLocation)); + ml->entry = &(pbEntry->entry); + e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent)); + e->event = Event_WriteMemoryLocation; + e->data = ml; + GUI_InsertEvent (e); + pthread_mutex_lock (&memoryMutex); + pthread_cond_wait (&memoryCond, &memoryMutex); + pthread_mutex_unlock (&memoryMutex); + + if (ml->status != GE_NONE) + { + g_print (_("%s: line: %d:Can't write ME memory entry number %d! Error: %d\n"), + __FILE__, __LINE__, i + 1, ml->status); + } + g_free (ml); + } + gtk_progress_set_value (GTK_PROGRESS (progressDialog.pbarME), i + 1); + GUI_Refresh (); + } + + /* Save SIM memory */ + for (i = memoryStatus.MaxME; i < memoryStatus.MaxME + memoryStatus.MaxSM; i++) + { + pbEntry = g_ptr_array_index (contactsMemory, i); + +#ifdef XDEBUG + g_print ("%d;%s;%s;%d;%d;%d\n", pbEntry->entry.Empty, pbEntry->entry.Name, + pbEntry->entry.Number, (int) pbEntry->entry.MemoryType, pbEntry->entry.Group, + (int) pbEntry->status); +#endif + + if (pbEntry->status == E_Changed || pbEntry->status == E_Deleted) + { + if (pbEntry->status == E_Deleted) + { + pbEntry->entry.Name[0] = '\0'; + pbEntry->entry.Number[0] = '\0'; + pbEntry->entry.Group = 5; + } + + pbEntry->entry.Location = i - memoryStatus.MaxME + 1; + ml = (D_MemoryLocation *) g_malloc (sizeof (D_MemoryLocation)); + ml->entry = &(pbEntry->entry); + e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent)); + e->event = Event_WriteMemoryLocation; + e->data = ml; + GUI_InsertEvent (e); + pthread_mutex_lock (&memoryMutex); + pthread_cond_wait (&memoryCond, &memoryMutex); + pthread_mutex_unlock (&memoryMutex); + + if (ml->status != GE_NONE) + { + g_print(_("%s: line %d:Can't write SM memory entry number %d! Error: %d\n"), + __FILE__, __LINE__, i - memoryStatus.MaxME + 1, ml->status); + } + g_free (ml); + } + gtk_progress_set_value (GTK_PROGRESS (progressDialog.pbarSM), i - memoryStatus.MaxME + 1); + GUI_Refresh (); + } + + statusInfo.ch_ME = statusInfo.ch_SM = 0; + RefreshStatusInfo (); + gtk_widget_hide (progressDialog.dialog); + } +} + + +static GtkWidget *CreateSaveQuestionDialog (GtkSignalFunc SaveFunc, + GtkSignalFunc DontSaveFunc) +{ + GtkWidget *dialog; + GtkWidget *button, *label, *hbox, *pixmap; + + dialog = gtk_dialog_new (); + gtk_window_set_title (GTK_WINDOW (dialog), _("Save changes?")); + gtk_window_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); + gtk_window_set_modal (GTK_WINDOW (dialog), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 10); + gtk_signal_connect (GTK_OBJECT (dialog), "delete_event", + GTK_SIGNAL_FUNC (DeleteEvent), NULL); + + button = gtk_button_new_with_label (_("Save")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (SaveFunc), (gpointer) dialog); + GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT); + gtk_widget_grab_default (button); + gtk_widget_show (button); + + button = gtk_button_new_with_label (_("Don't save")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (DontSaveFunc), (gpointer) dialog); + gtk_widget_show (button); + + button = gtk_button_new_with_label (_("Cancel")); + gtk_box_pack_start(GTK_BOX (GTK_DIALOG (dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect(GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (CancelDialog), (gpointer) dialog); + gtk_widget_show (button); + + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox); + gtk_widget_show (hbox); + + pixmap = gtk_pixmap_new (questMark.pixmap, questMark.mask); + gtk_box_pack_start (GTK_BOX (hbox), pixmap, FALSE, FALSE, 10); + gtk_widget_show (pixmap); + + label = gtk_label_new (_("You have made changes in your\ncontacts directory.\n\ +\n\nDo you want save these changes into phone?\n")); + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 2); + gtk_widget_show (label); + + return dialog; +} + + +static void OkExtPbkDialog (GtkWidget *w, gpointer data) { + + ExtPbkDialog *d=(ExtPbkDialog*)data; + GSM_NumberType numtype; + gint i, found=999; + gchar *chars; + + if (w==d->gbutton) numtype=GSM_General; + else if (w==d->mbutton) numtype=GSM_Mobile; + else if (w==d->wbutton) numtype=GSM_Work; + else if (w==d->fbutton) numtype=GSM_Fax; + else if (w==d->hbutton) numtype=GSM_Home; + else numtype=GSM_General; + + /* Search through subentries */ + + for (i=0;ipbEntry->entry.SubEntriesCount;i++) { + if (d->pbEntry->entry.SubEntries[i].EntryType==GSM_Number) + if (d->pbEntry->entry.SubEntries[i].NumberType==numtype) + found=i; + } + + if (found>i) { /* Not found */ + found=d->pbEntry->entry.SubEntriesCount; + d->pbEntry->entry.SubEntriesCount++; + d->pbEntry->entry.SubEntries[found].EntryType=GSM_Number; + d->pbEntry->entry.SubEntries[found].NumberType=numtype; + } + + chars=gtk_editable_get_chars(GTK_EDITABLE(d->entry),0,-1); + strcpy(d->pbEntry->entry.SubEntries[found].data.Number,chars); + g_free(chars); + + /* Update the entry dialog */ + EditPbEntry(d->pbEntry,d->row); + + gtk_widget_hide (d->dialog); +} + + +void ExtPbkChanged (GtkWidget *widget, gpointer data ) +{ + static ExtPbkDialog dialog = {NULL,NULL,0,NULL,NULL,NULL,NULL,NULL}; + GtkWidget *button; + static GtkWidget *label; + gchar *chars; + + + if (dialog.dialog==NULL) { + + dialog.dialog=gtk_dialog_new(); + + gtk_window_set_title (GTK_WINDOW (dialog.dialog), _("Which Extended Phonebook Entry?")); + gtk_window_set_modal(GTK_WINDOW (dialog.dialog), TRUE); + gtk_container_set_border_width (GTK_CONTAINER (dialog.dialog), 10); + gtk_signal_connect (GTK_OBJECT (dialog.dialog), "delete_event", + GTK_SIGNAL_FUNC (DeleteEvent), NULL); + + dialog.gbutton = gtk_button_new_with_label (_("General")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog.dialog)->vbox), + dialog.gbutton, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (dialog.gbutton), "clicked", + GTK_SIGNAL_FUNC (OkExtPbkDialog), (gpointer)&dialog ); + gtk_widget_show (dialog.gbutton); + dialog.mbutton = gtk_button_new_with_label (_("Mobile")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog.dialog)->vbox), + dialog.mbutton, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (dialog.mbutton), "clicked", + GTK_SIGNAL_FUNC (OkExtPbkDialog), (gpointer)&dialog ); + gtk_widget_show (dialog.mbutton); + dialog.wbutton = gtk_button_new_with_label (_("Work")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog.dialog)->vbox), + dialog.wbutton, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (dialog.wbutton), "clicked", + GTK_SIGNAL_FUNC (OkExtPbkDialog), (gpointer)&dialog ); + gtk_widget_show (dialog.wbutton); + dialog.fbutton = gtk_button_new_with_label (_("Fax")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog.dialog)->vbox), + dialog.fbutton, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (dialog.fbutton), "clicked", + GTK_SIGNAL_FUNC (OkExtPbkDialog), (gpointer)&dialog ); + gtk_widget_show (dialog.fbutton); + dialog.hbutton = gtk_button_new_with_label (_("Home")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog.dialog)->vbox), + dialog.hbutton, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (dialog.hbutton), "clicked", + GTK_SIGNAL_FUNC (OkExtPbkDialog), (gpointer)&dialog ); + gtk_widget_show (dialog.hbutton); + + button = gtk_button_new_with_label (_("Cancel")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog.dialog)->action_area), + button, TRUE, TRUE, 10); + gtk_signal_connect (GTK_OBJECT (button), "clicked", + GTK_SIGNAL_FUNC (CancelDialog), (gpointer) dialog.dialog); + gtk_widget_show (button); + + label = gtk_label_new(""); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog.dialog)->vbox), label, FALSE, FALSE, 5); + gtk_widget_show(label); + } + + chars=gtk_editable_get_chars(GTK_EDITABLE(widget),0,-1); + gtk_label_set_text(GTK_LABEL(label),chars); + g_free(chars); + dialog.pbEntry=((EditEntryData*)data)->pbEntry; + dialog.row=((EditEntryData*)data)->row; + dialog.entry=widget; + gtk_widget_show(dialog.dialog); +} + + + +void GUI_RefreshContacts (void) +{ + PhonebookEntry *pbEntry; + gint row_i = 0; + register gint i; + + if (contactsMemoryInitialized == FALSE) + return; + + gtk_clist_freeze (GTK_CLIST (clist)); + gtk_clist_clear (GTK_CLIST (clist)); + + for (i = 0; i < memoryStatus.MaxME + memoryStatus.MaxSM; i++) + { + gchar *row[4]; + + pbEntry = g_ptr_array_index (contactsMemory, i); + if (pbEntry->status != E_Empty && pbEntry->status != E_Deleted) + { + row[0] = pbEntry->entry.Name; + + row[1] = pbEntry->entry.Number; + + if (pbEntry->entry.MemoryType == GMT_ME) + row[2] = "P"; + else + row[2] = "S"; + if (GetModelFeature(FN_CALLERGROUPS)!=0) + row[3] = xgnokiiConfig.callerGroups[pbEntry->entry.Group]; + else + row[3] = ""; + gtk_clist_append (GTK_CLIST (clist), row); + if (pbEntry->entry.MemoryType == GMT_ME) + gtk_clist_set_pixmap (GTK_CLIST (clist), row_i, 2, + memoryPixmaps.phoneMemPix, memoryPixmaps.mask); + else + gtk_clist_set_pixmap (GTK_CLIST (clist), row_i, 2, + memoryPixmaps.simMemPix, memoryPixmaps.mask); + + gtk_clist_set_row_data (GTK_CLIST (clist), row_i++, (gpointer) pbEntry); + } +#ifdef XDEBUG + g_print ("%d;%s;%s;%d;%d;%d\n", pbEntry->entry.Empty, pbEntry->entry.Name, + pbEntry->entry.Number, (int) pbEntry->entry.MemoryType, pbEntry->entry.Group, + (int) pbEntry->status); +#endif + } + + gtk_clist_sort (GTK_CLIST (clist)); + gtk_clist_thaw (GTK_CLIST (clist)); +} + + +static gint InsertPBEntryME (GSM_PhonebookEntry *entry) +{ + PhonebookEntry *pbEntry; + + if ((pbEntry = (PhonebookEntry *) g_malloc (sizeof (PhonebookEntry))) == NULL) + { + g_print (_("%s: line %d: Can't allocate memory!\n"), __FILE__, __LINE__); + g_ptr_array_free (contactsMemory, TRUE); + gtk_widget_hide (progressDialog.dialog); + return (-1); + } + + pbEntry->entry = *entry; + + if (*pbEntry->entry.Name == '\0' && *pbEntry->entry.Number == '\0') + pbEntry->status = E_Empty; + else + pbEntry->status = E_Unchanged; + + g_ptr_array_add (contactsMemory, (gpointer) pbEntry); + gtk_progress_set_value (GTK_PROGRESS (progressDialog.pbarME), entry->Location); + GUI_Refresh (); + + return (GE_NONE); +} + + +static gint InsertPBEntrySM (GSM_PhonebookEntry *entry) +{ + PhonebookEntry *pbEntry; + + if ((pbEntry = (PhonebookEntry *) g_malloc (sizeof (PhonebookEntry))) == NULL) + { + g_print (_("%s: line %d: Can't allocate memory!\n"), __FILE__, __LINE__); + g_ptr_array_free (contactsMemory, TRUE); + gtk_widget_hide (progressDialog.dialog); + return (-1); + } + + pbEntry->entry = *entry; + + if (*pbEntry->entry.Name == '\0' && *pbEntry->entry.Number == '\0') + pbEntry->status = E_Empty; + else + { + pbEntry->status = E_Unchanged; + if (fbus3810) + { + memoryStatus.UsedSM++; + memoryStatus.FreeSM--; + } + } + + g_ptr_array_add (contactsMemory, (gpointer) pbEntry); + gtk_progress_set_value (GTK_PROGRESS (progressDialog.pbarSM), entry->Location); + GUI_Refresh (); + + return (GE_NONE); +} + + +static inline gint ReadFailedPBEntry (gint i) +{ + g_ptr_array_free (contactsMemory, TRUE); + gtk_widget_hide (progressDialog.dialog); + return (0); +} + + +static void ReadContactsMain (void) +{ + PhoneEvent *e; + D_MemoryStatus *ms; + D_MemoryLocationAll *mla; + PhonebookEntry *pbEntry; + register gint i; + + fbus3810 = FALSE; + + if (contactsMemoryInitialized == TRUE) + { + for (i = 0; i < memoryStatus.MaxME + memoryStatus.MaxSM; i++) + { + pbEntry = g_ptr_array_index (contactsMemory, i); + g_free (pbEntry); + } + g_ptr_array_free (contactsMemory, TRUE); + contactsMemory = NULL; + gtk_clist_clear (GTK_CLIST (clist)); + contactsMemoryInitialized = FALSE; + memoryStatus.MaxME = memoryStatus.UsedME = memoryStatus.FreeME = + memoryStatus.MaxSM = memoryStatus.UsedSM = memoryStatus.FreeSM = 0; + statusInfo.ch_ME = statusInfo.ch_SM = 0; + RefreshStatusInfo (); + } + + ms = (D_MemoryStatus *) g_malloc (sizeof (D_MemoryStatus)); + ms->memoryStatus.MemoryType = GMT_ME; + e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent)); + e->event = Event_GetMemoryStatus; + e->data = ms; + GUI_InsertEvent (e); + pthread_mutex_lock (&memoryMutex); + pthread_cond_wait (&memoryCond, &memoryMutex); + pthread_mutex_unlock (&memoryMutex); + + if (ms->status != GE_NONE) + /* Phone don't support ME (5110) */ + memoryStatus.MaxME = memoryStatus.UsedME = memoryStatus.FreeME = 0; + else + { + memoryStatus.MaxME = ms->memoryStatus.Used + ms->memoryStatus.Free; + memoryStatus.UsedME = ms->memoryStatus.Used; + memoryStatus.FreeME = ms->memoryStatus.Free; + } + + ms->memoryStatus.MemoryType = GMT_SM; + e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent)); + e->event = Event_GetMemoryStatus; + e->data = ms; + GUI_InsertEvent (e); + pthread_mutex_lock (&memoryMutex); + pthread_cond_wait (&memoryCond, &memoryMutex); + pthread_mutex_unlock (&memoryMutex); + + if (ms->status != GE_NONE) + { + fbus3810 = TRUE; /* I try to recognize memoryStatus.UsedSM while reading */ + gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Can't get SM memory status!\n\n\ +Setting max SIM entries to 100!\n")); + memoryStatus.MaxSM = memoryStatus.FreeSM = 100; + memoryStatus.UsedSM = 0; + gtk_widget_show (errorDialog.dialog); + } + else + { + memoryStatus.MaxSM = ms->memoryStatus.Used + ms->memoryStatus.Free; + memoryStatus.UsedSM = ms->memoryStatus.Used; + memoryStatus.FreeSM = ms->memoryStatus.Free; + } + g_free (ms); + + statusInfo.ch_ME = statusInfo.ch_SM = 0; + + RefreshStatusInfo (); + + if (progressDialog.dialog == NULL) + { + CreateProgressDialog (memoryStatus.MaxME, memoryStatus.MaxSM); + } + + gtk_progress_set_value (GTK_PROGRESS (progressDialog.pbarME), 0); + gtk_progress_set_value (GTK_PROGRESS (progressDialog.pbarSM), 0); + gtk_window_set_title (GTK_WINDOW (progressDialog.dialog), _("Getting entries")); + gtk_widget_show_now (progressDialog.dialog); + + contactsMemory = g_ptr_array_new (); + + mla = (D_MemoryLocationAll *) g_malloc (sizeof (D_MemoryLocationAll)); + if (memoryStatus.MaxME > 0) + { + mla->min = 1; + mla->max = memoryStatus.MaxME; + mla->type = GMT_ME; + mla->used = memoryStatus.UsedME; //MW + mla->InsertEntry = InsertPBEntryME; + mla->ReadFailed = ReadFailedPBEntry; + + e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent)); + e->event = Event_GetMemoryLocationAll; + e->data = mla; + GUI_InsertEvent (e); + pthread_mutex_lock (&memoryMutex); + pthread_cond_wait (&memoryCond, &memoryMutex); + pthread_mutex_unlock (&memoryMutex); + + if (mla->status != GE_NONE) + { + g_free (mla); + gtk_widget_hide (progressDialog.dialog); + return; + } + } + + mla->min = 1; + mla->max = memoryStatus.MaxSM; + mla->type = GMT_SM; + mla->used = memoryStatus.UsedSM; //MW + mla->InsertEntry = InsertPBEntrySM; + mla->ReadFailed = ReadFailedPBEntry; + + e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent)); + e->event = Event_GetMemoryLocationAll; + e->data = mla; + GUI_InsertEvent (e); + pthread_mutex_lock (&memoryMutex); + pthread_cond_wait (&memoryCond, &memoryMutex); + pthread_mutex_unlock (&memoryMutex); + + if (mla->status != GE_NONE) + { + g_free (mla); + gtk_widget_hide (progressDialog.dialog); + return; + } + + g_free (mla); + + gtk_widget_hide (progressDialog.dialog); + + contactsMemoryInitialized = TRUE; + statusInfo.ch_ME = statusInfo.ch_SM = 0; + GUIEventSend (GUI_EVENT_CONTACTS_CHANGED); + GUIEventSend (GUI_EVENT_SMS_NUMBER_CHANGED); +} + + +static void ReadSaveCallback (GtkWidget *widget, gpointer data) +{ + gtk_widget_hide (GTK_WIDGET (data)); + SaveContacts (); + ReadContactsMain (); +} + + +static void ReadDontSaveCallback (GtkWidget *widget, gpointer data) +{ + gtk_widget_hide (GTK_WIDGET (data)); + ReadContactsMain (); +} + + +static void ReadSaveContacts (void) +{ + static GtkWidget *dialog = NULL; + + if (dialog == NULL) + dialog = CreateSaveQuestionDialog (ReadSaveCallback, ReadDontSaveCallback); + + gtk_widget_show (dialog); +} + + +static void ReadContacts (void) +{ + if (contactsMemoryInitialized == TRUE && (statusInfo.ch_ME || statusInfo.ch_SM)) + ReadSaveContacts (); + else + ReadContactsMain (); +} + + +inline void GUI_ReadContacts (void) +{ + ReadContacts (); +} + + +inline void GUI_SaveContacts (void) +{ + SaveContacts (); +} + + +inline void GUI_ShowContacts (void) +{ + if (xgnokiiConfig.callerGroups[0] == NULL) + { + GUI_Refresh (); + GUI_InitCallerGroupsInf (); + } + gtk_clist_set_column_visibility (GTK_CLIST (clist), 3, (GetModelFeature(FN_CALLERGROUPS)!=0)); + GUI_RefreshContacts (); + gtk_widget_show (GUI_ContactsWindow); +// if (!contactsMemoryInitialized) +// ReadContacts (); +} + +static void ExportVCARD (FILE *f) +{ + gchar buf2[10]; + register gint i,j; + PhonebookEntry *pbEntry; + + for(i = 0; i < memoryStatus.MaxME + memoryStatus.MaxSM; i++) + { + pbEntry = g_ptr_array_index (contactsMemory, i); + + if (pbEntry->status == E_Deleted || pbEntry->status == E_Empty) + continue; + + fprintf (f, "BEGIN:VCARD\n"); + fprintf (f, "VERSION:3.0\n"); + fprintf (f, "FN:%s\n", pbEntry->entry.Name); + fprintf (f, "TEL;PREF:%s\n", pbEntry->entry.Number); + + if (pbEntry->entry.MemoryType == GMT_ME) + sprintf (buf2, "ME%d", i + 1); + else + sprintf (buf2, "SM%d", i - memoryStatus.MaxME + 1); + + fprintf (f, "X_GSM_STORE_AT:%s\n", buf2); + fprintf (f, "X_GSM_CALLERGROUP:%d\n", pbEntry->entry.Group); + + /* Add ext. pbk info if required */ + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + for (j = 0; j < pbEntry->entry.SubEntriesCount; j++) + { + if (pbEntry->entry.SubEntries[j].EntryType == GSM_Number) + fprintf (f, "TEL;UNKNOWN_%d:%s\n", pbEntry->entry.SubEntries[j].NumberType, + pbEntry->entry.SubEntries[j].data.Number); + } + + fprintf (f, "END:VCARD\n\n"); + } + + fclose (f); +} + + +static void ExportNative (FILE *f) +{ + gchar buf[IO_BUF_LEN], buf2[10]; + register gint i,j; + PhonebookEntry *pbEntry; + + + for(i = 0; i < memoryStatus.MaxME + memoryStatus.MaxSM; i++) + { + pbEntry = g_ptr_array_index (contactsMemory, i); + + if (pbEntry->status != E_Deleted && pbEntry->status != E_Empty) + { + if (index (pbEntry->entry.Name, ';') != NULL) + { + strcpy (buf, "\""); + strcat (buf, pbEntry->entry.Name); + strcat (buf, "\";"); + } + else + { + strcpy (buf, pbEntry->entry.Name); + strcat (buf, ";"); + } + + if (index (pbEntry->entry.Number, ';') != NULL) + { + strcat (buf, "\""); + strcat (buf, pbEntry->entry.Number); + strcat (buf, "\";"); + } + else + { + strcat (buf, pbEntry->entry.Number); + strcat (buf, ";"); + } + + if (pbEntry->entry.MemoryType == GMT_ME) + sprintf (buf2, "B;%d;%d;", i + 1, pbEntry->entry.Group); + else + sprintf (buf2, "A;%d;%d;", i - memoryStatus.MaxME + 1, pbEntry->entry.Group); + strcat (buf, buf2); + + /* Add ext. pbk info if required */ + if (GetModelFeature(FN_PHONEBOOK)==F_PBK71) + { + for (j = 0; j < pbEntry->entry.SubEntriesCount; j++) + if (pbEntry->entry.SubEntries[j].EntryType==GSM_Number) + { + sprintf(buf2,"%d;",pbEntry->entry.SubEntries[j].NumberType); + strcat(buf,buf2); + + if (index (pbEntry->entry.SubEntries[j].data.Number, ';') != NULL) + { + strcat (buf, "\""); + strcat (buf, pbEntry->entry.SubEntries[j].data.Number); + strcat (buf, "\";"); + } + else + { + strcat (buf, pbEntry->entry.SubEntries[j].data.Number); + strcat (buf, ";"); + } + } + } + fprintf (f, "%s\n", buf); + } + } + + fclose(f); +} + + +static void ExportContactsMain (gchar *name) +{ + FILE *f; + gchar buf[IO_BUF_LEN]; + + if ((f = fopen (name, "w")) == NULL) + { + g_snprintf (buf, IO_BUF_LEN, _("Can't open file %s for writing!"), name); + gtk_label_set_text (GTK_LABEL (errorDialog.text), buf); + gtk_widget_show (errorDialog.dialog); + return; + } + + if (strstr (name, ".vcard") || strstr (name, ".gcrd")) + ExportVCARD (f); + else + ExportNative (f); +} + + +static void YesExportDialog (GtkWidget *w, gpointer data) +{ + gtk_widget_hide (GTK_WIDGET (data)); + ExportContactsMain (exportDialogData.fileName); +} + + +static void OkExportDialog (GtkWidget *w, GtkFileSelection *fs) +{ + static YesNoDialog dialog = { NULL, NULL}; + FILE *f; + gchar err[80]; + + exportDialogData.fileName = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs)); + gtk_widget_hide (GTK_WIDGET (fs)); + + if ((f = fopen (exportDialogData.fileName, "r")) != NULL) + { + fclose (f); + if (dialog.dialog == NULL) + { + CreateYesNoDialog (&dialog, YesExportDialog, CancelDialog, GUI_ContactsWindow); + gtk_window_set_title (GTK_WINDOW (dialog.dialog), _("Overwrite file?")); + g_snprintf ( err, 80, _("File %s already exist.\nOverwrite?"), exportDialogData.fileName); + gtk_label_set_text (GTK_LABEL(dialog.text), err); + } + gtk_widget_show (dialog.dialog); + } + else + ExportContactsMain (exportDialogData.fileName); +} + + +static void ExportContacts (void) +{ + static GtkWidget *fileDialog = NULL; + + if (contactsMemoryInitialized) + { + if (fileDialog == NULL) + { + fileDialog = gtk_file_selection_new (_("Export")); + gtk_signal_connect (GTK_OBJECT (fileDialog), "delete_event", + GTK_SIGNAL_FUNC (DeleteEvent), NULL); + gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (fileDialog)->ok_button), + "clicked", GTK_SIGNAL_FUNC (OkExportDialog), (gpointer) fileDialog); + gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (fileDialog)->cancel_button), + "clicked", GTK_SIGNAL_FUNC (CancelDialog), (gpointer) fileDialog); + } + + gtk_widget_show (fileDialog); + } +} + + +static bool ParseLine (GSM_PhonebookEntry *entry, gint *num, gchar *buf) +{ + register gint i = 0; + size_t len; + gchar s_num[5]; + gchar *endptr; + + entry->Empty = FALSE; + entry->SubEntriesCount=0; + + len = strlen (buf); + if (buf[i] == '"') + { + i++; + while (i < len && i <= GSM_MAX_PHONEBOOK_NAME_LENGTH && buf[i] != '"') + { + entry->Name[i - 1] = buf[i]; + i++; + } + entry->Name[i - 1] = '\0'; + if (i >= len) + return FALSE; + if (buf[++i] != ';') + return FALSE; + } + else + { + while (i < len && i < GSM_MAX_PHONEBOOK_NAME_LENGTH && buf[i] != ';') + { + entry->Name[i] = buf[i]; + i++; + } + entry->Name[i] = '\0'; + if (buf[i] != ';') + return FALSE; + if (i >= len) + return FALSE; + } + buf += (i + 1); + i = 0; + + len = strlen (buf); + if (buf[i] == '"') + { + i++; + while (i < len && i <= GSM_MAX_PHONEBOOK_NUMBER_LENGTH && buf[i] != '"') + { + entry->Number[i - 1] = buf[i]; + i++; + } + entry->Number[i - 1] = '\0'; + if (i >= len) + return FALSE; + if (buf[++i] != ';') + return FALSE; + } + else + { + while (i < len && i < GSM_MAX_PHONEBOOK_NUMBER_LENGTH && buf[i] != ';') + { + entry->Number[i] = buf[i]; + i++; + } + entry->Number[i] = '\0'; + if (buf[i] != ';') + return FALSE; + if (i >= len) + return FALSE; + } + buf += (i + 1); + i = 0; + + if (!strncmp(buf, "B;", 2)) + { + entry->MemoryType = GMT_ME; + buf += 2; + } + else + if (!strncmp(buf, "A;", 2)) + { + entry->MemoryType = GMT_SM; + buf += 2; + } + else + if (!strncmp(buf, "ME;", 3)) + { + entry->MemoryType = GMT_ME; + buf += 3; + } + else + if (!strncmp(buf, "SM;", 3)) + { + entry->MemoryType = GMT_SM; + buf += 3; + } + else + return FALSE; + + len = strlen (buf); + while (i < len && i < 4 && buf[i] != ';') + { + s_num[i] = buf[i]; + i++; + } + s_num[i] = '\0'; + if (buf[i] != ';') + return FALSE; + if (i >= len) + return FALSE; + buf += (i + 1); + i = 0; + + *num = strtol (s_num, &endptr, 10); + if (s_num == endptr) + return FALSE; + if (*num == LONG_MIN || *num == LONG_MAX) + return FALSE; + + + if ( *buf == '\n' || *buf == '\r') /* for compatibility with NCDS */ + entry->Group = 5; + else + { + len = strlen (buf); + while (i < len && i < 4 && buf[i] != ';') + { + s_num[i] = buf[i]; + i++; + } + s_num[i] = '\0'; + if (buf[i] != ';') + return FALSE; + if (i >= len) + return FALSE; + + entry->Group = strtol (s_num, &endptr, 10); + if (s_num == endptr) + return FALSE; + if (entry->Group == LONG_MIN || entry->Group == LONG_MAX) + return FALSE; + if (entry->Group < 0 || entry->Group > 5) + return FALSE; + + buf += (i + 1); + i = 0; + + /* Ext Pbk Support */ + + while (*buf!='\n') + { + entry->SubEntries[entry->SubEntriesCount].EntryType=GSM_Number; + len = strlen (buf); + while (i < len && i < 4 && buf[i] != ';') + { + s_num[i] = buf[i]; + i++; + } + s_num[i] = '\0'; + if (buf[i] != ';') + return FALSE; + if (i >= len) + return FALSE; + entry->SubEntries[entry->SubEntriesCount].NumberType=(GSM_NumberType)strtol (s_num, &endptr, 10); + if (s_num == endptr) + return FALSE; + buf += (i + 1); + i = 0; + len = strlen (buf); + while (i < len && i < GSM_MAX_PHONEBOOK_TEXT_LENGTH && buf[i] != ';') + { + entry->SubEntries[entry->SubEntriesCount].data.Number[i] = buf[i]; + i++; + } + entry->SubEntries[entry->SubEntriesCount].data.Number[i] = '\0'; + buf += (i + 1); + i = 0; + if (i >= len) + return FALSE; + entry->SubEntriesCount++; + } + } + + return TRUE; +} + + +static void OkImportDialog (GtkWidget *w, GtkFileSelection *fs) +{ + FILE *f; + PhoneEvent *e; + D_MemoryStatus *ms; + PhonebookEntry *pbEntry; + GSM_PhonebookEntry gsmEntry; + gchar buf[IO_BUF_LEN]; + gchar *fileName; + gint i; + + fileName = gtk_file_selection_get_filename (GTK_FILE_SELECTION (fs)); + gtk_widget_hide (GTK_WIDGET (fs)); + + if ((f = fopen (fileName, "r")) == NULL) + { + g_snprintf (buf, IO_BUF_LEN, _("Can't open file %s for reading!"), fileName); + gtk_label_set_text (GTK_LABEL(errorDialog.text), buf); + gtk_widget_show (errorDialog.dialog); + return; + } + + if (contactsMemoryInitialized == TRUE) + { + for(i = 0; i < memoryStatus.MaxME + memoryStatus.MaxSM; i++) + { + pbEntry = g_ptr_array_index(contactsMemory, i); + g_free(pbEntry); + } + g_ptr_array_free (contactsMemory, TRUE); + contactsMemory = NULL; + gtk_clist_clear (GTK_CLIST (clist)); + contactsMemoryInitialized = FALSE; + memoryStatus.MaxME = memoryStatus.UsedME = memoryStatus.FreeME = + memoryStatus.MaxSM = memoryStatus.UsedSM = memoryStatus.FreeSM = 0; + statusInfo.ch_ME = statusInfo.ch_SM = 0; + RefreshStatusInfo (); + } + + ms = (D_MemoryStatus *) g_malloc (sizeof (D_MemoryStatus)); + ms->memoryStatus.MemoryType = GMT_ME; + e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent)); + e->event = Event_GetMemoryStatus; + e->data = ms; + GUI_InsertEvent (e); + pthread_mutex_lock (&memoryMutex); + pthread_cond_wait (&memoryCond, &memoryMutex); + pthread_mutex_unlock (&memoryMutex); + + if (ms->status != GE_NONE) + /* Phone don't support ME (5110) */ + memoryStatus.MaxME = memoryStatus.UsedME = memoryStatus.FreeME = 0; + else + { + memoryStatus.MaxME = ms->memoryStatus.Used + ms->memoryStatus.Free; + memoryStatus.UsedME = 0; + memoryStatus.FreeME = memoryStatus.MaxME; + } + + ms->memoryStatus.MemoryType = GMT_SM; + e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent)); + e->event = Event_GetMemoryStatus; + e->data = ms; + GUI_InsertEvent (e); + pthread_mutex_lock (&memoryMutex); + pthread_cond_wait (&memoryCond, &memoryMutex); + pthread_mutex_unlock (&memoryMutex); + + if (ms->status != GE_NONE) + { + gtk_label_set_text (GTK_LABEL (errorDialog.text), _("Can't get SM memory status!\n\n\ +Setting max SIM entries set to 100!\n")); + memoryStatus.MaxSM = memoryStatus.FreeSM = 100; + memoryStatus.UsedSM = 0; + gtk_widget_show (errorDialog.dialog); + } + else + { + memoryStatus.MaxSM = ms->memoryStatus.Used + ms->memoryStatus.Free; + memoryStatus.UsedSM = 0; + memoryStatus.FreeSM = memoryStatus.MaxSM; + } + g_free (ms); + + statusInfo.ch_ME = statusInfo.ch_SM = 0; + + RefreshStatusInfo (); + + contactsMemory = g_ptr_array_new (); + + for (i = 1; i <= memoryStatus.MaxME; i++) + { + if ((pbEntry = (PhonebookEntry *) g_malloc (sizeof (PhonebookEntry))) == NULL) + { + fclose (f); + g_print (_("%s: line %d: Can't allocate memory!\n"), __FILE__, __LINE__); + g_ptr_array_free (contactsMemory, TRUE); + return; + } + + pbEntry->entry.Empty = FALSE; + pbEntry->entry.Name[0] = '\0'; + pbEntry->entry.Number[0] = '\0'; + pbEntry->entry.MemoryType = GMT_ME; + pbEntry->entry.Group = 5; + pbEntry->status = E_Deleted; /* I must set status to E_Deleted, since I */ + /* I want clear empty entries when saving to */ + /* to phone */ + pbEntry->entry.SubEntriesCount=0; + + g_ptr_array_add (contactsMemory, (gpointer) pbEntry); + pbEntry = NULL; + } + + for (i = 1; i <= memoryStatus.MaxSM; i++) + { + if ((pbEntry = (PhonebookEntry *) g_malloc (sizeof (PhonebookEntry))) == NULL) + { + fclose (f); + g_print (_("%s: line %d: Can't allocate memory!\n"), __FILE__, __LINE__); + g_ptr_array_free (contactsMemory, TRUE); + return; + } + + pbEntry->entry.Empty = FALSE; + pbEntry->entry.Name[0] = '\0'; + pbEntry->entry.Number[0] = '\0'; + pbEntry->entry.MemoryType = GMT_SM; + pbEntry->entry.Group = 5; + pbEntry->status = E_Deleted; + pbEntry->entry.SubEntriesCount=0; + + g_ptr_array_add (contactsMemory, (gpointer) pbEntry); + pbEntry = NULL; + } + + + while (fgets (buf, IO_BUF_LEN, f)) + { + if (ParseLine (&gsmEntry, &i, buf)) + { + if (gsmEntry.MemoryType == GMT_ME && memoryStatus.FreeME > 0 + && i > 0 && i <= memoryStatus.MaxME) + { + pbEntry = g_ptr_array_index (contactsMemory, i - 1); + + if (pbEntry->status == E_Deleted) + { + pbEntry->entry = gsmEntry; + pbEntry->status = E_Changed; + memoryStatus.UsedME++; + memoryStatus.FreeME--; + statusInfo.ch_ME = 1; + } + } + else if (gsmEntry.MemoryType == GMT_SM && memoryStatus.FreeSM > 0 + && i > 0 && i <= memoryStatus.MaxSM) + { + pbEntry = g_ptr_array_index (contactsMemory, memoryStatus.MaxME + i - 1); + + if (pbEntry->status == E_Deleted) + { + pbEntry->entry = gsmEntry; + pbEntry->status = E_Changed; + memoryStatus.UsedSM++; + memoryStatus.FreeSM--; + statusInfo.ch_SM = 1; + } + } + } + } + + contactsMemoryInitialized = TRUE; + RefreshStatusInfo (); + GUIEventSend (GUI_EVENT_CONTACTS_CHANGED); + GUIEventSend (GUI_EVENT_SMS_NUMBER_CHANGED); +} + + +static void ImportContactsFileDialog () +{ + static GtkWidget *fileDialog = NULL; + + if (fileDialog == NULL) + { + fileDialog = gtk_file_selection_new (_("Import")); + gtk_signal_connect (GTK_OBJECT (fileDialog), "delete_event", + GTK_SIGNAL_FUNC (DeleteEvent), NULL); + gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (fileDialog)->ok_button), + "clicked", GTK_SIGNAL_FUNC (OkImportDialog), (gpointer) fileDialog); + gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (fileDialog)->cancel_button), + "clicked", GTK_SIGNAL_FUNC (CancelDialog), (gpointer) fileDialog); + } + + gtk_widget_show (fileDialog); +} + + +static void ImportSaveCallback (GtkWidget *widget, gpointer data) +{ + gtk_widget_hide (GTK_WIDGET (data)); + SaveContacts (); + ImportContactsFileDialog (); +} + + +static void ImportDontSaveCallback (GtkWidget *widget, gpointer data) +{ + gtk_widget_hide (GTK_WIDGET (data)); + ImportContactsFileDialog (); +} + + +void static ImportSaveContacts (void) +{ + static GtkWidget *dialog = NULL; + + if (dialog == NULL) + dialog = CreateSaveQuestionDialog (ImportSaveCallback, ImportDontSaveCallback); + + gtk_widget_show (dialog); +} + + +static void ImportContacts (void) +{ + if (contactsMemoryInitialized == TRUE && (statusInfo.ch_ME || statusInfo.ch_SM)) + ImportSaveContacts (); + else + ImportContactsFileDialog (); +} + + +static void QuitSaveCallback (GtkWidget *widget, gpointer data) +{ + PhoneEvent *e; + + gtk_widget_hide (GTK_WIDGET (data)); + SaveContacts (); + e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent)); + e->event = Event_Exit; + e->data = NULL; + GUI_InsertEvent (e); + pthread_join (monitor_th, NULL); + gtk_main_quit (); +} + + +static void QuitDontSaveCallback (GtkWidget *widget, gpointer data) +{ + PhoneEvent *e; + + gtk_widget_hide (GTK_WIDGET (data)); + e = (PhoneEvent *) g_malloc (sizeof (PhoneEvent)); + e->event = Event_Exit; + e->data = NULL; + GUI_InsertEvent (e); + pthread_join (monitor_th, NULL); + gtk_main_quit (); +} + + +void GUI_QuitSaveContacts (void) +{ + static GtkWidget *dialog = NULL; + + if (dialog == NULL) + dialog = CreateSaveQuestionDialog (QuitSaveCallback, QuitDontSaveCallback); + + gtk_widget_show (dialog); +} + + +/* Function take number and return name belonged to number. + If no name is found, return NULL; + Do not modify returned name! +*/ +gchar *GUI_GetName (gchar *number) +{ + PhonebookEntry *pbEntry; + register gint i; + + if (contactsMemoryInitialized == FALSE || number == NULL) + return (gchar *)NULL; + + for(i = 0; i < memoryStatus.MaxME + memoryStatus.MaxSM; i++) + { + pbEntry = g_ptr_array_index (contactsMemory, i); + + if (pbEntry->status == E_Empty || pbEntry->status == E_Deleted) + continue; + + if (strcmp (pbEntry->entry.Number, number) == 0) + return pbEntry->entry.Name; + } + + for (i = 0; i < memoryStatus.MaxME + memoryStatus.MaxSM; i++) + { + pbEntry = g_ptr_array_index (contactsMemory, i); + + if (pbEntry->status == E_Empty || pbEntry->status == E_Deleted) + continue; + + if (strrncmp (pbEntry->entry.Number, number, 9) == 0) + return pbEntry->entry.Name; + } + + return NULL; +} + + +gchar *GUI_GetNameExact (gchar *number) +{ + PhonebookEntry *pbEntry; + register gint i; + + if (contactsMemoryInitialized == FALSE || number == NULL) + return (gchar *)NULL; + + for(i = 0; i < memoryStatus.MaxME + memoryStatus.MaxSM; i++) + { + pbEntry = g_ptr_array_index (contactsMemory, i); + + if (pbEntry->status == E_Empty || pbEntry->status == E_Deleted) + continue; + + if (strcmp (pbEntry->entry.Number, number) == 0) + return pbEntry->entry.Name; + } + + return NULL; +} + + +gchar *GUI_GetNumber (gchar *name) +{ + PhonebookEntry *pbEntry; + register gint i; + + if (contactsMemoryInitialized == FALSE || name == NULL || *name == '\0') + return (gchar *)NULL; + + for(i = 0; i < memoryStatus.MaxME + memoryStatus.MaxSM; i++) + { + pbEntry = g_ptr_array_index (contactsMemory, i); + + if (pbEntry->status == E_Empty || pbEntry->status == E_Deleted) + continue; + + if (strcmp (pbEntry->entry.Name, name) == 0) + return pbEntry->entry.Number; + } + + return NULL; +} + + +static void SelectDialogClickEntry (GtkWidget *clist, + gint row, + gint column, + GdkEventButton *event, + SelectContactData *data ) +{ + if(event && event->type == GDK_2BUTTON_PRESS) + gtk_signal_emit_by_name(GTK_OBJECT (data->okButton), "clicked"); +} + + +SelectContactData *GUI_SelectContactDialog (void) +{ + PhonebookEntry *pbEntry; + static SelectContactData selectContactData; + SortColumn *sColumn; + gchar *titles[4] = { "Name", "Number", "Memory", "Group"}; + gint row_i = 0; + register gint i; + gchar string[100]; + + if (contactsMemoryInitialized == FALSE) + return NULL; + + selectContactData.dialog = gtk_dialog_new (); + gtk_widget_set_usize (GTK_WIDGET (selectContactData.dialog), 436, 200); + gtk_window_set_title (GTK_WINDOW (selectContactData.dialog), _("Select contacts")); + gtk_window_set_modal (GTK_WINDOW (selectContactData.dialog), TRUE); + + selectContactData.okButton = gtk_button_new_with_label (_("Ok")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (selectContactData.dialog)->action_area), + selectContactData.okButton, TRUE, TRUE, 10); + GTK_WIDGET_SET_FLAGS (selectContactData.okButton, GTK_CAN_DEFAULT); + gtk_widget_grab_default (selectContactData.okButton); + gtk_widget_show (selectContactData.okButton); + + selectContactData.cancelButton = gtk_button_new_with_label (_("Cancel")); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (selectContactData.dialog)->action_area), + selectContactData.cancelButton, TRUE, TRUE, 10); + gtk_widget_show (selectContactData.cancelButton); + + selectContactData.clist = gtk_clist_new_with_titles (4, titles); + gtk_clist_set_shadow_type (GTK_CLIST (selectContactData.clist), GTK_SHADOW_OUT); + gtk_clist_set_compare_func (GTK_CLIST (selectContactData.clist), CListCompareFunc); + gtk_clist_set_sort_column (GTK_CLIST (selectContactData.clist), 0); + gtk_clist_set_sort_type (GTK_CLIST (selectContactData.clist), GTK_SORT_ASCENDING); + gtk_clist_set_auto_sort (GTK_CLIST (selectContactData.clist), FALSE); + gtk_clist_set_selection_mode (GTK_CLIST (selectContactData.clist), GTK_SELECTION_EXTENDED); + + gtk_clist_set_column_width (GTK_CLIST(selectContactData.clist), 0, 150); + gtk_clist_set_column_width (GTK_CLIST(selectContactData.clist), 1, 115); + gtk_clist_set_column_width (GTK_CLIST(selectContactData.clist), 3, 70); + gtk_clist_set_column_justification (GTK_CLIST(selectContactData.clist), 2, GTK_JUSTIFY_CENTER); + gtk_clist_set_column_visibility (GTK_CLIST(selectContactData.clist), 3, (GetModelFeature(FN_CALLERGROUPS)!=0)); + + for (i = 0; i < 4; i++) + { + if ((sColumn = g_malloc (sizeof (SortColumn))) == NULL) + { + g_print (_("Error: %s: line %d: Can't allocate memory!\n"), __FILE__, __LINE__); + return NULL; + } + sColumn->clist = selectContactData.clist; + sColumn->column = i; + gtk_signal_connect (GTK_OBJECT (GTK_CLIST (selectContactData.clist)->column[i].button), "clicked", + GTK_SIGNAL_FUNC (SetSortColumn), (gpointer) sColumn); + } + + gtk_signal_connect (GTK_OBJECT (selectContactData.clist), "select_row", + GTK_SIGNAL_FUNC (SelectDialogClickEntry), + (gpointer) &selectContactData); + + selectContactData.clistScrolledWindow = gtk_scrolled_window_new (NULL, NULL); + gtk_container_add (GTK_CONTAINER (selectContactData.clistScrolledWindow), + selectContactData.clist); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (selectContactData.clistScrolledWindow), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (selectContactData.dialog)->vbox), + selectContactData.clistScrolledWindow, + TRUE, TRUE, 0); + + gtk_widget_show (selectContactData.clist); + gtk_widget_show (selectContactData.clistScrolledWindow); + + if (xgnokiiConfig.callerGroups[0] == NULL) + GUI_InitCallerGroupsInf (); + + gtk_clist_freeze (GTK_CLIST (selectContactData.clist)); + for (i = 0; i < memoryStatus.MaxME + memoryStatus.MaxSM; i++) + { + gchar *row[4]; + + pbEntry = g_ptr_array_index (contactsMemory, i); + if (pbEntry->status != E_Empty && pbEntry->status != E_Deleted) + { + row[0] = pbEntry->entry.Name; + + if (pbEntry->entry.SubEntriesCount>0) { + snprintf(string,100,"%s *",pbEntry->entry.Number); + row[1]=string; + } else row[1] = pbEntry->entry.Number; + + + if (pbEntry->entry.MemoryType == GMT_ME) + row[2] = "P"; + else + row[2] = "S"; + if (GetModelFeature(FN_CALLERGROUPS)!=0) + row[3] = xgnokiiConfig.callerGroups[pbEntry->entry.Group]; + else + row[3] = ""; + gtk_clist_append (GTK_CLIST (selectContactData.clist), row); + if (pbEntry->entry.MemoryType == GMT_ME) + gtk_clist_set_pixmap (GTK_CLIST (selectContactData.clist), row_i, 2, + memoryPixmaps.phoneMemPix, memoryPixmaps.mask); + else + gtk_clist_set_pixmap (GTK_CLIST (selectContactData.clist), row_i, 2, + memoryPixmaps.simMemPix, memoryPixmaps.mask); + + gtk_clist_set_row_data (GTK_CLIST (selectContactData.clist), row_i++, (gpointer) pbEntry); + } + } + + gtk_clist_sort (GTK_CLIST (selectContactData.clist)); + gtk_clist_thaw (GTK_CLIST (selectContactData.clist)); + + gtk_widget_show (selectContactData.dialog); + + return &selectContactData; +} + + +static GtkItemFactoryEntry menu_items[] = { + { NULL, NULL, NULL, 0, ""}, + { NULL, "R", ReadContacts, 0, NULL}, + { NULL, "S", SaveContacts, 0, NULL}, + { NULL, NULL, NULL, 0, ""}, + { NULL, "I", ImportContacts, 0, NULL}, + { NULL, "E", ExportContacts, 0, NULL}, + { NULL, NULL, NULL, 0, ""}, + { NULL, "W", CloseContacts, 0, NULL}, + { NULL, NULL, NULL, 0, ""}, + { NULL, "N", NewEntry, 0, NULL}, + { NULL, "U", DuplicateEntry, 0, NULL}, + { NULL, NULL, EditEntry, 0, NULL}, + { NULL, "D", DeleteEntry, 0, NULL}, + { NULL, NULL, NULL, 0, ""}, + { NULL, "C", ChMemType, 0, NULL}, + { NULL, NULL, NULL, 0, ""}, + { NULL, "F", FindFirstEntry, 0, NULL}, + { NULL, "L", SearchEntry, 0, NULL}, + { NULL, NULL, NULL, 0, ""}, + { NULL, "A", SelectAll, 0, NULL}, + { NULL, NULL, NULL, 0, ""}, + { NULL, "V", DialVoice, 0, NULL}, + { NULL, NULL, NULL, 0, ""}, + { NULL, NULL, Help1, 0, NULL}, + { NULL, NULL, GUI_ShowAbout, 0, NULL}, +}; + + +static void InitMainMenu (void) +{ + menu_items[0].path = g_strdup (_("/_File")); + menu_items[1].path = g_strdup (_("/File/_Read from phone")); + menu_items[2].path = g_strdup (_("/File/_Save to phone")); + menu_items[3].path = g_strdup (_("/File/Sep1")); + menu_items[4].path = g_strdup (_("/File/_Import from file")); + menu_items[5].path = g_strdup (_("/File/_Export to file")); + menu_items[6].path = g_strdup (_("/File/Sep2")); + menu_items[7].path = g_strdup (_("/File/_Close")); + menu_items[8].path = g_strdup (_("/_Edit")); + menu_items[9].path = g_strdup (_("/Edit/_New")); + menu_items[10].path = g_strdup (_("/Edit/D_uplicate")); + menu_items[11].path = g_strdup (_("/Edit/_Edit")); + menu_items[12].path = g_strdup (_("/Edit/_Delete")); + menu_items[13].path = g_strdup (_("/Edit/Sep3")); + menu_items[14].path = g_strdup (_("/Edit/_Change memory type")); + menu_items[15].path = g_strdup (_("/Edit/Sep4")); + menu_items[16].path = g_strdup (_("/Edit/_Find")); + menu_items[17].path = g_strdup (_("/Edit/Find ne_xt")); + menu_items[18].path = g_strdup (_("/Edit/Sep5")); + menu_items[19].path = g_strdup (_("/Edit/Select _all")); + menu_items[20].path = g_strdup (_("/_Dial")); + menu_items[21].path = g_strdup (_("/Dial/Dial _voice")); + menu_items[22].path = g_strdup (_("/_Help")); + menu_items[23].path = g_strdup (_("/Help/_Help")); + menu_items[24].path = g_strdup (_("/Help/_About")); +} + + +void GUI_CreateContactsWindow (void) +{ + int nmenu_items = sizeof (menu_items) / sizeof (menu_items[0]); + GtkItemFactory *item_factory; + GtkAccelGroup *accel_group; + SortColumn *sColumn; + GtkWidget *menubar; + GtkWidget *main_vbox; + GtkWidget *toolbar; + GtkWidget *clistScrolledWindow; + GtkWidget *status_hbox; + register gint i; + gchar *titles[4] = { _("Name"), _("Number"), _("Memory"), _("Group")}; + + InitMainMenu (); + contactsMemoryInitialized = FALSE; + GUI_ContactsWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_window_set_title (GTK_WINDOW (GUI_ContactsWindow), _("Contacts")); + gtk_widget_set_usize (GTK_WIDGET (GUI_ContactsWindow), 436, 220); + //gtk_container_set_border_width (GTK_CONTAINER (GUI_ContactsWindow), 10); + gtk_signal_connect (GTK_OBJECT (GUI_ContactsWindow), "delete_event", + GTK_SIGNAL_FUNC (DeleteEvent), NULL); + gtk_widget_realize (GUI_ContactsWindow); + + accel_group = gtk_accel_group_new (); + item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "
", + accel_group); + + gtk_item_factory_create_items (item_factory, nmenu_items, menu_items, NULL); + + gtk_accel_group_attach (accel_group, GTK_OBJECT (GUI_ContactsWindow)); + + /* Finally, return the actual menu bar created by the item factory. */ + menubar = gtk_item_factory_get_widget (item_factory, "
"); + + main_vbox = gtk_vbox_new (FALSE, 1); + gtk_container_border_width (GTK_CONTAINER (main_vbox), 1); + gtk_container_add (GTK_CONTAINER (GUI_ContactsWindow), main_vbox); + gtk_widget_show (main_vbox); + + gtk_box_pack_start (GTK_BOX (main_vbox), menubar, FALSE, FALSE, 0); + gtk_widget_show (menubar); + + /* Create the toolbar */ + + toolbar = gtk_toolbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS); + gtk_toolbar_set_button_relief (GTK_TOOLBAR (toolbar), GTK_RELIEF_NORMAL); + + gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Read from phone"), NULL, + NewPixmap(Read_xpm, GUI_ContactsWindow->window, + &GUI_ContactsWindow->style->bg[GTK_STATE_NORMAL]), + (GtkSignalFunc) ReadContacts, NULL); + gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Save to phone"), NULL, + NewPixmap(Send_xpm, GUI_ContactsWindow->window, + &GUI_ContactsWindow->style->bg[GTK_STATE_NORMAL]), + (GtkSignalFunc) SaveContacts, NULL); + + gtk_toolbar_append_space (GTK_TOOLBAR (toolbar)); + + gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Import from file"), NULL, + NewPixmap(Open_xpm, GUI_ContactsWindow->window, + &GUI_ContactsWindow->style->bg[GTK_STATE_NORMAL]), + (GtkSignalFunc) ImportContacts, NULL); + gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Export to file"), NULL, + NewPixmap(Save_xpm, GUI_ContactsWindow->window, + &GUI_ContactsWindow->style->bg[GTK_STATE_NORMAL]), + (GtkSignalFunc) ExportContacts, NULL); + + gtk_toolbar_append_space (GTK_TOOLBAR (toolbar)); + + gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("New entry"), NULL, + NewPixmap(New_xpm, GUI_ContactsWindow->window, + &GUI_ContactsWindow->style->bg[GTK_STATE_NORMAL]), + (GtkSignalFunc) NewEntry, NULL); + gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Duplicate entry"), NULL, + NewPixmap(Duplicate_xpm, GUI_ContactsWindow->window, + &GUI_ContactsWindow->style->bg[GTK_STATE_NORMAL]), + (GtkSignalFunc) DuplicateEntry, NULL); + gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Edit entry"), NULL, + NewPixmap(Edit_xpm, GUI_ContactsWindow->window, + &GUI_ContactsWindow->style->bg[GTK_STATE_NORMAL]), + (GtkSignalFunc) EditEntry, NULL); + gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Delete entry"), NULL, + NewPixmap(Delete_xpm, GUI_ContactsWindow->window, + &GUI_ContactsWindow->style->bg[GTK_STATE_NORMAL]), + (GtkSignalFunc) DeleteEntry, NULL); + + gtk_toolbar_append_space (GTK_TOOLBAR(toolbar)); + + gtk_toolbar_append_item (GTK_TOOLBAR (toolbar), NULL, _("Dial voice"), NULL, + NewPixmap(Dial_xpm, GUI_ContactsWindow->window, + &GUI_ContactsWindow->style->bg[GTK_STATE_NORMAL]), + (GtkSignalFunc) DialVoice, NULL); + +// gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS); + + gtk_box_pack_start (GTK_BOX (main_vbox), toolbar, FALSE, FALSE, 0); + gtk_widget_show (toolbar); + + + clist = gtk_clist_new_with_titles (4, titles); + gtk_clist_set_shadow_type (GTK_CLIST (clist), GTK_SHADOW_OUT); + gtk_clist_set_compare_func (GTK_CLIST (clist), CListCompareFunc); + gtk_clist_set_sort_column (GTK_CLIST (clist), 0); + gtk_clist_set_sort_type (GTK_CLIST (clist), GTK_SORT_ASCENDING); + gtk_clist_set_auto_sort (GTK_CLIST (clist), FALSE); + gtk_clist_set_selection_mode (GTK_CLIST (clist), GTK_SELECTION_EXTENDED); + + gtk_clist_set_column_width (GTK_CLIST (clist), 0, 150); + gtk_clist_set_column_width (GTK_CLIST (clist), 1, 115); + gtk_clist_set_column_width (GTK_CLIST (clist), 3, 70); + gtk_clist_set_column_justification (GTK_CLIST (clist), 2, GTK_JUSTIFY_CENTER); +// gtk_clist_set_column_visibility (GTK_CLIST (clist), 3, (GetModelFeature(FN_CALLERGROUPS)!=0)); + + for (i = 0; i < 4; i++) + { + if ((sColumn = g_malloc (sizeof (SortColumn))) == NULL) + { + g_print (_("Error: %s: line %d: Can't allocate memory!\n"), __FILE__, __LINE__); + gtk_main_quit (); + } + sColumn->clist = clist; + sColumn->column = i; + gtk_signal_connect (GTK_OBJECT (GTK_CLIST (clist)->column[i].button), "clicked", + GTK_SIGNAL_FUNC (SetSortColumn), (gpointer) sColumn); + } + + gtk_signal_connect (GTK_OBJECT (clist), "select_row", + GTK_SIGNAL_FUNC (ClickEntry), NULL); + + clistScrolledWindow = gtk_scrolled_window_new (NULL, NULL); + gtk_container_add (GTK_CONTAINER (clistScrolledWindow), clist); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (clistScrolledWindow), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_box_pack_start (GTK_BOX (main_vbox), clistScrolledWindow, + TRUE, TRUE, 0); + + gtk_widget_show (clist); + gtk_widget_show (clistScrolledWindow); + + status_hbox = gtk_hbox_new (FALSE,20); + gtk_box_pack_start (GTK_BOX (main_vbox), status_hbox, FALSE, FALSE, 0); + gtk_widget_show (status_hbox); + + memoryStatus.MaxME = memoryStatus.UsedME = memoryStatus.FreeME = + memoryStatus.MaxSM = memoryStatus.UsedSM = memoryStatus.FreeSM = 0; + statusInfo.ch_ME = statusInfo.ch_SM = 0; + + statusInfo.label = gtk_label_new (""); + RefreshStatusInfo (); + gtk_box_pack_start (GTK_BOX (status_hbox), statusInfo.label, FALSE, FALSE, 10); + gtk_widget_show (statusInfo.label); + + memoryPixmaps.simMemPix = gdk_pixmap_create_from_xpm_d (GUI_ContactsWindow->window, + &memoryPixmaps.mask, + &GUI_ContactsWindow->style->bg[GTK_STATE_NORMAL], + sim_xpm); + + memoryPixmaps.phoneMemPix = gdk_pixmap_create_from_xpm_d (GUI_ContactsWindow->window, + &memoryPixmaps.mask, + &GUI_ContactsWindow->style->bg[GTK_STATE_NORMAL], + phone_xpm); + + questMark.pixmap = gdk_pixmap_create_from_xpm_d (GUI_ContactsWindow->window, + &questMark.mask, + &GUI_ContactsWindow->style->bg[GTK_STATE_NORMAL], + quest_xpm); + + CreateErrorDialog (&errorDialog, GUI_ContactsWindow); + GUIEventAdd (GUI_EVENT_CONTACTS_CHANGED, GUI_RefreshContacts); + GUIEventAdd (GUI_EVENT_CALLERS_GROUPS_CHANGED, GUI_RefreshGroupMenu); +} +