blob: f3f86e735a87592c5f640233683f43ff46aee469 [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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700384void ConfigList::updateSelection(void)
385{
386 struct menu *menu;
387 enum prop_type type;
388
389 ConfigItem* item = (ConfigItem*)selectedItem();
390 if (!item)
391 return;
392
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 menu = item->menu;
Roman Zippel43bf6122006-06-08 22:12:45 -0700394 emit menuChanged(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395 if (!menu)
396 return;
397 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
398 if (mode == menuMode && type == P_MENU)
399 emit menuSelected(menu);
400}
401
402void ConfigList::updateList(ConfigItem* item)
403{
404 ConfigItem* last = 0;
405
Roman Zippel43bf6122006-06-08 22:12:45 -0700406 if (!rootEntry) {
407 if (mode != listMode)
408 goto update;
409 QListViewItemIterator it(this);
410 ConfigItem* item;
411
412 for (; it.current(); ++it) {
413 item = (ConfigItem*)it.current();
414 if (!item->menu)
415 continue;
416 item->testUpdateMenu(menu_is_visible(item->menu));
417 }
418 return;
419 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420
421 if (rootEntry != &rootmenu && (mode == singleMode ||
422 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
423 item = firstChild();
424 if (!item)
425 item = new ConfigItem(this, 0, true);
426 last = item;
427 }
428 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
429 rootEntry->sym && rootEntry->prompt) {
430 item = last ? last->nextSibling() : firstChild();
431 if (!item)
432 item = new ConfigItem(this, last, rootEntry, true);
433 else
434 item->testUpdateMenu(true);
435
436 updateMenuList(item, rootEntry);
437 triggerUpdate();
438 return;
439 }
440update:
441 updateMenuList(this, rootEntry);
442 triggerUpdate();
443}
444
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445void ConfigList::setValue(ConfigItem* item, tristate val)
446{
447 struct symbol* sym;
448 int type;
449 tristate oldval;
450
451 sym = item->menu ? item->menu->sym : 0;
452 if (!sym)
453 return;
454
455 type = sym_get_type(sym);
456 switch (type) {
457 case S_BOOLEAN:
458 case S_TRISTATE:
459 oldval = sym_get_tristate_value(sym);
460
461 if (!sym_set_tristate_value(sym, val))
462 return;
463 if (oldval == no && item->menu->list)
464 item->setOpen(TRUE);
465 parent()->updateList(item);
466 break;
467 }
468}
469
470void ConfigList::changeValue(ConfigItem* item)
471{
472 struct symbol* sym;
473 struct menu* menu;
474 int type, oldexpr, newexpr;
475
476 menu = item->menu;
477 if (!menu)
478 return;
479 sym = menu->sym;
480 if (!sym) {
481 if (item->menu->list)
482 item->setOpen(!item->isOpen());
483 return;
484 }
485
486 type = sym_get_type(sym);
487 switch (type) {
488 case S_BOOLEAN:
489 case S_TRISTATE:
490 oldexpr = sym_get_tristate_value(sym);
491 newexpr = sym_toggle_tristate_value(sym);
492 if (item->menu->list) {
493 if (oldexpr == newexpr)
494 item->setOpen(!item->isOpen());
495 else if (oldexpr == no)
496 item->setOpen(TRUE);
497 }
498 if (oldexpr != newexpr)
499 parent()->updateList(item);
500 break;
501 case S_INT:
502 case S_HEX:
503 case S_STRING:
504#if QT_VERSION >= 300
505 if (colMap[dataColIdx] >= 0)
506 item->startRename(colMap[dataColIdx]);
507 else
508#endif
509 parent()->lineEdit->show(item);
510 break;
511 }
512}
513
514void ConfigList::setRootMenu(struct menu *menu)
515{
516 enum prop_type type;
517
518 if (rootEntry == menu)
519 return;
520 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
521 if (type != P_MENU)
522 return;
523 updateMenuList(this, 0);
524 rootEntry = menu;
525 updateListAll();
526 setSelected(currentItem(), hasFocus());
527}
528
529void ConfigList::setParentMenu(void)
530{
531 ConfigItem* item;
532 struct menu *oldroot;
533
534 oldroot = rootEntry;
535 if (rootEntry == &rootmenu)
536 return;
537 setRootMenu(menu_get_parent_menu(rootEntry->parent));
538
539 QListViewItemIterator it(this);
540 for (; (item = (ConfigItem*)it.current()); it++) {
541 if (item->menu == oldroot) {
542 setCurrentItem(item);
543 ensureItemVisible(item);
544 break;
545 }
546 }
547}
548
Roman Zippel7fc925f2006-06-08 22:12:46 -0700549/*
550 * update all the children of a menu entry
551 * removes/adds the entries from the parent widget as necessary
552 *
553 * parent: either the menu list widget or a menu entry widget
554 * menu: entry to be updated
555 */
556template <class P>
557void ConfigList::updateMenuList(P* parent, struct menu* menu)
558{
559 struct menu* child;
560 ConfigItem* item;
561 ConfigItem* last;
562 bool visible;
563 enum prop_type type;
564
565 if (!menu) {
566 while ((item = parent->firstChild()))
567 delete item;
568 return;
569 }
570
571 last = parent->firstChild();
572 if (last && !last->goParent)
573 last = 0;
574 for (child = menu->list; child; child = child->next) {
575 item = last ? last->nextSibling() : parent->firstChild();
576 type = child->prompt ? child->prompt->type : P_UNKNOWN;
577
578 switch (mode) {
579 case menuMode:
580 if (!(child->flags & MENU_ROOT))
581 goto hide;
582 break;
583 case symbolMode:
584 if (child->flags & MENU_ROOT)
585 goto hide;
586 break;
587 default:
588 break;
589 }
590
591 visible = menu_is_visible(child);
592 if (showAll || visible) {
593 if (!item || item->menu != child)
594 item = new ConfigItem(parent, last, child, visible);
595 else
596 item->testUpdateMenu(visible);
597
598 if (mode == fullMode || mode == menuMode || type != P_MENU)
599 updateMenuList(item, child);
600 else
601 updateMenuList(item, 0);
602 last = item;
603 continue;
604 }
605 hide:
606 if (item && item->menu == child) {
607 last = parent->firstChild();
608 if (last == item)
609 last = 0;
610 else while (last->nextSibling() != item)
611 last = last->nextSibling();
612 delete item;
613 }
614 }
615}
616
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617void ConfigList::keyPressEvent(QKeyEvent* ev)
618{
619 QListViewItem* i = currentItem();
620 ConfigItem* item;
621 struct menu *menu;
622 enum prop_type type;
623
Roman Zippel43bf6122006-06-08 22:12:45 -0700624 if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625 emit parentSelected();
626 ev->accept();
627 return;
628 }
629
630 if (!i) {
631 Parent::keyPressEvent(ev);
632 return;
633 }
634 item = (ConfigItem*)i;
635
636 switch (ev->key()) {
637 case Key_Return:
638 case Key_Enter:
639 if (item->goParent) {
640 emit parentSelected();
641 break;
642 }
643 menu = item->menu;
644 if (!menu)
645 break;
646 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
647 if (type == P_MENU && rootEntry != menu &&
648 mode != fullMode && mode != menuMode) {
649 emit menuSelected(menu);
650 break;
651 }
652 case Key_Space:
653 changeValue(item);
654 break;
655 case Key_N:
656 setValue(item, no);
657 break;
658 case Key_M:
659 setValue(item, mod);
660 break;
661 case Key_Y:
662 setValue(item, yes);
663 break;
664 default:
665 Parent::keyPressEvent(ev);
666 return;
667 }
668 ev->accept();
669}
670
671void ConfigList::contentsMousePressEvent(QMouseEvent* e)
672{
673 //QPoint p(contentsToViewport(e->pos()));
674 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
675 Parent::contentsMousePressEvent(e);
676}
677
678void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
679{
680 QPoint p(contentsToViewport(e->pos()));
681 ConfigItem* item = (ConfigItem*)itemAt(p);
682 struct menu *menu;
683 enum prop_type ptype;
684 const QPixmap* pm;
685 int idx, x;
686
687 if (!item)
688 goto skip;
689
690 menu = item->menu;
691 x = header()->offset() + p.x();
692 idx = colRevMap[header()->sectionAt(x)];
693 switch (idx) {
694 case promptColIdx:
695 pm = item->pixmap(promptColIdx);
696 if (pm) {
697 int off = header()->sectionPos(0) + itemMargin() +
698 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
699 if (x >= off && x < off + pm->width()) {
700 if (item->goParent) {
701 emit parentSelected();
702 break;
703 } else if (!menu)
704 break;
705 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
706 if (ptype == P_MENU && rootEntry != menu &&
707 mode != fullMode && mode != menuMode)
708 emit menuSelected(menu);
709 else
710 changeValue(item);
711 }
712 }
713 break;
714 case noColIdx:
715 setValue(item, no);
716 break;
717 case modColIdx:
718 setValue(item, mod);
719 break;
720 case yesColIdx:
721 setValue(item, yes);
722 break;
723 case dataColIdx:
724 changeValue(item);
725 break;
726 }
727
728skip:
729 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
730 Parent::contentsMouseReleaseEvent(e);
731}
732
733void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
734{
735 //QPoint p(contentsToViewport(e->pos()));
736 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
737 Parent::contentsMouseMoveEvent(e);
738}
739
740void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
741{
742 QPoint p(contentsToViewport(e->pos()));
743 ConfigItem* item = (ConfigItem*)itemAt(p);
744 struct menu *menu;
745 enum prop_type ptype;
746
747 if (!item)
748 goto skip;
749 if (item->goParent) {
750 emit parentSelected();
751 goto skip;
752 }
753 menu = item->menu;
754 if (!menu)
755 goto skip;
756 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
757 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
758 emit menuSelected(menu);
759 else if (menu->sym)
760 changeValue(item);
761
762skip:
763 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
764 Parent::contentsMouseDoubleClickEvent(e);
765}
766
767void ConfigList::focusInEvent(QFocusEvent *e)
768{
769 Parent::focusInEvent(e);
770
771 QListViewItem* item = currentItem();
772 if (!item)
773 return;
774
775 setSelected(item, TRUE);
776 emit gotFocus();
777}
778
Roman Zippel7fc925f2006-06-08 22:12:46 -0700779void ConfigList::contextMenuEvent(QContextMenuEvent *e)
780{
781 if (e->y() <= header()->geometry().bottom()) {
782 if (!headerPopup) {
783 QAction *action;
784
785 headerPopup = new QPopupMenu(this);
786 action = new QAction("Show Name", 0, this);
787 action->setToggleAction(TRUE);
788 connect(action, SIGNAL(toggled(bool)),
789 parent(), SLOT(setShowName(bool)));
790 connect(parent(), SIGNAL(showNameChanged(bool)),
791 action, SLOT(setOn(bool)));
792 action->setOn(showName);
793 action->addTo(headerPopup);
794 action = new QAction("Show Range", 0, this);
795 action->setToggleAction(TRUE);
796 connect(action, SIGNAL(toggled(bool)),
797 parent(), SLOT(setShowRange(bool)));
798 connect(parent(), SIGNAL(showRangeChanged(bool)),
799 action, SLOT(setOn(bool)));
800 action->setOn(showRange);
801 action->addTo(headerPopup);
802 action = new QAction("Show Data", 0, this);
803 action->setToggleAction(TRUE);
804 connect(action, SIGNAL(toggled(bool)),
805 parent(), SLOT(setShowData(bool)));
806 connect(parent(), SIGNAL(showDataChanged(bool)),
807 action, SLOT(setOn(bool)));
808 action->setOn(showData);
809 action->addTo(headerPopup);
810 }
811 headerPopup->exec(e->globalPos());
812 e->accept();
813 } else
814 e->ignore();
815}
816
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817ConfigView* ConfigView::viewList;
818
Roman Zippel7fc925f2006-06-08 22:12:46 -0700819ConfigView::ConfigView(QWidget* parent, const char *name)
820 : Parent(parent, name)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821{
Roman Zippel7fc925f2006-06-08 22:12:46 -0700822 list = new ConfigList(this, name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 lineEdit = new ConfigLineEdit(this);
824 lineEdit->hide();
825
826 this->nextView = viewList;
827 viewList = this;
828}
829
830ConfigView::~ConfigView(void)
831{
832 ConfigView** vp;
833
834 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
835 if (*vp == this) {
836 *vp = nextView;
837 break;
838 }
839 }
840}
841
Roman Zippel7fc925f2006-06-08 22:12:46 -0700842void ConfigView::setShowAll(bool b)
843{
844 if (list->showAll != b) {
845 list->showAll = b;
846 list->updateListAll();
847 emit showAllChanged(b);
848 }
849}
850
851void ConfigView::setShowName(bool b)
852{
853 if (list->showName != b) {
854 list->showName = b;
855 list->reinit();
856 emit showNameChanged(b);
857 }
858}
859
860void ConfigView::setShowRange(bool b)
861{
862 if (list->showRange != b) {
863 list->showRange = b;
864 list->reinit();
865 emit showRangeChanged(b);
866 }
867}
868
869void ConfigView::setShowData(bool b)
870{
871 if (list->showData != b) {
872 list->showData = b;
873 list->reinit();
874 emit showDataChanged(b);
875 }
876}
877
878void ConfigList::setAllOpen(bool open)
879{
880 QListViewItemIterator it(this);
881
882 for (; it.current(); it++)
883 it.current()->setOpen(open);
884}
885
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886void ConfigView::updateList(ConfigItem* item)
887{
888 ConfigView* v;
889
890 for (v = viewList; v; v = v->nextView)
891 v->list->updateList(item);
892}
893
894void ConfigView::updateListAll(void)
895{
896 ConfigView* v;
897
898 for (v = viewList; v; v = v->nextView)
899 v->list->updateListAll();
900}
901
Roman Zippel43bf6122006-06-08 22:12:45 -0700902ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
903 : Parent(parent, name), menu(0)
904{
Roman Zippel7fc925f2006-06-08 22:12:46 -0700905 if (name) {
906 configSettings->beginGroup(name);
907 _showDebug = configSettings->readBoolEntry("/showDebug", false);
908 configSettings->endGroup();
909 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
910 }
911}
912
913void ConfigInfoView::saveSettings(void)
914{
915 if (name()) {
916 configSettings->beginGroup(name());
917 configSettings->writeEntry("/showDebug", showDebug());
918 configSettings->endGroup();
919 }
Roman Zippel43bf6122006-06-08 22:12:45 -0700920}
921
922void ConfigInfoView::setShowDebug(bool b)
923{
924 if (_showDebug != b) {
925 _showDebug = b;
926 if (menu)
927 menuInfo();
928 emit showDebugChanged(b);
929 }
930}
931
932void ConfigInfoView::setInfo(struct menu *m)
933{
934 menu = m;
935 if (!menu)
936 clear();
937 else
938 menuInfo();
939}
940
941void ConfigInfoView::setSource(const QString& name)
942{
943 const char *p = name.latin1();
944
945 menu = NULL;
946
947 switch (p[0]) {
948 case 'm':
949 if (sscanf(p, "m%p", &menu) == 1)
950 menuInfo();
951 break;
952 }
953}
954
955void ConfigInfoView::menuInfo(void)
956{
957 struct symbol* sym;
958 QString head, debug, help;
959
960 sym = menu->sym;
961 if (sym) {
962 if (menu->prompt) {
963 head += "<big><b>";
964 head += print_filter(_(menu->prompt->text));
965 head += "</b></big>";
966 if (sym->name) {
967 head += " (";
968 head += print_filter(sym->name);
969 head += ")";
970 }
971 } else if (sym->name) {
972 head += "<big><b>";
973 head += print_filter(sym->name);
974 head += "</b></big>";
975 }
976 head += "<br><br>";
977
978 if (showDebug())
979 debug = debug_info(sym);
980
981 help = print_filter(_(sym->help));
982 } else if (menu->prompt) {
983 head += "<big><b>";
984 head += print_filter(_(menu->prompt->text));
985 head += "</b></big><br><br>";
986 if (showDebug()) {
987 if (menu->prompt->visible.expr) {
988 debug += "&nbsp;&nbsp;dep: ";
989 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
990 debug += "<br><br>";
991 }
992 }
993 }
994 if (showDebug())
995 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
996
997 setText(head + debug + help);
998}
999
1000QString ConfigInfoView::debug_info(struct symbol *sym)
1001{
1002 QString debug;
1003
1004 debug += "type: ";
1005 debug += print_filter(sym_type_name(sym->type));
1006 if (sym_is_choice(sym))
1007 debug += " (choice)";
1008 debug += "<br>";
1009 if (sym->rev_dep.expr) {
1010 debug += "reverse dep: ";
1011 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1012 debug += "<br>";
1013 }
1014 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1015 switch (prop->type) {
1016 case P_PROMPT:
1017 case P_MENU:
1018 debug += "prompt: ";
1019 debug += print_filter(_(prop->text));
1020 debug += "<br>";
1021 break;
1022 case P_DEFAULT:
1023 debug += "default: ";
1024 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1025 debug += "<br>";
1026 break;
1027 case P_CHOICE:
1028 if (sym_is_choice(sym)) {
1029 debug += "choice: ";
1030 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1031 debug += "<br>";
1032 }
1033 break;
1034 case P_SELECT:
1035 debug += "select: ";
1036 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1037 debug += "<br>";
1038 break;
1039 case P_RANGE:
1040 debug += "range: ";
1041 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1042 debug += "<br>";
1043 break;
1044 default:
1045 debug += "unknown property: ";
1046 debug += prop_get_type_name(prop->type);
1047 debug += "<br>";
1048 }
1049 if (prop->visible.expr) {
1050 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1051 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1052 debug += "<br>";
1053 }
1054 }
1055 debug += "<br>";
1056
1057 return debug;
1058}
1059
1060QString ConfigInfoView::print_filter(const QString &str)
1061{
1062 QRegExp re("[<>&\"\\n]");
1063 QString res = str;
1064 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1065 switch (res[i].latin1()) {
1066 case '<':
1067 res.replace(i, 1, "&lt;");
1068 i += 4;
1069 break;
1070 case '>':
1071 res.replace(i, 1, "&gt;");
1072 i += 4;
1073 break;
1074 case '&':
1075 res.replace(i, 1, "&amp;");
1076 i += 5;
1077 break;
1078 case '"':
1079 res.replace(i, 1, "&quot;");
1080 i += 6;
1081 break;
1082 case '\n':
1083 res.replace(i, 1, "<br>");
1084 i += 4;
1085 break;
1086 }
1087 }
1088 return res;
1089}
1090
1091void ConfigInfoView::expr_print_help(void *data, const char *str)
1092{
1093 reinterpret_cast<QString*>(data)->append(print_filter(str));
1094}
1095
Roman Zippel7fc925f2006-06-08 22:12:46 -07001096QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1097{
1098 QPopupMenu* popup = Parent::createPopupMenu(pos);
1099 QAction* action = new QAction("Show Debug Info", 0, popup);
1100 action->setToggleAction(TRUE);
1101 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1102 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1103 action->setOn(showDebug());
1104 popup->insertSeparator();
1105 action->addTo(popup);
1106 return popup;
1107}
1108
1109void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1110{
1111 Parent::contentsContextMenuEvent(e);
1112}
1113
1114ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
1115 : Parent(parent, name), result(NULL)
Roman Zippel43bf6122006-06-08 22:12:45 -07001116{
1117 setCaption("Search Config");
1118
1119 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1120 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1121 layout2->addWidget(new QLabel("Find:", this));
1122 editField = new QLineEdit(this);
1123 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1124 layout2->addWidget(editField);
1125 searchButton = new QPushButton("Search", this);
1126 searchButton->setAutoDefault(FALSE);
1127 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1128 layout2->addWidget(searchButton);
1129 layout1->addLayout(layout2);
1130
Roman Zippel7fc925f2006-06-08 22:12:46 -07001131 split = new QSplitter(this);
Roman Zippel43bf6122006-06-08 22:12:45 -07001132 split->setOrientation(QSplitter::Vertical);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001133 list = new ConfigView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001134 list->list->mode = listMode;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001135 info = new ConfigInfoView(split, name);
Roman Zippel43bf6122006-06-08 22:12:45 -07001136 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1137 info, SLOT(setInfo(struct menu *)));
1138 layout1->addWidget(split);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001139
1140 if (name) {
1141 int x, y, width, height;
1142 bool ok;
1143
1144 configSettings->beginGroup(name);
1145 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1146 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1147 resize(width, height);
1148 x = configSettings->readNumEntry("/window x", 0, &ok);
1149 if (ok)
1150 y = configSettings->readNumEntry("/window y", 0, &ok);
1151 if (ok)
1152 move(x, y);
1153 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1154 if (ok)
1155 split->setSizes(sizes);
1156 configSettings->endGroup();
1157 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1158 }
1159}
1160
1161void ConfigSearchWindow::saveSettings(void)
1162{
1163 if (name()) {
1164 configSettings->beginGroup(name());
1165 configSettings->writeEntry("/window x", pos().x());
1166 configSettings->writeEntry("/window y", pos().y());
1167 configSettings->writeEntry("/window width", size().width());
1168 configSettings->writeEntry("/window height", size().height());
1169 configSettings->writeSizes("/split", split->sizes());
1170 configSettings->endGroup();
1171 }
Roman Zippel43bf6122006-06-08 22:12:45 -07001172}
1173
1174void ConfigSearchWindow::search(void)
1175{
1176 struct symbol **p;
1177 struct property *prop;
1178 ConfigItem *lastItem = NULL;
1179
1180 free(result);
1181 list->list->clear();
1182
1183 result = sym_re_search(editField->text().latin1());
1184 if (!result)
1185 return;
1186 for (p = result; *p; p++) {
1187 for_all_prompts((*p), prop)
1188 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1189 menu_is_visible(prop->menu));
1190 }
1191}
1192
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193/*
1194 * Construct the complete config widget
1195 */
1196ConfigMainWindow::ConfigMainWindow(void)
1197{
1198 QMenuBar* menu;
Roman Zippel7fc925f2006-06-08 22:12:46 -07001199 bool ok;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200 int x, y, width, height;
1201
1202 QWidget *d = configApp->desktop();
1203
Roman Zippel7fc925f2006-06-08 22:12:46 -07001204 width = configSettings->readNumEntry("/window width", d->width() - 64);
1205 height = configSettings->readNumEntry("/window height", d->height() - 64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 resize(width, height);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001207 x = configSettings->readNumEntry("/window x", 0, &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 if (ok)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001209 y = configSettings->readNumEntry("/window y", 0, &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210 if (ok)
1211 move(x, y);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212
1213 split1 = new QSplitter(this);
1214 split1->setOrientation(QSplitter::Horizontal);
1215 setCentralWidget(split1);
1216
Roman Zippel7fc925f2006-06-08 22:12:46 -07001217 menuView = new ConfigView(split1, "menu");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 menuList = menuView->list;
1219
1220 split2 = new QSplitter(split1);
1221 split2->setOrientation(QSplitter::Vertical);
1222
1223 // create config tree
Roman Zippel7fc925f2006-06-08 22:12:46 -07001224 configView = new ConfigView(split2, "config");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225 configList = configView->list;
1226
Roman Zippel7fc925f2006-06-08 22:12:46 -07001227 helpText = new ConfigInfoView(split2, "help");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228 helpText->setTextFormat(Qt::RichText);
1229
1230 setTabOrder(configList, helpText);
1231 configList->setFocus();
1232
1233 menu = menuBar();
1234 toolBar = new QToolBar("Tools", this);
1235
1236 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
1237 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1238 backAction->setEnabled(FALSE);
1239 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
1240 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1241 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
1242 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1243 QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
1244 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1245 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
1246 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001247 QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this);
1248 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
1250 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1251 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
1252 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1253 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
1254 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1255
1256 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
1257 showNameAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001258 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1259 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1260 showNameAction->setOn(configView->showName());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
1262 showRangeAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001263 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1264 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001265 showRangeAction->setOn(configList->showRange);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
1267 showDataAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001268 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1269 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 showDataAction->setOn(configList->showData);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
1272 showAllAction->setToggleAction(TRUE);
Roman Zippel7fc925f2006-06-08 22:12:46 -07001273 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1274 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001275 showAllAction->setOn(configList->showAll);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
1277 showDebugAction->setToggleAction(TRUE);
Roman Zippel43bf6122006-06-08 22:12:45 -07001278 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1279 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
Roman Zippel7fc925f2006-06-08 22:12:46 -07001280 showDebugAction->setOn(helpText->showDebug());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281
1282 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
1283 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1284 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
1285 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1286
1287 // init tool bar
1288 backAction->addTo(toolBar);
1289 toolBar->addSeparator();
1290 loadAction->addTo(toolBar);
1291 saveAction->addTo(toolBar);
1292 toolBar->addSeparator();
1293 singleViewAction->addTo(toolBar);
1294 splitViewAction->addTo(toolBar);
1295 fullViewAction->addTo(toolBar);
1296
1297 // create config menu
1298 QPopupMenu* config = new QPopupMenu(this);
1299 menu->insertItem("&File", config);
1300 loadAction->addTo(config);
1301 saveAction->addTo(config);
1302 saveAsAction->addTo(config);
1303 config->insertSeparator();
Roman Zippel43bf6122006-06-08 22:12:45 -07001304 searchAction->addTo(config);
1305 config->insertSeparator();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 quitAction->addTo(config);
1307
1308 // create options menu
1309 QPopupMenu* optionMenu = new QPopupMenu(this);
1310 menu->insertItem("&Option", optionMenu);
1311 showNameAction->addTo(optionMenu);
1312 showRangeAction->addTo(optionMenu);
1313 showDataAction->addTo(optionMenu);
1314 optionMenu->insertSeparator();
1315 showAllAction->addTo(optionMenu);
1316 showDebugAction->addTo(optionMenu);
1317
1318 // create help menu
1319 QPopupMenu* helpMenu = new QPopupMenu(this);
1320 menu->insertSeparator();
1321 menu->insertItem("&Help", helpMenu);
1322 showIntroAction->addTo(helpMenu);
1323 showAboutAction->addTo(helpMenu);
1324
Roman Zippel43bf6122006-06-08 22:12:45 -07001325 connect(configList, SIGNAL(menuChanged(struct menu *)),
1326 helpText, SLOT(setInfo(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327 connect(configList, SIGNAL(menuSelected(struct menu *)),
1328 SLOT(changeMenu(struct menu *)));
1329 connect(configList, SIGNAL(parentSelected()),
1330 SLOT(goBack()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001331 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1332 helpText, SLOT(setInfo(struct menu *)));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1334 SLOT(changeMenu(struct menu *)));
1335
1336 connect(configList, SIGNAL(gotFocus(void)),
1337 SLOT(listFocusChanged(void)));
1338 connect(menuList, SIGNAL(gotFocus(void)),
1339 SLOT(listFocusChanged(void)));
1340
Roman Zippel7fc925f2006-06-08 22:12:46 -07001341 QString listMode = configSettings->readEntry("/listMode", "symbol");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342 if (listMode == "single")
1343 showSingleView();
1344 else if (listMode == "full")
1345 showFullView();
1346 else /*if (listMode == "split")*/
1347 showSplitView();
1348
1349 // UI setup done, restore splitter positions
Roman Zippel7fc925f2006-06-08 22:12:46 -07001350 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 if (ok)
1352 split1->setSizes(sizes);
1353
Roman Zippel7fc925f2006-06-08 22:12:46 -07001354 sizes = configSettings->readSizes("/split2", &ok);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355 if (ok)
1356 split2->setSizes(sizes);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357}
1358
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359/*
1360 * display a new help entry as soon as a new menu entry is selected
1361 */
1362void ConfigMainWindow::setHelp(QListViewItem* item)
1363{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364 struct menu* menu = 0;
1365
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366 if (item)
1367 menu = ((ConfigItem*)item)->menu;
Roman Zippel43bf6122006-06-08 22:12:45 -07001368 helpText->setInfo(menu);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369}
1370
1371void ConfigMainWindow::loadConfig(void)
1372{
1373 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1374 if (s.isNull())
1375 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001376 if (conf_read(QFile::encodeName(s)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1378 ConfigView::updateListAll();
1379}
1380
1381void ConfigMainWindow::saveConfig(void)
1382{
1383 if (conf_write(NULL))
1384 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1385}
1386
1387void ConfigMainWindow::saveConfigAs(void)
1388{
1389 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1390 if (s.isNull())
1391 return;
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001392 if (conf_write(QFile::encodeName(s)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1394}
1395
Roman Zippel43bf6122006-06-08 22:12:45 -07001396void ConfigMainWindow::searchConfig(void)
1397{
1398 if (!searchWindow)
Roman Zippel7fc925f2006-06-08 22:12:46 -07001399 searchWindow = new ConfigSearchWindow(this, "search");
Roman Zippel43bf6122006-06-08 22:12:45 -07001400 searchWindow->show();
1401}
1402
Linus Torvalds1da177e2005-04-16 15:20:36 -07001403void ConfigMainWindow::changeMenu(struct menu *menu)
1404{
1405 configList->setRootMenu(menu);
1406 backAction->setEnabled(TRUE);
1407}
1408
1409void ConfigMainWindow::listFocusChanged(void)
1410{
1411 if (menuList->hasFocus()) {
1412 if (menuList->mode == menuMode)
1413 configList->clearSelection();
1414 setHelp(menuList->selectedItem());
1415 } else if (configList->hasFocus()) {
1416 setHelp(configList->selectedItem());
1417 }
1418}
1419
1420void ConfigMainWindow::goBack(void)
1421{
1422 ConfigItem* item;
1423
1424 configList->setParentMenu();
1425 if (configList->rootEntry == &rootmenu)
1426 backAction->setEnabled(FALSE);
1427 item = (ConfigItem*)menuList->selectedItem();
1428 while (item) {
1429 if (item->menu == configList->rootEntry) {
1430 menuList->setSelected(item, TRUE);
1431 break;
1432 }
1433 item = (ConfigItem*)item->parent();
1434 }
1435}
1436
1437void ConfigMainWindow::showSingleView(void)
1438{
1439 menuView->hide();
1440 menuList->setRootMenu(0);
1441 configList->mode = singleMode;
1442 if (configList->rootEntry == &rootmenu)
1443 configList->updateListAll();
1444 else
1445 configList->setRootMenu(&rootmenu);
1446 configList->setAllOpen(TRUE);
1447 configList->setFocus();
1448}
1449
1450void ConfigMainWindow::showSplitView(void)
1451{
1452 configList->mode = symbolMode;
1453 if (configList->rootEntry == &rootmenu)
1454 configList->updateListAll();
1455 else
1456 configList->setRootMenu(&rootmenu);
1457 configList->setAllOpen(TRUE);
1458 configApp->processEvents();
1459 menuList->mode = menuMode;
1460 menuList->setRootMenu(&rootmenu);
1461 menuList->setAllOpen(TRUE);
1462 menuView->show();
1463 menuList->setFocus();
1464}
1465
1466void ConfigMainWindow::showFullView(void)
1467{
1468 menuView->hide();
1469 menuList->setRootMenu(0);
1470 configList->mode = fullMode;
1471 if (configList->rootEntry == &rootmenu)
1472 configList->updateListAll();
1473 else
1474 configList->setRootMenu(&rootmenu);
1475 configList->setAllOpen(FALSE);
1476 configList->setFocus();
1477}
1478
Linus Torvalds1da177e2005-04-16 15:20:36 -07001479/*
1480 * ask for saving configuration before quitting
1481 * TODO ask only when something changed
1482 */
1483void ConfigMainWindow::closeEvent(QCloseEvent* e)
1484{
1485 if (!sym_change_count) {
1486 e->accept();
1487 return;
1488 }
1489 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1490 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1491 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1492 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1493 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1494 switch (mb.exec()) {
1495 case QMessageBox::Yes:
1496 conf_write(NULL);
1497 case QMessageBox::No:
1498 e->accept();
1499 break;
1500 case QMessageBox::Cancel:
1501 e->ignore();
1502 break;
1503 }
1504}
1505
1506void ConfigMainWindow::showIntro(void)
1507{
1508 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1509 "For each option, a blank box indicates the feature is disabled, a check\n"
1510 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1511 "as a module. Clicking on the box will cycle through the three states.\n\n"
1512 "If you do not see an option (e.g., a device driver) that you believe\n"
1513 "should be present, try turning on Show All Options under the Options menu.\n"
1514 "Although there is no cross reference yet to help you figure out what other\n"
1515 "options must be enabled to support the option you are interested in, you can\n"
1516 "still view the help of a grayed-out option.\n\n"
1517 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1518 "which you can then match by examining other options.\n\n";
1519
1520 QMessageBox::information(this, "qconf", str);
1521}
1522
1523void ConfigMainWindow::showAbout(void)
1524{
1525 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1526 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1527
1528 QMessageBox::information(this, "qconf", str);
1529}
1530
1531void ConfigMainWindow::saveSettings(void)
1532{
Roman Zippel7fc925f2006-06-08 22:12:46 -07001533 configSettings->writeEntry("/window x", pos().x());
1534 configSettings->writeEntry("/window y", pos().y());
1535 configSettings->writeEntry("/window width", size().width());
1536 configSettings->writeEntry("/window height", size().height());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537
1538 QString entry;
1539 switch(configList->mode) {
1540 case singleMode :
1541 entry = "single";
1542 break;
1543
1544 case symbolMode :
1545 entry = "split";
1546 break;
1547
1548 case fullMode :
1549 entry = "full";
1550 break;
1551 }
Roman Zippel7fc925f2006-06-08 22:12:46 -07001552 configSettings->writeEntry("/listMode", entry);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553
Roman Zippel7fc925f2006-06-08 22:12:46 -07001554 configSettings->writeSizes("/split1", split1->sizes());
1555 configSettings->writeSizes("/split2", split2->sizes());
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556}
1557
1558void fixup_rootmenu(struct menu *menu)
1559{
1560 struct menu *child;
1561 static int menu_cnt = 0;
1562
1563 menu->flags |= MENU_ROOT;
1564 for (child = menu->list; child; child = child->next) {
1565 if (child->prompt && child->prompt->type == P_MENU) {
1566 menu_cnt++;
1567 fixup_rootmenu(child);
1568 menu_cnt--;
1569 } else if (!menu_cnt)
1570 fixup_rootmenu(child);
1571 }
1572}
1573
1574static const char *progname;
1575
1576static void usage(void)
1577{
1578 printf("%s <config>\n", progname);
1579 exit(0);
1580}
1581
1582int main(int ac, char** av)
1583{
1584 ConfigMainWindow* v;
1585 const char *name;
1586
Arnaldo Carvalho de Melo3b9fa092005-05-05 15:09:46 -07001587 bindtextdomain(PACKAGE, LOCALEDIR);
1588 textdomain(PACKAGE);
1589
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590#ifndef LKC_DIRECT_LINK
1591 kconfig_load();
1592#endif
1593
1594 progname = av[0];
1595 configApp = new QApplication(ac, av);
1596 if (ac > 1 && av[1][0] == '-') {
1597 switch (av[1][1]) {
1598 case 'h':
1599 case '?':
1600 usage();
1601 }
1602 name = av[2];
1603 } else
1604 name = av[1];
1605 if (!name)
1606 usage();
1607
1608 conf_parse(name);
1609 fixup_rootmenu(&rootmenu);
1610 conf_read(NULL);
1611 //zconfdump(stdout);
1612
Roman Zippel7fc925f2006-06-08 22:12:46 -07001613 configSettings = new ConfigSettings();
1614 configSettings->beginGroup("/kconfig/qconf");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615 v = new ConfigMainWindow();
1616
1617 //zconfdump(stdout);
Roman Zippel43bf6122006-06-08 22:12:45 -07001618 configApp->setMainWidget(v);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1620 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
Roman Zippel43bf6122006-06-08 22:12:45 -07001621 v->show();
Linus Torvalds1da177e2005-04-16 15:20:36 -07001622 configApp->exec();
1623
Roman Zippel7fc925f2006-06-08 22:12:46 -07001624 configSettings->endGroup();
1625 delete configSettings;
1626
Linus Torvalds1da177e2005-04-16 15:20:36 -07001627 return 0;
1628}