Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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