src/drivers/usb/Kconfig: increase warning signs for BBB owners
[coreboot.git] / util / kconfig / qconf.cc
blobe787117c7d853399cc426197f97f408680693abd
1 /*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
4 * Released under the terms of the GNU GPL v2.0.
5 */
7 #include <qglobal.h>
9 #include <QMainWindow>
10 #include <QList>
11 #include <qtextbrowser.h>
12 #include <QAction>
13 #include <QFileDialog>
14 #include <QMenu>
16 #include <qapplication.h>
17 #include <qdesktopwidget.h>
18 #include <qtoolbar.h>
19 #include <qlayout.h>
20 #include <qsplitter.h>
21 #include <qlineedit.h>
22 #include <qlabel.h>
23 #include <qpushbutton.h>
24 #include <qmenubar.h>
25 #include <qmessagebox.h>
26 #include <qregexp.h>
27 #include <qevent.h>
29 #include <stdlib.h>
31 #include "lkc.h"
32 #include "qconf.h"
34 #include "qconf.moc"
35 #include "images.c"
37 #ifdef _
38 # undef _
39 # define _ qgettext
40 #endif
42 int kconfig_warnings = 0;
44 static QApplication *configApp;
45 static ConfigSettings *configSettings;
47 QAction *ConfigMainWindow::saveAction;
49 static inline QString qgettext(const char* str)
51 return QString::fromLocal8Bit(gettext(str));
54 static inline QString qgettext(const QString& str)
56 return QString::fromLocal8Bit(gettext(str.toLatin1()));
59 ConfigSettings::ConfigSettings()
60 : QSettings("kernel.org", "qconf")
64 /**
65 * Reads a list of integer values from the application settings.
67 QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
69 QList<int> result;
70 QStringList entryList = value(key).toStringList();
71 QStringList::Iterator it;
73 for (it = entryList.begin(); it != entryList.end(); ++it)
74 result.push_back((*it).toInt());
76 return result;
79 /**
80 * Writes a list of integer values to the application settings.
82 bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
84 QStringList stringList;
85 QList<int>::ConstIterator it;
87 for (it = value.begin(); it != value.end(); ++it)
88 stringList.push_back(QString::number(*it));
89 setValue(key, stringList);
91 return true;
96 * set the new data
97 * TODO check the value
99 void ConfigItem::okRename(int col)
104 * update the displayed of a menu entry
106 void ConfigItem::updateMenu(void)
108 ConfigList* list;
109 struct symbol* sym;
110 struct property *prop;
111 QString prompt;
112 int type;
113 tristate expr;
115 list = listView();
116 if (goParent) {
117 setPixmap(promptColIdx, list->menuBackPix);
118 prompt = "..";
119 goto set_prompt;
122 sym = menu->sym;
123 prop = menu->prompt;
124 prompt = _(menu_get_prompt(menu));
126 if (prop) switch (prop->type) {
127 case P_MENU:
128 if (list->mode == singleMode || list->mode == symbolMode) {
129 /* a menuconfig entry is displayed differently
130 * depending whether it's at the view root or a child.
132 if (sym && list->rootEntry == menu)
133 break;
134 setPixmap(promptColIdx, list->menuPix);
135 } else {
136 if (sym)
137 break;
138 setPixmap(promptColIdx, QIcon());
140 goto set_prompt;
141 case P_COMMENT:
142 setPixmap(promptColIdx, QIcon());
143 goto set_prompt;
144 default:
147 if (!sym)
148 goto set_prompt;
150 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
152 type = sym_get_type(sym);
153 switch (type) {
154 case S_BOOLEAN:
155 case S_TRISTATE:
156 char ch;
158 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
159 setPixmap(promptColIdx, QIcon());
160 setText(noColIdx, QString::null);
161 setText(modColIdx, QString::null);
162 setText(yesColIdx, QString::null);
163 break;
165 expr = sym_get_tristate_value(sym);
166 switch (expr) {
167 case yes:
168 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
169 setPixmap(promptColIdx, list->choiceYesPix);
170 else
171 setPixmap(promptColIdx, list->symbolYesPix);
172 setText(yesColIdx, "Y");
173 ch = 'Y';
174 break;
175 case mod:
176 setPixmap(promptColIdx, list->symbolModPix);
177 setText(modColIdx, "M");
178 ch = 'M';
179 break;
180 default:
181 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
182 setPixmap(promptColIdx, list->choiceNoPix);
183 else
184 setPixmap(promptColIdx, list->symbolNoPix);
185 setText(noColIdx, "N");
186 ch = 'N';
187 break;
189 if (expr != no)
190 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
191 if (expr != mod)
192 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
193 if (expr != yes)
194 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
196 setText(dataColIdx, QChar(ch));
197 break;
198 case S_INT:
199 case S_HEX:
200 case S_STRING:
201 const char* data;
203 data = sym_get_string_value(sym);
205 setText(dataColIdx, data);
206 if (type == S_STRING)
207 prompt = QString("%1: %2").arg(prompt).arg(data);
208 else
209 prompt = QString("(%2) %1").arg(prompt).arg(data);
210 break;
212 if (!sym_has_value(sym) && visible)
213 prompt += _(" (NEW)");
214 set_prompt:
215 setText(promptColIdx, prompt);
218 void ConfigItem::testUpdateMenu(bool v)
220 ConfigItem* i;
222 visible = v;
223 if (!menu)
224 return;
226 sym_calc_value(menu->sym);
227 if (menu->flags & MENU_CHANGED) {
228 /* the menu entry changed, so update all list items */
229 menu->flags &= ~MENU_CHANGED;
230 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
231 i->updateMenu();
232 } else if (listView()->updateAll)
233 updateMenu();
238 * construct a menu entry
240 void ConfigItem::init(void)
242 if (menu) {
243 ConfigList* list = listView();
244 nextItem = (ConfigItem*)menu->data;
245 menu->data = this;
247 if (list->mode != fullMode)
248 setExpanded(true);
249 sym_calc_value(menu->sym);
251 updateMenu();
255 * destruct a menu entry
257 ConfigItem::~ConfigItem(void)
259 if (menu) {
260 ConfigItem** ip = (ConfigItem**)&menu->data;
261 for (; *ip; ip = &(*ip)->nextItem) {
262 if (*ip == this) {
263 *ip = nextItem;
264 break;
270 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
271 : Parent(parent)
273 connect(this, SIGNAL(editingFinished()), SLOT(hide()));
276 void ConfigLineEdit::show(ConfigItem* i)
278 item = i;
279 if (sym_get_string_value(item->menu->sym))
280 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
281 else
282 setText(QString::null);
283 Parent::show();
284 setFocus();
287 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
289 switch (e->key()) {
290 case Qt::Key_Escape:
291 break;
292 case Qt::Key_Return:
293 case Qt::Key_Enter:
294 sym_set_string_value(item->menu->sym, text().toLatin1());
295 parent()->updateList(item);
296 break;
297 default:
298 Parent::keyPressEvent(e);
299 return;
301 e->accept();
302 parent()->list->setFocus();
303 hide();
306 ConfigList::ConfigList(ConfigView* p, const char *name)
307 : Parent(p),
308 updateAll(false),
309 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
310 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
311 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
312 showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
313 rootEntry(0), headerPopup(0)
315 int i;
317 setObjectName(name);
318 setSortingEnabled(false);
319 setRootIsDecorated(true);
321 setVerticalScrollMode(ScrollPerPixel);
322 setHorizontalScrollMode(ScrollPerPixel);
324 setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value"));
326 connect(this, SIGNAL(itemSelectionChanged(void)),
327 SLOT(updateSelection(void)));
329 if (name) {
330 configSettings->beginGroup(name);
331 showName = configSettings->value("/showName", false).toBool();
332 showRange = configSettings->value("/showRange", false).toBool();
333 showData = configSettings->value("/showData", false).toBool();
334 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
335 configSettings->endGroup();
336 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
339 addColumn(promptColIdx);
341 reinit();
344 bool ConfigList::menuSkip(struct menu *menu)
346 if (optMode == normalOpt && menu_is_visible(menu))
347 return false;
348 if (optMode == promptOpt && menu_has_prompt(menu))
349 return false;
350 if (optMode == allOpt)
351 return false;
352 return true;
355 void ConfigList::reinit(void)
357 removeColumn(dataColIdx);
358 removeColumn(yesColIdx);
359 removeColumn(modColIdx);
360 removeColumn(noColIdx);
361 removeColumn(nameColIdx);
363 if (showName)
364 addColumn(nameColIdx);
365 if (showRange) {
366 addColumn(noColIdx);
367 addColumn(modColIdx);
368 addColumn(yesColIdx);
370 if (showData)
371 addColumn(dataColIdx);
373 updateListAll();
376 void ConfigList::saveSettings(void)
378 if (!objectName().isEmpty()) {
379 configSettings->beginGroup(objectName());
380 configSettings->setValue("/showName", showName);
381 configSettings->setValue("/showRange", showRange);
382 configSettings->setValue("/showData", showData);
383 configSettings->setValue("/optionMode", (int)optMode);
384 configSettings->endGroup();
388 ConfigItem* ConfigList::findConfigItem(struct menu *menu)
390 ConfigItem* item = (ConfigItem*)menu->data;
392 for (; item; item = item->nextItem) {
393 if (this == item->listView())
394 break;
397 return item;
400 void ConfigList::updateSelection(void)
402 struct menu *menu;
403 enum prop_type type;
405 if (selectedItems().count() == 0)
406 return;
408 ConfigItem* item = (ConfigItem*)selectedItems().first();
409 if (!item)
410 return;
412 menu = item->menu;
413 emit menuChanged(menu);
414 if (!menu)
415 return;
416 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
417 if (mode == menuMode && type == P_MENU)
418 emit menuSelected(menu);
421 void ConfigList::updateList(ConfigItem* item)
423 ConfigItem* last = 0;
425 if (!rootEntry) {
426 if (mode != listMode)
427 goto update;
428 QTreeWidgetItemIterator it(this);
429 ConfigItem* item;
431 while (*it) {
432 item = (ConfigItem*)(*it);
433 if (!item->menu)
434 continue;
435 item->testUpdateMenu(menu_is_visible(item->menu));
437 ++it;
439 return;
442 if (rootEntry != &rootmenu && (mode == singleMode ||
443 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
444 item = (ConfigItem *)topLevelItem(0);
445 if (!item)
446 item = new ConfigItem(this, 0, true);
447 last = item;
449 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
450 rootEntry->sym && rootEntry->prompt) {
451 item = last ? last->nextSibling() : firstChild();
452 if (!item)
453 item = new ConfigItem(this, last, rootEntry, true);
454 else
455 item->testUpdateMenu(true);
457 updateMenuList(item, rootEntry);
458 update();
459 resizeColumnToContents(0);
460 return;
462 update:
463 updateMenuList(this, rootEntry);
464 update();
465 resizeColumnToContents(0);
468 void ConfigList::setValue(ConfigItem* item, tristate val)
470 struct symbol* sym;
471 int type;
472 tristate oldval;
474 sym = item->menu ? item->menu->sym : 0;
475 if (!sym)
476 return;
478 type = sym_get_type(sym);
479 switch (type) {
480 case S_BOOLEAN:
481 case S_TRISTATE:
482 oldval = sym_get_tristate_value(sym);
484 if (!sym_set_tristate_value(sym, val))
485 return;
486 if (oldval == no && item->menu->list)
487 item->setExpanded(true);
488 parent()->updateList(item);
489 break;
493 void ConfigList::changeValue(ConfigItem* item)
495 struct symbol* sym;
496 struct menu* menu;
497 int type, oldexpr, newexpr;
499 menu = item->menu;
500 if (!menu)
501 return;
502 sym = menu->sym;
503 if (!sym) {
504 if (item->menu->list)
505 item->setExpanded(!item->isExpanded());
506 return;
509 type = sym_get_type(sym);
510 switch (type) {
511 case S_BOOLEAN:
512 case S_TRISTATE:
513 oldexpr = sym_get_tristate_value(sym);
514 newexpr = sym_toggle_tristate_value(sym);
515 if (item->menu->list) {
516 if (oldexpr == newexpr)
517 item->setExpanded(!item->isExpanded());
518 else if (oldexpr == no)
519 item->setExpanded(true);
521 if (oldexpr != newexpr)
522 parent()->updateList(item);
523 break;
524 case S_INT:
525 case S_HEX:
526 case S_STRING:
527 parent()->lineEdit->show(item);
528 break;
532 void ConfigList::setRootMenu(struct menu *menu)
534 enum prop_type type;
536 if (rootEntry == menu)
537 return;
538 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
539 if (type != P_MENU)
540 return;
541 updateMenuList(this, 0);
542 rootEntry = menu;
543 updateListAll();
544 if (currentItem()) {
545 currentItem()->setSelected(hasFocus());
546 scrollToItem(currentItem());
550 void ConfigList::setParentMenu(void)
552 ConfigItem* item;
553 struct menu *oldroot;
555 oldroot = rootEntry;
556 if (rootEntry == &rootmenu)
557 return;
558 setRootMenu(menu_get_parent_menu(rootEntry->parent));
560 QTreeWidgetItemIterator it(this);
561 while (*it) {
562 item = (ConfigItem *)(*it);
563 if (item->menu == oldroot) {
564 setCurrentItem(item);
565 scrollToItem(item);
566 break;
569 ++it;
574 * update all the children of a menu entry
575 * removes/adds the entries from the parent widget as necessary
577 * parent: either the menu list widget or a menu entry widget
578 * menu: entry to be updated
580 void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
582 struct menu* child;
583 ConfigItem* item;
584 ConfigItem* last;
585 bool visible;
586 enum prop_type type;
588 if (!menu) {
589 while (parent->childCount() > 0)
591 delete parent->takeChild(0);
594 return;
597 last = parent->firstChild();
598 if (last && !last->goParent)
599 last = 0;
600 for (child = menu->list; child; child = child->next) {
601 item = last ? last->nextSibling() : parent->firstChild();
602 type = child->prompt ? child->prompt->type : P_UNKNOWN;
604 switch (mode) {
605 case menuMode:
606 if (!(child->flags & MENU_ROOT))
607 goto hide;
608 break;
609 case symbolMode:
610 if (child->flags & MENU_ROOT)
611 goto hide;
612 break;
613 default:
614 break;
617 visible = menu_is_visible(child);
618 if (!menuSkip(child)) {
619 if (!child->sym && !child->list && !child->prompt)
620 continue;
621 if (!item || item->menu != child)
622 item = new ConfigItem(parent, last, child, visible);
623 else
624 item->testUpdateMenu(visible);
626 if (mode == fullMode || mode == menuMode || type != P_MENU)
627 updateMenuList(item, child);
628 else
629 updateMenuList(item, 0);
630 last = item;
631 continue;
633 hide:
634 if (item && item->menu == child) {
635 last = parent->firstChild();
636 if (last == item)
637 last = 0;
638 else while (last->nextSibling() != item)
639 last = last->nextSibling();
640 delete item;
645 void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
647 struct menu* child;
648 ConfigItem* item;
649 ConfigItem* last;
650 bool visible;
651 enum prop_type type;
653 if (!menu) {
654 while (parent->topLevelItemCount() > 0)
656 delete parent->takeTopLevelItem(0);
659 return;
662 last = (ConfigItem*)parent->topLevelItem(0);
663 if (last && !last->goParent)
664 last = 0;
665 for (child = menu->list; child; child = child->next) {
666 item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
667 type = child->prompt ? child->prompt->type : P_UNKNOWN;
669 switch (mode) {
670 case menuMode:
671 if (!(child->flags & MENU_ROOT))
672 goto hide;
673 break;
674 case symbolMode:
675 if (child->flags & MENU_ROOT)
676 goto hide;
677 break;
678 default:
679 break;
682 visible = menu_is_visible(child);
683 if (!menuSkip(child)) {
684 if (!child->sym && !child->list && !child->prompt)
685 continue;
686 if (!item || item->menu != child)
687 item = new ConfigItem(parent, last, child, visible);
688 else
689 item->testUpdateMenu(visible);
691 if (mode == fullMode || mode == menuMode || type != P_MENU)
692 updateMenuList(item, child);
693 else
694 updateMenuList(item, 0);
695 last = item;
696 continue;
698 hide:
699 if (item && item->menu == child) {
700 last = (ConfigItem*)parent->topLevelItem(0);
701 if (last == item)
702 last = 0;
703 else while (last->nextSibling() != item)
704 last = last->nextSibling();
705 delete item;
710 void ConfigList::keyPressEvent(QKeyEvent* ev)
712 QTreeWidgetItem* i = currentItem();
713 ConfigItem* item;
714 struct menu *menu;
715 enum prop_type type;
717 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
718 emit parentSelected();
719 ev->accept();
720 return;
723 if (!i) {
724 Parent::keyPressEvent(ev);
725 return;
727 item = (ConfigItem*)i;
729 switch (ev->key()) {
730 case Qt::Key_Return:
731 case Qt::Key_Enter:
732 if (item->goParent) {
733 emit parentSelected();
734 break;
736 menu = item->menu;
737 if (!menu)
738 break;
739 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
740 if (type == P_MENU && rootEntry != menu &&
741 mode != fullMode && mode != menuMode) {
742 emit menuSelected(menu);
743 break;
745 case Qt::Key_Space:
746 changeValue(item);
747 break;
748 case Qt::Key_N:
749 setValue(item, no);
750 break;
751 case Qt::Key_M:
752 setValue(item, mod);
753 break;
754 case Qt::Key_Y:
755 setValue(item, yes);
756 break;
757 default:
758 Parent::keyPressEvent(ev);
759 return;
761 ev->accept();
764 void ConfigList::mousePressEvent(QMouseEvent* e)
766 //QPoint p(contentsToViewport(e->pos()));
767 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
768 Parent::mousePressEvent(e);
771 void ConfigList::mouseReleaseEvent(QMouseEvent* e)
773 QPoint p = e->pos();
774 ConfigItem* item = (ConfigItem*)itemAt(p);
775 struct menu *menu;
776 enum prop_type ptype;
777 QIcon icon;
778 int idx, x;
780 if (!item)
781 goto skip;
783 menu = item->menu;
784 x = header()->offset() + p.x();
785 idx = header()->logicalIndexAt(x);
786 switch (idx) {
787 case promptColIdx:
788 icon = item->pixmap(promptColIdx);
789 if (!icon.isNull()) {
790 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
791 if (x >= off && x < off + icon.availableSizes().first().width()) {
792 if (item->goParent) {
793 emit parentSelected();
794 break;
795 } else if (!menu)
796 break;
797 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
798 if (ptype == P_MENU && rootEntry != menu &&
799 mode != fullMode && mode != menuMode)
800 emit menuSelected(menu);
801 else
802 changeValue(item);
805 break;
806 case noColIdx:
807 setValue(item, no);
808 break;
809 case modColIdx:
810 setValue(item, mod);
811 break;
812 case yesColIdx:
813 setValue(item, yes);
814 break;
815 case dataColIdx:
816 changeValue(item);
817 break;
820 skip:
821 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
822 Parent::mouseReleaseEvent(e);
825 void ConfigList::mouseMoveEvent(QMouseEvent* e)
827 //QPoint p(contentsToViewport(e->pos()));
828 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
829 Parent::mouseMoveEvent(e);
832 void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
834 QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
835 ConfigItem* item = (ConfigItem*)itemAt(p);
836 struct menu *menu;
837 enum prop_type ptype;
839 if (!item)
840 goto skip;
841 if (item->goParent) {
842 emit parentSelected();
843 goto skip;
845 menu = item->menu;
846 if (!menu)
847 goto skip;
848 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
849 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
850 emit menuSelected(menu);
851 else if (menu->sym)
852 changeValue(item);
854 skip:
855 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
856 Parent::mouseDoubleClickEvent(e);
859 void ConfigList::focusInEvent(QFocusEvent *e)
861 struct menu *menu = NULL;
863 Parent::focusInEvent(e);
865 ConfigItem* item = (ConfigItem *)currentItem();
866 if (item) {
867 item->setSelected(true);
868 menu = item->menu;
870 emit gotFocus(menu);
873 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
875 if (e->y() <= header()->geometry().bottom()) {
876 if (!headerPopup) {
877 QAction *action;
879 headerPopup = new QMenu(this);
880 action = new QAction(_("Show Name"), this);
881 action->setCheckable(true);
882 connect(action, SIGNAL(toggled(bool)),
883 parent(), SLOT(setShowName(bool)));
884 connect(parent(), SIGNAL(showNameChanged(bool)),
885 action, SLOT(setOn(bool)));
886 action->setChecked(showName);
887 headerPopup->addAction(action);
888 action = new QAction(_("Show Range"), this);
889 action->setCheckable(true);
890 connect(action, SIGNAL(toggled(bool)),
891 parent(), SLOT(setShowRange(bool)));
892 connect(parent(), SIGNAL(showRangeChanged(bool)),
893 action, SLOT(setOn(bool)));
894 action->setChecked(showRange);
895 headerPopup->addAction(action);
896 action = new QAction(_("Show Data"), this);
897 action->setCheckable(true);
898 connect(action, SIGNAL(toggled(bool)),
899 parent(), SLOT(setShowData(bool)));
900 connect(parent(), SIGNAL(showDataChanged(bool)),
901 action, SLOT(setOn(bool)));
902 action->setChecked(showData);
903 headerPopup->addAction(action);
905 headerPopup->exec(e->globalPos());
906 e->accept();
907 } else
908 e->ignore();
911 ConfigView*ConfigView::viewList;
912 QAction *ConfigView::showNormalAction;
913 QAction *ConfigView::showAllAction;
914 QAction *ConfigView::showPromptAction;
916 ConfigView::ConfigView(QWidget* parent, const char *name)
917 : Parent(parent)
919 setObjectName(name);
920 QVBoxLayout *verticalLayout = new QVBoxLayout(this);
921 verticalLayout->setContentsMargins(0, 0, 0, 0);
923 list = new ConfigList(this);
924 verticalLayout->addWidget(list);
925 lineEdit = new ConfigLineEdit(this);
926 lineEdit->hide();
927 verticalLayout->addWidget(lineEdit);
929 this->nextView = viewList;
930 viewList = this;
933 ConfigView::~ConfigView(void)
935 ConfigView** vp;
937 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
938 if (*vp == this) {
939 *vp = nextView;
940 break;
945 void ConfigView::setOptionMode(QAction *act)
947 if (act == showNormalAction)
948 list->optMode = normalOpt;
949 else if (act == showAllAction)
950 list->optMode = allOpt;
951 else
952 list->optMode = promptOpt;
954 list->updateListAll();
957 void ConfigView::setShowName(bool b)
959 if (list->showName != b) {
960 list->showName = b;
961 list->reinit();
962 emit showNameChanged(b);
966 void ConfigView::setShowRange(bool b)
968 if (list->showRange != b) {
969 list->showRange = b;
970 list->reinit();
971 emit showRangeChanged(b);
975 void ConfigView::setShowData(bool b)
977 if (list->showData != b) {
978 list->showData = b;
979 list->reinit();
980 emit showDataChanged(b);
984 void ConfigList::setAllOpen(bool open)
986 QTreeWidgetItemIterator it(this);
988 while (*it) {
989 (*it)->setExpanded(open);
991 ++it;
995 void ConfigView::updateList(ConfigItem* item)
997 ConfigView* v;
999 for (v = viewList; v; v = v->nextView)
1000 v->list->updateList(item);
1003 void ConfigView::updateListAll(void)
1005 ConfigView* v;
1007 for (v = viewList; v; v = v->nextView)
1008 v->list->updateListAll();
1011 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
1012 : Parent(parent), sym(0), _menu(0)
1014 setObjectName(name);
1017 if (!objectName().isEmpty()) {
1018 configSettings->beginGroup(objectName());
1019 _showDebug = configSettings->value("/showDebug", false).toBool();
1020 configSettings->endGroup();
1021 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1025 void ConfigInfoView::saveSettings(void)
1027 if (!objectName().isEmpty()) {
1028 configSettings->beginGroup(objectName());
1029 configSettings->setValue("/showDebug", showDebug());
1030 configSettings->endGroup();
1034 void ConfigInfoView::setShowDebug(bool b)
1036 if (_showDebug != b) {
1037 _showDebug = b;
1038 if (_menu)
1039 menuInfo();
1040 else if (sym)
1041 symbolInfo();
1042 emit showDebugChanged(b);
1046 void ConfigInfoView::setInfo(struct menu *m)
1048 if (_menu == m)
1049 return;
1050 _menu = m;
1051 sym = NULL;
1052 if (!_menu)
1053 clear();
1054 else
1055 menuInfo();
1058 void ConfigInfoView::symbolInfo(void)
1060 QString str;
1062 str += "<big>Symbol: <b>";
1063 str += print_filter(sym->name);
1064 str += "</b></big><br><br>value: ";
1065 str += print_filter(sym_get_string_value(sym));
1066 str += "<br>visibility: ";
1067 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1068 str += "<br>";
1069 str += debug_info(sym);
1071 setText(str);
1074 void ConfigInfoView::menuInfo(void)
1076 struct symbol* sym;
1077 QString head, debug, help;
1079 sym = _menu->sym;
1080 if (sym) {
1081 if (_menu->prompt) {
1082 head += "<big><b>";
1083 head += print_filter(_(_menu->prompt->text));
1084 head += "</b></big>";
1085 if (sym->name) {
1086 head += " (";
1087 if (showDebug())
1088 head += QString().sprintf("<a href=\"s%p\">", sym);
1089 head += print_filter(sym->name);
1090 if (showDebug())
1091 head += "</a>";
1092 head += ")";
1094 } else if (sym->name) {
1095 head += "<big><b>";
1096 if (showDebug())
1097 head += QString().sprintf("<a href=\"s%p\">", sym);
1098 head += print_filter(sym->name);
1099 if (showDebug())
1100 head += "</a>";
1101 head += "</b></big>";
1103 head += "<br><br>";
1105 if (showDebug())
1106 debug = debug_info(sym);
1108 struct gstr help_gstr = str_new();
1109 menu_get_ext_help(_menu, &help_gstr);
1110 help = print_filter(str_get(&help_gstr));
1111 str_free(&help_gstr);
1112 } else if (_menu->prompt) {
1113 head += "<big><b>";
1114 head += print_filter(_(_menu->prompt->text));
1115 head += "</b></big><br><br>";
1116 if (showDebug()) {
1117 if (_menu->prompt->visible.expr) {
1118 debug += "&nbsp;&nbsp;dep: ";
1119 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1120 debug += "<br><br>";
1124 if (showDebug())
1125 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
1127 setText(head + debug + help);
1130 QString ConfigInfoView::debug_info(struct symbol *sym)
1132 QString debug;
1134 debug += "type: ";
1135 debug += print_filter(sym_type_name(sym->type));
1136 if (sym_is_choice(sym))
1137 debug += " (choice)";
1138 debug += "<br>";
1139 if (sym->rev_dep.expr) {
1140 debug += "reverse dep: ";
1141 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1142 debug += "<br>";
1144 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1145 switch (prop->type) {
1146 case P_PROMPT:
1147 case P_MENU:
1148 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1149 debug += print_filter(_(prop->text));
1150 debug += "</a><br>";
1151 break;
1152 case P_DEFAULT:
1153 case P_SELECT:
1154 case P_RANGE:
1155 case P_ENV:
1156 debug += prop_get_type_name(prop->type);
1157 debug += ": ";
1158 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1159 debug += "<br>";
1160 break;
1161 case P_CHOICE:
1162 if (sym_is_choice(sym)) {
1163 debug += "choice: ";
1164 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1165 debug += "<br>";
1167 break;
1168 default:
1169 debug += "unknown property: ";
1170 debug += prop_get_type_name(prop->type);
1171 debug += "<br>";
1173 if (prop->visible.expr) {
1174 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1175 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1176 debug += "<br>";
1179 debug += "<br>";
1181 return debug;
1184 QString ConfigInfoView::print_filter(const QString &str)
1186 QRegExp re("[<>&\"\\n]");
1187 QString res = str;
1188 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
1189 switch (res[i].toLatin1()) {
1190 case '<':
1191 res.replace(i, 1, "&lt;");
1192 i += 4;
1193 break;
1194 case '>':
1195 res.replace(i, 1, "&gt;");
1196 i += 4;
1197 break;
1198 case '&':
1199 res.replace(i, 1, "&amp;");
1200 i += 5;
1201 break;
1202 case '"':
1203 res.replace(i, 1, "&quot;");
1204 i += 6;
1205 break;
1206 case '\n':
1207 res.replace(i, 1, "<br>");
1208 i += 4;
1209 break;
1212 return res;
1215 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1217 QString* text = reinterpret_cast<QString*>(data);
1218 QString str2 = print_filter(str);
1220 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1221 *text += QString().sprintf("<a href=\"s%p\">", sym);
1222 *text += str2;
1223 *text += "</a>";
1224 } else
1225 *text += str2;
1228 QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
1230 QMenu* popup = Parent::createStandardContextMenu(pos);
1231 QAction* action = new QAction(_("Show Debug Info"), popup);
1232 action->setCheckable(true);
1233 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1234 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1235 action->setChecked(showDebug());
1236 popup->addSeparator();
1237 popup->addAction(action);
1238 return popup;
1241 void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
1243 Parent::contextMenuEvent(e);
1246 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
1247 : Parent(parent), result(NULL)
1249 setObjectName(name);
1250 setWindowTitle("Search Config");
1252 QVBoxLayout* layout1 = new QVBoxLayout(this);
1253 layout1->setContentsMargins(11, 11, 11, 11);
1254 layout1->setSpacing(6);
1255 QHBoxLayout* layout2 = new QHBoxLayout(0);
1256 layout2->setContentsMargins(0, 0, 0, 0);
1257 layout2->setSpacing(6);
1258 layout2->addWidget(new QLabel(_("Find:"), this));
1259 editField = new QLineEdit(this);
1260 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1261 layout2->addWidget(editField);
1262 searchButton = new QPushButton(_("Search"), this);
1263 searchButton->setAutoDefault(false);
1264 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1265 layout2->addWidget(searchButton);
1266 layout1->addLayout(layout2);
1268 split = new QSplitter(this);
1269 split->setOrientation(Qt::Vertical);
1270 list = new ConfigView(split, name);
1271 list->list->mode = listMode;
1272 info = new ConfigInfoView(split, name);
1273 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1274 info, SLOT(setInfo(struct menu *)));
1275 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1276 parent, SLOT(setMenuLink(struct menu *)));
1278 layout1->addWidget(split);
1280 if (name) {
1281 QVariant x, y;
1282 int width, height;
1283 bool ok;
1285 configSettings->beginGroup(name);
1286 width = configSettings->value("/window width", parent->width() / 2).toInt();
1287 height = configSettings->value("/window height", parent->height() / 2).toInt();
1288 resize(width, height);
1289 x = configSettings->value("/window x");
1290 y = configSettings->value("/window y");
1291 if ((x.isValid())&&(y.isValid()))
1292 move(x.toInt(), y.toInt());
1293 QList<int> sizes = configSettings->readSizes("/split", &ok);
1294 if (ok)
1295 split->setSizes(sizes);
1296 configSettings->endGroup();
1297 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1301 void ConfigSearchWindow::saveSettings(void)
1303 if (!objectName().isEmpty()) {
1304 configSettings->beginGroup(objectName());
1305 configSettings->setValue("/window x", pos().x());
1306 configSettings->setValue("/window y", pos().y());
1307 configSettings->setValue("/window width", size().width());
1308 configSettings->setValue("/window height", size().height());
1309 configSettings->writeSizes("/split", split->sizes());
1310 configSettings->endGroup();
1314 void ConfigSearchWindow::search(void)
1316 struct symbol **p;
1317 struct property *prop;
1318 ConfigItem *lastItem = NULL;
1320 free(result);
1321 list->list->clear();
1322 info->clear();
1324 result = sym_re_search(editField->text().toLatin1());
1325 if (!result)
1326 return;
1327 for (p = result; *p; p++) {
1328 for_all_prompts((*p), prop)
1329 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1330 menu_is_visible(prop->menu));
1335 * Construct the complete config widget
1337 ConfigMainWindow::ConfigMainWindow(void)
1338 : searchWindow(0)
1340 QMenuBar* menu;
1341 bool ok = true;
1342 QVariant x, y;
1343 int width, height;
1344 char title[256];
1346 QDesktopWidget *d = configApp->desktop();
1347 snprintf(title, sizeof(title), "%s%s",
1348 rootmenu.prompt->text,
1351 setWindowTitle(title);
1353 width = configSettings->value("/window width", d->width() - 64).toInt();
1354 height = configSettings->value("/window height", d->height() - 64).toInt();
1355 resize(width, height);
1356 x = configSettings->value("/window x");
1357 y = configSettings->value("/window y");
1358 if ((x.isValid())&&(y.isValid()))
1359 move(x.toInt(), y.toInt());
1361 split1 = new QSplitter(this);
1362 split1->setOrientation(Qt::Horizontal);
1363 setCentralWidget(split1);
1365 menuView = new ConfigView(split1, "menu");
1366 menuList = menuView->list;
1368 split2 = new QSplitter(split1);
1369 split2->setOrientation(Qt::Vertical);
1371 // create config tree
1372 configView = new ConfigView(split2, "config");
1373 configList = configView->list;
1375 helpText = new ConfigInfoView(split2, "help");
1377 setTabOrder(configList, helpText);
1378 configList->setFocus();
1380 menu = menuBar();
1381 toolBar = new QToolBar("Tools", this);
1382 addToolBar(toolBar);
1384 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
1385 connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
1386 backAction->setEnabled(false);
1387 QAction *quitAction = new QAction(_("&Quit"), this);
1388 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
1389 connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
1390 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1391 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
1392 connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
1393 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1394 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
1395 connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
1396 conf_set_changed_callback(conf_changed);
1397 // Set saveAction's initial state
1398 conf_changed();
1399 QAction *saveAsAction = new QAction(_("Save &As..."), this);
1400 connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
1401 QAction *searchAction = new QAction(_("&Find"), this);
1402 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
1403 connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
1404 singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
1405 singleViewAction->setCheckable(true);
1406 connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
1407 splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
1408 splitViewAction->setCheckable(true);
1409 connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
1410 fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
1411 fullViewAction->setCheckable(true);
1412 connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
1414 QAction *showNameAction = new QAction(_("Show Name"), this);
1415 showNameAction->setCheckable(true);
1416 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1417 showNameAction->setChecked(configView->showName());
1418 QAction *showRangeAction = new QAction(_("Show Range"), this);
1419 showRangeAction->setCheckable(true);
1420 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1421 QAction *showDataAction = new QAction(_("Show Data"), this);
1422 showDataAction->setCheckable(true);
1423 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1425 QActionGroup *optGroup = new QActionGroup(this);
1426 optGroup->setExclusive(true);
1427 connect(optGroup, SIGNAL(triggered(QAction*)), configView,
1428 SLOT(setOptionMode(QAction *)));
1429 connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
1430 SLOT(setOptionMode(QAction *)));
1432 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1433 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1434 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
1435 configView->showNormalAction->setCheckable(true);
1436 configView->showAllAction->setCheckable(true);
1437 configView->showPromptAction->setCheckable(true);
1439 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
1440 showDebugAction->setCheckable(true);
1441 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1442 showDebugAction->setChecked(helpText->showDebug());
1444 QAction *showIntroAction = new QAction( _("Introduction"), this);
1445 connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
1446 QAction *showAboutAction = new QAction( _("About"), this);
1447 connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
1449 // init tool bar
1450 toolBar->addAction(backAction);
1451 toolBar->addSeparator();
1452 toolBar->addAction(loadAction);
1453 toolBar->addAction(saveAction);
1454 toolBar->addSeparator();
1455 toolBar->addAction(singleViewAction);
1456 toolBar->addAction(splitViewAction);
1457 toolBar->addAction(fullViewAction);
1459 // create config menu
1460 QMenu* config = menu->addMenu(_("&File"));
1461 config->addAction(loadAction);
1462 config->addAction(saveAction);
1463 config->addAction(saveAsAction);
1464 config->addSeparator();
1465 config->addAction(quitAction);
1467 // create edit menu
1468 QMenu* editMenu = menu->addMenu(_("&Edit"));
1469 editMenu->addAction(searchAction);
1471 // create options menu
1472 QMenu* optionMenu = menu->addMenu(_("&Option"));
1473 optionMenu->addAction(showNameAction);
1474 optionMenu->addAction(showRangeAction);
1475 optionMenu->addAction(showDataAction);
1476 optionMenu->addSeparator();
1477 optionMenu->addActions(optGroup->actions());
1478 optionMenu->addSeparator();
1480 // create help menu
1481 menu->addSeparator();
1482 QMenu* helpMenu = menu->addMenu(_("&Help"));
1483 helpMenu->addAction(showIntroAction);
1484 helpMenu->addAction(showAboutAction);
1486 connect(configList, SIGNAL(menuChanged(struct menu *)),
1487 helpText, SLOT(setInfo(struct menu *)));
1488 connect(configList, SIGNAL(menuSelected(struct menu *)),
1489 SLOT(changeMenu(struct menu *)));
1490 connect(configList, SIGNAL(parentSelected()),
1491 SLOT(goBack()));
1492 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1493 helpText, SLOT(setInfo(struct menu *)));
1494 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1495 SLOT(changeMenu(struct menu *)));
1497 connect(configList, SIGNAL(gotFocus(struct menu *)),
1498 helpText, SLOT(setInfo(struct menu *)));
1499 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1500 helpText, SLOT(setInfo(struct menu *)));
1501 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1502 SLOT(listFocusChanged(void)));
1503 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1504 SLOT(setMenuLink(struct menu *)));
1506 QString listMode = configSettings->value("/listMode", "symbol").toString();
1507 if (listMode == "single")
1508 showSingleView();
1509 else if (listMode == "full")
1510 showFullView();
1511 else /*if (listMode == "split")*/
1512 showSplitView();
1514 // UI setup done, restore splitter positions
1515 QList<int> sizes = configSettings->readSizes("/split1", &ok);
1516 if (ok)
1517 split1->setSizes(sizes);
1519 sizes = configSettings->readSizes("/split2", &ok);
1520 if (ok)
1521 split2->setSizes(sizes);
1524 void ConfigMainWindow::loadConfig(void)
1526 QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
1527 if (s.isNull())
1528 return;
1529 if (conf_read(QFile::encodeName(s)))
1530 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1531 ConfigView::updateListAll();
1534 bool ConfigMainWindow::saveConfig(void)
1536 if (conf_write(NULL)) {
1537 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1538 return false;
1540 return true;
1543 void ConfigMainWindow::saveConfigAs(void)
1545 QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
1546 if (s.isNull())
1547 return;
1548 saveConfig();
1551 void ConfigMainWindow::searchConfig(void)
1553 if (!searchWindow)
1554 searchWindow = new ConfigSearchWindow(this, "search");
1555 searchWindow->show();
1558 void ConfigMainWindow::changeMenu(struct menu *menu)
1560 configList->setRootMenu(menu);
1561 if (configList->rootEntry->parent == &rootmenu)
1562 backAction->setEnabled(false);
1563 else
1564 backAction->setEnabled(true);
1567 void ConfigMainWindow::setMenuLink(struct menu *menu)
1569 struct menu *parent;
1570 ConfigList* list = NULL;
1571 ConfigItem* item;
1573 if (configList->menuSkip(menu))
1574 return;
1576 switch (configList->mode) {
1577 case singleMode:
1578 list = configList;
1579 parent = menu_get_parent_menu(menu);
1580 if (!parent)
1581 return;
1582 list->setRootMenu(parent);
1583 break;
1584 case symbolMode:
1585 if (menu->flags & MENU_ROOT) {
1586 configList->setRootMenu(menu);
1587 configList->clearSelection();
1588 list = menuList;
1589 } else {
1590 list = configList;
1591 parent = menu_get_parent_menu(menu->parent);
1592 if (!parent)
1593 return;
1594 item = menuList->findConfigItem(parent);
1595 if (item) {
1596 item->setSelected(true);
1597 menuList->scrollToItem(item);
1599 list->setRootMenu(parent);
1601 break;
1602 case fullMode:
1603 list = configList;
1604 break;
1605 default:
1606 break;
1609 if (list) {
1610 item = list->findConfigItem(menu);
1611 if (item) {
1612 item->setSelected(true);
1613 list->scrollToItem(item);
1614 list->setFocus();
1619 void ConfigMainWindow::listFocusChanged(void)
1621 if (menuList->mode == menuMode)
1622 configList->clearSelection();
1625 void ConfigMainWindow::goBack(void)
1627 ConfigItem* item, *oldSelection;
1629 configList->setParentMenu();
1630 if (configList->rootEntry == &rootmenu)
1631 backAction->setEnabled(false);
1633 if (menuList->selectedItems().count() == 0)
1634 return;
1636 item = (ConfigItem*)menuList->selectedItems().first();
1637 oldSelection = item;
1638 while (item) {
1639 if (item->menu == configList->rootEntry) {
1640 oldSelection->setSelected(false);
1641 item->setSelected(true);
1642 break;
1644 item = (ConfigItem*)item->parent();
1648 void ConfigMainWindow::showSingleView(void)
1650 singleViewAction->setEnabled(false);
1651 singleViewAction->setChecked(true);
1652 splitViewAction->setEnabled(true);
1653 splitViewAction->setChecked(false);
1654 fullViewAction->setEnabled(true);
1655 fullViewAction->setChecked(false);
1657 menuView->hide();
1658 menuList->setRootMenu(0);
1659 configList->mode = singleMode;
1660 if (configList->rootEntry == &rootmenu)
1661 configList->updateListAll();
1662 else
1663 configList->setRootMenu(&rootmenu);
1664 configList->setFocus();
1667 void ConfigMainWindow::showSplitView(void)
1669 singleViewAction->setEnabled(true);
1670 singleViewAction->setChecked(false);
1671 splitViewAction->setEnabled(false);
1672 splitViewAction->setChecked(true);
1673 fullViewAction->setEnabled(true);
1674 fullViewAction->setChecked(false);
1676 configList->mode = symbolMode;
1677 if (configList->rootEntry == &rootmenu)
1678 configList->updateListAll();
1679 else
1680 configList->setRootMenu(&rootmenu);
1681 configList->setAllOpen(true);
1682 configApp->processEvents();
1683 menuList->mode = menuMode;
1684 menuList->setRootMenu(&rootmenu);
1685 menuList->setAllOpen(true);
1686 menuView->show();
1687 menuList->setFocus();
1690 void ConfigMainWindow::showFullView(void)
1692 singleViewAction->setEnabled(true);
1693 singleViewAction->setChecked(false);
1694 splitViewAction->setEnabled(true);
1695 splitViewAction->setChecked(false);
1696 fullViewAction->setEnabled(false);
1697 fullViewAction->setChecked(true);
1699 menuView->hide();
1700 menuList->setRootMenu(0);
1701 configList->mode = fullMode;
1702 if (configList->rootEntry == &rootmenu)
1703 configList->updateListAll();
1704 else
1705 configList->setRootMenu(&rootmenu);
1706 configList->setFocus();
1710 * ask for saving configuration before quitting
1711 * TODO ask only when something changed
1713 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1715 if (!conf_get_changed()) {
1716 e->accept();
1717 return;
1719 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1720 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1721 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1722 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1723 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1724 switch (mb.exec()) {
1725 case QMessageBox::Yes:
1726 if (saveConfig())
1727 e->accept();
1728 else
1729 e->ignore();
1730 break;
1731 case QMessageBox::No:
1732 e->accept();
1733 break;
1734 case QMessageBox::Cancel:
1735 e->ignore();
1736 break;
1740 void ConfigMainWindow::showIntro(void)
1742 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
1743 "For each option, a blank box indicates the feature is disabled, a check\n"
1744 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1745 "as a module. Clicking on the box will cycle through the three states.\n\n"
1746 "If you do not see an option (e.g., a device driver) that you believe\n"
1747 "should be present, try turning on Show All Options under the Options menu.\n"
1748 "Although there is no cross reference yet to help you figure out what other\n"
1749 "options must be enabled to support the option you are interested in, you can\n"
1750 "still view the help of a grayed-out option.\n\n"
1751 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1752 "which you can then match by examining other options.\n\n");
1754 QMessageBox::information(this, "qconf", str);
1757 void ConfigMainWindow::showAbout(void)
1759 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
1760 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
1761 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1763 QMessageBox::information(this, "qconf", str);
1766 void ConfigMainWindow::saveSettings(void)
1768 configSettings->setValue("/window x", pos().x());
1769 configSettings->setValue("/window y", pos().y());
1770 configSettings->setValue("/window width", size().width());
1771 configSettings->setValue("/window height", size().height());
1773 QString entry;
1774 switch(configList->mode) {
1775 case singleMode :
1776 entry = "single";
1777 break;
1779 case symbolMode :
1780 entry = "split";
1781 break;
1783 case fullMode :
1784 entry = "full";
1785 break;
1787 default:
1788 break;
1790 configSettings->setValue("/listMode", entry);
1792 configSettings->writeSizes("/split1", split1->sizes());
1793 configSettings->writeSizes("/split2", split2->sizes());
1796 void ConfigMainWindow::conf_changed(void)
1798 if (saveAction)
1799 saveAction->setEnabled(conf_get_changed());
1802 void fixup_rootmenu(struct menu *menu)
1804 struct menu *child;
1805 static int menu_cnt = 0;
1807 menu->flags |= MENU_ROOT;
1808 for (child = menu->list; child; child = child->next) {
1809 if (child->prompt && child->prompt->type == P_MENU) {
1810 menu_cnt++;
1811 fixup_rootmenu(child);
1812 menu_cnt--;
1813 } else if (!menu_cnt)
1814 fixup_rootmenu(child);
1818 static const char *progname;
1820 static void usage(void)
1822 printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
1823 exit(0);
1826 int main(int ac, char** av)
1828 ConfigMainWindow* v;
1829 const char *name;
1831 bindtextdomain(PACKAGE, LOCALEDIR);
1832 textdomain(PACKAGE);
1834 progname = av[0];
1835 configApp = new QApplication(ac, av);
1836 if (ac > 1 && av[1][0] == '-') {
1837 switch (av[1][1]) {
1838 case 's':
1839 conf_set_message_callback(NULL);
1840 break;
1841 case 'h':
1842 case '?':
1843 usage();
1845 name = av[2];
1846 } else
1847 name = av[1];
1848 if (!name)
1849 usage();
1851 conf_parse(name);
1852 fixup_rootmenu(&rootmenu);
1853 conf_read(NULL);
1854 //zconfdump(stdout);
1856 configSettings = new ConfigSettings();
1857 configSettings->beginGroup("/kconfig/qconf");
1858 v = new ConfigMainWindow();
1860 //zconfdump(stdout);
1861 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1862 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1863 v->show();
1864 configApp->exec();
1866 configSettings->endGroup();
1867 delete configSettings;
1869 return 0;