diff --git a/src/callbacks.c b/src/callbacks.c index d8c4598..e2206a2 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -193,7 +193,7 @@ void on_phone_contacts_delete(gpointer data) { Phone * phone = data; - /* FIXME implement */ + phone_contacts_delete_selected(phone); } @@ -202,7 +202,16 @@ void on_phone_contacts_edit(gpointer data) { Phone * phone = data; - /* FIXME implement */ + phone_contacts_edit_selected(phone); +} + + +/* on_phone_contacts_new */ +void on_phone_contacts_new(gpointer data) +{ + Phone * phone = data; + + phone_contacts_new(phone); } diff --git a/src/callbacks.h b/src/callbacks.h index eda44dd..72f2c4a 100644 --- a/src/callbacks.h +++ b/src/callbacks.h @@ -44,6 +44,7 @@ void on_phone_code_leave(gpointer data); void on_phone_contacts_call(gpointer data); void on_phone_contacts_delete(gpointer data); void on_phone_contacts_edit(gpointer data); +void on_phone_contacts_new(gpointer data); void on_phone_contacts_show(gpointer data); void on_phone_contacts_write(gpointer data); diff --git a/src/gsm.c b/src/gsm.c index 965e485..3a2d1c0 100644 --- a/src/gsm.c +++ b/src/gsm.c @@ -600,6 +600,29 @@ void gsm_callback_on_message_deleted(GSM * gsm) } +/* gsm_contact_delete */ +int gsm_contact_delete(GSM * gsm, unsigned int index) +{ + /* FIXME implement */ + return 1; +} + + +/* gsm_contact_edit */ +int gsm_contact_edit(GSM * gsm, unsigned int index, char const * name, + char const * number) +{ + return gsm_modem_contact_edit(gsm->modem, index, name, number); +} + + +/* gsm_contact_new */ +int gsm_contact_new(GSM * gsm, char const * name, char const * number) +{ + return gsm_modem_contact_new(gsm->modem, name, number); +} + + /* gsm_enter_sim_pin */ int gsm_enter_sim_pin(GSM * gsm, char const * code) { diff --git a/src/gsm.h b/src/gsm.h index 628fffe..700a83b 100644 --- a/src/gsm.h +++ b/src/gsm.h @@ -57,8 +57,10 @@ typedef enum _GSMError GSM_ERROR_BUSY, GSM_ERROR_CALL_FAILED, GSM_ERROR_CALL_WAITING_FAILED, + GSM_ERROR_CONTACT_EDIT_FAILED, GSM_ERROR_CONTACT_FETCH_FAILED, GSM_ERROR_CONTACT_LIST_FAILED, + GSM_ERROR_CONTACT_NEW_FAILED, GSM_ERROR_FUNCTIONAL_FAILED, GSM_ERROR_HANGUP_FAILED, GSM_ERROR_MESSAGE_DELETE_FAILED, @@ -384,6 +386,12 @@ int gsm_call_reject(GSM * gsm); /* callbacks */ void gsm_callback_on_message_deleted(GSM * gsm); +/* contacts */ +int gsm_contact_delete(GSM * gsm, unsigned int index); +int gsm_contact_edit(GSM * gsm, unsigned int index, char const * name, + char const * number); +int gsm_contact_new(GSM * gsm, char const * name, char const * number); + int gsm_enter_sim_pin(GSM * gsm, char const * code); /* event */ diff --git a/src/modem.c b/src/modem.c index 7ed30a1..9ad2216 100644 --- a/src/modem.c +++ b/src/modem.c @@ -199,6 +199,52 @@ static void _modem_call_reject_callback(GSM * gsm) } +/* gsm_modem_contact_edit */ +int gsm_modem_contact_edit(GSMModem * gsmm, unsigned int index, + char const * name, char const * number) +{ + int ret; + char const cmd[] = "AT+CPBW="; + size_t len; + char * buf; + + if(name == NULL || number == NULL) + return gsm_event(gsmm->gsm, GSM_EVENT_TYPE_ERROR, + GSM_ERROR_CONTACT_EDIT_FAILED, NULL); + len = sizeof(cmd) + 11 + 1 + strlen(name) + 1 + strlen(number); + if((buf = malloc(len)) == NULL) + return 1; + snprintf(buf, len, "%s%u,%s,%s", cmd, index, name, number); + ret = gsm_queue_with_error(gsmm->gsm, buf, + GSM_ERROR_CONTACT_EDIT_FAILED); + free(buf); + return ret; +} + + +/* gsm_modem_contact_new */ +int gsm_modem_contact_new(GSMModem * gsmm, char const * name, + char const * number) +{ + int ret; + char const cmd[] = "AT+CPBW="; + size_t len; + char * buf; + + if(name == NULL || number == NULL) + return gsm_event(gsmm->gsm, GSM_EVENT_TYPE_ERROR, + GSM_ERROR_CONTACT_NEW_FAILED, NULL); + len = sizeof(cmd) + 1 + strlen(name) + 1 + strlen(number); + if((buf = malloc(len)) == NULL) + return 1; + snprintf(buf, len, "%s,%s,%s", cmd, name, number); + ret = gsm_queue_with_error(gsmm->gsm, buf, + GSM_ERROR_CONTACT_NEW_FAILED); + free(buf); + return ret; +} + + /* gsm_modem_enter_sim_pin */ static void _modem_enter_sim_pin_callback(GSM * gsm); diff --git a/src/modem.h b/src/modem.h index 5dbebb1..465ff97 100644 --- a/src/modem.h +++ b/src/modem.h @@ -56,6 +56,11 @@ int gsm_modem_call_hangup(GSMModem * gsmm); int gsm_modem_call_last(GSMModem * gsmm, GSMCallType calltype); int gsm_modem_call_reject(GSMModem * gsmm); +int gsm_modem_contact_edit(GSMModem * gsmm, unsigned int index, + char const * name, char const * number); +int gsm_modem_contact_new(GSMModem * gsmm, char const * name, + char const * number); + int gsm_modem_enter_sim_pin(GSMModem * gsmm, char const * code); int gsm_modem_get_battery_charge(GSMModem * gsmm); diff --git a/src/phone.c b/src/phone.c index 85b4c8d..5c8ffcd 100644 --- a/src/phone.c +++ b/src/phone.c @@ -144,6 +144,11 @@ struct _Phone GtkWidget * co_window; GtkListStore * co_store; GtkWidget * co_view; + /* dialog */ + int co_index; + GtkWidget * co_dialog; + GtkWidget * co_name; + GtkWidget * co_number; #ifdef DEBUG /* debugging */ @@ -226,6 +231,9 @@ static int _phone_register_trigger(Phone * phone, PhonePlugin * plugin, static void _phone_set_operator(Phone * phone, char const * operator); static void _phone_set_signal_level(Phone * phone, gdouble level); +static void _phone_show_contacts_dialog(Phone * phone, gboolean show, + int index, char const * name, char const * number); + static void _phone_track(Phone * phone, PhoneTrack what, gboolean track); /* callbacks */ @@ -299,6 +307,7 @@ Phone * phone_new(char const * device, unsigned int baudrate, int retry, phone->co_window = NULL; phone->co_store = gtk_list_store_new(PHONE_CONTACT_COLUMN_COUNT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING); + phone->co_dialog = NULL; #ifdef DEBUG phone->de_window = NULL; #endif @@ -538,6 +547,55 @@ void phone_contacts_call_selected(Phone * phone) } +/* phone_contacts_delete_selected */ +void phone_contacts_delete_selected(Phone * phone) +{ + GtkTreeSelection * treesel; + GtkTreeIter iter; + int index; + + if((treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW( + phone->co_view))) == NULL) + return; + if(gtk_tree_selection_get_selected(treesel, NULL, &iter) != TRUE) + return; + gtk_tree_model_get(GTK_TREE_MODEL(phone->co_store), &iter, + PHONE_CONTACT_COLUMN_ID, &index, -1); + /* FIXME ask for confirmation and implement */ +} + + +/* phone_contacts_edit_selected */ +void phone_contacts_edit_selected(Phone * phone) +{ + GtkTreeSelection * treesel; + GtkTreeIter iter; + int index; + gchar * name; + gchar * number; + + if((treesel = gtk_tree_view_get_selection(GTK_TREE_VIEW( + phone->co_view))) == NULL) + return; + if(gtk_tree_selection_get_selected(treesel, NULL, &iter) != TRUE) + return; + gtk_tree_model_get(GTK_TREE_MODEL(phone->co_store), &iter, + PHONE_CONTACT_COLUMN_ID, &index, + PHONE_CONTACT_COLUMN_NAME, &name, + PHONE_CONTACT_COLUMN_NUMBER, &number, -1); + _phone_show_contacts_dialog(phone, TRUE, index, name, number); + g_free(name); + g_free(number); +} + + +/* phone_contacts_new */ +void phone_contacts_new(Phone * phone) +{ + _phone_show_contacts_dialog(phone, TRUE, -1, NULL, NULL); +} + + /* phone_contacts_set */ void phone_contacts_set(Phone * phone, unsigned int index, char const * name, char const * number) @@ -1195,16 +1253,22 @@ void phone_show_contacts(Phone * phone, gboolean show) g_signal_connect_swapped(G_OBJECT(toolitem), "clicked", G_CALLBACK(on_phone_contacts_call), phone); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); - toolitem = gtk_tool_button_new_from_stock(GTK_STOCK_EDIT); - g_signal_connect_swapped(G_OBJECT(toolitem), "clicked", - G_CALLBACK(on_phone_contacts_edit), phone); - gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); toolitem = gtk_tool_button_new(NULL, _("Write")); gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolitem), "mail-reply-sender"); g_signal_connect_swapped(G_OBJECT(toolitem), "clicked", G_CALLBACK(on_phone_contacts_write), phone); gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); + toolitem = gtk_separator_tool_item_new(); + gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); + toolitem = gtk_tool_button_new_from_stock(GTK_STOCK_NEW); + g_signal_connect_swapped(G_OBJECT(toolitem), "clicked", + G_CALLBACK(on_phone_contacts_new), phone); + gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); + toolitem = gtk_tool_button_new_from_stock(GTK_STOCK_EDIT); + g_signal_connect_swapped(G_OBJECT(toolitem), "clicked", + G_CALLBACK(on_phone_contacts_edit), phone); + gtk_toolbar_insert(GTK_TOOLBAR(widget), toolitem, -1); toolitem = gtk_tool_button_new_from_stock(GTK_STOCK_DELETE); g_signal_connect_swapped(G_OBJECT(toolitem), "clicked", G_CALLBACK(on_phone_contacts_delete), phone); @@ -2306,6 +2370,83 @@ static void _phone_set_status(Phone * phone, GSMStatus status) } +/* phone_show_contacts_dialog */ +static void _on_contacts_dialog_response(GtkWidget * widget, gint response, + gpointer data); + +static void _phone_show_contacts_dialog(Phone * phone, gboolean show, + int index, char const * name, char const * number) +{ + char buf[256]; + GtkDialogFlags f = GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT; + GtkWidget * vbox; + GtkWidget * hbox; + GtkWidget * widget; + + if(phone->co_dialog == NULL) + { + phone->co_dialog = gtk_dialog_new_with_buttons(_("New contact"), + GTK_WINDOW(phone->co_window), f, + GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, + GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); + g_signal_connect(G_OBJECT(phone->co_dialog), "response", + G_CALLBACK(_on_contacts_dialog_response), + phone); + vbox = GTK_DIALOG(phone->co_dialog)->vbox; + hbox = gtk_hbox_new(FALSE, 4); + widget = gtk_label_new(_("Name: ")); + gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); + phone->co_name = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(hbox), phone->co_name, TRUE, TRUE, + 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 4); + hbox = gtk_hbox_new(FALSE, 4); + widget = gtk_label_new(_("Number: ")); + gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, TRUE, 0); + phone->co_number = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(hbox), phone->co_number, TRUE, TRUE, + 0); + gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 4); + gtk_widget_show_all(vbox); + } + if(show == FALSE) + { + gtk_widget_hide(phone->co_dialog); + return; + } + if((phone->co_index = index) >= 0) + { + snprintf(buf, sizeof(buf), "%s%s", _("Edit contact: "), + (name != NULL) ? name : ""); + gtk_window_set_title(GTK_WINDOW(phone->co_dialog), buf); + } + if(name != NULL) + gtk_entry_set_text(GTK_ENTRY(phone->co_name), name); + if(number != NULL) + gtk_entry_set_text(GTK_ENTRY(phone->co_number), number); + gtk_widget_show(phone->co_dialog); +} + +static void _on_contacts_dialog_response(GtkWidget * widget, gint response, + gpointer data) +{ + Phone * phone = data; + char const * name; + char const * number; + + gtk_widget_hide(widget); + if(response != GTK_RESPONSE_ACCEPT) + return; + name = gtk_entry_get_text(GTK_ENTRY(phone->co_name)); + number = gtk_entry_get_text(GTK_ENTRY(phone->co_number)); + /* FIXME also update the GtkListStore */ + if(phone->co_index < 0) + gsm_contact_new(phone->gsm, name, number); + else + gsm_contact_edit(phone->gsm, phone->co_index, name, number); +} + + /* phone_track */ static void _phone_track(Phone * phone, PhoneTrack what, gboolean track) { diff --git a/src/phone.h b/src/phone.h index 2f04d4c..b5cf9e0 100644 --- a/src/phone.h +++ b/src/phone.h @@ -65,6 +65,9 @@ void phone_code_enter(Phone * phone); /* contacts */ void phone_contacts_call_selected(Phone * phone); +void phone_contacts_delete_selected(Phone * phone); +void phone_contacts_edit_selected(Phone * phone); +void phone_contacts_new(Phone * phone); void phone_contacts_set(Phone * phone, unsigned int index, char const * name, char const * number); void phone_contacts_write_selected(Phone * phone);