kconfig: create links in info window
[deliverable/linux.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
3b9fa093
ACM
41static inline QString qgettext(const char* str)
42{
43bf612a 43 return QString::fromLocal8Bit(gettext(str));
3b9fa093
ACM
44}
45
46static inline QString qgettext(const QString& str)
47{
43bf612a 48 return QString::fromLocal8Bit(gettext(str.latin1()));
3b9fa093
ACM
49}
50
1da177e4
LT
51/**
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}
1da177e4 79
1da177e4
LT
80
81#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;
3b9fa093 114 prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
1da177e4
LT
115
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
3b9fa093 140 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
1da177e4
LT
141
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);
3b9fa093
ACM
150 setText(noColIdx, QString::null);
151 setText(modColIdx, QString::null);
152 setText(yesColIdx, QString::null);
1da177e4
LT
153 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);
3b9fa093 194
1da177e4
LT
195#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)
3b9fa093 202 prompt = QString("%1: %2").arg(prompt).arg(data);
1da177e4 203 else
3b9fa093 204 prompt = QString("(%2) %1").arg(prompt).arg(data);
1da177e4
LT
205 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
43bf612a
RZ
277ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
278 : Parent(parent)
279{
280 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
281}
282
1da177e4
LT
283void ConfigLineEdit::show(ConfigItem* i)
284{
285 item = i;
286 if (sym_get_string_value(item->menu->sym))
3b9fa093 287 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
1da177e4 288 else
3b9fa093 289 setText(QString::null);
1da177e4
LT
290 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
7fc925fd
RZ
313ConfigList::ConfigList(ConfigView* p, const char *name)
314 : Parent(p, name),
1da177e4
LT
315 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),
7fc925fd 320 rootEntry(0), headerPopup(0)
1da177e4
LT
321{
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
7fc925fd
RZ
334 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()));
1da177e4
LT
342 }
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
7fc925fd
RZ
372void 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
1da177e4
LT
384void 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
1da177e4 393 menu = item->menu;
43bf612a 394 emit menuChanged(menu);
1da177e4
LT
395 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
43bf612a
RZ
406 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 }
1da177e4
LT
420
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
1da177e4
LT
445void 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
7fc925fd
RZ
549/*
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
1da177e4
LT
617void ConfigList::keyPressEvent(QKeyEvent* ev)
618{
619 QListViewItem* i = currentItem();
620 ConfigItem* item;
621 struct menu *menu;
622 enum prop_type type;
623
43bf612a 624 if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
1da177e4
LT
625 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
7fc925fd
RZ
779void 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
1da177e4
LT
817ConfigView* ConfigView::viewList;
818
7fc925fd
RZ
819ConfigView::ConfigView(QWidget* parent, const char *name)
820 : Parent(parent, name)
1da177e4 821{
7fc925fd 822 list = new ConfigList(this, name);
1da177e4
LT
823 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
7fc925fd
RZ
842void 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
1da177e4
LT
886void 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
43bf612a
RZ
902ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
903 : Parent(parent, name), menu(0)
904{
7fc925fd
RZ
905 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 }
43bf612a
RZ
920}
921
922void ConfigInfoView::setShowDebug(bool b)
923{
924 if (_showDebug != b) {
925 _showDebug = b;
926 if (menu)
927 menuInfo();
ab45d190
RZ
928 else if (sym)
929 symbolInfo();
43bf612a
RZ
930 emit showDebugChanged(b);
931 }
932}
933
934void ConfigInfoView::setInfo(struct menu *m)
935{
936 menu = m;
937 if (!menu)
938 clear();
939 else
940 menuInfo();
941}
942
943void ConfigInfoView::setSource(const QString& name)
944{
945 const char *p = name.latin1();
946
947 menu = NULL;
ab45d190 948 sym = NULL;
43bf612a
RZ
949
950 switch (p[0]) {
951 case 'm':
ab45d190
RZ
952 struct menu *m;
953
954 if (sscanf(p, "m%p", &m) == 1 && menu != m) {
955 menu = m;
43bf612a 956 menuInfo();
ab45d190
RZ
957 }
958 break;
959 case 's':
960 struct symbol *s;
961
962 if (sscanf(p, "s%p", &s) == 1 && sym != s) {
963 sym = s;
964 symbolInfo();
965 }
43bf612a
RZ
966 break;
967 }
968}
969
ab45d190
RZ
970void ConfigInfoView::symbolInfo(void)
971{
972 QString str;
973
974 str += "<big>Symbol: <b>";
975 str += print_filter(sym->name);
976 str += "</b></big><br><br>value: ";
977 str += print_filter(sym_get_string_value(sym));
978 str += "<br>visibility: ";
979 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
980 str += "<br>";
981 str += debug_info(sym);
982
983 setText(str);
984}
985
43bf612a
RZ
986void ConfigInfoView::menuInfo(void)
987{
988 struct symbol* sym;
989 QString head, debug, help;
990
991 sym = menu->sym;
992 if (sym) {
993 if (menu->prompt) {
994 head += "<big><b>";
995 head += print_filter(_(menu->prompt->text));
996 head += "</b></big>";
997 if (sym->name) {
998 head += " (";
ab45d190
RZ
999 if (showDebug())
1000 head += QString().sprintf("<a href=\"s%p\">", sym);
43bf612a 1001 head += print_filter(sym->name);
ab45d190
RZ
1002 if (showDebug())
1003 head += "</a>";
43bf612a
RZ
1004 head += ")";
1005 }
1006 } else if (sym->name) {
1007 head += "<big><b>";
ab45d190
RZ
1008 if (showDebug())
1009 head += QString().sprintf("<a href=\"s%p\">", sym);
43bf612a 1010 head += print_filter(sym->name);
ab45d190
RZ
1011 if (showDebug())
1012 head += "</a>";
43bf612a
RZ
1013 head += "</b></big>";
1014 }
1015 head += "<br><br>";
1016
1017 if (showDebug())
1018 debug = debug_info(sym);
1019
1020 help = print_filter(_(sym->help));
1021 } else if (menu->prompt) {
1022 head += "<big><b>";
1023 head += print_filter(_(menu->prompt->text));
1024 head += "</b></big><br><br>";
1025 if (showDebug()) {
1026 if (menu->prompt->visible.expr) {
1027 debug += "&nbsp;&nbsp;dep: ";
1028 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1029 debug += "<br><br>";
1030 }
1031 }
1032 }
1033 if (showDebug())
1034 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1035
1036 setText(head + debug + help);
1037}
1038
1039QString ConfigInfoView::debug_info(struct symbol *sym)
1040{
1041 QString debug;
1042
1043 debug += "type: ";
1044 debug += print_filter(sym_type_name(sym->type));
1045 if (sym_is_choice(sym))
1046 debug += " (choice)";
1047 debug += "<br>";
1048 if (sym->rev_dep.expr) {
1049 debug += "reverse dep: ";
1050 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1051 debug += "<br>";
1052 }
1053 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1054 switch (prop->type) {
1055 case P_PROMPT:
1056 case P_MENU:
ab45d190 1057 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
43bf612a 1058 debug += print_filter(_(prop->text));
ab45d190 1059 debug += "</a><br>";
43bf612a
RZ
1060 break;
1061 case P_DEFAULT:
1062 debug += "default: ";
1063 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1064 debug += "<br>";
1065 break;
1066 case P_CHOICE:
1067 if (sym_is_choice(sym)) {
1068 debug += "choice: ";
1069 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1070 debug += "<br>";
1071 }
1072 break;
1073 case P_SELECT:
1074 debug += "select: ";
1075 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1076 debug += "<br>";
1077 break;
1078 case P_RANGE:
1079 debug += "range: ";
1080 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1081 debug += "<br>";
1082 break;
1083 default:
1084 debug += "unknown property: ";
1085 debug += prop_get_type_name(prop->type);
1086 debug += "<br>";
1087 }
1088 if (prop->visible.expr) {
1089 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1090 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1091 debug += "<br>";
1092 }
1093 }
1094 debug += "<br>";
1095
1096 return debug;
1097}
1098
1099QString ConfigInfoView::print_filter(const QString &str)
1100{
1101 QRegExp re("[<>&\"\\n]");
1102 QString res = str;
1103 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1104 switch (res[i].latin1()) {
1105 case '<':
1106 res.replace(i, 1, "&lt;");
1107 i += 4;
1108 break;
1109 case '>':
1110 res.replace(i, 1, "&gt;");
1111 i += 4;
1112 break;
1113 case '&':
1114 res.replace(i, 1, "&amp;");
1115 i += 5;
1116 break;
1117 case '"':
1118 res.replace(i, 1, "&quot;");
1119 i += 6;
1120 break;
1121 case '\n':
1122 res.replace(i, 1, "<br>");
1123 i += 4;
1124 break;
1125 }
1126 }
1127 return res;
1128}
1129
ab45d190 1130void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
43bf612a 1131{
ab45d190
RZ
1132 QString* text = reinterpret_cast<QString*>(data);
1133 QString str2 = print_filter(str);
1134
1135 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1136 *text += QString().sprintf("<a href=\"s%p\">", sym);
1137 *text += str2;
1138 *text += "</a>";
1139 } else
1140 *text += str2;
43bf612a
RZ
1141}
1142
7fc925fd
RZ
1143QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1144{
1145 QPopupMenu* popup = Parent::createPopupMenu(pos);
1146 QAction* action = new QAction("Show Debug Info", 0, popup);
1147 action->setToggleAction(TRUE);
1148 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1149 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1150 action->setOn(showDebug());
1151 popup->insertSeparator();
1152 action->addTo(popup);
1153 return popup;
1154}
1155
1156void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1157{
1158 Parent::contentsContextMenuEvent(e);
1159}
1160
1161ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
1162 : Parent(parent, name), result(NULL)
43bf612a
RZ
1163{
1164 setCaption("Search Config");
1165
1166 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1167 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1168 layout2->addWidget(new QLabel("Find:", this));
1169 editField = new QLineEdit(this);
1170 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1171 layout2->addWidget(editField);
1172 searchButton = new QPushButton("Search", this);
1173 searchButton->setAutoDefault(FALSE);
1174 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1175 layout2->addWidget(searchButton);
1176 layout1->addLayout(layout2);
1177
7fc925fd 1178 split = new QSplitter(this);
43bf612a 1179 split->setOrientation(QSplitter::Vertical);
7fc925fd 1180 list = new ConfigView(split, name);
43bf612a 1181 list->list->mode = listMode;
7fc925fd 1182 info = new ConfigInfoView(split, name);
43bf612a
RZ
1183 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1184 info, SLOT(setInfo(struct menu *)));
1185 layout1->addWidget(split);
7fc925fd
RZ
1186
1187 if (name) {
1188 int x, y, width, height;
1189 bool ok;
1190
1191 configSettings->beginGroup(name);
1192 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1193 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1194 resize(width, height);
1195 x = configSettings->readNumEntry("/window x", 0, &ok);
1196 if (ok)
1197 y = configSettings->readNumEntry("/window y", 0, &ok);
1198 if (ok)
1199 move(x, y);
1200 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1201 if (ok)
1202 split->setSizes(sizes);
1203 configSettings->endGroup();
1204 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1205 }
1206}
1207
1208void ConfigSearchWindow::saveSettings(void)
1209{
1210 if (name()) {
1211 configSettings->beginGroup(name());
1212 configSettings->writeEntry("/window x", pos().x());
1213 configSettings->writeEntry("/window y", pos().y());
1214 configSettings->writeEntry("/window width", size().width());
1215 configSettings->writeEntry("/window height", size().height());
1216 configSettings->writeSizes("/split", split->sizes());
1217 configSettings->endGroup();
1218 }
43bf612a
RZ
1219}
1220
1221void ConfigSearchWindow::search(void)
1222{
1223 struct symbol **p;
1224 struct property *prop;
1225 ConfigItem *lastItem = NULL;
1226
1227 free(result);
1228 list->list->clear();
1229
1230 result = sym_re_search(editField->text().latin1());
1231 if (!result)
1232 return;
1233 for (p = result; *p; p++) {
1234 for_all_prompts((*p), prop)
1235 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1236 menu_is_visible(prop->menu));
1237 }
1238}
1239
1da177e4
LT
1240/*
1241 * Construct the complete config widget
1242 */
1243ConfigMainWindow::ConfigMainWindow(void)
1244{
1245 QMenuBar* menu;
7fc925fd 1246 bool ok;
1da177e4
LT
1247 int x, y, width, height;
1248
1249 QWidget *d = configApp->desktop();
1250
7fc925fd
RZ
1251 width = configSettings->readNumEntry("/window width", d->width() - 64);
1252 height = configSettings->readNumEntry("/window height", d->height() - 64);
1da177e4 1253 resize(width, height);
7fc925fd 1254 x = configSettings->readNumEntry("/window x", 0, &ok);
1da177e4 1255 if (ok)
7fc925fd 1256 y = configSettings->readNumEntry("/window y", 0, &ok);
1da177e4
LT
1257 if (ok)
1258 move(x, y);
1da177e4
LT
1259
1260 split1 = new QSplitter(this);
1261 split1->setOrientation(QSplitter::Horizontal);
1262 setCentralWidget(split1);
1263
7fc925fd 1264 menuView = new ConfigView(split1, "menu");
1da177e4
LT
1265 menuList = menuView->list;
1266
1267 split2 = new QSplitter(split1);
1268 split2->setOrientation(QSplitter::Vertical);
1269
1270 // create config tree
7fc925fd 1271 configView = new ConfigView(split2, "config");
1da177e4
LT
1272 configList = configView->list;
1273
7fc925fd 1274 helpText = new ConfigInfoView(split2, "help");
1da177e4
LT
1275 helpText->setTextFormat(Qt::RichText);
1276
1277 setTabOrder(configList, helpText);
1278 configList->setFocus();
1279
1280 menu = menuBar();
1281 toolBar = new QToolBar("Tools", this);
1282
1283 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
1284 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1285 backAction->setEnabled(FALSE);
1286 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
1287 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1288 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
1289 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1290 QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
1291 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1292 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
1293 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
43bf612a
RZ
1294 QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this);
1295 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1da177e4
LT
1296 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
1297 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1298 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
1299 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1300 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
1301 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1302
1303 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
1304 showNameAction->setToggleAction(TRUE);
7fc925fd
RZ
1305 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1306 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1307 showNameAction->setOn(configView->showName());
1da177e4
LT
1308 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
1309 showRangeAction->setToggleAction(TRUE);
7fc925fd
RZ
1310 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1311 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1da177e4 1312 showRangeAction->setOn(configList->showRange);
1da177e4
LT
1313 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
1314 showDataAction->setToggleAction(TRUE);
7fc925fd
RZ
1315 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1316 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1da177e4 1317 showDataAction->setOn(configList->showData);
1da177e4
LT
1318 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
1319 showAllAction->setToggleAction(TRUE);
7fc925fd
RZ
1320 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1321 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
1da177e4 1322 showAllAction->setOn(configList->showAll);
1da177e4
LT
1323 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
1324 showDebugAction->setToggleAction(TRUE);
43bf612a
RZ
1325 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1326 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
7fc925fd 1327 showDebugAction->setOn(helpText->showDebug());
1da177e4
LT
1328
1329 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
1330 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1331 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
1332 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1333
1334 // init tool bar
1335 backAction->addTo(toolBar);
1336 toolBar->addSeparator();
1337 loadAction->addTo(toolBar);
1338 saveAction->addTo(toolBar);
1339 toolBar->addSeparator();
1340 singleViewAction->addTo(toolBar);
1341 splitViewAction->addTo(toolBar);
1342 fullViewAction->addTo(toolBar);
1343
1344 // create config menu
1345 QPopupMenu* config = new QPopupMenu(this);
1346 menu->insertItem("&File", config);
1347 loadAction->addTo(config);
1348 saveAction->addTo(config);
1349 saveAsAction->addTo(config);
1350 config->insertSeparator();
43bf612a
RZ
1351 searchAction->addTo(config);
1352 config->insertSeparator();
1da177e4
LT
1353 quitAction->addTo(config);
1354
1355 // create options menu
1356 QPopupMenu* optionMenu = new QPopupMenu(this);
1357 menu->insertItem("&Option", optionMenu);
1358 showNameAction->addTo(optionMenu);
1359 showRangeAction->addTo(optionMenu);
1360 showDataAction->addTo(optionMenu);
1361 optionMenu->insertSeparator();
1362 showAllAction->addTo(optionMenu);
1363 showDebugAction->addTo(optionMenu);
1364
1365 // create help menu
1366 QPopupMenu* helpMenu = new QPopupMenu(this);
1367 menu->insertSeparator();
1368 menu->insertItem("&Help", helpMenu);
1369 showIntroAction->addTo(helpMenu);
1370 showAboutAction->addTo(helpMenu);
1371
43bf612a
RZ
1372 connect(configList, SIGNAL(menuChanged(struct menu *)),
1373 helpText, SLOT(setInfo(struct menu *)));
1da177e4
LT
1374 connect(configList, SIGNAL(menuSelected(struct menu *)),
1375 SLOT(changeMenu(struct menu *)));
1376 connect(configList, SIGNAL(parentSelected()),
1377 SLOT(goBack()));
43bf612a
RZ
1378 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1379 helpText, SLOT(setInfo(struct menu *)));
1da177e4
LT
1380 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1381 SLOT(changeMenu(struct menu *)));
1382
1383 connect(configList, SIGNAL(gotFocus(void)),
1384 SLOT(listFocusChanged(void)));
1385 connect(menuList, SIGNAL(gotFocus(void)),
1386 SLOT(listFocusChanged(void)));
1387
7fc925fd 1388 QString listMode = configSettings->readEntry("/listMode", "symbol");
1da177e4
LT
1389 if (listMode == "single")
1390 showSingleView();
1391 else if (listMode == "full")
1392 showFullView();
1393 else /*if (listMode == "split")*/
1394 showSplitView();
1395
1396 // UI setup done, restore splitter positions
7fc925fd 1397 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1da177e4
LT
1398 if (ok)
1399 split1->setSizes(sizes);
1400
7fc925fd 1401 sizes = configSettings->readSizes("/split2", &ok);
1da177e4
LT
1402 if (ok)
1403 split2->setSizes(sizes);
1da177e4
LT
1404}
1405
1da177e4
LT
1406/*
1407 * display a new help entry as soon as a new menu entry is selected
1408 */
1409void ConfigMainWindow::setHelp(QListViewItem* item)
1410{
1da177e4
LT
1411 struct menu* menu = 0;
1412
1da177e4
LT
1413 if (item)
1414 menu = ((ConfigItem*)item)->menu;
43bf612a 1415 helpText->setInfo(menu);
1da177e4
LT
1416}
1417
1418void ConfigMainWindow::loadConfig(void)
1419{
1420 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1421 if (s.isNull())
1422 return;
3b9fa093 1423 if (conf_read(QFile::encodeName(s)))
1da177e4
LT
1424 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1425 ConfigView::updateListAll();
1426}
1427
1428void ConfigMainWindow::saveConfig(void)
1429{
1430 if (conf_write(NULL))
1431 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1432}
1433
1434void ConfigMainWindow::saveConfigAs(void)
1435{
1436 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1437 if (s.isNull())
1438 return;
3b9fa093 1439 if (conf_write(QFile::encodeName(s)))
1da177e4
LT
1440 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1441}
1442
43bf612a
RZ
1443void ConfigMainWindow::searchConfig(void)
1444{
1445 if (!searchWindow)
7fc925fd 1446 searchWindow = new ConfigSearchWindow(this, "search");
43bf612a
RZ
1447 searchWindow->show();
1448}
1449
1da177e4
LT
1450void ConfigMainWindow::changeMenu(struct menu *menu)
1451{
1452 configList->setRootMenu(menu);
1453 backAction->setEnabled(TRUE);
1454}
1455
1456void ConfigMainWindow::listFocusChanged(void)
1457{
1458 if (menuList->hasFocus()) {
1459 if (menuList->mode == menuMode)
1460 configList->clearSelection();
1461 setHelp(menuList->selectedItem());
1462 } else if (configList->hasFocus()) {
1463 setHelp(configList->selectedItem());
1464 }
1465}
1466
1467void ConfigMainWindow::goBack(void)
1468{
1469 ConfigItem* item;
1470
1471 configList->setParentMenu();
1472 if (configList->rootEntry == &rootmenu)
1473 backAction->setEnabled(FALSE);
1474 item = (ConfigItem*)menuList->selectedItem();
1475 while (item) {
1476 if (item->menu == configList->rootEntry) {
1477 menuList->setSelected(item, TRUE);
1478 break;
1479 }
1480 item = (ConfigItem*)item->parent();
1481 }
1482}
1483
1484void ConfigMainWindow::showSingleView(void)
1485{
1486 menuView->hide();
1487 menuList->setRootMenu(0);
1488 configList->mode = singleMode;
1489 if (configList->rootEntry == &rootmenu)
1490 configList->updateListAll();
1491 else
1492 configList->setRootMenu(&rootmenu);
1493 configList->setAllOpen(TRUE);
1494 configList->setFocus();
1495}
1496
1497void ConfigMainWindow::showSplitView(void)
1498{
1499 configList->mode = symbolMode;
1500 if (configList->rootEntry == &rootmenu)
1501 configList->updateListAll();
1502 else
1503 configList->setRootMenu(&rootmenu);
1504 configList->setAllOpen(TRUE);
1505 configApp->processEvents();
1506 menuList->mode = menuMode;
1507 menuList->setRootMenu(&rootmenu);
1508 menuList->setAllOpen(TRUE);
1509 menuView->show();
1510 menuList->setFocus();
1511}
1512
1513void ConfigMainWindow::showFullView(void)
1514{
1515 menuView->hide();
1516 menuList->setRootMenu(0);
1517 configList->mode = fullMode;
1518 if (configList->rootEntry == &rootmenu)
1519 configList->updateListAll();
1520 else
1521 configList->setRootMenu(&rootmenu);
1522 configList->setAllOpen(FALSE);
1523 configList->setFocus();
1524}
1525
1da177e4
LT
1526/*
1527 * ask for saving configuration before quitting
1528 * TODO ask only when something changed
1529 */
1530void ConfigMainWindow::closeEvent(QCloseEvent* e)
1531{
1532 if (!sym_change_count) {
1533 e->accept();
1534 return;
1535 }
1536 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1537 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1538 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1539 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1540 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1541 switch (mb.exec()) {
1542 case QMessageBox::Yes:
1543 conf_write(NULL);
1544 case QMessageBox::No:
1545 e->accept();
1546 break;
1547 case QMessageBox::Cancel:
1548 e->ignore();
1549 break;
1550 }
1551}
1552
1553void ConfigMainWindow::showIntro(void)
1554{
1555 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1556 "For each option, a blank box indicates the feature is disabled, a check\n"
1557 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1558 "as a module. Clicking on the box will cycle through the three states.\n\n"
1559 "If you do not see an option (e.g., a device driver) that you believe\n"
1560 "should be present, try turning on Show All Options under the Options menu.\n"
1561 "Although there is no cross reference yet to help you figure out what other\n"
1562 "options must be enabled to support the option you are interested in, you can\n"
1563 "still view the help of a grayed-out option.\n\n"
1564 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1565 "which you can then match by examining other options.\n\n";
1566
1567 QMessageBox::information(this, "qconf", str);
1568}
1569
1570void ConfigMainWindow::showAbout(void)
1571{
1572 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1573 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1574
1575 QMessageBox::information(this, "qconf", str);
1576}
1577
1578void ConfigMainWindow::saveSettings(void)
1579{
7fc925fd
RZ
1580 configSettings->writeEntry("/window x", pos().x());
1581 configSettings->writeEntry("/window y", pos().y());
1582 configSettings->writeEntry("/window width", size().width());
1583 configSettings->writeEntry("/window height", size().height());
1da177e4
LT
1584
1585 QString entry;
1586 switch(configList->mode) {
1587 case singleMode :
1588 entry = "single";
1589 break;
1590
1591 case symbolMode :
1592 entry = "split";
1593 break;
1594
1595 case fullMode :
1596 entry = "full";
1597 break;
1598 }
7fc925fd 1599 configSettings->writeEntry("/listMode", entry);
1da177e4 1600
7fc925fd
RZ
1601 configSettings->writeSizes("/split1", split1->sizes());
1602 configSettings->writeSizes("/split2", split2->sizes());
1da177e4
LT
1603}
1604
1605void fixup_rootmenu(struct menu *menu)
1606{
1607 struct menu *child;
1608 static int menu_cnt = 0;
1609
1610 menu->flags |= MENU_ROOT;
1611 for (child = menu->list; child; child = child->next) {
1612 if (child->prompt && child->prompt->type == P_MENU) {
1613 menu_cnt++;
1614 fixup_rootmenu(child);
1615 menu_cnt--;
1616 } else if (!menu_cnt)
1617 fixup_rootmenu(child);
1618 }
1619}
1620
1621static const char *progname;
1622
1623static void usage(void)
1624{
1625 printf("%s <config>\n", progname);
1626 exit(0);
1627}
1628
1629int main(int ac, char** av)
1630{
1631 ConfigMainWindow* v;
1632 const char *name;
1633
3b9fa093
ACM
1634 bindtextdomain(PACKAGE, LOCALEDIR);
1635 textdomain(PACKAGE);
1636
1da177e4
LT
1637#ifndef LKC_DIRECT_LINK
1638 kconfig_load();
1639#endif
1640
1641 progname = av[0];
1642 configApp = new QApplication(ac, av);
1643 if (ac > 1 && av[1][0] == '-') {
1644 switch (av[1][1]) {
1645 case 'h':
1646 case '?':
1647 usage();
1648 }
1649 name = av[2];
1650 } else
1651 name = av[1];
1652 if (!name)
1653 usage();
1654
1655 conf_parse(name);
1656 fixup_rootmenu(&rootmenu);
1657 conf_read(NULL);
1658 //zconfdump(stdout);
1659
7fc925fd
RZ
1660 configSettings = new ConfigSettings();
1661 configSettings->beginGroup("/kconfig/qconf");
1da177e4
LT
1662 v = new ConfigMainWindow();
1663
1664 //zconfdump(stdout);
43bf612a 1665 configApp->setMainWidget(v);
1da177e4
LT
1666 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1667 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
43bf612a 1668 v->show();
1da177e4
LT
1669 configApp->exec();
1670
7fc925fd
RZ
1671 configSettings->endGroup();
1672 delete configSettings;
1673
1da177e4
LT
1674 return 0;
1675}
This page took 0.190865 seconds and 5 git commands to generate.