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