Code

Add character script range to description
[inkscape.git] / src / ui / dialog / glyphs.cpp
1 /**
2  * Glyph selector dialog.
3  */
5 /* Authors:
6  *   Jon A. Cruz
7  *
8  * Copyright (C) 2010 Jon A. Cruz
9  * Released under GNU GPL, read the file 'COPYING' for more information
10  */
12 #include <vector>
14 #include <glibmm/i18n.h>
15 #include <gtkmm/entry.h>
16 #include <gtkmm/iconview.h>
17 #include <gtkmm/label.h>
18 #include <gtkmm/liststore.h>
19 #include <gtkmm/scrolledwindow.h>
20 #include <gtkmm/table.h>
21 #include <gtkmm/treemodelcolumn.h>
22 #include <gtkmm/widget.h>
24 #include <gtk/gtkbutton.h>
25 #include <gtk/gtkstock.h>
27 #include "glyphs.h"
29 #include "verbs.h"
30 #include "widgets/font-selector.h"
31 #include "libnrtype/font-instance.h"
33 namespace Inkscape {
34 namespace UI {
35 namespace Dialogs {
38 GlyphsPanel &GlyphsPanel::getInstance()
39 {
40     return *new GlyphsPanel();
41 }
44 //enum GUnicodeScript
45 #if GLIB_CHECK_VERSION(2,14,0)
46 static std::map<GUnicodeScript, Glib::ustring> &getScriptToName()
47 {
48     static bool init = false;
49     static std::map<GUnicodeScript, Glib::ustring> mappings;
50     if (!init) {
51         init = true;
52         mappings[G_UNICODE_SCRIPT_INVALID_CODE]         = _("all");
53         mappings[G_UNICODE_SCRIPT_COMMON]               = _("common");
54         mappings[G_UNICODE_SCRIPT_INHERITED]            = _("inherited");
55         mappings[G_UNICODE_SCRIPT_ARABIC]               = _("Arabic");
56         mappings[G_UNICODE_SCRIPT_ARMENIAN]             = _("Armenian");
57         mappings[G_UNICODE_SCRIPT_BENGALI]              = _("Bengali");
58         mappings[G_UNICODE_SCRIPT_BOPOMOFO]             = _("Bopomofo");
59         mappings[G_UNICODE_SCRIPT_CHEROKEE]             = _("Cherokee");
60         mappings[G_UNICODE_SCRIPT_COPTIC]               = _("Coptic");
61         mappings[G_UNICODE_SCRIPT_CYRILLIC]             = _("Cyrillic");
62         mappings[G_UNICODE_SCRIPT_DESERET]              = _("Deseret");
63         mappings[G_UNICODE_SCRIPT_DEVANAGARI]           = _("Devanagari");
64         mappings[G_UNICODE_SCRIPT_ETHIOPIC]             = _("Ethiopic");
65         mappings[G_UNICODE_SCRIPT_GEORGIAN]             = _("Georgian");
66         mappings[G_UNICODE_SCRIPT_GOTHIC]               = _("Gothic");
67         mappings[G_UNICODE_SCRIPT_GREEK]                = _("Greek");
68         mappings[G_UNICODE_SCRIPT_GUJARATI]             = _("Gujarati");
69         mappings[G_UNICODE_SCRIPT_GURMUKHI]             = _("Gurmukhi");
70         mappings[G_UNICODE_SCRIPT_HAN]                  = _("Han");
71         mappings[G_UNICODE_SCRIPT_HANGUL]               = _("Hangul");
72         mappings[G_UNICODE_SCRIPT_HEBREW]               = _("Hebrew");
73         mappings[G_UNICODE_SCRIPT_HIRAGANA]             = _("Hiragana");
74         mappings[G_UNICODE_SCRIPT_KANNADA]              = _("Kannada");
75         mappings[G_UNICODE_SCRIPT_KATAKANA]             = _("Katakana");
76         mappings[G_UNICODE_SCRIPT_KHMER]                = _("Khmer");
77         mappings[G_UNICODE_SCRIPT_LAO]                  = _("Lao");
78         mappings[G_UNICODE_SCRIPT_LATIN]                = _("Latin");
79         mappings[G_UNICODE_SCRIPT_MALAYALAM]            = _("Malayalam");
80         mappings[G_UNICODE_SCRIPT_MONGOLIAN]            = _("Mongolian");
81         mappings[G_UNICODE_SCRIPT_MYANMAR]              = _("Myanmar");
82         mappings[G_UNICODE_SCRIPT_OGHAM]                = _("Ogham");
83         mappings[G_UNICODE_SCRIPT_OLD_ITALIC]           = _("Old Italic");
84         mappings[G_UNICODE_SCRIPT_ORIYA]                = _("Oriya");
85         mappings[G_UNICODE_SCRIPT_RUNIC]                = _("Runic");
86         mappings[G_UNICODE_SCRIPT_SINHALA]              = _("Sinhala");
87         mappings[G_UNICODE_SCRIPT_SYRIAC]               = _("Syriac");
88         mappings[G_UNICODE_SCRIPT_TAMIL]                = _("Tamil");
89         mappings[G_UNICODE_SCRIPT_TELUGU]               = _("Telugu");
90         mappings[G_UNICODE_SCRIPT_THAANA]               = _("Thaana");
91         mappings[G_UNICODE_SCRIPT_THAI]                 = _("Thai");
92         mappings[G_UNICODE_SCRIPT_TIBETAN]              = _("Tibetan");
93         mappings[G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL]  = _("Canadian Aboriginal");
94         mappings[G_UNICODE_SCRIPT_YI]                   = _("Yi");
95         mappings[G_UNICODE_SCRIPT_TAGALOG]              = _("Tagalog");
96         mappings[G_UNICODE_SCRIPT_HANUNOO]              = _("Hanunoo");
97         mappings[G_UNICODE_SCRIPT_BUHID]                = _("Buhid");
98         mappings[G_UNICODE_SCRIPT_TAGBANWA]             = _("Tagbanwa");
99         mappings[G_UNICODE_SCRIPT_BRAILLE]              = _("Braille");
100         mappings[G_UNICODE_SCRIPT_CYPRIOT]              = _("Cypriot");
101         mappings[G_UNICODE_SCRIPT_LIMBU]                = _("Limbu");
102         mappings[G_UNICODE_SCRIPT_OSMANYA]              = _("Osmanya");
103         mappings[G_UNICODE_SCRIPT_SHAVIAN]              = _("Shavian");
104         mappings[G_UNICODE_SCRIPT_LINEAR_B]             = _("Linear B");
105         mappings[G_UNICODE_SCRIPT_TAI_LE]               = _("Tai Le");
106         mappings[G_UNICODE_SCRIPT_UGARITIC]             = _("Ugaritic");
107         mappings[G_UNICODE_SCRIPT_NEW_TAI_LUE]          = _("New Tai Lue");
108         mappings[G_UNICODE_SCRIPT_BUGINESE]             = _("Buginese");
109         mappings[G_UNICODE_SCRIPT_GLAGOLITIC]           = _("Glagolitic");
110         mappings[G_UNICODE_SCRIPT_TIFINAGH]             = _("Tifinagh");
111         mappings[G_UNICODE_SCRIPT_SYLOTI_NAGRI]         = _("Syloti Nagri");
112         mappings[G_UNICODE_SCRIPT_OLD_PERSIAN]          = _("Old Persian");
113         mappings[G_UNICODE_SCRIPT_KHAROSHTHI]           = _("Kharoshthi");
114         mappings[G_UNICODE_SCRIPT_UNKNOWN]              = _("unassigned");
115         mappings[G_UNICODE_SCRIPT_BALINESE]             = _("Balinese");
116         mappings[G_UNICODE_SCRIPT_CUNEIFORM]            = _("Cuneiform");
117         mappings[G_UNICODE_SCRIPT_PHOENICIAN]           = _("Phoenician");
118         mappings[G_UNICODE_SCRIPT_PHAGS_PA]             = _("Phags-pa");
119         mappings[G_UNICODE_SCRIPT_NKO]                  = _("N'Ko");
121 #if GLIB_CHECK_VERSION(2,14,0)
122         mappings[G_UNICODE_SCRIPT_KAYAH_LI]             = _("Kayah Li");
123         mappings[G_UNICODE_SCRIPT_LEPCHA]               = _("Lepcha");
124         mappings[G_UNICODE_SCRIPT_REJANG]               = _("Rejang");
125         mappings[G_UNICODE_SCRIPT_SUNDANESE]            = _("Sundanese");
126         mappings[G_UNICODE_SCRIPT_SAURASHTRA]           = _("Saurashtra");
127         mappings[G_UNICODE_SCRIPT_CHAM]                 = _("Cham");
128         mappings[G_UNICODE_SCRIPT_OL_CHIKI]             = _("Ol Chiki");
129         mappings[G_UNICODE_SCRIPT_VAI]                  = _("Vai");
130         mappings[G_UNICODE_SCRIPT_CARIAN]               = _("Carian");
131         mappings[G_UNICODE_SCRIPT_LYCIAN]               = _("Lycian");
132         mappings[G_UNICODE_SCRIPT_LYDIAN]               = _("Lydian");
133 #endif // GLIB_CHECK_VERSION(2,14,0)
134     }
135     return mappings;
137 #endif // GLIB_CHECK_VERSION(2,14,0)
140 class GlyphColumns : public Gtk::TreeModel::ColumnRecord
142 public:
143     Gtk::TreeModelColumn<gunichar> code;
144     Gtk::TreeModelColumn<Glib::ustring> name;
146     GlyphColumns()
147     {
148         add(code);
149         add(name);
150     }
151 };
153 GlyphColumns *GlyphsPanel::getColumns()
155     static GlyphColumns *columns = new GlyphColumns();
157     return columns;
160 /**
161  * Constructor
162  */
163 GlyphsPanel::GlyphsPanel(gchar const *prefsPath) :
164     Inkscape::UI::Widget::Panel("", prefsPath, SP_VERB_DIALOG_GLYPHS, "", false),
165     store(Gtk::ListStore::create(*getColumns())),
166     iconView(0),
167     entry(0),
168     label(0)
170     Gtk::Table *table = new Gtk::Table(3, 1, false);
171     _getContents()->pack_start(*Gtk::manage(table), Gtk::PACK_EXPAND_WIDGET);
172     guint row = 0;
174 // -------------------------------
176     GtkWidget *fontsel = sp_font_selector_new();
177     g_signal_connect( G_OBJECT(fontsel), "font_set", G_CALLBACK(fontChangeCB), this );
179     table->attach(*Gtk::manage(Glib::wrap(fontsel)),
180                   0, 1, row, row + 1,
181                   Gtk::SHRINK|Gtk::FILL, Gtk::SHRINK|Gtk::FILL);
182     row++;
185 // -------------------------------
187     GlyphColumns *columns = getColumns();
189     iconView = new Gtk::IconView(store);
190     iconView->set_text_column(columns->name);
191     //iconView->set_columns(16);
193     iconView->signal_item_activated().connect(sigc::mem_fun(*this, &GlyphsPanel::glyphActivated));
194     iconView->signal_selection_changed().connect(sigc::mem_fun(*this, &GlyphsPanel::glyphSelectionChanged));
197     Gtk::ScrolledWindow *scroller = new Gtk::ScrolledWindow();
198     scroller->set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS);
199     scroller->add(*Gtk::manage(iconView));
200     table->attach(*Gtk::manage(scroller),
201                   0, 1, row, row + 1,
202                   Gtk::EXPAND|Gtk::FILL, Gtk::EXPAND|Gtk::FILL);
203     row++;
205 // -------------------------------
207     Gtk::HBox *box = new Gtk::HBox();
209     entry = new Gtk::Entry();
210     entry->set_width_chars(12);
211     box->pack_start(*Gtk::manage(entry), Gtk::PACK_SHRINK);
213     label = new Gtk::Label("      ");
214     box->pack_start(*Gtk::manage(label), Gtk::PACK_EXPAND_PADDING);
216     GtkWidget *applyBtn = gtk_button_new_from_stock(GTK_STOCK_APPLY);
217     GTK_WIDGET_SET_FLAGS(applyBtn, GTK_CAN_DEFAULT | GTK_HAS_DEFAULT);
218     gtk_widget_set_sensitive(applyBtn, FALSE);
220     box->pack_end(*Gtk::manage(Glib::wrap(applyBtn)), Gtk::PACK_SHRINK);
222     table->attach( *Gtk::manage(box),
223                   0, 1, row, row + 1,
224                    Gtk::EXPAND|Gtk::FILL, Gtk::SHRINK);
225     row++;
227 // -------------------------------
230     show_all_children();
232     restorePanelPrefs();
235 GlyphsPanel::~GlyphsPanel()
240 void GlyphsPanel::glyphActivated(Gtk::TreeModel::Path const & path)
242     Gtk::ListStore::iterator row = store->get_iter(path);
243     gunichar ch = (*row)[getColumns()->code];
244     Glib::ustring tmp;
245     tmp += ch;
247     int startPos = 0;
248     int endPos = 0;
249     if (entry->get_selection_bounds(startPos, endPos)) {
250         // there was something selected.
251         entry->delete_text(startPos, endPos);
252     }
253     startPos = entry->get_position();
254     entry->insert_text(tmp, -1, startPos);
255     entry->set_position(startPos);
258 void GlyphsPanel::glyphSelectionChanged()
260     Gtk::IconView::ArrayHandle_TreePaths itemArray = iconView->get_selected_items();
261     if (itemArray.empty()) {
262         label->set_text("      ");
263     } else {
264         Gtk::TreeModel::Path const & path = *itemArray.begin();
265         Gtk::ListStore::iterator row = store->get_iter(path);
266         gunichar ch = (*row)[getColumns()->code];
269         Glib::ustring scriptName;
270 #if GLIB_CHECK_VERSION(2,14,0)
271         GUnicodeScript script = g_unichar_get_script(ch);
272         std::map<GUnicodeScript, Glib::ustring> mappings = getScriptToName();
273         if (mappings.find(script) != mappings.end()) {
274             scriptName = mappings[script];
275         }
276 #endif
277         gchar * tmp = g_strdup_printf("U+%04X %s", ch, scriptName.c_str());
278         label->set_text(tmp);
279     }
282 void GlyphsPanel::fontChangeCB(SPFontSelector *fontsel, font_instance *font, GlyphsPanel *self)
284     if (self) {
285         self->handleFontChange(fontsel, font);
286     }
290 void GlyphsPanel::handleFontChange(SPFontSelector * /*fontsel*/, font_instance *font)
292     if (font) {
293         gunichar maxUni = 0;
294         std::vector<gunichar> present;
295         for (gunichar ch = 0; ch < 65536; ch++) {
296             int glyphId = font->MapUnicodeChar(ch);
297             if (glyphId > 0) {
298                 maxUni = std::max(maxUni, ch);
299                 present.push_back(ch);
300             }
301         }
303         GlyphColumns *columns = getColumns();
304         store->clear();
305         for (std::vector<gunichar>::iterator it = present.begin(); it != present.end(); ++it)
306         {
307             Gtk::ListStore::iterator row = store->append();
308             Glib::ustring tmp;
309             tmp += *it;
310             (*row)[columns->code] = *it;
311             (*row)[columns->name] = tmp;
312         }
313     }
317 } // namespace Dialogs
318 } // namespace UI
319 } // namespace Inkscape
321 /*
322   Local Variables:
323   mode:c++
324   c-file-style:"stroustrup"
325   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
326   indent-tabs-mode:nil
327   fill-column:99
328   End:
329 */
330 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :