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