From 147209f7107e1c621f1822f47407689cd054e6af Mon Sep 17 00:00:00 2001 From: Tristan Matthews <tristan.matthews@savoirfairelinux.com> Date: Wed, 4 Jan 2012 15:36:44 -0500 Subject: [PATCH] * #8035: Fixes crash when selecting a recorded call in history We were inserting elements into the toolbar at invalid positions. Now the indices have been corrected and an assertion added to make this sort of error more obvious in the future. --- gnome/src/uimanager.c | 285 +++++++++++++++++++++++------------------- 1 file changed, 155 insertions(+), 130 deletions(-) diff --git a/gnome/src/uimanager.c b/gnome/src/uimanager.c index 99e622fb98..780be5f746 100644 --- a/gnome/src/uimanager.c +++ b/gnome/src/uimanager.c @@ -109,6 +109,14 @@ is_non_empty_string(const char *str) return str && strlen(str) > 0; } +/* Inserts an item in a toolbar at a given position, making sure that the index + * is valid, that it does not exceed the number of elements */ +static void add_to_toolbar(GtkWidget *toolbar, GtkWidget *item, int pos) +{ + g_assert(gtk_toolbar_get_n_items(GTK_TOOLBAR(toolbar)) >= pos); + gtk_toolbar_insert(GTK_TOOLBAR(toolbar), GTK_TOOL_ITEM(item), pos); +} + void update_actions() { @@ -163,19 +171,19 @@ update_actions() remove_from_toolbar(newCallWidget_); remove_from_toolbar(pickUpWidget_); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(newCallWidget_), 0); + add_to_toolbar(toolbar_, newCallWidget_, 0); remove_from_toolbar(playRecordWidget_); remove_from_toolbar(stopRecordWidget_); if (eel_gconf_get_integer(HISTORY_ENABLED)) { - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(historyButton_), -1); + add_to_toolbar(toolbar_, historyButton_, -1); gtk_widget_set_sensitive(historyButton_, TRUE); } // If addressbook support has been enabled and all addressbooks are loaded, display the icon if (addrbook && addrbook->is_ready() && addressbook_config_load_parameters()->enable) { - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(contactButton_), -1); + add_to_toolbar(toolbar_, contactButton_, -1); // Make the icon clickable only if at least one address book is active if (addrbook->is_active()) { @@ -202,134 +210,151 @@ update_actions() switch (selectedCall->_state) { case CALL_STATE_INCOMING: - DEBUG("UIManager: Call State Incoming"); - // Make the button toolbar clickable - gtk_action_set_sensitive(pickUpAction_, TRUE); - gtk_action_set_sensitive(hangUpAction_, TRUE); - // Replace the dial button with the hangup button - g_object_ref(newCallWidget_); - remove_from_toolbar(newCallWidget_); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(pickUpWidget_), - 0); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(hangUpWidget_), - 1); - break; + { + DEBUG("UIManager: Call State Incoming"); + // Make the button toolbar clickable + gtk_action_set_sensitive(pickUpAction_, TRUE); + gtk_action_set_sensitive(hangUpAction_, TRUE); + // Replace the dial button with the hangup button + g_object_ref(newCallWidget_); + remove_from_toolbar(newCallWidget_); + int pos = 0; + add_to_toolbar(toolbar_, pickUpWidget_, pos++); + add_to_toolbar(toolbar_, hangUpWidget_, pos); + break; + } case CALL_STATE_HOLD: - DEBUG("UIManager: Call State Hold"); - gtk_action_set_sensitive(hangUpAction_, TRUE); - gtk_widget_set_sensitive(holdMenu_, TRUE); - gtk_widget_set_sensitive(offHoldToolbar_, TRUE); - gtk_widget_set_sensitive(newCallWidget_, TRUE); + { + DEBUG("UIManager: Call State Hold"); + gtk_action_set_sensitive(hangUpAction_, TRUE); + gtk_widget_set_sensitive(holdMenu_, TRUE); + gtk_widget_set_sensitive(offHoldToolbar_, TRUE); + gtk_widget_set_sensitive(newCallWidget_, TRUE); - // Replace the hold button with the off-hold button - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(hangUpWidget_), 1); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(offHoldToolbar_), 2); + // Replace the hold button with the off-hold button + int pos = 1; + add_to_toolbar(toolbar_, hangUpWidget_, pos++); + add_to_toolbar(toolbar_, offHoldToolbar_, pos++); - if (instant_messaging_enabled) { - gtk_action_set_sensitive(imAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(imToolbar_), 3); - } + if (instant_messaging_enabled) { + gtk_action_set_sensitive(imAction_, TRUE); + add_to_toolbar(toolbar_, imToolbar_, pos); + } - break; + break; + } case CALL_STATE_RINGING: - DEBUG("UIManager: Call State Ringing"); - gtk_action_set_sensitive(pickUpAction_, TRUE); - gtk_action_set_sensitive(hangUpAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(hangUpWidget_), 1); - break; - case CALL_STATE_DIALING: - DEBUG("UIManager: Call State Dialing"); - gtk_action_set_sensitive(pickUpAction_, TRUE); - - if (active_calltree_tab == current_calls_tab) + { + DEBUG("UIManager: Call State Ringing"); + gtk_action_set_sensitive(pickUpAction_, TRUE); gtk_action_set_sensitive(hangUpAction_, TRUE); - - g_object_ref(newCallWidget_); - remove_from_toolbar(newCallWidget_); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(pickUpWidget_), 0); - - if (active_calltree_tab == current_calls_tab) - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(hangUpWidget_), 1); - else if (active_calltree_tab == history_tab) { - if (is_non_empty_string(selectedCall->_recordfile)) { - if (selectedCall->_record_is_playing) - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(stopRecordWidget_), 3); - else - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(playRecordWidget_), 3); + int pos = 1; + add_to_toolbar(toolbar_, hangUpWidget_, pos); + break; + } + case CALL_STATE_DIALING: + { + DEBUG("UIManager: Call State Dialing"); + gtk_action_set_sensitive(pickUpAction_, TRUE); + + if (active_calltree_tab == current_calls_tab) + gtk_action_set_sensitive(hangUpAction_, TRUE); + + g_object_ref(newCallWidget_); + remove_from_toolbar(newCallWidget_); + int pos = 0; + add_to_toolbar(toolbar_, pickUpWidget_, pos++); + + if (active_calltree_tab == current_calls_tab) + add_to_toolbar(toolbar_, hangUpWidget_, pos++); + else if (active_calltree_tab == history_tab) { + if (is_non_empty_string(selectedCall->_recordfile)) { + if (selectedCall->_record_is_playing) + add_to_toolbar(toolbar_, stopRecordWidget_, pos); + else + add_to_toolbar(toolbar_, playRecordWidget_, pos); + } } + break; } + case CALL_STATE_CURRENT: + { + DEBUG("UIManager: Call State Current"); + gtk_action_set_sensitive(hangUpAction_, TRUE); + int pos = 1; + add_to_toolbar(toolbar_, hangUpWidget_, pos++); + gtk_widget_set_sensitive(holdMenu_, TRUE); + gtk_widget_set_sensitive(holdToolbar_, TRUE); + gtk_widget_set_sensitive(transferToolbar_, TRUE); + gtk_action_set_sensitive(recordAction_, TRUE); + add_to_toolbar(toolbar_, holdToolbar_, pos++); + add_to_toolbar(toolbar_, transferToolbar_, pos++); + add_to_toolbar(toolbar_, recordWidget_, pos++); + g_signal_handler_block(transferToolbar_, transferButtonConnId_); + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), FALSE); + g_signal_handler_unblock(transferToolbar_, transferButtonConnId_); + g_signal_handler_block(recordWidget_, recordButtonConnId_); + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(recordWidget_), FALSE); + g_signal_handler_unblock(recordWidget_, recordButtonConnId_); - break; - case CALL_STATE_CURRENT: { - DEBUG("UIManager: Call State Current"); - gtk_action_set_sensitive(hangUpAction_, TRUE); - int pos = 1; - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(hangUpWidget_), pos++); - gtk_widget_set_sensitive(holdMenu_, TRUE); - gtk_widget_set_sensitive(holdToolbar_, TRUE); - gtk_widget_set_sensitive(transferToolbar_, TRUE); - gtk_action_set_sensitive(recordAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(holdToolbar_), pos++); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(transferToolbar_), pos++); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(recordWidget_), pos++); - g_signal_handler_block(transferToolbar_, transferButtonConnId_); - gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), FALSE); - g_signal_handler_unblock(transferToolbar_, transferButtonConnId_); - g_signal_handler_block(recordWidget_, recordButtonConnId_); - gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(recordWidget_), FALSE); - g_signal_handler_unblock(recordWidget_, recordButtonConnId_); + if (instant_messaging_enabled) { + gtk_action_set_sensitive(imAction_, TRUE); + add_to_toolbar(toolbar_, imToolbar_, pos); + } - if (instant_messaging_enabled) { - gtk_action_set_sensitive(imAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(imToolbar_), pos); + break; } - break; - } + case CALL_STATE_RECORD: + { + DEBUG("UIManager: Call State Record"); + int pos = 1; + gtk_action_set_sensitive(hangUpAction_, TRUE); + add_to_toolbar(toolbar_, hangUpWidget_, pos++); + gtk_widget_set_sensitive(holdMenu_, TRUE); + gtk_widget_set_sensitive(holdToolbar_, TRUE); + gtk_widget_set_sensitive(transferToolbar_, TRUE); + gtk_action_set_sensitive(recordAction_, TRUE); + add_to_toolbar(toolbar_, holdToolbar_, pos++); + add_to_toolbar(toolbar_, transferToolbar_, pos++); + add_to_toolbar(toolbar_, recordWidget_, pos++); + g_signal_handler_block(transferToolbar_, transferButtonConnId_); + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), FALSE); + g_signal_handler_unblock(transferToolbar_, transferButtonConnId_); + g_signal_handler_block(recordWidget_, recordButtonConnId_); + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(recordWidget_), TRUE); + g_signal_handler_unblock(recordWidget_, recordButtonConnId_); - case CALL_STATE_RECORD: { - DEBUG("UIManager: Call State Record"); - int pos = 1; - gtk_action_set_sensitive(hangUpAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(hangUpWidget_), pos++); - gtk_widget_set_sensitive(holdMenu_, TRUE); - gtk_widget_set_sensitive(holdToolbar_, TRUE); - gtk_widget_set_sensitive(transferToolbar_, TRUE); - gtk_action_set_sensitive(recordAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(holdToolbar_), pos++); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(transferToolbar_), pos++); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(recordWidget_), pos++); - g_signal_handler_block(transferToolbar_, transferButtonConnId_); - gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), FALSE); - g_signal_handler_unblock(transferToolbar_, transferButtonConnId_); - g_signal_handler_block(recordWidget_, recordButtonConnId_); - gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(recordWidget_), TRUE); - g_signal_handler_unblock(recordWidget_, recordButtonConnId_); + if (instant_messaging_enabled) { + gtk_action_set_sensitive(imAction_, TRUE); + add_to_toolbar(toolbar_, imToolbar_, pos); + } - if (instant_messaging_enabled) { - gtk_action_set_sensitive(imAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(imToolbar_), pos); + break; } - - break; - } case CALL_STATE_BUSY: case CALL_STATE_FAILURE: - DEBUG("UIManager: Call State Busy/Failure"); - gtk_action_set_sensitive(hangUpAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(hangUpWidget_), 1); - break; + { + int pos = 1; + DEBUG("UIManager: Call State Busy/Failure"); + gtk_action_set_sensitive(hangUpAction_, TRUE); + add_to_toolbar(toolbar_, hangUpWidget_, pos); + break; + } case CALL_STATE_TRANSFER: - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(hangUpWidget_), 1); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(transferToolbar_), 2); - g_signal_handler_block(transferToolbar_, transferButtonConnId_); - gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), TRUE); - g_signal_handler_unblock(transferToolbar_, transferButtonConnId_); - gtk_action_set_sensitive(hangUpAction_, TRUE); - gtk_widget_set_sensitive(holdMenu_, TRUE); - gtk_widget_set_sensitive(holdToolbar_, TRUE); - gtk_widget_set_sensitive(transferToolbar_, TRUE); - break; + { + int pos = 1; + add_to_toolbar(toolbar_, hangUpWidget_, pos++); + add_to_toolbar(toolbar_, transferToolbar_, pos); + g_signal_handler_block(transferToolbar_, transferButtonConnId_); + gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(transferToolbar_), TRUE); + g_signal_handler_unblock(transferToolbar_, transferButtonConnId_); + gtk_action_set_sensitive(hangUpAction_, TRUE); + gtk_widget_set_sensitive(holdMenu_, TRUE); + gtk_widget_set_sensitive(holdToolbar_, TRUE); + gtk_widget_set_sensitive(transferToolbar_, TRUE); + break; + } default: ERROR("UIMAnager: Error: Unknown state in action update!"); break; @@ -348,24 +373,25 @@ update_actions() DEBUG("UIManager: Conference State Active"); if (active_calltree_tab == current_calls_tab) { - int pos = 1; gtk_action_set_sensitive(hangUpAction_, TRUE); gtk_widget_set_sensitive(holdToolbar_, TRUE); gtk_action_set_sensitive(recordAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(hangUpWidget_), pos++); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(holdToolbar_), pos++); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(recordWidget_), pos++); + int pos = 1; + add_to_toolbar(toolbar_, hangUpWidget_, pos++); + add_to_toolbar(toolbar_, holdToolbar_, pos++); + add_to_toolbar(toolbar_, recordWidget_, pos++); if (instant_messaging_enabled) { gtk_action_set_sensitive(imAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(imToolbar_), pos); + add_to_toolbar(toolbar_, imToolbar_, pos); } } else if (active_calltree_tab == history_tab) { if (is_non_empty_string(selectedConf->_recordfile)) { + int pos = 2; if (selectedConf->_record_is_playing) - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(stopRecordWidget_), 3); + add_to_toolbar(toolbar_, stopRecordWidget_, pos); else - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(playRecordWidget_), 3); + add_to_toolbar(toolbar_, playRecordWidget_, pos); } } @@ -377,13 +403,13 @@ update_actions() gtk_action_set_sensitive(hangUpAction_, TRUE); gtk_widget_set_sensitive(holdToolbar_, TRUE); gtk_action_set_sensitive(recordAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(hangUpWidget_), pos++); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(holdToolbar_), pos++); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(recordWidget_), pos++); + add_to_toolbar(toolbar_, hangUpWidget_, pos++); + add_to_toolbar(toolbar_, holdToolbar_, pos++); + add_to_toolbar(toolbar_, recordWidget_, pos++); if (instant_messaging_enabled) { gtk_action_set_sensitive(imAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(imToolbar_), pos); + add_to_toolbar(toolbar_, imToolbar_, pos); } break; @@ -395,13 +421,13 @@ update_actions() gtk_action_set_sensitive(hangUpAction_, TRUE); gtk_widget_set_sensitive(offHoldToolbar_, TRUE); gtk_action_set_sensitive(recordAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(hangUpWidget_), pos++); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(offHoldToolbar_), pos++); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(recordWidget_), pos++); + add_to_toolbar(toolbar_, hangUpWidget_, pos++); + add_to_toolbar(toolbar_, offHoldToolbar_, pos++); + add_to_toolbar(toolbar_, recordWidget_, pos++); if (instant_messaging_enabled) { gtk_action_set_sensitive(imAction_, TRUE); - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(imToolbar_), pos); + add_to_toolbar(toolbar_, imToolbar_, pos); } break; @@ -415,8 +441,7 @@ update_actions() hide_status_hangup_icon(); if (account_list_get_size() > 0 && current_account_has_mailbox()) { - gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), - GTK_TOOL_ITEM(voicemailToolbar_), -2); + add_to_toolbar(toolbar_, voicemailToolbar_, -1); update_voicemail_status(); } } -- GitLab