Skip to content

Commit f176f5c

Browse files
Bracket Colors: Support user defined colors (#5)
* simple UI * start hooking up signals * mechanism to save settings from a conf file * save load settings for defaults button * less globals * better config color name * hook up colors * glib types * use colors from plugin config * update colors when settings change * reorganze, try to avoid giant files * update document colors when they switch * update headers * fix bug when some brackets werent getting added to bracket map * fix bug that was deleting newly inserted brackets * std::map insert doesnt overwrite, use insert_or_assign * handle when removing a bracket completes another * handle invalid color specs in config file * avoid static initialization fiasco * if there are problems loading config, use defaults * cleanup headers * mark GUI labels as translatable --------- Co-authored-by: Asif Amin <[email protected]>
1 parent 7bef4fd commit f176f5c

File tree

6 files changed

+843
-139
lines changed

6 files changed

+843
-139
lines changed

Diff for: bracketcolors/src/Configuration.cc

+293
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
1+
/*
2+
* Configuration.cc
3+
*
4+
* Copyright 2023 Asif Amin <[email protected]>
5+
*
6+
* This program is free software; you can redistribute it and/or modify
7+
* it under the terms of the GNU General Public License as published by
8+
* the Free Software Foundation; either version 2 of the License, or
9+
* (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18+
* MA 02110-1301, USA.
19+
*/
20+
21+
22+
/* --------------------------------- INCLUDES ------------------------------- */
23+
24+
#include <geanyplugin.h>
25+
#include "Configuration.h"
26+
27+
28+
/* ------------------------------ IMPLEMENTATION ---------------------------- */
29+
30+
31+
// -----------------------------------------------------------------------------
32+
BracketColorsPluginSetting::BracketColorsPluginSetting(
33+
std::string group,
34+
std::string key,
35+
gpointer value
36+
)
37+
/*
38+
Constructor
39+
----------------------------------------------------------------------------- */
40+
: mGroup(group),
41+
mKey(key),
42+
mValue(value)
43+
{
44+
// nothing to do
45+
}
46+
47+
48+
49+
// -----------------------------------------------------------------------------
50+
BooleanSetting::BooleanSetting(
51+
std::string group,
52+
std::string key,
53+
gpointer value
54+
)
55+
/*
56+
Constructor
57+
----------------------------------------------------------------------------- */
58+
: BracketColorsPluginSetting(group, key, value)
59+
{
60+
// nothing to do
61+
}
62+
63+
64+
65+
// -----------------------------------------------------------------------------
66+
ColorSetting::ColorSetting(
67+
std::string group,
68+
std::string key,
69+
gpointer value
70+
)
71+
/*
72+
Constructor
73+
----------------------------------------------------------------------------- */
74+
: BracketColorsPluginSetting(group, key, value)
75+
{
76+
// nothing to do
77+
}
78+
79+
80+
81+
// -----------------------------------------------------------------------------
82+
bool BooleanSetting::read(GKeyFile *kf)
83+
/*
84+
85+
----------------------------------------------------------------------------- */
86+
{
87+
gboolean *aBool = static_cast<gboolean *>(mValue);
88+
*aBool = utils_get_setting_boolean(
89+
kf, mGroup.c_str(), mKey.c_str(), *aBool
90+
);
91+
return true;
92+
}
93+
94+
95+
96+
// -----------------------------------------------------------------------------
97+
bool BooleanSetting::write(GKeyFile *kf)
98+
/*
99+
100+
----------------------------------------------------------------------------- */
101+
{
102+
const gboolean *aBool = static_cast<gboolean *>(mValue);
103+
g_key_file_set_boolean(
104+
kf, mGroup.c_str(), mKey.c_str(), *aBool
105+
);
106+
return true;
107+
}
108+
109+
110+
111+
// -----------------------------------------------------------------------------
112+
bool ColorSetting::read(GKeyFile *kf)
113+
/*
114+
115+
----------------------------------------------------------------------------- */
116+
{
117+
std::string *strPtr = reinterpret_cast<std::string *>(mValue);
118+
119+
gchar *str = utils_get_setting_string(
120+
kf, mGroup.c_str(), mKey.c_str(), strPtr->c_str()
121+
);
122+
123+
/*
124+
* Make sure the color is valid
125+
*/
126+
bool ret = false;
127+
128+
GdkColor color;
129+
if (utils_parse_color(str, &color)) {
130+
*strPtr = std::string(str);
131+
ret = true;
132+
}
133+
else {
134+
g_debug("%s: Failed to parse color '%s'", __FUNCTION__, str);
135+
}
136+
137+
g_free(str);
138+
return ret;
139+
}
140+
141+
142+
143+
// -----------------------------------------------------------------------------
144+
bool ColorSetting::write(GKeyFile *kf)
145+
/*
146+
147+
----------------------------------------------------------------------------- */
148+
{
149+
std::string *strPtr = reinterpret_cast<std::string *>(mValue);
150+
g_key_file_set_string(
151+
kf, mGroup.c_str(), mKey.c_str(), strPtr->c_str()
152+
);
153+
return true;
154+
}
155+
156+
157+
158+
// -----------------------------------------------------------------------------
159+
static gboolean read_keyfile(
160+
GKeyFile *kf,
161+
std::string filename,
162+
GKeyFileFlags flags
163+
)
164+
/*
165+
166+
----------------------------------------------------------------------------- */
167+
{
168+
GError *error = NULL;
169+
if (!g_key_file_load_from_file(kf, filename.c_str(), flags, &error)) {
170+
if (error->domain != G_FILE_ERROR || error->code != G_FILE_ERROR_NOENT) {
171+
g_debug("%s: Failed to load configuration file: %s", __FUNCTION__, error->message);
172+
}
173+
g_error_free(error);
174+
return FALSE;
175+
}
176+
177+
return TRUE;
178+
}
179+
180+
181+
182+
// -----------------------------------------------------------------------------
183+
static gboolean write_keyfile(
184+
GKeyFile *kf,
185+
std::string filename
186+
)
187+
/*
188+
189+
----------------------------------------------------------------------------- */
190+
{
191+
gchar *dirname = g_path_get_dirname(filename.c_str());
192+
193+
gsize length;
194+
gchar *data = g_key_file_to_data(kf, &length, NULL);
195+
196+
GError *error = NULL;
197+
gint err;
198+
gboolean success = FALSE;
199+
200+
if ((err = utils_mkdir(dirname, TRUE)) != 0) {
201+
g_warning(
202+
"Failed to create configuration directory \"%s\": %s",
203+
dirname, g_strerror(err)
204+
);
205+
}
206+
else if (!g_file_set_contents(filename.c_str(), data, (gssize)length, &error)) {
207+
g_warning("Failed to save configuration file: %s", error->message);
208+
g_error_free(error);
209+
} else {
210+
success = TRUE;
211+
}
212+
213+
g_free(data);
214+
g_free(dirname);
215+
216+
return success;
217+
}
218+
219+
220+
221+
// -----------------------------------------------------------------------------
222+
BracketColorsPluginConfiguration::BracketColorsPluginConfiguration(
223+
gboolean useDefaults,
224+
BracketColorArray colors
225+
)
226+
/*
227+
228+
----------------------------------------------------------------------------- */
229+
: mUseDefaults(useDefaults),
230+
mColors(colors),
231+
mCustomColors(mColors)
232+
{
233+
mPluginSettings.push_back(
234+
std::make_shared<BooleanSetting>("general", "defaults", &mUseDefaults)
235+
);
236+
237+
for (guint i = 0; i < mCustomColors.size(); i++) {
238+
std::string key = "order_" + std::to_string(i);
239+
mPluginSettings.push_back(
240+
std::make_shared<ColorSetting>("colors", key, &mCustomColors[i])
241+
);
242+
}
243+
}
244+
245+
246+
247+
// -----------------------------------------------------------------------------
248+
void BracketColorsPluginConfiguration::LoadConfig(std::string fileName)
249+
/*
250+
251+
----------------------------------------------------------------------------- */
252+
{
253+
GKeyFile *kf = g_key_file_new();
254+
bool success = true;
255+
256+
if (read_keyfile(kf, fileName, G_KEY_FILE_NONE)) {
257+
for (auto &it : mPluginSettings) {
258+
if (not it->read(kf)) {
259+
success = false;
260+
}
261+
}
262+
}
263+
else {
264+
g_debug("%s: Unable to load '%s''", __FUNCTION__, fileName.c_str());
265+
success = false;
266+
}
267+
268+
if (not success) {
269+
mUseDefaults = true;
270+
}
271+
272+
g_key_file_free(kf);
273+
}
274+
275+
276+
277+
// -----------------------------------------------------------------------------
278+
void BracketColorsPluginConfiguration::SaveConfig(std::string fileName)
279+
/*
280+
281+
----------------------------------------------------------------------------- */
282+
{
283+
GKeyFile *kf = g_key_file_new();
284+
285+
read_keyfile(kf, fileName, G_KEY_FILE_KEEP_COMMENTS);
286+
287+
for (auto &it : mPluginSettings) {
288+
it->write(kf);
289+
}
290+
write_keyfile(kf, fileName);
291+
292+
g_key_file_free(kf);
293+
}

0 commit comments

Comments
 (0)