5a38640c0c5e9fc65f3e45bf343f439f3283d6c6
[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     mark_today = true;
60     show_week_numbers = false;
61 }
62
63 bool Config::getFile()
64 {
65     // use XDG config dir (~/.config/ usually)
66     char *path_to_config;
67     path_to_config = g_build_filename(g_get_user_config_dir(),
68                                       "gsimplecal", "config", NULL);
69     if (g_file_test(path_to_config, G_FILE_TEST_EXISTS)) {
70         file.open(path_to_config, ios::in);
71     }
72     g_free(path_to_config);
73     return file.is_open();
74 }
75
76 void Config::readFile()
77 {
78     string line;
79     while (!file.eof()) {
80         getline(file, line);
81         parseLine(line);
82     }
83     file.close();
84 }
85
86 void Config::parseLine(string line)
87 {
88     if (!line.length() || line[0] == '#') {
89         return;
90     }
91     size_t pos = line.find_first_of('=');
92     if (pos == string::npos) {
93         return;
94     }
95     string var = strip(line.substr(0, pos));
96     string val = strip(line.substr(pos + 1));
97
98     addOption(var, val);
99 }
100
101 void Config::addOption(string var, string val)
102 {
103     if (var == "show_calendar") {
104         if (!fromString<bool>(show_calendar, val)) {
105             show_calendar = true;
106         }
107     } else if (var == "show_timezones") {
108         if (!fromString<bool>(show_timezones, val)) {
109             show_timezones = false;
110         }
111     } else if (var == "clock_format") {
112         clock_format = val;
113     } else if (var == "clock_label") {
114         ClockInfo* clockinfo = new ClockInfo;
115         clockinfo->label = val;
116         clocks.push_back(clockinfo);
117     } else if (var == "clock_tz") {
118         clocks[clocks.size() - 1]->timezone = val;
119     } else if (var == "mainwindow_decorated") {
120         if (!fromString<bool>(mainwindow_decorated, val)) {
121             mainwindow_decorated = false;
122         }
123     } else if (var == "mainwindow_keep_above") {
124         if (!fromString<bool>(mainwindow_keep_above, val)) {
125             mainwindow_keep_above = true;
126         }
127     } else if (var == "mainwindow_sticky") {
128         if (!fromString<bool>(mainwindow_sticky, val)) {
129             mainwindow_sticky = false;
130         }
131     } else if (var == "mainwindow_skip_taskbar") {
132         if (!fromString<bool>(mainwindow_skip_taskbar, val)) {
133             mainwindow_skip_taskbar = true;
134         }
135     } else if (var == "mainwindow_position") {
136         if (val == "center") {
137             mainwindow_position = GTK_WIN_POS_CENTER;
138         } else if (val == "mouse") {
139             mainwindow_position = GTK_WIN_POS_MOUSE;
140         } else {
141             mainwindow_position = GTK_WIN_POS_NONE;
142         }
143     } else if (var == "mainwindow_resizable") {
144         if (!fromString<bool>(mainwindow_resizable, val)) {
145             mainwindow_resizable = true;
146         }
147     } else if (var == "mark_today") {
148         if (!fromString<bool>(mark_today, val)) {
149             mark_today = true;
150         }
151     } else if (var == "external_viewer") {
152         external_viewer = val;
153     } else if (var == "show_week_numbers") {
154         if (!fromString<bool>(show_week_numbers, val)) {
155             show_week_numbers = false;
156         }
157     }
158 }
159
160 template <class T> bool Config::fromString(T& t, const string& s)
161 {
162     istringstream iss(s);
163     return !(iss >> t).fail();
164 }
165
166 string Config::strip(const string& s)
167 {
168     string::size_type const first = s.find_first_not_of(' ');
169     if (first == string::npos) {
170         return string();
171     }
172     return s.substr(first, s.find_last_not_of(' ') - first + 1);
173 }