File: recent.cpp

package info (click to toggle)
fityk 1.3.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,772 kB
  • sloc: cpp: 34,595; ansic: 4,676; python: 963; makefile: 384; sh: 119; xml: 91; java: 31; ruby: 27; perl: 25
file content (109 lines) | stat: -rw-r--r-- 3,267 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
// This file is part of fityk program. Copyright 2001-2014 Marcin Wojdyr
// Licence: GNU General Public License ver. 2+

#include "recent.h"

using std::list;
using std::string;

static const int MAX_NUMBER_OF_ITEMS = 15;
static const char* MAGIC_SEP = "   ";

void RecentFiles::load_from_config(wxConfigBase *c)
{
    items_.clear();
    if (menu_ != NULL)
        delete menu_;

    menu_ = new wxMenu;
    if (c && c->HasGroup(config_group_)) {
        // gaps shouldn't happend in the config file, but just in case...
        int counter = 0;
        for (int i = 0; i < MAX_NUMBER_OF_ITEMS; i++) {
            wxString key = wxString::Format("%s/%i", config_group_, i);
            if (c->HasEntry(key)) {
                wxString value = c->Read(key, wxT(""));
                if (value.empty()) // it should not normally happen
                    continue;
                int id = first_item_id_ + counter;
                ++counter;
                wxString opt;
                string::size_type sep = value.find(MAGIC_SEP);
                if (sep != string::npos) {
                    opt = value.substr(sep+3);
                    value.resize(sep);
                }
                wxFileName fn(value);
                Item item = { id, fn, opt };
                items_.push_back(item);
                wxString hint = fn.GetFullPath();
                if (!opt.empty())
                    hint += " " + opt;
                menu_->Append(id, fn.GetFullName(), hint);
            }
        }
    }
}

void RecentFiles::save_to_config(wxConfigBase *c)
{
    if (!c)
        return;
    if (c->HasGroup(config_group_))
        c->DeleteGroup(config_group_);
    int counter = 0;
    for (list<Item>::const_iterator i = items_.begin(); i != items_.end(); ++i){
        wxString key = wxString::Format("%s/%i", config_group_, counter);
        counter++;
        wxString value = i->fn.GetFullPath();
        if (!i->options.empty())
            value += MAGIC_SEP + i->options;
        c->Write(key, value);
    }
}

void RecentFiles::add(const wxString& path, const wxString& options)
{
    assert(menu_ != NULL);
    const wxFileName fn = wxFileName(path);

    // avoid duplicates
    for (list<Item>::iterator it = items_.begin(); it != items_.end(); ++it) {
        if (it->fn == fn && it->options == options) {
            pull(it->id);
            return;
        }
    }

    int id;
    if (items_.size() < (size_t) MAX_NUMBER_OF_ITEMS) {
        id = first_item_id_ + items_.size();
    } else {
        id = items_.back().id;
        items_.pop_back();
        menu_->Destroy(id);
    }

    Item item = { id, fn, options };
    items_.push_front(item);
    wxString hint = fn.GetFullPath();
    if (!options.empty())
        hint += " " + options;
    menu_->Prepend(id, fn.GetFullName(), hint);
}

const RecentFiles::Item& RecentFiles::pull(int id)
{
    for (list<Item>::iterator it = items_.begin(); it != items_.end(); ++it) {
        if (it->id == id) {
            if (it != items_.begin()) {
                items_.push_front(*it); // it does not invalidate iterator
                items_.erase(it);
                menu_->Prepend(menu_->Remove(id));
            }
            break;
        }
    }
    return items_.front();
}