Index: src/af/ev/unix/ev_UnixToolbar.cpp =================================================================== RCS file: /cvsroot/abi/src/af/ev/unix/ev_UnixToolbar.cpp,v retrieving revision 1.126 diff -u -r1.126 ev_UnixToolbar.cpp --- src/af/ev/unix/ev_UnixToolbar.cpp 20 May 2004 00:21:55 -0000 1.126 +++ src/af/ev/unix/ev_UnixToolbar.cpp 9 May 2005 12:40:12 -0000 @@ -17,9 +17,6 @@ * 02111-1307, USA. */ -//for GtkCombo->GtkList -#undef GTK_DISABLE_DEPRECATED - #include #include #include @@ -70,6 +67,16 @@ static const GtkTargetEntry s_AbiTBTargets[] = {{"abi-toolbars",0,0}}; +enum { + COLUMN_STRING = 0, + NUM_COLUMNS +}; + +void abi_gtk_combo_box_fill_from_string_vector (GtkComboBox *combo, const UT_GenericVector *strings); +void abi_gtk_combo_box_text_select_entry(GtkComboBox *combo, const gchar *text); +const gchar *abi_gtk_combo_box_get_active_text (GtkComboBox *combo); + + /** * toolbar_append_with_eventbox * @@ -225,11 +232,6 @@ wd->m_pUnixToolbar->invokeToolbarMethod(pView,pEM,NULL,0); } }; - - static void s_combo_list_changed(GtkWidget* list, GtkWidget * widget, gpointer user_data) - { - s_combo_changed(widget, user_data); - } // TODO: should this move out of wd? It's convenient here; maybe I'll make // a microclass for combo boxes. @@ -248,69 +250,28 @@ if (!wd->m_blockSignal) { const gchar * buffer = NULL; - if (GTK_IS_ENTRY(widget)) - buffer = gtk_entry_get_text(GTK_ENTRY(widget)); - else if (GTK_IS_LIST_ITEM(widget)) - { - GtkWidget* label = gtk_bin_get_child(GTK_BIN(widget)); - buffer = gtk_label_get_text(GTK_LABEL(label)); - } - else { - UT_ASSERT( UT_SHOULD_NOT_HAPPEN ); - return; - } - - // check if something actually _is_ changed... yeah yeah, another hack.. gtk sux sometimes - if (!strcmp(wd->m_comboEntryBuffer, buffer)) - return; + buffer = abi_gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); UT_uint32 length = strlen(buffer); - xxx_UT_DEBUGMSG(("LACHANCE: comboChanged, length: %d \n", length)); - // LACHANCE: in gtk2, it seems as if the gtk_entry's text buffer length is set to 0 - // when we move through combo elements/new combo elements are added. in this case, we - // have to ignore the signal-- things will be set correctly momentarily. this seems - // to work correctly, but it would be nice to find a more elegant solution - // (P.S.: GtkCombo SUCKS, and will hopefully soon be deprecated. We should really be - // using GtkOptionMenu for non-changeable drop-down toolbar menus) if (length > 0) - { - UT_ASSERT(length < 1024); - strcpy(wd->m_comboEntryBuffer, buffer); + { + UT_UCS4String ucsText(buffer); + wd->m_pUnixToolbar->toolbarEvent(wd, ucsText.ucs4_str(), ucsText.length()); if (wd->m_id == AP_TOOLBAR_ID_FMT_FONT && wd->m_pUnixToolbar->m_pFontPreview) - { + { wd->m_pUnixToolbar->m_pFontPreview->setFontFamily(buffer); wd->m_pUnixToolbar->m_pFontPreview->setText(buffer); wd->m_pUnixToolbar->m_pFontPreview->draw(); - } + } } } } - else // widget has no ->parent, so use the buffer's results - { - // Don't do changes for empty combo texts, or when the - // combo box selection has been aborted (by pressing - // outside the box - this appears to be recognizable - // by the HAS_GRAB flag being set: I don't know if - // that's the correct way to detect this case. - // jskov 2001.12.09) - if (UT_strcmp(wd->m_comboEntryBuffer, "") - && !(GTK_OBJECT_FLAGS(widget) & GTK_HAS_GRAB)) - { - const char * text = - (wd->m_id == AP_TOOLBAR_ID_FMT_SIZE ? - XAP_EncodingManager::fontsizes_mapping.lookupByTarget(wd->m_comboEntryBuffer) : - wd->m_comboEntryBuffer); - UT_ASSERT(text); - - UT_UCS4String ucsText(text); - wd->m_pUnixToolbar->toolbarEvent(wd, ucsText.ucs4_str(), ucsText.length()); - } - } } } // unblock when the menu goes away + // TODO ROB: handle font preview static void s_combo_hide(GtkWidget * widget, gpointer user_data) { _wd * wd = static_cast<_wd *>(user_data); @@ -332,6 +293,7 @@ } // unblock when the menu goes away + // TODO ROB: handle font preview static void s_combo_show(GtkWidget * widget, gpointer user_data) { _wd * wd = static_cast<_wd *>(user_data); @@ -820,25 +782,16 @@ iWidth = pControl->getPixelWidth(); } - GtkWidget * comboBox = gtk_combo_new(); - UT_ASSERT(comboBox); - - // Combo boxes flash on 8-bit displays unless you set its colormap - // to agree with what we're using elsewhere (gdk_rgb's version) - gtk_widget_set_colormap(comboBox, gdk_rgb_get_colormap()); + GtkWidget *comboBox = gtk_combo_box_new_text(); + GtkListStore *store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_STRING); + gtk_combo_box_set_model(GTK_COMBO_BOX(comboBox), GTK_TREE_MODEL(store)); + g_object_unref(store); // set the size of the entry to set the total combo size - gtk_widget_set_size_request(GTK_COMBO(comboBox)->entry, iWidth, -1); - - // the entry is read-only for now - gtk_editable_set_editable(GTK_EDITABLE(GTK_COMBO(comboBox)->entry), FALSE); - - // handle popup events, so we can block our signals until the popdown - GtkWidget * popwin = GTK_WIDGET(GTK_COMBO(comboBox)->popwin); - UT_ASSERT(popwin); - - g_object_set_data(G_OBJECT(popwin), "entry", GTK_COMBO(comboBox)->entry); + gtk_widget_set_size_request(comboBox, iWidth, -1); + // TODO ROB: handle font preview + /* g_signal_connect(G_OBJECT(popwin), "hide", G_CALLBACK(_wd::s_combo_hide), @@ -847,16 +800,13 @@ "show", G_CALLBACK(_wd::s_combo_show), wd); + */ + + g_signal_connect(G_OBJECT(GTK_COMBO_BOX(comboBox)), + "changed", + G_CALLBACK(_wd::s_combo_changed), + wd); - // connect to the ->entry directly? Cleaned up version below. - g_signal_connect(G_OBJECT(GTK_COMBO(comboBox)->entry), - "changed", - G_CALLBACK(_wd::s_combo_changed), - wd); - g_signal_connect(G_OBJECT(GTK_COMBO(comboBox)->list), - "select-child", - G_CALLBACK(_wd::s_combo_list_changed), - wd); // populate it if (pControl) { @@ -864,18 +814,7 @@ const UT_GenericVector * v = pControl->getContents(); UT_ASSERT(v); - - if (v) - { - UT_uint32 items = v->getItemCount(); - for (UT_uint32 m=0; m < items; m++) - { - const char * sz = v->getNthItem(m); - GtkWidget * li = gtk_list_item_new_with_label(sz); - gtk_widget_show(li); - gtk_container_add (GTK_CONTAINER(GTK_COMBO(comboBox)->list), li); - } - } + abi_gtk_combo_box_fill_from_string_vector (GTK_COMBO_BOX(comboBox), v); } // give a final show @@ -1093,7 +1032,7 @@ _wd * wd = m_vecToolbarWidgets.getNthItem(k); UT_ASSERT(wd); - GtkCombo * item = GTK_COMBO(wd->m_widget); + GtkComboBox * item = GTK_COMBO_BOX(wd->m_widget); UT_ASSERT(item); // Disable/enable toolbar item gtk_widget_set_sensitive(GTK_WIDGET(item), !bGrayed); @@ -1106,15 +1045,15 @@ { const char * fsz = XAP_EncodingManager::fontsizes_mapping.lookupBySource(szState); if ( fsz ) - gtk_entry_set_text(GTK_ENTRY(item->entry), fsz); + abi_gtk_combo_box_text_select_entry(item, fsz); else - gtk_entry_set_text(GTK_ENTRY(item->entry), ""); + abi_gtk_combo_box_text_select_entry(item, ""); } else - gtk_entry_set_text(GTK_ENTRY(item->entry), szState); + abi_gtk_combo_box_text_select_entry(item, szState); } else { - gtk_entry_set_text(GTK_ENTRY(item->entry), ""); + abi_gtk_combo_box_text_select_entry(item, ""); } wd->m_blockSignal = wasBlocked; @@ -1216,7 +1155,7 @@ EV_Toolbar_Control * pControl = pFactory->getControl(this, id); AP_UnixToolbar_StyleCombo * pStyleC = static_cast(pControl); pStyleC->repopulate(); - GtkCombo * item = GTK_COMBO(wd->m_widget); + GtkComboBox * item = GTK_COMBO_BOX(wd->m_widget); // // Now the combo box has to be refilled from this // @@ -1231,21 +1170,12 @@ bool wasBlocked = wd->m_blockSignal; wd->m_blockSignal = true; // block the signal, so we don't try to read the text entry while this is happening.. - GtkList * oldlist = GTK_LIST(item->list); - gtk_list_clear_items(oldlist,0,-1); // // Now make a new one. // - UT_uint32 items = v->getItemCount(); - for (UT_uint32 m=0; m < items; m++) - { - const char * sz = v->getNthItem(m); - GtkWidget * li = gtk_list_item_new_with_label(sz); - gtk_widget_show(li); - gtk_container_add (GTK_CONTAINER(GTK_COMBO(item)->list), li); - } + abi_gtk_combo_box_fill_from_string_vector (item, v); - wd->m_blockSignal = wasBlocked; + wd->m_blockSignal = wasBlocked; // // Don't need this anymore and we don't like memory leaks in abi @@ -1256,3 +1186,64 @@ // return true; } + +/*! +* Refill a combo box (list model, one string column) from a string vector. +*/ +void +abi_gtk_combo_box_fill_from_string_vector (GtkComboBox *combo, + const UT_GenericVector *strings) { + + GtkListStore *store = GTK_LIST_STORE (gtk_combo_box_get_model (combo)); + gtk_list_store_clear (store); + + int count = strings->size (); + for (int i = 0; i < count; i++) { + GtkTreeIter iter; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, COLUMN_STRING, strings->getNthItem (i), -1); + } +} + +/*! +* Select a combo box entry by its label. +*/ +void +abi_gtk_combo_box_text_select_entry (GtkComboBox *combo, + const gchar *text) { + + GtkTreeModel *model = gtk_combo_box_get_model (combo); + GtkTreeIter iter; + guint idx = 0; + if (gtk_tree_model_get_iter_first (model, &iter)) { + do { + gchar *value; + gtk_tree_model_get (model, &iter, COLUMN_STRING, &value, -1); + if (!UT_strcmp (text, value)) { + gtk_combo_box_set_active (combo, idx); + } + idx++; + } + while (gtk_tree_model_iter_next (model, &iter)); + } +} + +/** +* Get currently active combo box text. +*/ +const gchar * +abi_gtk_combo_box_get_active_text (GtkComboBox *combo) { + + GtkTreeModel *model = gtk_combo_box_get_model (combo); + gint idx = gtk_combo_box_get_active (combo); + GtkTreePath *path = gtk_tree_path_new_from_indices (idx, -1); + + GtkTreeIter iter; + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_path_free (path); + + const gchar *value; + gtk_tree_model_get (model, &iter, COLUMN_STRING, &value, -1); + + return value; +}