src/config.cpp

changeset 359
bcdfc801658b
parent 321
48e429bfd58c
child 421
7d26db0be944
equal deleted inserted replaced
358:7885fa5b09c5 359:bcdfc801658b
1 /* 1 /*
2 * LDForge: LDraw parts authoring CAD 2 * LDForge: LDraw parts authoring CAD
3 * Copyright (C) 2013 Santeri Piippo 3 * Copyright (C) 2013 Santeri Piippo
4 * 4 *
5 * This program is free software: you can redistribute it and/or modify 5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or 7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version. 8 * (at your option) any later version.
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19 #include <errno.h> 19 #include <errno.h>
20 #include <time.h> 20 #include <time.h>
21 #include <QDir> 21 #include <QDir>
22 #include <qtextstream.h> 22 #include <QTextStream>
23 #include "common.h" 23 #include "common.h"
24 #include "config.h" 24 #include "config.h"
25 #include "misc.h" 25 #include "misc.h"
26 #include "gui.h" 26 #include "gui.h"
27 27
28 config* g_configPointers[MAX_CONFIG]; 28 config* g_configPointers[MAX_CONFIG];
29 static ushort g_cfgPointerCursor = 0; 29 static ushort g_cfgPointerCursor = 0;
30 30
31 // ============================================================================= 31 // =============================================================================
32 // Load the configuration from file 32 // Load the configuration from file
33 bool config::load () { 33 bool config::load()
34 print ("config::load: Loading configuration file...\n"); 34 {
35 print ("config::load: Path to configuration is %1\n", filepath ()); 35 print( "config::load: Loading configuration file...\n" );
36 print( "config::load: Path to configuration is %1\n", filepath() );
36 37
37 // Locale must be disabled for atof 38 // Locale must be disabled for atof
38 setlocale (LC_NUMERIC, "C"); 39 setlocale( LC_NUMERIC, "C" );
39 40
40 File f (filepath (), File::Read); 41 File f( filepath(), File::Read );
41 if (!f) 42 int ln = 0;
43
44 if( !f )
42 return false; 45 return false;
43 46
44 size_t ln = 0;
45
46 // Read the values. 47 // Read the values.
47 for (str line : f) { 48 for( str line : f )
49 {
48 ln++; 50 ln++;
49 51
50 if (line.isEmpty () || line[0] == '#') 52 if( line.isEmpty() || line[0] == '#' )
51 continue; // Empty line or comment. 53 continue; // Empty line or comment.
52 54
53 // Find the equals sign. 55 // Find the equals sign.
54 int equals = line.indexOf ('='); 56 int equals = line.indexOf( '=' );
55 if (equals == -1) { 57
56 fprint (stderr, "couldn't find `=` sign in entry `%1`\n", line); 58 if( equals == -1 )
59 {
60 fprint( stderr, "couldn't find `=` sign in entry `%1`\n", line );
57 continue; 61 continue;
58 } 62 }
59 63
60 str entry = line.left (equals); 64 str entry = line.left( equals );
61 str valstring = line.right (line.length () - equals - 1); 65 str valstring = line.right( line.length() - equals - 1 );
62 66
63 // Find the config entry for this. 67 // Find the config entry for this.
64 config* cfg = null; 68 config* cfg = null;
65 for (config* i : g_configPointers) { 69
66 if (!i) 70 for( config* i : g_configPointers )
71 {
72 if( !i )
67 break; 73 break;
68 74
69 if (entry == i->name) 75 if( entry == i->name )
70 cfg = i; 76 cfg = i;
71 } 77 }
72 78
73 if (!cfg) { 79 if( !cfg )
74 fprint (stderr, "unknown config `%1`\n", entry); 80 {
81 fprint( stderr, "unknown config `%1`\n", entry );
75 continue; 82 continue;
76 } 83 }
77 84
78 switch (cfg->getType()) { 85 switch( cfg->getType() )
79 case CONFIG_int: 86 {
80 static_cast<intconfig*> (cfg)->value = valstring.toInt (); 87 case Type_int:
81 break; 88 static_cast<intconfig*>( cfg )->value = valstring.toInt();
82 89 break;
83 case CONFIG_str: 90
84 static_cast<strconfig*> (cfg)->value = valstring; 91 case Type_str:
85 break; 92 static_cast<strconfig*>( cfg )->value = valstring;
86 93 break;
87 case CONFIG_float: 94
88 static_cast<floatconfig*> (cfg)->value = valstring.toFloat (); 95 case Type_float:
89 break; 96 static_cast<floatconfig*>( cfg )->value = valstring.toFloat();
90 97 break;
91 case CONFIG_bool: 98
92 { 99 case Type_bool:
93 bool& val = static_cast<boolconfig*> (cfg)->value; 100 {
101 bool& val = static_cast<boolconfig*>( cfg )->value;
94 102
95 if (valstring.toUpper () == "TRUE" || valstring == "1") 103 if( valstring.toUpper() == "TRUE" || valstring == "1" )
96 val = true; 104 val = true;
97 elif (valstring.toUpper () == "FALSE" || valstring == "0") 105 elif( valstring.toUpper() == "FALSE" || valstring == "0" )
98 val = false; 106 val = false;
99 break; 107
100 } 108 break;
101 109 }
102 case CONFIG_keyseq: 110
103 static_cast<keyseqconfig*> (cfg)->value = keyseq::fromString (valstring); 111 case Type_keyseq:
112 static_cast<keyseqconfig*>( cfg )->value = keyseq::fromString( valstring );
104 break; 113 break;
105 114
106 default: 115 default:
107 break; 116 break;
108 } 117 }
109 } 118 }
110 119
111 f.close (); 120 f.close();
112 return true; 121 return true;
113 } 122 }
114 123
115 extern_cfg (str, io_ldpath); 124 extern_cfg( str, io_ldpath );
116 125
117 // ============================================================================= 126 // =============================================================================
118 // Save the configuration to disk 127 // Save the configuration to disk
119 bool config::save () { 128 bool config::save()
129 {
120 // The function will write floats, disable the locale now so that they 130 // The function will write floats, disable the locale now so that they
121 // are written properly. 131 // are written properly.
122 setlocale (LC_NUMERIC, "C"); 132 setlocale( LC_NUMERIC, "C" );
123 133
124 // If the directory doesn't exist, create it now. 134 // If the directory doesn't exist, create it now.
125 if (QDir (dirpath ()).exists () == false) { 135 if( QDir( dirpath() ).exists() == false )
126 fprint (stderr, "Creating config path %1...\n", dirpath ()); 136 {
127 if (!QDir ().mkpath (dirpath ())) { 137 fprint( stderr, "Creating config path %1...\n", dirpath() );
128 critical ("Failed to create the configuration directory. Configuration cannot be saved!\n"); 138
139 if( !QDir().mkpath( dirpath() ))
140 {
141 critical( "Failed to create the configuration directory. Configuration cannot be saved!\n" );
129 return false; 142 return false;
130 } 143 }
131 } 144 }
132 145
133 File f (filepath (), File::Write); 146 File f( filepath(), File::Write );
134 print ("writing cfg to %1\n", filepath ()); 147 print( "writing cfg to %1\n", filepath() );
135 148
136 if (!f) { 149 if( !f )
150 {
137 critical( fmt( QObject::tr( "Cannot save configuration, cannot open %1 for writing: %2\n" ), 151 critical( fmt( QObject::tr( "Cannot save configuration, cannot open %1 for writing: %2\n" ),
138 filepath(), strerror( errno ))); 152 filepath(), strerror( errno )) );
139 return false; 153 return false;
140 } 154 }
141 155
142 fprint (f, "# Configuration file for " APPNAME "\n"); 156 fprint( f, "# Configuration file for " APPNAME "\n" );
143 157
144 for (config* cfg : g_configPointers) { 158 for( config * cfg : g_configPointers )
145 if (!cfg) 159 {
146 break; 160 if( !cfg )
147 161 break;
148 if (cfg->isDefault ()) 162
163 if( cfg->isDefault() )
149 continue; 164 continue;
150 165
151 str valstring; 166 str valstring;
152 switch (cfg->getType ()) { 167
153 case CONFIG_int: 168 switch( cfg->getType() )
154 valstring = fmt ("%1", static_cast<intconfig*> (cfg)->value); 169 {
155 break; 170 case Type_int:
156 171 valstring = fmt( "%1", static_cast<intconfig*>( cfg )->value );
157 case CONFIG_str: 172 break;
158 valstring = static_cast<strconfig*> (cfg)->value; 173
159 break; 174 case Type_str:
160 175 valstring = static_cast<strconfig*>( cfg )->value;
161 case CONFIG_float: 176 break;
162 valstring = fmt ("%1", static_cast<floatconfig*> (cfg)->value); 177
163 break; 178 case Type_float:
164 179 valstring = fmt( "%1", static_cast<floatconfig*>( cfg )->value );
165 case CONFIG_bool: 180 break;
166 valstring = (static_cast<boolconfig*> (cfg)->value) ? "true" : "false"; 181
167 break; 182 case Type_bool:
168 183 valstring = ( static_cast<boolconfig*>( cfg )->value ) ? "true" : "false";
169 case CONFIG_keyseq: 184 break;
170 valstring = static_cast<keyseqconfig*> (cfg)->value.toString (); 185
186 case Type_keyseq:
187 valstring = static_cast<keyseqconfig*>( cfg )->value.toString();
171 break; 188 break;
172 189
173 default: 190 default:
174 break; 191 break;
175 } 192 }
176 193
177 // Write the entry now. 194 // Write the entry now.
178 fprint (f, "%1=%2\n", cfg->name, valstring); 195 fprint( f, "%1=%2\n", cfg->name, valstring );
179 } 196 }
180 197
181 f.close (); 198 f.close();
182 return true; 199 return true;
183 } 200 }
184 201
185 // ============================================================================= 202 // =============================================================================
186 void config::reset () { 203 void config::reset()
187 for (config* cfg : g_configPointers) { 204 {
188 if (!cfg) 205 for( config * cfg : g_configPointers )
189 break; 206 {
190 207 if( !cfg )
191 cfg->resetValue (); 208 break;
192 } 209
193 } 210 cfg->resetValue();
194 211 }
195 // ============================================================================= 212 }
196 str config::filepath () { 213
197 str path = fmt ("%1%2.cfg", dirpath (), 214 // =============================================================================
198 str (APPNAME).toLower ()); 215 str config::filepath()
216 {
217 str path = fmt( "%1%2.cfg", dirpath(),
218 str( APPNAME ).toLower() );
199 return path; 219 return path;
200 } 220 }
201 221
202 // ============================================================================= 222 // =============================================================================
203 str config::dirpath () { 223 str config::dirpath()
224 {
204 #ifndef _WIN32 225 #ifndef _WIN32
205 return fmt ("%1" DIRSLASH ".%2" DIRSLASH, 226 return fmt( "%1" DIRSLASH ".%2" DIRSLASH,
206 QDir::homePath (), str (APPNAME).toLower ()); 227 QDir::homePath(), str( APPNAME ).toLower() );
207 #else 228 #else
208 return fmt ("%1" DIRSLASH APPNAME DIRSLASH, QDir::homePath ()); 229 return fmt( "%1" DIRSLASH APPNAME DIRSLASH, QDir::homePath() );
209 #endif // _WIN32 230 #endif // _WIN32
210 } 231 }
211 232
212 void addConfig (config* ptr) { 233 void addConfig( config* ptr )
213 if (g_cfgPointerCursor == 0) 234 {
214 memset (g_configPointers, 0, sizeof g_configPointers); 235 if( g_cfgPointerCursor == 0 )
215 236 memset( g_configPointers, 0, sizeof g_configPointers );
216 assert (g_cfgPointerCursor < MAX_CONFIG); 237
238 assert( g_cfgPointerCursor < MAX_CONFIG );
217 g_configPointers[g_cfgPointerCursor++] = ptr; 239 g_configPointers[g_cfgPointerCursor++] = ptr;
218 } 240 }

mercurial