2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
8 #if QT_VERSION < 0x040000
9 #include <qmainwindow.h>
11 #include <qvaluelist.h>
12 #include <qtextbrowser.h>
15 #include <qfiledialog.h>
16 #include <qdragobject.h>
17 #include <qpopupmenu.h>
19 #include <q3mainwindow.h>
21 #include <q3valuelist.h>
22 #include <q3textbrowser.h>
25 #include <q3filedialog.h>
26 #include <q3dragobject.h>
27 #include <q3popupmenu.h>
30 #include <qapplication.h>
31 #include <qdesktopwidget.h>
34 #include <qsplitter.h>
35 #include <qlineedit.h>
37 #include <qpushbutton.h>
39 #include <qmessagebox.h>
49 #define WANTS_xpm_symbol_yes
50 #define WANTS_xpm_symbol_mod
51 #define WANTS_xpm_symbol_no
52 #define WANTS_xpm_choice_yes
53 #define WANTS_xpm_choice_no
54 #define WANTS_xpm_menu
55 #define WANTS_xpm_menu_inv
56 #define WANTS_xpm_menuback
57 #define WANTS_xpm_void
58 #define WANTS_xpm_back
59 #define WANTS_xpm_load
60 #define WANTS_xpm_save
61 #define WANTS_xpm_single_view
62 #define WANTS_xpm_split_view
63 #define WANTS_xpm_tree_view
71 static QApplication *configApp;
72 static ConfigSettings *configSettings;
74 Q3Action *ConfigMainWindow::saveAction;
76 static inline QString qgettext(const char* str)
78 return QString::fromLocal8Bit(gettext(str));
81 static inline QString qgettext(const QString& str)
83 return QString::fromLocal8Bit(gettext(str.latin1()));
87 * Reads a list of integer values from the application settings.
89 Q3ValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
91 Q3ValueList<int> result;
92 QStringList entryList = readListEntry(key, ok);
93 QStringList::Iterator it;
95 for (it = entryList.begin(); it != entryList.end(); ++it)
96 result.push_back((*it).toInt());
102 * Writes a list of integer values to the application settings.
104 bool ConfigSettings::writeSizes(const QString& key, const Q3ValueList<int>& value)
106 QStringList stringList;
107 Q3ValueList<int>::ConstIterator it;
109 for (it = value.begin(); it != value.end(); ++it)
110 stringList.push_back(QString::number(*it));
111 return writeEntry(key, stringList);
117 * TODO check the value
119 void ConfigItem::okRename(int col)
121 Parent::okRename(col);
122 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
123 listView()->updateList(this);
127 * update the displayed of a menu entry
129 void ConfigItem::updateMenu(void)
133 struct property *prop;
140 setPixmap(promptColIdx, list->menuBackPix);
147 prompt = _(menu_get_prompt(menu));
149 if (prop) switch (prop->type) {
151 if (list->mode == singleMode || list->mode == symbolMode) {
152 /* a menuconfig entry is displayed differently
153 * depending whether it's at the view root or a child.
155 if (sym && list->rootEntry == menu)
157 setPixmap(promptColIdx, list->menuPix);
161 setPixmap(promptColIdx, 0);
165 setPixmap(promptColIdx, 0);
173 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
175 type = sym_get_type(sym);
181 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
182 setPixmap(promptColIdx, 0);
183 setText(noColIdx, QString::null);
184 setText(modColIdx, QString::null);
185 setText(yesColIdx, QString::null);
188 expr = sym_get_tristate_value(sym);
191 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
192 setPixmap(promptColIdx, list->choiceYesPix);
194 setPixmap(promptColIdx, list->symbolYesPix);
195 setText(yesColIdx, "Y");
199 setPixmap(promptColIdx, list->symbolModPix);
200 setText(modColIdx, "M");
204 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
205 setPixmap(promptColIdx, list->choiceNoPix);
207 setPixmap(promptColIdx, list->symbolNoPix);
208 setText(noColIdx, "N");
213 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
215 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
217 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
219 setText(dataColIdx, QChar(ch));
226 data = sym_get_string_value(sym);
228 int i = list->mapIdx(dataColIdx);
230 setRenameEnabled(i, TRUE);
231 setText(dataColIdx, data);
232 if (type == S_STRING)
233 prompt = QString("%1: %2").arg(prompt).arg(data);
235 prompt = QString("(%2) %1").arg(prompt).arg(data);
238 if (!sym_has_value(sym) && visible)
239 prompt += _(" (NEW)");
241 setText(promptColIdx, prompt);
244 void ConfigItem::testUpdateMenu(bool v)
252 sym_calc_value(menu->sym);
253 if (menu->flags & MENU_CHANGED) {
254 /* the menu entry changed, so update all list items */
255 menu->flags &= ~MENU_CHANGED;
256 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
258 } else if (listView()->updateAll)
262 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
264 ConfigList* list = listView();
267 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
268 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
270 Parent::paintCell(p, cg, column, width, align);
272 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
276 * construct a menu entry
278 void ConfigItem::init(void)
281 ConfigList* list = listView();
282 nextItem = (ConfigItem*)menu->data;
285 if (list->mode != fullMode)
287 sym_calc_value(menu->sym);
293 * destruct a menu entry
295 ConfigItem::~ConfigItem(void)
298 ConfigItem** ip = (ConfigItem**)&menu->data;
299 for (; *ip; ip = &(*ip)->nextItem) {
308 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
311 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
314 void ConfigLineEdit::show(ConfigItem* i)
317 if (sym_get_string_value(item->menu->sym))
318 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
320 setText(QString::null);
325 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
332 sym_set_string_value(item->menu->sym, text().latin1());
333 parent()->updateList(item);
336 Parent::keyPressEvent(e);
340 parent()->list->setFocus();
344 ConfigList::ConfigList(ConfigView* p, const char *name)
347 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
348 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
349 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
350 showName(false), showRange(false), showData(false), optMode(normalOpt),
351 rootEntry(0), headerPopup(0)
356 setRootIsDecorated(TRUE);
357 disabledColorGroup = palette().active();
358 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
359 inactivedColorGroup = palette().active();
360 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
362 connect(this, SIGNAL(selectionChanged(void)),
363 SLOT(updateSelection(void)));
366 configSettings->beginGroup(name);
367 showName = configSettings->readBoolEntry("/showName", false);
368 showRange = configSettings->readBoolEntry("/showRange", false);
369 showData = configSettings->readBoolEntry("/showData", false);
370 optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
371 configSettings->endGroup();
372 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
375 for (i = 0; i < colNr; i++)
376 colMap[i] = colRevMap[i] = -1;
377 addColumn(promptColIdx, _("Option"));
382 bool ConfigList::menuSkip(struct menu *menu)
384 if (optMode == normalOpt && menu_is_visible(menu))
386 if (optMode == promptOpt && menu_has_prompt(menu))
388 if (optMode == allOpt)
393 void ConfigList::reinit(void)
395 removeColumn(dataColIdx);
396 removeColumn(yesColIdx);
397 removeColumn(modColIdx);
398 removeColumn(noColIdx);
399 removeColumn(nameColIdx);
402 addColumn(nameColIdx, _("Name"));
404 addColumn(noColIdx, "N");
405 addColumn(modColIdx, "M");
406 addColumn(yesColIdx, "Y");
409 addColumn(dataColIdx, _("Value"));
414 void ConfigList::saveSettings(void)
417 configSettings->beginGroup(name());
418 configSettings->writeEntry("/showName", showName);
419 configSettings->writeEntry("/showRange", showRange);
420 configSettings->writeEntry("/showData", showData);
421 configSettings->writeEntry("/optionMode", (int)optMode);
422 configSettings->endGroup();
426 ConfigItem* ConfigList::findConfigItem(struct menu *menu)
428 ConfigItem* item = (ConfigItem*)menu->data;
430 for (; item; item = item->nextItem) {
431 if (this == item->listView())
438 void ConfigList::updateSelection(void)
443 ConfigItem* item = (ConfigItem*)selectedItem();
448 emit menuChanged(menu);
451 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
452 if (mode == menuMode && type == P_MENU)
453 emit menuSelected(menu);
456 void ConfigList::updateList(ConfigItem* item)
458 ConfigItem* last = 0;
461 if (mode != listMode)
463 Q3ListViewItemIterator it(this);
466 for (; it.current(); ++it) {
467 item = (ConfigItem*)it.current();
470 item->testUpdateMenu(menu_is_visible(item->menu));
475 if (rootEntry != &rootmenu && (mode == singleMode ||
476 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
479 item = new ConfigItem(this, 0, true);
482 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
483 rootEntry->sym && rootEntry->prompt) {
484 item = last ? last->nextSibling() : firstChild();
486 item = new ConfigItem(this, last, rootEntry, true);
488 item->testUpdateMenu(true);
490 updateMenuList(item, rootEntry);
495 updateMenuList(this, rootEntry);
499 void ConfigList::setValue(ConfigItem* item, tristate val)
505 sym = item->menu ? item->menu->sym : 0;
509 type = sym_get_type(sym);
513 oldval = sym_get_tristate_value(sym);
515 if (!sym_set_tristate_value(sym, val))
517 if (oldval == no && item->menu->list)
519 parent()->updateList(item);
524 void ConfigList::changeValue(ConfigItem* item)
528 int type, oldexpr, newexpr;
535 if (item->menu->list)
536 item->setOpen(!item->isOpen());
540 type = sym_get_type(sym);
544 oldexpr = sym_get_tristate_value(sym);
545 newexpr = sym_toggle_tristate_value(sym);
546 if (item->menu->list) {
547 if (oldexpr == newexpr)
548 item->setOpen(!item->isOpen());
549 else if (oldexpr == no)
552 if (oldexpr != newexpr)
553 parent()->updateList(item);
558 if (colMap[dataColIdx] >= 0)
559 item->startRename(colMap[dataColIdx]);
561 parent()->lineEdit->show(item);
566 void ConfigList::setRootMenu(struct menu *menu)
570 if (rootEntry == menu)
572 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
575 updateMenuList(this, 0);
578 setSelected(currentItem(), hasFocus());
579 ensureItemVisible(currentItem());
582 void ConfigList::setParentMenu(void)
585 struct menu *oldroot;
588 if (rootEntry == &rootmenu)
590 setRootMenu(menu_get_parent_menu(rootEntry->parent));
592 Q3ListViewItemIterator it(this);
593 for (; (item = (ConfigItem*)it.current()); it++) {
594 if (item->menu == oldroot) {
595 setCurrentItem(item);
596 ensureItemVisible(item);
603 * update all the children of a menu entry
604 * removes/adds the entries from the parent widget as necessary
606 * parent: either the menu list widget or a menu entry widget
607 * menu: entry to be updated
610 void ConfigList::updateMenuList(P* parent, struct menu* menu)
619 while ((item = parent->firstChild()))
624 last = parent->firstChild();
625 if (last && !last->goParent)
627 for (child = menu->list; child; child = child->next) {
628 item = last ? last->nextSibling() : parent->firstChild();
629 type = child->prompt ? child->prompt->type : P_UNKNOWN;
633 if (!(child->flags & MENU_ROOT))
637 if (child->flags & MENU_ROOT)
644 visible = menu_is_visible(child);
645 if (!menuSkip(child)) {
646 if (!child->sym && !child->list && !child->prompt)
648 if (!item || item->menu != child)
649 item = new ConfigItem(parent, last, child, visible);
651 item->testUpdateMenu(visible);
653 if (mode == fullMode || mode == menuMode || type != P_MENU)
654 updateMenuList(item, child);
656 updateMenuList(item, 0);
661 if (item && item->menu == child) {
662 last = parent->firstChild();
665 else while (last->nextSibling() != item)
666 last = last->nextSibling();
672 void ConfigList::keyPressEvent(QKeyEvent* ev)
674 Q3ListViewItem* i = currentItem();
679 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
680 emit parentSelected();
686 Parent::keyPressEvent(ev);
689 item = (ConfigItem*)i;
694 if (item->goParent) {
695 emit parentSelected();
701 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
702 if (type == P_MENU && rootEntry != menu &&
703 mode != fullMode && mode != menuMode) {
704 emit menuSelected(menu);
720 Parent::keyPressEvent(ev);
726 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
728 //QPoint p(contentsToViewport(e->pos()));
729 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
730 Parent::contentsMousePressEvent(e);
733 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
735 QPoint p(contentsToViewport(e->pos()));
736 ConfigItem* item = (ConfigItem*)itemAt(p);
738 enum prop_type ptype;
746 x = header()->offset() + p.x();
747 idx = colRevMap[header()->sectionAt(x)];
750 pm = item->pixmap(promptColIdx);
752 int off = header()->sectionPos(0) + itemMargin() +
753 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
754 if (x >= off && x < off + pm->width()) {
755 if (item->goParent) {
756 emit parentSelected();
760 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
761 if (ptype == P_MENU && rootEntry != menu &&
762 mode != fullMode && mode != menuMode)
763 emit menuSelected(menu);
784 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
785 Parent::contentsMouseReleaseEvent(e);
788 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
790 //QPoint p(contentsToViewport(e->pos()));
791 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
792 Parent::contentsMouseMoveEvent(e);
795 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
797 QPoint p(contentsToViewport(e->pos()));
798 ConfigItem* item = (ConfigItem*)itemAt(p);
800 enum prop_type ptype;
804 if (item->goParent) {
805 emit parentSelected();
811 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
812 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
813 emit menuSelected(menu);
818 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
819 Parent::contentsMouseDoubleClickEvent(e);
822 void ConfigList::focusInEvent(QFocusEvent *e)
824 struct menu *menu = NULL;
826 Parent::focusInEvent(e);
828 ConfigItem* item = (ConfigItem *)currentItem();
830 setSelected(item, TRUE);
836 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
838 if (e->y() <= header()->geometry().bottom()) {
842 headerPopup = new Q3PopupMenu(this);
843 action = new Q3Action(NULL, _("Show Name"), 0, this);
844 action->setToggleAction(TRUE);
845 connect(action, SIGNAL(toggled(bool)),
846 parent(), SLOT(setShowName(bool)));
847 connect(parent(), SIGNAL(showNameChanged(bool)),
848 action, SLOT(setOn(bool)));
849 action->setOn(showName);
850 action->addTo(headerPopup);
851 action = new Q3Action(NULL, _("Show Range"), 0, this);
852 action->setToggleAction(TRUE);
853 connect(action, SIGNAL(toggled(bool)),
854 parent(), SLOT(setShowRange(bool)));
855 connect(parent(), SIGNAL(showRangeChanged(bool)),
856 action, SLOT(setOn(bool)));
857 action->setOn(showRange);
858 action->addTo(headerPopup);
859 action = new Q3Action(NULL, _("Show Data"), 0, this);
860 action->setToggleAction(TRUE);
861 connect(action, SIGNAL(toggled(bool)),
862 parent(), SLOT(setShowData(bool)));
863 connect(parent(), SIGNAL(showDataChanged(bool)),
864 action, SLOT(setOn(bool)));
865 action->setOn(showData);
866 action->addTo(headerPopup);
868 headerPopup->exec(e->globalPos());
874 ConfigView*ConfigView::viewList;
875 QAction *ConfigView::showNormalAction;
876 QAction *ConfigView::showAllAction;
877 QAction *ConfigView::showPromptAction;
879 ConfigView::ConfigView(QWidget* parent, const char *name)
880 : Parent(parent, name)
882 list = new ConfigList(this, name);
883 lineEdit = new ConfigLineEdit(this);
886 this->nextView = viewList;
890 ConfigView::~ConfigView(void)
894 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
902 void ConfigView::setOptionMode(QAction *act)
904 if (act == showNormalAction)
905 list->optMode = normalOpt;
906 else if (act == showAllAction)
907 list->optMode = allOpt;
909 list->optMode = promptOpt;
911 list->updateListAll();
914 void ConfigView::setShowName(bool b)
916 if (list->showName != b) {
919 emit showNameChanged(b);
923 void ConfigView::setShowRange(bool b)
925 if (list->showRange != b) {
928 emit showRangeChanged(b);
932 void ConfigView::setShowData(bool b)
934 if (list->showData != b) {
937 emit showDataChanged(b);
941 void ConfigList::setAllOpen(bool open)
943 Q3ListViewItemIterator it(this);
945 for (; it.current(); it++)
946 it.current()->setOpen(open);
949 void ConfigView::updateList(ConfigItem* item)
953 for (v = viewList; v; v = v->nextView)
954 v->list->updateList(item);
957 void ConfigView::updateListAll(void)
961 for (v = viewList; v; v = v->nextView)
962 v->list->updateListAll();
965 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
966 : Parent(parent, name), sym(0), _menu(0)
969 configSettings->beginGroup(name);
970 _showDebug = configSettings->readBoolEntry("/showDebug", false);
971 configSettings->endGroup();
972 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
976 void ConfigInfoView::saveSettings(void)
979 configSettings->beginGroup(name());
980 configSettings->writeEntry("/showDebug", showDebug());
981 configSettings->endGroup();
985 void ConfigInfoView::setShowDebug(bool b)
987 if (_showDebug != b) {
993 emit showDebugChanged(b);
997 void ConfigInfoView::setInfo(struct menu *m)
1009 void ConfigInfoView::symbolInfo(void)
1013 str += "<big>Symbol: <b>";
1014 str += print_filter(sym->name);
1015 str += "</b></big><br><br>value: ";
1016 str += print_filter(sym_get_string_value(sym));
1017 str += "<br>visibility: ";
1018 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
1020 str += debug_info(sym);
1025 void ConfigInfoView::menuInfo(void)
1028 QString head, debug, help;
1032 if (_menu->prompt) {
1034 head += print_filter(_(_menu->prompt->text));
1035 head += "</b></big>";
1039 head += QString().sprintf("<a href=\"s%p\">", sym);
1040 head += print_filter(sym->name);
1045 } else if (sym->name) {
1048 head += QString().sprintf("<a href=\"s%p\">", sym);
1049 head += print_filter(sym->name);
1052 head += "</b></big>";
1057 debug = debug_info(sym);
1059 struct gstr help_gstr = str_new();
1060 menu_get_ext_help(_menu, &help_gstr);
1061 help = print_filter(str_get(&help_gstr));
1062 str_free(&help_gstr);
1063 } else if (_menu->prompt) {
1065 head += print_filter(_(_menu->prompt->text));
1066 head += "</b></big><br><br>";
1068 if (_menu->prompt->visible.expr) {
1069 debug += " dep: ";
1070 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1071 debug += "<br><br>";
1076 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
1078 setText(head + debug + help);
1081 QString ConfigInfoView::debug_info(struct symbol *sym)
1086 debug += print_filter(sym_type_name(sym->type));
1087 if (sym_is_choice(sym))
1088 debug += " (choice)";
1090 if (sym->rev_dep.expr) {
1091 debug += "reverse dep: ";
1092 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1095 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1096 switch (prop->type) {
1099 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
1100 debug += print_filter(_(prop->text));
1101 debug += "</a><br>";
1107 debug += prop_get_type_name(prop->type);
1109 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1113 if (sym_is_choice(sym)) {
1114 debug += "choice: ";
1115 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1120 debug += "unknown property: ";
1121 debug += prop_get_type_name(prop->type);
1124 if (prop->visible.expr) {
1125 debug += " dep: ";
1126 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1135 QString ConfigInfoView::print_filter(const QString &str)
1137 QRegExp re("[<>&\"\\n]");
1139 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1140 switch (res[i].latin1()) {
1142 res.replace(i, 1, "<");
1146 res.replace(i, 1, ">");
1150 res.replace(i, 1, "&");
1154 res.replace(i, 1, """);
1158 res.replace(i, 1, "<br>");
1166 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
1168 QString* text = reinterpret_cast<QString*>(data);
1169 QString str2 = print_filter(str);
1171 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1172 *text += QString().sprintf("<a href=\"s%p\">", sym);
1179 Q3PopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
1181 Q3PopupMenu* popup = Parent::createPopupMenu(pos);
1182 Q3Action* action = new Q3Action(NULL, _("Show Debug Info"), 0, popup);
1183 action->setToggleAction(TRUE);
1184 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1185 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1186 action->setOn(showDebug());
1187 popup->insertSeparator();
1188 action->addTo(popup);
1192 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
1194 Parent::contentsContextMenuEvent(e);
1197 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
1198 : Parent(parent, name), result(NULL)
1200 setCaption("Search Config");
1202 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1203 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
1204 layout2->addWidget(new QLabel(_("Find:"), this));
1205 editField = new QLineEdit(this);
1206 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1207 layout2->addWidget(editField);
1208 searchButton = new QPushButton(_("Search"), this);
1209 searchButton->setAutoDefault(FALSE);
1210 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1211 layout2->addWidget(searchButton);
1212 layout1->addLayout(layout2);
1214 split = new QSplitter(this);
1215 split->setOrientation(Qt::Vertical);
1216 list = new ConfigView(split, name);
1217 list->list->mode = listMode;
1218 info = new ConfigInfoView(split, name);
1219 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1220 info, SLOT(setInfo(struct menu *)));
1221 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1222 parent, SLOT(setMenuLink(struct menu *)));
1224 layout1->addWidget(split);
1227 int x, y, width, height;
1230 configSettings->beginGroup(name);
1231 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1232 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1233 resize(width, height);
1234 x = configSettings->readNumEntry("/window x", 0, &ok);
1236 y = configSettings->readNumEntry("/window y", 0, &ok);
1239 Q3ValueList<int> sizes = configSettings->readSizes("/split", &ok);
1241 split->setSizes(sizes);
1242 configSettings->endGroup();
1243 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1247 void ConfigSearchWindow::saveSettings(void)
1250 configSettings->beginGroup(name());
1251 configSettings->writeEntry("/window x", pos().x());
1252 configSettings->writeEntry("/window y", pos().y());
1253 configSettings->writeEntry("/window width", size().width());
1254 configSettings->writeEntry("/window height", size().height());
1255 configSettings->writeSizes("/split", split->sizes());
1256 configSettings->endGroup();
1260 void ConfigSearchWindow::search(void)
1263 struct property *prop;
1264 ConfigItem *lastItem = NULL;
1267 list->list->clear();
1270 result = sym_re_search(editField->text().latin1());
1273 for (p = result; *p; p++) {
1274 for_all_prompts((*p), prop)
1275 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1276 menu_is_visible(prop->menu));
1281 * Construct the complete config widget
1283 ConfigMainWindow::ConfigMainWindow(void)
1288 int x, y, width, height;
1291 QDesktopWidget *d = configApp->desktop();
1292 snprintf(title, sizeof(title), "%s%s",
1293 rootmenu.prompt->text,
1294 #if QT_VERSION < 0x040000
1302 width = configSettings->readNumEntry("/window width", d->width() - 64);
1303 height = configSettings->readNumEntry("/window height", d->height() - 64);
1304 resize(width, height);
1305 x = configSettings->readNumEntry("/window x", 0, &ok);
1307 y = configSettings->readNumEntry("/window y", 0, &ok);
1311 split1 = new QSplitter(this);
1312 split1->setOrientation(Qt::Horizontal);
1313 setCentralWidget(split1);
1315 menuView = new ConfigView(split1, "menu");
1316 menuList = menuView->list;
1318 split2 = new QSplitter(split1);
1319 split2->setOrientation(Qt::Vertical);
1321 // create config tree
1322 configView = new ConfigView(split2, "config");
1323 configList = configView->list;
1325 helpText = new ConfigInfoView(split2, "help");
1326 helpText->setTextFormat(Qt::RichText);
1328 setTabOrder(configList, helpText);
1329 configList->setFocus();
1332 toolBar = new Q3ToolBar("Tools", this);
1334 backAction = new Q3Action("Back", QPixmap(xpm_back), _("Back"), 0, this);
1335 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1336 backAction->setEnabled(FALSE);
1337 Q3Action *quitAction = new Q3Action("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this);
1338 connect(quitAction, SIGNAL(activated()), SLOT(close()));
1339 Q3Action *loadAction = new Q3Action("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this);
1340 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
1341 saveAction = new Q3Action("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this);
1342 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
1343 conf_set_changed_callback(conf_changed);
1344 // Set saveAction's initial state
1346 Q3Action *saveAsAction = new Q3Action("Save As...", _("Save &As..."), 0, this);
1347 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
1348 Q3Action *searchAction = new Q3Action("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this);
1349 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
1350 Q3Action *singleViewAction = new Q3Action("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
1351 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
1352 Q3Action *splitViewAction = new Q3Action("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
1353 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
1354 Q3Action *fullViewAction = new Q3Action("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
1355 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1357 Q3Action *showNameAction = new Q3Action(NULL, _("Show Name"), 0, this);
1358 showNameAction->setToggleAction(TRUE);
1359 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1360 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1361 showNameAction->setOn(configView->showName());
1362 Q3Action *showRangeAction = new Q3Action(NULL, _("Show Range"), 0, this);
1363 showRangeAction->setToggleAction(TRUE);
1364 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1365 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1366 showRangeAction->setOn(configList->showRange);
1367 Q3Action *showDataAction = new Q3Action(NULL, _("Show Data"), 0, this);
1368 showDataAction->setToggleAction(TRUE);
1369 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1370 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1371 showDataAction->setOn(configList->showData);
1373 QActionGroup *optGroup = new QActionGroup(this);
1374 optGroup->setExclusive(TRUE);
1375 connect(optGroup, SIGNAL(selected(QAction *)), configView,
1376 SLOT(setOptionMode(QAction *)));
1377 connect(optGroup, SIGNAL(selected(QAction *)), menuView,
1378 SLOT(setOptionMode(QAction *)));
1380 #if QT_VERSION >= 0x040000
1381 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1382 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1383 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
1385 configView->showNormalAction = new QAction(_("Show Normal Options"), 0, optGroup);
1386 configView->showAllAction = new QAction(_("Show All Options"), 0, optGroup);
1387 configView->showPromptAction = new QAction(_("Show Prompt Options"), 0, optGroup);
1389 configView->showNormalAction->setToggleAction(TRUE);
1390 configView->showNormalAction->setOn(configList->optMode == normalOpt);
1391 configView->showAllAction->setToggleAction(TRUE);
1392 configView->showAllAction->setOn(configList->optMode == allOpt);
1393 configView->showPromptAction->setToggleAction(TRUE);
1394 configView->showPromptAction->setOn(configList->optMode == promptOpt);
1396 Q3Action *showDebugAction = new Q3Action(NULL, _("Show Debug Info"), 0, this);
1397 showDebugAction->setToggleAction(TRUE);
1398 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1399 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
1400 showDebugAction->setOn(helpText->showDebug());
1402 Q3Action *showIntroAction = new Q3Action(NULL, _("Introduction"), 0, this);
1403 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
1404 Q3Action *showAboutAction = new Q3Action(NULL, _("About"), 0, this);
1405 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1408 backAction->addTo(toolBar);
1409 toolBar->addSeparator();
1410 loadAction->addTo(toolBar);
1411 saveAction->addTo(toolBar);
1412 toolBar->addSeparator();
1413 singleViewAction->addTo(toolBar);
1414 splitViewAction->addTo(toolBar);
1415 fullViewAction->addTo(toolBar);
1417 // create config menu
1418 Q3PopupMenu* config = new Q3PopupMenu(this);
1419 menu->insertItem(_("&File"), config);
1420 loadAction->addTo(config);
1421 saveAction->addTo(config);
1422 saveAsAction->addTo(config);
1423 config->insertSeparator();
1424 quitAction->addTo(config);
1427 Q3PopupMenu* editMenu = new Q3PopupMenu(this);
1428 menu->insertItem(_("&Edit"), editMenu);
1429 searchAction->addTo(editMenu);
1431 // create options menu
1432 Q3PopupMenu* optionMenu = new Q3PopupMenu(this);
1433 menu->insertItem(_("&Option"), optionMenu);
1434 showNameAction->addTo(optionMenu);
1435 showRangeAction->addTo(optionMenu);
1436 showDataAction->addTo(optionMenu);
1437 optionMenu->insertSeparator();
1438 optGroup->addTo(optionMenu);
1439 optionMenu->insertSeparator();
1442 Q3PopupMenu* helpMenu = new Q3PopupMenu(this);
1443 menu->insertSeparator();
1444 menu->insertItem(_("&Help"), helpMenu);
1445 showIntroAction->addTo(helpMenu);
1446 showAboutAction->addTo(helpMenu);
1448 connect(configList, SIGNAL(menuChanged(struct menu *)),
1449 helpText, SLOT(setInfo(struct menu *)));
1450 connect(configList, SIGNAL(menuSelected(struct menu *)),
1451 SLOT(changeMenu(struct menu *)));
1452 connect(configList, SIGNAL(parentSelected()),
1454 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1455 helpText, SLOT(setInfo(struct menu *)));
1456 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1457 SLOT(changeMenu(struct menu *)));
1459 connect(configList, SIGNAL(gotFocus(struct menu *)),
1460 helpText, SLOT(setInfo(struct menu *)));
1461 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1462 helpText, SLOT(setInfo(struct menu *)));
1463 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1464 SLOT(listFocusChanged(void)));
1465 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1466 SLOT(setMenuLink(struct menu *)));
1468 QString listMode = configSettings->readEntry("/listMode", "symbol");
1469 if (listMode == "single")
1471 else if (listMode == "full")
1473 else /*if (listMode == "split")*/
1476 // UI setup done, restore splitter positions
1477 Q3ValueList<int> sizes = configSettings->readSizes("/split1", &ok);
1479 split1->setSizes(sizes);
1481 sizes = configSettings->readSizes("/split2", &ok);
1483 split2->setSizes(sizes);
1486 void ConfigMainWindow::loadConfig(void)
1488 QString s = Q3FileDialog::getOpenFileName(conf_get_configname(), NULL, this);
1491 if (conf_read(QFile::encodeName(s)))
1492 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1493 ConfigView::updateListAll();
1496 bool ConfigMainWindow::saveConfig(void)
1498 if (conf_write(NULL)) {
1499 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1505 void ConfigMainWindow::saveConfigAs(void)
1507 QString s = Q3FileDialog::getSaveFileName(conf_get_configname(), NULL, this);
1513 void ConfigMainWindow::searchConfig(void)
1516 searchWindow = new ConfigSearchWindow(this, "search");
1517 searchWindow->show();
1520 void ConfigMainWindow::changeMenu(struct menu *menu)
1522 configList->setRootMenu(menu);
1523 if (configList->rootEntry->parent == &rootmenu)
1524 backAction->setEnabled(FALSE);
1526 backAction->setEnabled(TRUE);
1529 void ConfigMainWindow::setMenuLink(struct menu *menu)
1531 struct menu *parent;
1532 ConfigList* list = NULL;
1535 if (configList->menuSkip(menu))
1538 switch (configList->mode) {
1541 parent = menu_get_parent_menu(menu);
1544 list->setRootMenu(parent);
1547 if (menu->flags & MENU_ROOT) {
1548 configList->setRootMenu(menu);
1549 configList->clearSelection();
1553 parent = menu_get_parent_menu(menu->parent);
1556 item = menuList->findConfigItem(parent);
1558 menuList->setSelected(item, TRUE);
1559 menuList->ensureItemVisible(item);
1561 list->setRootMenu(parent);
1572 item = list->findConfigItem(menu);
1574 list->setSelected(item, TRUE);
1575 list->ensureItemVisible(item);
1581 void ConfigMainWindow::listFocusChanged(void)
1583 if (menuList->mode == menuMode)
1584 configList->clearSelection();
1587 void ConfigMainWindow::goBack(void)
1591 configList->setParentMenu();
1592 if (configList->rootEntry == &rootmenu)
1593 backAction->setEnabled(FALSE);
1594 item = (ConfigItem*)menuList->selectedItem();
1596 if (item->menu == configList->rootEntry) {
1597 menuList->setSelected(item, TRUE);
1600 item = (ConfigItem*)item->parent();
1604 void ConfigMainWindow::showSingleView(void)
1607 menuList->setRootMenu(0);
1608 configList->mode = singleMode;
1609 if (configList->rootEntry == &rootmenu)
1610 configList->updateListAll();
1612 configList->setRootMenu(&rootmenu);
1613 configList->setAllOpen(TRUE);
1614 configList->setFocus();
1617 void ConfigMainWindow::showSplitView(void)
1619 configList->mode = symbolMode;
1620 if (configList->rootEntry == &rootmenu)
1621 configList->updateListAll();
1623 configList->setRootMenu(&rootmenu);
1624 configList->setAllOpen(TRUE);
1625 configApp->processEvents();
1626 menuList->mode = menuMode;
1627 menuList->setRootMenu(&rootmenu);
1628 menuList->setAllOpen(TRUE);
1630 menuList->setFocus();
1633 void ConfigMainWindow::showFullView(void)
1636 menuList->setRootMenu(0);
1637 configList->mode = fullMode;
1638 if (configList->rootEntry == &rootmenu)
1639 configList->updateListAll();
1641 configList->setRootMenu(&rootmenu);
1642 configList->setAllOpen(FALSE);
1643 configList->setFocus();
1647 * ask for saving configuration before quitting
1648 * TODO ask only when something changed
1650 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1652 if (!conf_get_changed()) {
1656 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1657 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1658 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1659 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1660 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1661 switch (mb.exec()) {
1662 case QMessageBox::Yes:
1668 case QMessageBox::No:
1671 case QMessageBox::Cancel:
1677 void ConfigMainWindow::showIntro(void)
1679 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
1680 "For each option, a blank box indicates the feature is disabled, a check\n"
1681 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1682 "as a module. Clicking on the box will cycle through the three states.\n\n"
1683 "If you do not see an option (e.g., a device driver) that you believe\n"
1684 "should be present, try turning on Show All Options under the Options menu.\n"
1685 "Although there is no cross reference yet to help you figure out what other\n"
1686 "options must be enabled to support the option you are interested in, you can\n"
1687 "still view the help of a grayed-out option.\n\n"
1688 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1689 "which you can then match by examining other options.\n\n");
1691 QMessageBox::information(this, "qconf", str);
1694 void ConfigMainWindow::showAbout(void)
1696 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1697 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1699 QMessageBox::information(this, "qconf", str);
1702 void ConfigMainWindow::saveSettings(void)
1704 configSettings->writeEntry("/window x", pos().x());
1705 configSettings->writeEntry("/window y", pos().y());
1706 configSettings->writeEntry("/window width", size().width());
1707 configSettings->writeEntry("/window height", size().height());
1710 switch(configList->mode) {
1726 configSettings->writeEntry("/listMode", entry);
1728 configSettings->writeSizes("/split1", split1->sizes());
1729 configSettings->writeSizes("/split2", split2->sizes());
1732 void ConfigMainWindow::conf_changed(void)
1735 saveAction->setEnabled(conf_get_changed());
1738 void fixup_rootmenu(struct menu *menu)
1741 static int menu_cnt = 0;
1743 menu->flags |= MENU_ROOT;
1744 for (child = menu->list; child; child = child->next) {
1745 if (child->prompt && child->prompt->type == P_MENU) {
1747 fixup_rootmenu(child);
1749 } else if (!menu_cnt)
1750 fixup_rootmenu(child);
1754 static const char *progname;
1756 static void usage(void)
1758 printf(_("%s <config>\n"), progname);
1762 int main(int ac, char** av)
1764 ConfigMainWindow* v;
1767 bindtextdomain(PACKAGE, LOCALEDIR);
1768 textdomain(PACKAGE);
1771 configApp = new QApplication(ac, av);
1772 if (ac > 1 && av[1][0] == '-') {
1785 fixup_rootmenu(&rootmenu);
1787 //zconfdump(stdout);
1789 configSettings = new ConfigSettings();
1790 configSettings->beginGroup("/kconfig/qconf");
1791 v = new ConfigMainWindow();
1793 //zconfdump(stdout);
1794 configApp->setMainWidget(v);
1795 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1796 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1800 configSettings->endGroup();
1801 delete configSettings;