[PATCH] kconfig: add "void conf_set_changed_callback(void (*fn)(void))", use it in...
[deliverable/linux.git] / scripts / kconfig / qconf.cc
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>
9 #include <qlayout.h>
10 #include <qvbox.h>
11 #include <qsplitter.h>
12 #include <qlistview.h>
13 #include <qtextbrowser.h>
14 #include <qlineedit.h>
15 #include <qlabel.h>
16 #include <qpushbutton.h>
17 #include <qmenubar.h>
18 #include <qmessagebox.h>
19 #include <qaction.h>
20 #include <qheader.h>
21 #include <qfiledialog.h>
22 #include <qdragobject.h>
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
33 #ifdef _
34 # undef _
35 # define _ qgettext
36 #endif
37
38 static QApplication *configApp;
39 static ConfigSettings *configSettings;
40
41 QAction *ConfigMainWindow::saveAction;
42
43 static inline QString qgettext(const char* str)
44 {
45 return QString::fromLocal8Bit(gettext(str));
46 }
47
48 static inline QString qgettext(const QString& str)
49 {
50 return QString::fromLocal8Bit(gettext(str.latin1()));
51 }
52
53 /**
54 * Reads a list of integer values from the application settings.
55 */
56 QValueList<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 */
72 bool 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 }
81
82
83 #if QT_VERSION >= 300
84 /*
85 * set the new data
86 * TODO check the value
87 */
88 void 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 */
98 void 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;
116 prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
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
142 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
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);
152 setText(noColIdx, QString::null);
153 setText(modColIdx, QString::null);
154 setText(yesColIdx, QString::null);
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);
196
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)
204 prompt = QString("%1: %2").arg(prompt).arg(data);
205 else
206 prompt = QString("(%2) %1").arg(prompt).arg(data);
207 break;
208 }
209 if (!sym_has_value(sym) && visible)
210 prompt += " (NEW)";
211 set_prompt:
212 setText(promptColIdx, prompt);
213 }
214
215 void 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
233 void 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 */
249 void 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 */
266 ConfigItem::~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
279 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
280 : Parent(parent)
281 {
282 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
283 }
284
285 void ConfigLineEdit::show(ConfigItem* i)
286 {
287 item = i;
288 if (sym_get_string_value(item->menu->sym))
289 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
290 else
291 setText(QString::null);
292 Parent::show();
293 setFocus();
294 }
295
296 void 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
315 ConfigList::ConfigList(ConfigView* p, const char *name)
316 : Parent(p, name),
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),
322 rootEntry(0), headerPopup(0)
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
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()));
344 }
345
346 for (i = 0; i < colNr; i++)
347 colMap[i] = colRevMap[i] = -1;
348 addColumn(promptColIdx, "Option");
349
350 reinit();
351 }
352
353 void 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
374 void 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
386 ConfigItem* 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
398 void 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
407 menu = item->menu;
408 emit menuChanged(menu);
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
416 void ConfigList::updateList(ConfigItem* item)
417 {
418 ConfigItem* last = 0;
419
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 }
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 }
454 update:
455 updateMenuList(this, rootEntry);
456 triggerUpdate();
457 }
458
459 void 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
484 void 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
528 void 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());
541 ensureItemVisible(currentItem());
542 }
543
544 void 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
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 */
571 template <class P>
572 void 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
632 void ConfigList::keyPressEvent(QKeyEvent* ev)
633 {
634 QListViewItem* i = currentItem();
635 ConfigItem* item;
636 struct menu *menu;
637 enum prop_type type;
638
639 if (ev->key() == Key_Escape && mode != fullMode && mode != listMode) {
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
686 void 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
693 void 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
743 skip:
744 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
745 Parent::contentsMouseReleaseEvent(e);
746 }
747
748 void 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
755 void 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
777 skip:
778 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
779 Parent::contentsMouseDoubleClickEvent(e);
780 }
781
782 void ConfigList::focusInEvent(QFocusEvent *e)
783 {
784 struct menu *menu = NULL;
785
786 Parent::focusInEvent(e);
787
788 ConfigItem* item = (ConfigItem *)currentItem();
789 if (item) {
790 setSelected(item, TRUE);
791 menu = item->menu;
792 }
793 emit gotFocus(menu);
794 }
795
796 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
797 {
798 if (e->y() <= header()->geometry().bottom()) {
799 if (!headerPopup) {
800 QAction *action;
801
802 headerPopup = new QPopupMenu(this);
803 action = new QAction(NULL, "Show Name", 0, this);
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);
811 action = new QAction(NULL, "Show Range", 0, this);
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);
819 action = new QAction(NULL, "Show Data", 0, this);
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
834 ConfigView* ConfigView::viewList;
835
836 ConfigView::ConfigView(QWidget* parent, const char *name)
837 : Parent(parent, name)
838 {
839 list = new ConfigList(this, name);
840 lineEdit = new ConfigLineEdit(this);
841 lineEdit->hide();
842
843 this->nextView = viewList;
844 viewList = this;
845 }
846
847 ConfigView::~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
859 void ConfigView::setShowAll(bool b)
860 {
861 if (list->showAll != b) {
862 list->showAll = b;
863 list->updateListAll();
864 emit showAllChanged(b);
865 }
866 }
867
868 void ConfigView::setShowName(bool b)
869 {
870 if (list->showName != b) {
871 list->showName = b;
872 list->reinit();
873 emit showNameChanged(b);
874 }
875 }
876
877 void ConfigView::setShowRange(bool b)
878 {
879 if (list->showRange != b) {
880 list->showRange = b;
881 list->reinit();
882 emit showRangeChanged(b);
883 }
884 }
885
886 void ConfigView::setShowData(bool b)
887 {
888 if (list->showData != b) {
889 list->showData = b;
890 list->reinit();
891 emit showDataChanged(b);
892 }
893 }
894
895 void ConfigList::setAllOpen(bool open)
896 {
897 QListViewItemIterator it(this);
898
899 for (; it.current(); it++)
900 it.current()->setOpen(open);
901 }
902
903 void ConfigView::updateList(ConfigItem* item)
904 {
905 ConfigView* v;
906
907 for (v = viewList; v; v = v->nextView)
908 v->list->updateList(item);
909 }
910
911 void ConfigView::updateListAll(void)
912 {
913 ConfigView* v;
914
915 for (v = viewList; v; v = v->nextView)
916 v->list->updateListAll();
917 }
918
919 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
920 : Parent(parent, name), menu(0)
921 {
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
930 void ConfigInfoView::saveSettings(void)
931 {
932 if (name()) {
933 configSettings->beginGroup(name());
934 configSettings->writeEntry("/showDebug", showDebug());
935 configSettings->endGroup();
936 }
937 }
938
939 void ConfigInfoView::setShowDebug(bool b)
940 {
941 if (_showDebug != b) {
942 _showDebug = b;
943 if (menu)
944 menuInfo();
945 else if (sym)
946 symbolInfo();
947 emit showDebugChanged(b);
948 }
949 }
950
951 void ConfigInfoView::setInfo(struct menu *m)
952 {
953 if (menu == m)
954 return;
955 menu = m;
956 if (!menu)
957 clear();
958 else
959 menuInfo();
960 }
961
962 void ConfigInfoView::setSource(const QString& name)
963 {
964 const char *p = name.latin1();
965
966 menu = NULL;
967 sym = NULL;
968
969 switch (p[0]) {
970 case 'm':
971 struct menu *m;
972
973 if (sscanf(p, "m%p", &m) == 1 && menu != m) {
974 menu = m;
975 menuInfo();
976 emit menuSelected(menu);
977 }
978 break;
979 case 's':
980 struct symbol *s;
981
982 if (sscanf(p, "s%p", &s) == 1 && sym != s) {
983 sym = s;
984 symbolInfo();
985 }
986 break;
987 }
988 }
989
990 void ConfigInfoView::symbolInfo(void)
991 {
992 QString str;
993
994 str += "<big>Symbol: <b>";
995 str += print_filter(sym->name);
996 str += "</b></big><br><br>value: ";
997 str += print_filter(sym_get_string_value(sym));
998 str += "<br>visibility: ";
999 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1000 str += "<br>";
1001 str += debug_info(sym);
1002
1003 setText(str);
1004 }
1005
1006 void ConfigInfoView::menuInfo(void)
1007 {
1008 struct symbol* sym;
1009 QString head, debug, help;
1010
1011 sym = menu->sym;
1012 if (sym) {
1013 if (menu->prompt) {
1014 head += "<big><b>";
1015 head += print_filter(_(menu->prompt->text));
1016 head += "</b></big>";
1017 if (sym->name) {
1018 head += " (";
1019 if (showDebug())
1020 head += QString().sprintf("<a href=\"s%p\">", sym);
1021 head += print_filter(sym->name);
1022 if (showDebug())
1023 head += "</a>";
1024 head += ")";
1025 }
1026 } else if (sym->name) {
1027 head += "<big><b>";
1028 if (showDebug())
1029 head += QString().sprintf("<a href=\"s%p\">", sym);
1030 head += print_filter(sym->name);
1031 if (showDebug())
1032 head += "</a>";
1033 head += "</b></big>";
1034 }
1035 head += "<br><br>";
1036
1037 if (showDebug())
1038 debug = debug_info(sym);
1039
1040 help = print_filter(_(sym->help));
1041 } else if (menu->prompt) {
1042 head += "<big><b>";
1043 head += print_filter(_(menu->prompt->text));
1044 head += "</b></big><br><br>";
1045 if (showDebug()) {
1046 if (menu->prompt->visible.expr) {
1047 debug += "&nbsp;&nbsp;dep: ";
1048 expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1049 debug += "<br><br>";
1050 }
1051 }
1052 }
1053 if (showDebug())
1054 debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1055
1056 setText(head + debug + help);
1057 }
1058
1059 QString ConfigInfoView::debug_info(struct symbol *sym)
1060 {
1061 QString debug;
1062
1063 debug += "type: ";
1064 debug += print_filter(sym_type_name(sym->type));
1065 if (sym_is_choice(sym))
1066 debug += " (choice)";
1067 debug += "<br>";
1068 if (sym->rev_dep.expr) {
1069 debug += "reverse dep: ";
1070 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1071 debug += "<br>";
1072 }
1073 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1074 switch (prop->type) {
1075 case P_PROMPT:
1076 case P_MENU:
1077 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1078 debug += print_filter(_(prop->text));
1079 debug += "</a><br>";
1080 break;
1081 case P_DEFAULT:
1082 debug += "default: ";
1083 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1084 debug += "<br>";
1085 break;
1086 case P_CHOICE:
1087 if (sym_is_choice(sym)) {
1088 debug += "choice: ";
1089 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1090 debug += "<br>";
1091 }
1092 break;
1093 case P_SELECT:
1094 debug += "select: ";
1095 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1096 debug += "<br>";
1097 break;
1098 case P_RANGE:
1099 debug += "range: ";
1100 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1101 debug += "<br>";
1102 break;
1103 default:
1104 debug += "unknown property: ";
1105 debug += prop_get_type_name(prop->type);
1106 debug += "<br>";
1107 }
1108 if (prop->visible.expr) {
1109 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1110 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1111 debug += "<br>";
1112 }
1113 }
1114 debug += "<br>";
1115
1116 return debug;
1117 }
1118
1119 QString ConfigInfoView::print_filter(const QString &str)
1120 {
1121 QRegExp re("[<>&\"\\n]");
1122 QString res = str;
1123 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1124 switch (res[i].latin1()) {
1125 case '<':
1126 res.replace(i, 1, "&lt;");
1127 i += 4;
1128 break;
1129 case '>':
1130 res.replace(i, 1, "&gt;");
1131 i += 4;
1132 break;
1133 case '&':
1134 res.replace(i, 1, "&amp;");
1135 i += 5;
1136 break;
1137 case '"':
1138 res.replace(i, 1, "&quot;");
1139 i += 6;
1140 break;
1141 case '\n':
1142 res.replace(i, 1, "<br>");
1143 i += 4;
1144 break;
1145 }
1146 }
1147 return res;
1148 }
1149
1150 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1151 {
1152 QString* text = reinterpret_cast<QString*>(data);
1153 QString str2 = print_filter(str);
1154
1155 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1156 *text += QString().sprintf("<a href=\"s%p\">", sym);
1157 *text += str2;
1158 *text += "</a>";
1159 } else
1160 *text += str2;
1161 }
1162
1163 QPopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1164 {
1165 QPopupMenu* popup = Parent::createPopupMenu(pos);
1166 QAction* action = new QAction(NULL,"Show Debug Info", 0, popup);
1167 action->setToggleAction(TRUE);
1168 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1169 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1170 action->setOn(showDebug());
1171 popup->insertSeparator();
1172 action->addTo(popup);
1173 return popup;
1174 }
1175
1176 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1177 {
1178 Parent::contentsContextMenuEvent(e);
1179 }
1180
1181 ConfigSearchWindow::ConfigSearchWindow(QWidget* parent, const char *name)
1182 : Parent(parent, name), result(NULL)
1183 {
1184 setCaption("Search Config");
1185
1186 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1187 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1188 layout2->addWidget(new QLabel("Find:", this));
1189 editField = new QLineEdit(this);
1190 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1191 layout2->addWidget(editField);
1192 searchButton = new QPushButton("Search", this);
1193 searchButton->setAutoDefault(FALSE);
1194 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1195 layout2->addWidget(searchButton);
1196 layout1->addLayout(layout2);
1197
1198 split = new QSplitter(this);
1199 split->setOrientation(QSplitter::Vertical);
1200 list = new ConfigView(split, name);
1201 list->list->mode = listMode;
1202 info = new ConfigInfoView(split, name);
1203 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1204 info, SLOT(setInfo(struct menu *)));
1205 layout1->addWidget(split);
1206
1207 if (name) {
1208 int x, y, width, height;
1209 bool ok;
1210
1211 configSettings->beginGroup(name);
1212 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1213 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1214 resize(width, height);
1215 x = configSettings->readNumEntry("/window x", 0, &ok);
1216 if (ok)
1217 y = configSettings->readNumEntry("/window y", 0, &ok);
1218 if (ok)
1219 move(x, y);
1220 QValueList<int> sizes = configSettings->readSizes("/split", &ok);
1221 if (ok)
1222 split->setSizes(sizes);
1223 configSettings->endGroup();
1224 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1225 }
1226 }
1227
1228 void ConfigSearchWindow::saveSettings(void)
1229 {
1230 if (name()) {
1231 configSettings->beginGroup(name());
1232 configSettings->writeEntry("/window x", pos().x());
1233 configSettings->writeEntry("/window y", pos().y());
1234 configSettings->writeEntry("/window width", size().width());
1235 configSettings->writeEntry("/window height", size().height());
1236 configSettings->writeSizes("/split", split->sizes());
1237 configSettings->endGroup();
1238 }
1239 }
1240
1241 void ConfigSearchWindow::search(void)
1242 {
1243 struct symbol **p;
1244 struct property *prop;
1245 ConfigItem *lastItem = NULL;
1246
1247 free(result);
1248 list->list->clear();
1249
1250 result = sym_re_search(editField->text().latin1());
1251 if (!result)
1252 return;
1253 for (p = result; *p; p++) {
1254 for_all_prompts((*p), prop)
1255 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1256 menu_is_visible(prop->menu));
1257 }
1258 }
1259
1260 /*
1261 * Construct the complete config widget
1262 */
1263 ConfigMainWindow::ConfigMainWindow(void)
1264 : searchWindow(0)
1265 {
1266 QMenuBar* menu;
1267 bool ok;
1268 int x, y, width, height;
1269
1270 QWidget *d = configApp->desktop();
1271
1272 width = configSettings->readNumEntry("/window width", d->width() - 64);
1273 height = configSettings->readNumEntry("/window height", d->height() - 64);
1274 resize(width, height);
1275 x = configSettings->readNumEntry("/window x", 0, &ok);
1276 if (ok)
1277 y = configSettings->readNumEntry("/window y", 0, &ok);
1278 if (ok)
1279 move(x, y);
1280
1281 split1 = new QSplitter(this);
1282 split1->setOrientation(QSplitter::Horizontal);
1283 setCentralWidget(split1);
1284
1285 menuView = new ConfigView(split1, "menu");
1286 menuList = menuView->list;
1287
1288 split2 = new QSplitter(split1);
1289 split2->setOrientation(QSplitter::Vertical);
1290
1291 // create config tree
1292 configView = new ConfigView(split2, "config");
1293 configList = configView->list;
1294
1295 helpText = new ConfigInfoView(split2, "help");
1296 helpText->setTextFormat(Qt::RichText);
1297
1298 setTabOrder(configList, helpText);
1299 configList->setFocus();
1300
1301 menu = menuBar();
1302 toolBar = new QToolBar("Tools", this);
1303
1304 backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
1305 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1306 backAction->setEnabled(FALSE);
1307 QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
1308 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1309 QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
1310 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1311 saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
1312 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1313 conf_set_changed_callback(conf_changed);
1314 // Set saveAction's initial state
1315 conf_changed();
1316 QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
1317 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1318 QAction *searchAction = new QAction("Search", "&Search", CTRL+Key_F, this);
1319 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1320 QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
1321 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1322 QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
1323 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1324 QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
1325 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1326
1327 QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
1328 showNameAction->setToggleAction(TRUE);
1329 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1330 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1331 showNameAction->setOn(configView->showName());
1332 QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
1333 showRangeAction->setToggleAction(TRUE);
1334 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1335 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1336 showRangeAction->setOn(configList->showRange);
1337 QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
1338 showDataAction->setToggleAction(TRUE);
1339 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1340 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1341 showDataAction->setOn(configList->showData);
1342 QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
1343 showAllAction->setToggleAction(TRUE);
1344 connect(showAllAction, SIGNAL(toggled(bool)), configView, SLOT(setShowAll(bool)));
1345 connect(showAllAction, SIGNAL(toggled(bool)), menuView, SLOT(setShowAll(bool)));
1346 showAllAction->setOn(configList->showAll);
1347 QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
1348 showDebugAction->setToggleAction(TRUE);
1349 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1350 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1351 showDebugAction->setOn(helpText->showDebug());
1352
1353 QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
1354 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1355 QAction *showAboutAction = new QAction(NULL, "About", 0, this);
1356 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1357
1358 // init tool bar
1359 backAction->addTo(toolBar);
1360 toolBar->addSeparator();
1361 loadAction->addTo(toolBar);
1362 saveAction->addTo(toolBar);
1363 toolBar->addSeparator();
1364 singleViewAction->addTo(toolBar);
1365 splitViewAction->addTo(toolBar);
1366 fullViewAction->addTo(toolBar);
1367
1368 // create config menu
1369 QPopupMenu* config = new QPopupMenu(this);
1370 menu->insertItem("&File", config);
1371 loadAction->addTo(config);
1372 saveAction->addTo(config);
1373 saveAsAction->addTo(config);
1374 config->insertSeparator();
1375 searchAction->addTo(config);
1376 config->insertSeparator();
1377 quitAction->addTo(config);
1378
1379 // create options menu
1380 QPopupMenu* optionMenu = new QPopupMenu(this);
1381 menu->insertItem("&Option", optionMenu);
1382 showNameAction->addTo(optionMenu);
1383 showRangeAction->addTo(optionMenu);
1384 showDataAction->addTo(optionMenu);
1385 optionMenu->insertSeparator();
1386 showAllAction->addTo(optionMenu);
1387 showDebugAction->addTo(optionMenu);
1388
1389 // create help menu
1390 QPopupMenu* helpMenu = new QPopupMenu(this);
1391 menu->insertSeparator();
1392 menu->insertItem("&Help", helpMenu);
1393 showIntroAction->addTo(helpMenu);
1394 showAboutAction->addTo(helpMenu);
1395
1396 connect(configList, SIGNAL(menuChanged(struct menu *)),
1397 helpText, SLOT(setInfo(struct menu *)));
1398 connect(configList, SIGNAL(menuSelected(struct menu *)),
1399 SLOT(changeMenu(struct menu *)));
1400 connect(configList, SIGNAL(parentSelected()),
1401 SLOT(goBack()));
1402 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1403 helpText, SLOT(setInfo(struct menu *)));
1404 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1405 SLOT(changeMenu(struct menu *)));
1406
1407 connect(configList, SIGNAL(gotFocus(struct menu *)),
1408 helpText, SLOT(setInfo(struct menu *)));
1409 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1410 helpText, SLOT(setInfo(struct menu *)));
1411 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1412 SLOT(listFocusChanged(void)));
1413 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1414 SLOT(setMenuLink(struct menu *)));
1415
1416 QString listMode = configSettings->readEntry("/listMode", "symbol");
1417 if (listMode == "single")
1418 showSingleView();
1419 else if (listMode == "full")
1420 showFullView();
1421 else /*if (listMode == "split")*/
1422 showSplitView();
1423
1424 // UI setup done, restore splitter positions
1425 QValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1426 if (ok)
1427 split1->setSizes(sizes);
1428
1429 sizes = configSettings->readSizes("/split2", &ok);
1430 if (ok)
1431 split2->setSizes(sizes);
1432 }
1433
1434 void ConfigMainWindow::loadConfig(void)
1435 {
1436 QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1437 if (s.isNull())
1438 return;
1439 if (conf_read(QFile::encodeName(s)))
1440 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1441 ConfigView::updateListAll();
1442 }
1443
1444 void ConfigMainWindow::saveConfig(void)
1445 {
1446 if (conf_write(NULL))
1447 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1448 }
1449
1450 void ConfigMainWindow::saveConfigAs(void)
1451 {
1452 QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1453 if (s.isNull())
1454 return;
1455 if (conf_write(QFile::encodeName(s)))
1456 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1457 }
1458
1459 void ConfigMainWindow::searchConfig(void)
1460 {
1461 if (!searchWindow)
1462 searchWindow = new ConfigSearchWindow(this, "search");
1463 searchWindow->show();
1464 }
1465
1466 void ConfigMainWindow::changeMenu(struct menu *menu)
1467 {
1468 configList->setRootMenu(menu);
1469 backAction->setEnabled(TRUE);
1470 }
1471
1472 void ConfigMainWindow::setMenuLink(struct menu *menu)
1473 {
1474 struct menu *parent;
1475 ConfigList* list = NULL;
1476 ConfigItem* item;
1477
1478 if (!menu_is_visible(menu) && !configView->showAll())
1479 return;
1480
1481 switch (configList->mode) {
1482 case singleMode:
1483 list = configList;
1484 parent = menu_get_parent_menu(menu);
1485 if (!parent)
1486 return;
1487 list->setRootMenu(parent);
1488 break;
1489 case symbolMode:
1490 if (menu->flags & MENU_ROOT) {
1491 configList->setRootMenu(menu);
1492 configList->clearSelection();
1493 list = menuList;
1494 } else {
1495 list = configList;
1496 parent = menu_get_parent_menu(menu->parent);
1497 if (!parent)
1498 return;
1499 item = menuList->findConfigItem(parent);
1500 if (item) {
1501 menuList->setSelected(item, TRUE);
1502 menuList->ensureItemVisible(item);
1503 }
1504 list->setRootMenu(parent);
1505 }
1506 break;
1507 case fullMode:
1508 list = configList;
1509 break;
1510 }
1511
1512 if (list) {
1513 item = list->findConfigItem(menu);
1514 if (item) {
1515 list->setSelected(item, TRUE);
1516 list->ensureItemVisible(item);
1517 list->setFocus();
1518 }
1519 }
1520 }
1521
1522 void ConfigMainWindow::listFocusChanged(void)
1523 {
1524 if (menuList->mode == menuMode)
1525 configList->clearSelection();
1526 }
1527
1528 void ConfigMainWindow::goBack(void)
1529 {
1530 ConfigItem* item;
1531
1532 configList->setParentMenu();
1533 if (configList->rootEntry == &rootmenu)
1534 backAction->setEnabled(FALSE);
1535 item = (ConfigItem*)menuList->selectedItem();
1536 while (item) {
1537 if (item->menu == configList->rootEntry) {
1538 menuList->setSelected(item, TRUE);
1539 break;
1540 }
1541 item = (ConfigItem*)item->parent();
1542 }
1543 }
1544
1545 void ConfigMainWindow::showSingleView(void)
1546 {
1547 menuView->hide();
1548 menuList->setRootMenu(0);
1549 configList->mode = singleMode;
1550 if (configList->rootEntry == &rootmenu)
1551 configList->updateListAll();
1552 else
1553 configList->setRootMenu(&rootmenu);
1554 configList->setAllOpen(TRUE);
1555 configList->setFocus();
1556 }
1557
1558 void ConfigMainWindow::showSplitView(void)
1559 {
1560 configList->mode = symbolMode;
1561 if (configList->rootEntry == &rootmenu)
1562 configList->updateListAll();
1563 else
1564 configList->setRootMenu(&rootmenu);
1565 configList->setAllOpen(TRUE);
1566 configApp->processEvents();
1567 menuList->mode = menuMode;
1568 menuList->setRootMenu(&rootmenu);
1569 menuList->setAllOpen(TRUE);
1570 menuView->show();
1571 menuList->setFocus();
1572 }
1573
1574 void ConfigMainWindow::showFullView(void)
1575 {
1576 menuView->hide();
1577 menuList->setRootMenu(0);
1578 configList->mode = fullMode;
1579 if (configList->rootEntry == &rootmenu)
1580 configList->updateListAll();
1581 else
1582 configList->setRootMenu(&rootmenu);
1583 configList->setAllOpen(FALSE);
1584 configList->setFocus();
1585 }
1586
1587 /*
1588 * ask for saving configuration before quitting
1589 * TODO ask only when something changed
1590 */
1591 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1592 {
1593 if (!conf_get_changed()) {
1594 e->accept();
1595 return;
1596 }
1597 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1598 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1599 mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1600 mb.setButtonText(QMessageBox::No, "&Discard Changes");
1601 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1602 switch (mb.exec()) {
1603 case QMessageBox::Yes:
1604 conf_write(NULL);
1605 case QMessageBox::No:
1606 e->accept();
1607 break;
1608 case QMessageBox::Cancel:
1609 e->ignore();
1610 break;
1611 }
1612 }
1613
1614 void ConfigMainWindow::showIntro(void)
1615 {
1616 static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1617 "For each option, a blank box indicates the feature is disabled, a check\n"
1618 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1619 "as a module. Clicking on the box will cycle through the three states.\n\n"
1620 "If you do not see an option (e.g., a device driver) that you believe\n"
1621 "should be present, try turning on Show All Options under the Options menu.\n"
1622 "Although there is no cross reference yet to help you figure out what other\n"
1623 "options must be enabled to support the option you are interested in, you can\n"
1624 "still view the help of a grayed-out option.\n\n"
1625 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1626 "which you can then match by examining other options.\n\n";
1627
1628 QMessageBox::information(this, "qconf", str);
1629 }
1630
1631 void ConfigMainWindow::showAbout(void)
1632 {
1633 static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1634 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1635
1636 QMessageBox::information(this, "qconf", str);
1637 }
1638
1639 void ConfigMainWindow::saveSettings(void)
1640 {
1641 configSettings->writeEntry("/window x", pos().x());
1642 configSettings->writeEntry("/window y", pos().y());
1643 configSettings->writeEntry("/window width", size().width());
1644 configSettings->writeEntry("/window height", size().height());
1645
1646 QString entry;
1647 switch(configList->mode) {
1648 case singleMode :
1649 entry = "single";
1650 break;
1651
1652 case symbolMode :
1653 entry = "split";
1654 break;
1655
1656 case fullMode :
1657 entry = "full";
1658 break;
1659 }
1660 configSettings->writeEntry("/listMode", entry);
1661
1662 configSettings->writeSizes("/split1", split1->sizes());
1663 configSettings->writeSizes("/split2", split2->sizes());
1664 }
1665
1666 void ConfigMainWindow::conf_changed(void)
1667 {
1668 if (saveAction)
1669 saveAction->setEnabled(conf_get_changed());
1670 }
1671
1672 void fixup_rootmenu(struct menu *menu)
1673 {
1674 struct menu *child;
1675 static int menu_cnt = 0;
1676
1677 menu->flags |= MENU_ROOT;
1678 for (child = menu->list; child; child = child->next) {
1679 if (child->prompt && child->prompt->type == P_MENU) {
1680 menu_cnt++;
1681 fixup_rootmenu(child);
1682 menu_cnt--;
1683 } else if (!menu_cnt)
1684 fixup_rootmenu(child);
1685 }
1686 }
1687
1688 static const char *progname;
1689
1690 static void usage(void)
1691 {
1692 printf("%s <config>\n", progname);
1693 exit(0);
1694 }
1695
1696 int main(int ac, char** av)
1697 {
1698 ConfigMainWindow* v;
1699 const char *name;
1700
1701 bindtextdomain(PACKAGE, LOCALEDIR);
1702 textdomain(PACKAGE);
1703
1704 #ifndef LKC_DIRECT_LINK
1705 kconfig_load();
1706 #endif
1707
1708 progname = av[0];
1709 configApp = new QApplication(ac, av);
1710 if (ac > 1 && av[1][0] == '-') {
1711 switch (av[1][1]) {
1712 case 'h':
1713 case '?':
1714 usage();
1715 }
1716 name = av[2];
1717 } else
1718 name = av[1];
1719 if (!name)
1720 usage();
1721
1722 conf_parse(name);
1723 fixup_rootmenu(&rootmenu);
1724 conf_read(NULL);
1725 //zconfdump(stdout);
1726
1727 configSettings = new ConfigSettings();
1728 configSettings->beginGroup("/kconfig/qconf");
1729 v = new ConfigMainWindow();
1730
1731 //zconfdump(stdout);
1732 configApp->setMainWidget(v);
1733 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1734 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1735 v->show();
1736 configApp->exec();
1737
1738 configSettings->endGroup();
1739 delete configSettings;
1740
1741 return 0;
1742 }
This page took 0.066875 seconds and 6 git commands to generate.