📄 app.c
字号:
/* * main gsms aplication window * * Authors: Michael Jochum <e9725005@stud3.tuwien.ac.at> * Gerhard Khueny <e9625442@student.tuwien.ac.at> * TODO: * * Fixes: * * For license terms, see the file COPYING in the project directory. */#include <config.h>#include <gnome.h>#include <pthread.h>#include <gmodule.h>#include "menus.h"#include "log.h"#include "sendsms.h"#include "app.h"#include "queue.h"#include "pref.h"#include "abook.h"#include "gsms_send_anim.xpm"typedef struct { GList *recipients; GtkWidget *tree; GtkWidget *text; GnomeAppBar *appbar; GtkWidget *app; GtkWidget *popup; GtkTooltips *rcp_tooltip; GtkAdjustment *rcp_adj; /* handel for send_sms */ gpointer send_sms_h; /* send dialog */ GtkWidget *sd_window; GtkWidget *sd_label_num; GtkWidget *sd_progress; GtkWidget *sd_label; GtkWidget *sd_button_label; GtkWidget *sd_anim; gboolean sd_done; gint sd_timer_id; /* id to remove the autoclose timer */} AppWidgets;static AppWidgets appwidgets;static GtkCTreeNode *sel_node = NULL;static gboolean forall = FALSE;static gint yes_no_to_all = 0;static gint app_close_down_cb(GtkWidget * window, GdkEventAny * e, gpointer data);/* callbacks/funcs for the dynamic creation of entris for receptients */static void to_entry_remove(GtkWidget * entry);static void to_entry_cleanup (void);static void to_entry_activate_cb(GtkWidget * entry, gpointer data);static void to_entry_changed_cb(GtkWidget * entry, gpointer data);static void to_button_clicked_cb(GtkWidget * button, gpointer data);static void text_changed_cb(GtkWidget * text, gpointer data);static GSList* remove_numbers (GSList *numbers , gboolean clean);static void tree_select_item_cb (GtkCTree *ctree, GList *node, gint column, gpointer user_data);static void tree_unselect_item_cb (GtkCTree *ctree, GList *node, gint column, gpointer user_data);static void tree_clicked_cb (GtkWidget *ctree, GdkEventButton *event, gpointer user_data);static void ctree_add_sms(Gsms *sms);static GSmsNumber* get_numbers(AbookEntry *entry);/* helper function for app_send_sms */static void app_send_sms_to(GSList **all, GSList *numbers, Gsms *sms, gchar *text);static void sms_send_cb(GSmsMessage *message, GSList *messages);static void ctree_add_sms_item (GSList *num, GtkCTreeNode *node);static void queue_clean_up (gboolean remove);static gint open_fail_dialog (gchar *num);GtkWidget *send_dialog_new(void);static gint send_dialog_close_cb(GtkWidget * window, GdkEventAny * e, gpointer data);void send_dialog_button_cb(GtkButton *button, gpointer user_data);gboolean send_dialog_timer_cb(gpointer data);static void forall_button_cb (GtkToggleButton *togglebutton, gpointer user_data);/**************************************************************************//********************** global visible functions **************************//**************************************************************************/GtkWidget *sms_app_new(const gchar * geometry){ gchar *titles[] = { " SMS to: ", "Status" }; GtkWidget *button, *label, *frame, *vbox, *swindow, *entry, *status, *vbox_to, *hbox, *vscrollbar, *mainframe, *paned; GtkAdjustment *adjustment; appwidgets.sd_window = NULL; /* gsms log handlers */ g_log_set_handler(NULL, G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_INFO, (GLogFunc) gsms_log_func, NULL); g_log_set_handler("LIBSMS", G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_INFO, (GLogFunc) gsms_log_func, NULL); g_log_set_handler("MAIN", G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_INFO, (GLogFunc) gsms_log_func, NULL); g_log_set_handler("SOCKET", G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_INFO, (GLogFunc) gsms_log_func, NULL); g_log_set_handler("HTTP", G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_INFO, (GLogFunc) gsms_log_func, NULL); g_log_set_handler("PLUGIN", G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_INFO, (GLogFunc) gsms_log_func, NULL); /* gsms app */ appwidgets.app = gnome_app_new(PACKAGE, _("SMS-Center")); gtk_window_set_policy(GTK_WINDOW(appwidgets.app), FALSE, TRUE, FALSE); gtk_window_set_default_size(GTK_WINDOW(appwidgets.app), 640, 480); gtk_window_set_wmclass(GTK_WINDOW(appwidgets.app), "GSMS", "SMS-Center"); mainframe = gtk_frame_new(NULL); paned=gtk_hpaned_new(); gtk_frame_set_shadow_type(GTK_FRAME(mainframe), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(mainframe), paned); /* Left side of the app */ vbox = gtk_vbox_new(FALSE, 0); frame = gtk_frame_new(NULL); swindow = gtk_scrolled_window_new(NULL, NULL); appwidgets.tree = gtk_ctree_new_with_titles(2, 0, titles); appwidgets.popup = create_popup(); gtk_signal_connect(GTK_OBJECT(appwidgets.tree), "button-press-event", GTK_SIGNAL_FUNC(tree_clicked_cb), appwidgets.popup); gtk_signal_connect(GTK_OBJECT(appwidgets.tree), "tree-select-row", GTK_SIGNAL_FUNC(tree_select_item_cb), NULL); gtk_signal_connect(GTK_OBJECT(appwidgets.tree), "tree-unselect-row", GTK_SIGNAL_FUNC(tree_unselect_item_cb), NULL); gtk_paned_pack1 (GTK_PANED (paned), frame, TRUE, FALSE); gtk_container_add(GTK_CONTAINER(frame), vbox); gtk_container_add(GTK_CONTAINER(vbox), swindow); gtk_container_add(GTK_CONTAINER(swindow), appwidgets.tree); /* Right side of the app */ vbox = gtk_vbox_new(FALSE, 0); frame = gtk_frame_new(NULL); gtk_paned_add2 (GTK_PANED (paned), frame); gtk_container_add(GTK_CONTAINER(frame), vbox); label = gtk_label_new("Recipients"); vbox_to = gtk_vbox_new(FALSE, 0); swindow = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS); appwidgets.rcp_adj = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(swindow)); button = gtk_button_new_with_label("TO:"); entry = gtk_entry_new(); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(to_button_clicked_cb), entry); /* Entry list */ appwidgets.recipients = NULL; appwidgets.recipients = g_list_append(appwidgets.recipients, entry); appwidgets.rcp_tooltip = gtk_tooltips_new(); gtk_tooltips_set_tip(appwidgets.rcp_tooltip, entry, "Enter Number like +436992233", NULL); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 5); gtk_container_add(GTK_CONTAINER(hbox), entry); gtk_box_pack_start(GTK_BOX(vbox_to), hbox, FALSE, FALSE, 0); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(swindow), vbox_to); gtk_container_add(GTK_CONTAINER(vbox), swindow); gtk_signal_connect(GTK_OBJECT(entry), "activate", GTK_SIGNAL_FUNC(to_entry_activate_cb), (gpointer) vbox_to); label = gtk_label_new("TEXT"); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); hbox = gtk_hbox_new(FALSE, 0); adjustment = (GtkAdjustment *) gtk_adjustment_new(0, 0, 1, 0.1, 0, 0); vscrollbar = gtk_vscrollbar_new(adjustment); appwidgets.text = gtk_text_new(NULL, adjustment); gtk_text_set_editable(GTK_TEXT(appwidgets.text), TRUE); gtk_container_add(GTK_CONTAINER(hbox), appwidgets.text); gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0); gtk_container_add(GTK_CONTAINER(vbox), hbox); gtk_signal_connect(GTK_OBJECT(appwidgets.text), "changed", GTK_SIGNAL_FUNC(text_changed_cb), NULL); status = gnome_appbar_new(FALSE, TRUE, GNOME_PREFERENCES_NEVER); appwidgets.appbar = GNOME_APPBAR(status); gnome_appbar_set_status(appwidgets.appbar, _("Enter text ... ")); gnome_app_set_contents(GNOME_APP(appwidgets.app), mainframe); gnome_app_set_statusbar(GNOME_APP(appwidgets.app), status); sms_install_menus_and_toolbar(appwidgets.app); gtk_signal_connect(GTK_OBJECT(appwidgets.app), "delete_event", GTK_SIGNAL_FUNC(app_close_down_cb), NULL); log_window_new(); gsms_abook_new(); if (geometry != NULL) { gint x, y, w, h; if (gnome_parse_geometry(geometry, &x, &y, &w, &h)) { if (x != -1) { gtk_widget_set_uposition(appwidgets.app, x, y); } if (w != -1) { gtk_window_set_default_size( GTK_WINDOW(appwidgets.app), w, h); } } else { g_error(_("Could not parse geometry string %s "), geometry); } } return appwidgets.app;}void sms_app_close(GtkWidget * app){ g_return_if_fail(GNOME_IS_APP(app)); gtk_widget_destroy(app); gtk_main_quit();}voidapp_clear_queue (void){ queue_clean_up (TRUE); }gboolean app_queue_sms(void){ gchar *text; Gsms *sms; GSmsNumber *pnum; GList *rcp_entry; GtkWidget *dialog; AbookEntry *ab_entry; text = gtk_editable_get_chars(GTK_EDITABLE(appwidgets.text), 0, -1); if (*text == '\0') { dialog = gnome_warning_dialog_parented ( "Please enter a text !!", GTK_WINDOW(appwidgets.app)); gtk_window_set_modal(GTK_WINDOW(dialog), TRUE); g_free(text); return FALSE; } sms = g_new0(Gsms, 1); sms->text = text; rcp_entry = appwidgets.recipients; while(rcp_entry != NULL) { gchar *to; to = gtk_editable_get_chars(GTK_EDITABLE(rcp_entry->data), 0, -1 ); if (*to == '\0') { g_free (to); } else { ab_entry = abook_search(to); if (ab_entry != NULL) { pnum = get_numbers(ab_entry); } else { /* TODO check if number correct */ pnum = g_new0(GSmsNumber, 1); pnum->phone_number = to; } sms->numbers = g_slist_append(sms->numbers, pnum); } rcp_entry = g_list_next(rcp_entry); } if(sms->numbers == NULL) return FALSE; sms_queue = g_list_append(sms_queue, sms); ctree_add_sms(sms); to_entry_cleanup(); return TRUE;} static GSmsNumber* get_numbers(AbookEntry *entry) { GSmsNumber *num=g_new0(GSmsNumber, 1); GList *alias_ptr; if(entry->alias == NULL) { num->name=g_strdup(entry->nick); num->phone_number=g_strdup(entry->number); return num; } else { num->name = g_strdup(entry->nick); num->numbers = NULL; alias_ptr = entry->alias; while(alias_ptr != NULL) { GSmsNumber *alias_num=g_new0(GSmsNumber,1); AbookEntry *alias_entry = alias_ptr->data; alias_num->name=g_strdup(alias_entry->nick); alias_num->phone_number=g_strdup(alias_entry->number); num->numbers = g_slist_append(num->numbers, alias_num); alias_ptr=g_list_next(alias_ptr); } } return num;}void app_send_sms(void){ GList *queue; GSList *all_messages = NULL; if (sms_queue == NULL) { if(!app_queue_sms()) return; } else if (gtk_text_get_length(GTK_TEXT(appwidgets.text)) > 0) if(!app_queue_sms()) return; if (appwidgets.sd_window != NULL) return; queue = sms_queue; while( queue != NULL ) { Gsms *sms = queue->data; app_send_sms_to(& all_messages, sms->numbers, (Gsms *) queue->data, NULL); queue = g_list_next(queue); } forall = FALSE; if(all_messages != NULL) { appwidgets.sd_window = send_dialog_new(); gtk_object_set_user_data( GTK_OBJECT(appwidgets.sd_progress), GINT_TO_POINTER(g_slist_length(all_messages))); appwidgets.send_sms_h = send_sms(all_messages, configuration.max_threads, sms_send_cb); }}void app_popup_item_remove (){ GSmsNumber *number; Gsms *sms; GtkCTreeRow *treerow; /* Get info about this node */ treerow=GTK_CTREE_ROW(sel_node); /* Remove a main node (sms) */ if (treerow->parent == NULL) { sms = (Gsms*) gtk_ctree_node_get_row_data( GTK_CTREE(appwidgets.tree), sel_node); gtk_ctree_remove_node(GTK_CTREE(appwidgets.tree),sel_node); if (sms != NULL) { sms->numbers=remove_numbers(sms->numbers, TRUE); g_free(sms->text); sms_queue = g_list_remove(sms_queue, sms); g_free(sms); } } else { number = (GSmsNumber*) gtk_ctree_node_get_row_data( GTK_CTREE(appwidgets.tree), sel_node); sms = (Gsms*) gtk_ctree_node_get_row_data( GTK_CTREE(appwidgets.tree), GTK_CTREE_NODE(treerow->parent)); gtk_ctree_remove_node(GTK_CTREE(appwidgets.tree),sel_node); if (number != NULL) { /* Remove all numbers */ number->numbers=remove_numbers(number->numbers, TRUE); g_free(number->name); g_free(number->phone_number); sms->numbers=g_slist_remove(sms->numbers, number); g_free(number); /* If all numbers removed, remone message */ if (sms->numbers == NULL) { g_free(sms->text); sms_queue = g_list_remove(sms_queue, sms); g_free(sms); gtk_ctree_remove_node( GTK_CTREE(appwidgets.tree), GTK_CTREE_NODE(treerow->parent)); } } } sel_node = NULL;}void app_popup_item_edit () { gint pos=0; Gsms *sms; GList *list_ptr; GSList *slist_ptr; GtkCTreeRow *treerow=GTK_CTREE_ROW(sel_node); if (treerow->parent == NULL) sms = (Gsms*) gtk_ctree_node_get_row_data( GTK_CTREE(appwidgets.tree), sel_node); else { sel_node = GTK_CTREE_NODE(treerow->parent); sms = (Gsms*) gtk_ctree_node_get_row_data( GTK_CTREE(appwidgets.tree), sel_node); } if (sms != NULL) { gtk_editable_insert_text(GTK_EDITABLE(appwidgets.text), sms->text, strlen(sms->text), &pos); list_ptr=appwidgets.recipients; slist_ptr=sms->numbers; while (slist_ptr != NULL) { GtkWidget *entry; GSmsNumber *number; entry = GTK_WIDGET(list_ptr->data); number = (GSmsNumber*) slist_ptr->data; if(number->name != NULL) gtk_entry_set_text(GTK_ENTRY(entry), number->name); else gtk_entry_set_text(GTK_ENTRY(entry), number->phone_number); gtk_signal_emit_by_name(GTK_OBJECT(entry),"activate"); slist_ptr=g_slist_next(slist_ptr); list_ptr=g_list_next(list_ptr); } app_popup_item_remove (); } }void app_set_font (void) { GdkFont *font; GtkStyle *style; font = gdk_font_load(configuration.fontname); if (font != NULL ) { style = gtk_style_copy (gtk_widget_get_style (appwidgets.text)); gdk_font_unref (style->font); style->font=font; gtk_widget_set_style (GTK_WIDGET(appwidgets.text), style); } }/**************************************************************************//************************** helper functions ******************************//**************************************************************************//* helper function for app_send_sms * builds recursivly a list suitable for send_sms */static voidapp_send_sms_to(GSList **all, GSList *numbers, Gsms *sms, gchar *text) { if(text == NULL) text = g_strdup(sms->text); while(numbers != NULL) { GSmsNumber *num = numbers->data; gint sel_button = -1; if(num->phone_number != NULL) { if((num->sent == -1) && !forall) sel_button = open_fail_dialog (num->phone_number); if((sel_button == 0) && forall) yes_no_to_all = 1; if((sel_button == 1) && forall) yes_no_to_all = -1; if((num->sent < 0 ) && (sel_button == 1 || (yes_no_to_all == -1))) num->sent = 2; if (((yes_no_to_all == 1) || sel_button == 0 ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -