diff --git a/sflphone-client-gnome/debian/changelog b/sflphone-client-gnome/debian/changelog index 8511b73550de033368fd0e30f06d372a01c1a8cb..55d1fd7d23f8a7c4383b1c22ff66fce77650b2f6 100644 --- a/sflphone-client-gnome/debian/changelog +++ b/sflphone-client-gnome/debian/changelog @@ -1,19 +1,3 @@ -sflphone-client-gnome (0.9.5-0ubuntu1~1.gbp22d013) SYSTEM; urgency=low - - ** SNAPSHOT build @22d0135a841ca830bf4ff57ba068506b919fb86e ** - - [ SFLphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1~rc1 - - [ Emmanuel Milou ] - * [#1402] Build the daemon with the local pjsip library (vs the - installed one) - * [#1402] Add info message after configure - - [ Sflphone Project ] - - -- Sflphone Project <sflphone@mtl.savoirfairelinux.net> Fri, 08 May 2009 00:01:57 -0400 - sflphone-client-gnome (0.9.5-0ubuntu1~rc1) SYSTEM; urgency=low [ SFLphone Project ] @@ -43,145 +27,6 @@ sflphone-client-gnome (0.9.5-0ubuntu1~rc1) SYSTEM; urgency=low -- Sflphone Project <sflphone@mtl.savoirfairelinux.net> Tue, 05 May 2009 19:16:13 -0400 -sflphone-client-gnome (0.9.5-0ubuntu1~6.gbpdfcd86) SYSTEM; urgency=low - - ** SNAPSHOT build @dfcd86f7fdabcc0462e8e5aef3a21ada929e077b ** - - [ Emmanuel Milou ] - * [#1220] Add Conflicts: sflphone in debian control files - * [#1179] Add liblog4c3 runtime dependency - * [#1212] FIx typo error in dependency list for itnrepid - * [#1212] FIx .desktop file to point on the right exec - * [#1212] Modify changelog replacing tag - - [ Sflphone Project ] - * "[#1262] Updated changelogs for version 0.9.5-0ubuntu1~beta" - - [ Emmanuel Milou ] - * [#1212] restore changelogs - - [ Sflphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 04-27 - - [ Emmanuel Milou ] - * [#1212] restore changelogs - - [ Sflphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1~beta - - [ Emmanuel Milou ] - * [#1212] restore changelogs - - [ Sflphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1~beta - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 04-28 - - [ Emmanuel Milou ] - * [#1212] Restore changelogs - - [ Sflphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 04-28 - - [ Julien Bonjean ] - * [#1262]Introduced dynamic version setting - - [ Sflphone Project ] - - [ Alexandre Savard ] - * [#1143] Add celtcodec.cpp - * [#1143] add configure and make stuffs - * [#1143] add frame size into each codecs - * [#1143] Take timestamp's step size from codec - * [#1143] RTP thread at 11 ms - * [#1143] Dynamic RTP thread sleep parameter - * [#1143] Fix dynamic thread sleep time calculation - - [ Emmanuel Milou ] - * [#1262] sflphone-client-gnome uses changelog version number - - [ Alexandre Savard ] - * [#1143] Some cleanup - - [ SFLphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 04-29 - - [ Emmanuel Milou ] - * [#1262] Update changelogs - * [#1262] Update rules - * [#1143] Build celt codec only if version >= 0.5.1 is detected - * [1143] Restore rules files - do not need to specify --without-celt - * [#1336] Change SFLphone logo - * [#1331] Fix searchbar problems - * [#1332] Fix unexplicit labels - * [#1334] Fix unexplicit label - * [#1329] Fix recordings config panel - - [ Sflphone Project ] - - [ SFLphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 04-30 - - [ Emmanuel Milou ] - * [#1336] Add new logo - * [#1335] Enable/disable address book, change option name - * [#1324] Add more insightful status bar message - * [#1330] Fix behaviour if no addressbook are active - - [ Sflphone Project ] - - [ SFLphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 05-01 - - [ Julien Bonjean ] - * [#1161] Added build system scripts - - [ Emmanuel Milou ] - * [#1215] Redesign current account computing - * [#1333] Remove default voicemail number - * [#1333] Voicemail icon update if current account has no voicemail - number + unit tests - * [#1333] Remove default voicemail number in assistant; update status - bar message - * [#1333] Add voicemail number field in wizard - * [#1342] Make config panels more GNOME compliant - - [ Sflphone Project ] - - [ Alexandre Savard ] - * [#1143] Fixed auio record after celt refactoring - * [#1327] Alsa display unappropriate info - * [#1328] Unappropriate label in audio preferences panel - * [#1316] Forgot 's' to RFC3969 'sip:' URI when calling in unicast - mode - * [#1316] #define IP_TO_IP_PATTERN "sip:" - * [#1316] 'sip:' subtitution to 4 char - * [#1321] Startup wizard password display is inconsistent - * [#1325] Error window in preferences shows formatting error - * [#1325] Proposed Implementation - * [#1325] Add title to window - * [#1343] Moved key stroke signal from call tree to main window - * [#1343] Dialing on key strike disabled when either history or - contact selected - * [#1343] Cannot dial when focus not on white frame - - [ SFLphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 05-02 - - [ Emmanuel Milou ] - * [#1331] Fix clear default message bug - * [#936] Remove old codecs from repository - - [ Sflphone Project ] - - -- Sflphone Project <sflphone@mtl.savoirfairelinux.net> Tue, 05 May 2009 00:02:19 -0400 - sflphone-client-gnome (0.9.5-0ubuntu1~beta) SYSTEM; urgency=low [ Julien Bonjean ] diff --git a/sflphone-client-gnome/src/actions.c b/sflphone-client-gnome/src/actions.c index cf1bf134ca9caf6a25b61f2d49bdaf00149fce18..20359285fbedebaaeb9acf1444ac387286b93b10 100644 --- a/sflphone-client-gnome/src/actions.c +++ b/sflphone-client-gnome/src/actions.c @@ -294,7 +294,7 @@ sflphone_hang_up() void sflphone_pick_up() { - + DEBUG("sflphone_pick_up\n"); call_t * selectedCall = calltab_get_selected_call(active_calltree); if(selectedCall) { @@ -328,6 +328,10 @@ sflphone_pick_up() break; } } + else { + sflphone_new_call(); + } + } void @@ -536,6 +540,8 @@ sflphone_new_call() call_t *c; gchar *from, *to; + + DEBUG("sflphone_new_call\n"); sflphone_on_hold(); // Play a tone when creating a new call @@ -557,6 +563,7 @@ sflphone_new_call() void sflphone_keypad( guint keyval, gchar * key) { + DEBUG("sflphone_keypad \n"); call_t * c = calltab_get_selected_call(current_calls); if((active_calltree != current_calls) || (active_calltree == current_calls && !c)) @@ -581,6 +588,7 @@ sflphone_keypad( guint keyval, gchar * key) switch(c->state) { case CALL_STATE_DIALING: // Currently dialing => edit number + DEBUG("Writing a number\n"); process_dialing(c, keyval, key); break; case CALL_STATE_RECORD: @@ -670,6 +678,10 @@ sflphone_keypad( guint keyval, gchar * key) default: break; } + + } + else { + sflphone_new_call(); } } diff --git a/sflphone-client-gnome/src/config/addressbook-config.c b/sflphone-client-gnome/src/config/addressbook-config.c index a5755874f8f2ac472a6ac564f384d103cfe27758..a9f0eae296cb912d9bbbf9779f282f201abe2333 100644 --- a/sflphone-client-gnome/src/config/addressbook-config.c +++ b/sflphone-client-gnome/src/config/addressbook-config.c @@ -266,9 +266,9 @@ create_addressbook_settings() gtk_box_pack_start(GTK_BOX(ret), result_frame, FALSE, FALSE, 0); gtk_widget_show (result_frame); - table = gtk_table_new ( 6, 3, FALSE/* homogeneous */); - gtk_table_set_row_spacings( GTK_TABLE(table), 10); - gtk_table_set_col_spacings( GTK_TABLE(table), 10); + table = gtk_table_new ( 3, 3, FALSE/* homogeneous */); + gtk_table_set_row_spacings( GTK_TABLE(table), 8); + gtk_table_set_col_spacings( GTK_TABLE(table), 8); gtk_widget_show(table); gtk_container_add( GTK_CONTAINER (result_frame) , table ); @@ -296,40 +296,61 @@ create_addressbook_settings() g_signal_connect (G_OBJECT(photo) , "clicked" , G_CALLBACK (display_contact_photo_cb), NULL); gtk_table_attach ( GTK_TABLE( table ), photo, 1, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + // Fields gnome_main_section_new (_("Fields"), &result_frame); gtk_box_pack_start(GTK_BOX(ret), result_frame, FALSE, FALSE, 0); gtk_widget_show (result_frame); table = gtk_table_new ( 5, 3, FALSE); - gtk_table_set_row_spacings( GTK_TABLE(table), 10); - gtk_table_set_col_spacings( GTK_TABLE(table), 10); + gtk_table_set_row_spacings( GTK_TABLE(table), 8); + gtk_table_set_col_spacings( GTK_TABLE(table), 8); gtk_widget_show(table); gtk_container_add( GTK_CONTAINER (result_frame) , table ); + label = gtk_label_new (_("Use the following fields from Evolution's address books:")); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_table_attach ( GTK_TABLE( table ), label, 1, 4, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + item = gtk_check_button_new_with_mnemonic( _("_Business phone")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(item), addressbook_config->search_phone_business); g_signal_connect (G_OBJECT(item) , "clicked" , G_CALLBACK (search_phone_business_cb) , NULL); - gtk_table_attach ( GTK_TABLE( table ), item, 1, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach ( GTK_TABLE( table ), item, 1, 4, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); item = gtk_check_button_new_with_mnemonic( _("_Home phone")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(item), addressbook_config->search_phone_home); g_signal_connect (G_OBJECT(item) , "clicked" , G_CALLBACK (search_phone_home_cb) , NULL); - gtk_table_attach ( GTK_TABLE( table ), item, 1, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach ( GTK_TABLE( table ), item, 1, 4, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); item = gtk_check_button_new_with_mnemonic( _("_Mobile phone")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(item), addressbook_config->search_phone_mobile); g_signal_connect (G_OBJECT(item) , "clicked" , G_CALLBACK (search_phone_mobile_cb) , NULL); - gtk_table_attach ( GTK_TABLE( table ), item, 1, 3, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach ( GTK_TABLE( table ), item, 1, 4, 4, 5, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + + // Address Book gnome_main_section_new (_("Address Books"), &result_frame); gtk_box_pack_start(GTK_BOX(ret), result_frame, TRUE, TRUE, 0); gtk_widget_show (result_frame); + table = gtk_table_new ( 2, 3, FALSE/* homogeneous */); + gtk_table_set_row_spacings( GTK_TABLE(table), 8); + gtk_table_set_col_spacings( GTK_TABLE(table), 8); + gtk_widget_show(table); + gtk_container_add( GTK_CONTAINER (result_frame) , table ); + + label = gtk_label_new (_("Select which Evolution address books to use:")); + gtk_misc_set_alignment(GTK_MISC(label), 0.00, 0.1); + + gtk_table_attach ( GTK_TABLE( table ), label, 1, 4, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + scrolled_window = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_IN); - gtk_container_add( GTK_CONTAINER (result_frame) , scrolled_window ); + gtk_table_attach ( GTK_TABLE( table ), scrolled_window, 1, 4, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + store = gtk_list_store_new(3, G_TYPE_BOOLEAN, // Active diff --git a/sflphone-client-gnome/src/config/audioconf.c b/sflphone-client-gnome/src/config/audioconf.c index 2aabd26c0b8a21a2f3a069569cab86028eeabf7e..7d4e0ee0ac17c483cbc30b82fe3dfe4e1455c93d 100644 --- a/sflphone-client-gnome/src/config/audioconf.c +++ b/sflphone-client-gnome/src/config/audioconf.c @@ -616,7 +616,7 @@ GtkWidget* codecs_box() select_audio_manager( void ) { - DEBUG("audio manager selected"); + DEBUG("audio manager selected\n"); if( !SHOW_ALSA_CONF && !gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(pulse) ) ) { @@ -656,7 +656,7 @@ GtkWidget* api_box() gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(alsa), SHOW_ALSA_CONF ); gtk_box_pack_end( GTK_BOX(ret) , alsa , TRUE , TRUE , 1); g_signal_connect(G_OBJECT(alsa), "clicked", G_CALLBACK(select_audio_manager), NULL); - + // gtk_misc_set_alignment(GTK_MISC(alsa), 0.2, 0.4); gtk_widget_show_all(ret); return ret; @@ -756,6 +756,7 @@ GtkWidget* ringtones_box() // check button to enable ringtones ret = gtk_hbox_new( TRUE , 1); enableTone = gtk_check_button_new_with_mnemonic( _("_Enable ringtones")); + // gtk_misc_set_alignment(GTK_MISC(enableTone), 0.2, 0.5); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(enableTone), dbus_is_ringtone_enabled() ); gtk_box_pack_start( GTK_BOX(ret) , enableTone , TRUE , TRUE , 1); g_signal_connect(G_OBJECT( enableTone) , "clicked" , G_CALLBACK( ringtone_enabled ) , NULL); diff --git a/sflphone-client-gnome/src/config/configwindow.c b/sflphone-client-gnome/src/config/configwindow.c index f33f0f2f9a49c186508595d180cfa0cb5969fd3c..951082084a1dd50f908fcf12e60f17bc45629243 100644 --- a/sflphone-client-gnome/src/config/configwindow.c +++ b/sflphone-client-gnome/src/config/configwindow.c @@ -74,6 +74,10 @@ enum { COLUMN_ACCOUNT_COUNT }; +// Mail notification +GtkWidget * widg; + + /** * Fills the treelist with accounts @@ -161,6 +165,14 @@ set_popup_mode( void ) set_notif_level( ) { dbus_set_notify(); + + if (dbus_get_notify()) + gtk_widget_set_sensitive(widg, TRUE); + else { + gtk_widget_set_sensitive(widg, FALSE); + if (dbus_get_mail_notify()) + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(widg), FALSE); + } } void @@ -532,6 +544,7 @@ GtkWidget* create_stun_tab() + GtkWidget* create_general_settings () { @@ -543,7 +556,9 @@ create_general_settings () GtkWidget *notifBox; GtkWidget *notifAll; - GtkWidget *widg; + // GtkWidget *widg; + + GtkWidget *mutewidget; GtkWidget *trayBox; GtkWidget *trayItem; @@ -569,16 +584,23 @@ create_general_settings () gtk_container_add( GTK_CONTAINER(frame) , notifBox); gtk_container_set_border_width(GTK_CONTAINER(notifBox), 2); + // Notification All notifAll = gtk_check_button_new_with_mnemonic( _("_Enable notifications")); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(notifAll), dbus_get_notify() ); gtk_box_pack_start( GTK_BOX(notifBox) , notifAll , TRUE , TRUE , 1); g_signal_connect(G_OBJECT( notifAll ) , "clicked" , G_CALLBACK( set_notif_level ) , NULL ); - + + // Notification widg = gtk_check_button_new_with_mnemonic( _("Enable voicemail _notifications")); gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(widg), dbus_get_mail_notify() ); gtk_box_pack_start( GTK_BOX(notifBox) , widg , TRUE , TRUE , 1); g_signal_connect(G_OBJECT( widg ) , "clicked" , G_CALLBACK( set_mail_notif ) , NULL); + if (dbus_get_notify()) + gtk_widget_set_sensitive(widg, TRUE); + else + gtk_widget_set_sensitive(widg, FALSE); + // System Tray option frame gnome_main_section_new (_("System Tray Icon"), &frame); gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0); @@ -612,6 +634,7 @@ create_general_settings () gtk_container_add( GTK_CONTAINER(frame) , hbox); label = gtk_label_new_with_mnemonic(_("_History size limit")); + gtk_misc_set_alignment(GTK_MISC(label), 0.03, 0.4); gtk_box_pack_start( GTK_BOX(hbox) , label , TRUE , TRUE , 0); value = gtk_hscale_new_with_range(0.0 , 50.0 , 5.0); @@ -635,10 +658,10 @@ create_general_settings () gtk_widget_show( vbox ); gtk_container_add( GTK_CONTAINER(frame) , vbox); - widg = gtk_check_button_new_with_mnemonic( _("Mute other applications during a _call")); - gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(widg), dbus_get_pulse_app_volume_control() ); - gtk_box_pack_start( GTK_BOX(vbox) , widg , TRUE , TRUE , 1); - g_signal_connect(G_OBJECT( widg ) , "clicked" , G_CALLBACK( set_pulse_app_volume_control ) , NULL); + mutewidget = gtk_check_button_new_with_mnemonic( _("Mute other applications during a _call")); + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(mutewidget), dbus_get_pulse_app_volume_control() ); + gtk_box_pack_start( GTK_BOX(vbox) , mutewidget , TRUE , TRUE , 1); + g_signal_connect(G_OBJECT( mutewidget ) , "clicked" , G_CALLBACK( set_pulse_app_volume_control ) , NULL); n = account_list_get_sip_account_number(); DEBUG("sip account number = %i", n); @@ -662,7 +685,7 @@ create_general_settings () //gtk_widget_set_sensitive( GTK_WIDGET(applyButton), (n==0)?FALSE:TRUE ); label = gtk_label_new(_("Port:")); - + gtk_misc_set_alignment(GTK_MISC(label), 0.03, 0.4); entryPort = gtk_spin_button_new_with_range(1, 65535, 1); gtk_label_set_mnemonic_widget (GTK_LABEL (label), entryPort); gtk_spin_button_set_value(GTK_SPIN_BUTTON(entryPort), curPort); @@ -718,7 +741,7 @@ create_recording_settings () // label label = gtk_label_new_with_mnemonic(_("_Recordings folder")); gtk_table_attach( GTK_TABLE(table), label, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 5); - gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); + gtk_misc_set_alignment(GTK_MISC(label), 0.08, 0.5); // folder chooser button @@ -756,7 +779,7 @@ show_config_window () // Set window properties gtk_dialog_set_has_separator(dialog, FALSE); - gtk_window_set_default_size(GTK_WINDOW(dialog), 400, 400); + gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 400); gtk_container_set_border_width(GTK_CONTAINER(dialog), 0); // Create tabs container @@ -823,7 +846,7 @@ show_accounts_window( void ) // Set window properties gtk_dialog_set_has_separator(dialog, FALSE); - gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 500); + gtk_window_set_default_size(GTK_WINDOW(dialog), 600, 500); gtk_container_set_border_width(GTK_CONTAINER(dialog), 0); gnome_main_section_new (_("Configured Accounts"), &accountFrame); diff --git a/sflphone-client-gnome/src/config/hooks-config.c b/sflphone-client-gnome/src/config/hooks-config.c index f6f37ceffee32bad6b2961d4cf97854fe42edac5..4d9ece57aee93ab4d5dc109dc0dfce7ecfd6b265 100644 --- a/sflphone-client-gnome/src/config/hooks-config.c +++ b/sflphone-client-gnome/src/config/hooks-config.c @@ -131,30 +131,34 @@ GtkWidget* create_hooks_settings (){ gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0); gtk_widget_show (frame); - table = gtk_table_new ( 5, 3, FALSE/* homogeneous */); + table = gtk_table_new ( 6, 2, FALSE/* homogeneous */); gtk_table_set_row_spacings( GTK_TABLE(table), 10); gtk_table_set_col_spacings( GTK_TABLE(table), 10); gtk_widget_show(table); gtk_container_add( GTK_CONTAINER (frame) , table ); + label = gtk_label_new(_("SFLphone can run custom commands if incoming calls come with an URL attached.\nIn this case, %s will be replaced with the passed URL.")); + gtk_table_attach ( GTK_TABLE( table ), label, 0, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + widg = gtk_check_button_new_with_mnemonic( _("Trigger on specific _SIP header")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widg), (g_strcasecmp (_urlhook_config->sip_enabled, "1")==0)?TRUE:FALSE); g_signal_connect (G_OBJECT(widg) , "clicked" , G_CALLBACK (sip_enabled_cb), NULL); gtk_table_attach ( GTK_TABLE( table ), widg, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - label = gtk_label_new_with_mnemonic (_("FIXME: ")); - gtk_table_attach ( GTK_TABLE( table ), label, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + // label = gtk_label_new_with_mnemonic (_("FIXME: ")); + // gtk_table_attach ( GTK_TABLE( table ), label, 1, 2, 1, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); field = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), field); gtk_entry_set_text(GTK_ENTRY(field), _urlhook_config->sip_field); - gtk_table_attach ( GTK_TABLE( table ), field, 2, 3, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach ( GTK_TABLE( table ), field, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); widg = gtk_check_button_new_with_mnemonic( _("Trigger on _IAX2 URL")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widg), (g_strcasecmp (_urlhook_config->iax2_enabled, "1")==0)?TRUE:FALSE); g_signal_connect (G_OBJECT(widg) , "clicked" , G_CALLBACK (iax2_enabled_cb), NULL); - gtk_table_attach ( GTK_TABLE( table ), widg, 0, 3, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach ( GTK_TABLE( table ), widg, 0, 2, 2, 3, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); label = gtk_label_new_with_mnemonic (_("_Command to run: ")); + gtk_misc_set_alignment(GTK_MISC(label), 0.05, 0.5); gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 3, 4, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); command = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), command); @@ -165,24 +169,24 @@ GtkWidget* create_hooks_settings (){ gtk_box_pack_start(GTK_BOX(ret), frame, FALSE, FALSE, 0); gtk_widget_show (frame); - table = gtk_table_new ( 2, 2, FALSE/* homogeneous */); + table = gtk_table_new ( 4, 2, FALSE/* homogeneous */); gtk_table_set_row_spacings( GTK_TABLE(table), 10); gtk_table_set_col_spacings( GTK_TABLE(table), 10); gtk_widget_show(table); gtk_container_add( GTK_CONTAINER (frame) , table ); - widg = gtk_check_button_new_with_mnemonic( _("_Prefix dialed numbers with")); + widg = gtk_check_button_new_with_mnemonic( _("_Prefix dialed numbers with:")); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(widg), (g_strcasecmp (_urlhook_config->phone_number_enabled, "1")==0)?TRUE:FALSE); g_signal_connect (G_OBJECT(widg) , "clicked" , G_CALLBACK (phone_number_enabled_cb), NULL); - gtk_table_attach ( GTK_TABLE( table ), widg, 0, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_table_attach ( GTK_TABLE( table ), widg, 0, 1, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); - label = gtk_label_new_with_mnemonic (_("_FIXME: ")); - gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + // label = gtk_label_new (_("Prepend: ")); + // gtk_table_attach ( GTK_TABLE( table ), label, 0, 1, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); prefix = gtk_entry_new (); gtk_label_set_mnemonic_widget (GTK_LABEL (label), prefix); gtk_entry_set_text(GTK_ENTRY(prefix), _urlhook_config->phone_number_prefix); gtk_widget_set_sensitive (GTK_WIDGET (prefix), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON (widg))); - gtk_table_attach ( GTK_TABLE( table ), prefix, 1, 2, 1, 2, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10); + gtk_table_attach ( GTK_TABLE( table ), prefix, 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 10); gtk_widget_show_all(ret); diff --git a/sflphone-client-gnome/src/config/hooks-config.h b/sflphone-client-gnome/src/config/hooks-config.h index fe9c92c62f0be2ea37ba16869303e481297d6ef6..d4651fbe3729deb99910b26ef0cd2bf2ab4bcb8c 100644 --- a/sflphone-client-gnome/src/config/hooks-config.h +++ b/sflphone-client-gnome/src/config/hooks-config.h @@ -28,7 +28,7 @@ G_BEGIN_DECLS #define DEFAULT_SIP_URL_FIELD "X-sflphone-url" -#define DEFAULT_URL_COMMAND "x-www-browser" +#define DEFAULT_URL_COMMAND "xdg-open \"%s\"" #define URLHOOK_COMMAND "URLHOOK_COMMAND" #define URLHOOK_SIP_FIELD "URLHOOK_SIP_FIELD" #define URLHOOK_SIP_ENABLED "URLHOOK_SIP_ENABLED" diff --git a/sflphone-client-gnome/src/contacts/calltree.c b/sflphone-client-gnome/src/contacts/calltree.c index bcd6ff746554e7160e33ef0a7065d8615070fbae..01d6d6960dceda42824aebb60085a45ebf541662 100644 --- a/sflphone-client-gnome/src/contacts/calltree.c +++ b/sflphone-client-gnome/src/contacts/calltree.c @@ -25,6 +25,12 @@ #include <toolbar.h> #include <mainwindow.h> + +GtkWidget *sw; +GtkCellRenderer *rend; +GtkTreeViewColumn *col; +GtkTreeSelection *sel; + /** * Show popup menu */ @@ -141,12 +147,13 @@ button_pressed(GtkWidget* widget, GdkEventButton *event, gpointer user_data UNUS return FALSE; } + static gboolean on_key_released (GtkWidget *widget UNUSED, GdkEventKey *event, gpointer user_data UNUSED) { - + DEBUG("key-release-event signal cought by on_key_released callback \n"); // If a modifier key is pressed, it's a shortcut, pass along if(event->state & GDK_CONTROL_MASK || event->state & GDK_MOD1_MASK || @@ -175,13 +182,27 @@ calltree_reset (calltab_t* tab) gtk_list_store_clear (tab->store); } +void +focus_on_calltree_out(){ + DEBUG("set_focus_on_calltree_out \n"); + // gtk_widget_grab_focus(GTK_WIDGET(sw)); + focus_is_on_calltree = FALSE; +} + +void +focus_on_calltree_in(){ + DEBUG("set_focus_on_calltree_in \n"); + // gtk_widget_grab_focus(GTK_WIDGET(sw)); + focus_is_on_calltree = TRUE; +} + void calltree_create (calltab_t* tab, gchar* searchbar_type) { - GtkWidget *sw; - GtkCellRenderer *rend; - GtkTreeViewColumn *col; - GtkTreeSelection *sel; + // GtkWidget *sw; + // GtkCellRenderer *rend; + // GtkTreeViewColumn *col; + // GtkTreeSelection *sel; tab->tree = gtk_vbox_new(FALSE, 10); @@ -207,7 +228,8 @@ calltree_create (calltab_t* tab, gchar* searchbar_type) G_CALLBACK (row_activated), NULL); - // GTK_WIDGET_SET_FLAGS (GTK_WIDGET(sw),GTK_CAN_FOCUS); + GTK_WIDGET_SET_FLAGS (GTK_WIDGET(sw),GTK_CAN_FOCUS); + gtk_widget_grab_focus (GTK_WIDGET(sw)); // Connect the popup menu g_signal_connect (G_OBJECT (tab->view), "popup-menu", @@ -217,9 +239,15 @@ calltree_create (calltab_t* tab, gchar* searchbar_type) G_CALLBACK (button_pressed), NULL); - g_signal_connect (G_OBJECT (sw), "key-release-event", - G_CALLBACK (on_key_released), NULL); + // g_signal_connect (G_OBJECT (sw), "key-release-event", + // G_CALLBACK (on_key_released), NULL); + + g_signal_connect_after (G_OBJECT (tab->view), "focus-in-event", + G_CALLBACK (focus_on_calltree_in), NULL); + g_signal_connect_after (G_OBJECT (tab->view), "focus-out-event", + G_CALLBACK (focus_on_calltree_out), NULL); + gtk_widget_grab_focus(GTK_WIDGET(tab->view)); rend = gtk_cell_renderer_pixbuf_new(); col = gtk_tree_view_column_new_with_attributes ("Icon", diff --git a/sflphone-client-gnome/src/contacts/calltree.h b/sflphone-client-gnome/src/contacts/calltree.h index 1dd57d2d282a4b5b48d0d7f6859ed55bf512cff4..09d5ad6887eed8e64af16c9c801ae1c26d9d5538 100644 --- a/sflphone-client-gnome/src/contacts/calltree.h +++ b/sflphone-client-gnome/src/contacts/calltree.h @@ -23,7 +23,7 @@ #include <gtk/gtk.h> #include <calltab.h> #include <timestamp.h> - +#include <mainwindow.h> /** @file calltree.h * @brief The GtkTreeView that list calls in the main window. diff --git a/sflphone-client-gnome/src/contacts/searchbar.c b/sflphone-client-gnome/src/contacts/searchbar.c index f83d72381a909a6c2d78837ba42ac3b03f8576d9..4d4a133182b12d0b339c84e89beccc8e8e3ceb11 100644 --- a/sflphone-client-gnome/src/contacts/searchbar.c +++ b/sflphone-client-gnome/src/contacts/searchbar.c @@ -26,6 +26,7 @@ const GdkColor BLACK_COLOR = { 0, 0, 0, 0 }; const GdkColor GRAY_COLOR = { 0, 30000, 30000, 30000 }; +GtkWidget * searchbox; void searchbar_entry_changed (GtkEntry* entry, gchar* arg1 UNUSED, gpointer data UNUSED) { // gtk_widget_grab_focus (GTK_WIDGET(searchbox)); @@ -39,17 +40,40 @@ void searchbar_entry_changed (GtkEntry* entry, gchar* arg1 UNUSED, gpointer data } +// static void +// focus_in_event(GtkWidget *widget, GdkEventFocus *event, gpointer data) +// { + +// } + + void searchbar_clear_entry_if_default (GtkWidget* widget, gpointer user_data UNUSED) { + DEBUG("searchbar_clear_entry_if_default\n"); gtk_widget_modify_text(widget, GTK_STATE_NORMAL, &BLACK_COLOR); if(g_ascii_strncasecmp(gtk_entry_get_text(GTK_ENTRY(widget)), "Search history", 14) == 0 || g_ascii_strncasecmp(gtk_entry_get_text(GTK_ENTRY(widget)), "Search contact", 14) == 0 ) gtk_entry_set_text(GTK_ENTRY(widget), ""); - // gtk_widget_grab_focus (GTK_WIDGET(searchbox)); + // gtk_widget_grab_focus (GTK_WIDGET(searchbox));1 } +void +focus_on_searchbar_out(){ + DEBUG("set_focus_on_searchbar_out \n"); + // gtk_widget_grab_focus(GTK_WIDGET(sw)); + focus_is_on_searchbar = FALSE; +} + +void +focus_on_searchbar_in(){ + DEBUG("set_focus_on_searchbar_in \n"); + // gtk_widget_grab_focus(GTK_WIDGET(sw)); + focus_is_on_searchbar = TRUE; +} + + void searchbar_init(calltab_t *tab) { @@ -63,7 +87,7 @@ searchbar_init(calltab_t *tab) GtkWidget* searchbar_new(gchar* searchbar_type) { - GtkWidget * searchbox; + // GtkWidget * searchbox; GtkWidget* image; GtkWidget* ret = gtk_hbox_new(FALSE, 0); @@ -84,8 +108,13 @@ GtkWidget* searchbar_new(gchar* searchbar_type) { gtk_widget_modify_text(searchbox, GTK_STATE_NORMAL, &GRAY_COLOR); gtk_entry_set_text(GTK_ENTRY(searchbox), _("Search contact")); - g_signal_connect(GTK_ENTRY(searchbox), "changed", G_CALLBACK(searchbar_entry_changed), NULL); - g_signal_connect(GTK_ENTRY(searchbox), "grab-focus", G_CALLBACK(searchbar_clear_entry_if_default), NULL); + g_signal_connect_after(GTK_ENTRY(searchbox), "changed", G_CALLBACK(searchbar_entry_changed), NULL); + g_signal_connect_after(GTK_ENTRY(searchbox), "grab-focus", G_CALLBACK(searchbar_clear_entry_if_default), NULL); + + g_signal_connect_after (G_OBJECT (searchbox), "focus-in-event", + G_CALLBACK (focus_on_searchbar_in), NULL); + g_signal_connect_after (G_OBJECT (searchbox), "focus-out-event", + G_CALLBACK (focus_on_searchbar_out), NULL); gtk_box_pack_start(GTK_BOX(ret), searchbox, TRUE, TRUE, 0); diff --git a/sflphone-client-gnome/src/contacts/searchbar.h b/sflphone-client-gnome/src/contacts/searchbar.h index aabe3ea4113a06c6ba2ce156af4d09fe5b234fa1..f7ed3035200642cb71612d6322e2ce8793ca436b 100644 --- a/sflphone-client-gnome/src/contacts/searchbar.h +++ b/sflphone-client-gnome/src/contacts/searchbar.h @@ -30,6 +30,7 @@ #include <calllist.h> #include <gtk/gtk.h> +#include <mainwindow.h> // From version 2.16, gtk provides the functionalities libsexy used to provide #if GTK_CHECK_VERSION(2,16,0) diff --git a/sflphone-client-gnome/src/dbus/dbus.c b/sflphone-client-gnome/src/dbus/dbus.c index fcd3d92d2f883f24a31452ff1ec8e4a730893ae2..6c17fed77ecfbe75640778cb8f1853575bb62ff6 100644 --- a/sflphone-client-gnome/src/dbus/dbus.c +++ b/sflphone-client-gnome/src/dbus/dbus.c @@ -215,25 +215,41 @@ dbus_connect () /* Create a proxy object for the "bus driver" (name "org.freedesktop.DBus") */ + instanceProxy = dbus_g_proxy_new_for_name (connection, "org.sflphone.SFLphone", "/org/sflphone/SFLphone/Instance", "org.sflphone.SFLphone.Instance"); - + /* + instanceProxy = dbus_g_proxy_new_for_name_owner (connection, + "org.sflphone.SFLphone", + "/org/sflphone/SFLphone/Instance", + "org.sflphone.SFLphone.Instance", + &error); + */ + if (instanceProxy==NULL) { ERROR ("Failed to get proxy to Instance"); return FALSE; } - DEBUG ("DBus connected to Instance"); - + DEBUG ("DBus connected to Instance"); + + callManagerProxy = dbus_g_proxy_new_for_name (connection, "org.sflphone.SFLphone", "/org/sflphone/SFLphone/CallManager", "org.sflphone.SFLphone.CallManager"); + /* + callManagerProxy = dbus_g_proxy_new_for_name_owner (connection, + "org.sflphone.SFLphone", + "/org/sflphone/SFLphone/CallManager", + "org.sflphone.SFLphone.CallManager", + &error); + */ if (callManagerProxy==NULL) { ERROR ("Failed to get proxy to CallManagers"); @@ -284,11 +300,20 @@ dbus_connect () dbus_g_proxy_connect_signal (callManagerProxy, "volumeChanged", G_CALLBACK(volume_changed_cb), NULL, NULL); - configurationManagerProxy = dbus_g_proxy_new_for_name (connection, + + configurationManagerProxy = dbus_g_proxy_new_for_name (connection, "org.sflphone.SFLphone", "/org/sflphone/SFLphone/ConfigurationManager", "org.sflphone.SFLphone.ConfigurationManager"); + + /* + configurationManagerProxy = dbus_g_proxy_new_for_name_owner (connection, + "org.sflphone.SFLphone", + "/org/sflphone/SFLphone/ConfigurationManager", + "org.sflphone.SFLphone.ConfigurationManager", + &error); + */ if (!configurationManagerProxy) { ERROR ("Failed to get proxy to ConfigurationManager"); diff --git a/sflphone-client-gnome/src/mainwindow.c b/sflphone-client-gnome/src/mainwindow.c index c4a28e6d7b3f3c2acbaec6201e21f087885699d5..1db50d7282e3881c999dc9c0207c794428097cda 100644 --- a/sflphone-client-gnome/src/mainwindow.c +++ b/sflphone-client-gnome/src/mainwindow.c @@ -98,25 +98,14 @@ main_window_ask_quit(){ } -/* + static gboolean -on_key_released (GtkWidget *widget, - GdkEventKey *event, - gpointer user_data UNUSED) +on_key_released (GtkWidget *widget, GdkEventKey *event, gpointer user_data UNUSED) { - printf("On key released from Main Window : %s\n", gtk_widget_get_name(widget)); + DEBUG("On key released from Main Window : %s\n", gtk_widget_get_name(widget)); - // if ((active_calltree != contacts) && (active_calltree != history)) { - if (gtk_widget_is_focus(window)){ - printf("Focus is on main window \n"); - } - if (!GTK_WIDGET_CAN_FOCUS(widget)){ - printf("Widget can't focus \n"); - gtk_widget_grab_focus(GTK_WIDGET(window)); - } - - if (gtk_widget_is_focus (window)) { + if (focus_is_on_searchbar == FALSE) { // If a modifier key is pressed, it's a shortcut, pass along if(event->state & GDK_CONTROL_MASK || event->state & GDK_MOD1_MASK || @@ -131,24 +120,34 @@ on_key_released (GtkWidget *widget, return FALSE; else sflphone_keypad(event->keyval, event->string); - } + } + return TRUE; } +void +focus_on_mainwindow_out(){ + DEBUG("focus_on_mainwindow_out \n"); + // gtk_widget_grab_focus(GTK_WIDGET(window)); + +} void -set_focus_on_mainwindow(){ - DEBUG("set_focus_on_mainwindow \n"); - gtk_widget_grab_focus(GTK_WIDGET(window)); +focus_on_mainwindow_in(){ + DEBUG("focus_on_mainwindow_in \n"); + // gtk_widget_grab_focus(GTK_WIDGET(window)); } -*/ + void create_main_window () { GtkWidget *widget; + focus_is_on_calltree = FALSE; + focus_is_on_searchbar = FALSE; + window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width (GTK_CONTAINER (window), 0); gtk_window_set_title (GTK_WINDOW (window), PACKAGE); @@ -161,17 +160,21 @@ create_main_window () // gtk_widget_grab_focus (GTK_WIDGET(window)); /* Connect the destroy event of the window with our on_destroy function - * When the window is about to be destroyed we get a notificaiton and - * stop the main GTK loop - */ + * When the window is about to be destroyed we get a notificaiton and + * stop the main GTK loop + */ g_signal_connect (G_OBJECT (window), "delete-event", G_CALLBACK (on_delete), NULL); - // g_signal_connect (G_OBJECT (window), "key-release-event", - // G_CALLBACK (on_key_released), NULL); + g_signal_connect (G_OBJECT (window), "key-release-event", + G_CALLBACK (on_key_released), NULL); + + g_signal_connect_after (G_OBJECT (window), "focus-in-event", + G_CALLBACK (focus_on_mainwindow_in), NULL); - // g_signal_connect (G_OBJECT (window), "client-event", - // G_CALLBACK (set_focus_on_mainwindow), NULL); + g_signal_connect_after (G_OBJECT (window), "focus-out-event", + G_CALLBACK (focus_on_mainwindow_out), NULL); + gtk_widget_set_name (window, "mainwindow"); diff --git a/sflphone-client-gnome/src/mainwindow.h b/sflphone-client-gnome/src/mainwindow.h index 956f982c0c8549f1c592eee721be1bcac870c334..bdf3c0af125353ceb8ffa9ba4f7894805b004746 100644 --- a/sflphone-client-gnome/src/mainwindow.h +++ b/sflphone-client-gnome/src/mainwindow.h @@ -21,6 +21,7 @@ #define __MAINWINDOW_H__ #include <calllist.h> +#include <calltree.h> /** @file mainwindow.h * @brief The main window of the client. @@ -91,5 +92,13 @@ void statusbar_pop_message( guint id ); void main_window_searchbar( gboolean *state ); +//static gboolean +//on_key_released (GtkWidget *widget, GdkEventKey *event, +// gpointer user_data); // void set_focus_on_mainwindow(); + +gboolean focus_is_on_calltree; + +gboolean focus_is_on_searchbar; + #endif diff --git a/sflphone-common/debian/changelog b/sflphone-common/debian/changelog index 0a2a850db5d24edb880e1d7d22430fc8bfcd5b1c..88b8e4367280db0d36866c4595c44f72a0b4d6fb 100644 --- a/sflphone-common/debian/changelog +++ b/sflphone-common/debian/changelog @@ -1,19 +1,3 @@ -sflphone-common (0.9.5-0ubuntu1~1.gbp22d013) SYSTEM; urgency=low - - ** SNAPSHOT build @22d0135a841ca830bf4ff57ba068506b919fb86e ** - - [ SFLphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1~rc1 - - [ Emmanuel Milou ] - * [#1402] Build the daemon with the local pjsip library (vs the - installed one) - * [#1402] Add info message after configure - - [ Sflphone Project ] - - -- Sflphone Project <sflphone@mtl.savoirfairelinux.net> Fri, 08 May 2009 00:01:55 -0400 - sflphone-common (0.9.5-0ubuntu1~rc1) SYSTEM; urgency=low [ SFLphone Project ] @@ -43,145 +27,6 @@ sflphone-common (0.9.5-0ubuntu1~rc1) SYSTEM; urgency=low -- Sflphone Project <sflphone@mtl.savoirfairelinux.net> Tue, 05 May 2009 19:16:09 -0400 -sflphone-common (0.9.5-0ubuntu1~6.gbpdfcd86) SYSTEM; urgency=low - - ** SNAPSHOT build @dfcd86f7fdabcc0462e8e5aef3a21ada929e077b ** - - [ Emmanuel Milou ] - * [#1220] Add Conflicts: sflphone in debian control files - * [#1179] Add liblog4c3 runtime dependency - * [#1212] FIx typo error in dependency list for itnrepid - * [#1212] FIx .desktop file to point on the right exec - * [#1212] Modify changelog replacing tag - - [ Sflphone Project ] - * "[#1262] Updated changelogs for version 0.9.5-0ubuntu1~beta" - - [ Emmanuel Milou ] - * [#1212] restore changelogs - - [ Sflphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 04-27 - - [ Emmanuel Milou ] - * [#1212] restore changelogs - - [ Sflphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1~beta - - [ Emmanuel Milou ] - * [#1212] restore changelogs - - [ Sflphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1~beta - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 04-28 - - [ Emmanuel Milou ] - * [#1212] Restore changelogs - - [ Sflphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 04-28 - - [ Julien Bonjean ] - * [#1262]Introduced dynamic version setting - - [ Sflphone Project ] - - [ Alexandre Savard ] - * [#1143] Add celtcodec.cpp - * [#1143] add configure and make stuffs - * [#1143] add frame size into each codecs - * [#1143] Take timestamp's step size from codec - * [#1143] RTP thread at 11 ms - * [#1143] Dynamic RTP thread sleep parameter - * [#1143] Fix dynamic thread sleep time calculation - - [ Emmanuel Milou ] - * [#1262] sflphone-client-gnome uses changelog version number - - [ Alexandre Savard ] - * [#1143] Some cleanup - - [ SFLphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 04-29 - - [ Emmanuel Milou ] - * [#1262] Update changelogs - * [#1262] Update rules - * [#1143] Build celt codec only if version >= 0.5.1 is detected - * [1143] Restore rules files - do not need to specify --without-celt - * [#1336] Change SFLphone logo - * [#1331] Fix searchbar problems - * [#1332] Fix unexplicit labels - * [#1334] Fix unexplicit label - * [#1329] Fix recordings config panel - - [ Sflphone Project ] - - [ SFLphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 04-30 - - [ Emmanuel Milou ] - * [#1336] Add new logo - * [#1335] Enable/disable address book, change option name - * [#1324] Add more insightful status bar message - * [#1330] Fix behaviour if no addressbook are active - - [ Sflphone Project ] - - [ SFLphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 05-01 - - [ Julien Bonjean ] - * [#1161] Added build system scripts - - [ Emmanuel Milou ] - * [#1215] Redesign current account computing - * [#1333] Remove default voicemail number - * [#1333] Voicemail icon update if current account has no voicemail - number + unit tests - * [#1333] Remove default voicemail number in assistant; update status - bar message - * [#1333] Add voicemail number field in wizard - * [#1342] Make config panels more GNOME compliant - - [ Sflphone Project ] - - [ Alexandre Savard ] - * [#1143] Fixed auio record after celt refactoring - * [#1327] Alsa display unappropriate info - * [#1328] Unappropriate label in audio preferences panel - * [#1316] Forgot 's' to RFC3969 'sip:' URI when calling in unicast - mode - * [#1316] #define IP_TO_IP_PATTERN "sip:" - * [#1316] 'sip:' subtitution to 4 char - * [#1321] Startup wizard password display is inconsistent - * [#1325] Error window in preferences shows formatting error - * [#1325] Proposed Implementation - * [#1325] Add title to window - * [#1343] Moved key stroke signal from call tree to main window - * [#1343] Dialing on key strike disabled when either history or - contact selected - * [#1343] Cannot dial when focus not on white frame - - [ SFLphone Project ] - * [#1262] Updated changelogs for version 0.9.5-0ubuntu1 Snapshot 2009- - 05-02 - - [ Emmanuel Milou ] - * [#1331] Fix clear default message bug - * [#936] Remove old codecs from repository - - [ Sflphone Project ] - - -- Sflphone Project <sflphone@mtl.savoirfairelinux.net> Tue, 05 May 2009 00:02:13 -0400 - sflphone-common (0.9.5-0ubuntu1~beta) SYSTEM; urgency=low [ Julien Bonjean ] diff --git a/sflphone-common/src/audio/alsalayer.cpp b/sflphone-common/src/audio/alsalayer.cpp index 2d2811b363722e41d4a2d774182eec2ef21681e4..2a3939bfc37fd012bb27fb36ef56b3ba9a705786 100644 --- a/sflphone-common/src/audio/alsalayer.cpp +++ b/sflphone-common/src/audio/alsalayer.cpp @@ -50,7 +50,7 @@ AlsaLayer::~AlsaLayer (void) closeLayer(); } - void +bool AlsaLayer::closeLayer() { _debugAlsa("Close ALSA streams\n"); @@ -73,6 +73,8 @@ AlsaLayer::closeLayer() _CaptureHandle = 0; _PlaybackHandle = 0; + + return true; } bool diff --git a/sflphone-common/src/audio/alsalayer.h b/sflphone-common/src/audio/alsalayer.h index 1a392f691e0534eeff24ce80b20c2b8bc5c6768a..27259dd0c4f707dbaba833d929dab3c44d496c57 100644 --- a/sflphone-common/src/audio/alsalayer.h +++ b/sflphone-common/src/audio/alsalayer.h @@ -48,7 +48,7 @@ class AlsaLayer : public AudioLayer { */ ~AlsaLayer(void); - void closeLayer( void ); + bool closeLayer( void ); /** * Check if no devices are opened, otherwise close them. diff --git a/sflphone-common/src/audio/audiolayer.h b/sflphone-common/src/audio/audiolayer.h index 679738b68c7fc15242eff85fd5e52c6068687f2f..f7d5404ef44218de97f5e3f4ae2233b29bd82a34 100644 --- a/sflphone-common/src/audio/audiolayer.h +++ b/sflphone-common/src/audio/audiolayer.h @@ -76,7 +76,7 @@ class AudioLayer { */ virtual ~AudioLayer(void) {} - virtual void closeLayer( void ) = 0; + virtual bool closeLayer( void ) = 0; /** * Check if no devices are opened, otherwise close them. diff --git a/sflphone-common/src/audio/audiortp.cpp b/sflphone-common/src/audio/audiortp.cpp index 1b8077a94ce7e5806f3d7914cbb725dd09dbbf0a..4bd99083789a9caa777831b6c60c58deeabda770 100644 --- a/sflphone-common/src/audio/audiortp.cpp +++ b/sflphone-common/src/audio/audiortp.cpp @@ -572,8 +572,13 @@ AudioRtpRTX::run () { step = _codecFrameSize; int countTime = 0; // for receive - - int threadSleep = (_codecFrameSize * 1000) / _codecSampleRate; + + int threadSleep = 0; + if (_codecSampleRate != 0) + threadSleep = (_codecFrameSize * 1000) / _codecSampleRate; + else + threadSleep = _layerFrameSize; + TimerPort::setTimer(threadSleep); audiolayer->startStream(); diff --git a/sflphone-common/src/audio/audiostream.cpp b/sflphone-common/src/audio/audiostream.cpp index 01a56c974a63f160cb7cb1f8db1ebf3bd33c0690..08587fdb310803fe561ae208c025869f6b7ab86b 100644 --- a/sflphone-common/src/audio/audiostream.cpp +++ b/sflphone-common/src/audio/audiostream.cpp @@ -32,27 +32,52 @@ AudioStream::AudioStream( pa_context* context, int type, std::string desc, doubl channel_map.channels = 1; pa_cvolume_set( &_volume , 1 , PA_VOLUME_NORM ) ; // * vol / 100 ; - _audiostream = createStream( context ); + _context = context; + + // connectStream(); } AudioStream::~AudioStream() { - _debug("Destroy audio streams\n"); - pa_stream_disconnect( pulseStream() ); - pa_stream_unref( pulseStream() ); -} + disconnectStream(); +} + +bool +AudioStream::connectStream() +{ + ost::MutexLock guard(_mutex); + + if(!_audiostream) + _audiostream = createStream( _context ); + else { + disconnectStream(); + _audiostream = createStream( _context ); + } + + return true; +} -void -AudioStream::disconnect( void ) +bool +AudioStream::disconnectStream( void ) { + ost::MutexLock guard(_mutex); + _debug("Destroy audio streams\n"); - pa_stream_disconnect( pulseStream() ); - pa_stream_unref( pulseStream() ); + pa_stream_disconnect( _audiostream ); + pa_stream_unref( _audiostream ); + + _audiostream = NULL; + + return true; } + + void AudioStream::stream_state_callback( pa_stream* s, void* user_data UNUSED ) { + + _debug("AudioStream::stream_state_callback :: The state of the stream changed\n"); assert(s); switch(pa_stream_get_state(s)){ @@ -79,12 +104,20 @@ AudioStream::stream_state_callback( pa_stream* s, void* user_data UNUSED ) } } +pa_stream_state_t +AudioStream::getStreamState(void) { + + ost::MutexLock guard(_mutex); + return pa_stream_get_state(_audiostream); +} pa_stream* AudioStream::createStream( pa_context* c ) { + ost::MutexLock guard(_mutex); + pa_stream* s; //pa_cvolume cv; diff --git a/sflphone-common/src/audio/audiostream.h b/sflphone-common/src/audio/audiostream.h index 121b87ad9c70a4f5ef09c7865a9af2ac166c06d3..f21e4b0d27654a5efa5f28e919de6817de075d0b 100644 --- a/sflphone-common/src/audio/audiostream.h +++ b/sflphone-common/src/audio/audiostream.h @@ -27,6 +27,8 @@ #include "ringbuffer.h" #include "audioloop.h" +#include <cc++/thread.h> + /** * This data structure contains the different king of audio streams available */ @@ -68,10 +70,15 @@ class AudioStream { */ int putUrgent( void* buffer , int toCopy ); + /** + * Connect the pulse audio stream + */ + bool connectStream(); + /** * Disconnect the pulseaudio stream */ - void disconnect(); + bool disconnectStream(); /** * Accessor: Get the pulseaudio stream object @@ -94,6 +101,14 @@ class AudioStream { void setVolume( double pc ) { _volume.values[0] *= pc/100; } pa_cvolume getVolume( void ) { return _volume; } + /** + * Accessor + * @return stream state + */ + pa_stream_state_t getStreamState(void); + + + private: // Copy Constructor @@ -124,6 +139,11 @@ class AudioStream { */ void write( void ); + /** + * The pulse audio context + */ + pa_context* _context; + /** * The pulse audio object */ @@ -146,6 +166,8 @@ class AudioStream { pa_sample_spec sample_spec ; pa_cvolume _volume; + ost::Mutex _mutex; + }; #endif // _AUDIO_STREAM_H diff --git a/sflphone-common/src/audio/pulselayer.cpp b/sflphone-common/src/audio/pulselayer.cpp index 02c107ea976fd5ac17cc30a6363637a894be5ebb..fd71c8473568e414169c5be2eb3cd498f71fb2e9 100644 --- a/sflphone-common/src/audio/pulselayer.cpp +++ b/sflphone-common/src/audio/pulselayer.cpp @@ -41,6 +41,7 @@ static void audioCallback ( pa_stream* s, size_t bytes, void* userdata ) { PulseLayer::streamState = 0; _debug("PulseLayer::Pulse audio constructor: Create context\n"); + } // Destructor @@ -48,27 +49,31 @@ PulseLayer::~PulseLayer (void) { closeLayer (); - pa_context_disconnect( context ); - pa_context_unref( context ); + // pa_context_disconnect( context ); + // pa_context_unref( context ); } - void +bool PulseLayer::closeLayer( void ) { _debug("PulseLayer::closeLayer :: Destroy pulselayer\n"); - playback->disconnect(); - record->disconnect(); + playback->disconnectStream(); + record->disconnectStream(); - while(PulseLayer::streamState != 2) - ; + while(PulseLayer::streamState != 2); PulseLayer::streamState = 0; //TODO Remove this ugly hack sleep(2); + + pa_context_disconnect( context ); + pa_context_unref( context ); + + return true; } - void +void PulseLayer::connectPulseAudioServer( void ) { _debug("PulseLayer::connectPulseAudioServer \n"); @@ -123,33 +128,45 @@ void PulseLayer::context_state_callback( pa_context* c, void* user_data ) } } -void PulseLayer::disconnectPulseAudioServer( void ) +bool PulseLayer::disconnectPulseAudioServer( void ) { - _debug(" PulseLayer::disconnectPulseAudioServer( void ) \n"); - if( playback ) - delete playback; playback=NULL; + _debug(" PulseLayer::disconnectPulseAudioServer( void ) \n"); - if( record ) + if( playback ){ + // playback->disconnectStream(); + delete playback; playback=NULL; + } + if( record ){ + // record->disconnectStream(); delete record; record=NULL; + } + if (!playback && !record) + return true; + else + return false; } -void PulseLayer::createStreams( pa_context* c ) +bool PulseLayer::createStreams( pa_context* c ) { _debug("PulseLayer::createStreams \n"); playback = new AudioStream(c, PLAYBACK_STREAM, PLAYBACK_STREAM_NAME, _manager->getSpkrVolume()); + playback->connectStream(); pa_stream_set_write_callback( playback->pulseStream(), audioCallback, this); // pa_stream_set_overflow_callback( playback->pulseStream() , overflow , this); // pa_stream_set_suspended_callback( playback->pulseStream(), stream_suspended_callback, this); record = new AudioStream(c, CAPTURE_STREAM, CAPTURE_STREAM_NAME , _manager->getMicVolume()); + record->connectStream(); pa_stream_set_read_callback( record->pulseStream() , audioCallback, this); // pa_stream_set_underflow_callback( record->pulseStream() , underflow , this); // pa_stream_set_suspended_callback(record->pulseStream(), stream_suspended_callback, this); pa_threaded_mainloop_signal(m , 0); + + return true; } @@ -177,7 +194,7 @@ bool PulseLayer::openDevice(int indexIn UNUSED, int indexOut UNUSED, int sampleR // startStream(); _debug("Connection Done!! \n"); - return true; + } void PulseLayer::closeCaptureStream( void ) diff --git a/sflphone-common/src/audio/pulselayer.h b/sflphone-common/src/audio/pulselayer.h index ce2bc2e6af79d49dd5d049f952896c2b03956c44..beae9eacc2b5b7400aca9ccd6d25a79b98dcd1c8 100644 --- a/sflphone-common/src/audio/pulselayer.h +++ b/sflphone-common/src/audio/pulselayer.h @@ -37,7 +37,7 @@ class PulseLayer : public AudioLayer { PulseLayer(ManagerImpl* manager); ~PulseLayer(void); - void closeLayer( void ); + bool closeLayer( void ); /** * Check if no devices are opened, otherwise close them. @@ -153,7 +153,7 @@ class PulseLayer : public AudioLayer { * Create the audio streams into the given context * @param c The pulseaudio context */ - void createStreams( pa_context* c ); + bool createStreams( pa_context* c ); /** * Drop the pending frames and close the playback device @@ -168,7 +168,7 @@ class PulseLayer : public AudioLayer { /** * Close the connection with the local pulseaudio server */ - void disconnectPulseAudioServer( void ); + bool disconnectPulseAudioServer( void ); /** * Get some information about the pulseaudio server @@ -192,9 +192,12 @@ class PulseLayer : public AudioLayer { int spkrVolume; int micVolume; + // private: public: static int streamState; + + friend class AudioLayerTest; }; #endif // _PULSE_LAYER_H_ diff --git a/sflphone-common/src/dbus/configurationmanager.cpp b/sflphone-common/src/dbus/configurationmanager.cpp index 09be9dc26c1fcb5a9beb0d49fe32247478a98a97..86e60e0ed2102590c642ffae6b0ee4b7975ff0d5 100644 --- a/sflphone-common/src/dbus/configurationmanager.cpp +++ b/sflphone-common/src/dbus/configurationmanager.cpp @@ -36,6 +36,7 @@ const char* ConfigurationManager::SERVER_PATH = "/org/sflphone/SFLphone/Configur std::map< std::string, std::string > ConfigurationManager::getAccountDetails( const std::string& accountID ) { + _debug("ConfigurationManager::getAccountDetails\n"); return Manager::instance().getAccountDetails(accountID); } @@ -50,6 +51,7 @@ ConfigurationManager::setAccountDetails( const std::string& accountID, void ConfigurationManager::sendRegister( const std::string& accountID, const int32_t& expire ) { + _debug("ConfigurationManager::sendRegister received\n"); Manager::instance().sendRegister(accountID, expire); } @@ -109,12 +111,14 @@ ConfigurationManager::getRingtoneList( ) std::vector< std::string > ConfigurationManager::getCodecList( ) { + _debug("ConfigurationManager::getRingtoneList received\n"); return Manager::instance().getCodecList(); } std::vector< std::string > ConfigurationManager::getCodecDetails( const int32_t& payload ) { + _debug("ConfigurationManager::getRingtoneList received\n"); return Manager::instance().getCodecDetails( payload ); } diff --git a/sflphone-common/src/managerimpl.cpp b/sflphone-common/src/managerimpl.cpp index 07135fd051959d32e5272de54c537127080825f1..a9886dd739a8159032bfe38097e1485f991aceef 100644 --- a/sflphone-common/src/managerimpl.cpp +++ b/sflphone-common/src/managerimpl.cpp @@ -1843,7 +1843,7 @@ int ManagerImpl::app_is_running( std::string process ) /** * Initialization: Main Thread */ - void +bool ManagerImpl::initAudioDriver(void) { @@ -1871,13 +1871,17 @@ ManagerImpl::initAudioDriver(void) if (_audiodriver == 0) { _debug("Init audio driver error\n"); + return false; } else { error = getAudioDriver()->getErrorMessage(); if (error == -1) { _debug("Init audio driver: %i\n", error); + return false; } } + return true; + } /** @@ -1974,7 +1978,7 @@ void ManagerImpl::switchAudioManager (void) // need to stop audio streams if there is currently no call if( (type != PULSEAUDIO) && (!hasCurrentCall())) { - _debug("There is currently a call!!\n"); + // _debug("There is currently a call!!\n"); _audiodriver->stopStream(); } diff --git a/sflphone-common/src/managerimpl.h b/sflphone-common/src/managerimpl.h index 86578e3285c0f4090a36823dce39b8429069f19a..758811d5cbfcee361f2dd88c7f144e8287d7bef0 100644 --- a/sflphone-common/src/managerimpl.h +++ b/sflphone-common/src/managerimpl.h @@ -880,6 +880,11 @@ class ManagerImpl { */ AccountMap getSipAccountMap( void ); + /* + * Initialize audiodriver + */ + bool initAudioDriver(void); + private: /** @@ -905,11 +910,7 @@ class ManagerImpl { */ void initAudioCodec(void); - /* - * Initialize audiodriver - */ - void initAudioDriver(void); - + /* * Initialize zeroconf module and scanning */ diff --git a/sflphone-common/test/Makefile.am b/sflphone-common/test/Makefile.am index 8f3003587d6e748791b0407c6465ad85d2d6343d..5b89c3b709cc04d76ae52041c63ce96d1b5a8b66 100644 --- a/sflphone-common/test/Makefile.am +++ b/sflphone-common/test/Makefile.am @@ -1,6 +1,6 @@ include ../globals.mak -bin_PROGRAMS = numbercleanerTester pluginmanagerTester hookmanagerTester +bin_PROGRAMS = numbercleanerTester pluginmanagerTester hookmanagerTester audiolayerTester OBJECT_FILES= \ ../src/sflphoned-managerimpl.o \ @@ -78,3 +78,21 @@ hookmanagerTester_LDADD = \ -luuid \ $(OBJECT_FILES) +audiolayerTester_SOURCES = \ + audiolayerTest.h \ + audiolayerTest.cpp \ + TestMain.cpp + +audiolayerTester_LDADD = \ + ../src/libsflphone.la \ + $(SFLPHONE_LIBS) $(ZEROCONFLIB) $(LIB_DNSSD) \ + @ALSA_LIBS@ \ + @PULSEAUDIO_LIBS@ \ + @CPPUNIT_LIBS@ \ + @CCEXT2_LIBS@ \ + @CCGNU2_LIBS@ \ + @CCRTP_LIBS@ \ + @SAMPLERATE_LIBS@ \ + $(PJSIP_LIBS) \ + -luuid \ + $(OBJECT_FILES) \ No newline at end of file diff --git a/sflphone-common/test/audiolayerTest.cpp b/sflphone-common/test/audiolayerTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4a4b6396f32bc50f9f9a036a9455d139dbb8dad1 --- /dev/null +++ b/sflphone-common/test/audiolayerTest.cpp @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdio.h> +#include <sstream> + +#include "audiolayerTest.h" + +#include <unistd.h> + + +using std::cout; +using std::endl; + + + +void AudioLayerTest::setUp(){ + + // Instanciate the manager + Manager::instance().initConfigFile(); + Manager::instance().init(); + + // _audiodriver = Manager::instance().getAudioDriver(); + + // std::string alsaPlugin; + // AlsaLayer *alsalayer; + + // int numCardIn, numCardOut, sampleRate, frameSize; + // layer = _audiodriver->getLayerType(); + + /* + alsaPlugin = Manager::instance().getConfigString( AUDIO , ALSA_PLUGIN ); + numCardIn = Manager::instance().getConfigInt( AUDIO , ALSA_CARD_ID_IN ); + numCardOut = Manager::instance().getConfigInt( AUDIO , ALSA_CARD_ID_OUT ); + sampleRate = Manager::instance().getConfigInt( AUDIO , ALSA_SAMPLE_RATE ); + if (sampleRate <=0 || sampleRate > 48000) { + sampleRate = 44100; + } + frameSize = Manager::instance().getConfigInt(AUDIO, ALSA_FRAME_SIZE ); + */ + + // get a pointer to the audio layer + // _audiodriver = Manager::instance().getAudioDriver(); + +} + +void AudioLayerTest::testAudioLayerConfig(){ + int sampling_rate = Manager::instance().getConfigInt(AUDIO, ALSA_SAMPLE_RATE); + int frame_size = Manager::instance().getConfigInt(AUDIO, ALSA_FRAME_SIZE); + + CPPUNIT_ASSERT(Manager::instance().getAudioDriver()->getSampleRate() == sampling_rate); + CPPUNIT_ASSERT(Manager::instance().getAudioDriver()->getFrameSize() == frame_size); +} + +void AudioLayerTest::testAudioLayerSwitch(){ + + _debug("---------- AudioLayerTest::testAudioLayerSwitch ---------------------------\n"); + + + int previous_layer = Manager::instance().getAudioDriver()->getLayerType(); + + for(int i = 0; i < 2; i++) { + _debug("---------- AudioLayerTest::testAudioLayerSwitch - %i -------------\n",i); + Manager::instance().switchAudioManager(); + if(previous_layer == ALSA) { + CPPUNIT_ASSERT(Manager::instance().getAudioDriver()->getLayerType() == PULSEAUDIO); + } + else { + CPPUNIT_ASSERT(Manager::instance().getAudioDriver()->getLayerType() == ALSA); + } + previous_layer = Manager::instance().getAudioDriver()->getLayerType(); + usleep(100000); + } +} + + + +void AudioLayerTest::testPulseConnect(){ + + _debug("---------- AudioLayerTest::testPulseConnect ---------------------------\n"); + + ManagerImpl* manager; + manager = &Manager::instance(); + + _pulselayer = new PulseLayer(manager); + + CPPUNIT_ASSERT(_pulselayer->getLayerType() == PULSEAUDIO); + + std::string alsaPlugin; + int numCardIn, numCardOut, sampleRate, frameSize; + + alsaPlugin = manager->getConfigString( AUDIO , ALSA_PLUGIN ); + numCardIn = manager->getConfigInt( AUDIO , ALSA_CARD_ID_IN ); + numCardOut = manager->getConfigInt( AUDIO , ALSA_CARD_ID_OUT ); + sampleRate = manager->getConfigInt( AUDIO , ALSA_SAMPLE_RATE ); + frameSize = manager->getConfigInt(AUDIO, ALSA_FRAME_SIZE ); + + CPPUNIT_ASSERT(_pulselayer->getPlaybackStream() == NULL); + CPPUNIT_ASSERT(_pulselayer->getRecordStream() == NULL); + + _pulselayer->setErrorMessage(-1); + try { + CPPUNIT_ASSERT(_pulselayer->openDevice(numCardIn, numCardOut, sampleRate, frameSize, SFL_PCM_BOTH, alsaPlugin) == true); + } + catch (...) { + _debug("Exception occured wile opening device! \n"); + } + + usleep(100000); + + CPPUNIT_ASSERT(_pulselayer->getPlaybackStream() != NULL); + CPPUNIT_ASSERT(_pulselayer->getRecordStream() != NULL); + + CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->pulseStream() != NULL); + CPPUNIT_ASSERT(_pulselayer->getRecordStream()->pulseStream() != NULL); + + // Must return Access failure "PA_ERR_ACCESS" == 2 + CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->getStreamState() == 2); + CPPUNIT_ASSERT(_pulselayer->getRecordStream()->getStreamState() == 2); + + CPPUNIT_ASSERT(_pulselayer->createStreams(_pulselayer->context) == true); + + // usleep(1000000); + + CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->pulseStream() != NULL); + CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->pulseStream() != NULL); + + // Must return No error "PA_OK" == 1 + CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->getStreamState() == 1); + CPPUNIT_ASSERT(_pulselayer->getRecordStream()->getStreamState() == 1); + + CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->disconnectStream() == true); + CPPUNIT_ASSERT(_pulselayer->getRecordStream()->disconnectStream() == true); + + // _debug("%i\n",_pulselayer->getPlaybackStream()->getStreamState()); + + CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->connectStream() == true); + CPPUNIT_ASSERT(_pulselayer->getRecordStream()->connectStream() == true); + + CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->getStreamState() == 1); + CPPUNIT_ASSERT(_pulselayer->getRecordStream()->getStreamState() == 1); + + CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->connectStream() == true); + CPPUNIT_ASSERT(_pulselayer->getRecordStream()->connectStream() == true); + + CPPUNIT_ASSERT(_pulselayer->getPlaybackStream()->getStreamState() == 1); + CPPUNIT_ASSERT(_pulselayer->getRecordStream()->getStreamState() == 1); + + // usleep(1000000); + CPPUNIT_ASSERT(_pulselayer->disconnectPulseAudioServer() == true); +} + + +void AudioLayerTest::testAlsaConnect(){ + + _debug("---------- AudioLayerTest::testAlsaConnect ---------------------------\n"); + + int layer = Manager::instance().getAudioDriver()->getLayerType(); + + int type, samplerate, framesize, numCardIn, numCardOut; + std::string alsaPlugin; + + if (layer != ALSA) { + Manager::instance().switchAudioManager(); + usleep(100000); + } + + // _audiolayer = Manager::instance().getAudioDriver(); + + // CPPUNIT_ASSERT(_audiolayer->closeLayer() == true); + // usleep(100000); + + // delete _audiolayer; _audiolayer == NULL; + + Manager::instance().setConfig( PREFERENCES, CONFIG_AUDIO, ALSA); + + + // _audiolayer->setErrorMessage(-1); + // CPPUNIT_ASSERT(Manager::instance().initAudioDriver() == true); + + // _audiolayer = Manager::instance().getAudioDriver(); + + // CPPUNIT_ASSERT(_audiolayer->getLayerType() == ALSA); + +} + +void AudioLayerTest::tearDown(){ + // Delete the audio recorder module + // delete _ar; _ar = NULL; +} diff --git a/sflphone-common/test/audiolayerTest.h b/sflphone-common/test/audiolayerTest.h new file mode 100644 index 0000000000000000000000000000000000000000..87c13a7a8503513d630042b24481ec71e68801e9 --- /dev/null +++ b/sflphone-common/test/audiolayerTest.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2009 Savoir-Faire Linux inc. + * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +// Cppunit import +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCaller.h> +#include <cppunit/TestCase.h> +#include <cppunit/TestSuite.h> + +#include <assert.h> + +// Application import +#include "manager.h" + +#include "config/config.h" +#include "user_cfg.h" + +#include "audio/audiolayer.h" +#include "audio/alsalayer.h" +#include "audio/pulselayer.h" + +/* + * @file audiorecorderTest.cpp + * @brief Regroups unitary tests related to the plugin manager. + */ + +#ifndef _AUDIOLAYER_TEST_ +#define _AUDIOLAYER_TEST_ + + + +class AudioLayerTest : public CppUnit::TestCase { + + /* + * Use cppunit library macros to add unit test the factory + */ + CPPUNIT_TEST_SUITE( AudioLayerTest ); + CPPUNIT_TEST( testAudioLayerConfig ); + // CPPUNIT_TEST( testAudioLayerSwitch ); + CPPUNIT_TEST( testPulseConnect ); + // CPPUNIT_TEST( testAlsaConnect ); + CPPUNIT_TEST_SUITE_END(); + + public: + AudioLayerTest() : CppUnit::TestCase("Audio Layer Tests") {} + + /* + * Code factoring - Common resources can be initialized here. + * This method is called by unitcpp before each test + */ + void setUp(); + + /* + * Code factoring - Common resources can be released here. + * This method is called by unitcpp after each test + */ + inline void tearDown(); + + void testAudioLayerConfig(); + void testAudioLayerSwitch(); + void testPulseConnect(); + void testAlsaConnect(); + + private: + + ManagerImpl* manager; + + PulseLayer* _pulselayer; + + int layer; +}; + +/* Register our test module */ +CPPUNIT_TEST_SUITE_REGISTRATION( AudioLayerTest ); + +#endif diff --git a/sflphone-common/test/audiorecorderTest.cpp b/sflphone-common/test/audiorecorderTest.cpp index 30650f9d0ee2c5d36fa45d8d40e02552de8a8481..9c0bf863edb284f29fcd5f7361c6ede3da6b68a8 100644 --- a/sflphone-common/test/audiorecorderTest.cpp +++ b/sflphone-common/test/audiorecorderTest.cpp @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * along with this program; if not, write to the Free Software- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ diff --git a/sflphone-common/test/audiorecorderTest.h b/sflphone-common/test/audiorecorderTest.h index 1748bda1db973fd4063dda0872a90bf9c09af5e8..216b657079562007a1eb04955f390e3263ef1c87 100644 --- a/sflphone-common/test/audiorecorderTest.h +++ b/sflphone-common/test/audiorecorderTest.h @@ -1,4 +1,4 @@ -x/* +/* * Copyright (C) 2009 Savoir-Faire Linux inc. * Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com> * diff --git a/tools/pysflphone/pysflphone.py b/tools/pysflphone/pysflphone.py new file mode 100644 index 0000000000000000000000000000000000000000..d100b6b8167eed92decf0b40e0c0c10b3b218d3b --- /dev/null +++ b/tools/pysflphone/pysflphone.py @@ -0,0 +1,269 @@ +#!/usr/bin/env python +# +# Copyright (C) 2009 by the Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + + +import sys +import os +import random +from traceback import print_exc + +import gobject +from gobject import GObject + +import getopt + +import time + +from threading import Thread + +from Errors import * + +try: + import dbus + from dbus.mainloop.glib import DBusGMainLoop +except ImportError, e: + raise SflPhoneError("No python-dbus module found") + + +from sflphonectrlsimple import SflPhoneCtrlSimple + +# +# Main application +# + + +def printHelp(): + """Print help""" + print sys.argv[0] + " usage:\n\ +\n\ + --help Print this help.\n\ +\n\ + --gaa Get all accounts.\n\ + --gara Get all registered accounts. \n\ + --gaea Get all enabled accounts. \n\ + --gasa Get all SIP accounts. \n\ + --gaia Get all IAX accounts. \n\ + --gcc Get current callid. \n\ + --gacl Get active codec list. \n\ + \n\ + --gad <account> Get account details . \n\ + --enable <account> Enable the account. \n\ + --disable <account> Disable the account. \n\ + --register <account> Register the account. \n\ + --unregister <account> Unregister the account. \n\ + \n\ + --call <destination> Call to number \n\ + --transfer <destination> Transfer active call \n\ +\n\ + --gcd <callid|\"current\"> Get call details. \n\ + --accept <callid|\"current\"> Accept the call \n\ + --hangup <callid|\"current\"> Hangup the call \n\ + --refuse <callid|\"current\"> Refuse the call \n\ + --hold <callid|\"current\"> Hold the call \n\ + --unhold <callid|\"current\"> Unhold the call \n\ + --dtmf <key> Send DTMF\n" + + + +# Option definition +try: + opts, args = getopt.getopt(sys.argv[1:],"", [ "help", "gaa", "gal", "gara", "gaea", "gasa", "gaia", "gacl", "gac", "gcc", + "hangup=", "refuse=", "hold", "unhold=", "transfer=","dtmf=", "accept=", + "gcd=", "gad=", "register=", "unregister=", "enable=", "disable=", "call=" ]) +except getopt.GetoptError,err: + print str(err) + sys.exit(2) + + +# SFLPhone instance. +sflphone = SflPhoneCtrlSimple() + +# If no arguments, run the d-bus event loop. +if len(sys.argv) == 1: + loop = gobject.MainLoop() + loop.run() + +# Parse all arguments +else: + for opt, arg in opts: + + if opt == "--help": + printHelp() + + # + # info options + # + + # Get all accounts + elif opt == "--gaa": + for account in sflphone.getAllAccounts(): + print account + + # Get all registered accounts + elif opt == "--gara": + for account in sflphone.getAllRegisteredAccounts(): + print account + + # Get all enabled accounts + elif opt == "--gaea": + for account in sflphone.getAllEnabledAccounts(): + print account + + # Get all SIP accounts + elif opt == "--gasa": + for account in sflphone.getAllSipAccounts(): + print account + + # Get all IAX accounts + elif opt == "--gaia": + for account in sflphone.getAllIaxAccounts(): + print account + + # Get current call + elif opt == "--gcc": + call = sflphone.getCurrentCallID() + if call: + print call + else: + print "No current call." + + # Get account details + elif opt == "--gad": + if sflphone.checkAccountExists(arg): + details = sflphone.getAccountDetails(arg) + for var in details: + print var + ": " + details[var] + else: + print "No such account: " + arg + + # Get active codec list + elif opt == "--gacl": + print "Not implemented." + + # Get call details + elif opt == "--gcd": + if arg == "current": arg = sflphone.getCurrentCallID() + + details = sflphone.getCallDetails(arg) + if details: + print "Call: " + arg + print "Account: " + details['ACCOUNTID'] + print "Peer: " + details['PEER_NAME'] + "<" + details['PEER_NUMBER'] + ">" + + + # + # call options + # + + # Make a call + elif opt == "--call": + sflphone.Call(arg) + + # Hangup a call + elif opt == "--hangup": + if arg == "current": + arg = sflphone.getCurrentCallID() + + if arg: + sflphone.HangUp(arg) + + # Refuse a call + elif opt == "--refuse": + if arg == "current": arg = sflphone.getCurrentCallID() + sflphone.Refuse(arg) + + # Hold a call + elif opt == "--hold": + if arg == "current": arg = sflphone.getCurrentCallID() + sflphone.Hold(arg) + + # Unhold a call + elif opt == "--unhold": + if arg == "current": arg = sflphone.getCurrentCallID() + sflphone.UnHold(arg) + + # Transfer the current call + elif opt == "--transfer": + call = sflphone.callmanager.getCurrentCallID() + sflphone.Transfert(call, arg) + + # Send DTMF + elif opt == "--dtmf": + sflphone.Dtmf(arg) + + # Accept a call + elif opt == "--accept": + if arg == "current": arg = sflphone.getCurrentCallID() + sflphone.Accept(arg) + + + # + # account options + # + + # Register an account + elif opt == "--register": + if not sflphone.checkAccountExists(arg): + print "Account " + arg + ": no such account." + + elif arg in sflphone.getAllRegisteredAccounts(): + print "Account " + arg + ": already registered." + + else: + sflphone.setAccountRegistered(arg, True) + print arg + ": Sent register request." + + # Unregister an account + elif opt == "--unregister": + if not sflphone.checkAccountExists(arg): + print "Account " + arg + ": no such account." + + elif arg not in sflphone.getAllRegisteredAccounts(): + print "Account " + arg + ": is not registered." + + else: + sflphone.setAccountRegistered(arg, False) + print arg + ": Sent unregister request." + + # Enable an account + elif opt == "--enable": + if not sflphone.checkAccountExists(arg): + print "Account " + arg + ": no such account." + + elif sflphone.isAccountEnable(arg): + print "Account " + arg + ": already enabled." + + else: + sflphone.setAccountEnable(arg, True) + print arg + ": Account enabled." + + # Disable an account + elif opt == "--disable": + if not sflphone.checkAccountExists(arg): + print "Account " + arg + ": no such account." + + elif not sflphone.isAccountEnable(arg): + print "Account " + arg + ": already disabled." + + else: + sflphone.setAccountRegistered(arg, False) + sflphone.setAccountEnable(arg, False) + print arg + ": Account disabled." + + diff --git a/tools/pysflphone/pysflphone_testdbus.py b/tools/pysflphone/pysflphone_testdbus.py new file mode 100644 index 0000000000000000000000000000000000000000..52f58ba132bc940815836cc344ea286132d55d4d --- /dev/null +++ b/tools/pysflphone/pysflphone_testdbus.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +from sflphonectrlsimple import SflPhoneCtrlSimple + + +class SflPhoneTests(SflPhoneCtrlSimple): + + def test_get_allaccounts_methods(self): + + print "--- getAllAccounts() ---" + for account in self.getAllAccounts(): + print " " + account + print "\n" + + print "--- getAllRegisteredAccounts() ---" + for account in self.getAllRegisteredAccounts(): + print " " + account + print "\n" + + print "--- getAllSipAccounts() ---" + for account in self.getAllSipAccounts(): + print " " + account + print "\n" + + print "--- getAllIaxAccounts() ---" + for account in self.getAllIaxAccounts(): + print " " + account + print "\n" + + # def test_codecs_methods(self): + +# print "--- getCodecList() ---" +# for codec int self.getCodecList(): +# print " " + codec +# print "\n" + + +sfl = SflPhoneTests() + +sfl.test_get_allaccounts_methods() + + + + + + diff --git a/tools/pysflphone/sflphonectrlsimple.py b/tools/pysflphone/sflphonectrlsimple.py index e629506c73efe3255562c77b1d862e8dec8f1df5..a7d0a5ee2a7bad04adcb6f09b80ff6d4fadae411 100755 --- a/tools/pysflphone/sflphonectrlsimple.py +++ b/tools/pysflphone/sflphonectrlsimple.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (C) 2008 by the Free Software Foundation, Inc. +# Copyright (C) 2009 by the Free Software Foundation, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -23,23 +23,33 @@ import os import random from traceback import print_exc +import gobject +from gobject import GObject + +import getopt + +import time +import md5 + +from threading import Thread + from Errors import * try: - import dbus + import dbus + from dbus.mainloop.glib import DBusGMainLoop except ImportError, e: - raise SflPhoneError("No python-dbus module found") - -# TODO list -# - handle signals to stay synchronzed with state of daemon (ie server registration can be lost anytime) + raise SflPhoneError("No python-dbus module found") class SflPhoneCtrlSimple(object): """Simple class for controlling SflPhoned through DBUS""" + # list of active calls (known by the client) + activeCalls = {} def __init__(self, name=sys.argv[0]): - # current active account + # current active account self.account = None # client name self.name = name @@ -59,31 +69,37 @@ class SflPhoneCtrlSimple(object): return try: + # register the main loop for d-bus events + DBusGMainLoop(set_as_default=True) self.bus = dbus.SessionBus() except dbus.DBusException, e: raise SPdbusError("Unable to connect DBUS session bus") - dbus_objects = dbus.Interface(self.bus.get_object('org.freedesktop.DBus', '/org/freedesktop/DBus'), 'org.freedesktop.DBus').ListNames() + dbus_objects = dbus.Interface(self.bus.get_object( + 'org.freedesktop.DBus', '/org/freedesktop/DBus'), + 'org.freedesktop.DBus').ListNames() + if not "org.sflphone.SFLphone" in dbus_objects: raise SPdbusError("Unable to find org.sflphone.SFLphone in DBUS. Check if sflphoned is running") try: proxy_instance = self.bus.get_object("org.sflphone.SFLphone", - "/org/sflphone/SFLphone/Instance", - introspect=False) + "/org/sflphone/SFLphone/Instance", introspect=False) proxy_callmgr = self.bus.get_object("org.sflphone.SFLphone", - "/org/sflphone/SFLphone/CallManager", - introspect=False) - proxy_confmgr = self.bus.get_object("org.sflphone.SFLphone", - "/org/sflphone/SFLphone/ConfigurationManager", - introspect=False) + "/org/sflphone/SFLphone/CallManager", introspect=False) + proxy_confmgr = self.bus.get_object("org.sflphone.SFLphone", + "/org/sflphone/SFLphone/ConfigurationManager", + introspect=False) + self.instance = dbus.Interface(proxy_instance, - "org.sflphone.SFLphone.Instance") + "org.sflphone.SFLphone.Instance") self.callmanager = dbus.Interface(proxy_callmgr, - "org.sflphone.SFLphone.CallManager") + "org.sflphone.SFLphone.CallManager") self.configurationmanager = dbus.Interface(proxy_confmgr, - "org.sflphone.SFLphone.ConfigurationManager") + "org.sflphone.SFLphone.ConfigurationManager") + except dbus.DBusException, e: + raise SPdbusError("Unable to bind to sflphoned api, ask core-dev team to implement getVersion method and start to pray.") try: @@ -92,8 +108,15 @@ class SflPhoneCtrlSimple(object): except: raise SPdaemonError("Client registration failed") + try: + proxy_callmgr.connect_to_signal('incomingCall', self.onIncomingCall) + proxy_callmgr.connect_to_signal('callStateChanged', self.onCallStateChanged) + except dbus.DBusException, e: + print e + def unregister(self): + if not self.registered: return #raise SflPhoneError("Not registered !") @@ -107,18 +130,57 @@ class SflPhoneCtrlSimple(object): def isRegistered(self): return self.registered + + # + # Signal handling + # + + # On incoming call event, add the call to the list of active calls + def onIncomingCall(self, account, callid, to): + print "Incoming call: " + account + ", " + callid + ", " + to + self.activeCalls[callid] = {'Account': account, 'To': to, 'State': '' } + + # On call state changed event, set the values for new calls, + # or delete the call from the list of active calls + def onCallStateChanged(self, callid, state): + print "Call state changed: " + callid + ", " + state + if state == "HUNGUP": + try: + del self.activeCalls[callid] + except KeyError: + print "Call " + callid + " didn't exist. Cannot delete." + + elif state in [ "RINGING", "CURRENT", "INCOMING", "HOLD" ]: + try: + self.activeCalls[callid]['State'] = state + except KeyError, e: + print "This call didn't exist!: " + callid + ". Adding it to the list." + callDetails = self.getCallDetails(callid) + self.activeCalls[callid] = {'Account': callDetails['ACCOUNTID'], 'To': callDetails['PEER_NUMBER'], 'State': state } + elif state in [ "BUSY", "FAILURE" ]: + try: + del self.activeCalls[callid] + except KeyError, e: + print "This call didn't exist!: " + callid + +# elif state == "UNHOLD_CURRENT": +# self.activeCalls[callid]['State'] = "UNHOLD_CURRENT" + + # # Account management # - def getAccountList(self): + def getAllAccounts(self): + """ Return a list with all accounts""" return self.configurationmanager.getAccountList() - def getEnabledAccountList(self): - accounts = self.configurationmanager.getAccountList() + def getAllEnabledAccounts(self): + """ Return a list with all enabled accounts""" + accounts = self.getAllAccounts() activeaccounts = [] for testedaccount in accounts: - if ( self.configurationmanager.getAccountDetails(testedaccount)['Account.enable'] == "TRUE" ): + if self.isAccountEnable(testedaccount): activeaccounts.append(testedaccount) return activeaccounts @@ -129,35 +191,56 @@ class SflPhoneCtrlSimple(object): if account is None: if self.account is None: raise SflPhoneError("No provided or current account !") - return self.configurationmanager.getAccountDetails(self.account) + if checkAccountExists(self.account): + return self.configurationmanager.getAccountDetails(self.account) else: - return self.configurationmanager.getAccountDetails(account) + if self.checkAccountExists(account): + + return self.configurationmanager.getAccountDetails(account) def setAccountByAlias(self, alias): """Define as active the first account who match with the alias""" - for testedaccount in self.configurationmanager.getAccountList(): - details = self.configurationmanager.getAccountDetails(testedaccount) - if ( details['Account.enable'] == "TRUE" and details['Account.alias'] == alias ): + for testedaccount in self.getAllAccounts(): + details = self.getAccountDetails(testedaccount) + if ( details['Account.enable'] == "TRUE" and + details['Account.alias'] == alias ): self.account = testedaccount return - raise SPaccountError("No account matched with alias") + raise SPaccountError("No enabled account matched with alias") + def getAccountByAlias(self, alias): + """Get account name having its alias""" + + for account in self.getAllAccounts(): + details = self.getAccountDetails(account) + if details['Account.alias'] == alias: + return account + + raise SPaccountError("No account matched with alias") + def setAccount(self, account): """Define the active account""" - if account in self.getAccountList(): + if account in self.getAllAccounts(): self.account = account else: raise SflPhoneError("Not a valid account") + def setFirstRegisteredAccount(self): + """Find the first enabled account and define it as active""" + + rAccounts = self.getAllRegisteredAccounts() + if 0 == len(rAccounts): + raise SflPhoneError("No registered account !") + self.account = rAccounts[0] def setFirstActiveAccount(self): """Find the first enabled account and define it as active""" - aAccounts = self.getEnabledAccountList() + aAccounts = self.getAllEnabledAccounts() if 0 == len(aAccounts): raise SflPhoneError("No active account !") self.account = aAccounts[0] @@ -173,20 +256,113 @@ class SflPhoneCtrlSimple(object): """Return True if the account is registered. If no account is provided, active account is used""" if account is None: - if self.account is None: - raise SflPhoneError("No provided or current account !") - account = self.account - return self.configurationmanager.getAccountDetails(account)['Status'] == "REGISTERED" + if self.account is None: + raise SflPhoneError("No provided or current account !") + account = self.account + return self.getAccountDetails(account)['Status'] == "REGISTERED" def isAccountEnable(self, account=None): """Return True if the account is enabled. If no account is provided, active account is used""" if account is None: - if self.account is None: - raise SflPhoneError("No provided or current account !") - account = self.account - return self.configurationmanager.getAccountDetails(account)['Account.enable'] == "TRUE" + if self.account is None: + raise SflPhoneError("No provided or current account !") + account = self.account + return self.getAccountDetails(account)['Account.enable'] == "TRUE" + + def setAccountEnable(self, account=None, enable=False): + """Set account enabled""" + if account is None: + if self.account is None: + raise SflPhoneError("No provided or current account !") + account = self.account + + if enable == True: + details = self.getAccountDetails(account) + details['Account.enable'] = "TRUE" + self.configurationmanager.setAccountDetails(account, details) + else: + details = self.getAccountDetails(account) + details['Account.enable'] = "FALSE" + self.configurationmanager.setAccountDetails(account, details) + + def checkAccountExists(self, account=None): + """ Checks if the account exists """ + if account is None: + raise SflPhoneError("No provided or current account !") + return account in self.getAllAccounts() + + def getAllRegisteredAccounts(self): + """Return a list of registered accounts""" + + registeredAccountsList = [] + for account in self.getAllAccounts(): + if self.isAccountRegistered(account): + registeredAccountsList.append(account) + + return registeredAccountsList + + def getAllEnabledAccounts(self): + """Return a list of enabled accounts""" + + enabledAccountsList = [] + for accountName in self.getAllAccounts(): + if self.getAccountDetails(accountName)['Account.enable'] == "TRUE": + enabledAccountsList.append(accountName) + + return enabledAccountsList + + def getAllSipAccounts(self): + """Return a list of SIP accounts""" + + sipAccountsList = [] + for accountName in self.getAllAccounts(): + if self.getAccountDetails(accountName)['Account.type'] == "SIP": + sipAccountsList.append(accountName) + + return sipAccountsList + + def getAllIaxAccounts(self): + """Return a list of IAX accounts""" + + iaxAccountsList = [] + for accountName in self.getAllAccounts(): + if self.getAccountDetails(accountName)['Account.type'] == "IAX": + iaxAccountsList.append(accountName) + + return iaxAccountsList + + def setAccountRegistered(self, account=None, register=False): + """ Tries to register the account """ + + if account is None: + if self.account is None: + raise SflPhoneError("No provided or current account !") + account = self.account + + try: + if register: + self.configurationmanager.sendRegister(account, int(1)) + #self.setAccount(account) + else: + self.configurationmanager.sendRegister(account, int(0)) + #self.setFirstRegisteredAccount() + except SflPhoneError, e: + print e + + # + # Codec manager + # + + def getCodecList(self): + """ Return the codec list """ + return self.configurationmanager.getCodecList() + + def getActiveCodecList(self): + """ Return the active codec list """ + return self.configurationmanager.getActiveCodecList() + # @@ -199,32 +375,54 @@ class SflPhoneCtrlSimple(object): return self.callmanager.getCurrentCallID() - def getCallDetails(self): + def getCurrentCallDetails(self): """Return informations on the current call if any""" return self.callmanager.getCallDetails(self.getCurrentCallID()) + def getCallDetails(self, callid): + """Return informations on this call if exists""" + + return self.callmanager.getCallDetails(callid) + + def printClientCallList(self): + print "Client active call list:" + print "------------------------" + for call in self.activeCalls: + print "\t" + call # # Action # def Call(self, dest): """Start a call and return a CallID""" + if not self.account: + self.setFirstRegisteredAccount() if not self.isAccountRegistered(): raise SflPhoneError("Can't place a call without a registered account") if dest is None or dest == "": - pass # just to see - #raise SflPhoneError("Invalid call destination") + raise SflPhoneError("Invalid call destination") - callid = str(random.randrange(2**32-1)) + # callid = str(random.randrange(2**32-1)) + t = long( time.time() * 1000 ) + r = long( random.random()*100000000000000000L ) + data = str(t) + str(r) + callid = md5.md5(data).hexdigest() + + # Add the call to the list of active calls and set status to SENT + self.activeCalls[callid] = {'Account': self.account, 'To': dest, 'State': 'SENT' } + # Send the request to the CallManager self.callmanager.placeCall(self.account, callid, dest) + return callid def HangUp(self, callid): """End a call identified by a CallID""" + if not self.account: + self.setFirstRegisteredAccount() if not self.isAccountRegistered(): raise SflPhoneError("Can't hangup a call without a registered account") @@ -233,11 +431,13 @@ class SflPhoneCtrlSimple(object): pass # just to see #raise SflPhoneError("Invalid callID") - self.callmanager.hangUp(callid) + self.callmanager.hangUp(callid) - def Transfert(self, callid): + def Transfert(self, callid, to): """Transfert a call identified by a CallID""" + if not self.account: + self.setFirstRegisteredAccount() if not self.isAccountRegistered(): raise SflPhoneError("Can't transfert a call without a registered account") @@ -245,11 +445,13 @@ class SflPhoneCtrlSimple(object): if callid is None or callid == "": raise SflPhoneError("Invalid callID") - self.callmanager.transfert(callid) + self.callmanager.transfert(callid, to) def Refuse(self, callid): """Refuse an incoming call identified by a CallID""" + if not self.account: + self.setFirstRegisteredAccount() if not self.isAccountRegistered(): raise SflPhoneError("Can't refuse a call without a registered account") @@ -262,8 +464,10 @@ class SflPhoneCtrlSimple(object): def Accept(self, callid): """Accept an incoming call identified by a CallID""" + if not self.account: + self.setFirstRegisteredAccount() - if not self.isAccountRegistered(): + if not self.isAccountRegistered(): raise SflPhoneError("Can't accept a call without a registered account") if callid is None or callid == "": @@ -274,6 +478,8 @@ class SflPhoneCtrlSimple(object): def Hold(self, callid): """Hold a call identified by a CallID""" + if not self.account: + self.setFirstRegisteredAccount() if not self.isAccountRegistered(): raise SflPhoneError("Can't hold a call without a registered account") @@ -286,6 +492,8 @@ class SflPhoneCtrlSimple(object): def UnHold(self, callid): """Unhold an incoming call identified by a CallID""" + if not self.account: + self.setFirstRegisteredAccount() if not self.isAccountRegistered(): raise SflPhoneError("Can't unhold a call without a registered account") @@ -296,6 +504,9 @@ class SflPhoneCtrlSimple(object): self.callmanager.unhold(callid) + def Dtmf(self, key): + """Send a DTMF""" + self.callmanager.playDTMF(key)