most_used_symbols.vala 6.26 KB
Newer Older
1
/*
2
 * This file is part of GNOME LaTeX.
3
 *
4
 * Copyright © 2010-2012 Sébastien Wilmet
5
 *
6
 * GNOME LaTeX is free software: you can redistribute it and/or modify
7 8 9 10
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
11
 * GNOME LaTeX is distributed in the hope that it will be useful,
12 13 14 15 16
 * 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
17
 * along with GNOME LaTeX.  If not, see <http://www.gnu.org/licenses/>.
18 19
 *
 * Author: Sébastien Wilmet
20 21
 */

22
using Gtk;
23 24 25

public class MostUsedSymbols : GLib.Object
{
26 27
    private static MostUsedSymbols _instance = null;
    private bool _modified = false;
28
    private Gtk.ListStore _store;
29

30
    // The column containing the number of times a symbol has been used.
31
    private const int SYMBOL_COLUMN_NUM = SymbolColumn.N_COLUMNS;
32

33 34
    private MostUsedSymbols ()
    {
35 36
        init_models ();
        load_data ();
37 38 39 40 41
    }

    // singleton
    public static MostUsedSymbols get_default ()
    {
42 43 44 45
        if (_instance == null)
            _instance = new MostUsedSymbols ();

        return _instance;
46 47
    }

48
    private void init_models ()
49
    {
50
        _store = new Gtk.ListStore (SymbolColumn.N_COLUMNS + 1,
51 52 53 54 55 56 57
            typeof (Gdk.Pixbuf),
            typeof (string), // command
            typeof (string), // tooltip
            typeof (string), // id
            typeof (int)     // number of times used
        );

58
        _store.set_sort_column_id (SYMBOL_COLUMN_NUM, SortType.DESCENDING);
59
    }
60

61 62
    public TreeModel get_model ()
    {
63
        return _store as TreeModel;
64 65 66 67
    }

    public void clear ()
    {
68
        _store.clear ();
69 70
    }

71
    public void increment_symbol (string id)
72
    {
73
        TreeIter iter;
74

75
        if (!get_iter_at_symbol_id (id, out iter))
76 77
            add_symbol (id, 1);
        else
78
        {
79 80
            int num;
            TreeModel model = _store as TreeModel;
81
            model.get (iter, SYMBOL_COLUMN_NUM, out num);
82

83
            _store.set (iter, SYMBOL_COLUMN_NUM, num + 1);
84
        }
85

86
        _modified = true;
87 88
    }

89
    private bool get_iter_at_symbol_id (string id, out TreeIter iter)
90
    {
91
        if (!_store.get_iter_first (out iter))
92
            return false;
93

94
        do
95
        {
96 97 98 99 100 101
            string cur_id;
            TreeModel model = _store as TreeModel;
            model.get (iter, SymbolColumn.ID, out cur_id);

            if (cur_id == id)
                return true;
102
        }
103
        while (_store.iter_next (ref iter));
104

105 106
        return false;
    }
107

108 109 110 111 112
    private void add_symbol (string id, int nb_times_used)
    {
        Gdk.Pixbuf? pixbuf = Symbols.get_pixbuf (id);
        if (pixbuf == null)
            return;
113

114 115
        string command;
        string tooltip;
116
        if (!Symbols.get_default ().get_symbol_info (id, out command, out tooltip))
117 118
            return;

119 120 121 122
        TreeIter iter;
        _store.append (out iter);
        _store.set (iter,
            SymbolColumn.PIXBUF, pixbuf,
123 124
            SymbolColumn.COMMAND, command,
            SymbolColumn.TOOLTIP, tooltip,
125
            SymbolColumn.ID, id,
126
            SYMBOL_COLUMN_NUM, nb_times_used
127
        );
128 129
    }

130
    private File get_xml_file ()
131
    {
132
        string path = Path.build_filename (Environment.get_user_data_dir (),
133
            "gnome-latex", "most_used_symbols.xml");
134 135 136 137 138 139 140

        return File.new_for_path (path);
    }

    private void load_data ()
    {
        File file = get_xml_file ();
141
        if (!file.query_exists ())
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
            return;

        string? contents = Utils.load_file (file);
        if (contents == null)
            return;

        try
        {
            MarkupParser parser = { parser_start, null, null, null, null };
            MarkupParseContext context = new MarkupParseContext (parser, 0, this, null);
            context.parse (contents, -1);
        }
        catch (GLib.Error e)
        {
            warning ("Impossible to load the most used symbols: %s", e.message);
        }
158 159 160 161 162 163 164 165 166 167 168
    }

    private void parser_start (MarkupParseContext context, string name,
        string[] attr_names, string[] attr_values) throws MarkupError
    {
        switch (name)
        {
            case "symbols":
                return;

            case "symbol":
169 170 171
                string id = null;
                int num = 0;

172
                for (int i = 0; i < attr_names.length; i++)
173 174 175 176
                {
                    switch (attr_names[i])
                    {
                        case "id":
177
                            id = attr_values[i];
178
                            break;
179 180 181

                        case "num":
                            num = int.parse (attr_values[i]);
182
                            break;
183 184

                        case "command":
185
                        case "package":
186
                            // Used in the past but no longer required.
187
                            break;
188

189 190 191 192 193
                        default:
                            throw new MarkupError.UNKNOWN_ATTRIBUTE (
                                "unknown attribute \"" + attr_names[i] + "\"");
                    }
                }
194 195

                add_symbol (id, num);
196 197 198 199 200 201 202 203 204 205
                break;

            default:
                throw new MarkupError.UNKNOWN_ELEMENT (
                    "unknown element \"" + name + "\"");
        }
    }

    public void save ()
    {
206
        if (!_modified)
207 208
            return;

209 210
        _modified = false;

211 212
        File file = get_xml_file ();

213
        TreeIter iter;
214
        bool is_empty = !_store.get_iter_first (out iter);
215 216

        if (is_empty)
217 218 219 220 221 222
        {
            Utils.delete_file (file);
            return;
        }

        string content = "<symbols>\n";
223 224

        do
225
        {
226 227 228 229 230 231
            string id;
            int num;

            TreeModel model = _store as TreeModel;
            model.get (iter,
                SymbolColumn.ID, out id,
232
                SYMBOL_COLUMN_NUM, out num
233 234 235
            );

            content += "  <symbol id=\"%s\" num=\"%d\" />\n".printf (id, num);
236
        }
237 238
        while (_store.iter_next (ref iter));

239 240
        content += "</symbols>\n";

241
        Utils.save_file (file, content);
242 243
    }
}