blob: e4eeb59a8c24aae7065144f1618220d2f22b8cec [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) {
Cyrill V. Gorcunoved8b4d42007-02-14 00:33:03 -0800609 if (!child->sym && !child->list && !child->prompt)
610 continue;
Roman Zippel7fc925f2006-06-08 22:12:46 -0700611 if (!item || item->menu != child)
612 item = new ConfigItem(parent, last, child, visible);
613 else
614 item->testUpdateMenu(visible);
615
616 if (mode == fullMode || mode == menuMode || type != P_MENU)
617 updateMenuList(item, child);
618 else
619 updateMenuList(item, 0);
620 last = item;
621 continue;
622 }
623 hide:
624 if (item && item->menu == child) {
625 last = parent->firstChild();
626 if (last == item)
627 last = 0;
628 else while (last->nextSibling() != item)
629 last = last->nextSibling();
630 delete item;
631 }
632 }
633}
634
Linus Torvalds1da177e2005-04-16 15:20:36 -0700635void ConfigList::keyPressEvent(QKeyEvent* ev)
636{
637 QListViewItem* i = currentItem();
638 ConfigItem* item;
639 struct menu *menu;
640 enum prop_type type;
641
Roman Zippel43bf6122006-06-08 22:12:45 -0700642 if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 emit parentSelected();
644 ev->accept();
645 return;
646 }
647
648 if (!i) {
649 Parent::keyPressEvent(ev);
650 return;
651 }
652 item = (ConfigItem*)i;
653
654 switch (ev->key()) {
655 case Key_Return:
656 case Key_Enter:
657 if (item->goParent) {
658 emit parentSelected();
659 break;
660 }
661 menu = item->menu;
662 if (!menu)
663 break;
664 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
665 if (type == P_MENU && rootEntry != menu &&
666 mode != fullMode && mode != menuMode) {
667 emit menuSelected(menu);
668 break;
669 }
670 case Key_Space:
671 changeValue(item);
672 break;
673 case Key_N:
674 setValue(item, no);
675 break;
676 case Key_M:
677 setValue(item, mod);
678 break;
679 case Key_Y:
680 setValue(item, yes);
681 break;
682 default:
683 Parent::keyPressEvent(ev);
684 return;
685 }
686 ev->accept();
687}
688
689void ConfigList::contentsMousePressEvent(QMouseEvent* e)
690{
691 //QPoint p(contentsToViewport(e->pos()));
692 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
693 Parent::contentsMousePressEvent(e);
694}
695
696void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
697{
698 QPoint p(contentsToViewport(e->pos()));
699 ConfigItem* item = (ConfigItem*)itemAt(p);
700 struct menu *menu;
701 enum prop_type ptype;
702 const QPixmap* pm;
703 int idx, x;
704
705 if (!item)
706 goto skip;
707
708 menu = item->menu;
709 x = header()->offset() + p.x();
710 idx = colRevMap[header()->sectionAt(x)];
711 switch (idx) {
712 case promptColIdx:
713 pm = item->pixmap(promptColIdx);
714 if (pm) {
715 int off = header()->sectionPos(0) + itemMargin() +
716 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
717 if (x >= off && x < off + pm->width()) {
718 if (item->goParent) {
719 emit parentSelected();
720 break;
721 } else if (!menu)
722 break;
723 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
724 if (ptype == P_MENU && rootEntry != menu &&
725 mode != fullMode && mode != menuMode)
726 emit menuSelected(menu);
727 else
728 changeValue(item);
729 }
730 }
731 break;
732 case noColIdx:
733 setValue(item, no);
734 break;
735 case modColIdx:
736 setValue(item, mod);
737 break;
738 case yesColIdx:
739 setValue(item, yes);
740 break;
741 case dataColIdx:
742 changeValue(item);
743 break;
744 }
745
746skip:
747 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
748 Parent::contentsMouseReleaseEvent(e);
749}
750
751void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
752{
753 //QPoint p(contentsToViewport(e->pos()));
754 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
755 Parent::contentsMouseMoveEvent(e);
756}
757
758void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
759{
760 QPoint p(contentsToViewport(e->pos()));
761 ConfigItem* item = (ConfigItem*)itemAt(p);
762 struct menu *menu;
763 enum prop_type ptype;
764
765 if (!item)
766 goto skip;
767 if (item->goParent) {
768 emit parentSelected();
769 goto skip;
770 }
771 menu = item->menu;
772 if (!menu)
773 goto skip;
774 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
775 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
776 emit menuSelected(menu);
777 else if (menu->sym)
778 changeValue(item);
779
780skip:
781 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
782 Parent::contentsMouseDoubleClickEvent(e);
783}
784
785void ConfigList::focusInEvent(QFocusEvent *e)
786{
Roman Zippelb65a47e2006-06-08 22:12:47 -0700787 struct menu *menu = NULL;
788
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 Parent::focusInEvent(e);
790
Roman Zippelb65a47e2006-06-08 22:12:47 -0700791 ConfigItem* item = (ConfigItem *)currentItem();
792 if (item) {
793 setSelected(item, TRUE);
794 menu = item->menu;
795 }
796 emit gotFocus(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700797}
798
Roman Zippel7fc925f2006-06-08 22:12:46 -0700799void ConfigList::contextMenuEvent(QContextMenuEvent *e)
800{
801 if (e->y() <= header()->geometry().bottom()) {
802 if (!headerPopup) {
803 QAction *action;
804
805 headerPopup = new QPopupMenu(this);
akpm@osdl.org44ddc4f2006-12-06 20:37:41 -0800806 action = new QAction(NULL, "Show Name", 0, this);
Roman Zippel7fc925f2006-06-08 22:12:46 -0700807 action->setToggleAction(TRUE);
808 connect(action, SIGNAL(toggled(bool)),
809 parent(), SLOT(setShowName(bool)));
810 connect(parent(), SIGNAL(showNameChanged(bool)),
811 action, SLOT(setOn(bool)));
812 action->setOn(showName);
813 action->addTo(headerPopup);
akpm@osdl.org44ddc4f2006-12-06 20:37:41 -0800814 action = new QAction(NULL, "Show Range", 0, this);
Roman Zippel7fc925f2006-06-08 22:12:46 -0700815 action->setToggleAction(TRUE);
816 connect(action, SIGNAL(toggled(bool)),
817 parent(), SLOT(setShowRange(bool)));
818 connect(parent(), SIGNAL(showRangeChanged(bool)),
819 action, SLOT(setOn(bool)));
820 action->setOn(showRange);
821 action->addTo(headerPopup);
akpm@osdl.org44ddc4f2006-12-06 20:37:41 -0800822 action = new QAction(NULL, "Show Data", 0, this);
Roman Zippel7fc925f2006-06-08 22:12:46 -0700823 action->setToggleAction(TRUE);
824 connect(action, SIGNAL(toggled(bool)),
825 parent(), SLOT(setShowData(bool)));
826 connect(parent(), SIGNAL(showDataChanged(bool)),
827 action, SLOT(setOn(bool)));
828 action->setOn(showData);
829 action->addTo(headerPopup);
830 }
831 headerPopup->exec(e->globalPos());
832 e->accept();
833 } else
834 e->ignore();
835}
836
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837ConfigView* ConfigView::viewList;
838
Roman Zippel7fc925f2006-06-08 22:12:46 -0700839ConfigView::ConfigView(QWidget* parent, const char *name)
840 : Parent(parent, name)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700841{
Roman Zippel7fc925f2006-06-08 22:12:46 -0700842 list = new ConfigList(this, name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700843 lineEdit = new ConfigLineEdit(this);
844 lineEdit->hide();
845
846 this->nextView = viewList;
847 viewList = this;
848}
849
850ConfigView::~ConfigView(void)
851{
852 ConfigView** vp;
853
854 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
855 if (*vp == this) {
856 *vp = nextView;
857 break;
858 }
859 }
860}
861
Roman Zippel7fc925f2006-06-08 22:12:46 -0700862void ConfigView::setShowAll(bool b)
863{
864 if (list->showAll != b) {
865 list->showAll = b;
866 list->updateListAll();
867 emit showAllChanged(b);
868 }
869}
870
871void ConfigView::setShowName(bool b)
872{
873 if (list->showName != b) {
874 list->showName = b;
875 list->reinit();
876 emit showNameChanged(b);
877 }
878}
879
880void ConfigView::setShowRange(bool b)
881{
882 if (list->showRange != b) {
883 list->showRange = b;
884 list->reinit();
885 emit showRangeChanged(b);
886 }
887}
888
889void ConfigView::setShowData(bool b)
890{
891 if (list->showData != b) {
892 list->showData = b;
893 list->reinit();
894 emit showDataChanged(b);
895 }
896}
897
898void ConfigList::setAllOpen(bool open)
899{
900 QListViewItemIterator it(this);
901
902 for (; it.current(); it++)
903 it.current()->setOpen(open);
904}
905
Linus Torvalds1da177e2005-04-16 15:20:36 -0700906void ConfigView::updateList(ConfigItem* item)
907{
908 ConfigView* v;
909
910 for (v = viewList; v; v = v->nextView)
911 v->list->updateList(item);
912}
913
914void ConfigView::updateListAll(void)
915{
916 ConfigView* v;
917
918 for (v = viewList; v; v = v->nextView)
919 v->list->updateListAll();
920}
921
Roman Zippel43bf6122006-06-08 22:12:45 -0700922ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
Roman Zippel6fa1da82007-01-10 23:15:31 -0800923 : Parent(parent, name), menu(0), sym(0)
Roman Zippel43bf6122006-06-08 22:12:45 -0700924{
Roman Zippel7fc925f2006-06-08 22:12:46 -0700925 if (name) {
926 configSettings->beginGroup(name);
927 _showDebug = configSettings->readBoolEntry("/showDebug", false);
928 configSettings->endGroup();
929 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
930 }
931}
932
933void ConfigInfoView::saveSettings(void)
934{
935 if (name()) {
936 configSettings->beginGroup(name());
937 configSettings->writeEntry("/showDebug", showDebug());
938 configSettings->endGroup();
939 }
Roman Zippel43bf6122006-06-08 22:12:45 -0700940}
941
942void ConfigInfoView::setShowDebug(bool b)
943{
944 if (_showDebug != b) {
945 _showDebug = b;
946 if (menu)
947 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -0700948 else if (sym)
949 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -0700950 emit showDebugChanged(b);
951 }
952}
953
954void ConfigInfoView::setInfo(struct menu *m)
955{
Roman Zippelb65a47e2006-06-08 22:12:47 -0700956 if (menu == m)
957 return;
Roman Zippel43bf6122006-06-08 22:12:45 -0700958 menu = m;
Roman Zippel6fa1da82007-01-10 23:15:31 -0800959 sym = NULL;
960 if (!menu)
Roman Zippel43bf6122006-06-08 22:12:45 -0700961 clear();
Roman Zippel6fa1da82007-01-10 23:15:31 -0800962 else
Roman Zippel43bf6122006-06-08 22:12:45 -0700963 menuInfo();
964}
965
966void ConfigInfoView::setSource(const QString& name)
967{
968 const char *p = name.latin1();
969
970 menu = NULL;
Roman Zippelab45d192006-06-08 22:12:47 -0700971 sym = NULL;
Roman Zippel43bf6122006-06-08 22:12:45 -0700972
973 switch (p[0]) {
974 case 'm':
Roman Zippelab45d192006-06-08 22:12:47 -0700975 struct menu *m;
976
977 if (sscanf(p, "m%p", &m) == 1 && menu != m) {
978 menu = m;
Roman Zippel43bf6122006-06-08 22:12:45 -0700979 menuInfo();
Roman Zippelb65a47e2006-06-08 22:12:47 -0700980 emit menuSelected(menu);
Roman Zippelab45d192006-06-08 22:12:47 -0700981 }
982 break;
983 case 's':
984 struct symbol *s;
985
986 if (sscanf(p, "s%p", &s) == 1 && sym != s) {
987 sym = s;
988 symbolInfo();
989 }
Roman Zippel43bf6122006-06-08 22:12:45 -0700990 break;
991 }
992}
993
Roman Zippelab45d192006-06-08 22:12:47 -0700994void ConfigInfoView::symbolInfo(void)
995{
996 QString str;
997
998 str += "<big>Symbol: <b>";
999 str += print_filter(sym->name);
1000 str += "</b></big><br><br>value: ";
1001 str += print_filter(sym_get_string_value(sym));
1002 str += "<br>visibility: ";
1003 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1004 str += "<br>";
1005 str += debug_info(sym);
1006
1007 setText(str);
1008}
1009
Roman Zippel43bf6122006-06-08 22:12:45 -07001010void ConfigInfoView::menuInfo(void)
1011{
1012 struct symbol* sym;
1013 QString head, debug, help;
1014
1015 sym = menu->sym;
1016 if (sym) {
1017 if (menu->prompt) {
1018 head += "<big><b>";
1019 head += print_filter(_(menu->prompt->text));
1020 head += "</b></big>";
1021 if (sym->name) {
1022 head += " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001023 if (showDebug())
1024 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001025 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001026 if (showDebug())
1027 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001028 head += ")";
1029 }
1030 } else if (sym->name) {
1031 head += "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001032 if (showDebug())
1033 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001034 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001035 if (showDebug())
1036 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001037 head += "</b></big>";
1038 }
1039 head += "<br><br>";
1040
1041 if (showDebug())
1042 debug = debug_info(sym);
1043
Sam Ravnborg03d29122007-07-21 00:00:36 +02001044 help = print_filter(_(menu_get_help(menu)));
Roman Zippel43bf6122006-06-08 22:12:45 -07001045 } else if (menu->prompt) {
1046 head += "<big><b>";
1047 head += print_filter(_(menu->prompt->text));
1048 head += "</b></big><br><br>";
1049 if (showDebug()) {
1050 if (menu->prompt->visible.expr) {
1051 debug += "&nbsp;&nbsp;dep: ";
1052 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1053 debug += "<br><br>";
1054 }
1055 }
1056 }
1057 if (showDebug())
1058 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1059
1060 setText(head + debug + help);
1061}
1062
1063QString ConfigInfoView::debug_info(struct symbol *sym)
1064{
1065 QString debug;
1066
1067 debug += "type: ";
1068 debug += print_filter(sym_type_name(sym->type));
1069 if (sym_is_choice(sym))
1070 debug += " (choice)";
1071 debug += "<br>";
1072 if (sym->rev_dep.expr) {
1073 debug += "reverse dep: ";
1074 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1075 debug += "<br>";
1076 }
1077 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1078 switch (prop->type) {
1079 case P_PROMPT:
1080 case P_MENU:
Roman Zippelab45d192006-06-08 22:12:47 -07001081 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
Roman Zippel43bf6122006-06-08 22:12:45 -07001082 debug += print_filter(_(prop->text));
Roman Zippelab45d192006-06-08 22:12:47 -07001083 debug += "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001084 break;
1085 case P_DEFAULT:
1086 debug += "default: ";
1087 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1088 debug += "<br>";
1089 break;
1090 case P_CHOICE:
1091 if (sym_is_choice(sym)) {
1092 debug += "choice: ";
1093 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1094 debug += "<br>";
1095 }
1096 break;
1097 case P_SELECT:
1098 debug += "select: ";
1099 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1100 debug += "<br>";
1101 break;
1102 case P_RANGE:
1103 debug += "range: ";
1104 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1105 debug += "<br>";
1106 break;
1107 default:
1108 debug += "unknown property: ";
1109 debug += prop_get_type_name(prop->type);
1110 debug += "<br>";
1111 }
1112 if (prop->visible.expr) {
1113 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1114 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1115 debug += "<br>";
1116 }
1117 }
1118 debug += "<br>";
1119
1120 return debug;
1121}
1122
1123QString ConfigInfoView::print_filter(const QString &str)
1124{
1125 QRegExp re("[<>&\"\\n]");
1126 QString res = str;
1127 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1128 switch (res[i].latin1()) {
1129 case '<':
1130 res.replace(i, 1, "&lt;");
1131 i += 4;
1132 break;
1133 case '>':
1134 res.replace(i, 1, "&gt;");
1135 i += 4;
1136 break;
1137 case '&':
1138 res.replace(i, 1, "&amp;");
1139 i += 5;
1140 break;
1141 case '"':
1142 res.replace(i, 1, "&quot;");
1143 i += 6;
1144 break;
1145 case '\n':
1146 res.replace(i, 1, "<br>");
1147 i += 4;
1148 break;
1149 }
1150 }
1151 return res;
1152}
1153
Roman Zippelab45d192006-06-08 22:12:47 -07001154void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001155{
Roman Zippelab45d192006-06-08 22:12:47 -07001156 QString* text = reinterpret_cast<QString*>(data);
1157 QString str2 = print_filter(str);
1158
1159 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1160 *text += QString().sprintf("<a href=\"s%p\">", sym);
1161 *text += str2;
1162 *text += "</a>";
1163 } else
1164 *text += str2;
Roman Zippel43bf6122006-06-08 22:12:45 -07001165}
1166
Roman Zippel7fc925f2006-06-08 22:12:46 -07001167QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1168{
1169 QPopupMenu* popup = Parent::createPopupMenu(pos);
akpm@osdl.org44ddc4f2006-12-06 20:37:41 -08001170 QAction* action = new QAction(NULL,"Show Debug Info", 0, popup);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001171 action->setToggleAction(TRUE);
1172 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1173 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1174 action->setOn(showDebug());
1175 popup->insertSeparator();
1176 action->addTo(popup);
1177 return popup;
1178}
1179
1180void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1181{
1182 Parent::contentsContextMenuEvent(e);
1183}
1184
Marco Costalba63431e72006-10-05 19:12:59 +02001185ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001186 : Parent(parent, name), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001187{
1188 setCaption("Search Config");
1189
1190 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1191 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1192 layout2->addWidget(new QLabel("Find:", this));
1193 editField = new QLineEdit(this);
1194 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1195 layout2->addWidget(editField);
1196 searchButton = new QPushButton("Search", this);
1197 searchButton->setAutoDefault(FALSE);
1198 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1199 layout2->addWidget(searchButton);
1200 layout1->addLayout(layout2);
1201
Roman Zippel7fc925f2006-06-08 22:12:46 -07001202 split = new QSplitter(this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001203 split->setOrientation(QSplitter::Vertical);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001204 list = new ConfigView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001205 list->list->mode = listMode;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001206 info = new ConfigInfoView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001207 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1208 info, SLOT(setInfo(struct menu *)));
Marco Costalba63431e72006-10-05 19:12:59 +02001209 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1210 parent, SLOT(setMenuLink(struct menu *)));
1211
Roman Zippel43bf6122006-06-08 22:12:45 -07001212 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001213
1214 if (name) {
1215 int x, y, width, height;
1216 bool ok;
1217
1218 configSettings->beginGroup(name);
1219 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1220 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1221 resize(width, height);
1222 x = configSettings->readNumEntry("/window x", 0, &ok);
1223 if (ok)
1224 y = configSettings->readNumEntry("/window y", 0, &ok);
1225 if (ok)
1226 move(x, y);
1227 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1228 if (ok)
1229 split->setSizes(sizes);
1230 configSettings->endGroup();
1231 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1232 }
1233}
1234
1235void ConfigSearchWindow::saveSettings(void)
1236{
1237 if (name()) {
1238 configSettings->beginGroup(name());
1239 configSettings->writeEntry("/window x", pos().x());
1240 configSettings->writeEntry("/window y", pos().y());
1241 configSettings->writeEntry("/window width", size().width());
1242 configSettings->writeEntry("/window height", size().height());
1243 configSettings->writeSizes("/split", split->sizes());
1244 configSettings->endGroup();
1245 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001246}
1247
1248void ConfigSearchWindow::search(void)
1249{
1250 struct symbol **p;
1251 struct property *prop;
1252 ConfigItem *lastItem = NULL;
1253
1254 free(result);
1255 list->list->clear();
Cyrill V. Gorcunov786fb182007-02-14 00:32:59 -08001256 info->clear();
Roman Zippel43bf6122006-06-08 22:12:45 -07001257
1258 result = sym_re_search(editField->text().latin1());
1259 if (!result)
1260 return;
1261 for (p = result; *p; p++) {
1262 for_all_prompts((*p), prop)
1263 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1264 menu_is_visible(prop->menu));
1265 }
1266}
1267
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268/*
1269 * Construct the complete config widget
1270 */
1271ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001272 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273{
1274 QMenuBar* menu;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001275 bool ok;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276 int x, y, width, height;
1277
1278 QWidget *d = configApp->desktop();
1279
Roman Zippel7fc925f2006-06-08 22:12:46 -07001280 width = configSettings->readNumEntry("/window width", d->width() - 64);
1281 height = configSettings->readNumEntry("/window height", d->height() - 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 resize(width, height);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001283 x = configSettings->readNumEntry("/window x", 0, &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 if (ok)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001285 y = configSettings->readNumEntry("/window y", 0, &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286 if (ok)
1287 move(x, y);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288
1289 split1 = new QSplitter(this);
1290 split1->setOrientation(QSplitter::Horizontal);
1291 setCentralWidget(split1);
1292
Roman Zippel7fc925f2006-06-08 22:12:46 -07001293 menuView = new ConfigView(split1, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 menuList = menuView->list;
1295
1296 split2 = new QSplitter(split1);
1297 split2->setOrientation(QSplitter::Vertical);
1298
1299 // create config tree
Roman Zippel7fc925f2006-06-08 22:12:46 -07001300 configView = new ConfigView(split2, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301 configList = configView->list;
1302
Roman Zippel7fc925f2006-06-08 22:12:46 -07001303 helpText = new ConfigInfoView(split2, "help");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304 helpText->setTextFormat(Qt::RichText);
1305
1306 setTabOrder(configList, helpText);
1307 configList->setFocus();
1308
1309 menu = menuBar();
1310 toolBar = new QToolBar("Tools", this);
1311
1312 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
1313 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1314 backAction->setEnabled(FALSE);
1315 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
1316 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1317 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
1318 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
Karsten Wiese3b354c52006-12-13 00:34:08 -08001319 saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
Karsten Wiese3b354c52006-12-13 00:34:08 -08001321 conf_set_changed_callback(conf_changed);
1322 // Set saveAction's initial state
1323 conf_changed();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
1325 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
Shlomi Fish66e7c722007-02-14 00:32:58 -08001326 QAction *searchAction = new QAction("Find", "&Find", CTRL+Key_F, this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001327 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001328 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
1329 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1330 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
1331 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1332 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
1333 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1334
1335 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
1336 showNameAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001337 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1338 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1339 showNameAction->setOn(configView->showName());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
1341 showRangeAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001342 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1343 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344 showRangeAction->setOn(configList->showRange);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
1346 showDataAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001347 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1348 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349 showDataAction->setOn(configList->showData);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
1351 showAllAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001352 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1353 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 showAllAction->setOn(configList->showAll);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
1356 showDebugAction->setToggleAction(TRUE);
Roman Zippel43bf6122006-06-08 22:12:45 -07001357 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1358 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
Roman Zippel7fc925f2006-06-08 22:12:46 -07001359 showDebugAction->setOn(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360
1361 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
1362 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1363 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
1364 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1365
1366 // init tool bar
1367 backAction->addTo(toolBar);
1368 toolBar->addSeparator();
1369 loadAction->addTo(toolBar);
1370 saveAction->addTo(toolBar);
1371 toolBar->addSeparator();
1372 singleViewAction->addTo(toolBar);
1373 splitViewAction->addTo(toolBar);
1374 fullViewAction->addTo(toolBar);
1375
1376 // create config menu
1377 QPopupMenu* config = new QPopupMenu(this);
1378 menu->insertItem("&File", config);
1379 loadAction->addTo(config);
1380 saveAction->addTo(config);
1381 saveAsAction->addTo(config);
1382 config->insertSeparator();
1383 quitAction->addTo(config);
1384
Shlomi Fish66e7c722007-02-14 00:32:58 -08001385 // create edit menu
1386 QPopupMenu* editMenu = new QPopupMenu(this);
1387 menu->insertItem("&Edit", editMenu);
1388 searchAction->addTo(editMenu);
1389
Linus Torvalds1da177e2005-04-16 15:20:36 -07001390 // create options menu
1391 QPopupMenu* optionMenu = new QPopupMenu(this);
1392 menu->insertItem("&Option", optionMenu);
1393 showNameAction->addTo(optionMenu);
1394 showRangeAction->addTo(optionMenu);
1395 showDataAction->addTo(optionMenu);
1396 optionMenu->insertSeparator();
1397 showAllAction->addTo(optionMenu);
1398 showDebugAction->addTo(optionMenu);
1399
1400 // create help menu
1401 QPopupMenu* helpMenu = new QPopupMenu(this);
1402 menu->insertSeparator();
1403 menu->insertItem("&Help", helpMenu);
1404 showIntroAction->addTo(helpMenu);
1405 showAboutAction->addTo(helpMenu);
1406
Roman Zippel43bf6122006-06-08 22:12:45 -07001407 connect(configList, SIGNAL(menuChanged(struct menu *)),
1408 helpText, SLOT(setInfo(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 connect(configList, SIGNAL(menuSelected(struct menu *)),
1410 SLOT(changeMenu(struct menu *)));
1411 connect(configList, SIGNAL(parentSelected()),
1412 SLOT(goBack()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001413 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1414 helpText, SLOT(setInfo(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1416 SLOT(changeMenu(struct menu *)));
1417
Roman Zippelb65a47e2006-06-08 22:12:47 -07001418 connect(configList, SIGNAL(gotFocus(struct menu *)),
1419 helpText, SLOT(setInfo(struct menu *)));
1420 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1421 helpText, SLOT(setInfo(struct menu *)));
1422 connect(menuList, SIGNAL(gotFocus(struct menu *)),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001424 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1425 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
Roman Zippel7fc925f2006-06-08 22:12:46 -07001427 QString listMode = configSettings->readEntry("/listMode", "symbol");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428 if (listMode == "single")
1429 showSingleView();
1430 else if (listMode == "full")
1431 showFullView();
1432 else /*if (listMode == "split")*/
1433 showSplitView();
1434
1435 // UI setup done, restore splitter positions
Roman Zippel7fc925f2006-06-08 22:12:46 -07001436 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437 if (ok)
1438 split1->setSizes(sizes);
1439
Roman Zippel7fc925f2006-06-08 22:12:46 -07001440 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441 if (ok)
1442 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443}
1444
Linus Torvalds1da177e2005-04-16 15:20:36 -07001445void ConfigMainWindow::loadConfig(void)
1446{
1447 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1448 if (s.isNull())
1449 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001450 if (conf_read(QFile::encodeName(s)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1452 ConfigView::updateListAll();
1453}
1454
1455void ConfigMainWindow::saveConfig(void)
1456{
1457 if (conf_write(NULL))
1458 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1459}
1460
1461void ConfigMainWindow::saveConfigAs(void)
1462{
1463 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1464 if (s.isNull())
1465 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001466 if (conf_write(QFile::encodeName(s)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1468}
1469
Roman Zippel43bf6122006-06-08 22:12:45 -07001470void ConfigMainWindow::searchConfig(void)
1471{
1472 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001473 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001474 searchWindow->show();
1475}
1476
Linus Torvalds1da177e2005-04-16 15:20:36 -07001477void ConfigMainWindow::changeMenu(struct menu *menu)
1478{
1479 configList->setRootMenu(menu);
Cyrill V. Gorcunovf253f002007-02-14 00:33:00 -08001480 if (configList->rootEntry->parent == &rootmenu)
1481 backAction->setEnabled(FALSE);
1482 else
1483 backAction->setEnabled(TRUE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484}
1485
Roman Zippelb65a47e2006-06-08 22:12:47 -07001486void ConfigMainWindow::setMenuLink(struct menu *menu)
1487{
1488 struct menu *parent;
1489 ConfigList* list = NULL;
1490 ConfigItem* item;
1491
1492 if (!menu_is_visible(menu) && !configView->showAll())
1493 return;
1494
1495 switch (configList->mode) {
1496 case singleMode:
1497 list = configList;
1498 parent = menu_get_parent_menu(menu);
1499 if (!parent)
1500 return;
1501 list->setRootMenu(parent);
1502 break;
1503 case symbolMode:
1504 if (menu->flags & MENU_ROOT) {
1505 configList->setRootMenu(menu);
1506 configList->clearSelection();
1507 list = menuList;
1508 } else {
1509 list = configList;
1510 parent = menu_get_parent_menu(menu->parent);
1511 if (!parent)
1512 return;
1513 item = menuList->findConfigItem(parent);
1514 if (item) {
1515 menuList->setSelected(item, TRUE);
1516 menuList->ensureItemVisible(item);
1517 }
1518 list->setRootMenu(parent);
1519 }
1520 break;
1521 case fullMode:
1522 list = configList;
1523 break;
1524 }
1525
1526 if (list) {
1527 item = list->findConfigItem(menu);
1528 if (item) {
1529 list->setSelected(item, TRUE);
1530 list->ensureItemVisible(item);
1531 list->setFocus();
1532 }
1533 }
1534}
1535
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536void ConfigMainWindow::listFocusChanged(void)
1537{
Roman Zippelb65a47e2006-06-08 22:12:47 -07001538 if (menuList->mode == menuMode)
1539 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540}
1541
1542void ConfigMainWindow::goBack(void)
1543{
1544 ConfigItem* item;
1545
1546 configList->setParentMenu();
1547 if (configList->rootEntry == &rootmenu)
1548 backAction->setEnabled(FALSE);
1549 item = (ConfigItem*)menuList->selectedItem();
1550 while (item) {
1551 if (item->menu == configList->rootEntry) {
1552 menuList->setSelected(item, TRUE);
1553 break;
1554 }
1555 item = (ConfigItem*)item->parent();
1556 }
1557}
1558
1559void ConfigMainWindow::showSingleView(void)
1560{
1561 menuView->hide();
1562 menuList->setRootMenu(0);
1563 configList->mode = singleMode;
1564 if (configList->rootEntry == &rootmenu)
1565 configList->updateListAll();
1566 else
1567 configList->setRootMenu(&rootmenu);
1568 configList->setAllOpen(TRUE);
1569 configList->setFocus();
1570}
1571
1572void ConfigMainWindow::showSplitView(void)
1573{
1574 configList->mode = symbolMode;
1575 if (configList->rootEntry == &rootmenu)
1576 configList->updateListAll();
1577 else
1578 configList->setRootMenu(&rootmenu);
1579 configList->setAllOpen(TRUE);
1580 configApp->processEvents();
1581 menuList->mode = menuMode;
1582 menuList->setRootMenu(&rootmenu);
1583 menuList->setAllOpen(TRUE);
1584 menuView->show();
1585 menuList->setFocus();
1586}
1587
1588void ConfigMainWindow::showFullView(void)
1589{
1590 menuView->hide();
1591 menuList->setRootMenu(0);
1592 configList->mode = fullMode;
1593 if (configList->rootEntry == &rootmenu)
1594 configList->updateListAll();
1595 else
1596 configList->setRootMenu(&rootmenu);
1597 configList->setAllOpen(FALSE);
1598 configList->setFocus();
1599}
1600
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601/*
1602 * ask for saving configuration before quitting
1603 * TODO ask only when something changed
1604 */
1605void ConfigMainWindow::closeEvent(QCloseEvent* e)
1606{
Karsten Wieseb3214292006-12-13 00:34:06 -08001607 if (!conf_get_changed()) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 e->accept();
1609 return;
1610 }
1611 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1612 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1613 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1614 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1615 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1616 switch (mb.exec()) {
1617 case QMessageBox::Yes:
1618 conf_write(NULL);
1619 case QMessageBox::No:
1620 e->accept();
1621 break;
1622 case QMessageBox::Cancel:
1623 e->ignore();
1624 break;
1625 }
1626}
1627
1628void ConfigMainWindow::showIntro(void)
1629{
1630 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1631 "For each option, a blank box indicates the feature is disabled, a check\n"
1632 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1633 "as a module. Clicking on the box will cycle through the three states.\n\n"
1634 "If you do not see an option (e.g., a device driver) that you believe\n"
1635 "should be present, try turning on Show All Options under the Options menu.\n"
1636 "Although there is no cross reference yet to help you figure out what other\n"
1637 "options must be enabled to support the option you are interested in, you can\n"
1638 "still view the help of a grayed-out option.\n\n"
1639 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1640 "which you can then match by examining other options.\n\n";
1641
1642 QMessageBox::information(this, "qconf", str);
1643}
1644
1645void ConfigMainWindow::showAbout(void)
1646{
1647 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1648 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1649
1650 QMessageBox::information(this, "qconf", str);
1651}
1652
1653void ConfigMainWindow::saveSettings(void)
1654{
Roman Zippel7fc925f2006-06-08 22:12:46 -07001655 configSettings->writeEntry("/window x", pos().x());
1656 configSettings->writeEntry("/window y", pos().y());
1657 configSettings->writeEntry("/window width", size().width());
1658 configSettings->writeEntry("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659
1660 QString entry;
1661 switch(configList->mode) {
1662 case singleMode :
1663 entry = "single";
1664 break;
1665
1666 case symbolMode :
1667 entry = "split";
1668 break;
1669
1670 case fullMode :
1671 entry = "full";
1672 break;
1673 }
Roman Zippel7fc925f2006-06-08 22:12:46 -07001674 configSettings->writeEntry("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001675
Roman Zippel7fc925f2006-06-08 22:12:46 -07001676 configSettings->writeSizes("/split1", split1->sizes());
1677 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001678}
1679
Karsten Wiese3b354c52006-12-13 00:34:08 -08001680void ConfigMainWindow::conf_changed(void)
1681{
1682 if (saveAction)
1683 saveAction->setEnabled(conf_get_changed());
1684}
1685
Linus Torvalds1da177e2005-04-16 15:20:36 -07001686void fixup_rootmenu(struct menu *menu)
1687{
1688 struct menu *child;
1689 static int menu_cnt = 0;
1690
1691 menu->flags |= MENU_ROOT;
1692 for (child = menu->list; child; child = child->next) {
1693 if (child->prompt && child->prompt->type == P_MENU) {
1694 menu_cnt++;
1695 fixup_rootmenu(child);
1696 menu_cnt--;
1697 } else if (!menu_cnt)
1698 fixup_rootmenu(child);
1699 }
1700}
1701
1702static const char *progname;
1703
1704static void usage(void)
1705{
1706 printf("%s <config>\n", progname);
1707 exit(0);
1708}
1709
1710int main(int ac, char** av)
1711{
1712 ConfigMainWindow* v;
1713 const char *name;
1714
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001715 bindtextdomain(PACKAGE, LOCALEDIR);
1716 textdomain(PACKAGE);
1717
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718#ifndef LKC_DIRECT_LINK
1719 kconfig_load();
1720#endif
1721
1722 progname = av[0];
1723 configApp = new QApplication(ac, av);
1724 if (ac > 1 && av[1][0] == '-') {
1725 switch (av[1][1]) {
1726 case 'h':
1727 case '?':
1728 usage();
1729 }
1730 name = av[2];
1731 } else
1732 name = av[1];
1733 if (!name)
1734 usage();
1735
1736 conf_parse(name);
1737 fixup_rootmenu(&rootmenu);
1738 conf_read(NULL);
1739 //zconfdump(stdout);
1740
Roman Zippel7fc925f2006-06-08 22:12:46 -07001741 configSettings = new ConfigSettings();
1742 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001743 v = new ConfigMainWindow();
1744
1745 //zconfdump(stdout);
Roman Zippel43bf6122006-06-08 22:12:45 -07001746 configApp->setMainWidget(v);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1748 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001749 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 configApp->exec();
1751
Roman Zippel7fc925f2006-06-08 22:12:46 -07001752 configSettings->endGroup();
1753 delete configSettings;
1754
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 return 0;
1756}