/* AbiSource Application Framework * Copyright (C) 1998-2000 AbiSource, 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., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ // 9/4/04 Updated to use GtkTreeView , Tim O'Brien (obrientimo@vuw.ac.nz) #include #include #include #include #include "ut_assert.h" #include "ut_debugmsg.h" #include "ut_string.h" #include "ut_misc.h" #include "ut_hash.h" #include "ut_units.h" #include "xap_UnixDialogHelper.h" #include "xap_UnixDlg_FontChooser.h" #include "xap_UnixApp.h" #include "xap_Frame.h" #include "xap_UnixFrameImpl.h" #include "xap_EncodingManager.h" #include "gr_UnixGraphics.h" #define PREVIEW_BOX_BORDER_WIDTH_PIXELS 8 #define PREVIEW_BOX_HEIGHT_PIXELS 80 // your typographer's standard nonsense latin font phrase #define PREVIEW_ENTRY_DEFAULT_STRING "Lorem ipsum dolor sit amet, consectetaur adipisicing..." // // For Screen color picker enum { RED, GREEN, BLUE, OPACITY }; // // List store model , used as model for GtkTreeView enum { TEXT_COLUMN, N_COLUMNS }; static gint searchTreeView(GtkTreeView* tv, char * compareText) { GtkTreeModel* model; GtkTreeIter iter; char* text; UT_ASSERT(tv); // if text is null, it's not found if (!compareText) return -1; 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) { XAP_UnixDialog_FontChooser * p = new XAP_UnixDialog_FontChooser(pFactory,id); return p; } XAP_UnixDialog_FontChooser::XAP_UnixDialog_FontChooser(XAP_DialogFactory * pDlgFactory, XAP_Dialog_Id id) : XAP_Dialog_FontChooser(pDlgFactory,id) { m_fontManager = NULL; m_fontList = NULL; m_styleList = NULL; m_sizeList = NULL; m_checkStrikeOut = NULL; m_checkUnderline = NULL; m_checkOverline = NULL; m_checkHidden = NULL; m_checkTransparency = NULL; m_colorSelector = NULL; m_bgcolorSelector = NULL; m_preview = NULL; m_lastFont = NULL; m_gc = NULL; m_pFrame = NULL; m_doneFirstFont = false; for(UT_sint32 i = 0; i < 4;i++) { m_currentFGColor[i] = 0.0; m_currentBGColor[i] = 0.0; m_funkyColor[i] = 0.0; } } XAP_UnixDialog_FontChooser::~XAP_UnixDialog_FontChooser(void) { DELETEP(m_gc); DELETEP(m_lastFont); } /*****************************************************************/ static gint s_color_update(GtkWidget * /* widget */, XAP_UnixDialog_FontChooser * dlg) { UT_ASSERT(dlg); dlg->fgColorChanged(); return FALSE; } static gint s_bgcolor_update(GtkWidget * /* widget */, XAP_UnixDialog_FontChooser * dlg) { UT_ASSERT(dlg); dlg->bgColorChanged(); return FALSE; } static void s_select_row_font(GtkWidget * /* widget */, XAP_UnixDialog_FontChooser * dlg) { UT_ASSERT(dlg); // update the row number and show the changed preview // redisplay the preview text dlg->fontRowChanged(); } static void s_select_row_style(GtkWidget * /* widget */, XAP_UnixDialog_FontChooser * dlg) { UT_ASSERT(dlg); // redisplay the preview text dlg->styleRowChanged(); } static void s_select_row_size(GtkWidget * /* widget */, XAP_UnixDialog_FontChooser * dlg) { UT_ASSERT(dlg); // redisplay the preview text dlg->sizeRowChanged(); } static gboolean s_drawing_area_expose(GtkWidget * w, GdkEventExpose * /* pExposeEvent */) { XAP_UnixDialog_FontChooser * dlg = (XAP_UnixDialog_FontChooser *) gtk_object_get_user_data(GTK_OBJECT(w)); dlg->updatePreview(); // g_idle_add(static_cast(do_update),static_cast(dlg)); return TRUE; } static void s_underline_toggled(GtkWidget * w, XAP_UnixDialog_FontChooser * dlg) { dlg->underlineChanged(); } static void s_overline_toggled(GtkWidget * w, XAP_UnixDialog_FontChooser * dlg) { dlg->overlineChanged(); } static void s_strikeout_toggled(GtkWidget * w, XAP_UnixDialog_FontChooser * dlg) { dlg->strikeoutChanged(); } static void s_hidden_toggled(GtkWidget * w, XAP_UnixDialog_FontChooser * dlg) { dlg->hiddenChanged(); } static void s_transparency_toggled(GtkWidget * w, XAP_UnixDialog_FontChooser * dlg) { dlg->transparencyChanged(); } /*****************************************************************/ void XAP_UnixDialog_FontChooser::underlineChanged(void) { m_bUnderline = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_checkUnderline)); m_bChangedUnderline = !m_bChangedUnderline; setFontDecoration(m_bUnderline,m_bOverline,m_bStrikeout,m_bTopline,m_bBottomline); updatePreview(); } void XAP_UnixDialog_FontChooser::strikeoutChanged(void) { m_bStrikeout = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_checkStrikeOut)); m_bChangedStrikeOut = !m_bChangedStrikeOut; setFontDecoration(m_bUnderline,m_bOverline,m_bStrikeout,m_bTopline,m_bBottomline); updatePreview(); } void XAP_UnixDialog_FontChooser::overlineChanged(void) { m_bOverline = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_checkOverline)); m_bChangedOverline = !m_bChangedOverline; setFontDecoration(m_bUnderline,m_bOverline,m_bStrikeout,m_bTopline,m_bBottomline); updatePreview(); } void XAP_UnixDialog_FontChooser::hiddenChanged(void) { m_bHidden = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_checkHidden)); m_bChangedHidden = !m_bChangedHidden; } void XAP_UnixDialog_FontChooser::transparencyChanged(void) { bool bTrans = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_checkTransparency)); if(bTrans) { addOrReplaceVecProp("bgcolor","transparent"); m_currentBGColor[RED] = -1; m_currentBGColor[GREEN] = -1; m_currentBGColor[BLUE] = -1; } updatePreview(); } void XAP_UnixDialog_FontChooser::fontRowChanged(void) { static char szFontFamily[60]; 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(szFontFamily)); } updatePreview(); } void XAP_UnixDialog_FontChooser::styleRowChanged(void) { 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. :) if (rowNumber == LIST_STYLE_NORMAL) { addOrReplaceVecProp("font-style","normal"); addOrReplaceVecProp("font-weight","normal"); } else if (rowNumber == LIST_STYLE_BOLD) { addOrReplaceVecProp("font-style","normal"); addOrReplaceVecProp("font-weight","bold"); } else if (rowNumber == LIST_STYLE_ITALIC) { addOrReplaceVecProp("font-style","italic"); addOrReplaceVecProp("font-weight","normal"); } else if (rowNumber == LIST_STYLE_BOLD_ITALIC) { addOrReplaceVecProp("font-style","italic"); addOrReplaceVecProp("font-weight","bold"); } else { UT_ASSERT(0); } } updatePreview(); } void XAP_UnixDialog_FontChooser::sizeRowChanged(void) { // used similarly to convert between text and numeric arguments static char szFontSize[50]; 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(XAP_EncodingManager::fontsizes_mapping.lookupByTarget(text))); // g_snprintf(szFontSize, 50, "%spt",(UT_convertToPoints(text[0]))); // g_snprintf(szFontSize, 50, "%spt",text[0]); addOrReplaceVecProp("font-size",static_cast(szFontSize)); } updatePreview(); } void XAP_UnixDialog_FontChooser::fgColorChanged(void) { static char buf_color[8]; gtk_color_selection_get_color(GTK_COLOR_SELECTION(m_colorSelector), m_currentFGColor); // test for funkyColor-has-been-changed-to-sane-color case if (m_currentFGColor[RED] >= 0 && m_currentFGColor[GREEN] >= 0 && m_currentFGColor[BLUE] >= 0) { sprintf(buf_color, "%02x%02x%02x", static_cast(m_currentFGColor[RED] * static_cast(255.0)), static_cast(m_currentFGColor[GREEN] * static_cast(255.0)), static_cast(m_currentFGColor[BLUE] * static_cast(255.0))); addOrReplaceVecProp("color",static_cast(buf_color)); } updatePreview(); } void XAP_UnixDialog_FontChooser::bgColorChanged(void) { static char buf_color[8]; gtk_color_selection_get_color(GTK_COLOR_SELECTION(m_bgcolorSelector), m_currentBGColor); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_checkTransparency), FALSE); // test for funkyColor-has-been-changed-to-sane-color case if (m_currentBGColor[RED] >= 0 && m_currentBGColor[GREEN] >= 0 && m_currentBGColor[BLUE] >= 0) { sprintf(buf_color, "%02x%02x%02x", static_cast(m_currentBGColor[RED] * static_cast(255.0)), static_cast(m_currentBGColor[GREEN] * static_cast(255.0)), static_cast(m_currentBGColor[BLUE] * static_cast(255.0))); addOrReplaceVecProp("bgcolor",static_cast(buf_color)); } updatePreview(); } GtkWidget * XAP_UnixDialog_FontChooser::constructWindow(void) { const XAP_StringSet * pSS = m_pApp->getStringSet(); GtkWidget *windowFontSelection; GtkWidget *vboxMain; GtkWidget *vboxOuter; windowFontSelection = abiDialogNew ( "font dialog", TRUE, pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_FontTitle).utf8_str() ) ; vboxOuter = GTK_DIALOG(windowFontSelection)->vbox; vboxMain = constructWindowContents(vboxOuter); gtk_box_pack_start (GTK_BOX (vboxOuter), vboxMain, TRUE, TRUE, 0); abiAddStockButton ( GTK_DIALOG(windowFontSelection), GTK_STOCK_CANCEL, BUTTON_CANCEL ) ; abiAddStockButton ( GTK_DIALOG(windowFontSelection), GTK_STOCK_OK, BUTTON_OK ) ; return windowFontSelection; } // Glade generated dialog, using fixed widgets to closely match // the Windows layout, with some changes for color selector GtkWidget * XAP_UnixDialog_FontChooser::constructWindowContents(GtkWidget *parent) { GtkWidget *vboxMain; GtkWidget *notebookMain; GtkWidget *labelFont; GtkWidget *labelStyle; GtkWidget *listFonts; GtkWidget *labelSize; GtkWidget *frameEffects; GtkWidget *hboxDecorations; GtkWidget *checkbuttonStrikeout; GtkWidget *checkbuttonUnderline; GtkWidget *checkbuttonOverline; GtkWidget *checkbuttonHidden; GtkWidget *listStyles; GtkWidget *listSizes; GtkWidget *hbox1; GtkWidget *colorSelector; GtkWidget *colorBGSelector; GtkWidget *labelTabFont; GtkWidget *labelTabColor; GtkWidget *labelTabBGColor; GtkWidget *frame4; // the entry is a special drawing area full of one // of our graphics contexts GtkWidget *entryArea; const XAP_StringSet * pSS = m_pApp->getStringSet(); vboxMain = gtk_vbox_new (FALSE, 0); gtk_widget_show (vboxMain); notebookMain = gtk_notebook_new (); gtk_widget_show (notebookMain); gtk_box_pack_start (GTK_BOX (vboxMain), notebookMain, 1, 1, 0); gtk_container_set_border_width (GTK_CONTAINER (notebookMain), 8); GtkWidget *window1 = parent; GtkWidget *table1; GtkWidget *vbox1; GtkWidget *scrolledwindow1; GtkWidget *vbox2; GtkWidget *scrolledwindow2; GtkWidget *vbox3; GtkWidget *scrolledwindow3; GtkWidget *vboxmisc; // GtkWidget *hboxForEncoding; table1 = gtk_table_new (2, 3, FALSE); gtk_widget_set_name (table1, "table1"); gtk_widget_ref (table1); g_object_set_data_full (G_OBJECT (window1), "table1", table1, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (table1); // Label for first page of the notebook labelTabFont = gtk_label_new (pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_FontTab).utf8_str()); gtk_widget_show (labelTabFont); // // Make first page of the notebook // gtk_notebook_append_page(GTK_NOTEBOOK(notebookMain), table1,labelTabFont); vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_set_name (vbox1, "vbox1"); gtk_widget_ref (vbox1); g_object_set_data_full (G_OBJECT (window1), "vbox1", vbox1, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (vbox1); gtk_table_attach (GTK_TABLE (table1), vbox1, 0, 1, 0, 2, static_cast(GTK_EXPAND | GTK_FILL), static_cast(GTK_EXPAND | GTK_FILL), 0, 0); labelFont = gtk_label_new (pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_FontLabel).utf8_str()); gtk_widget_set_name (labelFont, "labelFont"); gtk_widget_ref (labelFont); g_object_set_data_full (G_OBJECT (window1), "labelFont", labelFont, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (labelFont); gtk_box_pack_start (GTK_BOX (vbox1), labelFont, FALSE, FALSE, 0); scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_name (scrolledwindow1, "scrolledwindow1"); gtk_widget_ref (scrolledwindow1); g_object_set_data_full (G_OBJECT (window1), "scrolledwindow1", scrolledwindow1, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (scrolledwindow1); 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 = createFontTabTreeView(); gtk_widget_set_name (listFonts, "listFonts"); gtk_widget_ref (listFonts); g_object_set_data_full (G_OBJECT (window1), "listFonts", listFonts, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (listFonts); gtk_container_add (GTK_CONTAINER (scrolledwindow1), listFonts); vbox2 = gtk_vbox_new (FALSE, 0); gtk_widget_set_name (vbox2, "vbox2"); gtk_widget_ref (vbox2); g_object_set_data_full (G_OBJECT (window1), "vbox2", vbox2, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (vbox2); gtk_table_attach (GTK_TABLE (table1), vbox2, 1, 2, 0, 1, static_cast(GTK_FILL), static_cast(GTK_FILL), 0, 0); labelStyle = gtk_label_new (pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_StyleLabel).utf8_str()); gtk_widget_set_name (labelStyle, "labelStyle"); gtk_widget_ref (labelStyle); g_object_set_data_full (G_OBJECT (window1), "labelStyle", labelStyle, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (labelStyle); gtk_box_pack_start (GTK_BOX (vbox2), labelStyle, FALSE, FALSE, 0); scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_name (scrolledwindow2, "scrolledwindow2"); gtk_widget_ref (scrolledwindow2); g_object_set_data_full (G_OBJECT (window1), "scrolledwindow2", scrolledwindow2, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (scrolledwindow2); 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 = createFontTabTreeView(); gtk_widget_set_name (listStyles, "listStyles"); gtk_widget_ref (listStyles); g_object_set_data_full (G_OBJECT (window1), "listStyles", listStyles, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (listStyles); gtk_container_add (GTK_CONTAINER (scrolledwindow2), listStyles); vbox3 = gtk_vbox_new (FALSE, 0); gtk_widget_set_name (vbox3, "vbox3"); gtk_widget_ref (vbox3); g_object_set_data_full (G_OBJECT (window1), "vbox3", vbox3, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (vbox3); gtk_table_attach (GTK_TABLE (table1), vbox3, 2, 3, 0, 1, static_cast(GTK_FILL), static_cast(GTK_FILL), 0, 0); labelSize = gtk_label_new (pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_SizeLabel).utf8_str()); gtk_widget_set_name (labelSize, "labelSize"); gtk_widget_ref (labelSize); g_object_set_data_full (G_OBJECT (window1), "labelSize", labelSize, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (labelSize); gtk_box_pack_start (GTK_BOX (vbox3), labelSize, FALSE, FALSE, 0); scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL); gtk_widget_set_name (scrolledwindow3, "scrolledwindow3"); gtk_widget_ref (scrolledwindow3); g_object_set_data_full (G_OBJECT (window1), "scrolledwindow3", scrolledwindow3, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (scrolledwindow3); 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 = createFontTabTreeView(); gtk_widget_set_name (listSizes, "listSizes"); gtk_widget_ref (listSizes); g_object_set_data_full (G_OBJECT (window1), "listSizes", listSizes, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (listSizes); gtk_container_add (GTK_CONTAINER (scrolledwindow3), listSizes); vboxmisc = gtk_vbox_new (FALSE, 0); gtk_widget_set_name (vboxmisc, "vboxmisc"); gtk_widget_ref (vboxmisc); g_object_set_data_full (G_OBJECT (window1), "vboxmisc", vboxmisc, reinterpret_cast(gtk_widget_unref)); gtk_widget_show (vboxmisc); gtk_table_attach (GTK_TABLE (table1), vboxmisc, 1, 3, 1, 2, static_cast(GTK_FILL), static_cast(GTK_FILL), 0, 0); frameEffects = gtk_frame_new (pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_EffectsFrameLabel).utf8_str()); gtk_frame_set_shadow_type(GTK_FRAME(frameEffects), GTK_SHADOW_NONE); gtk_widget_show (frameEffects); gtk_box_pack_start(GTK_BOX (vboxmisc), frameEffects, 0,0, 2); hboxDecorations = gtk_hbox_new (FALSE, 0); gtk_widget_show (hboxDecorations); gtk_container_add (GTK_CONTAINER (frameEffects), hboxDecorations); checkbuttonStrikeout = gtk_check_button_new_with_label (pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_StrikeoutCheck).utf8_str()); gtk_container_border_width (GTK_CONTAINER (checkbuttonStrikeout), 5); gtk_widget_show (checkbuttonStrikeout); gtk_box_pack_start (GTK_BOX (hboxDecorations), checkbuttonStrikeout, TRUE, TRUE, 0); checkbuttonUnderline = gtk_check_button_new_with_label (pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_UnderlineCheck).utf8_str()); gtk_container_border_width (GTK_CONTAINER (checkbuttonUnderline), 5); gtk_widget_show (checkbuttonUnderline); gtk_box_pack_start (GTK_BOX (hboxDecorations), checkbuttonUnderline, TRUE, TRUE, 0); checkbuttonOverline = gtk_check_button_new_with_label (pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_OverlineCheck).utf8_str()); gtk_container_border_width (GTK_CONTAINER (checkbuttonOverline), 5); gtk_widget_show (checkbuttonOverline); gtk_box_pack_start (GTK_BOX (hboxDecorations), checkbuttonOverline, TRUE, TRUE, 0); checkbuttonHidden = gtk_check_button_new_with_label (pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_HiddenCheck).utf8_str()); gtk_container_border_width (GTK_CONTAINER (checkbuttonHidden), 5); gtk_widget_show (checkbuttonHidden); gtk_box_pack_start (GTK_BOX (hboxDecorations), checkbuttonHidden, TRUE, TRUE, 0); /* Notebook page for ForeGround Color Selector */ hbox1 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox1); // Label for second page of the notebook labelTabColor = gtk_label_new (pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_ColorTab).utf8_str()); gtk_widget_show (labelTabColor); // // Make second page of the notebook // gtk_notebook_append_page(GTK_NOTEBOOK(notebookMain), hbox1,labelTabColor); colorSelector = gtk_color_selection_new (); gtk_color_selection_set_has_opacity_control(GTK_COLOR_SELECTION(colorSelector), FALSE); gtk_widget_show (colorSelector); gtk_box_pack_start (GTK_BOX (hbox1), colorSelector, TRUE, TRUE, 0); /*Notebook page for Background Color Selector*/ GtkWidget * vboxBG = gtk_vbox_new (FALSE, 0); gtk_widget_show (vboxBG); // Label for third page of the notebook labelTabBGColor = gtk_label_new (pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_BGColorTab).utf8_str()); gtk_widget_show (labelTabBGColor); // // Make third page of the notebook // gtk_notebook_append_page(GTK_NOTEBOOK(notebookMain), vboxBG,labelTabBGColor); colorBGSelector = gtk_color_selection_new (); gtk_color_selection_set_has_opacity_control(GTK_COLOR_SELECTION(colorBGSelector), FALSE); gtk_widget_show (colorBGSelector); gtk_box_pack_start (GTK_BOX (vboxBG), colorBGSelector, TRUE, TRUE, 0); // // Make a toggle button to set hightlight color transparent // GtkWidget * checkbuttonTrans = gtk_check_button_new_with_label (pSS->getValueUTF8(XAP_STRING_ID_DLG_UFS_TransparencyCheck).utf8_str()); gtk_widget_show (checkbuttonTrans); gtk_box_pack_start (GTK_BOX (vboxBG), checkbuttonTrans, TRUE, TRUE, 0); /* frame with preview */ frame4 = gtk_frame_new (NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame4), GTK_SHADOW_NONE); gtk_widget_show (frame4); gtk_box_pack_start (GTK_BOX (vboxMain), frame4, FALSE, FALSE, PREVIEW_BOX_BORDER_WIDTH_PIXELS); // setting the height takes into account the border applied on all // sides, so we need to double the single border width gtk_widget_set_size_request (frame4, -1, PREVIEW_BOX_HEIGHT_PIXELS + (PREVIEW_BOX_BORDER_WIDTH_PIXELS * 2)); gtk_container_border_width (GTK_CONTAINER (frame4), PREVIEW_BOX_BORDER_WIDTH_PIXELS); entryArea = createDrawingArea (); gtk_widget_set_events(entryArea, GDK_EXPOSURE_MASK); g_signal_connect(G_OBJECT(entryArea), "expose_event", G_CALLBACK(s_drawing_area_expose), NULL); gtk_widget_set_size_request (entryArea, -1, PREVIEW_BOX_HEIGHT_PIXELS); gtk_widget_show (entryArea); gtk_container_add (GTK_CONTAINER (frame4), entryArea); // save out to members for callback and class access m_fontList = listFonts; m_styleList = listStyles; m_sizeList = listSizes; m_colorSelector = colorSelector; m_bgcolorSelector = colorBGSelector; m_preview = entryArea; m_checkStrikeOut = checkbuttonStrikeout; m_checkUnderline = checkbuttonUnderline; m_checkOverline = checkbuttonOverline; m_checkHidden = checkbuttonHidden; m_checkTransparency = checkbuttonTrans; // bind signals to things g_signal_connect(G_OBJECT(m_checkUnderline), "toggled", G_CALLBACK(s_underline_toggled), static_cast(this)); g_signal_connect(G_OBJECT(m_checkOverline), "toggled", G_CALLBACK(s_overline_toggled), static_cast(this)); g_signal_connect(G_OBJECT(m_checkStrikeOut), "toggled", G_CALLBACK(s_strikeout_toggled), static_cast(this)); g_signal_connect(G_OBJECT(m_checkHidden), "toggled", G_CALLBACK(s_hidden_toggled), static_cast(this)); g_signal_connect(G_OBJECT(m_checkTransparency), "toggled", G_CALLBACK(s_transparency_toggled), static_cast(this)); g_signal_connect(G_OBJECT(listFonts), "cursor_changed", G_CALLBACK(s_select_row_font), static_cast(this)); g_signal_connect(G_OBJECT(listStyles), "cursor_changed", G_CALLBACK(s_select_row_style), static_cast(this)); g_signal_connect(G_OBJECT(listSizes), "cursor_changed", G_CALLBACK(s_select_row_size), static_cast(this)); // This is a catch-all color selector callback which catches any // real-time updating of the color so we can refresh our preview // text g_signal_connect(G_OBJECT(colorSelector), "color-changed", //"event", G_CALLBACK(s_color_update), static_cast(this)); g_signal_connect(G_OBJECT(colorBGSelector), "color-changed", //"event", G_CALLBACK(s_bgcolor_update), static_cast(this)); GTK_WIDGET_SET_FLAGS(listFonts, GTK_CAN_FOCUS); GTK_WIDGET_SET_FLAGS(listStyles, GTK_CAN_FOCUS); GTK_WIDGET_SET_FLAGS(listSizes, GTK_CAN_FOCUS); // 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 model = gtk_tree_view_get_model(GTK_TREE_VIEW(m_styleList)); gtk_list_store_clear(GTK_LIST_STORE(model)); text = const_cast(static_cast(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(static_cast(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(static_cast(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(static_cast(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); 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=const_cast(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); } } return vboxMain; } void XAP_UnixDialog_FontChooser::runModal(XAP_Frame * pFrame) { m_pFrame = static_cast(pFrame); gchar* text; // used similarly to convert between text and numeric arguments static char sizeString[50]; // Set up our own color space so we work well on 8-bit // displays. // establish the font manager before dialog creation #ifndef WITH_PANGO XAP_App * app = m_pFrame->getApp(); XAP_UnixApp * unixapp = static_cast (app); m_fontManager = unixapp->getFontManager(); #else XAP_App *pApp = m_pFrame->getApp(); m_gc = new GR_UnixGraphics(m_preview->window, pApp); m_fontManager = m_gc->getFontManager(); #endif // build the dialog GtkWidget * cf = constructWindow(); // freeze updates of the preview m_blockUpdate = true; // to sort out dupes UT_StringPtrMap fontHash(256); 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 UT_Vector * fonts = m_fontManager->getAllFonts(); for (UT_uint32 i = 0; i < fonts->size(); i++) { XAP_UnixFont * pFont = static_cast(fonts->getNthItem(i)); const char * fName = pFont->getName(); #else for(UT_uint32 i = 0; i < m_fontManager->getAvailableFontFamiliesCount(); i++) { const char * fName = m_fontManager->getNthAvailableFontFamily(i); #endif if (!fontHash.contains(fName, NULL)) { fontHash.insert(fName, static_cast(fName)); text = const_cast(fName); gtk_list_store_append(GTK_LIST_STORE(model), &iter); gtk_list_store_set(GTK_LIST_STORE(model), &iter, TEXT_COLUMN, text, -1); } } #ifndef WITH_PANGO DELETEP(fonts); #endif // Set the defaults in the list boxes according to dialog data gint foundAt = 0; // is this safe with an XML_Char * string? foundAt = searchTreeView(GTK_TREE_VIEW(m_fontList), const_cast(getVal("font-family"))); // 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; if (!getVal("font-style") || !getVal("font-weight")) st = LIST_STYLE_NONE; else if (!UT_stricmp(getVal("font-style"), "normal") && !UT_stricmp(getVal("font-weight"), "normal")) st = LIST_STYLE_NORMAL; else if (!UT_stricmp(getVal("font-style"), "normal") && !UT_stricmp(getVal("font-weight"), "bold")) st = LIST_STYLE_BOLD; else if (!UT_stricmp(getVal("font-style"), "italic") && !UT_stricmp(getVal("font-weight"), "normal")) st = LIST_STYLE_ITALIC; else if (!UT_stricmp(getVal("font-style"), "italic") && !UT_stricmp(getVal("font-weight"), "bold")) st = LIST_STYLE_BOLD_ITALIC; else { UT_ASSERT(UT_SHOULD_NOT_HAPPEN); } // 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 = searchTreeView(GTK_TREE_VIEW(m_sizeList), const_cast(XAP_EncodingManager::fontsizes_mapping.lookupBySource(sizeString))); // 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")) { UT_RGBColor c; UT_parseColor(getVal("color"), c); m_currentFGColor[RED] = (static_cast(c.m_red) / static_cast(255.0)); m_currentFGColor[GREEN] = (static_cast(c.m_grn) / static_cast(255.0)); m_currentFGColor[BLUE] = (static_cast(c.m_blu) / static_cast(255.0)); gtk_color_selection_set_color(GTK_COLOR_SELECTION(m_colorSelector), m_currentFGColor); } else { // if we have no color, use a placeholder of funky values // the user can't pick interactively. This catches ALL // the cases except where the user specifically enters -1 for // all Red, Green and Blue attributes manually. This user // should expect it not to touch the color. :) gtk_color_selection_set_color(GTK_COLOR_SELECTION(m_colorSelector), m_funkyColor); } // Set color in the color selector const XML_Char * pszBGCol = getVal("bgcolor"); if (pszBGCol && strcmp(pszBGCol,"transparent") != 0) { UT_RGBColor c; UT_parseColor(getVal("bgcolor"), c); m_currentBGColor[RED] = (static_cast(c.m_red) / static_cast(255.0)); m_currentBGColor[GREEN] = (static_cast(c.m_grn) / static_cast(255.0)); m_currentBGColor[BLUE] = (static_cast(c.m_blu) / static_cast(255.0)); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_checkTransparency), FALSE); gtk_color_selection_set_color(GTK_COLOR_SELECTION(m_bgcolorSelector), m_currentBGColor); } else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_checkTransparency), TRUE); // set the strikeout and underline check buttons gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_checkStrikeOut), m_bStrikeout); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_checkUnderline), m_bUnderline); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_checkOverline), m_bOverline); m_doneFirstFont = true; // attach a new graphics context gtk_widget_show ( cf ) ; #ifndef WITH_PANGO XAP_App *pApp = pFrame->getApp(); m_gc = new GR_UnixGraphics(m_preview->window, m_fontManager, pApp); #endif _createFontPreviewFromGC(m_gc,m_preview->allocation.width,m_preview->allocation.height); // // This enables callbacks on the preview area with a widget pointer to // access this dialog. // gtk_object_set_user_data(GTK_OBJECT(m_preview), this); // unfreeze updates of the preview m_blockUpdate = false; // manually trigger an update updatePreview(); switch ( abiRunModalDialog ( GTK_DIALOG(cf), pFrame, this, BUTTON_CANCEL, true ) ) { case BUTTON_OK: { m_answer = a_OK; break ; } default: { m_answer = a_CANCEL; break; } } // these dialogs are cached around through the dialog framework, // and this variable needs to get set back m_doneFirstFont = false; UT_DEBUGMSG(("FontChooserEnd: Family[%s%s] Size[%s%s] Weight[%s%s] Style[%s%s] Color[%s%s] Underline[%d%s] StrikeOut[%d%s]\n", ((getVal("font-family")) ? getVal("font-family") : ""), ((m_bChangedFontFamily) ? "(chg)" : ""), ((getVal("font-size")) ? getVal("font-size") : ""), ((m_bChangedFontSize) ? "(chg)" : ""), ((getVal("font-weight")) ? getVal("font-weight") : ""), ((m_bChangedFontWeight) ? "(chg)" : ""), ((getVal("font-style")) ? getVal("font-style") : ""), ((m_bChangedFontStyle) ? "(chg)" : ""), ((getVal("color")) ? getVal("color") : "" ), ((m_bChangedColor) ? "(chg)" : ""), (m_bUnderline), ((m_bChangedUnderline) ? "(chg)" : ""), (m_bStrikeout), ((m_bChangedStrikeOut) ? "(chg)" : ""))); // answer should be set by the appropriate callback // the caller can get the answer from getAnswer(). m_pFrame = NULL; } void XAP_UnixDialog_FontChooser::updatePreview(void) { // if we don't have anything yet, just ignore this request if (!m_gc) return; // if a font has been set since this dialog was launched, draw things with it if (m_doneFirstFont) { const UT_UCSChar * entryString = getDrawString (); if (!entryString) return; event_previewExposed(entryString); } else event_previewClear(); }