[PATCH] For gtk font dialog

From: Tim O'Brien <mild7_at_users.sourceforge.net>
Date: Sat Sep 04 2004 - 07:42:49 CEST

Hello,

Attached are two patches to make the font dialog easier to use from the
keyboard. They are against the stable version 2.0.11 , but can be
patched up to the CVS head versions with no problems.

The first makes a small change to
abi/src/af/xap/unix/xap_UnixDlg_FontChooser.h to make pressing escape
correctly cancel the dialog.

The second updates abi/src/af/xap/unix/xap_UnixDlg_FontChooser.cpp to
use GtkTreeView instead of GtkCList (as was mentioned in the TODO). This
means that lists can now correctly display the current font/size (ie it
scrolls the list down to the current font/size). Also the tab focus is
changed on "Font" tab of the dialog so that it is easier to navigate
just using the keyboard (it's more like the Windows version now).

Tim O'Brien

--- src/af/xap/unix/xap_UnixDlg_FontChooser.h Sat Sep 4 17:07:14 2004
+++ /tmp/build/abiword-2.0.11/abi/src/af/xap/unix/xap_UnixDlg_FontChooser.h Sat Sep 4 16:46:13 2004
@@ -83,10 +83,12 @@
 
 protected:
         
+ // Gtk sets up escape key to close a GtkDialog only when
+ // the one of the button responses is GTK_RESPONSE_CANCEL
         typedef enum
           {
- BUTTON_OK,
- BUTTON_CANCEL
+ BUTTON_OK = GTK_RESPONSE_OK,
+ BUTTON_CANCEL = GTK_RESPONSE_CANCEL
           } ResponseId ;
 
         // careful, these must be in the order the

--- src/af/xap/unix/xap_UnixDlg_FontChooser.cpp Sat Sep 4 17:07:18 2004
+++ /tmp/build/abiword-2.0.11/abi/src/af/xap/unix/xap_UnixDlg_FontChooser.cpp Sat Sep 4 16:53:34 2004
@@ -17,8 +17,8 @@
  * 02111-1307, USA.
  */
 
-// for searchCList. TODO: use GtkTreeView
-#undef GTK_DISABLE_DEPRECATED
+// 9/4/04 Updated to use GtkTreeView , Tim O'Brien (obrientimo@vuw.ac.nz)
+
 
 #include <stdio.h>
 #include <string.h>
@@ -54,27 +54,66 @@
                 OPACITY
         };
 
-static gint searchCList(GtkCList * clist, char * compareText)
+//
+// List store model , used as model for GtkTreeView
+ enum
+ {
+ TEXT_COLUMN,
+ N_COLUMNS
+ };
+
+static gint searchTreeView(GtkTreeView* tv, char * compareText)
 {
- UT_ASSERT(clist);
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ char* text;
+
+ UT_ASSERT(tv);
 
        // if text is null, it's not found
        if (!compareText)
                return -1;
 
- gchar * text[2] = {NULL, NULL};
-
- for (gint i = 0; i < clist->rows; i++)
- {
- gtk_clist_get_text(clist, i, 0, text);
- if (text && text[0])
- if (!UT_stricmp(text[0], compareText))
- return i;
- }
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(tv));
+ if (! gtk_tree_model_get_iter_first(model, &iter) )
+ return -1;
+
+ gint i = 0;
+ do {
+ gtk_tree_model_get(model, &iter, TEXT_COLUMN, &text, -1);
+ if (!UT_stricmp(text, compareText))
+ return i;
+ i++;
+ } while(gtk_tree_model_iter_next (model, &iter));
 
        return -1;
 }
 
+//
+// Create GtkTreeView that is similar to a CList
+// ie single text column, with no header
+GtkWidget* createFontTabTreeView()
+{
+ GtkWidget* treeView;
+ GtkListStore* listStore;
+ GtkTreeViewColumn* column;
+ GtkCellRenderer* renderer;
+
+ treeView = gtk_tree_view_new();
+ listStore = gtk_list_store_new(N_COLUMNS, G_TYPE_STRING);
+ gtk_tree_view_set_model(GTK_TREE_VIEW(treeView), GTK_TREE_MODEL(listStore));
+ column = gtk_tree_view_column_new();
+ renderer = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(column, renderer, TRUE);
+ gtk_tree_view_column_set_attributes(column, renderer, "text", TEXT_COLUMN, NULL);
+ gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeView), column);
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeView), FALSE);
+
+ return treeView;
+}
+
+
 /*****************************************************************/
 XAP_Dialog * XAP_UnixDialog_FontChooser::static_constructor(XAP_DialogFactory * pFactory,
                                                                                                                  XAP_Dialog_Id id)
@@ -138,11 +177,7 @@
         return FALSE;
 }
 
-static void s_select_row_font(GtkWidget * /* widget */,
- gint /* row */,
- gint /* column */,
- GdkEventButton * /* event */,
- XAP_UnixDialog_FontChooser * dlg)
+static void s_select_row_font(GtkWidget * /* widget */, XAP_UnixDialog_FontChooser * dlg)
 {
         UT_ASSERT(dlg);
     // update the row number and show the changed preview
@@ -150,11 +185,8 @@
         dlg->fontRowChanged();
 }
 
-static void s_select_row_style(GtkWidget * /* widget */,
- gint /* row */,
- gint /* column */,
- GdkEventButton * /* event */,
- XAP_UnixDialog_FontChooser * dlg)
+
+static void s_select_row_style(GtkWidget * /* widget */, XAP_UnixDialog_FontChooser * dlg)
 {
         UT_ASSERT(dlg);
 
@@ -162,11 +194,7 @@
         dlg->styleRowChanged();
 }
 
-static void s_select_row_size(GtkWidget * /* widget */,
- gint /* row */,
- gint /* column */,
- GdkEventButton * /* event */,
- XAP_UnixDialog_FontChooser * dlg)
+static void s_select_row_size(GtkWidget * /* widget */, XAP_UnixDialog_FontChooser * dlg)
 {
         UT_ASSERT(dlg);
 
@@ -262,39 +290,41 @@
 void XAP_UnixDialog_FontChooser::fontRowChanged(void)
 {
         static char szFontFamily[60];
- // this is used many times below to grab pointers to
- // strings inside list elements
- gchar * text[2] = {NULL, NULL};
-
- GList * selectedRow = NULL;
- gint rowNumber = 0;
-
- selectedRow = GTK_CLIST(m_fontList)->selection;
- if (selectedRow)
- {
- rowNumber = GPOINTER_TO_INT(selectedRow->data);
- gtk_clist_get_text(GTK_CLIST(m_fontList), rowNumber, 0, text);
- UT_ASSERT(text && text[0]);
- g_snprintf(szFontFamily, 50, "%s",text[0]);
+ GtkTreeSelection* selection;
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ gchar* text;
+
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(m_fontList));
+ if ( gtk_tree_selection_get_selected (selection, &model, &iter) )
+ {
+ gtk_tree_model_get(model, &iter, TEXT_COLUMN, &text, -1);
+ UT_ASSERT(text);
+ g_snprintf(szFontFamily, 50, "%s",text);
                 addOrReplaceVecProp("font-family",static_cast<XML_Char*>(szFontFamily));
         }
+
         updatePreview();
 }
 
 void XAP_UnixDialog_FontChooser::styleRowChanged(void)
 {
- // this is used many times below to grab pointers to
- // strings inside list elements
- gchar * text[2] = {NULL, NULL};
-
- GList * selectedRow = NULL;
- gint rowNumber = 0;
- selectedRow = GTK_CLIST(m_styleList)->selection;
- if (selectedRow)
- {
- rowNumber = GPOINTER_TO_INT(selectedRow->data);
- gtk_clist_get_text(GTK_CLIST(m_styleList), rowNumber, 0, text);
- UT_ASSERT(text && text[0]);
+ GtkTreeSelection* selection;
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ gchar* text;
+ gint rowNumber;
+ GtkTreePath* path;
+
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(m_styleList));
+ if ( gtk_tree_selection_get_selected (selection, &model, &iter) )
+ {
+ path = gtk_tree_model_get_path(model, &iter);
+ rowNumber = gtk_tree_path_get_indices(path)[0];
+ gtk_tree_path_free(path);
+
+ gtk_tree_model_get(model, &iter, TEXT_COLUMN, &text, -1);
+ UT_ASSERT(text);
 
                 // perhaps these attributes really should be smashed
                 // into bitfields. :)
@@ -331,21 +361,19 @@
 {
         // used similarly to convert between text and numeric arguments
         static char szFontSize[50];
- // this is used many times below to grab pointers to
- // strings inside list elements
- gchar * text[2] = {NULL, NULL};
-
- GList * selectedRow = NULL;
- gint rowNumber = 0;
- selectedRow = GTK_CLIST(m_sizeList)->selection;
- if (selectedRow)
- {
- rowNumber = GPOINTER_TO_INT(selectedRow->data);
- gtk_clist_get_text(GTK_CLIST(m_sizeList), rowNumber, 0, text);
- UT_ASSERT(text && text[0]);
+ GtkTreeSelection* selection;
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ gchar* text;
+
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(m_sizeList));
+ if ( gtk_tree_selection_get_selected (selection, &model, &iter) )
+ {
+ gtk_tree_model_get(model, &iter, TEXT_COLUMN, &text, -1);
+ UT_ASSERT(text);
 
                 g_snprintf(szFontSize, 50, "%spt",
- static_cast<const XML_Char *>(XAP_EncodingManager::fontsizes_mapping.lookupByTarget(text[0])));
+ static_cast<const XML_Char *>(XAP_EncodingManager::fontsizes_mapping.lookupByTarget(text)));
 
 // g_snprintf(szFontSize, 50, "%spt",(UT_convertToPoints(text[0])));
 // g_snprintf(szFontSize, 50, "%spt",text[0]);
@@ -508,15 +536,15 @@
         gtk_box_pack_start (GTK_BOX (vbox1), scrolledwindow1, TRUE, TRUE, 0);
         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
         gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow1), 3);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow1), GTK_SHADOW_IN);
 
- listFonts = gtk_clist_new (1);
+ listFonts = createFontTabTreeView();
         gtk_widget_set_name (listFonts, "listFonts");
         gtk_widget_ref (listFonts);
         g_object_set_data_full (G_OBJECT (window1), "listFonts", listFonts,
                                                           reinterpret_cast<GtkDestroyNotify>(gtk_widget_unref));
         gtk_widget_show (listFonts);
         gtk_container_add (GTK_CONTAINER (scrolledwindow1), listFonts);
- gtk_clist_set_column_auto_resize (GTK_CLIST(listFonts), 0, TRUE);
 
         vbox2 = gtk_vbox_new (FALSE, 0);
         gtk_widget_set_name (vbox2, "vbox2");
@@ -545,15 +573,15 @@
         gtk_box_pack_start (GTK_BOX (vbox2), scrolledwindow2, TRUE, TRUE, 0);
         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
         gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow2), 3);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow2), GTK_SHADOW_IN);
 
- listStyles = gtk_clist_new (1);
+ listStyles = createFontTabTreeView();
         gtk_widget_set_name (listStyles, "listStyles");
         gtk_widget_ref (listStyles);
         g_object_set_data_full (G_OBJECT (window1), "listStyles", listStyles,
                                                           reinterpret_cast<GtkDestroyNotify>(gtk_widget_unref));
         gtk_widget_show (listStyles);
         gtk_container_add (GTK_CONTAINER (scrolledwindow2), listStyles);
- gtk_clist_set_column_auto_resize (GTK_CLIST(listStyles), 0, TRUE);
 
         vbox3 = gtk_vbox_new (FALSE, 0);
         gtk_widget_set_name (vbox3, "vbox3");
@@ -582,15 +610,15 @@
         gtk_box_pack_start (GTK_BOX (vbox3), scrolledwindow3, TRUE, TRUE, 0);
         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow3), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
         gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow3), 3);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow3), GTK_SHADOW_IN);
 
- listSizes = gtk_clist_new (1);
+ listSizes = createFontTabTreeView();
         gtk_widget_set_name (listSizes, "listSizes");
         gtk_widget_ref (listSizes);
         g_object_set_data_full (G_OBJECT (window1), "listSizes", listSizes,
                                                           reinterpret_cast<GtkDestroyNotify>(gtk_widget_unref));
         gtk_widget_show (listSizes);
         gtk_container_add (GTK_CONTAINER (scrolledwindow3), listSizes);
- gtk_clist_set_column_auto_resize (GTK_CLIST(listSizes), 0, TRUE);
 
         vboxmisc = gtk_vbox_new (FALSE, 0);
         gtk_widget_set_name (vboxmisc, "vboxmisc");
@@ -737,17 +765,17 @@
                                            G_CALLBACK(s_transparency_toggled),
                                            static_cast<gpointer>(this));
 
-
         g_signal_connect(G_OBJECT(listFonts),
- "select_row",
+ "cursor_changed",
                                            G_CALLBACK(s_select_row_font),
                                            static_cast<gpointer>(this));
+
         g_signal_connect(G_OBJECT(listStyles),
- "select_row",
+ "cursor_changed",
                                            G_CALLBACK(s_select_row_style),
                                            static_cast<gpointer>(this));
         g_signal_connect(G_OBJECT(listSizes),
- "select_row",
+ "cursor_changed",
                                            G_CALLBACK(s_select_row_size),
                                            static_cast<gpointer>(this));
 
@@ -768,29 +796,54 @@
         GTK_WIDGET_SET_FLAGS(listStyles, GTK_CAN_FOCUS);
         GTK_WIDGET_SET_FLAGS(listSizes, GTK_CAN_FOCUS);
 
- gchar * text[2] = {NULL, NULL};
+ // Make the tab focus list more sensible
+ // font -> syle -> size -> other options ...
+ GList* focusList = NULL;
+
+ focusList = g_list_append(focusList, vbox1);
+ focusList = g_list_append(focusList, vbox2);
+ focusList = g_list_append(focusList, vbox3);
+ focusList = g_list_append(focusList, vboxmisc);
+ gtk_container_set_focus_chain(GTK_CONTAINER(table1), focusList);
+ g_list_free(focusList);
+ gtk_widget_grab_focus(scrolledwindow1);
+
+
+ gchar * text;
+ GtkTreeModel* model;
+ GtkTreeIter iter;
 
         // update the styles list
- gtk_clist_freeze(GTK_CLIST(m_styleList));
- gtk_clist_clear(GTK_CLIST(m_styleList));
- text[0] = const_cast<gchar *>(static_cast<const gchar *>(pSS->getValue(XAP_STRING_ID_DLG_UFS_StyleRegular))); gtk_clist_append(GTK_CLIST(m_styleList), text);
- text[0] = const_cast<gchar *>(static_cast<const gchar *>(pSS->getValue(XAP_STRING_ID_DLG_UFS_StyleItalic))); gtk_clist_append(GTK_CLIST(m_styleList), text);
- text[0] = const_cast<gchar *>(static_cast<const gchar *>(pSS->getValue(XAP_STRING_ID_DLG_UFS_StyleBold))); gtk_clist_append(GTK_CLIST(m_styleList), text);
- text[0] = const_cast<gchar *>(static_cast<const gchar *>(pSS->getValue(XAP_STRING_ID_DLG_UFS_StyleBoldItalic))); gtk_clist_append(GTK_CLIST(m_styleList), text);
- gtk_clist_thaw(GTK_CLIST(m_styleList));
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(m_styleList));
+ gtk_list_store_clear(GTK_LIST_STORE(model));
+
+ text = const_cast<gchar *>(static_cast<const gchar *>(pSS->getValue(XAP_STRING_ID_DLG_UFS_StyleRegular)));
+ gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, TEXT_COLUMN, text, -1);
+ text = const_cast<gchar *>(static_cast<const gchar *>(pSS->getValue(XAP_STRING_ID_DLG_UFS_StyleItalic)));
+ gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, TEXT_COLUMN, text, -1);
+ text = const_cast<gchar *>(static_cast<const gchar *>(pSS->getValue(XAP_STRING_ID_DLG_UFS_StyleBold)));
+ gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, TEXT_COLUMN, text, -1);
+ text = const_cast<gchar *>(static_cast<const gchar *>(pSS->getValue(XAP_STRING_ID_DLG_UFS_StyleBoldItalic)));
+ gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, TEXT_COLUMN, text, -1);
+
 
- gtk_clist_freeze(GTK_CLIST(m_sizeList));
- gtk_clist_clear(GTK_CLIST(m_sizeList));
+
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(m_sizeList));
+ gtk_list_store_clear(GTK_LIST_STORE(model));
         // TODO perhaps populate the list based on the selected font/style?
         {
                 int sz = XAP_EncodingManager::fontsizes_mapping.size();
                 for (int i = 0; i < sz; ++i)
                 {
- text[0]=const_cast<char*>(XAP_EncodingManager::fontsizes_mapping.nth2(i));
- gtk_clist_append(GTK_CLIST(m_sizeList), text);
+ text=const_cast<char*>(XAP_EncodingManager::fontsizes_mapping.nth2(i));
+ gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, TEXT_COLUMN, text, -1);
             }
         }
- gtk_clist_thaw(GTK_CLIST(m_sizeList));
 
         return vboxMain;
 }
@@ -798,10 +851,8 @@
 void XAP_UnixDialog_FontChooser::runModal(XAP_Frame * pFrame)
 {
         m_pFrame = static_cast<XAP_Frame *>(pFrame);
+ gchar* text;
 
- // this is used many times below to grab pointers to
- // strings inside list elements
- gchar * text[2] = {NULL, NULL};
         // used similarly to convert between text and numeric arguments
         static char sizeString[50];
 
@@ -828,8 +879,11 @@
         // to sort out dupes
         UT_StringPtrMap fontHash(256);
 
- gtk_clist_freeze(GTK_CLIST(m_fontList));
- gtk_clist_clear(GTK_CLIST(m_fontList));
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+
+ model = gtk_tree_view_get_model(GTK_TREE_VIEW(m_fontList));
+ gtk_list_store_clear(GTK_LIST_STORE(model));
 
         // throw them in the hash save duplicates
 #ifndef WITH_PANGO
@@ -850,8 +904,11 @@
                   {
                     fontHash.insert(fName,
                                     static_cast<const void *>(fName));
- text[0] = const_cast<gchar*>(fName);
- gtk_clist_append(GTK_CLIST(m_fontList), text);
+
+ text = const_cast<gchar*>(fName);
+ gtk_list_store_append(GTK_LIST_STORE(model), &iter);
+ gtk_list_store_set(GTK_LIST_STORE(model), &iter, TEXT_COLUMN, text, -1);
+
                   }
         }
 
@@ -859,16 +916,20 @@
         DELETEP(fonts);
 #endif
 
- gtk_clist_thaw(GTK_CLIST(m_fontList));
 
         // Set the defaults in the list boxes according to dialog data
         gint foundAt = 0;
 
         // is this safe with an XML_Char * string?
- foundAt = searchCList(GTK_CLIST(m_fontList), const_cast<char *>(getVal("font-family")));
+ foundAt = searchTreeView(GTK_TREE_VIEW(m_fontList), const_cast<char *>(getVal("font-family")));
 
- if (foundAt >= 0)
- gtk_clist_select_row(GTK_CLIST(m_fontList), foundAt, 0);
+ // select and scroll to font name
+ if (foundAt >= 0) {
+ GtkTreePath* path = gtk_tree_path_new_from_indices(foundAt, -1);
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(m_fontList), path, NULL, FALSE);
+ gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(m_fontList), path, NULL, TRUE, 0.5 , 0.0);
+ gtk_tree_path_free(path);
+ }
 
         // this is pretty messy
         listStyle st = LIST_STYLE_NORMAL;
@@ -890,14 +951,26 @@
         {
                 UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
         }
- if (st != LIST_STYLE_NONE)
- gtk_clist_select_row(GTK_CLIST(m_styleList), st, 0);
+
+ // select and scroll to style name
+ if (st != LIST_STYLE_NONE) {
+ GtkTreePath* path = gtk_tree_path_new_from_indices(st, -1);
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(m_styleList), path, NULL, FALSE);
+ gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(m_styleList), path, NULL, TRUE, 0.5 , 0.0);
+ gtk_tree_path_free(path);
+ }
 
         g_snprintf(sizeString, 60, "%s", std_size_string(UT_convertToPoints(getVal("font-size"))));
- foundAt = searchCList(GTK_CLIST(m_sizeList), const_cast<char *>(XAP_EncodingManager::fontsizes_mapping.lookupBySource(sizeString)));
+ foundAt = searchTreeView(GTK_TREE_VIEW(m_sizeList),
+ const_cast<char *>(XAP_EncodingManager::fontsizes_mapping.lookupBySource(sizeString)));
 
- if (foundAt >= 0)
- gtk_clist_select_row(GTK_CLIST(m_sizeList), foundAt, 0);
+ // select and scroll to size name
+ if (foundAt >= 0) {
+ GtkTreePath* path = gtk_tree_path_new_from_indices(foundAt, -1);
+ gtk_tree_view_set_cursor(GTK_TREE_VIEW(m_sizeList), path, NULL, FALSE);
+ gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(m_sizeList), path, NULL, TRUE, 0.5 , 0.0);
+ gtk_tree_path_free(path);
+ }
 
         // Set color in the color selector
         if (getVal("color"))
Received on Sat Sep 4 07:28:41 2004

This archive was generated by hypermail 2.1.8 : Sat Sep 04 2004 - 07:28:42 CEST