diff options
| author | su_v <suv-sf@users.sourceforge.net> | 2013-03-08 08:59:37 +0000 |
|---|---|---|
| committer | ~suv <suv-sf@users.sourceforge.net> | 2013-03-08 08:59:37 +0000 |
| commit | d8a3b36b43e0700126a7a25a1d38858d1a1d4836 (patch) | |
| tree | eaf5a86ac5542fc33ed8bb697a615e08ddd2ae01 /src/widgets | |
| parent | changes_2013_02_25a.patch (diff) | |
| parent | Drop deprecated get_vbox method in Gtk::Dialog (diff) | |
| download | inkscape-d8a3b36b43e0700126a7a25a1d38858d1a1d4836.tar.gz inkscape-d8a3b36b43e0700126a7a25a1d38858d1a1d4836.zip | |
merge from trunk (r12181)
(bzr r11668.1.53)
Diffstat (limited to 'src/widgets')
| -rw-r--r-- | src/widgets/desktop-widget.cpp | 9 | ||||
| -rw-r--r-- | src/widgets/font-selector.cpp | 262 | ||||
| -rw-r--r-- | src/widgets/font-selector.h | 27 | ||||
| -rw-r--r-- | src/widgets/icon.cpp | 1 | ||||
| -rw-r--r-- | src/widgets/text-toolbar.cpp | 486 |
5 files changed, 235 insertions, 550 deletions
diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 9e078cabb..b0d8d974e 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -82,11 +82,6 @@ using Inkscape::UI::UXManager; using Inkscape::UI::ToolboxFactory; using ege::AppearTimeTracker; -#ifdef WITH_INKBOARD -#endif - - - enum { ACTIVATE, DEACTIVATE, @@ -775,6 +770,10 @@ static void sp_desktop_widget_dispose(GObject *object) { SPDesktopWidget *dtw = SP_DESKTOP_WIDGET (object); + if (dtw == NULL) { + return; + } + UXManager::getInstance()->delTrack(dtw); if (dtw->desktop) { diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index 013ad9e94..453ef683f 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -8,10 +8,11 @@ * Lauris Kaplinski <lauris@kaplinski.com> * bulia byak <buliabyak@users.sf.net> * Johan Engelen <j.b.c.engelen@ewi.utwente.nl> + * Tavmjong Bah <tavmjong@free.fr> * * Copyright (C) 1999-2001 Ximian, Inc. * Copyright (C) 2002 Lauris Kaplinski - * Copyright (C) -2007 Authors + * Copyright (C) -2013 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -51,11 +52,9 @@ struct SPFontSelector NRNameList families; NRStyleList styles; - int familyidx; - int styleidx; gfloat fontsize; bool fontsize_dirty; - font_instance *font; + Glib::ustring *fontspec; }; @@ -63,7 +62,7 @@ struct SPFontSelectorClass { GtkHBoxClass parent_class; - void (* font_set) (SPFontSelector *fsel, font_instance *font); + void (* font_set) (SPFontSelector *fsel, gchar *fontspec); }; enum { @@ -138,6 +137,9 @@ static void sp_font_selector_set_size_tooltip(SPFontSelector *fsel) } +/* + * Create a widget with children for selecting font-family, font-style, and font-size. + */ static void sp_font_selector_init(SPFontSelector *fsel) { gtk_box_set_homogeneous(GTK_BOX(fsel), TRUE); @@ -155,8 +157,6 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(f), sw); - Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - fsel->family_treeview = gtk_tree_view_new (); GtkTreeViewColumn *column = gtk_tree_view_column_new (); GtkCellRenderer *cell = gtk_cell_renderer_text_new (); @@ -177,6 +177,7 @@ static void sp_font_selector_init(SPFontSelector *fsel) "widget \"*font_selector_family\" style \"fontfamily-separator-style\""); + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); Glib::RefPtr<Gtk::ListStore> store = fontlister->get_font_list(); gtk_tree_view_set_model (GTK_TREE_VIEW(fsel->family_treeview), GTK_TREE_MODEL (Glib::unwrap (store))); gtk_container_add(GTK_CONTAINER(sw), fsel->family_treeview); @@ -231,6 +232,7 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_widget_show(hb); gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 0); + // Font-size fsel->size = gtk_combo_box_text_new_with_entry (); sp_font_selector_set_size_tooltip(fsel); @@ -246,20 +248,20 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_widget_show_all (fsel->size); - fsel->familyidx = 0; - fsel->styleidx = 0; - fsel->fontsize = 10.0; + // Set default size... next two lines must match + gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(fsel->size))), "18.0"); + fsel->fontsize = 18.0; fsel->fontsize_dirty = false; - fsel->font = NULL; + + fsel->fontspec = new Glib::ustring; } static void sp_font_selector_dispose(GObject *object) { SPFontSelector *fsel = SP_FONT_SELECTOR (object); - if (fsel->font) { - fsel->font->Unref(); - fsel->font = NULL; + if (fsel->fontspec) { + delete fsel->fontspec; } if (fsel->families.length > 0) { @@ -277,49 +279,62 @@ static void sp_font_selector_dispose(GObject *object) } } +// Callback when family changed, updates style list for new family. static void sp_font_selector_family_select_row(GtkTreeSelection *selection, SPFontSelector *fsel) { - GtkTreeIter iter; - GtkTreeModel *model; - GtkListStore *store; - GtkTreePath *path; - GList *list=0; + // We need our own copy of the style list store since the font-family + // may not be the same in the font-selector as stored in the font-lister + // TODO: use font-lister class for this by modifying new_font_family to accept an optional style list + // TODO: add store to SPFontSelector struct and reuse. + + // Start by getting iterator to selected font + GtkTreeModel *model; + GtkTreeIter iter; if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; - path = gtk_tree_model_get_path (model, &iter); - gtk_tree_model_get (model, &iter, 1, &list, -1); - fsel->familyidx = gtk_tree_path_get_indices (path)[0]; - fsel->styleidx = 0; + // Next get family name with its style list + gchar *family; + GList *list=0; + gtk_tree_model_get (model, &iter, 0, &family, 1, &list, -1); - store = gtk_list_store_new (1, G_TYPE_STRING); + // Find best style match for selected family with current style (e.g. of selected text). + Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); + Glib::ustring style = fontlister->get_font_style(); + Glib::ustring best = fontlister->get_best_style_match (family, style); + // Create our own store of styles for selected font-family and find index of best style match + int path_index = 0; + int index = 0; + GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); // Where is this deleted? for ( ; list ; list = list->next ) { gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, static_cast<char*>(list->data), -1); + gtk_list_store_set (store, &iter, 0, (char*)list->data, -1); + + if( best.compare( (char*)list->data ) == 0 ) { + path_index = index; + } + ++index; } + // Attach store to tree view. Can trigger style changed signal (but not FONT_SET): gtk_tree_view_set_model (GTK_TREE_VIEW (fsel->style_treeview), GTK_TREE_MODEL (store)); - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, 0); + + // Get path to best style + GtkTreePath *path = gtk_tree_path_new (); + gtk_tree_path_append_index (path, path_index); + + // Highlight best style. Triggers style changed signal: gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path); gtk_tree_path_free (path); } +// Callback when row changed static void sp_font_selector_style_select_row (GtkTreeSelection *selection, SPFontSelector *fsel) { - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; - - path = gtk_tree_model_get_path (model, &iter); - fsel->styleidx = gtk_tree_path_get_indices (path)[0]; - if (!fsel->block_emit) { sp_font_selector_emit_set (fsel); @@ -329,6 +344,7 @@ static void sp_font_selector_style_select_row (GtkTreeSelection *selection, /* * Set the default list of font sizes, scaled to the users preferred unit + * TODO: This routine occurs both here and in text-toolbar. Move to font-lister? */ static void sp_font_selector_set_sizes( SPFontSelector *fsel ) { @@ -355,6 +371,7 @@ static void sp_font_selector_set_sizes( SPFontSelector *fsel ) } +// Callback when size changed static void sp_font_selector_size_changed( GtkComboBox */*cbox*/, SPFontSelector *fsel ) { char *text = NULL; @@ -388,9 +405,13 @@ static void sp_font_selector_size_changed( GtkComboBox */*cbox*/, SPFontSelector sp_font_selector_emit_set (fsel); } + +// Called from sp_font_selector_style_select_row +// Called from sp_font_selector_size_changed +// Called indirectly for sp_font_selector_family_select_row (since style changes). +// Emits FONT_SET signal (handled by TextEdit::onFontChange, GlyphsPanel::fontChangeCB). static void sp_font_selector_emit_set (SPFontSelector *fsel) { - font_instance *font; GtkTreeSelection *selection_family; GtkTreeSelection *selection_style; @@ -405,41 +426,27 @@ static void sp_font_selector_emit_set (SPFontSelector *fsel) model_family = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->family_treeview)); if (!model_family) return; - model_style = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->style_treeview)); - if (!model_style) return; + model_style = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->style_treeview)); + if (!model_style ) return; selection_family = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->family_treeview)); - selection_style = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)); + selection_style = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview )); if (!gtk_tree_selection_get_selected (selection_family, NULL, &iter_family)) return; - if (!gtk_tree_selection_get_selected (selection_style, NULL, &iter_style)) return; + if (!gtk_tree_selection_get_selected (selection_style, NULL, &iter_style )) return; gtk_tree_model_get (model_family, &iter_family, 0, &family, -1); - gtk_tree_model_get (model_style, &iter_style, 0, &style, -1); + gtk_tree_model_get (model_style, &iter_style, 0, &style, -1); if ((!family) || (!style)) return; - font = (font_factory::Default())->FaceFromUIStrings (family, style); + Glib::ustring fontspec = family; + fontspec += ", "; + fontspec += style; - // FIXME: when a text object uses non-available font, font==NULL and we can't set size - // (and the size shown in the widget is invalid). To fix, here we must always get some - // default font, exactly the same as sptext uses for on-canvas display, so that - // font!=NULL ever. - if (font != fsel->font || ( font && fsel->fontsize_dirty ) ) { - if ( font ) { - font->Ref(); - } - if ( fsel->font ) { - fsel->font->Unref(); - } - fsel->font = font; - g_signal_emit(fsel, fs_signals[FONT_SET], 0, fsel->font); - } - fsel->fontsize_dirty = false; - if (font) { - font->Unref(); - } - font = NULL; + *(fsel->fontspec) = fontspec; + + g_signal_emit(fsel, fs_signals[FONT_SET], 0, fontspec.c_str()); } GtkWidget *sp_font_selector_new() @@ -449,116 +456,53 @@ GtkWidget *sp_font_selector_new() return GTK_WIDGET(fsel); } + /* - * Returns the index of the fonts closest style match from the provided list of styles - * Used in both the Text dialog and the Text toolbar to set the style combo on selection change + * Sets the values displayed in the font-selector from a fontspec. + * It is only called from TextEdit with a new selection and from GlyphsPanel */ -unsigned int sp_font_selector_get_best_style (font_instance *font, GList *list) +void sp_font_selector_set_fontspec (SPFontSelector *fsel, Glib::ustring fontspec, double size) { - if ( !font || !list) { - return 0; - } - - font_instance *tempFont = NULL; - unsigned int currentStyleNumber = 0; - unsigned int bestStyleNumber = 0; - - Glib::ustring family = font_factory::Default()->GetUIFamilyString(font->descr); - - PangoFontDescription *incomingFont = pango_font_description_copy(font->descr); - pango_font_description_unset_fields(incomingFont, PANGO_FONT_MASK_SIZE); - - char *incomingFontString = pango_font_description_to_string(incomingFont); - - tempFont = (font_factory::Default())->FaceFromUIStrings(family.c_str(), static_cast<char*>(list->data)); - - PangoFontDescription *bestMatchForFont = NULL; - if (tempFont) { - bestMatchForFont = pango_font_description_copy(tempFont->descr); - tempFont->Unref(); - tempFont = NULL; - } - - if( bestMatchForFont != NULL ) { - pango_font_description_unset_fields(bestMatchForFont, PANGO_FONT_MASK_SIZE); - } - - list = list->next; - - while (list) { - currentStyleNumber++; - - tempFont = font_factory::Default()->FaceFromUIStrings(family.c_str(), static_cast<char*>(list->data)); - - PangoFontDescription *currentMatchForFont = NULL; - if (tempFont) { - currentMatchForFont = pango_font_description_copy(tempFont->descr); - tempFont->Unref(); - tempFont = NULL; - } - - if (currentMatchForFont) { - pango_font_description_unset_fields(currentMatchForFont, PANGO_FONT_MASK_SIZE); - - char *currentMatchString = pango_font_description_to_string(currentMatchForFont); - - if (!strcmp(incomingFontString, currentMatchString) - || pango_font_description_better_match(incomingFont, bestMatchForFont, currentMatchForFont)) { - // Found a better match for the font we are looking for - pango_font_description_free(bestMatchForFont); - bestMatchForFont = pango_font_description_copy(currentMatchForFont); - bestStyleNumber = currentStyleNumber; - } - - g_free(currentMatchString); - - pango_font_description_free(currentMatchForFont); - } - - list = list->next; - } - - if (bestMatchForFont) - pango_font_description_free(bestMatchForFont); - if (incomingFont) - pango_font_description_free(incomingFont); - g_free(incomingFontString); + if (!fontspec.empty()) + { - return bestStyleNumber; -} + Inkscape::FontLister *font_lister = Inkscape::FontLister::get_instance(); + std::pair<Glib::ustring, Glib::ustring> ui = font_lister->ui_from_fontspec( fontspec ); + Glib::ustring family = ui.first; + Glib::ustring style = ui.second; -void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, double size) -{ - if (font) - { Gtk::TreePath path; - - Glib::ustring family = font_factory::Default()->GetUIFamilyString(font->descr); - try { - path = Inkscape::FontLister::get_instance()->get_row_for_font (family); + path = font_lister->get_row_for_font (family); } catch (...) { + g_warning( "Couldn't find row for font-family: %s", family.c_str() ); return; } + // High light selected family and scroll so it is in view. fsel->block_emit = TRUE; gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->family_treeview)), path.gobj()); gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->family_treeview), path.gobj(), NULL, TRUE, 0.5, 0.5); - fsel->block_emit = FALSE; + fsel->block_emit = FALSE; // TODO: Should this be moved to the end? - GList *list = 0; - GtkTreeIter iter; - GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW(fsel->family_treeview)); - gtk_tree_model_get_iter (model, &iter, path.gobj()); - gtk_tree_model_get (model, &iter, 1, &list, -1); - unsigned int bestStyleNumber = sp_font_selector_get_best_style(font, list); + // We don't need to get best style since this is only called on a new + // selection where we already know the "best" style. + // Glib::ustring bestStyle = font_lister->get_best_style_match (family, style); + // std::cout << "Best: " << bestStyle << std::endl; + + // The "trial" style list and the regular list are the same in this case. + Gtk::TreePath path_c; + try { + path_c = font_lister->get_row_for_style( style ); + } catch (...) { + g_warning( "Couldn't find row for style: %s (%s)", style.c_str(), family.c_str() ); + return; + } + + gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path_c.gobj()); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->style_treeview), path_c.gobj(), NULL, TRUE, 0.5, 0.5); - GtkTreePath *path_c = gtk_tree_path_new (); - gtk_tree_path_append_index (path_c, bestStyleNumber); - gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path_c); - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->style_treeview), path_c, NULL, TRUE, 0.5, 0.5); - if (size != fsel->fontsize) { gchar s[8]; @@ -572,13 +516,9 @@ void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, doubl } -font_instance* sp_font_selector_get_font(SPFontSelector *fsel) +Glib::ustring sp_font_selector_get_fontspec(SPFontSelector *fsel) { - if (fsel->font) { - fsel->font->Ref(); - } - - return fsel->font; + return *(fsel->fontspec); } /* diff --git a/src/widgets/font-selector.h b/src/widgets/font-selector.h index 80e8b1e4d..66715f048 100644 --- a/src/widgets/font-selector.h +++ b/src/widgets/font-selector.h @@ -7,9 +7,11 @@ * Authors: * Chris Lahey <clahey@ximian.com> * Lauris Kaplinski <lauris@kaplinski.com> + * Tavmjong Bah <tavmjong@free.fr> * * Copyright (C) 1999-2001 Ximian, Inc. * Copyright (C) 2002 Lauris Kaplinski + * Copyright (C) 1999-2013 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -22,7 +24,24 @@ struct SPFontSelector; #define SP_FONT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_FONT_SELECTOR, SPFontSelector)) #define SP_IS_FONT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_FONT_SELECTOR)) -class font_instance; +/* + * The routines here create and manage a font selector widget with three parts, + * one each for font-family, font-style, and font-size. + * + * It is used by the TextEdit and Glyphs panel dialogs. The FontLister class is used + * to access the list of font-families and their associated styles for fonts either + * on the system or in the document. The FontLister class is also used by the Text + * toolbar. Fonts are kept track of by their "fontspecs" which are the same as the + * strings that Pango generates. + * + * The main functions are: + * Create the font-seletor widget. + * Update the lists when a new text selection is made. + * Update the Style list when a new font-family is selected, highlighting the + * best match to the original font style (as not all fonts have the same style options). + * Emit a signal when any change is made so that the Text Preview can be updated. + * Provide the currently selected values. + */ /* SPFontSelector */ @@ -30,13 +49,11 @@ GType sp_font_selector_get_type (void); GtkWidget *sp_font_selector_new (void); -void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, double size); +void sp_font_selector_set_fontspec (SPFontSelector *fsel, Glib::ustring fontspec, double size); +Glib::ustring sp_font_selector_get_fontspec (SPFontSelector *fsel); -font_instance *sp_font_selector_get_font (SPFontSelector *fsel); double sp_font_selector_get_size (SPFontSelector *fsel); -unsigned int sp_font_selector_get_best_style (font_instance *font, GList *list); - #endif // SP_FONT_SELECTOR_H /* diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index 8470e93db..7580d9602 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -24,6 +24,7 @@ #include <gtkmm/image.h> #include <gdkmm/pixbuf.h> #include <glibmm/fileutils.h> +#include <glibmm/miscutils.h> #include <2geom/transforms.h> #include "path-prefix.h" diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index a01f950a6..ef7d31d76 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -18,8 +18,8 @@ * * Copyright (C) 2004 David Turner * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2013 authors * Copyright (C) 2001-2002 Ximian, Inc. + * Copyright (C) 1999-2013 authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -133,115 +133,7 @@ static void sp_print_fontstyle( SPStyle *query ) { } #endif -/* - * Fill the font style combobox with the available font styles for the selected font family - * Set the selected style to that in font - */ -static void sp_text_fontstyle_populate(GObject *tbl, font_instance *font=NULL) -{ - - Ink_ComboBoxEntry_Action* act = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); - GtkTreeModel *model = ink_comboboxentry_action_get_model( act ); - gchar *current_font = ink_comboboxentry_action_get_active_text( act ); - if (!current_font) { - return; - } - - // If font list, take only first font in list - gchar** tokens = g_strsplit( current_font, ",", 0 ); - g_strstrip( tokens[0] ); - current_font = tokens[0]; - - // Get an iter to the selected font from the model data - // We cant get it from the combo, cause it might not have been created yet - gboolean found = false; - GtkTreeIter iter; - gboolean valid = gtk_tree_model_get_iter_first( model, &iter ); - while ( valid ) { - - // Get text from list entry - gchar* text = NULL; - gtk_tree_model_get( model, &iter, 0, &text, -1 ); // Column 0 - - // Check for match - if ( text && (strcmp( current_font, text ) == 0) ) { - found = true; - break; - } - valid = gtk_tree_model_iter_next( model, &iter ); - } - - g_strfreev( tokens ); - - Ink_ComboBoxEntry_Action* fontStyleAction = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); - - gchar *current_style = ink_comboboxentry_action_get_active_text( fontStyleAction ); - - GtkListStore *store = GTK_LIST_STORE( ink_comboboxentry_action_get_model( fontStyleAction ) ); - gtk_list_store_clear ( store ); - - // Get the list of styles from the selected font. - GList *list = NULL; - - if (found) { - - // Use precompiled list if font-family on system. - gtk_tree_model_get (model, &iter, 1, &list, -1); - - } else { - - // Use generic list if font-family not on system. - static GList *glist = NULL; - if( glist == NULL ) { - glist = g_list_append (glist, (void*)"Normal"); - glist = g_list_append (glist, (void*)"Italic"); - glist = g_list_append (glist, (void*)"Bold"); - glist = g_list_append (glist, (void*)"Bold Italic"); - } - list = glist; - } - - for (GList *l=list; l; l = l->next) - { - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, (char*)l->data, -1); - } - - // Select the style in the combo that best matches font - if (font && list) { - - unsigned int index = sp_font_selector_get_best_style(font, list); - - Ink_ComboBoxEntry_Action* fontStyleAction = - INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); - model = ink_comboboxentry_action_get_model( fontStyleAction ); - GtkTreePath *path_c = gtk_tree_path_new (); - gtk_tree_path_append_index (path_c, index); - gtk_tree_model_get_iter(model, &iter, path_c); - gchar *name; - gtk_tree_model_get (model, &iter, 0, &name, -1); - ink_comboboxentry_action_set_active_text( fontStyleAction, name ); - - } else if (current_style) { - ink_comboboxentry_action_set_active_text( fontStyleAction, current_style ); - } -} - // Font family -// -// In most cases we should just be able to set the new family name -// but there may be cases where a font family doesn't follow the -// standard naming pattern. To handle those cases, we do a song and -// dance to use Pango to find the best match. To do that we start -// with the old "fontSpec" (which is the returned string from -// pango_font_description_to_string() with the size unset). This -// has the form "[family-list] [style-options]" where the -// family-list is a comma separated list of font-family names -// (optionally terminated by a comma). An example would be -// "DejaVu Sans, Sans Bold". Only a "fontSpec" containing a -// single font-family will work with Pango's best match routine. -// If we can't obtain a good "fontSpec", we then resort to blindly -// changing the font-family. static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) { #ifdef DEBUG_TEXT @@ -252,156 +144,45 @@ static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GOb // quit if run by the _changed callbacks if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gchar *family = ink_comboboxentry_action_get_active_text( act ); #ifdef DEBUG_TEXT - std::cout << " New family: " << family << std::endl; -#endif - - // First try to get the old font spec from the stored value - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); - - Glib::ustring fontSpec = query->text->font_specification.set ? query->text->font_specification.value : ""; -#ifdef DEBUG_TEXT - std::cout << " fontSpec from query :" << fontSpec << ":" << std::endl; -#endif - - // If that didn't work, try to get font spec from style - if (fontSpec.empty()) { - - // Must query all to fill font-family, font-style, font-weight, font-specification - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - - // Construct a new font specification if it does not yet exist - font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query); - if( fontFromStyle ) { - fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle); - fontFromStyle->Unref(); - } - -#ifdef DEBUG_TEXT - std::cout << " fontSpec empty, try from style" << std::endl; - std::cout << " from style :" << fontSpec << ":" << std::endl; - sp_print_font( query ); -#endif - - } - - // And if that didn't work use default. DO WE REALLY WANT TO DO THIS? - if ( fontSpec.empty() ) { - - sp_style_read_from_prefs(query, "/tools/text"); - - // Construct a new font specification if it does not yet exist - font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query); - if ( fontFromStyle ) { - fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle); - fontFromStyle->Unref(); - } - -#ifdef DEBUG_TEXT - std::cout << " fontSpec empty, trying from prefs" << std::endl; - std::cout << " from prefs :" << fontSpec << ":" << std::endl; - sp_print_font( query ); + std::cout << "sp_text_fontfamily_value_changed: frozen... return" << std::endl; + std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n" << std::endl; #endif + return; } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - // Now we have a font specification, replace family. - Glib::ustring newFontSpec = ""; - SPCSSAttr *css = sp_repr_css_attr_new (); - - if (!fontSpec.empty()) newFontSpec = font_factory::Default()->ReplaceFontSpecificationFamily(fontSpec, family); - -#ifdef DEBUG_TEXT - std::cout << " New FontSpec from ReplaceFontSpecificationFamily :" << newFontSpec << ":" << std::endl; -#endif - - if (!fontSpec.empty() && !newFontSpec.empty() ) { - - if (fontSpec != newFontSpec) { - - font_instance *font = font_factory::Default()->FaceFromFontSpecification(newFontSpec.c_str()); - - if (font) { - sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str()); - - // Set all the these just in case they were altered when finding the best - // match for the new family and old style... Unnecessary? - - gchar c[256]; - - font->Family(c, 256); - - sp_repr_css_set_property (css, "font-family", c); - - font->Attribute( "weight", c, 256); - sp_repr_css_set_property (css, "font-weight", c); - - font->Attribute("style", c, 256); - sp_repr_css_set_property (css, "font-style", c); - - font->Attribute("stretch", c, 256); - sp_repr_css_set_property (css, "font-stretch", c); - - font->Attribute("variant", c, 256); - sp_repr_css_set_property (css, "font-variant", c); - - font->Unref(); - - // Set the list of font styles - sp_text_fontstyle_populate(tbl); - - } else { - g_warning(_("Failed to find font matching: %s\n"), newFontSpec.c_str()); - } - } - } else { - - // Either old font does not exist on system or ReplaceFontSpecificationFamily() failed. - // Blindly fall back to setting the family to text in the font-family chooser. + Glib::ustring new_family = ink_comboboxentry_action_get_active_text( act ); + // TODO: Think about how to handle handle multiple selections. While + // the font-family may be the same for all, the styles might be different. + // See: TextEdit::onApply() for example of looping over selected items. + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); #ifdef DEBUG_TEXT - std::cout << " Failed to find new font, blindly setting family: " << family << std::endl; + std::cout << " Old family: " << fontlister->get_font_family() << std::endl; + std::cout << " New family: " << new_family << std::endl; + std::cout << " Old active: " << fontlister->get_font_family_row() << std::endl; + std::cout << " New active: " << act->active << std::endl; #endif - sp_repr_css_set_property (css, "-inkscape-font-specification", family); - sp_repr_css_set_property (css, "font-family", family); - } + if( new_family.compare( fontlister->get_font_family() ) != 0 ) { - // If querying returned nothing, update default style. - if (result_fontspec == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - //sp_text_edit_dialog_default_set_insensitive (); //FIXME: Replace through a verb - } - else - { - sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); - } + std::pair<Glib::ustring,Glib::ustring> ui = fontlister->set_font_family( act->active ); + // active text set in sp_text_toolbox_selection_changed() - sp_style_unref(query); + SPCSSAttr *css = sp_repr_css_attr_new (); + fontlister->fill_css( css ); - g_free (family); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css, true, true); // Results in selection change called twice. + sp_repr_css_attr_unref (css); - // Save for undo - if (result_fontspec != QUERY_STYLE_NOTHING) { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Text: Change font family")); } - sp_repr_css_attr_unref (css); // unfreeze g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - // focus to canvas (not useful if you want to choose font for your text) - //gtk_widget_grab_focus (GTK_WIDGET((SP_ACTIVE_DESKTOP)->canvas)); - #ifdef DEBUG_TEXT std::cout << "sp_text_toolbox_fontfamily_changes: exit" << std::endl; std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" << std::endl; @@ -473,7 +254,6 @@ static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObje /* * Font style */ -//static void sp_text_fontstyle_value_changed( EgeSelectOneAction *act, GObject *tbl ) static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) { // quit if run by the _changed callbacks @@ -482,95 +262,26 @@ static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObj } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - // First query font-specification, this is the most complete font face description. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); + Glib::ustring new_style = ink_comboboxentry_action_get_active_text( act ); - // font_specification will not be set unless defined explicitily on a tspan. - // This should be fixed! - Glib::ustring fontSpec = query->text->font_specification.set ? query->text->font_specification.value : ""; + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - if (fontSpec.empty()) { - // Construct a new font specification if it does not yet exist - // Must query font-family, font-style, font-weight, to find correct font face. - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + if( new_style.compare( fontlister->get_font_style() ) != 0 ) { - font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query); - if ( fontFromStyle ) { - fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle); - fontFromStyle->Unref(); - } - } - - SPCSSAttr *css = sp_repr_css_attr_new (); + fontlister->set_font_style( new_style ); + // active text set in sp_text_toolbox_seletion_changed() - Glib::ustring current_style = ink_comboboxentry_action_get_active_text( act ); - Glib::ustring fontFamily = ""; - - if (query->text->font_family.set) { - fontFamily = query->text->font_family.value; - } else { - // if the font_family is not set, get it from the font family combo instead - Ink_ComboBoxEntry_Action* act = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); - fontFamily = ink_comboboxentry_action_get_active_text( act ); - } - - font_instance *font = (font_factory::Default())->FaceFromUIStrings (fontFamily.c_str(), current_style.c_str()); - - if (font) { - - gchar c[256]; - - font->Attribute( "weight", c, 256); - sp_repr_css_set_property (css, "font-weight", c); - - font->Attribute("style", c, 256); - sp_repr_css_set_property (css, "font-style", c); - - font->Attribute("stretch", c, 256); - sp_repr_css_set_property (css, "font-stretch", c); - - font->Attribute("variant", c, 256); - sp_repr_css_set_property (css, "font-variant", c); - - font->Unref(); - font = NULL; - - } else { - - // Font not found on system, blindly update style - // Options match choices in sp_text_fontstyle_populate - sp_repr_css_set_property (css, "font-weight", "normal"); - sp_repr_css_set_property (css, "font-style", "normal" ); - if( current_style.find("Bold") != Glib::ustring::npos ) { - sp_repr_css_set_property (css, "font-weight", "bold"); - } - if( current_style.find("Italic") != Glib::ustring::npos ) { - sp_repr_css_set_property (css, "font-style", "italic"); - } - } - - // If querying returned nothing, update default style. - if (result_fontspec == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } + SPCSSAttr *css = sp_repr_css_attr_new (); + fontlister->fill_css( css ); - sp_style_unref(query); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css, true, true); + sp_repr_css_attr_unref (css); - // Do we need to update other CSS values? - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, true); - if (result_fontspec != QUERY_STYLE_NOTHING) { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, - _("Text: Change font style")); + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + _("Text: Change font style")); } - sp_repr_css_attr_unref (css); - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } @@ -1145,6 +856,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ if (g_object_get_data(G_OBJECT(tbl), "freeze")) { #ifdef DEBUG_TEXT std::cout << " Frozen, returning" << std::endl; + std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; std::cout << std::endl; #endif @@ -1152,15 +864,21 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - // Update font list, but only if widget already created. Ink_ComboBoxEntry_Action* fontFamilyAction = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); + Ink_ComboBoxEntry_Action* fontStyleAction = + INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); + + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); + fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + fontlister->selection_update(); + + // Update font list, but only if widget already created. if( fontFamilyAction->combobox != NULL ) { - Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + ink_comboboxentry_action_set_active_text( fontFamilyAction, fontlister->get_font_family().c_str(), fontlister->get_font_family_row() ); + ink_comboboxentry_action_set_active_text( fontStyleAction, fontlister->get_font_style().c_str() ); } - // Only flowed text can be justified, only normal text can be kerned... // Find out if we have flowed text now so we can use it several places gboolean isFlow = false; @@ -1207,6 +925,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); #ifdef DEBUG_TEXT std::cout << " text_style_from_prefs: toolbar already set" << std:: endl; + std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; std::cout << std::endl; #endif @@ -1225,15 +944,6 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // If we have valid query data for text (font-family, font-specification) set toolbar accordingly. if (query->text) { - // Font family - if( query->text->font_family.value ) { - gchar *fontFamily = query->text->font_family.value; - - Ink_ComboBoxEntry_Action* fontFamilyAction = - INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); - ink_comboboxentry_action_set_active_text( fontFamilyAction, fontFamily ); - } - // Size (average of text selected) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); @@ -1247,16 +957,17 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ Ink_ComboBoxEntry_Action* fontSizeAction = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontSizeAction" ) ); + + // Freeze to ignore callbacks. + //g_object_freeze_notify( G_OBJECT( fontSizeAction->combobox ) ); sp_text_set_sizes(GTK_LIST_STORE(ink_comboboxentry_action_get_model(fontSizeAction)), unit); + //g_object_thaw_notify( G_OBJECT( fontSizeAction->combobox ) ); + ink_comboboxentry_action_set_active_text( fontSizeAction, os.str().c_str() ); Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", sp_style_get_css_unit_string(unit), ")"); ink_comboboxentry_action_set_tooltip ( fontSizeAction, tooltip.c_str()); - // Font styles - font_instance *font = font_factory::Default()->FaceFromStyle(query); - sp_text_fontstyle_populate(tbl, font); - // Superscript gboolean superscriptSet = ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && @@ -1438,6 +1149,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ } #ifdef DEBUG_TEXT + std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; std::cout << std::endl; #endif @@ -1457,41 +1169,47 @@ sp_text_toolbox_subselection_changed (gpointer /*tc*/, GObject *tbl) sp_text_toolbox_selection_changed (NULL, tbl); } +// TODO: possibly share with font-selector by moving most code to font-lister (passing family name) +static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*position*/, GdkEvent /*event*/, gpointer /*data*/ ) { -/* Recursively extract all "font-family" attributes from a document. */ -void -sp_text_toolbox_get_font_list_in_doc_recursive (SPObject *r, std::list<Glib::ustring> *l) -{ - if (!r) { - return; - } + Glib::ustring family = gtk_entry_get_text ( entry ); + //std::cout << "text_toolbox_missing_font_cb: selecting: " << family << std::endl; - const gchar *style = r->getRepr()->attribute("style"); - if( style != NULL ) { - //std::cout << style << std::endl; - std::vector<Glib::ustring> tokens = Glib::Regex::split_simple(";", style ); - for( size_t i=0; i < tokens.size(); ++i ) { - Glib::ustring token = tokens[i]; - size_t found = token.find("font-family:"); - if( found != Glib::ustring::npos ) { - // Remove "font-family:" - token.erase(found,12); - // Remove any leading single or double quote - if( token[0] == '\'' || token[0] == '"' ) { - token.erase(0,1); - } - // Remove any trailing single or double quote - if( token[token.length()-1] == '\'' || token[token.length()-1] == '"' ) { - token.erase(token.length()-1); - } - l->push_back( token ); - } - } - } + // Get all items with matching font-family set (not inherited!). + GSList *selectList = NULL; + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *document = sp_desktop_document( desktop ); + GSList *allList = get_all_items(NULL, document->getRoot(), desktop, false, false, true, NULL); + for (GSList *i = allList; i != NULL; i = i->next) { + + SPItem *item = SP_ITEM(i->data); + SPStyle *style = item->style; + + if (style && style->text) { + + Glib::ustring family_style; + if (style->text->font_family.set) { + family_style = style->text->font_family.value; + //std::cout << " family style from font_family: " << family_style << std::endl; + } + else if (style->text->font_specification.set) { + family_style = style->text->font_specification.value; + //std::cout << " family style from font_spec: " << family_style << std::endl; + } - for (SPObject *child = r->firstChild(); child; child = child->getNext()) { - sp_text_toolbox_get_font_list_in_doc_recursive( child, l ); + if (family_style.compare( family ) == 0 ) { + //std::cout << " found: " << item->getId() << std::endl; + selectList = g_slist_prepend (selectList, item); + } } + } + + // Update selection + Inkscape::Selection *selection = sp_desktop_selection (desktop ); + selection->clear(); + //std::cout << " list length: " << g_slist_length ( selectList ) << std::endl; + selection->setList(selectList); } @@ -1526,8 +1244,16 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje (gpointer)font_lister_separator_func, GTK_WIDGET(desktop->canvas)); // Focus widget ink_comboboxentry_action_popup_enable( act ); // Enable entry completion + + gchar *const info = _("Select all text with this font-family"); + ink_comboboxentry_action_set_info( act, info ); // Show selection icon + ink_comboboxentry_action_set_info_cb( act, (gpointer)sp_text_toolbox_select_cb ); + gchar *const warning = _("Font not found on system"); - ink_comboboxentry_action_set_warning( act, warning ); // Show icon with tooltip if missing font + ink_comboboxentry_action_set_warning( act, warning ); // Show icon w/ tooltip if font missing + ink_comboboxentry_action_set_warning_cb( act, (gpointer)sp_text_toolbox_select_cb ); + + //ink_comboboxentry_action_set_warning_callback( act, sp_text_fontfamily_select_all ); ink_comboboxentry_action_set_altx_name( act, "altx-text" ); // Set Alt-X keyboard shortcut g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontfamily_value_changed), holder ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); @@ -1577,18 +1303,20 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje /* Font styles */ { - GtkListStore* model_style = gtk_list_store_new( 1, G_TYPE_STRING ); + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); + Glib::RefPtr<Gtk::ListStore> store = fontlister->get_style_list(); + GtkListStore* model_style = store->gobj(); - Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontStyleAction", + Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontStyleAction", _("Font Style"), _("Font style"), NULL, GTK_TREE_MODEL(model_style), 12, // Width in characters - 0, // Extra list width - NULL, // Cell layout - NULL, // Separator - GTK_WIDGET(desktop->canvas)); // Focus widget + 0, // Extra list width + NULL, // Cell layout + NULL, // Separator + GTK_WIDGET(desktop->canvas)); // Focus widget g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontstyle_value_changed), holder ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); |
