blob: 99124458dbd5c9ce7efe46be483c44574e96fb0f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
6#include <qapplication.h>
7#include <qmainwindow.h>
8#include <qtoolbar.h>
Roman Zippel43bf6122006-06-08 22:12:45 -07009#include <qlayout.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010#include <qvbox.h>
11#include <qsplitter.h>
12#include <qlistview.h>
Roman Zippel43bf6122006-06-08 22:12:45 -070013#include <qtextbrowser.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070014#include <qlineedit.h>
Roman Zippel43bf6122006-06-08 22:12:45 -070015#include <qlabel.h>
16#include <qpushbutton.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070017#include <qmenubar.h>
18#include <qmessagebox.h>
19#include <qaction.h>
20#include <qheader.h>
21#include <qfiledialog.h>
Roman Zippel43bf6122006-06-08 22:12:45 -070022#include <qdragobject.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include <qregexp.h>
24
25#include <stdlib.h>
26
27#include "lkc.h"
28#include "qconf.h"
29
30#include "qconf.moc"
31#include "images.c"
32
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070033#ifdef _
34# undef _
35# define _ qgettext
36#endif
37
Linus Torvalds1da177e2005-04-16 15:20:36 -070038static QApplication *configApp;
Roman Zippel7fc925f2006-06-08 22:12:46 -070039static ConfigSettings *configSettings;
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Karsten Wiese3b354c52006-12-13 00:34:08 -080041QAction *ConfigMainWindow::saveAction;
42
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070043static inline QString qgettext(const char* str)
44{
Roman Zippel43bf6122006-06-08 22:12:45 -070045 return QString::fromLocal8Bit(gettext(str));
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070046}
47
48static inline QString qgettext(const QString& str)
49{
Roman Zippel43bf6122006-06-08 22:12:45 -070050 return QString::fromLocal8Bit(gettext(str.latin1()));
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070051}
52
Linus Torvalds1da177e2005-04-16 15:20:36 -070053/**
54 * Reads a list of integer values from the application settings.
55 */
56QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
57{
58 QValueList<int> result;
59 QStringList entryList = readListEntry(key, ok);
60 if (ok) {
61 QStringList::Iterator it;
62 for (it = entryList.begin(); it != entryList.end(); ++it)
63 result.push_back((*it).toInt());
64 }
65
66 return result;
67}
68
69/**
70 * Writes a list of integer values to the application settings.
71 */
72bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
73{
74 QStringList stringList;
75 QValueList<int>::ConstIterator it;
76
77 for (it = value.begin(); it != value.end(); ++it)
78 stringList.push_back(QString::number(*it));
79 return writeEntry(key, stringList);
80}
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
82
Linus Torvalds1da177e2005-04-16 15:20:36 -070083#if QT_VERSION >= 300
84/*
85 * set the new data
86 * TODO check the value
87 */
88void ConfigItem::okRename(int col)
89{
90 Parent::okRename(col);
91 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
Karsten Wiese49e56462007-02-14 00:32:57 -080092 listView()->updateList(this);
Linus Torvalds1da177e2005-04-16 15:20:36 -070093}
94#endif
95
96/*
97 * update the displayed of a menu entry
98 */
99void ConfigItem::updateMenu(void)
100{
101 ConfigList* list;
102 struct symbol* sym;
103 struct property *prop;
104 QString prompt;
105 int type;
106 tristate expr;
107
108 list = listView();
109 if (goParent) {
110 setPixmap(promptColIdx, list->menuBackPix);
111 prompt = "..";
112 goto set_prompt;
113 }
114
115 sym = menu->sym;
116 prop = menu->prompt;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700117 prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700118
119 if (prop) switch (prop->type) {
120 case P_MENU:
121 if (list->mode == singleMode || list->mode == symbolMode) {
122 /* a menuconfig entry is displayed differently
123 * depending whether it's at the view root or a child.
124 */
125 if (sym && list->rootEntry == menu)
126 break;
127 setPixmap(promptColIdx, list->menuPix);
128 } else {
129 if (sym)
130 break;
131 setPixmap(promptColIdx, 0);
132 }
133 goto set_prompt;
134 case P_COMMENT:
135 setPixmap(promptColIdx, 0);
136 goto set_prompt;
137 default:
138 ;
139 }
140 if (!sym)
141 goto set_prompt;
142
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700143 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144
145 type = sym_get_type(sym);
146 switch (type) {
147 case S_BOOLEAN:
148 case S_TRISTATE:
149 char ch;
150
151 if (!sym_is_changable(sym) && !list->showAll) {
152 setPixmap(promptColIdx, 0);
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700153 setText(noColIdx, QString::null);
154 setText(modColIdx, QString::null);
155 setText(yesColIdx, QString::null);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700156 break;
157 }
158 expr = sym_get_tristate_value(sym);
159 switch (expr) {
160 case yes:
161 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
162 setPixmap(promptColIdx, list->choiceYesPix);
163 else
164 setPixmap(promptColIdx, list->symbolYesPix);
165 setText(yesColIdx, "Y");
166 ch = 'Y';
167 break;
168 case mod:
169 setPixmap(promptColIdx, list->symbolModPix);
170 setText(modColIdx, "M");
171 ch = 'M';
172 break;
173 default:
174 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
175 setPixmap(promptColIdx, list->choiceNoPix);
176 else
177 setPixmap(promptColIdx, list->symbolNoPix);
178 setText(noColIdx, "N");
179 ch = 'N';
180 break;
181 }
182 if (expr != no)
183 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
184 if (expr != mod)
185 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
186 if (expr != yes)
187 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
188
189 setText(dataColIdx, QChar(ch));
190 break;
191 case S_INT:
192 case S_HEX:
193 case S_STRING:
194 const char* data;
195
196 data = sym_get_string_value(sym);
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700197
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198#if QT_VERSION >= 300
199 int i = list->mapIdx(dataColIdx);
200 if (i >= 0)
201 setRenameEnabled(i, TRUE);
202#endif
203 setText(dataColIdx, data);
204 if (type == S_STRING)
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700205 prompt = QString("%1: %2").arg(prompt).arg(data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 else
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700207 prompt = QString("(%2) %1").arg(prompt).arg(data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700208 break;
209 }
210 if (!sym_has_value(sym) && visible)
211 prompt += " (NEW)";
212set_prompt:
213 setText(promptColIdx, prompt);
214}
215
216void ConfigItem::testUpdateMenu(bool v)
217{
218 ConfigItem* i;
219
220 visible = v;
221 if (!menu)
222 return;
223
224 sym_calc_value(menu->sym);
225 if (menu->flags & MENU_CHANGED) {
226 /* the menu entry changed, so update all list items */
227 menu->flags &= ~MENU_CHANGED;
228 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
229 i->updateMenu();
230 } else if (listView()->updateAll)
231 updateMenu();
232}
233
234void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
235{
236 ConfigList* list = listView();
237
238 if (visible) {
239 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
240 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
241 else
242 Parent::paintCell(p, cg, column, width, align);
243 } else
244 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
245}
246
247/*
248 * construct a menu entry
249 */
250void ConfigItem::init(void)
251{
252 if (menu) {
253 ConfigList* list = listView();
254 nextItem = (ConfigItem*)menu->data;
255 menu->data = this;
256
257 if (list->mode != fullMode)
258 setOpen(TRUE);
259 sym_calc_value(menu->sym);
260 }
261 updateMenu();
262}
263
264/*
265 * destruct a menu entry
266 */
267ConfigItem::~ConfigItem(void)
268{
269 if (menu) {
270 ConfigItem** ip = (ConfigItem**)&menu->data;
271 for (; *ip; ip = &(*ip)->nextItem) {
272 if (*ip == this) {
273 *ip = nextItem;
274 break;
275 }
276 }
277 }
278}
279
Roman Zippel43bf6122006-06-08 22:12:45 -0700280ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
281 : Parent(parent)
282{
283 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
284}
285
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286void ConfigLineEdit::show(ConfigItem* i)
287{
288 item = i;
289 if (sym_get_string_value(item->menu->sym))
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700290 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 else
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700292 setText(QString::null);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 Parent::show();
294 setFocus();
295}
296
297void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
298{
299 switch (e->key()) {
300 case Key_Escape:
301 break;
302 case Key_Return:
303 case Key_Enter:
304 sym_set_string_value(item->menu->sym, text().latin1());
305 parent()->updateList(item);
306 break;
307 default:
308 Parent::keyPressEvent(e);
309 return;
310 }
311 e->accept();
312 parent()->list->setFocus();
313 hide();
314}
315
Roman Zippel7fc925f2006-06-08 22:12:46 -0700316ConfigList::ConfigList(ConfigView* p, const char *name)
317 : Parent(p, name),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700318 updateAll(false),
319 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
320 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
321 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
322 showAll(false), showName(false), showRange(false), showData(false),
Roman Zippel7fc925f2006-06-08 22:12:46 -0700323 rootEntry(0), headerPopup(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324{
325 int i;
326
327 setSorting(-1);
328 setRootIsDecorated(TRUE);
329 disabledColorGroup = palette().active();
330 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
331 inactivedColorGroup = palette().active();
332 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
333
334 connect(this, SIGNAL(selectionChanged(void)),
335 SLOT(updateSelection(void)));
336
Roman Zippel7fc925f2006-06-08 22:12:46 -0700337 if (name) {
338 configSettings->beginGroup(name);
339 showAll = configSettings->readBoolEntry("/showAll", false);
340 showName = configSettings->readBoolEntry("/showName", false);
341 showRange = configSettings->readBoolEntry("/showRange", false);
342 showData = configSettings->readBoolEntry("/showData", false);
343 configSettings->endGroup();
344 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 }
346
347 for (i = 0; i < colNr; i++)
348 colMap[i] = colRevMap[i] = -1;
349 addColumn(promptColIdx, "Option");
350
351 reinit();
352}
353
354void ConfigList::reinit(void)
355{
356 removeColumn(dataColIdx);
357 removeColumn(yesColIdx);
358 removeColumn(modColIdx);
359 removeColumn(noColIdx);
360 removeColumn(nameColIdx);
361
362 if (showName)
363 addColumn(nameColIdx, "Name");
364 if (showRange) {
365 addColumn(noColIdx, "N");
366 addColumn(modColIdx, "M");
367 addColumn(yesColIdx, "Y");
368 }
369 if (showData)
370 addColumn(dataColIdx, "Value");
371
372 updateListAll();
373}
374
Roman Zippel7fc925f2006-06-08 22:12:46 -0700375void ConfigList::saveSettings(void)
376{
377 if (name()) {
378 configSettings->beginGroup(name());
379 configSettings->writeEntry("/showName", showName);
380 configSettings->writeEntry("/showRange", showRange);
381 configSettings->writeEntry("/showData", showData);
382 configSettings->writeEntry("/showAll", showAll);
383 configSettings->endGroup();
384 }
385}
386
Roman Zippelb65a47e2006-06-08 22:12:47 -0700387ConfigItem* ConfigList::findConfigItem(struct menu *menu)
388{
389 ConfigItem* item = (ConfigItem*)menu->data;
390
391 for (; item; item = item->nextItem) {
392 if (this == item->listView())
393 break;
394 }
395
396 return item;
397}
398
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399void ConfigList::updateSelection(void)
400{
401 struct menu *menu;
402 enum prop_type type;
403
404 ConfigItem* item = (ConfigItem*)selectedItem();
405 if (!item)
406 return;
407
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408 menu = item->menu;
Roman Zippel43bf6122006-06-08 22:12:45 -0700409 emit menuChanged(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 if (!menu)
411 return;
412 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
413 if (mode == menuMode && type == P_MENU)
414 emit menuSelected(menu);
415}
416
417void ConfigList::updateList(ConfigItem* item)
418{
419 ConfigItem* last = 0;
420
Roman Zippel43bf6122006-06-08 22:12:45 -0700421 if (!rootEntry) {
422 if (mode != listMode)
423 goto update;
424 QListViewItemIterator it(this);
425 ConfigItem* item;
426
427 for (; it.current(); ++it) {
428 item = (ConfigItem*)it.current();
429 if (!item->menu)
430 continue;
431 item->testUpdateMenu(menu_is_visible(item->menu));
432 }
433 return;
434 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435
436 if (rootEntry != &rootmenu && (mode == singleMode ||
437 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
438 item = firstChild();
439 if (!item)
440 item = new ConfigItem(this, 0, true);
441 last = item;
442 }
443 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
444 rootEntry->sym && rootEntry->prompt) {
445 item = last ? last->nextSibling() : firstChild();
446 if (!item)
447 item = new ConfigItem(this, last, rootEntry, true);
448 else
449 item->testUpdateMenu(true);
450
451 updateMenuList(item, rootEntry);
452 triggerUpdate();
453 return;
454 }
455update:
456 updateMenuList(this, rootEntry);
457 triggerUpdate();
458}
459
Linus Torvalds1da177e2005-04-16 15:20:36 -0700460void ConfigList::setValue(ConfigItem* item, tristate val)
461{
462 struct symbol* sym;
463 int type;
464 tristate oldval;
465
466 sym = item->menu ? item->menu->sym : 0;
467 if (!sym)
468 return;
469
470 type = sym_get_type(sym);
471 switch (type) {
472 case S_BOOLEAN:
473 case S_TRISTATE:
474 oldval = sym_get_tristate_value(sym);
475
476 if (!sym_set_tristate_value(sym, val))
477 return;
478 if (oldval == no && item->menu->list)
479 item->setOpen(TRUE);
480 parent()->updateList(item);
481 break;
482 }
483}
484
485void ConfigList::changeValue(ConfigItem* item)
486{
487 struct symbol* sym;
488 struct menu* menu;
489 int type, oldexpr, newexpr;
490
491 menu = item->menu;
492 if (!menu)
493 return;
494 sym = menu->sym;
495 if (!sym) {
496 if (item->menu->list)
497 item->setOpen(!item->isOpen());
498 return;
499 }
500
501 type = sym_get_type(sym);
502 switch (type) {
503 case S_BOOLEAN:
504 case S_TRISTATE:
505 oldexpr = sym_get_tristate_value(sym);
506 newexpr = sym_toggle_tristate_value(sym);
507 if (item->menu->list) {
508 if (oldexpr == newexpr)
509 item->setOpen(!item->isOpen());
510 else if (oldexpr == no)
511 item->setOpen(TRUE);
512 }
513 if (oldexpr != newexpr)
514 parent()->updateList(item);
515 break;
516 case S_INT:
517 case S_HEX:
518 case S_STRING:
519#if QT_VERSION >= 300
520 if (colMap[dataColIdx] >= 0)
521 item->startRename(colMap[dataColIdx]);
522 else
523#endif
524 parent()->lineEdit->show(item);
525 break;
526 }
527}
528
529void ConfigList::setRootMenu(struct menu *menu)
530{
531 enum prop_type type;
532
533 if (rootEntry == menu)
534 return;
535 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
536 if (type != P_MENU)
537 return;
538 updateMenuList(this, 0);
539 rootEntry = menu;
540 updateListAll();
541 setSelected(currentItem(), hasFocus());
Roman Zippelb65a47e2006-06-08 22:12:47 -0700542 ensureItemVisible(currentItem());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543}
544
545void ConfigList::setParentMenu(void)
546{
547 ConfigItem* item;
548 struct menu *oldroot;
549
550 oldroot = rootEntry;
551 if (rootEntry == &rootmenu)
552 return;
553 setRootMenu(menu_get_parent_menu(rootEntry->parent));
554
555 QListViewItemIterator it(this);
556 for (; (item = (ConfigItem*)it.current()); it++) {
557 if (item->menu == oldroot) {
558 setCurrentItem(item);
559 ensureItemVisible(item);
560 break;
561 }
562 }
563}
564
Roman Zippel7fc925f2006-06-08 22:12:46 -0700565/*
566 * update all the children of a menu entry
567 * removes/adds the entries from the parent widget as necessary
568 *
569 * parent: either the menu list widget or a menu entry widget
570 * menu: entry to be updated
571 */
572template <class P>
573void ConfigList::updateMenuList(P* parent, struct menu* menu)
574{
575 struct menu* child;
576 ConfigItem* item;
577 ConfigItem* last;
578 bool visible;
579 enum prop_type type;
580
581 if (!menu) {
582 while ((item = parent->firstChild()))
583 delete item;
584 return;
585 }
586
587 last = parent->firstChild();
588 if (last && !last->goParent)
589 last = 0;
590 for (child = menu->list; child; child = child->next) {
591 item = last ? last->nextSibling() : parent->firstChild();
592 type = child->prompt ? child->prompt->type : P_UNKNOWN;
593
594 switch (mode) {
595 case menuMode:
596 if (!(child->flags & MENU_ROOT))
597 goto hide;
598 break;
599 case symbolMode:
600 if (child->flags & MENU_ROOT)
601 goto hide;
602 break;
603 default:
604 break;
605 }
606
607 visible = menu_is_visible(child);
608 if (showAll || visible) {
609 if (!item || item->menu != child)
610 item = new ConfigItem(parent, last, child, visible);
611 else
612 item->testUpdateMenu(visible);
613
614 if (mode == fullMode || mode == menuMode || type != P_MENU)
615 updateMenuList(item, child);
616 else
617 updateMenuList(item, 0);
618 last = item;
619 continue;
620 }
621 hide:
622 if (item && item->menu == child) {
623 last = parent->firstChild();
624 if (last == item)
625 last = 0;
626 else while (last->nextSibling() != item)
627 last = last->nextSibling();
628 delete item;
629 }
630 }
631}
632
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633void ConfigList::keyPressEvent(QKeyEvent* ev)
634{
635 QListViewItem* i = currentItem();
636 ConfigItem* item;
637 struct menu *menu;
638 enum prop_type type;
639
Roman Zippel43bf6122006-06-08 22:12:45 -0700640 if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700641 emit parentSelected();
642 ev->accept();
643 return;
644 }
645
646 if (!i) {
647 Parent::keyPressEvent(ev);
648 return;
649 }
650 item = (ConfigItem*)i;
651
652 switch (ev->key()) {
653 case Key_Return:
654 case Key_Enter:
655 if (item->goParent) {
656 emit parentSelected();
657 break;
658 }
659 menu = item->menu;
660 if (!menu)
661 break;
662 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
663 if (type == P_MENU && rootEntry != menu &&
664 mode != fullMode && mode != menuMode) {
665 emit menuSelected(menu);
666 break;
667 }
668 case Key_Space:
669 changeValue(item);
670 break;
671 case Key_N:
672 setValue(item, no);
673 break;
674 case Key_M:
675 setValue(item, mod);
676 break;
677 case Key_Y:
678 setValue(item, yes);
679 break;
680 default:
681 Parent::keyPressEvent(ev);
682 return;
683 }
684 ev->accept();
685}
686
687void ConfigList::contentsMousePressEvent(QMouseEvent* e)
688{
689 //QPoint p(contentsToViewport(e->pos()));
690 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
691 Parent::contentsMousePressEvent(e);
692}
693
694void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
695{
696 QPoint p(contentsToViewport(e->pos()));
697 ConfigItem* item = (ConfigItem*)itemAt(p);
698 struct menu *menu;
699 enum prop_type ptype;
700 const QPixmap* pm;
701 int idx, x;
702
703 if (!item)
704 goto skip;
705
706 menu = item->menu;
707 x = header()->offset() + p.x();
708 idx = colRevMap[header()->sectionAt(x)];
709 switch (idx) {
710 case promptColIdx:
711 pm = item->pixmap(promptColIdx);
712 if (pm) {
713 int off = header()->sectionPos(0) + itemMargin() +
714 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
715 if (x >= off && x < off + pm->width()) {
716 if (item->goParent) {
717 emit parentSelected();
718 break;
719 } else if (!menu)
720 break;
721 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
722 if (ptype == P_MENU && rootEntry != menu &&
723 mode != fullMode && mode != menuMode)
724 emit menuSelected(menu);
725 else
726 changeValue(item);
727 }
728 }
729 break;
730 case noColIdx:
731 setValue(item, no);
732 break;
733 case modColIdx:
734 setValue(item, mod);
735 break;
736 case yesColIdx:
737 setValue(item, yes);
738 break;
739 case dataColIdx:
740 changeValue(item);
741 break;
742 }
743
744skip:
745 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
746 Parent::contentsMouseReleaseEvent(e);
747}
748
749void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
750{
751 //QPoint p(contentsToViewport(e->pos()));
752 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
753 Parent::contentsMouseMoveEvent(e);
754}
755
756void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
757{
758 QPoint p(contentsToViewport(e->pos()));
759 ConfigItem* item = (ConfigItem*)itemAt(p);
760 struct menu *menu;
761 enum prop_type ptype;
762
763 if (!item)
764 goto skip;
765 if (item->goParent) {
766 emit parentSelected();
767 goto skip;
768 }
769 menu = item->menu;
770 if (!menu)
771 goto skip;
772 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
773 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
774 emit menuSelected(menu);
775 else if (menu->sym)
776 changeValue(item);
777
778skip:
779 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
780 Parent::contentsMouseDoubleClickEvent(e);
781}
782
783void ConfigList::focusInEvent(QFocusEvent *e)
784{
Roman Zippelb65a47e2006-06-08 22:12:47 -0700785 struct menu *menu = NULL;
786
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 Parent::focusInEvent(e);
788
Roman Zippelb65a47e2006-06-08 22:12:47 -0700789 ConfigItem* item = (ConfigItem *)currentItem();
790 if (item) {
791 setSelected(item, TRUE);
792 menu = item->menu;
793 }
794 emit gotFocus(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795}
796
Roman Zippel7fc925f2006-06-08 22:12:46 -0700797void ConfigList::contextMenuEvent(QContextMenuEvent *e)
798{
799 if (e->y() <= header()->geometry().bottom()) {
800 if (!headerPopup) {
801 QAction *action;
802
803 headerPopup = new QPopupMenu(this);
akpm@osdl.org44ddc4f2006-12-06 20:37:41 -0800804 action = new QAction(NULL, "Show Name", 0, this);
Roman Zippel7fc925f2006-06-08 22:12:46 -0700805 action->setToggleAction(TRUE);
806 connect(action, SIGNAL(toggled(bool)),
807 parent(), SLOT(setShowName(bool)));
808 connect(parent(), SIGNAL(showNameChanged(bool)),
809 action, SLOT(setOn(bool)));
810 action->setOn(showName);
811 action->addTo(headerPopup);
akpm@osdl.org44ddc4f2006-12-06 20:37:41 -0800812 action = new QAction(NULL, "Show Range", 0, this);
Roman Zippel7fc925f2006-06-08 22:12:46 -0700813 action->setToggleAction(TRUE);
814 connect(action, SIGNAL(toggled(bool)),
815 parent(), SLOT(setShowRange(bool)));
816 connect(parent(), SIGNAL(showRangeChanged(bool)),
817 action, SLOT(setOn(bool)));
818 action->setOn(showRange);
819 action->addTo(headerPopup);
akpm@osdl.org44ddc4f2006-12-06 20:37:41 -0800820 action = new QAction(NULL, "Show Data", 0, this);
Roman Zippel7fc925f2006-06-08 22:12:46 -0700821 action->setToggleAction(TRUE);
822 connect(action, SIGNAL(toggled(bool)),
823 parent(), SLOT(setShowData(bool)));
824 connect(parent(), SIGNAL(showDataChanged(bool)),
825 action, SLOT(setOn(bool)));
826 action->setOn(showData);
827 action->addTo(headerPopup);
828 }
829 headerPopup->exec(e->globalPos());
830 e->accept();
831 } else
832 e->ignore();
833}
834
Linus Torvalds1da177e2005-04-16 15:20:36 -0700835ConfigView* ConfigView::viewList;
836
Roman Zippel7fc925f2006-06-08 22:12:46 -0700837ConfigView::ConfigView(QWidget* parent, const char *name)
838 : Parent(parent, name)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700839{
Roman Zippel7fc925f2006-06-08 22:12:46 -0700840 list = new ConfigList(this, name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841 lineEdit = new ConfigLineEdit(this);
842 lineEdit->hide();
843
844 this->nextView = viewList;
845 viewList = this;
846}
847
848ConfigView::~ConfigView(void)
849{
850 ConfigView** vp;
851
852 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
853 if (*vp == this) {
854 *vp = nextView;
855 break;
856 }
857 }
858}
859
Roman Zippel7fc925f2006-06-08 22:12:46 -0700860void ConfigView::setShowAll(bool b)
861{
862 if (list->showAll != b) {
863 list->showAll = b;
864 list->updateListAll();
865 emit showAllChanged(b);
866 }
867}
868
869void ConfigView::setShowName(bool b)
870{
871 if (list->showName != b) {
872 list->showName = b;
873 list->reinit();
874 emit showNameChanged(b);
875 }
876}
877
878void ConfigView::setShowRange(bool b)
879{
880 if (list->showRange != b) {
881 list->showRange = b;
882 list->reinit();
883 emit showRangeChanged(b);
884 }
885}
886
887void ConfigView::setShowData(bool b)
888{
889 if (list->showData != b) {
890 list->showData = b;
891 list->reinit();
892 emit showDataChanged(b);
893 }
894}
895
896void ConfigList::setAllOpen(bool open)
897{
898 QListViewItemIterator it(this);
899
900 for (; it.current(); it++)
901 it.current()->setOpen(open);
902}
903
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904void ConfigView::updateList(ConfigItem* item)
905{
906 ConfigView* v;
907
908 for (v = viewList; v; v = v->nextView)
909 v->list->updateList(item);
910}
911
912void ConfigView::updateListAll(void)
913{
914 ConfigView* v;
915
916 for (v = viewList; v; v = v->nextView)
917 v->list->updateListAll();
918}
919
Roman Zippel43bf6122006-06-08 22:12:45 -0700920ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Roman Zippel6fa1da82007-01-10 23:15:31 -0800921 : Parent(parent, name), menu(0), sym(0)
Roman Zippel43bf6122006-06-08 22:12:45 -0700922{
Roman Zippel7fc925f2006-06-08 22:12:46 -0700923 if (name) {
924 configSettings->beginGroup(name);
925 _showDebug = configSettings->readBoolEntry("/showDebug", false);
926 configSettings->endGroup();
927 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
928 }
929}
930
931void ConfigInfoView::saveSettings(void)
932{
933 if (name()) {
934 configSettings->beginGroup(name());
935 configSettings->writeEntry("/showDebug", showDebug());
936 configSettings->endGroup();
937 }
Roman Zippel43bf6122006-06-08 22:12:45 -0700938}
939
940void ConfigInfoView::setShowDebug(bool b)
941{
942 if (_showDebug != b) {
943 _showDebug = b;
944 if (menu)
945 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -0700946 else if (sym)
947 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -0700948 emit showDebugChanged(b);
949 }
950}
951
952void ConfigInfoView::setInfo(struct menu *m)
953{
Roman Zippelb65a47e2006-06-08 22:12:47 -0700954 if (menu == m)
955 return;
Roman Zippel43bf6122006-06-08 22:12:45 -0700956 menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -0800957 sym = NULL;
958 if (!menu)
Roman Zippel43bf6122006-06-08 22:12:45 -0700959 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -0800960 else
Roman Zippel43bf6122006-06-08 22:12:45 -0700961 menuInfo();
962}
963
964void ConfigInfoView::setSource(const QString& name)
965{
966 const char *p = name.latin1();
967
968 menu = NULL;
Roman Zippelab45d192006-06-08 22:12:47 -0700969 sym = NULL;
Roman Zippel43bf6122006-06-08 22:12:45 -0700970
971 switch (p[0]) {
972 case 'm':
Roman Zippelab45d192006-06-08 22:12:47 -0700973 struct menu *m;
974
975 if (sscanf(p, "m%p", &m) == 1 && menu != m) {
976 menu = m;
Roman Zippel43bf6122006-06-08 22:12:45 -0700977 menuInfo();
Roman Zippelb65a47e2006-06-08 22:12:47 -0700978 emit menuSelected(menu);
Roman Zippelab45d192006-06-08 22:12:47 -0700979 }
980 break;
981 case 's':
982 struct symbol *s;
983
984 if (sscanf(p, "s%p", &s) == 1 && sym != s) {
985 sym = s;
986 symbolInfo();
987 }
Roman Zippel43bf6122006-06-08 22:12:45 -0700988 break;
989 }
990}
991
Roman Zippelab45d192006-06-08 22:12:47 -0700992void ConfigInfoView::symbolInfo(void)
993{
994 QString str;
995
996 str += "<big>Symbol: <b>";
997 str += print_filter(sym->name);
998 str += "</b></big><br><br>value: ";
999 str += print_filter(sym_get_string_value(sym));
1000 str += "<br>visibility: ";
1001 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1002 str += "<br>";
1003 str += debug_info(sym);
1004
1005 setText(str);
1006}
1007
Roman Zippel43bf6122006-06-08 22:12:45 -07001008void ConfigInfoView::menuInfo(void)
1009{
1010 struct symbol* sym;
1011 QString head, debug, help;
1012
1013 sym = menu->sym;
1014 if (sym) {
1015 if (menu->prompt) {
1016 head += "<big><b>";
1017 head += print_filter(_(menu->prompt->text));
1018 head += "</b></big>";
1019 if (sym->name) {
1020 head += " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001021 if (showDebug())
1022 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001023 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001024 if (showDebug())
1025 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001026 head += ")";
1027 }
1028 } else if (sym->name) {
1029 head += "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001030 if (showDebug())
1031 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001032 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001033 if (showDebug())
1034 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001035 head += "</b></big>";
1036 }
1037 head += "<br><br>";
1038
1039 if (showDebug())
1040 debug = debug_info(sym);
1041
1042 help = print_filter(_(sym->help));
1043 } else if (menu->prompt) {
1044 head += "<big><b>";
1045 head += print_filter(_(menu->prompt->text));
1046 head += "</b></big><br><br>";
1047 if (showDebug()) {
1048 if (menu->prompt->visible.expr) {
1049 debug += "&nbsp;&nbsp;dep: ";
1050 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1051 debug += "<br><br>";
1052 }
1053 }
1054 }
1055 if (showDebug())
1056 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1057
1058 setText(head + debug + help);
1059}
1060
1061QString ConfigInfoView::debug_info(struct symbol *sym)
1062{
1063 QString debug;
1064
1065 debug += "type: ";
1066 debug += print_filter(sym_type_name(sym->type));
1067 if (sym_is_choice(sym))
1068 debug += " (choice)";
1069 debug += "<br>";
1070 if (sym->rev_dep.expr) {
1071 debug += "reverse dep: ";
1072 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1073 debug += "<br>";
1074 }
1075 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1076 switch (prop->type) {
1077 case P_PROMPT:
1078 case P_MENU:
Roman Zippelab45d192006-06-08 22:12:47 -07001079 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
Roman Zippel43bf6122006-06-08 22:12:45 -07001080 debug += print_filter(_(prop->text));
Roman Zippelab45d192006-06-08 22:12:47 -07001081 debug += "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001082 break;
1083 case P_DEFAULT:
1084 debug += "default: ";
1085 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1086 debug += "<br>";
1087 break;
1088 case P_CHOICE:
1089 if (sym_is_choice(sym)) {
1090 debug += "choice: ";
1091 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1092 debug += "<br>";
1093 }
1094 break;
1095 case P_SELECT:
1096 debug += "select: ";
1097 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1098 debug += "<br>";
1099 break;
1100 case P_RANGE:
1101 debug += "range: ";
1102 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1103 debug += "<br>";
1104 break;
1105 default:
1106 debug += "unknown property: ";
1107 debug += prop_get_type_name(prop->type);
1108 debug += "<br>";
1109 }
1110 if (prop->visible.expr) {
1111 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1112 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1113 debug += "<br>";
1114 }
1115 }
1116 debug += "<br>";
1117
1118 return debug;
1119}
1120
1121QString ConfigInfoView::print_filter(const QString &str)
1122{
1123 QRegExp re("[<>&\"\\n]");
1124 QString res = str;
1125 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1126 switch (res[i].latin1()) {
1127 case '<':
1128 res.replace(i, 1, "&lt;");
1129 i += 4;
1130 break;
1131 case '>':
1132 res.replace(i, 1, "&gt;");
1133 i += 4;
1134 break;
1135 case '&':
1136 res.replace(i, 1, "&amp;");
1137 i += 5;
1138 break;
1139 case '"':
1140 res.replace(i, 1, "&quot;");
1141 i += 6;
1142 break;
1143 case '\n':
1144 res.replace(i, 1, "<br>");
1145 i += 4;
1146 break;
1147 }
1148 }
1149 return res;
1150}
1151
Roman Zippelab45d192006-06-08 22:12:47 -07001152void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001153{
Roman Zippelab45d192006-06-08 22:12:47 -07001154 QString* text = reinterpret_cast<QString*>(data);
1155 QString str2 = print_filter(str);
1156
1157 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1158 *text += QString().sprintf("<a href=\"s%p\">", sym);
1159 *text += str2;
1160 *text += "</a>";
1161 } else
1162 *text += str2;
Roman Zippel43bf6122006-06-08 22:12:45 -07001163}
1164
Roman Zippel7fc925f2006-06-08 22:12:46 -07001165QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1166{
1167 QPopupMenu* popup = Parent::createPopupMenu(pos);
akpm@osdl.org44ddc4f2006-12-06 20:37:41 -08001168 QAction* action = new QAction(NULL,"Show Debug Info", 0, popup);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001169 action->setToggleAction(TRUE);
1170 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1171 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1172 action->setOn(showDebug());
1173 popup->insertSeparator();
1174 action->addTo(popup);
1175 return popup;
1176}
1177
1178void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1179{
1180 Parent::contentsContextMenuEvent(e);
1181}
1182
1183ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
1184 : Parent(parent, name), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001185{
1186 setCaption("Search Config");
1187
1188 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1189 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1190 layout2->addWidget(new QLabel("Find:", this));
1191 editField = new QLineEdit(this);
1192 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1193 layout2->addWidget(editField);
1194 searchButton = new QPushButton("Search", this);
1195 searchButton->setAutoDefault(FALSE);
1196 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1197 layout2->addWidget(searchButton);
1198 layout1->addLayout(layout2);
1199
Roman Zippel7fc925f2006-06-08 22:12:46 -07001200 split = new QSplitter(this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001201 split->setOrientation(QSplitter::Vertical);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001202 list = new ConfigView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001203 list->list->mode = listMode;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001204 info = new ConfigInfoView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001205 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1206 info, SLOT(setInfo(struct menu *)));
1207 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001208
1209 if (name) {
1210 int x, y, width, height;
1211 bool ok;
1212
1213 configSettings->beginGroup(name);
1214 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1215 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1216 resize(width, height);
1217 x = configSettings->readNumEntry("/window x", 0, &ok);
1218 if (ok)
1219 y = configSettings->readNumEntry("/window y", 0, &ok);
1220 if (ok)
1221 move(x, y);
1222 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1223 if (ok)
1224 split->setSizes(sizes);
1225 configSettings->endGroup();
1226 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1227 }
1228}
1229
1230void ConfigSearchWindow::saveSettings(void)
1231{
1232 if (name()) {
1233 configSettings->beginGroup(name());
1234 configSettings->writeEntry("/window x", pos().x());
1235 configSettings->writeEntry("/window y", pos().y());
1236 configSettings->writeEntry("/window width", size().width());
1237 configSettings->writeEntry("/window height", size().height());
1238 configSettings->writeSizes("/split", split->sizes());
1239 configSettings->endGroup();
1240 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001241}
1242
1243void ConfigSearchWindow::search(void)
1244{
1245 struct symbol **p;
1246 struct property *prop;
1247 ConfigItem *lastItem = NULL;
1248
1249 free(result);
1250 list->list->clear();
Cyrill V. Gorcunov786fb182007-02-14 00:32:59 -08001251 info->clear();
Roman Zippel43bf6122006-06-08 22:12:45 -07001252
1253 result = sym_re_search(editField->text().latin1());
1254 if (!result)
1255 return;
1256 for (p = result; *p; p++) {
1257 for_all_prompts((*p), prop)
1258 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1259 menu_is_visible(prop->menu));
1260 }
1261}
1262
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263/*
1264 * Construct the complete config widget
1265 */
1266ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001267 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268{
1269 QMenuBar* menu;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001270 bool ok;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271 int x, y, width, height;
1272
1273 QWidget *d = configApp->desktop();
1274
Roman Zippel7fc925f2006-06-08 22:12:46 -07001275 width = configSettings->readNumEntry("/window width", d->width() - 64);
1276 height = configSettings->readNumEntry("/window height", d->height() - 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277 resize(width, height);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001278 x = configSettings->readNumEntry("/window x", 0, &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 if (ok)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001280 y = configSettings->readNumEntry("/window y", 0, &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281 if (ok)
1282 move(x, y);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283
1284 split1 = new QSplitter(this);
1285 split1->setOrientation(QSplitter::Horizontal);
1286 setCentralWidget(split1);
1287
Roman Zippel7fc925f2006-06-08 22:12:46 -07001288 menuView = new ConfigView(split1, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289 menuList = menuView->list;
1290
1291 split2 = new QSplitter(split1);
1292 split2->setOrientation(QSplitter::Vertical);
1293
1294 // create config tree
Roman Zippel7fc925f2006-06-08 22:12:46 -07001295 configView = new ConfigView(split2, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296 configList = configView->list;
1297
Roman Zippel7fc925f2006-06-08 22:12:46 -07001298 helpText = new ConfigInfoView(split2, "help");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 helpText->setTextFormat(Qt::RichText);
1300
1301 setTabOrder(configList, helpText);
1302 configList->setFocus();
1303
1304 menu = menuBar();
1305 toolBar = new QToolBar("Tools", this);
1306
1307 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
1308 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1309 backAction->setEnabled(FALSE);
1310 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
1311 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1312 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
1313 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
Karsten Wiese3b354c52006-12-13 00:34:08 -08001314 saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
Karsten Wiese3b354c52006-12-13 00:34:08 -08001316 conf_set_changed_callback(conf_changed);
1317 // Set saveAction's initial state
1318 conf_changed();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
1320 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
Shlomi Fish66e7c722007-02-14 00:32:58 -08001321 QAction *searchAction = new QAction("Find", "&Find", CTRL+Key_F, this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001322 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
1324 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1325 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
1326 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1327 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
1328 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1329
1330 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
1331 showNameAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001332 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1333 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1334 showNameAction->setOn(configView->showName());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
1336 showRangeAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001337 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1338 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339 showRangeAction->setOn(configList->showRange);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
1341 showDataAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001342 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1343 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 showDataAction->setOn(configList->showData);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
1346 showAllAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001347 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1348 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349 showAllAction->setOn(configList->showAll);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
1351 showDebugAction->setToggleAction(TRUE);
Roman Zippel43bf6122006-06-08 22:12:45 -07001352 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1353 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
Roman Zippel7fc925f2006-06-08 22:12:46 -07001354 showDebugAction->setOn(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355
1356 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
1357 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1358 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
1359 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1360
1361 // init tool bar
1362 backAction->addTo(toolBar);
1363 toolBar->addSeparator();
1364 loadAction->addTo(toolBar);
1365 saveAction->addTo(toolBar);
1366 toolBar->addSeparator();
1367 singleViewAction->addTo(toolBar);
1368 splitViewAction->addTo(toolBar);
1369 fullViewAction->addTo(toolBar);
1370
1371 // create config menu
1372 QPopupMenu* config = new QPopupMenu(this);
1373 menu->insertItem("&File", config);
1374 loadAction->addTo(config);
1375 saveAction->addTo(config);
1376 saveAsAction->addTo(config);
1377 config->insertSeparator();
1378 quitAction->addTo(config);
1379
Shlomi Fish66e7c722007-02-14 00:32:58 -08001380 // create edit menu
1381 QPopupMenu* editMenu = new QPopupMenu(this);
1382 menu->insertItem("&Edit", editMenu);
1383 searchAction->addTo(editMenu);
1384
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385 // create options menu
1386 QPopupMenu* optionMenu = new QPopupMenu(this);
1387 menu->insertItem("&Option", optionMenu);
1388 showNameAction->addTo(optionMenu);
1389 showRangeAction->addTo(optionMenu);
1390 showDataAction->addTo(optionMenu);
1391 optionMenu->insertSeparator();
1392 showAllAction->addTo(optionMenu);
1393 showDebugAction->addTo(optionMenu);
1394
1395 // create help menu
1396 QPopupMenu* helpMenu = new QPopupMenu(this);
1397 menu->insertSeparator();
1398 menu->insertItem("&Help", helpMenu);
1399 showIntroAction->addTo(helpMenu);
1400 showAboutAction->addTo(helpMenu);
1401
Roman Zippel43bf6122006-06-08 22:12:45 -07001402 connect(configList, SIGNAL(menuChanged(struct menu *)),
1403 helpText, SLOT(setInfo(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 connect(configList, SIGNAL(menuSelected(struct menu *)),
1405 SLOT(changeMenu(struct menu *)));
1406 connect(configList, SIGNAL(parentSelected()),
1407 SLOT(goBack()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001408 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1409 helpText, SLOT(setInfo(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1411 SLOT(changeMenu(struct menu *)));
1412
Roman Zippelb65a47e2006-06-08 22:12:47 -07001413 connect(configList, SIGNAL(gotFocus(struct menu *)),
1414 helpText, SLOT(setInfo(struct menu *)));
1415 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1416 helpText, SLOT(setInfo(struct menu *)));
1417 connect(menuList, SIGNAL(gotFocus(struct menu *)),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001418 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001419 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1420 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421
Roman Zippel7fc925f2006-06-08 22:12:46 -07001422 QString listMode = configSettings->readEntry("/listMode", "symbol");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 if (listMode == "single")
1424 showSingleView();
1425 else if (listMode == "full")
1426 showFullView();
1427 else /*if (listMode == "split")*/
1428 showSplitView();
1429
1430 // UI setup done, restore splitter positions
Roman Zippel7fc925f2006-06-08 22:12:46 -07001431 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432 if (ok)
1433 split1->setSizes(sizes);
1434
Roman Zippel7fc925f2006-06-08 22:12:46 -07001435 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001436 if (ok)
1437 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001438}
1439
Linus Torvalds1da177e2005-04-16 15:20:36 -07001440void ConfigMainWindow::loadConfig(void)
1441{
1442 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1443 if (s.isNull())
1444 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001445 if (conf_read(QFile::encodeName(s)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1447 ConfigView::updateListAll();
1448}
1449
1450void ConfigMainWindow::saveConfig(void)
1451{
1452 if (conf_write(NULL))
1453 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1454}
1455
1456void ConfigMainWindow::saveConfigAs(void)
1457{
1458 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1459 if (s.isNull())
1460 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001461 if (conf_write(QFile::encodeName(s)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1463}
1464
Roman Zippel43bf6122006-06-08 22:12:45 -07001465void ConfigMainWindow::searchConfig(void)
1466{
1467 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001468 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001469 searchWindow->show();
1470}
1471
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472void ConfigMainWindow::changeMenu(struct menu *menu)
1473{
1474 configList->setRootMenu(menu);
1475 backAction->setEnabled(TRUE);
1476}
1477
Roman Zippelb65a47e2006-06-08 22:12:47 -07001478void ConfigMainWindow::setMenuLink(struct menu *menu)
1479{
1480 struct menu *parent;
1481 ConfigList* list = NULL;
1482 ConfigItem* item;
1483
1484 if (!menu_is_visible(menu) && !configView->showAll())
1485 return;
1486
1487 switch (configList->mode) {
1488 case singleMode:
1489 list = configList;
1490 parent = menu_get_parent_menu(menu);
1491 if (!parent)
1492 return;
1493 list->setRootMenu(parent);
1494 break;
1495 case symbolMode:
1496 if (menu->flags & MENU_ROOT) {
1497 configList->setRootMenu(menu);
1498 configList->clearSelection();
1499 list = menuList;
1500 } else {
1501 list = configList;
1502 parent = menu_get_parent_menu(menu->parent);
1503 if (!parent)
1504 return;
1505 item = menuList->findConfigItem(parent);
1506 if (item) {
1507 menuList->setSelected(item, TRUE);
1508 menuList->ensureItemVisible(item);
1509 }
1510 list->setRootMenu(parent);
1511 }
1512 break;
1513 case fullMode:
1514 list = configList;
1515 break;
1516 }
1517
1518 if (list) {
1519 item = list->findConfigItem(menu);
1520 if (item) {
1521 list->setSelected(item, TRUE);
1522 list->ensureItemVisible(item);
1523 list->setFocus();
1524 }
1525 }
1526}
1527
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528void ConfigMainWindow::listFocusChanged(void)
1529{
Roman Zippelb65a47e2006-06-08 22:12:47 -07001530 if (menuList->mode == menuMode)
1531 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532}
1533
1534void ConfigMainWindow::goBack(void)
1535{
1536 ConfigItem* item;
1537
1538 configList->setParentMenu();
1539 if (configList->rootEntry == &rootmenu)
1540 backAction->setEnabled(FALSE);
1541 item = (ConfigItem*)menuList->selectedItem();
1542 while (item) {
1543 if (item->menu == configList->rootEntry) {
1544 menuList->setSelected(item, TRUE);
1545 break;
1546 }
1547 item = (ConfigItem*)item->parent();
1548 }
1549}
1550
1551void ConfigMainWindow::showSingleView(void)
1552{
1553 menuView->hide();
1554 menuList->setRootMenu(0);
1555 configList->mode = singleMode;
1556 if (configList->rootEntry == &rootmenu)
1557 configList->updateListAll();
1558 else
1559 configList->setRootMenu(&rootmenu);
1560 configList->setAllOpen(TRUE);
1561 configList->setFocus();
1562}
1563
1564void ConfigMainWindow::showSplitView(void)
1565{
1566 configList->mode = symbolMode;
1567 if (configList->rootEntry == &rootmenu)
1568 configList->updateListAll();
1569 else
1570 configList->setRootMenu(&rootmenu);
1571 configList->setAllOpen(TRUE);
1572 configApp->processEvents();
1573 menuList->mode = menuMode;
1574 menuList->setRootMenu(&rootmenu);
1575 menuList->setAllOpen(TRUE);
1576 menuView->show();
1577 menuList->setFocus();
1578}
1579
1580void ConfigMainWindow::showFullView(void)
1581{
1582 menuView->hide();
1583 menuList->setRootMenu(0);
1584 configList->mode = fullMode;
1585 if (configList->rootEntry == &rootmenu)
1586 configList->updateListAll();
1587 else
1588 configList->setRootMenu(&rootmenu);
1589 configList->setAllOpen(FALSE);
1590 configList->setFocus();
1591}
1592
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593/*
1594 * ask for saving configuration before quitting
1595 * TODO ask only when something changed
1596 */
1597void ConfigMainWindow::closeEvent(QCloseEvent* e)
1598{
Karsten Wieseb3214292006-12-13 00:34:06 -08001599 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600 e->accept();
1601 return;
1602 }
1603 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1604 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1605 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1606 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1607 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1608 switch (mb.exec()) {
1609 case QMessageBox::Yes:
1610 conf_write(NULL);
1611 case QMessageBox::No:
1612 e->accept();
1613 break;
1614 case QMessageBox::Cancel:
1615 e->ignore();
1616 break;
1617 }
1618}
1619
1620void ConfigMainWindow::showIntro(void)
1621{
1622 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1623 "For each option, a blank box indicates the feature is disabled, a check\n"
1624 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1625 "as a module. Clicking on the box will cycle through the three states.\n\n"
1626 "If you do not see an option (e.g., a device driver) that you believe\n"
1627 "should be present, try turning on Show All Options under the Options menu.\n"
1628 "Although there is no cross reference yet to help you figure out what other\n"
1629 "options must be enabled to support the option you are interested in, you can\n"
1630 "still view the help of a grayed-out option.\n\n"
1631 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1632 "which you can then match by examining other options.\n\n";
1633
1634 QMessageBox::information(this, "qconf", str);
1635}
1636
1637void ConfigMainWindow::showAbout(void)
1638{
1639 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1640 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1641
1642 QMessageBox::information(this, "qconf", str);
1643}
1644
1645void ConfigMainWindow::saveSettings(void)
1646{
Roman Zippel7fc925f2006-06-08 22:12:46 -07001647 configSettings->writeEntry("/window x", pos().x());
1648 configSettings->writeEntry("/window y", pos().y());
1649 configSettings->writeEntry("/window width", size().width());
1650 configSettings->writeEntry("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651
1652 QString entry;
1653 switch(configList->mode) {
1654 case singleMode :
1655 entry = "single";
1656 break;
1657
1658 case symbolMode :
1659 entry = "split";
1660 break;
1661
1662 case fullMode :
1663 entry = "full";
1664 break;
1665 }
Roman Zippel7fc925f2006-06-08 22:12:46 -07001666 configSettings->writeEntry("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667
Roman Zippel7fc925f2006-06-08 22:12:46 -07001668 configSettings->writeSizes("/split1", split1->sizes());
1669 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001670}
1671
Karsten Wiese3b354c52006-12-13 00:34:08 -08001672void ConfigMainWindow::conf_changed(void)
1673{
1674 if (saveAction)
1675 saveAction->setEnabled(conf_get_changed());
1676}
1677
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678void fixup_rootmenu(struct menu *menu)
1679{
1680 struct menu *child;
1681 static int menu_cnt = 0;
1682
1683 menu->flags |= MENU_ROOT;
1684 for (child = menu->list; child; child = child->next) {
1685 if (child->prompt && child->prompt->type == P_MENU) {
1686 menu_cnt++;
1687 fixup_rootmenu(child);
1688 menu_cnt--;
1689 } else if (!menu_cnt)
1690 fixup_rootmenu(child);
1691 }
1692}
1693
1694static const char *progname;
1695
1696static void usage(void)
1697{
1698 printf("%s <config>\n", progname);
1699 exit(0);
1700}
1701
1702int main(int ac, char** av)
1703{
1704 ConfigMainWindow* v;
1705 const char *name;
1706
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001707 bindtextdomain(PACKAGE, LOCALEDIR);
1708 textdomain(PACKAGE);
1709
Linus Torvalds1da177e2005-04-16 15:20:36 -07001710#ifndef LKC_DIRECT_LINK
1711 kconfig_load();
1712#endif
1713
1714 progname = av[0];
1715 configApp = new QApplication(ac, av);
1716 if (ac > 1 && av[1][0] == '-') {
1717 switch (av[1][1]) {
1718 case 'h':
1719 case '?':
1720 usage();
1721 }
1722 name = av[2];
1723 } else
1724 name = av[1];
1725 if (!name)
1726 usage();
1727
1728 conf_parse(name);
1729 fixup_rootmenu(&rootmenu);
1730 conf_read(NULL);
1731 //zconfdump(stdout);
1732
Roman Zippel7fc925f2006-06-08 22:12:46 -07001733 configSettings = new ConfigSettings();
1734 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001735 v = new ConfigMainWindow();
1736
1737 //zconfdump(stdout);
Roman Zippel43bf6122006-06-08 22:12:45 -07001738 configApp->setMainWidget(v);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1740 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001741 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001742 configApp->exec();
1743
Roman Zippel7fc925f2006-06-08 22:12:46 -07001744 configSettings->endGroup();
1745 delete configSettings;
1746
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 return 0;
1748}