Imported Upstream version 1.4
[debian/gsimplecal.git] / src / Config.cpp
1 #include <cstdlib>
2 #include <iostream>
3 #include <fstream>
4 #include <string>
5 #include <sstream>
6
7 #include <glib/gstdio.h>
8 #include <gtk/gtk.h>
9
10 #include "Config.hpp"
11
12 using namespace std;
13
14
15 Config* Config::_instance = NULL;
16
17 Config* Config::getInstance()
18 {
19     if (_instance == NULL) {
20         _instance = new Config();
21         atexit(Destroy);
22     }
23     return _instance;
24 }
25
26 void Config::Destroy()
27 {
28     delete _instance;
29     _instance = NULL;
30 }
31
32
33 Config::Config()
34 {
35     getDefaults();
36     if (getFile()) {
37         readFile();
38     }
39 }
40
41 Config::~Config()
42 {
43     for (unsigned int i = 0; i < clocks.size(); i++) {
44         delete clocks[i];
45     }
46 }
47
48
49 void Config::getDefaults()
50 {
51     show_calendar = true;
52     show_timezones = false;
53     clock_format = string("%H:%M");
54     mainwindow_decorated = false;
55     mainwindow_keep_above = true;
56     mainwindow_sticky = false;
57     mainwindow_skip_taskbar = true;
58     mainwindow_position = GTK_WIN_POS_MOUSE;
59     mainwindow_xoffset = 0;
60     mainwindow_yoffset = 0;
61     mark_today = true;
62     show_week_numbers = false;
63     close_on_unfocus = false;
64 }
65
66 bool Config::getFile()
67 {
68     // use XDG config dir (~/.config/ usually)
69     char *path_to_config;
70     path_to_config = g_build_filename(g_get_user_config_dir(),
71                                       "gsimplecal", "config", NULL);
72     if (g_file_test(path_to_config, G_FILE_TEST_EXISTS)) {
73         file.open(path_to_config, ios::in);
74     }
75     g_free(path_to_config);
76     return file.is_open();
77 }
78
79 void Config::readFile()
80 {
81     string line;
82     while (!file.eof()) {
83         getline(file, line);
84         parseLine(line);
85     }
86     file.close();
87 }
88
89 void Config::parseLine(string line)
90 {
91     if (!line.length() || line[0] == '#') {
92         return;
93     }
94     size_t pos = line.find_first_of('=');
95     if (pos == string::npos) {
96         return;
97     }
98     string var = strip(line.substr(0, pos));
99     string val = strip(line.substr(pos + 1));
100
101     addOption(var, val);
102 }
103
104 void Config::addOption(string var, string val)
105 {
106     if (var == "show_calendar") {
107         if (!fromString<bool>(show_calendar, val)) {
108             show_calendar = true;
109         }
110     } else if (var == "show_timezones") {
111         if (!fromString<bool>(show_timezones, val)) {
112             show_timezones = false;
113         }
114     } else if (var == "clock_format") {
115         clock_format = val;
116     } else if (var == "clock_label") {
117         ClockInfo* clockinfo = new ClockInfo;
118         clockinfo->label = val;
119         clocks.push_back(clockinfo);
120     } else if (var == "clock_tz") {
121         clocks[clocks.size() - 1]->timezone = val;
122     } else if (var == "mainwindow_decorated") {
123         if (!fromString<bool>(mainwindow_decorated, val)) {
124             mainwindow_decorated = false;
125         }
126     } else if (var == "mainwindow_keep_above") {
127         if (!fromString<bool>(mainwindow_keep_above, val)) {
128             mainwindow_keep_above = true;
129         }
130     } else if (var == "mainwindow_sticky") {
131         if (!fromString<bool>(mainwindow_sticky, val)) {
132             mainwindow_sticky = false;
133         }
134     } else if (var == "mainwindow_skip_taskbar") {
135         if (!fromString<bool>(mainwindow_skip_taskbar, val)) {
136             mainwindow_skip_taskbar = true;
137         }
138     } else if (var == "mainwindow_position") {
139         if (val == "center") {
140             mainwindow_position = GTK_WIN_POS_CENTER;
141         } else if (val == "mouse") {
142             mainwindow_position = GTK_WIN_POS_MOUSE;
143         } else {
144             mainwindow_position = GTK_WIN_POS_NONE;
145         }
146     } else if (var == "mainwindow_xoffset") {
147         stringstream convert(val);
148         if (!(convert >> mainwindow_xoffset)) {
149                 mainwindow_xoffset = 0;
150         }
151     }  else if (var == "mainwindow_yoffset") {
152         stringstream convert(val);
153         if (!(convert >> mainwindow_yoffset)) {
154             mainwindow_yoffset = 0;
155         }
156     } else if (var == "mainwindow_resizable") {
157         if (!fromString<bool>(mainwindow_resizable, val)) {
158             mainwindow_resizable = true;
159         }
160     } else if (var == "mark_today") {
161         if (!fromString<bool>(mark_today, val)) {
162             mark_today = true;
163         }
164     } else if (var == "external_viewer") {
165         external_viewer = val;
166     } else if (var == "show_week_numbers") {
167         if (!fromString<bool>(show_week_numbers, val)) {
168             show_week_numbers = false;
169         }
170     } else if (var == "close_on_unfocus") {
171         if (!fromString<bool>(close_on_unfocus, val)) {
172             close_on_unfocus = false;
173         }
174     }
175 }
176
177 template <class T> bool Config::fromString(T& t, const string& s)
178 {
179     istringstream iss(s);
180     return !(iss >> t).fail();
181 }
182
183 string Config::strip(const string& s)
184 {
185     string::size_type const first = s.find_first_not_of(' ');
186     if (first == string::npos) {
187         return string();
188     }
189     return s.substr(first, s.find_last_not_of(' ') - first + 1);
190 }