| |
1 /* |
| |
2 * LDForge: LDraw parts authoring CAD |
| |
3 * Copyright (C) 2013 Santeri Piippo |
| |
4 * |
| |
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 |
| |
7 * the Free Software Foundation, either version 3 of the License, or |
| |
8 * (at your option) any later version. |
| |
9 * |
| |
10 * This program is distributed in the hope that it will be useful, |
| |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| |
13 * GNU General Public License for more details. |
| |
14 * |
| |
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/>. |
| |
17 */ |
| |
18 |
| |
19 #include "common.h" |
| |
20 #include "configDialog.h" |
| |
21 #include "file.h" |
| |
22 #include "config.h" |
| |
23 #include "misc.h" |
| |
24 #include "colors.h" |
| |
25 #include "colorSelectDialog.h" |
| |
26 #include <qgridlayout.h> |
| |
27 #include <qfiledialog.h> |
| |
28 #include <qcolordialog.h> |
| |
29 #include <qboxlayout.h> |
| |
30 #include <qevent.h> |
| |
31 #include <qgroupbox.h> |
| |
32 |
| |
33 extern_cfg (str, gl_bgcolor); |
| |
34 extern_cfg (str, gl_maincolor); |
| |
35 extern_cfg (bool, lv_colorize); |
| |
36 extern_cfg (bool, gl_colorbfc); |
| |
37 extern_cfg (float, gl_maincolor_alpha); |
| |
38 extern_cfg (int, gl_linethickness); |
| |
39 extern_cfg (int, gui_toolbar_iconsize); |
| |
40 extern_cfg (str, gui_colortoolbar); |
| |
41 extern_cfg (bool, gl_selflash); |
| |
42 extern_cfg (bool, edit_schemanticinline); |
| |
43 extern_cfg (bool, gl_blackedges); |
| |
44 |
| |
45 ConfigDialog* g_ConfigDialog = null; |
| |
46 |
| |
47 #define INIT_CHECKBOX(BOX, CFG) \ |
| |
48 BOX->setCheckState (CFG ? Qt::Checked : Qt::Unchecked); |
| |
49 |
| |
50 #define APPLY_CHECKBOX(BTN, CFG) \ |
| |
51 CFG = BTN->checkState() == Qt::Checked; |
| |
52 |
| |
53 // ============================================================================= |
| |
54 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
55 // ============================================================================= |
| |
56 ConfigDialog::ConfigDialog (ForgeWindow* parent) : QDialog (parent) { |
| |
57 g_ConfigDialog = this; |
| |
58 tabs = new QTabWidget; |
| |
59 |
| |
60 initMainTab (); |
| |
61 initShortcutsTab (); |
| |
62 initQuickColorTab (); |
| |
63 initGridTab (); |
| |
64 initExtProgTab (); |
| |
65 |
| |
66 IMPLEMENT_DIALOG_BUTTONS |
| |
67 |
| |
68 QVBoxLayout* layout = new QVBoxLayout; |
| |
69 layout->addWidget (tabs); |
| |
70 layout->addWidget (bbx_buttons); |
| |
71 setLayout (layout); |
| |
72 |
| |
73 setWindowTitle ("Settings"); |
| |
74 setWindowIcon (getIcon ("settings")); |
| |
75 } |
| |
76 |
| |
77 // ============================================================================= |
| |
78 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
79 // ============================================================================= |
| |
80 void ConfigDialog::initMainTab () { |
| |
81 mainTab = new QWidget; |
| |
82 |
| |
83 // ========================================================================= |
| |
84 // Background and foreground colors |
| |
85 lb_viewBg = new QLabel ("Background color:"); |
| |
86 pb_viewBg = new QPushButton; |
| |
87 setButtonBackground (pb_viewBg, gl_bgcolor.value); |
| |
88 connect (pb_viewBg, SIGNAL (clicked ()), |
| |
89 this, SLOT (slot_setGLBackground ())); |
| |
90 pb_viewBg->setWhatsThis ("This is the background color for the viewport."); |
| |
91 |
| |
92 lb_viewFg = new QLabel ("Foreground color:"); |
| |
93 pb_viewFg = new QPushButton; |
| |
94 setButtonBackground (pb_viewFg, gl_maincolor.value); |
| |
95 connect (pb_viewFg, SIGNAL (clicked ()), |
| |
96 this, SLOT (slot_setGLForeground ())); |
| |
97 pb_viewFg->setWhatsThis ("This color is used for the main color."); |
| |
98 |
| |
99 // ========================================================================= |
| |
100 // Alpha and line thickness sliders |
| |
101 lb_viewFgAlpha = new QLabel ("Alpha:"); |
| |
102 makeSlider (sl_viewFgAlpha, 1, 10, (gl_maincolor_alpha * 10.0f)); |
| |
103 sl_viewFgAlpha->setWhatsThis ("Opacity of main color in the viewport."); |
| |
104 |
| |
105 lb_lineThickness = new QLabel ("Line thickness:"); |
| |
106 makeSlider (sl_lineThickness, 1, 8, gl_linethickness); |
| |
107 sl_lineThickness->setWhatsThis ("How thick lines should be drawn in the viewport."); |
| |
108 |
| |
109 // ========================================================================= |
| |
110 // Tool bar icon size slider |
| |
111 lb_iconSize = new QLabel ("Toolbar icon size:"); |
| |
112 makeSlider (sl_iconSize, 1, 5, (gui_toolbar_iconsize - 12) / 4); |
| |
113 |
| |
114 // ========================================================================= |
| |
115 // List view colorizer and BFC red/green view checkboxes |
| |
116 cb_colorize = new QCheckBox ("Colorize polygons in object list"); |
| |
117 cb_colorize->setChecked (lv_colorize); |
| |
118 cb_colorize->setWhatsThis ("Makes colored objects (non-16 and 24) appear " |
| |
119 "colored in the object list. A red polygon will have its description " |
| |
120 "written in red text."); |
| |
121 |
| |
122 cb_colorBFC = new QCheckBox ("Red/green BFC view"); |
| |
123 cb_colorBFC->setChecked (gl_colorbfc); |
| |
124 cb_colorBFC->setWhatsThis ("Polygons' front sides become green and back " |
| |
125 "sides red. Not implemented yet."); |
| |
126 |
| |
127 cb_selFlash = new QCheckBox ("Selection flash"); |
| |
128 cb_selFlash->setChecked (gl_selflash); |
| |
129 cb_colorBFC->setWhatsThis ("A pulse effect for clearer selection view."); |
| |
130 |
| |
131 cb_blackEdges = new QCheckBox ("Black edges"); |
| |
132 cb_blackEdges->setWhatsThis ("Makes all edgelines appear black. If this is " |
| |
133 "not set, edge lines take their color as defined in LDConfig.ldr"); |
| |
134 cb_blackEdges->setChecked (gl_blackedges); |
| |
135 |
| |
136 cb_schemanticInline = new QCheckBox ("Schemantic insertion only"); |
| |
137 cb_schemanticInline->setChecked (edit_schemanticinline); |
| |
138 cb_colorBFC->setWhatsThis ("When inserting objects through inlining, file " |
| |
139 "inserting or through external programs, all non-schemantics (those without " |
| |
140 "actual meaning in the part file like comments and such) are filtered out."); |
| |
141 |
| |
142 cb_schemanticInline->setEnabled (false); |
| |
143 cb_colorBFC->setEnabled (false); |
| |
144 |
| |
145 QGridLayout* layout = new QGridLayout; |
| |
146 layout->addWidget (lb_viewBg, 0, 0); |
| |
147 layout->addWidget (pb_viewBg, 0, 1); |
| |
148 layout->addWidget (lb_viewFg, 0, 2); |
| |
149 layout->addWidget (pb_viewFg, 0, 3); |
| |
150 |
| |
151 layout->addWidget (lb_lineThickness, 1, 0); |
| |
152 layout->addWidget (sl_lineThickness, 1, 1); |
| |
153 layout->addWidget (lb_viewFgAlpha, 1, 2); |
| |
154 layout->addWidget (sl_viewFgAlpha, 1, 3); |
| |
155 |
| |
156 layout->addWidget (lb_iconSize, 2, 0); |
| |
157 layout->addWidget (sl_iconSize, 2, 1); |
| |
158 |
| |
159 layout->addWidget (cb_colorize, 3, 0, 1, 4); |
| |
160 layout->addWidget (cb_colorBFC, 4, 0, 1, 4); |
| |
161 layout->addWidget (cb_selFlash, 5, 0, 1, 4); |
| |
162 layout->addWidget (cb_blackEdges, 6, 0, 1, 4); |
| |
163 layout->addWidget (cb_schemanticInline, 7, 0, 1, 4); |
| |
164 mainTab->setLayout (layout); |
| |
165 |
| |
166 // Add the tab to the manager |
| |
167 tabs->addTab (mainTab, "Main settings"); |
| |
168 } |
| |
169 |
| |
170 // ============================================================================= |
| |
171 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
172 // ============================================================================= |
| |
173 void ConfigDialog::initShortcutsTab () { |
| |
174 shortcutsTab = new QWidget; |
| |
175 lw_shortcutList = new QListWidget; |
| |
176 lw_shortcutList->setAlternatingRowColors (true); |
| |
177 |
| |
178 shortcutsTab->setWhatsThis ("Here you can alter keyboard shortcuts for " |
| |
179 "almost all LDForge actions. Only exceptions are the controls for the " |
| |
180 "viewport. Use the set button to set a key shortcut, clear to remove it " |
| |
181 "and reset to restore the shortcut to its default value.\n" |
| |
182 "\tShortcut changes apply immediately after closing this dialog." ); |
| |
183 |
| |
184 // Init table items |
| |
185 ulong i = 0; |
| |
186 for (actionmeta& info : g_ActionMeta) { |
| |
187 QAction* const act = *info.qAct; |
| |
188 |
| |
189 ShortcutListItem* item = new ShortcutListItem; |
| |
190 setShortcutText (item, info); |
| |
191 item->setIcon (act->icon ()); |
| |
192 item->setActionInfo (&info); |
| |
193 |
| |
194 // If the action doesn't have a valid icon, use an empty one |
| |
195 // so that the list is kept aligned. |
| |
196 if (act->icon ().isNull ()) |
| |
197 item->setIcon (getIcon ("empty")); |
| |
198 |
| |
199 lw_shortcutList->insertItem (i++, item); |
| |
200 } |
| |
201 |
| |
202 lw_shortcutList->setSortingEnabled (true); |
| |
203 lw_shortcutList->sortItems (); |
| |
204 |
| |
205 pb_setShortcut = new QPushButton ("Set"); |
| |
206 pb_resetShortcut = new QPushButton ("Reset"); |
| |
207 pb_clearShortcut = new QPushButton ("Clear"); |
| |
208 |
| |
209 connect (pb_setShortcut, SIGNAL (clicked ()), this, SLOT (slot_setShortcut ())); |
| |
210 connect (pb_resetShortcut, SIGNAL (clicked ()), this, SLOT (slot_resetShortcut ())); |
| |
211 connect (pb_clearShortcut, SIGNAL (clicked ()), this, SLOT (slot_clearShortcut ())); |
| |
212 |
| |
213 QVBoxLayout* buttonLayout = new QVBoxLayout; |
| |
214 buttonLayout->addWidget (pb_setShortcut); |
| |
215 buttonLayout->addWidget (pb_resetShortcut); |
| |
216 buttonLayout->addWidget (pb_clearShortcut); |
| |
217 buttonLayout->addStretch (10); |
| |
218 |
| |
219 QGridLayout* layout = new QGridLayout; |
| |
220 layout->addWidget (lw_shortcutList, 0, 0); |
| |
221 layout->addLayout (buttonLayout, 0, 1); |
| |
222 shortcutsTab->setLayout (layout); |
| |
223 tabs->addTab (shortcutsTab, "Shortcuts"); |
| |
224 } |
| |
225 |
| |
226 // ============================================================================= |
| |
227 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
228 // ============================================================================= |
| |
229 void ConfigDialog::initQuickColorTab () { |
| |
230 quickColorTab = new QWidget; |
| |
231 |
| |
232 pb_addColor = new QPushButton (getIcon ("palette"), "Add"); |
| |
233 pb_delColor = new QPushButton (getIcon ("delete"), "Remove"); |
| |
234 pb_changeColor = new QPushButton (getIcon ("palette"), "Set"); |
| |
235 pb_addColorSeparator = new QPushButton ("Add Separator"); |
| |
236 pb_moveColorUp = new QPushButton (getIcon ("arrow-up"), "Move Up"); |
| |
237 pb_moveColorDown = new QPushButton (getIcon ("arrow-down"), "Move Down"); |
| |
238 pb_clearColors = new QPushButton (getIcon ("delete-all"), "Clear"); |
| |
239 lw_quickColors = new QListWidget; |
| |
240 |
| |
241 quickColorMeta = parseQuickColorMeta (); |
| |
242 updateQuickColorList (); |
| |
243 |
| |
244 QVBoxLayout* buttonLayout = new QVBoxLayout; |
| |
245 buttonLayout->addWidget (pb_addColor); |
| |
246 buttonLayout->addWidget (pb_delColor); |
| |
247 buttonLayout->addWidget (pb_changeColor); |
| |
248 buttonLayout->addWidget (pb_addColorSeparator); |
| |
249 buttonLayout->addWidget (pb_moveColorUp); |
| |
250 buttonLayout->addWidget (pb_moveColorDown); |
| |
251 buttonLayout->addWidget (pb_clearColors); |
| |
252 buttonLayout->addStretch (1); |
| |
253 |
| |
254 connect (pb_addColor, SIGNAL (clicked ()), this, SLOT (slot_setColor ())); |
| |
255 connect (pb_delColor, SIGNAL (clicked ()), this, SLOT (slot_delColor ())); |
| |
256 connect (pb_changeColor, SIGNAL (clicked ()), this, SLOT (slot_setColor ())); |
| |
257 connect (pb_addColorSeparator, SIGNAL (clicked ()), this, SLOT (slot_addColorSeparator ())); |
| |
258 connect (pb_moveColorUp, SIGNAL (clicked ()), this, SLOT (slot_moveColor ())); |
| |
259 connect (pb_moveColorDown, SIGNAL (clicked ()), this, SLOT (slot_moveColor ())); |
| |
260 connect (pb_clearColors, SIGNAL (clicked ()), this, SLOT (slot_clearColors ())); |
| |
261 |
| |
262 QGridLayout* layout = new QGridLayout; |
| |
263 layout->addWidget (lw_quickColors, 0, 0); |
| |
264 layout->addLayout (buttonLayout, 0, 1); |
| |
265 |
| |
266 quickColorTab->setLayout (layout); |
| |
267 tabs->addTab (quickColorTab, "Quick Colors"); |
| |
268 } |
| |
269 |
| |
270 // ============================================================================= |
| |
271 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
272 // ============================================================================= |
| |
273 void ConfigDialog::initGridTab () { |
| |
274 QWidget* tab = new QWidget; |
| |
275 QGridLayout* layout = new QGridLayout; |
| |
276 QVBoxLayout* l2 = new QVBoxLayout; |
| |
277 |
| |
278 QLabel* xlabel = new QLabel ("X"), |
| |
279 *ylabel = new QLabel ("Y"), |
| |
280 *zlabel = new QLabel ("Z"), |
| |
281 *anglabel = new QLabel ("Angle"); |
| |
282 |
| |
283 short i = 1; |
| |
284 for (QLabel* label : std::initializer_list<QLabel*> ({xlabel, ylabel, zlabel, anglabel})) { |
| |
285 label->setAlignment (Qt::AlignCenter); |
| |
286 layout->addWidget (label, 0, i++); |
| |
287 } |
| |
288 |
| |
289 for (int i = 0; i < g_NumGrids; ++i) { |
| |
290 // Icon |
| |
291 lb_gridIcons[i] = new QLabel; |
| |
292 lb_gridIcons[i]->setPixmap (getIcon (fmt ("grid-%s", str (g_GridInfo[i].name).tolower ().chars ()))); |
| |
293 |
| |
294 // Text label |
| |
295 lb_gridLabels[i] = new QLabel (fmt ("%s:", g_GridInfo[i].name)); |
| |
296 |
| |
297 QHBoxLayout* labellayout = new QHBoxLayout; |
| |
298 labellayout->addWidget (lb_gridIcons[i]); |
| |
299 labellayout->addWidget (lb_gridLabels[i]); |
| |
300 layout->addLayout (labellayout, i + 1, 0); |
| |
301 |
| |
302 // Add the widgets |
| |
303 for (int j = 0; j < 4; ++j) { |
| |
304 dsb_gridData[i][j] = new QDoubleSpinBox; |
| |
305 dsb_gridData[i][j]->setValue (g_GridInfo[i].confs[j]->value); |
| |
306 layout->addWidget (dsb_gridData[i][j], i + 1, j + 1); |
| |
307 } |
| |
308 } |
| |
309 |
| |
310 l2->addLayout (layout); |
| |
311 l2->addStretch (1); |
| |
312 |
| |
313 tab->setLayout (l2); |
| |
314 tabs->addTab (tab, "Grids"); |
| |
315 } |
| |
316 |
| |
317 // ============================================================================= |
| |
318 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
319 // ============================================================================= |
| |
320 extern_cfg (str, prog_ytruder); |
| |
321 extern_cfg (str, prog_rectifier); |
| |
322 extern_cfg (str, prog_intersector); |
| |
323 extern_cfg (str, prog_isecalc); |
| |
324 static const struct extProgInfo { |
| |
325 const char* const name, *iconname; |
| |
326 strconfig* const path; |
| |
327 mutable QLineEdit* input; |
| |
328 mutable QPushButton* setPathButton; |
| |
329 } g_extProgInfo[] = { |
| |
330 { "Ytruder", "ytruder", &prog_ytruder, null, null }, |
| |
331 { "Rectifier", "rectifier", &prog_rectifier, null, null }, |
| |
332 { "Intersector", "intersector", &prog_intersector, null, null }, |
| |
333 { "Isecalc", "isecalc", &prog_isecalc, null, null }, |
| |
334 }; |
| |
335 |
| |
336 void ConfigDialog::initExtProgTab () { |
| |
337 QWidget* tab = new QWidget; |
| |
338 QGridLayout* pathsLayout = new QGridLayout; |
| |
339 QGroupBox* pathsBox = new QGroupBox ("Paths", this); |
| |
340 QVBoxLayout* layout = new QVBoxLayout (this); |
| |
341 |
| |
342 ulong row = 0; |
| |
343 for (const extProgInfo& info : g_extProgInfo) { |
| |
344 QLabel* icon = new QLabel, |
| |
345 *progLabel = new QLabel (info.name); |
| |
346 QLineEdit* input = new QLineEdit; |
| |
347 QPushButton* setPathButton = new QPushButton (); |
| |
348 |
| |
349 icon->setPixmap (getIcon (info.iconname)); |
| |
350 input->setText (info.path->value); |
| |
351 setPathButton->setIcon (getIcon ("folder")); |
| |
352 info.input = input; |
| |
353 info.setPathButton = setPathButton; |
| |
354 |
| |
355 connect (setPathButton, SIGNAL (clicked ()), this, SLOT (slot_setExtProgPath ())); |
| |
356 |
| |
357 pathsLayout->addWidget (icon, row, 0); |
| |
358 pathsLayout->addWidget (progLabel, row, 1); |
| |
359 pathsLayout->addWidget (input, row, 2); |
| |
360 pathsLayout->addWidget (setPathButton, row, 3); |
| |
361 ++row; |
| |
362 } |
| |
363 |
| |
364 pathsBox->setLayout (pathsLayout); |
| |
365 layout->addWidget (pathsBox); |
| |
366 layout->addSpacing (10); |
| |
367 |
| |
368 tab->setLayout (layout); |
| |
369 tabs->addTab (tab, "Ext. Programs"); |
| |
370 } |
| |
371 |
| |
372 // ============================================================================= |
| |
373 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
374 // ============================================================================= |
| |
375 void ConfigDialog::updateQuickColorList (quickColorMetaEntry* pSel) { |
| |
376 for (QListWidgetItem* qItem : quickColorItems) |
| |
377 delete qItem; |
| |
378 |
| |
379 quickColorItems.clear (); |
| |
380 |
| |
381 // Init table items |
| |
382 for (quickColorMetaEntry& entry : quickColorMeta) { |
| |
383 QListWidgetItem* qItem = new QListWidgetItem; |
| |
384 |
| |
385 if (entry.bSeparator) { |
| |
386 qItem->setText ("--------"); |
| |
387 qItem->setIcon (getIcon ("empty")); |
| |
388 } else { |
| |
389 color* col = entry.col; |
| |
390 |
| |
391 if (col == null) { |
| |
392 qItem->setText ("[[unknown color]]"); |
| |
393 qItem->setIcon (getIcon ("error")); |
| |
394 } else { |
| |
395 qItem->setText (col->zName); |
| |
396 qItem->setIcon (getIcon ("palette")); |
| |
397 } |
| |
398 } |
| |
399 |
| |
400 lw_quickColors->addItem (qItem); |
| |
401 quickColorItems.push_back (qItem); |
| |
402 |
| |
403 if (pSel && &entry == pSel) { |
| |
404 lw_quickColors->setCurrentItem (qItem); |
| |
405 lw_quickColors->scrollToItem (qItem); |
| |
406 } |
| |
407 } |
| |
408 } |
| |
409 |
| |
410 // ============================================================================= |
| |
411 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
412 // ============================================================================= |
| |
413 void ConfigDialog::slot_setColor () { |
| |
414 quickColorMetaEntry* entry = null; |
| |
415 QListWidgetItem* item = null; |
| |
416 const bool isNew = static_cast<QPushButton*> (sender ()) == pb_addColor; |
| |
417 |
| |
418 if (isNew == false) { |
| |
419 item = getSelectedQuickColor (); |
| |
420 if (!item) |
| |
421 return; |
| |
422 |
| |
423 ulong ulIdx = getItemRow (item, quickColorItems); |
| |
424 entry = &quickColorMeta[ulIdx]; |
| |
425 |
| |
426 if (entry->bSeparator == true) |
| |
427 return; // don't color separators |
| |
428 } |
| |
429 |
| |
430 short dDefault = entry ? entry->col->index () : -1; |
| |
431 short dValue; |
| |
432 |
| |
433 if (ColorSelectDialog::staticDialog (dValue, dDefault, this) == false) |
| |
434 return; |
| |
435 |
| |
436 if (entry) |
| |
437 entry->col = getColor (dValue); |
| |
438 else { |
| |
439 quickColorMetaEntry entry = {getColor (dValue), null, false}; |
| |
440 |
| |
441 item = getSelectedQuickColor (); |
| |
442 ulong idx; |
| |
443 |
| |
444 if (item) |
| |
445 idx = getItemRow (item, quickColorItems) + 1; |
| |
446 else |
| |
447 idx = quickColorItems.size(); |
| |
448 |
| |
449 quickColorMeta.insert (quickColorMeta.begin() + idx, entry); |
| |
450 entry = quickColorMeta[idx]; |
| |
451 } |
| |
452 |
| |
453 updateQuickColorList (entry); |
| |
454 } |
| |
455 |
| |
456 // ============================================================================= |
| |
457 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
458 // ============================================================================= |
| |
459 void ConfigDialog::slot_delColor () { |
| |
460 if (lw_quickColors->selectedItems().size() == 0) |
| |
461 return; |
| |
462 |
| |
463 QListWidgetItem* qItem = lw_quickColors->selectedItems ()[0]; |
| |
464 ulong ulIdx = getItemRow (qItem, quickColorItems); |
| |
465 quickColorMeta.erase (quickColorMeta.begin () + ulIdx); |
| |
466 updateQuickColorList (); |
| |
467 } |
| |
468 |
| |
469 // ============================================================================= |
| |
470 void ConfigDialog::slot_moveColor () { |
| |
471 const bool bUp = (static_cast<QPushButton*> (sender()) == pb_moveColorUp); |
| |
472 |
| |
473 if (lw_quickColors->selectedItems().size() == 0) |
| |
474 return; |
| |
475 |
| |
476 QListWidgetItem* qItem = lw_quickColors->selectedItems ()[0]; |
| |
477 ulong ulIdx = getItemRow (qItem, quickColorItems); |
| |
478 |
| |
479 long lDest = bUp ? (ulIdx - 1) : (ulIdx + 1); |
| |
480 |
| |
481 if (lDest < 0 || (ulong)lDest >= quickColorItems.size ()) |
| |
482 return; // destination out of bounds |
| |
483 |
| |
484 quickColorMetaEntry tmp = quickColorMeta[lDest]; |
| |
485 quickColorMeta[lDest] = quickColorMeta[ulIdx]; |
| |
486 quickColorMeta[ulIdx] = tmp; |
| |
487 |
| |
488 updateQuickColorList (&quickColorMeta[lDest]); |
| |
489 } |
| |
490 |
| |
491 // ============================================================================= |
| |
492 void ConfigDialog::slot_addColorSeparator() { |
| |
493 quickColorMeta.push_back ({null, null, true}); |
| |
494 updateQuickColorList (&quickColorMeta[quickColorMeta.size () - 1]); |
| |
495 } |
| |
496 |
| |
497 // ============================================================================= |
| |
498 void ConfigDialog::slot_clearColors () { |
| |
499 quickColorMeta.clear (); |
| |
500 updateQuickColorList (); |
| |
501 } |
| |
502 |
| |
503 // ============================================================================= |
| |
504 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
505 // ============================================================================= |
| |
506 void ConfigDialog::makeSlider (QSlider*& slider, short min, short max, short defval) { |
| |
507 slider = new QSlider (Qt::Horizontal); |
| |
508 slider->setRange (min, max); |
| |
509 slider->setSliderPosition (defval); |
| |
510 slider->setTickPosition (QSlider::TicksAbove); |
| |
511 slider->setTickInterval (1); |
| |
512 } |
| |
513 |
| |
514 // ============================================================================= |
| |
515 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
516 // ============================================================================= |
| |
517 ConfigDialog::~ConfigDialog () { |
| |
518 g_ConfigDialog = null; |
| |
519 } |
| |
520 |
| |
521 // ============================================================================= |
| |
522 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
523 // ============================================================================= |
| |
524 void ConfigDialog::pickColor (strconfig& cfg, QPushButton* qButton) { |
| |
525 QColorDialog dlg (QColor (cfg.value.chars())); |
| |
526 dlg.setWindowIcon (getIcon ("colorselect")); |
| |
527 |
| |
528 if (dlg.exec ()) { |
| |
529 uchar r = dlg.currentColor ().red (), |
| |
530 g = dlg.currentColor ().green (), |
| |
531 b = dlg.currentColor ().blue (); |
| |
532 cfg.value.format ("#%.2X%.2X%.2X", r, g, b); |
| |
533 setButtonBackground (qButton, cfg.value); |
| |
534 } |
| |
535 } |
| |
536 |
| |
537 void ConfigDialog::slot_setGLBackground () { |
| |
538 pickColor (gl_bgcolor, pb_viewBg); |
| |
539 } |
| |
540 |
| |
541 void ConfigDialog::slot_setGLForeground () { |
| |
542 pickColor (gl_maincolor, pb_viewFg); |
| |
543 } |
| |
544 |
| |
545 // ============================================================================= |
| |
546 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
547 // ============================================================================= |
| |
548 void ConfigDialog::setButtonBackground (QPushButton* qButton, str zValue) { |
| |
549 qButton->setIcon (getIcon ("colorselect")); |
| |
550 qButton->setAutoFillBackground (true); |
| |
551 qButton->setStyleSheet ( |
| |
552 fmt ("background-color: %s", zValue.chars()).chars() |
| |
553 ); |
| |
554 } |
| |
555 |
| |
556 // ============================================================================= |
| |
557 long ConfigDialog::getItemRow (QListWidgetItem* qItem, std::vector<QListWidgetItem*>& haystack) { |
| |
558 long i = 0; |
| |
559 |
| |
560 for (QListWidgetItem* it : haystack) { |
| |
561 if (it == qItem) |
| |
562 return i; |
| |
563 ++i; |
| |
564 } |
| |
565 |
| |
566 return -1; |
| |
567 } |
| |
568 |
| |
569 // ============================================================================= |
| |
570 QListWidgetItem* ConfigDialog::getSelectedQuickColor () { |
| |
571 if (lw_quickColors->selectedItems().size() == 0) |
| |
572 return null; |
| |
573 |
| |
574 return lw_quickColors->selectedItems ()[0]; |
| |
575 } |
| |
576 |
| |
577 // ============================================================================= |
| |
578 QList<ShortcutListItem*> ConfigDialog::getShortcutSelection () { |
| |
579 QList<ShortcutListItem*> out; |
| |
580 |
| |
581 for (QListWidgetItem* entry : lw_shortcutList->selectedItems ()) |
| |
582 out << static_cast<ShortcutListItem*> (entry); |
| |
583 |
| |
584 return out; |
| |
585 } |
| |
586 |
| |
587 // ============================================================================= |
| |
588 void ConfigDialog::slot_setShortcut () { |
| |
589 QList<ShortcutListItem*> sel = getShortcutSelection (); |
| |
590 |
| |
591 if (sel.size() < 1) |
| |
592 return; |
| |
593 |
| |
594 ShortcutListItem* item = sel[0]; |
| |
595 if (KeySequenceDialog::staticDialog (*(item->getActionInfo ()), this)) |
| |
596 setShortcutText (item, *(item->getActionInfo ())); |
| |
597 } |
| |
598 |
| |
599 // ============================================================================= |
| |
600 void ConfigDialog::slot_resetShortcut () { |
| |
601 QList<ShortcutListItem*> sel = getShortcutSelection (); |
| |
602 |
| |
603 for (ShortcutListItem* item : sel) { |
| |
604 actionmeta* info = item->getActionInfo (); |
| |
605 keyseqconfig* conf = info->conf; |
| |
606 |
| |
607 conf->reset (); |
| |
608 (*info->qAct)->setShortcut (*conf); |
| |
609 |
| |
610 setShortcutText (item, *info); |
| |
611 } |
| |
612 } |
| |
613 |
| |
614 // ============================================================================= |
| |
615 void ConfigDialog::slot_clearShortcut () { |
| |
616 QList<ShortcutListItem*> sel = getShortcutSelection (); |
| |
617 QKeySequence dummy; |
| |
618 |
| |
619 for (ShortcutListItem* item : sel) { |
| |
620 actionmeta* info = item->getActionInfo (); |
| |
621 keyseqconfig* conf = info->conf; |
| |
622 conf->value = dummy; |
| |
623 |
| |
624 (*info->qAct)->setShortcut (*conf); |
| |
625 setShortcutText (item, *info); |
| |
626 } |
| |
627 } |
| |
628 |
| |
629 // ============================================================================= |
| |
630 void ConfigDialog::slot_setExtProgPath () { |
| |
631 const extProgInfo* info = null; |
| |
632 for (const extProgInfo& it : g_extProgInfo) { |
| |
633 if (it.setPathButton == sender ()) { |
| |
634 info = ⁢ |
| |
635 break; |
| |
636 } |
| |
637 } |
| |
638 |
| |
639 assert (info != null); |
| |
640 |
| |
641 str filter; |
| |
642 #ifdef _WIN32 |
| |
643 filter = "Applications (*.exe)(*.exe);;All files (*.*)(*.*)"; |
| |
644 #endif // WIN32 |
| |
645 |
| |
646 str fpath = QFileDialog::getOpenFileName (this, fmt ("Path to %s", info->name), "", filter); |
| |
647 if (!~fpath) |
| |
648 return; |
| |
649 |
| |
650 info->input->setText (fpath); |
| |
651 } |
| |
652 |
| |
653 // ============================================================================= |
| |
654 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
655 // ============================================================================= |
| |
656 void ConfigDialog::setShortcutText (QListWidgetItem* qItem, actionmeta meta) { |
| |
657 QAction* const act = *meta.qAct; |
| |
658 str zLabel = act->iconText (); |
| |
659 str zKeybind = act->shortcut ().toString (); |
| |
660 |
| |
661 qItem->setText (fmt ("%s (%s)", zLabel.chars () ,zKeybind.chars ()).chars()); |
| |
662 } |
| |
663 |
| |
664 // ============================================================================= |
| |
665 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
666 // ============================================================================= |
| |
667 str ConfigDialog::makeColorToolBarString () { |
| |
668 str val; |
| |
669 |
| |
670 for (quickColorMetaEntry entry : quickColorMeta) { |
| |
671 if (~val > 0) |
| |
672 val += ':'; |
| |
673 |
| |
674 if (entry.bSeparator) |
| |
675 val += '|'; |
| |
676 else |
| |
677 val.appendformat ("%d", entry.col->index ()); |
| |
678 } |
| |
679 |
| |
680 return val; |
| |
681 } |
| |
682 |
| |
683 // ============================================================================= |
| |
684 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
685 // ============================================================================= |
| |
686 void ConfigDialog::staticDialog () { |
| |
687 ConfigDialog dlg (g_win); |
| |
688 |
| |
689 if (dlg.exec ()) { |
| |
690 lv_colorize = dlg.cb_colorize->isChecked (); |
| |
691 gl_colorbfc = dlg.cb_colorBFC->isChecked (); |
| |
692 gl_selflash = dlg.cb_selFlash->isChecked (); |
| |
693 edit_schemanticinline = dlg.cb_schemanticInline->isChecked (); |
| |
694 gl_blackedges = dlg.cb_blackEdges->isChecked (); |
| |
695 |
| |
696 gl_maincolor_alpha = ((double)dlg.sl_viewFgAlpha->value ()) / 10.0f; |
| |
697 gl_linethickness = dlg.sl_lineThickness->value (); |
| |
698 gui_toolbar_iconsize = (dlg.sl_iconSize->value () * 4) + 12; |
| |
699 |
| |
700 // Manage the quick color toolbar |
| |
701 g_win->setQuickColorMeta (dlg.quickColorMeta); |
| |
702 gui_colortoolbar = dlg.makeColorToolBarString (); |
| |
703 |
| |
704 // Set the grid settings |
| |
705 for (int i = 0; i < g_NumGrids; ++i) |
| |
706 for (int j = 0; j < 4; ++j) |
| |
707 g_GridInfo[i].confs[j]->value = dlg.dsb_gridData[i][j]->value (); |
| |
708 |
| |
709 // Ext program settings |
| |
710 for (const extProgInfo& info : g_extProgInfo) |
| |
711 *info.path = info.input->text (); |
| |
712 |
| |
713 // Save the config |
| |
714 config::save (); |
| |
715 |
| |
716 // Reload all subfiles as the ldraw path potentially changed. |
| |
717 reloadAllSubfiles (); |
| |
718 |
| |
719 g_win->R ()->setBackground (); |
| |
720 g_win->refresh (); |
| |
721 g_win->updateToolBars (); |
| |
722 } |
| |
723 } |
| |
724 |
| |
725 // ========================================================================================================================= |
| |
726 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
727 // ========================================================================================================================= |
| |
728 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
729 // ========================================================================================================================= |
| |
730 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
731 // ========================================================================================================================= |
| |
732 KeySequenceDialog::KeySequenceDialog (QKeySequence seq, QWidget* parent, |
| |
733 Qt::WindowFlags f) : QDialog (parent, f), seq (seq) |
| |
734 { |
| |
735 lb_output = new QLabel; |
| |
736 IMPLEMENT_DIALOG_BUTTONS |
| |
737 |
| |
738 setWhatsThis ("Into this dialog you can input a key sequence for use as a " |
| |
739 "shortcut in LDForge. Use OK to confirm the new shortcut and Cancel to " |
| |
740 "dismiss."); |
| |
741 |
| |
742 QVBoxLayout* layout = new QVBoxLayout; |
| |
743 layout->addWidget (lb_output); |
| |
744 layout->addWidget (bbx_buttons); |
| |
745 setLayout (layout); |
| |
746 |
| |
747 updateOutput (); |
| |
748 } |
| |
749 |
| |
750 // ============================================================================= |
| |
751 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
752 // ============================================================================= |
| |
753 bool KeySequenceDialog::staticDialog (actionmeta& meta, QWidget* parent) { |
| |
754 KeySequenceDialog dlg (*meta.conf, parent); |
| |
755 |
| |
756 if (dlg.exec () == false) |
| |
757 return false; |
| |
758 |
| |
759 *meta.conf = dlg.seq; |
| |
760 (*meta.qAct)->setShortcut (*meta.conf); |
| |
761 return true; |
| |
762 } |
| |
763 |
| |
764 // ============================================================================= |
| |
765 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
766 // ============================================================================= |
| |
767 void KeySequenceDialog::updateOutput () { |
| |
768 str zShortcut = seq.toString (); |
| |
769 |
| |
770 str zText = fmt ("<center><b>%s</b></center>", zShortcut.chars ()); |
| |
771 |
| |
772 lb_output->setText (zText); |
| |
773 } |
| |
774 |
| |
775 // ============================================================================= |
| |
776 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
| |
777 // ============================================================================= |
| |
778 void KeySequenceDialog::keyPressEvent (QKeyEvent* ev) { |
| |
779 seq = ev->key (); |
| |
780 |
| |
781 switch (seq) { |
| |
782 case Qt::Key_Shift: |
| |
783 case Qt::Key_Control: |
| |
784 case Qt::Key_Alt: |
| |
785 case Qt::Key_Meta: |
| |
786 seq = 0; |
| |
787 break; |
| |
788 |
| |
789 default: |
| |
790 break; |
| |
791 } |
| |
792 |
| |
793 seq = (seq | ev->modifiers ()); |
| |
794 |
| |
795 updateOutput (); |
| |
796 } |