blob: ae6c725464110c67bf1e72325c4f7fa8879b6c94 [file] [log] [blame]
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
Masahiro Yamada238c9b92017-02-11 12:39:54 +09003 * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09004 * Released under the terms of the GNU GPL v2.0.
5 */
6
7#include <qglobal.h>
8
Masahiro Yamada238c9b92017-02-11 12:39:54 +09009#include <QMainWindow>
10#include <QList>
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +090011#include <qtextbrowser.h>
Masahiro Yamada238c9b92017-02-11 12:39:54 +090012#include <QAction>
13#include <QFileDialog>
14#include <QMenu>
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +090015
16#include <qapplication.h>
17#include <qdesktopwidget.h>
18#include <qtoolbar.h>
19#include <qlayout.h>
20#include <qsplitter.h>
21#include <qlineedit.h>
22#include <qlabel.h>
23#include <qpushbutton.h>
24#include <qmenubar.h>
25#include <qmessagebox.h>
26#include <qregexp.h>
27#include <qevent.h>
28
29#include <stdlib.h>
30
31#include "lkc.h"
32#include "qconf.h"
33
34#include "qconf.moc"
35#include "images.c"
36
37#ifdef _
38# undef _
39# define _ qgettext
40#endif
41
42static QApplication *configApp;
43static ConfigSettings *configSettings;
44
Masahiro Yamada238c9b92017-02-11 12:39:54 +090045QAction *ConfigMainWindow::saveAction;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +090046
47static inline QString qgettext(const char* str)
48{
49 return QString::fromLocal8Bit(gettext(str));
50}
51
52static inline QString qgettext(const QString& str)
53{
Masahiro Yamada238c9b92017-02-11 12:39:54 +090054 return QString::fromLocal8Bit(gettext(str.toLatin1()));
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +090055}
56
57ConfigSettings::ConfigSettings()
58 : QSettings("kernel.org", "qconf")
59{
60}
61
62/**
63 * Reads a list of integer values from the application settings.
64 */
Masahiro Yamada238c9b92017-02-11 12:39:54 +090065QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +090066{
Masahiro Yamada238c9b92017-02-11 12:39:54 +090067 QList<int> result;
68
69 if (contains(key))
70 {
71 QStringList entryList = value(key).toStringList();
72 QStringList::Iterator it;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +090073
Masahiro Yamada238c9b92017-02-11 12:39:54 +090074 for (it = entryList.begin(); it != entryList.end(); ++it)
75 result.push_back((*it).toInt());
76
77 *ok = true;
78 }
79 else
80 *ok = false;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +090081
82 return result;
83}
84
85/**
86 * Writes a list of integer values to the application settings.
87 */
Masahiro Yamada238c9b92017-02-11 12:39:54 +090088bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +090089{
90 QStringList stringList;
Masahiro Yamada238c9b92017-02-11 12:39:54 +090091 QList<int>::ConstIterator it;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +090092
93 for (it = value.begin(); it != value.end(); ++it)
94 stringList.push_back(QString::number(*it));
Masahiro Yamada238c9b92017-02-11 12:39:54 +090095 setValue(key, stringList);
96
97 return true;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +090098}
99
100
101/*
102 * set the new data
103 * TODO check the value
104 */
105void ConfigItem::okRename(int col)
106{
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900107}
108
109/*
110 * update the displayed of a menu entry
111 */
112void ConfigItem::updateMenu(void)
113{
114 ConfigList* list;
115 struct symbol* sym;
116 struct property *prop;
117 QString prompt;
118 int type;
119 tristate expr;
120
121 list = listView();
122 if (goParent) {
123 setPixmap(promptColIdx, list->menuBackPix);
124 prompt = "..";
125 goto set_prompt;
126 }
127
128 sym = menu->sym;
129 prop = menu->prompt;
130 prompt = _(menu_get_prompt(menu));
131
132 if (prop) switch (prop->type) {
133 case P_MENU:
134 if (list->mode == singleMode || list->mode == symbolMode) {
135 /* a menuconfig entry is displayed differently
136 * depending whether it's at the view root or a child.
137 */
138 if (sym && list->rootEntry == menu)
139 break;
140 setPixmap(promptColIdx, list->menuPix);
141 } else {
142 if (sym)
143 break;
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900144 setPixmap(promptColIdx, QIcon());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900145 }
146 goto set_prompt;
147 case P_COMMENT:
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900148 setPixmap(promptColIdx, QIcon());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900149 goto set_prompt;
150 default:
151 ;
152 }
153 if (!sym)
154 goto set_prompt;
155
156 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
157
158 type = sym_get_type(sym);
159 switch (type) {
160 case S_BOOLEAN:
161 case S_TRISTATE:
162 char ch;
163
164 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900165 setPixmap(promptColIdx, QIcon());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900166 setText(noColIdx, QString::null);
167 setText(modColIdx, QString::null);
168 setText(yesColIdx, QString::null);
169 break;
170 }
171 expr = sym_get_tristate_value(sym);
172 switch (expr) {
173 case yes:
174 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
175 setPixmap(promptColIdx, list->choiceYesPix);
176 else
177 setPixmap(promptColIdx, list->symbolYesPix);
178 setText(yesColIdx, "Y");
179 ch = 'Y';
180 break;
181 case mod:
182 setPixmap(promptColIdx, list->symbolModPix);
183 setText(modColIdx, "M");
184 ch = 'M';
185 break;
186 default:
187 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
188 setPixmap(promptColIdx, list->choiceNoPix);
189 else
190 setPixmap(promptColIdx, list->symbolNoPix);
191 setText(noColIdx, "N");
192 ch = 'N';
193 break;
194 }
195 if (expr != no)
196 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
197 if (expr != mod)
198 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
199 if (expr != yes)
200 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
201
202 setText(dataColIdx, QChar(ch));
203 break;
204 case S_INT:
205 case S_HEX:
206 case S_STRING:
207 const char* data;
208
209 data = sym_get_string_value(sym);
210
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900211 setText(dataColIdx, data);
212 if (type == S_STRING)
213 prompt = QString("%1: %2").arg(prompt).arg(data);
214 else
215 prompt = QString("(%2) %1").arg(prompt).arg(data);
216 break;
217 }
218 if (!sym_has_value(sym) && visible)
219 prompt += _(" (NEW)");
220set_prompt:
221 setText(promptColIdx, prompt);
222}
223
224void ConfigItem::testUpdateMenu(bool v)
225{
226 ConfigItem* i;
227
228 visible = v;
229 if (!menu)
230 return;
231
232 sym_calc_value(menu->sym);
233 if (menu->flags & MENU_CHANGED) {
234 /* the menu entry changed, so update all list items */
235 menu->flags &= ~MENU_CHANGED;
236 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
237 i->updateMenu();
238 } else if (listView()->updateAll)
239 updateMenu();
240}
241
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900242
243/*
244 * construct a menu entry
245 */
246void ConfigItem::init(void)
247{
248 if (menu) {
249 ConfigList* list = listView();
250 nextItem = (ConfigItem*)menu->data;
251 menu->data = this;
252
253 if (list->mode != fullMode)
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900254 setExpanded(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900255 sym_calc_value(menu->sym);
256 }
257 updateMenu();
258}
259
260/*
261 * destruct a menu entry
262 */
263ConfigItem::~ConfigItem(void)
264{
265 if (menu) {
266 ConfigItem** ip = (ConfigItem**)&menu->data;
267 for (; *ip; ip = &(*ip)->nextItem) {
268 if (*ip == this) {
269 *ip = nextItem;
270 break;
271 }
272 }
273 }
274}
275
276ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
277 : Parent(parent)
278{
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900279 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900280}
281
282void ConfigLineEdit::show(ConfigItem* i)
283{
284 item = i;
285 if (sym_get_string_value(item->menu->sym))
286 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
287 else
288 setText(QString::null);
289 Parent::show();
290 setFocus();
291}
292
293void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
294{
295 switch (e->key()) {
296 case Qt::Key_Escape:
297 break;
298 case Qt::Key_Return:
299 case Qt::Key_Enter:
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900300 sym_set_string_value(item->menu->sym, text().toLatin1());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900301 parent()->updateList(item);
302 break;
303 default:
304 Parent::keyPressEvent(e);
305 return;
306 }
307 e->accept();
308 parent()->list->setFocus();
309 hide();
310}
311
312ConfigList::ConfigList(ConfigView* p, const char *name)
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900313 : Parent(p),
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900314 updateAll(false),
315 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
316 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
317 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900318 showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900319 rootEntry(0), headerPopup(0)
320{
321 int i;
322
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900323 setObjectName(name);
324 setSortingEnabled(false);
325 setRootIsDecorated(true);
326
327 setVerticalScrollMode(ScrollPerPixel);
328 setHorizontalScrollMode(ScrollPerPixel);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900329
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900330 setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value"));
331
332 connect(this, SIGNAL(itemSelectionChanged(void)),
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900333 SLOT(updateSelection(void)));
334
335 if (name) {
336 configSettings->beginGroup(name);
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900337 showName = configSettings->value("/showName", false).toBool();
338 showRange = configSettings->value("/showRange", false).toBool();
339 showData = configSettings->value("/showData", false).toBool();
340 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900341 configSettings->endGroup();
342 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
343 }
344
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900345 addColumn(promptColIdx);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900346
347 reinit();
348}
349
350bool ConfigList::menuSkip(struct menu *menu)
351{
352 if (optMode == normalOpt && menu_is_visible(menu))
353 return false;
354 if (optMode == promptOpt && menu_has_prompt(menu))
355 return false;
356 if (optMode == allOpt)
357 return false;
358 return true;
359}
360
361void ConfigList::reinit(void)
362{
363 removeColumn(dataColIdx);
364 removeColumn(yesColIdx);
365 removeColumn(modColIdx);
366 removeColumn(noColIdx);
367 removeColumn(nameColIdx);
368
369 if (showName)
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900370 addColumn(nameColIdx);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900371 if (showRange) {
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900372 addColumn(noColIdx);
373 addColumn(modColIdx);
374 addColumn(yesColIdx);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900375 }
376 if (showData)
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900377 addColumn(dataColIdx);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900378
379 updateListAll();
380}
381
382void ConfigList::saveSettings(void)
383{
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900384 if (!objectName().isEmpty()) {
385 configSettings->beginGroup(objectName());
386 configSettings->setValue("/showName", showName);
387 configSettings->setValue("/showRange", showRange);
388 configSettings->setValue("/showData", showData);
389 configSettings->setValue("/optionMode", (int)optMode);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900390 configSettings->endGroup();
391 }
392}
393
394ConfigItem* ConfigList::findConfigItem(struct menu *menu)
395{
396 ConfigItem* item = (ConfigItem*)menu->data;
397
398 for (; item; item = item->nextItem) {
399 if (this == item->listView())
400 break;
401 }
402
403 return item;
404}
405
406void ConfigList::updateSelection(void)
407{
408 struct menu *menu;
409 enum prop_type type;
410
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900411 if (selectedItems().count() == 0)
412 return;
413
414 ConfigItem* item = (ConfigItem*)selectedItems().first();
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900415 if (!item)
416 return;
417
418 menu = item->menu;
419 emit menuChanged(menu);
420 if (!menu)
421 return;
422 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
423 if (mode == menuMode && type == P_MENU)
424 emit menuSelected(menu);
425}
426
427void ConfigList::updateList(ConfigItem* item)
428{
429 ConfigItem* last = 0;
430
431 if (!rootEntry) {
432 if (mode != listMode)
433 goto update;
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900434 QTreeWidgetItemIterator it(this);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900435 ConfigItem* item;
436
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900437 while (*it) {
438 item = (ConfigItem*)(*it);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900439 if (!item->menu)
440 continue;
441 item->testUpdateMenu(menu_is_visible(item->menu));
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900442
443 ++it;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900444 }
445 return;
446 }
447
448 if (rootEntry != &rootmenu && (mode == singleMode ||
449 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900450 item = (ConfigItem *)topLevelItem(0);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900451 if (!item)
452 item = new ConfigItem(this, 0, true);
453 last = item;
454 }
455 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
456 rootEntry->sym && rootEntry->prompt) {
457 item = last ? last->nextSibling() : firstChild();
458 if (!item)
459 item = new ConfigItem(this, last, rootEntry, true);
460 else
461 item->testUpdateMenu(true);
462
463 updateMenuList(item, rootEntry);
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900464 update();
465 resizeColumnToContents(0);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900466 return;
467 }
468update:
469 updateMenuList(this, rootEntry);
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900470 update();
471 resizeColumnToContents(0);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900472}
473
474void ConfigList::setValue(ConfigItem* item, tristate val)
475{
476 struct symbol* sym;
477 int type;
478 tristate oldval;
479
480 sym = item->menu ? item->menu->sym : 0;
481 if (!sym)
482 return;
483
484 type = sym_get_type(sym);
485 switch (type) {
486 case S_BOOLEAN:
487 case S_TRISTATE:
488 oldval = sym_get_tristate_value(sym);
489
490 if (!sym_set_tristate_value(sym, val))
491 return;
492 if (oldval == no && item->menu->list)
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900493 item->setExpanded(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900494 parent()->updateList(item);
495 break;
496 }
497}
498
499void ConfigList::changeValue(ConfigItem* item)
500{
501 struct symbol* sym;
502 struct menu* menu;
503 int type, oldexpr, newexpr;
504
505 menu = item->menu;
506 if (!menu)
507 return;
508 sym = menu->sym;
509 if (!sym) {
510 if (item->menu->list)
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900511 item->setExpanded(!item->isExpanded());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900512 return;
513 }
514
515 type = sym_get_type(sym);
516 switch (type) {
517 case S_BOOLEAN:
518 case S_TRISTATE:
519 oldexpr = sym_get_tristate_value(sym);
520 newexpr = sym_toggle_tristate_value(sym);
521 if (item->menu->list) {
522 if (oldexpr == newexpr)
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900523 item->setExpanded(!item->isExpanded());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900524 else if (oldexpr == no)
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900525 item->setExpanded(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900526 }
527 if (oldexpr != newexpr)
528 parent()->updateList(item);
529 break;
530 case S_INT:
531 case S_HEX:
532 case S_STRING:
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900533 parent()->lineEdit->show(item);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900534 break;
535 }
536}
537
538void ConfigList::setRootMenu(struct menu *menu)
539{
540 enum prop_type type;
541
542 if (rootEntry == menu)
543 return;
544 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
545 if (type != P_MENU)
546 return;
547 updateMenuList(this, 0);
548 rootEntry = menu;
549 updateListAll();
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900550 if (currentItem()) {
551 currentItem()->setSelected(hasFocus());
552 scrollToItem(currentItem());
553 }
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900554}
555
556void ConfigList::setParentMenu(void)
557{
558 ConfigItem* item;
559 struct menu *oldroot;
560
561 oldroot = rootEntry;
562 if (rootEntry == &rootmenu)
563 return;
564 setRootMenu(menu_get_parent_menu(rootEntry->parent));
565
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900566 QTreeWidgetItemIterator it(this);
567 while (*it) {
568 item = (ConfigItem *)(*it);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900569 if (item->menu == oldroot) {
570 setCurrentItem(item);
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900571 scrollToItem(item);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900572 break;
573 }
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900574
575 ++it;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900576 }
577}
578
579/*
580 * update all the children of a menu entry
581 * removes/adds the entries from the parent widget as necessary
582 *
583 * parent: either the menu list widget or a menu entry widget
584 * menu: entry to be updated
585 */
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900586void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900587{
588 struct menu* child;
589 ConfigItem* item;
590 ConfigItem* last;
591 bool visible;
592 enum prop_type type;
593
594 if (!menu) {
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900595 while (parent->childCount() > 0)
596 {
597 delete parent->takeChild(0);
598 }
599
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900600 return;
601 }
602
603 last = parent->firstChild();
604 if (last && !last->goParent)
605 last = 0;
606 for (child = menu->list; child; child = child->next) {
607 item = last ? last->nextSibling() : parent->firstChild();
608 type = child->prompt ? child->prompt->type : P_UNKNOWN;
609
610 switch (mode) {
611 case menuMode:
612 if (!(child->flags & MENU_ROOT))
613 goto hide;
614 break;
615 case symbolMode:
616 if (child->flags & MENU_ROOT)
617 goto hide;
618 break;
619 default:
620 break;
621 }
622
623 visible = menu_is_visible(child);
624 if (!menuSkip(child)) {
625 if (!child->sym && !child->list && !child->prompt)
626 continue;
627 if (!item || item->menu != child)
628 item = new ConfigItem(parent, last, child, visible);
629 else
630 item->testUpdateMenu(visible);
631
632 if (mode == fullMode || mode == menuMode || type != P_MENU)
633 updateMenuList(item, child);
634 else
635 updateMenuList(item, 0);
636 last = item;
637 continue;
638 }
639 hide:
640 if (item && item->menu == child) {
641 last = parent->firstChild();
642 if (last == item)
643 last = 0;
644 else while (last->nextSibling() != item)
645 last = last->nextSibling();
646 delete item;
647 }
648 }
649}
650
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900651void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
652{
653 struct menu* child;
654 ConfigItem* item;
655 ConfigItem* last;
656 bool visible;
657 enum prop_type type;
658
659 if (!menu) {
660 while (parent->topLevelItemCount() > 0)
661 {
662 delete parent->takeTopLevelItem(0);
663 }
664
665 return;
666 }
667
668 last = (ConfigItem*)parent->topLevelItem(0);
669 if (last && !last->goParent)
670 last = 0;
671 for (child = menu->list; child; child = child->next) {
672 item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
673 type = child->prompt ? child->prompt->type : P_UNKNOWN;
674
675 switch (mode) {
676 case menuMode:
677 if (!(child->flags & MENU_ROOT))
678 goto hide;
679 break;
680 case symbolMode:
681 if (child->flags & MENU_ROOT)
682 goto hide;
683 break;
684 default:
685 break;
686 }
687
688 visible = menu_is_visible(child);
689 if (!menuSkip(child)) {
690 if (!child->sym && !child->list && !child->prompt)
691 continue;
692 if (!item || item->menu != child)
693 item = new ConfigItem(parent, last, child, visible);
694 else
695 item->testUpdateMenu(visible);
696
697 if (mode == fullMode || mode == menuMode || type != P_MENU)
698 updateMenuList(item, child);
699 else
700 updateMenuList(item, 0);
701 last = item;
702 continue;
703 }
704 hide:
705 if (item && item->menu == child) {
706 last = (ConfigItem*)parent->topLevelItem(0);
707 if (last == item)
708 last = 0;
709 else while (last->nextSibling() != item)
710 last = last->nextSibling();
711 delete item;
712 }
713 }
714}
715
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900716void ConfigList::keyPressEvent(QKeyEvent* ev)
717{
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900718 QTreeWidgetItem* i = currentItem();
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900719 ConfigItem* item;
720 struct menu *menu;
721 enum prop_type type;
722
723 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
724 emit parentSelected();
725 ev->accept();
726 return;
727 }
728
729 if (!i) {
730 Parent::keyPressEvent(ev);
731 return;
732 }
733 item = (ConfigItem*)i;
734
735 switch (ev->key()) {
736 case Qt::Key_Return:
737 case Qt::Key_Enter:
738 if (item->goParent) {
739 emit parentSelected();
740 break;
741 }
742 menu = item->menu;
743 if (!menu)
744 break;
745 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
746 if (type == P_MENU && rootEntry != menu &&
747 mode != fullMode && mode != menuMode) {
748 emit menuSelected(menu);
749 break;
750 }
751 case Qt::Key_Space:
752 changeValue(item);
753 break;
754 case Qt::Key_N:
755 setValue(item, no);
756 break;
757 case Qt::Key_M:
758 setValue(item, mod);
759 break;
760 case Qt::Key_Y:
761 setValue(item, yes);
762 break;
763 default:
764 Parent::keyPressEvent(ev);
765 return;
766 }
767 ev->accept();
768}
769
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900770void ConfigList::mousePressEvent(QMouseEvent* e)
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900771{
772 //QPoint p(contentsToViewport(e->pos()));
773 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900774 Parent::mousePressEvent(e);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900775}
776
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900777void ConfigList::mouseReleaseEvent(QMouseEvent* e)
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900778{
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900779 QPoint p = e->pos();
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900780 ConfigItem* item = (ConfigItem*)itemAt(p);
781 struct menu *menu;
782 enum prop_type ptype;
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900783 QIcon icon;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900784 int idx, x;
785
786 if (!item)
787 goto skip;
788
789 menu = item->menu;
790 x = header()->offset() + p.x();
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900791 idx = header()->logicalIndexAt(x);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900792 switch (idx) {
793 case promptColIdx:
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900794 icon = item->pixmap(promptColIdx);
795 if (!icon.isNull()) {
796 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
797 if (x >= off && x < off + icon.availableSizes().first().width()) {
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900798 if (item->goParent) {
799 emit parentSelected();
800 break;
801 } else if (!menu)
802 break;
803 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
804 if (ptype == P_MENU && rootEntry != menu &&
805 mode != fullMode && mode != menuMode)
806 emit menuSelected(menu);
807 else
808 changeValue(item);
809 }
810 }
811 break;
812 case noColIdx:
813 setValue(item, no);
814 break;
815 case modColIdx:
816 setValue(item, mod);
817 break;
818 case yesColIdx:
819 setValue(item, yes);
820 break;
821 case dataColIdx:
822 changeValue(item);
823 break;
824 }
825
826skip:
827 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900828 Parent::mouseReleaseEvent(e);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900829}
830
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900831void ConfigList::mouseMoveEvent(QMouseEvent* e)
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900832{
833 //QPoint p(contentsToViewport(e->pos()));
834 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900835 Parent::mouseMoveEvent(e);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900836}
837
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900838void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900839{
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900840 QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900841 ConfigItem* item = (ConfigItem*)itemAt(p);
842 struct menu *menu;
843 enum prop_type ptype;
844
845 if (!item)
846 goto skip;
847 if (item->goParent) {
848 emit parentSelected();
849 goto skip;
850 }
851 menu = item->menu;
852 if (!menu)
853 goto skip;
854 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
855 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
856 emit menuSelected(menu);
857 else if (menu->sym)
858 changeValue(item);
859
860skip:
861 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900862 Parent::mouseDoubleClickEvent(e);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900863}
864
865void ConfigList::focusInEvent(QFocusEvent *e)
866{
867 struct menu *menu = NULL;
868
869 Parent::focusInEvent(e);
870
871 ConfigItem* item = (ConfigItem *)currentItem();
872 if (item) {
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900873 item->setSelected(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900874 menu = item->menu;
875 }
876 emit gotFocus(menu);
877}
878
879void ConfigList::contextMenuEvent(QContextMenuEvent *e)
880{
881 if (e->y() <= header()->geometry().bottom()) {
882 if (!headerPopup) {
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900883 QAction *action;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900884
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900885 headerPopup = new QMenu(this);
886 action = new QAction(_("Show Name"), this);
887 action->setCheckable(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900888 connect(action, SIGNAL(toggled(bool)),
889 parent(), SLOT(setShowName(bool)));
890 connect(parent(), SIGNAL(showNameChanged(bool)),
891 action, SLOT(setOn(bool)));
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900892 action->setChecked(showName);
893 headerPopup->addAction(action);
894 action = new QAction(_("Show Range"), this);
895 action->setCheckable(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900896 connect(action, SIGNAL(toggled(bool)),
897 parent(), SLOT(setShowRange(bool)));
898 connect(parent(), SIGNAL(showRangeChanged(bool)),
899 action, SLOT(setOn(bool)));
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900900 action->setChecked(showRange);
901 headerPopup->addAction(action);
902 action = new QAction(_("Show Data"), this);
903 action->setCheckable(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900904 connect(action, SIGNAL(toggled(bool)),
905 parent(), SLOT(setShowData(bool)));
906 connect(parent(), SIGNAL(showDataChanged(bool)),
907 action, SLOT(setOn(bool)));
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900908 action->setChecked(showData);
909 headerPopup->addAction(action);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900910 }
911 headerPopup->exec(e->globalPos());
912 e->accept();
913 } else
914 e->ignore();
915}
916
917ConfigView*ConfigView::viewList;
918QAction *ConfigView::showNormalAction;
919QAction *ConfigView::showAllAction;
920QAction *ConfigView::showPromptAction;
921
922ConfigView::ConfigView(QWidget* parent, const char *name)
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900923 : Parent(parent)
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900924{
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900925 setObjectName(name);
926 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
927 verticalLayout->setContentsMargins(0, 0, 0, 0);
928
929 list = new ConfigList(this);
930 verticalLayout->addWidget(list);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900931 lineEdit = new ConfigLineEdit(this);
932 lineEdit->hide();
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900933 verticalLayout->addWidget(lineEdit);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900934
935 this->nextView = viewList;
936 viewList = this;
937}
938
939ConfigView::~ConfigView(void)
940{
941 ConfigView** vp;
942
943 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
944 if (*vp == this) {
945 *vp = nextView;
946 break;
947 }
948 }
949}
950
951void ConfigView::setOptionMode(QAction *act)
952{
953 if (act == showNormalAction)
954 list->optMode = normalOpt;
955 else if (act == showAllAction)
956 list->optMode = allOpt;
957 else
958 list->optMode = promptOpt;
959
960 list->updateListAll();
961}
962
963void ConfigView::setShowName(bool b)
964{
965 if (list->showName != b) {
966 list->showName = b;
967 list->reinit();
968 emit showNameChanged(b);
969 }
970}
971
972void ConfigView::setShowRange(bool b)
973{
974 if (list->showRange != b) {
975 list->showRange = b;
976 list->reinit();
977 emit showRangeChanged(b);
978 }
979}
980
981void ConfigView::setShowData(bool b)
982{
983 if (list->showData != b) {
984 list->showData = b;
985 list->reinit();
986 emit showDataChanged(b);
987 }
988}
989
990void ConfigList::setAllOpen(bool open)
991{
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900992 QTreeWidgetItemIterator it(this);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900993
Masahiro Yamada238c9b92017-02-11 12:39:54 +0900994 while (*it) {
995 (*it)->setExpanded(open);
996
997 ++it;
998 }
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +0900999}
1000
1001void ConfigView::updateList(ConfigItem* item)
1002{
1003 ConfigView* v;
1004
1005 for (v = viewList; v; v = v->nextView)
1006 v->list->updateList(item);
1007}
1008
1009void ConfigView::updateListAll(void)
1010{
1011 ConfigView* v;
1012
1013 for (v = viewList; v; v = v->nextView)
1014 v->list->updateListAll();
1015}
1016
1017ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001018 : Parent(parent), sym(0), _menu(0)
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001019{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001020 setObjectName(name);
1021
1022
1023 if (!objectName().isEmpty()) {
1024 configSettings->beginGroup(objectName());
1025 setShowDebug(configSettings->value("/showDebug", false).toBool());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001026 configSettings->endGroup();
1027 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1028 }
1029}
1030
1031void ConfigInfoView::saveSettings(void)
1032{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001033 if (!objectName().isEmpty()) {
1034 configSettings->beginGroup(objectName());
1035 configSettings->setValue("/showDebug", showDebug());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001036 configSettings->endGroup();
1037 }
1038}
1039
1040void ConfigInfoView::setShowDebug(bool b)
1041{
1042 if (_showDebug != b) {
1043 _showDebug = b;
1044 if (_menu)
1045 menuInfo();
1046 else if (sym)
1047 symbolInfo();
1048 emit showDebugChanged(b);
1049 }
1050}
1051
1052void ConfigInfoView::setInfo(struct menu *m)
1053{
1054 if (_menu == m)
1055 return;
1056 _menu = m;
1057 sym = NULL;
1058 if (!_menu)
1059 clear();
1060 else
1061 menuInfo();
1062}
1063
1064void ConfigInfoView::symbolInfo(void)
1065{
1066 QString str;
1067
1068 str += "<big>Symbol: <b>";
1069 str += print_filter(sym->name);
1070 str += "</b></big><br><br>value: ";
1071 str += print_filter(sym_get_string_value(sym));
1072 str += "<br>visibility: ";
1073 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1074 str += "<br>";
1075 str += debug_info(sym);
1076
1077 setText(str);
1078}
1079
1080void ConfigInfoView::menuInfo(void)
1081{
1082 struct symbol* sym;
1083 QString head, debug, help;
1084
1085 sym = _menu->sym;
1086 if (sym) {
1087 if (_menu->prompt) {
1088 head += "<big><b>";
1089 head += print_filter(_(_menu->prompt->text));
1090 head += "</b></big>";
1091 if (sym->name) {
1092 head += " (";
1093 if (showDebug())
1094 head += QString().sprintf("<a href=\"s%p\">", sym);
1095 head += print_filter(sym->name);
1096 if (showDebug())
1097 head += "</a>";
1098 head += ")";
1099 }
1100 } else if (sym->name) {
1101 head += "<big><b>";
1102 if (showDebug())
1103 head += QString().sprintf("<a href=\"s%p\">", sym);
1104 head += print_filter(sym->name);
1105 if (showDebug())
1106 head += "</a>";
1107 head += "</b></big>";
1108 }
1109 head += "<br><br>";
1110
1111 if (showDebug())
1112 debug = debug_info(sym);
1113
1114 struct gstr help_gstr = str_new();
1115 menu_get_ext_help(_menu, &help_gstr);
1116 help = print_filter(str_get(&help_gstr));
1117 str_free(&help_gstr);
1118 } else if (_menu->prompt) {
1119 head += "<big><b>";
1120 head += print_filter(_(_menu->prompt->text));
1121 head += "</b></big><br><br>";
1122 if (showDebug()) {
1123 if (_menu->prompt->visible.expr) {
1124 debug += "&nbsp;&nbsp;dep: ";
1125 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1126 debug += "<br><br>";
1127 }
1128 }
1129 }
1130 if (showDebug())
1131 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
1132
1133 setText(head + debug + help);
1134}
1135
1136QString ConfigInfoView::debug_info(struct symbol *sym)
1137{
1138 QString debug;
1139
1140 debug += "type: ";
1141 debug += print_filter(sym_type_name(sym->type));
1142 if (sym_is_choice(sym))
1143 debug += " (choice)";
1144 debug += "<br>";
1145 if (sym->rev_dep.expr) {
1146 debug += "reverse dep: ";
1147 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1148 debug += "<br>";
1149 }
1150 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1151 switch (prop->type) {
1152 case P_PROMPT:
1153 case P_MENU:
1154 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1155 debug += print_filter(_(prop->text));
1156 debug += "</a><br>";
1157 break;
1158 case P_DEFAULT:
1159 case P_SELECT:
1160 case P_RANGE:
1161 case P_ENV:
1162 debug += prop_get_type_name(prop->type);
1163 debug += ": ";
1164 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1165 debug += "<br>";
1166 break;
1167 case P_CHOICE:
1168 if (sym_is_choice(sym)) {
1169 debug += "choice: ";
1170 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1171 debug += "<br>";
1172 }
1173 break;
1174 default:
1175 debug += "unknown property: ";
1176 debug += prop_get_type_name(prop->type);
1177 debug += "<br>";
1178 }
1179 if (prop->visible.expr) {
1180 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1181 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1182 debug += "<br>";
1183 }
1184 }
1185 debug += "<br>";
1186
1187 return debug;
1188}
1189
1190QString ConfigInfoView::print_filter(const QString &str)
1191{
1192 QRegExp re("[<>&\"\\n]");
1193 QString res = str;
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001194 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1195 switch (res[i].toLatin1()) {
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001196 case '<':
1197 res.replace(i, 1, "&lt;");
1198 i += 4;
1199 break;
1200 case '>':
1201 res.replace(i, 1, "&gt;");
1202 i += 4;
1203 break;
1204 case '&':
1205 res.replace(i, 1, "&amp;");
1206 i += 5;
1207 break;
1208 case '"':
1209 res.replace(i, 1, "&quot;");
1210 i += 6;
1211 break;
1212 case '\n':
1213 res.replace(i, 1, "<br>");
1214 i += 4;
1215 break;
1216 }
1217 }
1218 return res;
1219}
1220
1221void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1222{
1223 QString* text = reinterpret_cast<QString*>(data);
1224 QString str2 = print_filter(str);
1225
1226 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1227 *text += QString().sprintf("<a href=\"s%p\">", sym);
1228 *text += str2;
1229 *text += "</a>";
1230 } else
1231 *text += str2;
1232}
1233
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001234QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001235{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001236 QMenu* popup = Parent::createStandardContextMenu(pos);
1237 QAction* action = new QAction(_("Show Debug Info"), popup);
1238 action->setCheckable(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001239 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1240 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001241 action->setChecked(showDebug());
1242 popup->addSeparator();
1243 popup->addAction(action);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001244 return popup;
1245}
1246
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001247void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001248{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001249 Parent::contextMenuEvent(e);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001250}
1251
1252ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001253 : Parent(parent), result(NULL)
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001254{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001255 setObjectName(name);
1256 setWindowTitle("Search Config");
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001257
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001258 QVBoxLayout* layout1 = new QVBoxLayout(this);
1259 layout1->setContentsMargins(11, 11, 11, 11);
1260 layout1->setSpacing(6);
1261 QHBoxLayout* layout2 = new QHBoxLayout(0);
1262 layout2->setContentsMargins(0, 0, 0, 0);
1263 layout2->setSpacing(6);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001264 layout2->addWidget(new QLabel(_("Find:"), this));
1265 editField = new QLineEdit(this);
1266 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1267 layout2->addWidget(editField);
1268 searchButton = new QPushButton(_("Search"), this);
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001269 searchButton->setAutoDefault(false);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001270 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1271 layout2->addWidget(searchButton);
1272 layout1->addLayout(layout2);
1273
1274 split = new QSplitter(this);
1275 split->setOrientation(Qt::Vertical);
1276 list = new ConfigView(split, name);
1277 list->list->mode = listMode;
1278 info = new ConfigInfoView(split, name);
1279 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1280 info, SLOT(setInfo(struct menu *)));
1281 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1282 parent, SLOT(setMenuLink(struct menu *)));
1283
1284 layout1->addWidget(split);
1285
1286 if (name) {
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001287 QVariant x, y;
1288 int width, height;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001289 bool ok;
1290
1291 configSettings->beginGroup(name);
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001292 width = configSettings->value("/window width", parent->width() / 2).toInt();
1293 height = configSettings->value("/window height", parent->height() / 2).toInt();
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001294 resize(width, height);
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001295 x = configSettings->value("/window x");
1296 y = configSettings->value("/window y");
1297 if ((x.isValid())&&(y.isValid()))
1298 move(x.toInt(), y.toInt());
1299 QList<int> sizes = configSettings->readSizes("/split", &ok);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001300 if (ok)
1301 split->setSizes(sizes);
1302 configSettings->endGroup();
1303 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1304 }
1305}
1306
1307void ConfigSearchWindow::saveSettings(void)
1308{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001309 if (!objectName().isEmpty()) {
1310 configSettings->beginGroup(objectName());
1311 configSettings->setValue("/window x", pos().x());
1312 configSettings->setValue("/window y", pos().y());
1313 configSettings->setValue("/window width", size().width());
1314 configSettings->setValue("/window height", size().height());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001315 configSettings->writeSizes("/split", split->sizes());
1316 configSettings->endGroup();
1317 }
1318}
1319
1320void ConfigSearchWindow::search(void)
1321{
1322 struct symbol **p;
1323 struct property *prop;
1324 ConfigItem *lastItem = NULL;
1325
1326 free(result);
1327 list->list->clear();
1328 info->clear();
1329
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001330 result = sym_re_search(editField->text().toLatin1());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001331 if (!result)
1332 return;
1333 for (p = result; *p; p++) {
1334 for_all_prompts((*p), prop)
1335 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1336 menu_is_visible(prop->menu));
1337 }
1338}
1339
1340/*
1341 * Construct the complete config widget
1342 */
1343ConfigMainWindow::ConfigMainWindow(void)
1344 : searchWindow(0)
1345{
1346 QMenuBar* menu;
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001347 bool ok = true;
1348 QVariant x, y;
1349 int width, height;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001350 char title[256];
1351
1352 QDesktopWidget *d = configApp->desktop();
1353 snprintf(title, sizeof(title), "%s%s",
1354 rootmenu.prompt->text,
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001355 ""
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001356 );
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001357 setWindowTitle(title);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001358
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001359 width = configSettings->value("/window width", d->width() - 64).toInt();
1360 height = configSettings->value("/window height", d->height() - 64).toInt();
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001361 resize(width, height);
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001362 x = configSettings->value("/window x");
1363 y = configSettings->value("/window y");
1364 if ((x.isValid())&&(y.isValid()))
1365 move(x.toInt(), y.toInt());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001366
1367 split1 = new QSplitter(this);
1368 split1->setOrientation(Qt::Horizontal);
1369 setCentralWidget(split1);
1370
1371 menuView = new ConfigView(split1, "menu");
1372 menuList = menuView->list;
1373
1374 split2 = new QSplitter(split1);
1375 split2->setOrientation(Qt::Vertical);
1376
1377 // create config tree
1378 configView = new ConfigView(split2, "config");
1379 configList = configView->list;
1380
1381 helpText = new ConfigInfoView(split2, "help");
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001382
1383 setTabOrder(configList, helpText);
1384 configList->setFocus();
1385
1386 menu = menuBar();
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001387 toolBar = new QToolBar("Tools", this);
1388 addToolBar(toolBar);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001389
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001390 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
1391 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
1392 backAction->setEnabled(false);
1393 QAction *quitAction = new QAction(_("&Quit"), this);
1394 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
1395 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
1396 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1397 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
1398 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
1399 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1400 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
1401 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001402 conf_set_changed_callback(conf_changed);
1403 // Set saveAction's initial state
1404 conf_changed();
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001405 QAction *saveAsAction = new QAction(_("Save &As..."), this);
1406 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
1407 QAction *searchAction = new QAction(_("&Find"), this);
1408 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
1409 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
1410 singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
1411 singleViewAction->setCheckable(true);
1412 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
1413 splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
1414 splitViewAction->setCheckable(true);
1415 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
1416 fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
1417 fullViewAction->setCheckable(true);
1418 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001419
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001420 QAction *showNameAction = new QAction(_("Show Name"), this);
1421 showNameAction->setCheckable(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001422 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001423 showNameAction->setChecked(configView->showName());
1424 QAction *showRangeAction = new QAction(_("Show Range"), this);
1425 showRangeAction->setCheckable(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001426 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001427 QAction *showDataAction = new QAction(_("Show Data"), this);
1428 showDataAction->setCheckable(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001429 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001430
1431 QActionGroup *optGroup = new QActionGroup(this);
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001432 optGroup->setExclusive(true);
1433 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001434 SLOT(setOptionMode(QAction *)));
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001435 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001436 SLOT(setOptionMode(QAction *)));
1437
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001438 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1439 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1440 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001441 configView->showNormalAction->setCheckable(true);
1442 configView->showAllAction->setCheckable(true);
1443 configView->showPromptAction->setCheckable(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001444
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001445 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
1446 showDebugAction->setCheckable(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001447 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001448 showDebugAction->setChecked(helpText->showDebug());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001449
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001450 QAction *showIntroAction = new QAction( _("Introduction"), this);
1451 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
1452 QAction *showAboutAction = new QAction( _("About"), this);
1453 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001454
1455 // init tool bar
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001456 toolBar->addAction(backAction);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001457 toolBar->addSeparator();
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001458 toolBar->addAction(loadAction);
1459 toolBar->addAction(saveAction);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001460 toolBar->addSeparator();
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001461 toolBar->addAction(singleViewAction);
1462 toolBar->addAction(splitViewAction);
1463 toolBar->addAction(fullViewAction);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001464
1465 // create config menu
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001466 QMenu* config = menu->addMenu(_("&File"));
1467 config->addAction(loadAction);
1468 config->addAction(saveAction);
1469 config->addAction(saveAsAction);
1470 config->addSeparator();
1471 config->addAction(quitAction);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001472
1473 // create edit menu
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001474 QMenu* editMenu = menu->addMenu(_("&Edit"));
1475 editMenu->addAction(searchAction);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001476
1477 // create options menu
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001478 QMenu* optionMenu = menu->addMenu(_("&Option"));
1479 optionMenu->addAction(showNameAction);
1480 optionMenu->addAction(showRangeAction);
1481 optionMenu->addAction(showDataAction);
1482 optionMenu->addSeparator();
1483 optionMenu->addActions(optGroup->actions());
1484 optionMenu->addSeparator();
1485 optionMenu->addAction(showDebugAction);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001486
1487 // create help menu
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001488 menu->addSeparator();
1489 QMenu* helpMenu = menu->addMenu(_("&Help"));
1490 helpMenu->addAction(showIntroAction);
1491 helpMenu->addAction(showAboutAction);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001492
1493 connect(configList, SIGNAL(menuChanged(struct menu *)),
1494 helpText, SLOT(setInfo(struct menu *)));
1495 connect(configList, SIGNAL(menuSelected(struct menu *)),
1496 SLOT(changeMenu(struct menu *)));
1497 connect(configList, SIGNAL(parentSelected()),
1498 SLOT(goBack()));
1499 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1500 helpText, SLOT(setInfo(struct menu *)));
1501 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1502 SLOT(changeMenu(struct menu *)));
1503
1504 connect(configList, SIGNAL(gotFocus(struct menu *)),
1505 helpText, SLOT(setInfo(struct menu *)));
1506 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1507 helpText, SLOT(setInfo(struct menu *)));
1508 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1509 SLOT(listFocusChanged(void)));
1510 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1511 SLOT(setMenuLink(struct menu *)));
1512
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001513 QString listMode = configSettings->value("/listMode", "symbol").toString();
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001514 if (listMode == "single")
1515 showSingleView();
1516 else if (listMode == "full")
1517 showFullView();
1518 else /*if (listMode == "split")*/
1519 showSplitView();
1520
1521 // UI setup done, restore splitter positions
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001522 QList<int> sizes = configSettings->readSizes("/split1", &ok);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001523 if (ok)
1524 split1->setSizes(sizes);
1525
1526 sizes = configSettings->readSizes("/split2", &ok);
1527 if (ok)
1528 split2->setSizes(sizes);
1529}
1530
1531void ConfigMainWindow::loadConfig(void)
1532{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001533 QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001534 if (s.isNull())
1535 return;
1536 if (conf_read(QFile::encodeName(s)))
1537 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1538 ConfigView::updateListAll();
1539}
1540
1541bool ConfigMainWindow::saveConfig(void)
1542{
1543 if (conf_write(NULL)) {
1544 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1545 return false;
1546 }
1547 return true;
1548}
1549
1550void ConfigMainWindow::saveConfigAs(void)
1551{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001552 QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001553 if (s.isNull())
1554 return;
1555 saveConfig();
1556}
1557
1558void ConfigMainWindow::searchConfig(void)
1559{
1560 if (!searchWindow)
1561 searchWindow = new ConfigSearchWindow(this, "search");
1562 searchWindow->show();
1563}
1564
1565void ConfigMainWindow::changeMenu(struct menu *menu)
1566{
1567 configList->setRootMenu(menu);
1568 if (configList->rootEntry->parent == &rootmenu)
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001569 backAction->setEnabled(false);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001570 else
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001571 backAction->setEnabled(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001572}
1573
1574void ConfigMainWindow::setMenuLink(struct menu *menu)
1575{
1576 struct menu *parent;
1577 ConfigList* list = NULL;
1578 ConfigItem* item;
1579
1580 if (configList->menuSkip(menu))
1581 return;
1582
1583 switch (configList->mode) {
1584 case singleMode:
1585 list = configList;
1586 parent = menu_get_parent_menu(menu);
1587 if (!parent)
1588 return;
1589 list->setRootMenu(parent);
1590 break;
1591 case symbolMode:
1592 if (menu->flags & MENU_ROOT) {
1593 configList->setRootMenu(menu);
1594 configList->clearSelection();
1595 list = menuList;
1596 } else {
1597 list = configList;
1598 parent = menu_get_parent_menu(menu->parent);
1599 if (!parent)
1600 return;
1601 item = menuList->findConfigItem(parent);
1602 if (item) {
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001603 item->setSelected(true);
1604 menuList->scrollToItem(item);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001605 }
1606 list->setRootMenu(parent);
1607 }
1608 break;
1609 case fullMode:
1610 list = configList;
1611 break;
1612 default:
1613 break;
1614 }
1615
1616 if (list) {
1617 item = list->findConfigItem(menu);
1618 if (item) {
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001619 item->setSelected(true);
1620 list->scrollToItem(item);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001621 list->setFocus();
1622 }
1623 }
1624}
1625
1626void ConfigMainWindow::listFocusChanged(void)
1627{
1628 if (menuList->mode == menuMode)
1629 configList->clearSelection();
1630}
1631
1632void ConfigMainWindow::goBack(void)
1633{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001634 ConfigItem* item, *oldSelection;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001635
1636 configList->setParentMenu();
1637 if (configList->rootEntry == &rootmenu)
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001638 backAction->setEnabled(false);
1639
1640 if (menuList->selectedItems().count() == 0)
1641 return;
1642
1643 item = (ConfigItem*)menuList->selectedItems().first();
1644 oldSelection = item;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001645 while (item) {
1646 if (item->menu == configList->rootEntry) {
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001647 oldSelection->setSelected(false);
1648 item->setSelected(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001649 break;
1650 }
1651 item = (ConfigItem*)item->parent();
1652 }
1653}
1654
1655void ConfigMainWindow::showSingleView(void)
1656{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001657 singleViewAction->setEnabled(false);
1658 singleViewAction->setChecked(true);
1659 splitViewAction->setEnabled(true);
1660 splitViewAction->setChecked(false);
1661 fullViewAction->setEnabled(true);
1662 fullViewAction->setChecked(false);
1663
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001664 menuView->hide();
1665 menuList->setRootMenu(0);
1666 configList->mode = singleMode;
1667 if (configList->rootEntry == &rootmenu)
1668 configList->updateListAll();
1669 else
1670 configList->setRootMenu(&rootmenu);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001671 configList->setFocus();
1672}
1673
1674void ConfigMainWindow::showSplitView(void)
1675{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001676 singleViewAction->setEnabled(true);
1677 singleViewAction->setChecked(false);
1678 splitViewAction->setEnabled(false);
1679 splitViewAction->setChecked(true);
1680 fullViewAction->setEnabled(true);
1681 fullViewAction->setChecked(false);
1682
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001683 configList->mode = symbolMode;
1684 if (configList->rootEntry == &rootmenu)
1685 configList->updateListAll();
1686 else
1687 configList->setRootMenu(&rootmenu);
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001688 configList->setAllOpen(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001689 configApp->processEvents();
1690 menuList->mode = menuMode;
1691 menuList->setRootMenu(&rootmenu);
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001692 menuList->setAllOpen(true);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001693 menuView->show();
1694 menuList->setFocus();
1695}
1696
1697void ConfigMainWindow::showFullView(void)
1698{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001699 singleViewAction->setEnabled(true);
1700 singleViewAction->setChecked(false);
1701 splitViewAction->setEnabled(true);
1702 splitViewAction->setChecked(false);
1703 fullViewAction->setEnabled(false);
1704 fullViewAction->setChecked(true);
1705
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001706 menuView->hide();
1707 menuList->setRootMenu(0);
1708 configList->mode = fullMode;
1709 if (configList->rootEntry == &rootmenu)
1710 configList->updateListAll();
1711 else
1712 configList->setRootMenu(&rootmenu);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001713 configList->setFocus();
1714}
1715
1716/*
1717 * ask for saving configuration before quitting
1718 * TODO ask only when something changed
1719 */
1720void ConfigMainWindow::closeEvent(QCloseEvent* e)
1721{
1722 if (!conf_get_changed()) {
1723 e->accept();
1724 return;
1725 }
1726 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1727 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1728 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1729 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1730 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1731 switch (mb.exec()) {
1732 case QMessageBox::Yes:
1733 if (saveConfig())
1734 e->accept();
1735 else
1736 e->ignore();
1737 break;
1738 case QMessageBox::No:
1739 e->accept();
1740 break;
1741 case QMessageBox::Cancel:
1742 e->ignore();
1743 break;
1744 }
1745}
1746
1747void ConfigMainWindow::showIntro(void)
1748{
1749 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
1750 "For each option, a blank box indicates the feature is disabled, a check\n"
1751 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1752 "as a module. Clicking on the box will cycle through the three states.\n\n"
1753 "If you do not see an option (e.g., a device driver) that you believe\n"
1754 "should be present, try turning on Show All Options under the Options menu.\n"
1755 "Although there is no cross reference yet to help you figure out what other\n"
1756 "options must be enabled to support the option you are interested in, you can\n"
1757 "still view the help of a grayed-out option.\n\n"
1758 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1759 "which you can then match by examining other options.\n\n");
1760
1761 QMessageBox::information(this, "qconf", str);
1762}
1763
1764void ConfigMainWindow::showAbout(void)
1765{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001766 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
1767 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001768 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1769
1770 QMessageBox::information(this, "qconf", str);
1771}
1772
1773void ConfigMainWindow::saveSettings(void)
1774{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001775 configSettings->setValue("/window x", pos().x());
1776 configSettings->setValue("/window y", pos().y());
1777 configSettings->setValue("/window width", size().width());
1778 configSettings->setValue("/window height", size().height());
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001779
1780 QString entry;
1781 switch(configList->mode) {
1782 case singleMode :
1783 entry = "single";
1784 break;
1785
1786 case symbolMode :
1787 entry = "split";
1788 break;
1789
1790 case fullMode :
1791 entry = "full";
1792 break;
1793
1794 default:
1795 break;
1796 }
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001797 configSettings->setValue("/listMode", entry);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001798
1799 configSettings->writeSizes("/split1", split1->sizes());
1800 configSettings->writeSizes("/split2", split2->sizes());
1801}
1802
1803void ConfigMainWindow::conf_changed(void)
1804{
1805 if (saveAction)
1806 saveAction->setEnabled(conf_get_changed());
1807}
1808
1809void fixup_rootmenu(struct menu *menu)
1810{
1811 struct menu *child;
1812 static int menu_cnt = 0;
1813
1814 menu->flags |= MENU_ROOT;
1815 for (child = menu->list; child; child = child->next) {
1816 if (child->prompt && child->prompt->type == P_MENU) {
1817 menu_cnt++;
1818 fixup_rootmenu(child);
1819 menu_cnt--;
1820 } else if (!menu_cnt)
1821 fixup_rootmenu(child);
1822 }
1823}
1824
1825static const char *progname;
1826
1827static void usage(void)
1828{
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001829 printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001830 exit(0);
1831}
1832
1833int main(int ac, char** av)
1834{
1835 ConfigMainWindow* v;
1836 const char *name;
1837
1838 bindtextdomain(PACKAGE, LOCALEDIR);
1839 textdomain(PACKAGE);
1840
1841 progname = av[0];
1842 configApp = new QApplication(ac, av);
1843 if (ac > 1 && av[1][0] == '-') {
1844 switch (av[1][1]) {
Masahiro Yamada331cec32015-07-05 01:56:54 +09001845 case 's':
1846 conf_set_message_callback(NULL);
1847 break;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001848 case 'h':
1849 case '?':
1850 usage();
1851 }
1852 name = av[2];
1853 } else
1854 name = av[1];
1855 if (!name)
1856 usage();
1857
1858 conf_parse(name);
1859 fixup_rootmenu(&rootmenu);
1860 conf_read(NULL);
1861 //zconfdump(stdout);
1862
1863 configSettings = new ConfigSettings();
1864 configSettings->beginGroup("/kconfig/qconf");
1865 v = new ConfigMainWindow();
1866
1867 //zconfdump(stdout);
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001868 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1869 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1870 v->show();
1871 configApp->exec();
1872
1873 configSettings->endGroup();
1874 delete configSettings;
Masahiro Yamada238c9b92017-02-11 12:39:54 +09001875 delete v;
1876 delete configApp;
Masahiro Yamadaed16f5a2014-07-30 14:08:13 +09001877
1878 return 0;
1879}