blob: 338bdea9654177316a9044c86a9667039fb6845e [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
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070041static inline QString qgettext(const char* str)
42{
Roman Zippel43bf6122006-06-08 22:12:45 -070043 return QString::fromLocal8Bit(gettext(str));
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070044}
45
46static inline QString qgettext(const QString& str)
47{
Roman Zippel43bf6122006-06-08 22:12:45 -070048 return QString::fromLocal8Bit(gettext(str.latin1()));
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -070049}
50
Linus Torvalds1da177e2005-04-16 15:20:36 -070051/**
52 * Reads a list of integer values from the application settings.
53 */
54QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
55{
56 QValueList<int> result;
57 QStringList entryList = readListEntry(key, ok);
58 if (ok) {
59 QStringList::Iterator it;
60 for (it = entryList.begin(); it != entryList.end(); ++it)
61 result.push_back((*it).toInt());
62 }
63
64 return result;
65}
66
67/**
68 * Writes a list of integer values to the application settings.
69 */
70bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
71{
72 QStringList stringList;
73 QValueList<int>::ConstIterator it;
74
75 for (it = value.begin(); it != value.end(); ++it)
76 stringList.push_back(QString::number(*it));
77 return writeEntry(key, stringList);
78}
Linus Torvalds1da177e2005-04-16 15:20:36 -070079
80
Linus Torvalds1da177e2005-04-16 15:20:36 -070081#if QT_VERSION >= 300
82/*
83 * set the new data
84 * TODO check the value
85 */
86void ConfigItem::okRename(int col)
87{
88 Parent::okRename(col);
89 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
90}
91#endif
92
93/*
94 * update the displayed of a menu entry
95 */
96void ConfigItem::updateMenu(void)
97{
98 ConfigList* list;
99 struct symbol* sym;
100 struct property *prop;
101 QString prompt;
102 int type;
103 tristate expr;
104
105 list = listView();
106 if (goParent) {
107 setPixmap(promptColIdx, list->menuBackPix);
108 prompt = "..";
109 goto set_prompt;
110 }
111
112 sym = menu->sym;
113 prop = menu->prompt;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700114 prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115
116 if (prop) switch (prop->type) {
117 case P_MENU:
118 if (list->mode == singleMode || list->mode == symbolMode) {
119 /* a menuconfig entry is displayed differently
120 * depending whether it's at the view root or a child.
121 */
122 if (sym && list->rootEntry == menu)
123 break;
124 setPixmap(promptColIdx, list->menuPix);
125 } else {
126 if (sym)
127 break;
128 setPixmap(promptColIdx, 0);
129 }
130 goto set_prompt;
131 case P_COMMENT:
132 setPixmap(promptColIdx, 0);
133 goto set_prompt;
134 default:
135 ;
136 }
137 if (!sym)
138 goto set_prompt;
139
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700140 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700141
142 type = sym_get_type(sym);
143 switch (type) {
144 case S_BOOLEAN:
145 case S_TRISTATE:
146 char ch;
147
148 if (!sym_is_changable(sym) && !list->showAll) {
149 setPixmap(promptColIdx, 0);
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700150 setText(noColIdx, QString::null);
151 setText(modColIdx, QString::null);
152 setText(yesColIdx, QString::null);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153 break;
154 }
155 expr = sym_get_tristate_value(sym);
156 switch (expr) {
157 case yes:
158 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
159 setPixmap(promptColIdx, list->choiceYesPix);
160 else
161 setPixmap(promptColIdx, list->symbolYesPix);
162 setText(yesColIdx, "Y");
163 ch = 'Y';
164 break;
165 case mod:
166 setPixmap(promptColIdx, list->symbolModPix);
167 setText(modColIdx, "M");
168 ch = 'M';
169 break;
170 default:
171 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
172 setPixmap(promptColIdx, list->choiceNoPix);
173 else
174 setPixmap(promptColIdx, list->symbolNoPix);
175 setText(noColIdx, "N");
176 ch = 'N';
177 break;
178 }
179 if (expr != no)
180 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
181 if (expr != mod)
182 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
183 if (expr != yes)
184 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
185
186 setText(dataColIdx, QChar(ch));
187 break;
188 case S_INT:
189 case S_HEX:
190 case S_STRING:
191 const char* data;
192
193 data = sym_get_string_value(sym);
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700194
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195#if QT_VERSION >= 300
196 int i = list->mapIdx(dataColIdx);
197 if (i >= 0)
198 setRenameEnabled(i, TRUE);
199#endif
200 setText(dataColIdx, data);
201 if (type == S_STRING)
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700202 prompt = QString("%1: %2").arg(prompt).arg(data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203 else
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700204 prompt = QString("(%2) %1").arg(prompt).arg(data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 break;
206 }
207 if (!sym_has_value(sym) && visible)
208 prompt += " (NEW)";
209set_prompt:
210 setText(promptColIdx, prompt);
211}
212
213void ConfigItem::testUpdateMenu(bool v)
214{
215 ConfigItem* i;
216
217 visible = v;
218 if (!menu)
219 return;
220
221 sym_calc_value(menu->sym);
222 if (menu->flags & MENU_CHANGED) {
223 /* the menu entry changed, so update all list items */
224 menu->flags &= ~MENU_CHANGED;
225 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
226 i->updateMenu();
227 } else if (listView()->updateAll)
228 updateMenu();
229}
230
231void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
232{
233 ConfigList* list = listView();
234
235 if (visible) {
236 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
237 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
238 else
239 Parent::paintCell(p, cg, column, width, align);
240 } else
241 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
242}
243
244/*
245 * construct a menu entry
246 */
247void ConfigItem::init(void)
248{
249 if (menu) {
250 ConfigList* list = listView();
251 nextItem = (ConfigItem*)menu->data;
252 menu->data = this;
253
254 if (list->mode != fullMode)
255 setOpen(TRUE);
256 sym_calc_value(menu->sym);
257 }
258 updateMenu();
259}
260
261/*
262 * destruct a menu entry
263 */
264ConfigItem::~ConfigItem(void)
265{
266 if (menu) {
267 ConfigItem** ip = (ConfigItem**)&menu->data;
268 for (; *ip; ip = &(*ip)->nextItem) {
269 if (*ip == this) {
270 *ip = nextItem;
271 break;
272 }
273 }
274 }
275}
276
Roman Zippel43bf6122006-06-08 22:12:45 -0700277ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
278 : Parent(parent)
279{
280 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
281}
282
Linus Torvalds1da177e2005-04-16 15:20:36 -0700283void ConfigLineEdit::show(ConfigItem* i)
284{
285 item = i;
286 if (sym_get_string_value(item->menu->sym))
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700287 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700288 else
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -0700289 setText(QString::null);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700290 Parent::show();
291 setFocus();
292}
293
294void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
295{
296 switch (e->key()) {
297 case Key_Escape:
298 break;
299 case Key_Return:
300 case Key_Enter:
301 sym_set_string_value(item->menu->sym, text().latin1());
302 parent()->updateList(item);
303 break;
304 default:
305 Parent::keyPressEvent(e);
306 return;
307 }
308 e->accept();
309 parent()->list->setFocus();
310 hide();
311}
312
Roman Zippel7fc925f2006-06-08 22:12:46 -0700313ConfigList::ConfigList(ConfigView* p, const char *name)
314 : Parent(p, name),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700315 updateAll(false),
316 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
317 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
318 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
319 showAll(false), showName(false), showRange(false), showData(false),
Roman Zippel7fc925f2006-06-08 22:12:46 -0700320 rootEntry(0), headerPopup(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700321{
322 int i;
323
324 setSorting(-1);
325 setRootIsDecorated(TRUE);
326 disabledColorGroup = palette().active();
327 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
328 inactivedColorGroup = palette().active();
329 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
330
331 connect(this, SIGNAL(selectionChanged(void)),
332 SLOT(updateSelection(void)));
333
Roman Zippel7fc925f2006-06-08 22:12:46 -0700334 if (name) {
335 configSettings->beginGroup(name);
336 showAll = configSettings->readBoolEntry("/showAll", false);
337 showName = configSettings->readBoolEntry("/showName", false);
338 showRange = configSettings->readBoolEntry("/showRange", false);
339 showData = configSettings->readBoolEntry("/showData", false);
340 configSettings->endGroup();
341 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 }
343
344 for (i = 0; i < colNr; i++)
345 colMap[i] = colRevMap[i] = -1;
346 addColumn(promptColIdx, "Option");
347
348 reinit();
349}
350
351void ConfigList::reinit(void)
352{
353 removeColumn(dataColIdx);
354 removeColumn(yesColIdx);
355 removeColumn(modColIdx);
356 removeColumn(noColIdx);
357 removeColumn(nameColIdx);
358
359 if (showName)
360 addColumn(nameColIdx, "Name");
361 if (showRange) {
362 addColumn(noColIdx, "N");
363 addColumn(modColIdx, "M");
364 addColumn(yesColIdx, "Y");
365 }
366 if (showData)
367 addColumn(dataColIdx, "Value");
368
369 updateListAll();
370}
371
Roman Zippel7fc925f2006-06-08 22:12:46 -0700372void ConfigList::saveSettings(void)
373{
374 if (name()) {
375 configSettings->beginGroup(name());
376 configSettings->writeEntry("/showName", showName);
377 configSettings->writeEntry("/showRange", showRange);
378 configSettings->writeEntry("/showData", showData);
379 configSettings->writeEntry("/showAll", showAll);
380 configSettings->endGroup();
381 }
382}
383
Roman Zippelb65a47e2006-06-08 22:12:47 -0700384ConfigItem* ConfigList::findConfigItem(struct menu *menu)
385{
386 ConfigItem* item = (ConfigItem*)menu->data;
387
388 for (; item; item = item->nextItem) {
389 if (this == item->listView())
390 break;
391 }
392
393 return item;
394}
395
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396void ConfigList::updateSelection(void)
397{
398 struct menu *menu;
399 enum prop_type type;
400
401 ConfigItem* item = (ConfigItem*)selectedItem();
402 if (!item)
403 return;
404
Linus Torvalds1da177e2005-04-16 15:20:36 -0700405 menu = item->menu;
Roman Zippel43bf6122006-06-08 22:12:45 -0700406 emit menuChanged(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407 if (!menu)
408 return;
409 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
410 if (mode == menuMode && type == P_MENU)
411 emit menuSelected(menu);
412}
413
414void ConfigList::updateList(ConfigItem* item)
415{
416 ConfigItem* last = 0;
417
Roman Zippel43bf6122006-06-08 22:12:45 -0700418 if (!rootEntry) {
419 if (mode != listMode)
420 goto update;
421 QListViewItemIterator it(this);
422 ConfigItem* item;
423
424 for (; it.current(); ++it) {
425 item = (ConfigItem*)it.current();
426 if (!item->menu)
427 continue;
428 item->testUpdateMenu(menu_is_visible(item->menu));
429 }
430 return;
431 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432
433 if (rootEntry != &rootmenu && (mode == singleMode ||
434 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
435 item = firstChild();
436 if (!item)
437 item = new ConfigItem(this, 0, true);
438 last = item;
439 }
440 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
441 rootEntry->sym && rootEntry->prompt) {
442 item = last ? last->nextSibling() : firstChild();
443 if (!item)
444 item = new ConfigItem(this, last, rootEntry, true);
445 else
446 item->testUpdateMenu(true);
447
448 updateMenuList(item, rootEntry);
449 triggerUpdate();
450 return;
451 }
452update:
453 updateMenuList(this, rootEntry);
454 triggerUpdate();
455}
456
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457void ConfigList::setValue(ConfigItem* item, tristate val)
458{
459 struct symbol* sym;
460 int type;
461 tristate oldval;
462
463 sym = item->menu ? item->menu->sym : 0;
464 if (!sym)
465 return;
466
467 type = sym_get_type(sym);
468 switch (type) {
469 case S_BOOLEAN:
470 case S_TRISTATE:
471 oldval = sym_get_tristate_value(sym);
472
473 if (!sym_set_tristate_value(sym, val))
474 return;
475 if (oldval == no && item->menu->list)
476 item->setOpen(TRUE);
477 parent()->updateList(item);
478 break;
479 }
480}
481
482void ConfigList::changeValue(ConfigItem* item)
483{
484 struct symbol* sym;
485 struct menu* menu;
486 int type, oldexpr, newexpr;
487
488 menu = item->menu;
489 if (!menu)
490 return;
491 sym = menu->sym;
492 if (!sym) {
493 if (item->menu->list)
494 item->setOpen(!item->isOpen());
495 return;
496 }
497
498 type = sym_get_type(sym);
499 switch (type) {
500 case S_BOOLEAN:
501 case S_TRISTATE:
502 oldexpr = sym_get_tristate_value(sym);
503 newexpr = sym_toggle_tristate_value(sym);
504 if (item->menu->list) {
505 if (oldexpr == newexpr)
506 item->setOpen(!item->isOpen());
507 else if (oldexpr == no)
508 item->setOpen(TRUE);
509 }
510 if (oldexpr != newexpr)
511 parent()->updateList(item);
512 break;
513 case S_INT:
514 case S_HEX:
515 case S_STRING:
516#if QT_VERSION >= 300
517 if (colMap[dataColIdx] >= 0)
518 item->startRename(colMap[dataColIdx]);
519 else
520#endif
521 parent()->lineEdit->show(item);
522 break;
523 }
524}
525
526void ConfigList::setRootMenu(struct menu *menu)
527{
528 enum prop_type type;
529
530 if (rootEntry == menu)
531 return;
532 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
533 if (type != P_MENU)
534 return;
535 updateMenuList(this, 0);
536 rootEntry = menu;
537 updateListAll();
538 setSelected(currentItem(), hasFocus());
Roman Zippelb65a47e2006-06-08 22:12:47 -0700539 ensureItemVisible(currentItem());
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540}
541
542void ConfigList::setParentMenu(void)
543{
544 ConfigItem* item;
545 struct menu *oldroot;
546
547 oldroot = rootEntry;
548 if (rootEntry == &rootmenu)
549 return;
550 setRootMenu(menu_get_parent_menu(rootEntry->parent));
551
552 QListViewItemIterator it(this);
553 for (; (item = (ConfigItem*)it.current()); it++) {
554 if (item->menu == oldroot) {
555 setCurrentItem(item);
556 ensureItemVisible(item);
557 break;
558 }
559 }
560}
561
Roman Zippel7fc925f2006-06-08 22:12:46 -0700562/*
563 * update all the children of a menu entry
564 * removes/adds the entries from the parent widget as necessary
565 *
566 * parent: either the menu list widget or a menu entry widget
567 * menu: entry to be updated
568 */
569template <class P>
570void ConfigList::updateMenuList(P* parent, struct menu* menu)
571{
572 struct menu* child;
573 ConfigItem* item;
574 ConfigItem* last;
575 bool visible;
576 enum prop_type type;
577
578 if (!menu) {
579 while ((item = parent->firstChild()))
580 delete item;
581 return;
582 }
583
584 last = parent->firstChild();
585 if (last && !last->goParent)
586 last = 0;
587 for (child = menu->list; child; child = child->next) {
588 item = last ? last->nextSibling() : parent->firstChild();
589 type = child->prompt ? child->prompt->type : P_UNKNOWN;
590
591 switch (mode) {
592 case menuMode:
593 if (!(child->flags & MENU_ROOT))
594 goto hide;
595 break;
596 case symbolMode:
597 if (child->flags & MENU_ROOT)
598 goto hide;
599 break;
600 default:
601 break;
602 }
603
604 visible = menu_is_visible(child);
605 if (showAll || visible) {
606 if (!item || item->menu != child)
607 item = new ConfigItem(parent, last, child, visible);
608 else
609 item->testUpdateMenu(visible);
610
611 if (mode == fullMode || mode == menuMode || type != P_MENU)
612 updateMenuList(item, child);
613 else
614 updateMenuList(item, 0);
615 last = item;
616 continue;
617 }
618 hide:
619 if (item && item->menu == child) {
620 last = parent->firstChild();
621 if (last == item)
622 last = 0;
623 else while (last->nextSibling() != item)
624 last = last->nextSibling();
625 delete item;
626 }
627 }
628}
629
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630void ConfigList::keyPressEvent(QKeyEvent* ev)
631{
632 QListViewItem* i = currentItem();
633 ConfigItem* item;
634 struct menu *menu;
635 enum prop_type type;
636
Roman Zippel43bf6122006-06-08 22:12:45 -0700637 if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 emit parentSelected();
639 ev->accept();
640 return;
641 }
642
643 if (!i) {
644 Parent::keyPressEvent(ev);
645 return;
646 }
647 item = (ConfigItem*)i;
648
649 switch (ev->key()) {
650 case Key_Return:
651 case Key_Enter:
652 if (item->goParent) {
653 emit parentSelected();
654 break;
655 }
656 menu = item->menu;
657 if (!menu)
658 break;
659 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
660 if (type == P_MENU && rootEntry != menu &&
661 mode != fullMode && mode != menuMode) {
662 emit menuSelected(menu);
663 break;
664 }
665 case Key_Space:
666 changeValue(item);
667 break;
668 case Key_N:
669 setValue(item, no);
670 break;
671 case Key_M:
672 setValue(item, mod);
673 break;
674 case Key_Y:
675 setValue(item, yes);
676 break;
677 default:
678 Parent::keyPressEvent(ev);
679 return;
680 }
681 ev->accept();
682}
683
684void ConfigList::contentsMousePressEvent(QMouseEvent* e)
685{
686 //QPoint p(contentsToViewport(e->pos()));
687 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
688 Parent::contentsMousePressEvent(e);
689}
690
691void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
692{
693 QPoint p(contentsToViewport(e->pos()));
694 ConfigItem* item = (ConfigItem*)itemAt(p);
695 struct menu *menu;
696 enum prop_type ptype;
697 const QPixmap* pm;
698 int idx, x;
699
700 if (!item)
701 goto skip;
702
703 menu = item->menu;
704 x = header()->offset() + p.x();
705 idx = colRevMap[header()->sectionAt(x)];
706 switch (idx) {
707 case promptColIdx:
708 pm = item->pixmap(promptColIdx);
709 if (pm) {
710 int off = header()->sectionPos(0) + itemMargin() +
711 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
712 if (x >= off && x < off + pm->width()) {
713 if (item->goParent) {
714 emit parentSelected();
715 break;
716 } else if (!menu)
717 break;
718 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
719 if (ptype == P_MENU && rootEntry != menu &&
720 mode != fullMode && mode != menuMode)
721 emit menuSelected(menu);
722 else
723 changeValue(item);
724 }
725 }
726 break;
727 case noColIdx:
728 setValue(item, no);
729 break;
730 case modColIdx:
731 setValue(item, mod);
732 break;
733 case yesColIdx:
734 setValue(item, yes);
735 break;
736 case dataColIdx:
737 changeValue(item);
738 break;
739 }
740
741skip:
742 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
743 Parent::contentsMouseReleaseEvent(e);
744}
745
746void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
747{
748 //QPoint p(contentsToViewport(e->pos()));
749 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
750 Parent::contentsMouseMoveEvent(e);
751}
752
753void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
754{
755 QPoint p(contentsToViewport(e->pos()));
756 ConfigItem* item = (ConfigItem*)itemAt(p);
757 struct menu *menu;
758 enum prop_type ptype;
759
760 if (!item)
761 goto skip;
762 if (item->goParent) {
763 emit parentSelected();
764 goto skip;
765 }
766 menu = item->menu;
767 if (!menu)
768 goto skip;
769 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
770 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
771 emit menuSelected(menu);
772 else if (menu->sym)
773 changeValue(item);
774
775skip:
776 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
777 Parent::contentsMouseDoubleClickEvent(e);
778}
779
780void ConfigList::focusInEvent(QFocusEvent *e)
781{
Roman Zippelb65a47e2006-06-08 22:12:47 -0700782 struct menu *menu = NULL;
783
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784 Parent::focusInEvent(e);
785
Roman Zippelb65a47e2006-06-08 22:12:47 -0700786 ConfigItem* item = (ConfigItem *)currentItem();
787 if (item) {
788 setSelected(item, TRUE);
789 menu = item->menu;
790 }
791 emit gotFocus(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700792}
793
Roman Zippel7fc925f2006-06-08 22:12:46 -0700794void ConfigList::contextMenuEvent(QContextMenuEvent *e)
795{
796 if (e->y() <= header()->geometry().bottom()) {
797 if (!headerPopup) {
798 QAction *action;
799
800 headerPopup = new QPopupMenu(this);
801 action = new QAction("Show Name", 0, this);
802 action->setToggleAction(TRUE);
803 connect(action, SIGNAL(toggled(bool)),
804 parent(), SLOT(setShowName(bool)));
805 connect(parent(), SIGNAL(showNameChanged(bool)),
806 action, SLOT(setOn(bool)));
807 action->setOn(showName);
808 action->addTo(headerPopup);
809 action = new QAction("Show Range", 0, this);
810 action->setToggleAction(TRUE);
811 connect(action, SIGNAL(toggled(bool)),
812 parent(), SLOT(setShowRange(bool)));
813 connect(parent(), SIGNAL(showRangeChanged(bool)),
814 action, SLOT(setOn(bool)));
815 action->setOn(showRange);
816 action->addTo(headerPopup);
817 action = new QAction("Show Data", 0, this);
818 action->setToggleAction(TRUE);
819 connect(action, SIGNAL(toggled(bool)),
820 parent(), SLOT(setShowData(bool)));
821 connect(parent(), SIGNAL(showDataChanged(bool)),
822 action, SLOT(setOn(bool)));
823 action->setOn(showData);
824 action->addTo(headerPopup);
825 }
826 headerPopup->exec(e->globalPos());
827 e->accept();
828 } else
829 e->ignore();
830}
831
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832ConfigView* ConfigView::viewList;
833
Roman Zippel7fc925f2006-06-08 22:12:46 -0700834ConfigView::ConfigView(QWidget* parent, const char *name)
835 : Parent(parent, name)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836{
Roman Zippel7fc925f2006-06-08 22:12:46 -0700837 list = new ConfigList(this, name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838 lineEdit = new ConfigLineEdit(this);
839 lineEdit->hide();
840
841 this->nextView = viewList;
842 viewList = this;
843}
844
845ConfigView::~ConfigView(void)
846{
847 ConfigView** vp;
848
849 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
850 if (*vp == this) {
851 *vp = nextView;
852 break;
853 }
854 }
855}
856
Roman Zippel7fc925f2006-06-08 22:12:46 -0700857void ConfigView::setShowAll(bool b)
858{
859 if (list->showAll != b) {
860 list->showAll = b;
861 list->updateListAll();
862 emit showAllChanged(b);
863 }
864}
865
866void ConfigView::setShowName(bool b)
867{
868 if (list->showName != b) {
869 list->showName = b;
870 list->reinit();
871 emit showNameChanged(b);
872 }
873}
874
875void ConfigView::setShowRange(bool b)
876{
877 if (list->showRange != b) {
878 list->showRange = b;
879 list->reinit();
880 emit showRangeChanged(b);
881 }
882}
883
884void ConfigView::setShowData(bool b)
885{
886 if (list->showData != b) {
887 list->showData = b;
888 list->reinit();
889 emit showDataChanged(b);
890 }
891}
892
893void ConfigList::setAllOpen(bool open)
894{
895 QListViewItemIterator it(this);
896
897 for (; it.current(); it++)
898 it.current()->setOpen(open);
899}
900
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901void ConfigView::updateList(ConfigItem* item)
902{
903 ConfigView* v;
904
905 for (v = viewList; v; v = v->nextView)
906 v->list->updateList(item);
907}
908
909void ConfigView::updateListAll(void)
910{
911 ConfigView* v;
912
913 for (v = viewList; v; v = v->nextView)
914 v->list->updateListAll();
915}
916
Roman Zippel43bf6122006-06-08 22:12:45 -0700917ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
918 : Parent(parent, name), menu(0)
919{
Roman Zippel7fc925f2006-06-08 22:12:46 -0700920 if (name) {
921 configSettings->beginGroup(name);
922 _showDebug = configSettings->readBoolEntry("/showDebug", false);
923 configSettings->endGroup();
924 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
925 }
926}
927
928void ConfigInfoView::saveSettings(void)
929{
930 if (name()) {
931 configSettings->beginGroup(name());
932 configSettings->writeEntry("/showDebug", showDebug());
933 configSettings->endGroup();
934 }
Roman Zippel43bf6122006-06-08 22:12:45 -0700935}
936
937void ConfigInfoView::setShowDebug(bool b)
938{
939 if (_showDebug != b) {
940 _showDebug = b;
941 if (menu)
942 menuInfo();
Roman Zippelab45d192006-06-08 22:12:47 -0700943 else if (sym)
944 symbolInfo();
Roman Zippel43bf6122006-06-08 22:12:45 -0700945 emit showDebugChanged(b);
946 }
947}
948
949void ConfigInfoView::setInfo(struct menu *m)
950{
Roman Zippelb65a47e2006-06-08 22:12:47 -0700951 if (menu == m)
952 return;
Roman Zippel43bf6122006-06-08 22:12:45 -0700953 menu = m;
954 if (!menu)
955 clear();
956 else
957 menuInfo();
958}
959
960void ConfigInfoView::setSource(const QString& name)
961{
962 const char *p = name.latin1();
963
964 menu = NULL;
Roman Zippelab45d192006-06-08 22:12:47 -0700965 sym = NULL;
Roman Zippel43bf6122006-06-08 22:12:45 -0700966
967 switch (p[0]) {
968 case 'm':
Roman Zippelab45d192006-06-08 22:12:47 -0700969 struct menu *m;
970
971 if (sscanf(p, "m%p", &m) == 1 && menu != m) {
972 menu = m;
Roman Zippel43bf6122006-06-08 22:12:45 -0700973 menuInfo();
Roman Zippelb65a47e2006-06-08 22:12:47 -0700974 emit menuSelected(menu);
Roman Zippelab45d192006-06-08 22:12:47 -0700975 }
976 break;
977 case 's':
978 struct symbol *s;
979
980 if (sscanf(p, "s%p", &s) == 1 && sym != s) {
981 sym = s;
982 symbolInfo();
983 }
Roman Zippel43bf6122006-06-08 22:12:45 -0700984 break;
985 }
986}
987
Roman Zippelab45d192006-06-08 22:12:47 -0700988void ConfigInfoView::symbolInfo(void)
989{
990 QString str;
991
992 str += "<big>Symbol: <b>";
993 str += print_filter(sym->name);
994 str += "</b></big><br><br>value: ";
995 str += print_filter(sym_get_string_value(sym));
996 str += "<br>visibility: ";
997 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
998 str += "<br>";
999 str += debug_info(sym);
1000
1001 setText(str);
1002}
1003
Roman Zippel43bf6122006-06-08 22:12:45 -07001004void ConfigInfoView::menuInfo(void)
1005{
1006 struct symbol* sym;
1007 QString head, debug, help;
1008
1009 sym = menu->sym;
1010 if (sym) {
1011 if (menu->prompt) {
1012 head += "<big><b>";
1013 head += print_filter(_(menu->prompt->text));
1014 head += "</b></big>";
1015 if (sym->name) {
1016 head += " (";
Roman Zippelab45d192006-06-08 22:12:47 -07001017 if (showDebug())
1018 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001019 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001020 if (showDebug())
1021 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001022 head += ")";
1023 }
1024 } else if (sym->name) {
1025 head += "<big><b>";
Roman Zippelab45d192006-06-08 22:12:47 -07001026 if (showDebug())
1027 head += QString().sprintf("<a href=\"s%p\">", sym);
Roman Zippel43bf6122006-06-08 22:12:45 -07001028 head += print_filter(sym->name);
Roman Zippelab45d192006-06-08 22:12:47 -07001029 if (showDebug())
1030 head += "</a>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001031 head += "</b></big>";
1032 }
1033 head += "<br><br>";
1034
1035 if (showDebug())
1036 debug = debug_info(sym);
1037
1038 help = print_filter(_(sym->help));
1039 } else if (menu->prompt) {
1040 head += "<big><b>";
1041 head += print_filter(_(menu->prompt->text));
1042 head += "</b></big><br><br>";
1043 if (showDebug()) {
1044 if (menu->prompt->visible.expr) {
1045 debug += "&nbsp;&nbsp;dep: ";
1046 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1047 debug += "<br><br>";
1048 }
1049 }
1050 }
1051 if (showDebug())
1052 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1053
1054 setText(head + debug + help);
1055}
1056
1057QString ConfigInfoView::debug_info(struct symbol *sym)
1058{
1059 QString debug;
1060
1061 debug += "type: ";
1062 debug += print_filter(sym_type_name(sym->type));
1063 if (sym_is_choice(sym))
1064 debug += " (choice)";
1065 debug += "<br>";
1066 if (sym->rev_dep.expr) {
1067 debug += "reverse dep: ";
1068 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1069 debug += "<br>";
1070 }
1071 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1072 switch (prop->type) {
1073 case P_PROMPT:
1074 case P_MENU:
Roman Zippelab45d192006-06-08 22:12:47 -07001075 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
Roman Zippel43bf6122006-06-08 22:12:45 -07001076 debug += print_filter(_(prop->text));
Roman Zippelab45d192006-06-08 22:12:47 -07001077 debug += "</a><br>";
Roman Zippel43bf6122006-06-08 22:12:45 -07001078 break;
1079 case P_DEFAULT:
1080 debug += "default: ";
1081 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1082 debug += "<br>";
1083 break;
1084 case P_CHOICE:
1085 if (sym_is_choice(sym)) {
1086 debug += "choice: ";
1087 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1088 debug += "<br>";
1089 }
1090 break;
1091 case P_SELECT:
1092 debug += "select: ";
1093 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1094 debug += "<br>";
1095 break;
1096 case P_RANGE:
1097 debug += "range: ";
1098 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1099 debug += "<br>";
1100 break;
1101 default:
1102 debug += "unknown property: ";
1103 debug += prop_get_type_name(prop->type);
1104 debug += "<br>";
1105 }
1106 if (prop->visible.expr) {
1107 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1108 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1109 debug += "<br>";
1110 }
1111 }
1112 debug += "<br>";
1113
1114 return debug;
1115}
1116
1117QString ConfigInfoView::print_filter(const QString &str)
1118{
1119 QRegExp re("[<>&\"\\n]");
1120 QString res = str;
1121 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1122 switch (res[i].latin1()) {
1123 case '<':
1124 res.replace(i, 1, "&lt;");
1125 i += 4;
1126 break;
1127 case '>':
1128 res.replace(i, 1, "&gt;");
1129 i += 4;
1130 break;
1131 case '&':
1132 res.replace(i, 1, "&amp;");
1133 i += 5;
1134 break;
1135 case '"':
1136 res.replace(i, 1, "&quot;");
1137 i += 6;
1138 break;
1139 case '\n':
1140 res.replace(i, 1, "<br>");
1141 i += 4;
1142 break;
1143 }
1144 }
1145 return res;
1146}
1147
Roman Zippelab45d192006-06-08 22:12:47 -07001148void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
Roman Zippel43bf6122006-06-08 22:12:45 -07001149{
Roman Zippelab45d192006-06-08 22:12:47 -07001150 QString* text = reinterpret_cast<QString*>(data);
1151 QString str2 = print_filter(str);
1152
1153 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1154 *text += QString().sprintf("<a href=\"s%p\">", sym);
1155 *text += str2;
1156 *text += "</a>";
1157 } else
1158 *text += str2;
Roman Zippel43bf6122006-06-08 22:12:45 -07001159}
1160
Roman Zippel7fc925f2006-06-08 22:12:46 -07001161QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1162{
1163 QPopupMenu* popup = Parent::createPopupMenu(pos);
1164 QAction* action = new QAction("Show Debug Info", 0, popup);
1165 action->setToggleAction(TRUE);
1166 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1167 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1168 action->setOn(showDebug());
1169 popup->insertSeparator();
1170 action->addTo(popup);
1171 return popup;
1172}
1173
1174void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1175{
1176 Parent::contentsContextMenuEvent(e);
1177}
1178
1179ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
1180 : Parent(parent, name), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001181{
1182 setCaption("Search Config");
1183
1184 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1185 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1186 layout2->addWidget(new QLabel("Find:", this));
1187 editField = new QLineEdit(this);
1188 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1189 layout2->addWidget(editField);
1190 searchButton = new QPushButton("Search", this);
1191 searchButton->setAutoDefault(FALSE);
1192 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1193 layout2->addWidget(searchButton);
1194 layout1->addLayout(layout2);
1195
Roman Zippel7fc925f2006-06-08 22:12:46 -07001196 split = new QSplitter(this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001197 split->setOrientation(QSplitter::Vertical);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001198 list = new ConfigView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001199 list->list->mode = listMode;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001200 info = new ConfigInfoView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001201 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1202 info, SLOT(setInfo(struct menu *)));
1203 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001204
1205 if (name) {
1206 int x, y, width, height;
1207 bool ok;
1208
1209 configSettings->beginGroup(name);
1210 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1211 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1212 resize(width, height);
1213 x = configSettings->readNumEntry("/window x", 0, &ok);
1214 if (ok)
1215 y = configSettings->readNumEntry("/window y", 0, &ok);
1216 if (ok)
1217 move(x, y);
1218 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1219 if (ok)
1220 split->setSizes(sizes);
1221 configSettings->endGroup();
1222 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1223 }
1224}
1225
1226void ConfigSearchWindow::saveSettings(void)
1227{
1228 if (name()) {
1229 configSettings->beginGroup(name());
1230 configSettings->writeEntry("/window x", pos().x());
1231 configSettings->writeEntry("/window y", pos().y());
1232 configSettings->writeEntry("/window width", size().width());
1233 configSettings->writeEntry("/window height", size().height());
1234 configSettings->writeSizes("/split", split->sizes());
1235 configSettings->endGroup();
1236 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001237}
1238
1239void ConfigSearchWindow::search(void)
1240{
1241 struct symbol **p;
1242 struct property *prop;
1243 ConfigItem *lastItem = NULL;
1244
1245 free(result);
1246 list->list->clear();
1247
1248 result = sym_re_search(editField->text().latin1());
1249 if (!result)
1250 return;
1251 for (p = result; *p; p++) {
1252 for_all_prompts((*p), prop)
1253 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1254 menu_is_visible(prop->menu));
1255 }
1256}
1257
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258/*
1259 * Construct the complete config widget
1260 */
1261ConfigMainWindow::ConfigMainWindow(void)
Roman Zippelf12aa702006-11-25 11:09:31 -08001262 : searchWindow(0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263{
1264 QMenuBar* menu;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001265 bool ok;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266 int x, y, width, height;
1267
1268 QWidget *d = configApp->desktop();
1269
Roman Zippel7fc925f2006-06-08 22:12:46 -07001270 width = configSettings->readNumEntry("/window width", d->width() - 64);
1271 height = configSettings->readNumEntry("/window height", d->height() - 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272 resize(width, height);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001273 x = configSettings->readNumEntry("/window x", 0, &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001274 if (ok)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001275 y = configSettings->readNumEntry("/window y", 0, &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276 if (ok)
1277 move(x, y);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001278
1279 split1 = new QSplitter(this);
1280 split1->setOrientation(QSplitter::Horizontal);
1281 setCentralWidget(split1);
1282
Roman Zippel7fc925f2006-06-08 22:12:46 -07001283 menuView = new ConfigView(split1, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 menuList = menuView->list;
1285
1286 split2 = new QSplitter(split1);
1287 split2->setOrientation(QSplitter::Vertical);
1288
1289 // create config tree
Roman Zippel7fc925f2006-06-08 22:12:46 -07001290 configView = new ConfigView(split2, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291 configList = configView->list;
1292
Roman Zippel7fc925f2006-06-08 22:12:46 -07001293 helpText = new ConfigInfoView(split2, "help");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 helpText->setTextFormat(Qt::RichText);
1295
1296 setTabOrder(configList, helpText);
1297 configList->setFocus();
1298
1299 menu = menuBar();
1300 toolBar = new QToolBar("Tools", this);
1301
1302 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
1303 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1304 backAction->setEnabled(FALSE);
1305 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
1306 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1307 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
1308 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1309 QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
1310 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1311 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
1312 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001313 QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this);
1314 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
1316 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1317 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
1318 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1319 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
1320 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1321
1322 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
1323 showNameAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001324 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1325 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1326 showNameAction->setOn(configView->showName());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
1328 showRangeAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001329 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1330 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001331 showRangeAction->setOn(configList->showRange);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
1333 showDataAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001334 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1335 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 showDataAction->setOn(configList->showData);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
1338 showAllAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001339 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1340 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341 showAllAction->setOn(configList->showAll);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
1343 showDebugAction->setToggleAction(TRUE);
Roman Zippel43bf6122006-06-08 22:12:45 -07001344 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1345 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
Roman Zippel7fc925f2006-06-08 22:12:46 -07001346 showDebugAction->setOn(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347
1348 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
1349 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1350 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
1351 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1352
1353 // init tool bar
1354 backAction->addTo(toolBar);
1355 toolBar->addSeparator();
1356 loadAction->addTo(toolBar);
1357 saveAction->addTo(toolBar);
1358 toolBar->addSeparator();
1359 singleViewAction->addTo(toolBar);
1360 splitViewAction->addTo(toolBar);
1361 fullViewAction->addTo(toolBar);
1362
1363 // create config menu
1364 QPopupMenu* config = new QPopupMenu(this);
1365 menu->insertItem("&File", config);
1366 loadAction->addTo(config);
1367 saveAction->addTo(config);
1368 saveAsAction->addTo(config);
1369 config->insertSeparator();
Roman Zippel43bf6122006-06-08 22:12:45 -07001370 searchAction->addTo(config);
1371 config->insertSeparator();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 quitAction->addTo(config);
1373
1374 // create options menu
1375 QPopupMenu* optionMenu = new QPopupMenu(this);
1376 menu->insertItem("&Option", optionMenu);
1377 showNameAction->addTo(optionMenu);
1378 showRangeAction->addTo(optionMenu);
1379 showDataAction->addTo(optionMenu);
1380 optionMenu->insertSeparator();
1381 showAllAction->addTo(optionMenu);
1382 showDebugAction->addTo(optionMenu);
1383
1384 // create help menu
1385 QPopupMenu* helpMenu = new QPopupMenu(this);
1386 menu->insertSeparator();
1387 menu->insertItem("&Help", helpMenu);
1388 showIntroAction->addTo(helpMenu);
1389 showAboutAction->addTo(helpMenu);
1390
Roman Zippel43bf6122006-06-08 22:12:45 -07001391 connect(configList, SIGNAL(menuChanged(struct menu *)),
1392 helpText, SLOT(setInfo(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 connect(configList, SIGNAL(menuSelected(struct menu *)),
1394 SLOT(changeMenu(struct menu *)));
1395 connect(configList, SIGNAL(parentSelected()),
1396 SLOT(goBack()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001397 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1398 helpText, SLOT(setInfo(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001399 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1400 SLOT(changeMenu(struct menu *)));
1401
Roman Zippelb65a47e2006-06-08 22:12:47 -07001402 connect(configList, SIGNAL(gotFocus(struct menu *)),
1403 helpText, SLOT(setInfo(struct menu *)));
1404 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1405 helpText, SLOT(setInfo(struct menu *)));
1406 connect(menuList, SIGNAL(gotFocus(struct menu *)),
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 SLOT(listFocusChanged(void)));
Roman Zippelb65a47e2006-06-08 22:12:47 -07001408 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1409 SLOT(setMenuLink(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410
Roman Zippel7fc925f2006-06-08 22:12:46 -07001411 QString listMode = configSettings->readEntry("/listMode", "symbol");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 if (listMode == "single")
1413 showSingleView();
1414 else if (listMode == "full")
1415 showFullView();
1416 else /*if (listMode == "split")*/
1417 showSplitView();
1418
1419 // UI setup done, restore splitter positions
Roman Zippel7fc925f2006-06-08 22:12:46 -07001420 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421 if (ok)
1422 split1->setSizes(sizes);
1423
Roman Zippel7fc925f2006-06-08 22:12:46 -07001424 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 if (ok)
1426 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427}
1428
Linus Torvalds1da177e2005-04-16 15:20:36 -07001429void ConfigMainWindow::loadConfig(void)
1430{
1431 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1432 if (s.isNull())
1433 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001434 if (conf_read(QFile::encodeName(s)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001435 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1436 ConfigView::updateListAll();
1437}
1438
1439void ConfigMainWindow::saveConfig(void)
1440{
1441 if (conf_write(NULL))
1442 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1443}
1444
1445void ConfigMainWindow::saveConfigAs(void)
1446{
1447 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1448 if (s.isNull())
1449 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001450 if (conf_write(QFile::encodeName(s)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1452}
1453
Roman Zippel43bf6122006-06-08 22:12:45 -07001454void ConfigMainWindow::searchConfig(void)
1455{
1456 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001457 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001458 searchWindow->show();
1459}
1460
Linus Torvalds1da177e2005-04-16 15:20:36 -07001461void ConfigMainWindow::changeMenu(struct menu *menu)
1462{
1463 configList->setRootMenu(menu);
1464 backAction->setEnabled(TRUE);
1465}
1466
Roman Zippelb65a47e2006-06-08 22:12:47 -07001467void ConfigMainWindow::setMenuLink(struct menu *menu)
1468{
1469 struct menu *parent;
1470 ConfigList* list = NULL;
1471 ConfigItem* item;
1472
1473 if (!menu_is_visible(menu) && !configView->showAll())
1474 return;
1475
1476 switch (configList->mode) {
1477 case singleMode:
1478 list = configList;
1479 parent = menu_get_parent_menu(menu);
1480 if (!parent)
1481 return;
1482 list->setRootMenu(parent);
1483 break;
1484 case symbolMode:
1485 if (menu->flags & MENU_ROOT) {
1486 configList->setRootMenu(menu);
1487 configList->clearSelection();
1488 list = menuList;
1489 } else {
1490 list = configList;
1491 parent = menu_get_parent_menu(menu->parent);
1492 if (!parent)
1493 return;
1494 item = menuList->findConfigItem(parent);
1495 if (item) {
1496 menuList->setSelected(item, TRUE);
1497 menuList->ensureItemVisible(item);
1498 }
1499 list->setRootMenu(parent);
1500 }
1501 break;
1502 case fullMode:
1503 list = configList;
1504 break;
1505 }
1506
1507 if (list) {
1508 item = list->findConfigItem(menu);
1509 if (item) {
1510 list->setSelected(item, TRUE);
1511 list->ensureItemVisible(item);
1512 list->setFocus();
1513 }
1514 }
1515}
1516
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517void ConfigMainWindow::listFocusChanged(void)
1518{
Roman Zippelb65a47e2006-06-08 22:12:47 -07001519 if (menuList->mode == menuMode)
1520 configList->clearSelection();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521}
1522
1523void ConfigMainWindow::goBack(void)
1524{
1525 ConfigItem* item;
1526
1527 configList->setParentMenu();
1528 if (configList->rootEntry == &rootmenu)
1529 backAction->setEnabled(FALSE);
1530 item = (ConfigItem*)menuList->selectedItem();
1531 while (item) {
1532 if (item->menu == configList->rootEntry) {
1533 menuList->setSelected(item, TRUE);
1534 break;
1535 }
1536 item = (ConfigItem*)item->parent();
1537 }
1538}
1539
1540void ConfigMainWindow::showSingleView(void)
1541{
1542 menuView->hide();
1543 menuList->setRootMenu(0);
1544 configList->mode = singleMode;
1545 if (configList->rootEntry == &rootmenu)
1546 configList->updateListAll();
1547 else
1548 configList->setRootMenu(&rootmenu);
1549 configList->setAllOpen(TRUE);
1550 configList->setFocus();
1551}
1552
1553void ConfigMainWindow::showSplitView(void)
1554{
1555 configList->mode = symbolMode;
1556 if (configList->rootEntry == &rootmenu)
1557 configList->updateListAll();
1558 else
1559 configList->setRootMenu(&rootmenu);
1560 configList->setAllOpen(TRUE);
1561 configApp->processEvents();
1562 menuList->mode = menuMode;
1563 menuList->setRootMenu(&rootmenu);
1564 menuList->setAllOpen(TRUE);
1565 menuView->show();
1566 menuList->setFocus();
1567}
1568
1569void ConfigMainWindow::showFullView(void)
1570{
1571 menuView->hide();
1572 menuList->setRootMenu(0);
1573 configList->mode = fullMode;
1574 if (configList->rootEntry == &rootmenu)
1575 configList->updateListAll();
1576 else
1577 configList->setRootMenu(&rootmenu);
1578 configList->setAllOpen(FALSE);
1579 configList->setFocus();
1580}
1581
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582/*
1583 * ask for saving configuration before quitting
1584 * TODO ask only when something changed
1585 */
1586void ConfigMainWindow::closeEvent(QCloseEvent* e)
1587{
1588 if (!sym_change_count) {
1589 e->accept();
1590 return;
1591 }
1592 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1593 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1594 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1595 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1596 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1597 switch (mb.exec()) {
1598 case QMessageBox::Yes:
1599 conf_write(NULL);
1600 case QMessageBox::No:
1601 e->accept();
1602 break;
1603 case QMessageBox::Cancel:
1604 e->ignore();
1605 break;
1606 }
1607}
1608
1609void ConfigMainWindow::showIntro(void)
1610{
1611 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1612 "For each option, a blank box indicates the feature is disabled, a check\n"
1613 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1614 "as a module. Clicking on the box will cycle through the three states.\n\n"
1615 "If you do not see an option (e.g., a device driver) that you believe\n"
1616 "should be present, try turning on Show All Options under the Options menu.\n"
1617 "Although there is no cross reference yet to help you figure out what other\n"
1618 "options must be enabled to support the option you are interested in, you can\n"
1619 "still view the help of a grayed-out option.\n\n"
1620 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1621 "which you can then match by examining other options.\n\n";
1622
1623 QMessageBox::information(this, "qconf", str);
1624}
1625
1626void ConfigMainWindow::showAbout(void)
1627{
1628 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1629 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1630
1631 QMessageBox::information(this, "qconf", str);
1632}
1633
1634void ConfigMainWindow::saveSettings(void)
1635{
Roman Zippel7fc925f2006-06-08 22:12:46 -07001636 configSettings->writeEntry("/window x", pos().x());
1637 configSettings->writeEntry("/window y", pos().y());
1638 configSettings->writeEntry("/window width", size().width());
1639 configSettings->writeEntry("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001640
1641 QString entry;
1642 switch(configList->mode) {
1643 case singleMode :
1644 entry = "single";
1645 break;
1646
1647 case symbolMode :
1648 entry = "split";
1649 break;
1650
1651 case fullMode :
1652 entry = "full";
1653 break;
1654 }
Roman Zippel7fc925f2006-06-08 22:12:46 -07001655 configSettings->writeEntry("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001656
Roman Zippel7fc925f2006-06-08 22:12:46 -07001657 configSettings->writeSizes("/split1", split1->sizes());
1658 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659}
1660
1661void fixup_rootmenu(struct menu *menu)
1662{
1663 struct menu *child;
1664 static int menu_cnt = 0;
1665
1666 menu->flags |= MENU_ROOT;
1667 for (child = menu->list; child; child = child->next) {
1668 if (child->prompt && child->prompt->type == P_MENU) {
1669 menu_cnt++;
1670 fixup_rootmenu(child);
1671 menu_cnt--;
1672 } else if (!menu_cnt)
1673 fixup_rootmenu(child);
1674 }
1675}
1676
1677static const char *progname;
1678
1679static void usage(void)
1680{
1681 printf("%s <config>\n", progname);
1682 exit(0);
1683}
1684
1685int main(int ac, char** av)
1686{
1687 ConfigMainWindow* v;
1688 const char *name;
1689
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001690 bindtextdomain(PACKAGE, LOCALEDIR);
1691 textdomain(PACKAGE);
1692
Linus Torvalds1da177e2005-04-16 15:20:36 -07001693#ifndef LKC_DIRECT_LINK
1694 kconfig_load();
1695#endif
1696
1697 progname = av[0];
1698 configApp = new QApplication(ac, av);
1699 if (ac > 1 && av[1][0] == '-') {
1700 switch (av[1][1]) {
1701 case 'h':
1702 case '?':
1703 usage();
1704 }
1705 name = av[2];
1706 } else
1707 name = av[1];
1708 if (!name)
1709 usage();
1710
1711 conf_parse(name);
1712 fixup_rootmenu(&rootmenu);
1713 conf_read(NULL);
1714 //zconfdump(stdout);
1715
Roman Zippel7fc925f2006-06-08 22:12:46 -07001716 configSettings = new ConfigSettings();
1717 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 v = new ConfigMainWindow();
1719
1720 //zconfdump(stdout);
Roman Zippel43bf6122006-06-08 22:12:45 -07001721 configApp->setMainWidget(v);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001722 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1723 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001724 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 configApp->exec();
1726
Roman Zippel7fc925f2006-06-08 22:12:46 -07001727 configSettings->endGroup();
1728 delete configSettings;
1729
Linus Torvalds1da177e2005-04-16 15:20:36 -07001730 return 0;
1731}