1 /*
2  * Copyright © 2004 Noah Levitt
3  * Copyright © 2007 Christian Persch
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License as published by the
7  * Free Software Foundation; either version 3 of the License, or (at your
8  * option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
18  */
19 
20 #include <config.h>
21 
22 #include <glib/gi18n-lib.h>
23 #include <gtk/gtk.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "gucharmap.h"
28 #include "gucharmap-private.h"
29 
30 static gboolean
is_special_script(const char * script)31 is_special_script (const char *script)
32 {
33   return g_str_equal (script, "Common") ||
34     g_str_equal (script, "Inherited") ||
35     g_str_equal (script, "Unknown");
36 }
37 
38 static void
gucharmap_script_chapters_model_init(GucharmapScriptChaptersModel * model)39 gucharmap_script_chapters_model_init (GucharmapScriptChaptersModel *model)
40 {
41   GucharmapChaptersModel *chapters_model = GUCHARMAP_CHAPTERS_MODEL (model);
42   GtkListStore *store = GTK_LIST_STORE (model);
43   const gchar **unicode_scripts;
44   GtkTreeIter iter;
45   guint i;
46   GType types[] = {
47     G_TYPE_STRING,
48     G_TYPE_STRING,
49     PANGO_TYPE_ATTR_LIST,
50   };
51   PangoAttrList *attr_list;
52 
53   attr_list = pango_attr_list_new ();
54   pango_attr_list_insert (attr_list, pango_attr_style_new (PANGO_STYLE_ITALIC));
55 
56   gtk_list_store_set_column_types (store, G_N_ELEMENTS (types), types);
57 
58   unicode_scripts = gucharmap_unicode_list_scripts ();
59   for (i = 0;  unicode_scripts[i]; i++)
60     {
61       gtk_list_store_append (store, &iter);
62       gtk_list_store_set (store, &iter,
63                           GUCHARMAP_CHAPTERS_MODEL_COLUMN_ID, unicode_scripts[i],
64                           GUCHARMAP_CHAPTERS_MODEL_COLUMN_LABEL, _(unicode_scripts[i]),
65                           _GUCHARMAP_CHAPTERS_MODEL_COLUMN_LABEL_ATTRS,
66                                   is_special_script (unicode_scripts[i]) ? attr_list : NULL,
67                           -1);
68     }
69   g_free (unicode_scripts);
70   pango_attr_list_unref (attr_list);
71 
72   chapters_model->priv->sort_column = GUCHARMAP_CHAPTERS_MODEL_COLUMN_LABEL;
73 }
74 
75 static GucharmapCodepointList *
get_codepoint_list(GucharmapChaptersModel * chapters,GtkTreeIter * iter)76 get_codepoint_list (GucharmapChaptersModel *chapters,
77                     GtkTreeIter *iter)
78 {
79   GtkTreeModel *model = GTK_TREE_MODEL (chapters);
80   GucharmapCodepointList *list;
81   gchar *script_untranslated;
82 
83   gtk_tree_model_get (model, iter, GUCHARMAP_CHAPTERS_MODEL_COLUMN_ID, &script_untranslated, -1);
84 
85   list = gucharmap_script_codepoint_list_new ();
86   if (!gucharmap_script_codepoint_list_set_script (GUCHARMAP_SCRIPT_CODEPOINT_LIST (list), script_untranslated))
87     {
88       g_error ("gucharmap_script_codepoint_list_set_script (\"%s\") failed\n", script_untranslated);
89       /* not reached */
90       return NULL;
91     }
92 
93   g_free (script_untranslated);
94   return list;
95 }
96 
97 static gboolean
append_script(GtkTreeModel * model,GtkTreePath * path,GtkTreeIter * iter,GucharmapScriptCodepointList * list)98 append_script (GtkTreeModel                 *model,
99                GtkTreePath                  *path,
100                GtkTreeIter                  *iter,
101                GucharmapScriptCodepointList *list)
102 {
103   gchar *script_untranslated;
104 
105   gtk_tree_model_get (model, iter, GUCHARMAP_CHAPTERS_MODEL_COLUMN_ID, &script_untranslated, -1);
106 
107   gucharmap_script_codepoint_list_append_script (list, script_untranslated);
108 
109   return FALSE;
110 }
111 
112 static GucharmapCodepointList *
get_book_codepoint_list(GucharmapChaptersModel * chapters)113 get_book_codepoint_list (GucharmapChaptersModel *chapters)
114 {
115   GucharmapChaptersModelPrivate *priv = chapters->priv;
116 
117   if (priv->book_list == NULL)
118     {
119       GtkTreeModel *model = GTK_TREE_MODEL (chapters);
120 
121       priv->book_list = gucharmap_script_codepoint_list_new ();
122       gtk_tree_model_foreach (model, (GtkTreeModelForeachFunc) append_script, priv->book_list);
123     }
124 
125   return g_object_ref (priv->book_list);
126 }
127 
128 static gboolean
character_to_iter(GucharmapChaptersModel * chapters_model,gunichar wc,GtkTreeIter * iter)129 character_to_iter (GucharmapChaptersModel *chapters_model,
130                    gunichar           wc,
131                    GtkTreeIter       *iter)
132 {
133   const char *script;
134 
135   script = gucharmap_unicode_get_script_for_char (wc);
136   if (script == NULL)
137     return FALSE;
138 
139   return gucharmap_chapters_model_id_to_iter (chapters_model, script, iter);
140 }
141 
142 static void
gucharmap_script_chapters_model_class_init(GucharmapScriptChaptersModelClass * clazz)143 gucharmap_script_chapters_model_class_init (GucharmapScriptChaptersModelClass *clazz)
144 {
145   GucharmapChaptersModelClass *chapters_class = GUCHARMAP_CHAPTERS_MODEL_CLASS (clazz);
146 
147   _gucharmap_intl_ensure_initialized ();
148 
149   chapters_class->title = _("Script");
150   chapters_class->character_to_iter = character_to_iter;
151   chapters_class->get_codepoint_list = get_codepoint_list;
152   chapters_class->get_book_codepoint_list = get_book_codepoint_list;
153 }
154 
G_DEFINE_TYPE(GucharmapScriptChaptersModel,gucharmap_script_chapters_model,GUCHARMAP_TYPE_CHAPTERS_MODEL)155 G_DEFINE_TYPE (GucharmapScriptChaptersModel, gucharmap_script_chapters_model, GUCHARMAP_TYPE_CHAPTERS_MODEL)
156 
157 GucharmapChaptersModel *
158 gucharmap_script_chapters_model_new (void)
159 {
160   return g_object_new (gucharmap_script_chapters_model_get_type (), NULL);
161 }
162