* #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.
This commit is contained in:
Tristan Matthews
2012-01-04 15:36:44 -05:00
parent 8118e28413
commit 147209f710

View File

@ -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;
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);
// 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);
if (instant_messaging_enabled) {
gtk_action_set_sensitive(imAction_, TRUE);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(imToolbar_), 3);
}
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 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);
g_object_ref(newCallWidget_);
remove_from_toolbar(newCallWidget_);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(pickUpWidget_), 0);
// 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 (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);
if (instant_messaging_enabled) {
gtk_action_set_sensitive(imAction_, TRUE);
add_to_toolbar(toolbar_, imToolbar_, pos);
}
break;
}
case CALL_STATE_RINGING:
{
DEBUG("UIManager: Call State Ringing");
gtk_action_set_sensitive(pickUpAction_, TRUE);
gtk_action_set_sensitive(hangUpAction_, TRUE);
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_);
if (instant_messaging_enabled) {
gtk_action_set_sensitive(imAction_, TRUE);
add_to_toolbar(toolbar_, imToolbar_, pos);
}
break;
}
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_);
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_);
if (instant_messaging_enabled) {
gtk_action_set_sensitive(imAction_, TRUE);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(imToolbar_), pos);
if (instant_messaging_enabled) {
gtk_action_set_sensitive(imAction_, TRUE);
add_to_toolbar(toolbar_, imToolbar_, pos);
}
break;
}
break;
}
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);
gtk_toolbar_insert(GTK_TOOLBAR(toolbar_), GTK_TOOL_ITEM(imToolbar_), pos);
}
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();
}
}