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
10 #include <qmainwindow.h>
12 #include <qvaluelist.h>
13 #include <qtextbrowser.h>
16 #include <qfiledialog.h>
17 #include <qdragobject.h>
18 #include <qpopupmenu.h>
20 #include <q3mainwindow.h>
22 #include <q3valuelist.h>
23 #include <q3textbrowser.h>
26 #include <q3filedialog.h>
27 #include <q3dragobject.h>
28 #include <q3popupmenu.h>
31 #include <qapplication.h>
32 #include <qdesktopwidget.h>
35 #include <qsplitter.h>
36 #include <qlineedit.h>
38 #include <qpushbutton.h>
40 #include <qmessagebox.h>
57 static QApplication
*configApp
;
58 static ConfigSettings
*configSettings
;
60 Q3Action
*ConfigMainWindow::saveAction
;
62 static inline QString
qgettext(const char* str
)
64 return QString::fromLocal8Bit(gettext(str
));
67 static inline QString
qgettext(const QString
& str
)
69 return QString::fromLocal8Bit(gettext(str
.latin1()));
72 ConfigSettings::ConfigSettings()
73 : QSettings("kernel.org", "qconf")
78 * Reads a list of integer values from the application settings.
80 Q3ValueList
<int> ConfigSettings::readSizes(const QString
& key
, bool *ok
)
82 Q3ValueList
<int> result
;
83 QStringList entryList
= readListEntry(key
, ok
);
84 QStringList::Iterator it
;
86 for (it
= entryList
.begin(); it
!= entryList
.end(); ++it
)
87 result
.push_back((*it
).toInt());
93 * Writes a list of integer values to the application settings.
95 bool ConfigSettings::writeSizes(const QString
& key
, const Q3ValueList
<int>& value
)
97 QStringList stringList
;
98 Q3ValueList
<int>::ConstIterator it
;
100 for (it
= value
.begin(); it
!= value
.end(); ++it
)
101 stringList
.push_back(QString::number(*it
));
102 return writeEntry(key
, stringList
);
108 * TODO check the value
110 void ConfigItem::okRename(int col
)
112 Parent::okRename(col
);
113 sym_set_string_value(menu
->sym
, text(dataColIdx
).latin1());
114 listView()->updateList(this);
118 * update the displayed of a menu entry
120 void ConfigItem::updateMenu(void)
124 struct property
*prop
;
131 setPixmap(promptColIdx
, list
->menuBackPix
);
138 prompt
= _(menu_get_prompt(menu
));
140 if (prop
) switch (prop
->type
) {
142 if (list
->mode
== singleMode
|| list
->mode
== symbolMode
) {
143 /* a menuconfig entry is displayed differently
144 * depending whether it's at the view root or a child.
146 if (sym
&& list
->rootEntry
== menu
)
148 setPixmap(promptColIdx
, list
->menuPix
);
152 setPixmap(promptColIdx
, 0);
156 setPixmap(promptColIdx
, 0);
164 setText(nameColIdx
, QString::fromLocal8Bit(sym
->name
));
166 type
= sym_get_type(sym
);
172 if (!sym_is_changable(sym
) && list
->optMode
== normalOpt
) {
173 setPixmap(promptColIdx
, 0);
174 setText(noColIdx
, QString::null
);
175 setText(modColIdx
, QString::null
);
176 setText(yesColIdx
, QString::null
);
179 expr
= sym_get_tristate_value(sym
);
182 if (sym_is_choice_value(sym
) && type
== S_BOOLEAN
)
183 setPixmap(promptColIdx
, list
->choiceYesPix
);
185 setPixmap(promptColIdx
, list
->symbolYesPix
);
186 setText(yesColIdx
, "Y");
190 setPixmap(promptColIdx
, list
->symbolModPix
);
191 setText(modColIdx
, "M");
195 if (sym_is_choice_value(sym
) && type
== S_BOOLEAN
)
196 setPixmap(promptColIdx
, list
->choiceNoPix
);
198 setPixmap(promptColIdx
, list
->symbolNoPix
);
199 setText(noColIdx
, "N");
204 setText(noColIdx
, sym_tristate_within_range(sym
, no
) ? "_" : 0);
206 setText(modColIdx
, sym_tristate_within_range(sym
, mod
) ? "_" : 0);
208 setText(yesColIdx
, sym_tristate_within_range(sym
, yes
) ? "_" : 0);
210 setText(dataColIdx
, QChar(ch
));
217 data
= sym_get_string_value(sym
);
219 int i
= list
->mapIdx(dataColIdx
);
221 setRenameEnabled(i
, TRUE
);
222 setText(dataColIdx
, data
);
223 if (type
== S_STRING
)
224 prompt
= QString("%1: %2").arg(prompt
).arg(data
);
226 prompt
= QString("(%2) %1").arg(prompt
).arg(data
);
229 if (!sym_has_value(sym
) && visible
)
230 prompt
+= _(" (NEW)");
232 setText(promptColIdx
, prompt
);
235 void ConfigItem::testUpdateMenu(bool v
)
243 sym_calc_value(menu
->sym
);
244 if (menu
->flags
& MENU_CHANGED
) {
245 /* the menu entry changed, so update all list items */
246 menu
->flags
&= ~MENU_CHANGED
;
247 for (i
= (ConfigItem
*)menu
->data
; i
; i
= i
->nextItem
)
249 } else if (listView()->updateAll
)
253 void ConfigItem::paintCell(QPainter
* p
, const QColorGroup
& cg
, int column
, int width
, int align
)
255 ConfigList
* list
= listView();
258 if (isSelected() && !list
->hasFocus() && list
->mode
== menuMode
)
259 Parent::paintCell(p
, list
->inactivedColorGroup
, column
, width
, align
);
261 Parent::paintCell(p
, cg
, column
, width
, align
);
263 Parent::paintCell(p
, list
->disabledColorGroup
, column
, width
, align
);
267 * construct a menu entry
269 void ConfigItem::init(void)
272 ConfigList
* list
= listView();
273 nextItem
= (ConfigItem
*)menu
->data
;
276 if (list
->mode
!= fullMode
)
278 sym_calc_value(menu
->sym
);
284 * destruct a menu entry
286 ConfigItem::~ConfigItem(void)
289 ConfigItem
** ip
= (ConfigItem
**)&menu
->data
;
290 for (; *ip
; ip
= &(*ip
)->nextItem
) {
299 ConfigLineEdit::ConfigLineEdit(ConfigView
* parent
)
302 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
305 void ConfigLineEdit::show(ConfigItem
* i
)
308 if (sym_get_string_value(item
->menu
->sym
))
309 setText(QString::fromLocal8Bit(sym_get_string_value(item
->menu
->sym
)));
311 setText(QString::null
);
316 void ConfigLineEdit::keyPressEvent(QKeyEvent
* e
)
323 sym_set_string_value(item
->menu
->sym
, text().latin1());
324 parent()->updateList(item
);
327 Parent::keyPressEvent(e
);
331 parent()->list
->setFocus();
335 ConfigList::ConfigList(ConfigView
* p
, const char *name
)
338 symbolYesPix(xpm_symbol_yes
), symbolModPix(xpm_symbol_mod
), symbolNoPix(xpm_symbol_no
),
339 choiceYesPix(xpm_choice_yes
), choiceNoPix(xpm_choice_no
),
340 menuPix(xpm_menu
), menuInvPix(xpm_menu_inv
), menuBackPix(xpm_menuback
), voidPix(xpm_void
),
341 showName(false), showRange(false), showData(false), optMode(normalOpt
),
342 rootEntry(0), headerPopup(0)
347 setRootIsDecorated(TRUE
);
348 disabledColorGroup
= palette().active();
349 disabledColorGroup
.setColor(QColorGroup::Text
, palette().disabled().text());
350 inactivedColorGroup
= palette().active();
351 inactivedColorGroup
.setColor(QColorGroup::Highlight
, palette().disabled().highlight());
353 connect(this, SIGNAL(selectionChanged(void)),
354 SLOT(updateSelection(void)));
357 configSettings
->beginGroup(name
);
358 showName
= configSettings
->readBoolEntry("/showName", false);
359 showRange
= configSettings
->readBoolEntry("/showRange", false);
360 showData
= configSettings
->readBoolEntry("/showData", false);
361 optMode
= (enum optionMode
)configSettings
->readNumEntry("/optionMode", false);
362 configSettings
->endGroup();
363 connect(configApp
, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
366 for (i
= 0; i
< colNr
; i
++)
367 colMap
[i
] = colRevMap
[i
] = -1;
368 addColumn(promptColIdx
, _("Option"));
373 bool ConfigList::menuSkip(struct menu
*menu
)
375 if (optMode
== normalOpt
&& menu_is_visible(menu
))
377 if (optMode
== promptOpt
&& menu_has_prompt(menu
))
379 if (optMode
== allOpt
)
384 void ConfigList::reinit(void)
386 removeColumn(dataColIdx
);
387 removeColumn(yesColIdx
);
388 removeColumn(modColIdx
);
389 removeColumn(noColIdx
);
390 removeColumn(nameColIdx
);
393 addColumn(nameColIdx
, _("Name"));
395 addColumn(noColIdx
, "N");
396 addColumn(modColIdx
, "M");
397 addColumn(yesColIdx
, "Y");
400 addColumn(dataColIdx
, _("Value"));
405 void ConfigList::saveSettings(void)
408 configSettings
->beginGroup(name());
409 configSettings
->writeEntry("/showName", showName
);
410 configSettings
->writeEntry("/showRange", showRange
);
411 configSettings
->writeEntry("/showData", showData
);
412 configSettings
->writeEntry("/optionMode", (int)optMode
);
413 configSettings
->endGroup();
417 ConfigItem
* ConfigList::findConfigItem(struct menu
*menu
)
419 ConfigItem
* item
= (ConfigItem
*)menu
->data
;
421 for (; item
; item
= item
->nextItem
) {
422 if (this == item
->listView())
429 void ConfigList::updateSelection(void)
434 ConfigItem
* item
= (ConfigItem
*)selectedItem();
439 emit
menuChanged(menu
);
442 type
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
443 if (mode
== menuMode
&& type
== P_MENU
)
444 emit
menuSelected(menu
);
447 void ConfigList::updateList(ConfigItem
* item
)
449 ConfigItem
* last
= 0;
452 if (mode
!= listMode
)
454 Q3ListViewItemIterator
it(this);
457 for (; it
.current(); ++it
) {
458 item
= (ConfigItem
*)it
.current();
461 item
->testUpdateMenu(menu_is_visible(item
->menu
));
466 if (rootEntry
!= &rootmenu
&& (mode
== singleMode
||
467 (mode
== symbolMode
&& rootEntry
->parent
!= &rootmenu
))) {
470 item
= new ConfigItem(this, 0, true);
473 if ((mode
== singleMode
|| (mode
== symbolMode
&& !(rootEntry
->flags
& MENU_ROOT
))) &&
474 rootEntry
->sym
&& rootEntry
->prompt
) {
475 item
= last
? last
->nextSibling() : firstChild();
477 item
= new ConfigItem(this, last
, rootEntry
, true);
479 item
->testUpdateMenu(true);
481 updateMenuList(item
, rootEntry
);
486 updateMenuList(this, rootEntry
);
490 void ConfigList::setValue(ConfigItem
* item
, tristate val
)
496 sym
= item
->menu
? item
->menu
->sym
: 0;
500 type
= sym_get_type(sym
);
504 oldval
= sym_get_tristate_value(sym
);
506 if (!sym_set_tristate_value(sym
, val
))
508 if (oldval
== no
&& item
->menu
->list
)
510 parent()->updateList(item
);
515 void ConfigList::changeValue(ConfigItem
* item
)
519 int type
, oldexpr
, newexpr
;
526 if (item
->menu
->list
)
527 item
->setOpen(!item
->isOpen());
531 type
= sym_get_type(sym
);
535 oldexpr
= sym_get_tristate_value(sym
);
536 newexpr
= sym_toggle_tristate_value(sym
);
537 if (item
->menu
->list
) {
538 if (oldexpr
== newexpr
)
539 item
->setOpen(!item
->isOpen());
540 else if (oldexpr
== no
)
543 if (oldexpr
!= newexpr
)
544 parent()->updateList(item
);
549 if (colMap
[dataColIdx
] >= 0)
550 item
->startRename(colMap
[dataColIdx
]);
552 parent()->lineEdit
->show(item
);
557 void ConfigList::setRootMenu(struct menu
*menu
)
561 if (rootEntry
== menu
)
563 type
= menu
&& menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
566 updateMenuList(this, 0);
569 setSelected(currentItem(), hasFocus());
570 ensureItemVisible(currentItem());
573 void ConfigList::setParentMenu(void)
576 struct menu
*oldroot
;
579 if (rootEntry
== &rootmenu
)
581 setRootMenu(menu_get_parent_menu(rootEntry
->parent
));
583 Q3ListViewItemIterator
it(this);
584 for (; (item
= (ConfigItem
*)it
.current()); it
++) {
585 if (item
->menu
== oldroot
) {
586 setCurrentItem(item
);
587 ensureItemVisible(item
);
594 * update all the children of a menu entry
595 * removes/adds the entries from the parent widget as necessary
597 * parent: either the menu list widget or a menu entry widget
598 * menu: entry to be updated
601 void ConfigList::updateMenuList(P
* parent
, struct menu
* menu
)
610 while ((item
= parent
->firstChild()))
615 last
= parent
->firstChild();
616 if (last
&& !last
->goParent
)
618 for (child
= menu
->list
; child
; child
= child
->next
) {
619 item
= last
? last
->nextSibling() : parent
->firstChild();
620 type
= child
->prompt
? child
->prompt
->type
: P_UNKNOWN
;
624 if (!(child
->flags
& MENU_ROOT
))
628 if (child
->flags
& MENU_ROOT
)
635 visible
= menu_is_visible(child
);
636 if (!menuSkip(child
)) {
637 if (!child
->sym
&& !child
->list
&& !child
->prompt
)
639 if (!item
|| item
->menu
!= child
)
640 item
= new ConfigItem(parent
, last
, child
, visible
);
642 item
->testUpdateMenu(visible
);
644 if (mode
== fullMode
|| mode
== menuMode
|| type
!= P_MENU
)
645 updateMenuList(item
, child
);
647 updateMenuList(item
, 0);
652 if (item
&& item
->menu
== child
) {
653 last
= parent
->firstChild();
656 else while (last
->nextSibling() != item
)
657 last
= last
->nextSibling();
663 void ConfigList::keyPressEvent(QKeyEvent
* ev
)
665 Q3ListViewItem
* i
= currentItem();
670 if (ev
->key() == Qt::Key_Escape
&& mode
!= fullMode
&& mode
!= listMode
) {
671 emit
parentSelected();
677 Parent::keyPressEvent(ev
);
680 item
= (ConfigItem
*)i
;
685 if (item
->goParent
) {
686 emit
parentSelected();
692 type
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
693 if (type
== P_MENU
&& rootEntry
!= menu
&&
694 mode
!= fullMode
&& mode
!= menuMode
) {
695 emit
menuSelected(menu
);
711 Parent::keyPressEvent(ev
);
717 void ConfigList::contentsMousePressEvent(QMouseEvent
* e
)
719 //QPoint p(contentsToViewport(e->pos()));
720 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
721 Parent::contentsMousePressEvent(e
);
724 void ConfigList::contentsMouseReleaseEvent(QMouseEvent
* e
)
726 QPoint
p(contentsToViewport(e
->pos()));
727 ConfigItem
* item
= (ConfigItem
*)itemAt(p
);
729 enum prop_type ptype
;
737 x
= header()->offset() + p
.x();
738 idx
= colRevMap
[header()->sectionAt(x
)];
741 pm
= item
->pixmap(promptColIdx
);
743 int off
= header()->sectionPos(0) + itemMargin() +
744 treeStepSize() * (item
->depth() + (rootIsDecorated() ? 1 : 0));
745 if (x
>= off
&& x
< off
+ pm
->width()) {
746 if (item
->goParent
) {
747 emit
parentSelected();
751 ptype
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
752 if (ptype
== P_MENU
&& rootEntry
!= menu
&&
753 mode
!= fullMode
&& mode
!= menuMode
)
754 emit
menuSelected(menu
);
775 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
776 Parent::contentsMouseReleaseEvent(e
);
779 void ConfigList::contentsMouseMoveEvent(QMouseEvent
* e
)
781 //QPoint p(contentsToViewport(e->pos()));
782 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
783 Parent::contentsMouseMoveEvent(e
);
786 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent
* e
)
788 QPoint
p(contentsToViewport(e
->pos()));
789 ConfigItem
* item
= (ConfigItem
*)itemAt(p
);
791 enum prop_type ptype
;
795 if (item
->goParent
) {
796 emit
parentSelected();
802 ptype
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
803 if (ptype
== P_MENU
&& (mode
== singleMode
|| mode
== symbolMode
))
804 emit
menuSelected(menu
);
809 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
810 Parent::contentsMouseDoubleClickEvent(e
);
813 void ConfigList::focusInEvent(QFocusEvent
*e
)
815 struct menu
*menu
= NULL
;
817 Parent::focusInEvent(e
);
819 ConfigItem
* item
= (ConfigItem
*)currentItem();
821 setSelected(item
, TRUE
);
827 void ConfigList::contextMenuEvent(QContextMenuEvent
*e
)
829 if (e
->y() <= header()->geometry().bottom()) {
833 headerPopup
= new Q3PopupMenu(this);
834 action
= new Q3Action(NULL
, _("Show Name"), 0, this);
835 action
->setToggleAction(TRUE
);
836 connect(action
, SIGNAL(toggled(bool)),
837 parent(), SLOT(setShowName(bool)));
838 connect(parent(), SIGNAL(showNameChanged(bool)),
839 action
, SLOT(setOn(bool)));
840 action
->setOn(showName
);
841 action
->addTo(headerPopup
);
842 action
= new Q3Action(NULL
, _("Show Range"), 0, this);
843 action
->setToggleAction(TRUE
);
844 connect(action
, SIGNAL(toggled(bool)),
845 parent(), SLOT(setShowRange(bool)));
846 connect(parent(), SIGNAL(showRangeChanged(bool)),
847 action
, SLOT(setOn(bool)));
848 action
->setOn(showRange
);
849 action
->addTo(headerPopup
);
850 action
= new Q3Action(NULL
, _("Show Data"), 0, this);
851 action
->setToggleAction(TRUE
);
852 connect(action
, SIGNAL(toggled(bool)),
853 parent(), SLOT(setShowData(bool)));
854 connect(parent(), SIGNAL(showDataChanged(bool)),
855 action
, SLOT(setOn(bool)));
856 action
->setOn(showData
);
857 action
->addTo(headerPopup
);
859 headerPopup
->exec(e
->globalPos());
865 ConfigView
*ConfigView::viewList
;
866 QAction
*ConfigView::showNormalAction
;
867 QAction
*ConfigView::showAllAction
;
868 QAction
*ConfigView::showPromptAction
;
870 ConfigView::ConfigView(QWidget
* parent
, const char *name
)
871 : Parent(parent
, name
)
873 list
= new ConfigList(this, name
);
874 lineEdit
= new ConfigLineEdit(this);
877 this->nextView
= viewList
;
881 ConfigView::~ConfigView(void)
885 for (vp
= &viewList
; *vp
; vp
= &(*vp
)->nextView
) {
893 void ConfigView::setOptionMode(QAction
*act
)
895 if (act
== showNormalAction
)
896 list
->optMode
= normalOpt
;
897 else if (act
== showAllAction
)
898 list
->optMode
= allOpt
;
900 list
->optMode
= promptOpt
;
902 list
->updateListAll();
905 void ConfigView::setShowName(bool b
)
907 if (list
->showName
!= b
) {
910 emit
showNameChanged(b
);
914 void ConfigView::setShowRange(bool b
)
916 if (list
->showRange
!= b
) {
919 emit
showRangeChanged(b
);
923 void ConfigView::setShowData(bool b
)
925 if (list
->showData
!= b
) {
928 emit
showDataChanged(b
);
932 void ConfigList::setAllOpen(bool open
)
934 Q3ListViewItemIterator
it(this);
936 for (; it
.current(); it
++)
937 it
.current()->setOpen(open
);
940 void ConfigView::updateList(ConfigItem
* item
)
944 for (v
= viewList
; v
; v
= v
->nextView
)
945 v
->list
->updateList(item
);
948 void ConfigView::updateListAll(void)
952 for (v
= viewList
; v
; v
= v
->nextView
)
953 v
->list
->updateListAll();
956 ConfigInfoView::ConfigInfoView(QWidget
* parent
, const char *name
)
957 : Parent(parent
, name
), sym(0), _menu(0)
960 configSettings
->beginGroup(name
);
961 _showDebug
= configSettings
->readBoolEntry("/showDebug", false);
962 configSettings
->endGroup();
963 connect(configApp
, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
967 void ConfigInfoView::saveSettings(void)
970 configSettings
->beginGroup(name());
971 configSettings
->writeEntry("/showDebug", showDebug());
972 configSettings
->endGroup();
976 void ConfigInfoView::setShowDebug(bool b
)
978 if (_showDebug
!= b
) {
984 emit
showDebugChanged(b
);
988 void ConfigInfoView::setInfo(struct menu
*m
)
1000 void ConfigInfoView::symbolInfo(void)
1004 str
+= "<big>Symbol: <b>";
1005 str
+= print_filter(sym
->name
);
1006 str
+= "</b></big><br><br>value: ";
1007 str
+= print_filter(sym_get_string_value(sym
));
1008 str
+= "<br>visibility: ";
1009 str
+= sym
->visible
== yes
? "y" : sym
->visible
== mod
? "m" : "n";
1011 str
+= debug_info(sym
);
1016 void ConfigInfoView::menuInfo(void)
1019 QString head
, debug
, help
;
1023 if (_menu
->prompt
) {
1025 head
+= print_filter(_(_menu
->prompt
->text
));
1026 head
+= "</b></big>";
1030 head
+= QString().sprintf("<a href=\"s%p\">", sym
);
1031 head
+= print_filter(sym
->name
);
1036 } else if (sym
->name
) {
1039 head
+= QString().sprintf("<a href=\"s%p\">", sym
);
1040 head
+= print_filter(sym
->name
);
1043 head
+= "</b></big>";
1048 debug
= debug_info(sym
);
1050 struct gstr help_gstr
= str_new();
1051 menu_get_ext_help(_menu
, &help_gstr
);
1052 help
= print_filter(str_get(&help_gstr
));
1053 str_free(&help_gstr
);
1054 } else if (_menu
->prompt
) {
1056 head
+= print_filter(_(_menu
->prompt
->text
));
1057 head
+= "</b></big><br><br>";
1059 if (_menu
->prompt
->visible
.expr
) {
1060 debug
+= " dep: ";
1061 expr_print(_menu
->prompt
->visible
.expr
, expr_print_help
, &debug
, E_NONE
);
1062 debug
+= "<br><br>";
1067 debug
+= QString().sprintf("defined at %s:%d<br><br>", _menu
->file
->name
, _menu
->lineno
);
1069 setText(head
+ debug
+ help
);
1072 QString
ConfigInfoView::debug_info(struct symbol
*sym
)
1077 debug
+= print_filter(sym_type_name(sym
->type
));
1078 if (sym_is_choice(sym
))
1079 debug
+= " (choice)";
1081 if (sym
->rev_dep
.expr
) {
1082 debug
+= "reverse dep: ";
1083 expr_print(sym
->rev_dep
.expr
, expr_print_help
, &debug
, E_NONE
);
1086 for (struct property
*prop
= sym
->prop
; prop
; prop
= prop
->next
) {
1087 switch (prop
->type
) {
1090 debug
+= QString().sprintf("prompt: <a href=\"m%p\">", prop
->menu
);
1091 debug
+= print_filter(_(prop
->text
));
1092 debug
+= "</a><br>";
1098 debug
+= prop_get_type_name(prop
->type
);
1100 expr_print(prop
->expr
, expr_print_help
, &debug
, E_NONE
);
1104 if (sym_is_choice(sym
)) {
1105 debug
+= "choice: ";
1106 expr_print(prop
->expr
, expr_print_help
, &debug
, E_NONE
);
1111 debug
+= "unknown property: ";
1112 debug
+= prop_get_type_name(prop
->type
);
1115 if (prop
->visible
.expr
) {
1116 debug
+= " dep: ";
1117 expr_print(prop
->visible
.expr
, expr_print_help
, &debug
, E_NONE
);
1126 QString
ConfigInfoView::print_filter(const QString
&str
)
1128 QRegExp
re("[<>&\"\\n]");
1130 for (int i
= 0; (i
= res
.find(re
, i
)) >= 0;) {
1131 switch (res
[i
].latin1()) {
1133 res
.replace(i
, 1, "<");
1137 res
.replace(i
, 1, ">");
1141 res
.replace(i
, 1, "&");
1145 res
.replace(i
, 1, """);
1149 res
.replace(i
, 1, "<br>");
1157 void ConfigInfoView::expr_print_help(void *data
, struct symbol
*sym
, const char *str
)
1159 QString
* text
= reinterpret_cast<QString
*>(data
);
1160 QString str2
= print_filter(str
);
1162 if (sym
&& sym
->name
&& !(sym
->flags
& SYMBOL_CONST
)) {
1163 *text
+= QString().sprintf("<a href=\"s%p\">", sym
);
1170 Q3PopupMenu
* ConfigInfoView::createPopupMenu(const QPoint
& pos
)
1172 Q3PopupMenu
* popup
= Parent::createPopupMenu(pos
);
1173 Q3Action
* action
= new Q3Action(NULL
, _("Show Debug Info"), 0, popup
);
1174 action
->setToggleAction(TRUE
);
1175 connect(action
, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1176 connect(this, SIGNAL(showDebugChanged(bool)), action
, SLOT(setOn(bool)));
1177 action
->setOn(showDebug());
1178 popup
->insertSeparator();
1179 action
->addTo(popup
);
1183 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent
*e
)
1185 Parent::contentsContextMenuEvent(e
);
1188 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow
* parent
, const char *name
)
1189 : Parent(parent
, name
), result(NULL
)
1191 setCaption("Search Config");
1193 QVBoxLayout
* layout1
= new QVBoxLayout(this, 11, 6);
1194 QHBoxLayout
* layout2
= new QHBoxLayout(0, 0, 6);
1195 layout2
->addWidget(new QLabel(_("Find:"), this));
1196 editField
= new QLineEdit(this);
1197 connect(editField
, SIGNAL(returnPressed()), SLOT(search()));
1198 layout2
->addWidget(editField
);
1199 searchButton
= new QPushButton(_("Search"), this);
1200 searchButton
->setAutoDefault(FALSE
);
1201 connect(searchButton
, SIGNAL(clicked()), SLOT(search()));
1202 layout2
->addWidget(searchButton
);
1203 layout1
->addLayout(layout2
);
1205 split
= new QSplitter(this);
1206 split
->setOrientation(Qt::Vertical
);
1207 list
= new ConfigView(split
, name
);
1208 list
->list
->mode
= listMode
;
1209 info
= new ConfigInfoView(split
, name
);
1210 connect(list
->list
, SIGNAL(menuChanged(struct menu
*)),
1211 info
, SLOT(setInfo(struct menu
*)));
1212 connect(list
->list
, SIGNAL(menuChanged(struct menu
*)),
1213 parent
, SLOT(setMenuLink(struct menu
*)));
1215 layout1
->addWidget(split
);
1218 int x
, y
, width
, height
;
1221 configSettings
->beginGroup(name
);
1222 width
= configSettings
->readNumEntry("/window width", parent
->width() / 2);
1223 height
= configSettings
->readNumEntry("/window height", parent
->height() / 2);
1224 resize(width
, height
);
1225 x
= configSettings
->readNumEntry("/window x", 0, &ok
);
1227 y
= configSettings
->readNumEntry("/window y", 0, &ok
);
1230 Q3ValueList
<int> sizes
= configSettings
->readSizes("/split", &ok
);
1232 split
->setSizes(sizes
);
1233 configSettings
->endGroup();
1234 connect(configApp
, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1238 void ConfigSearchWindow::saveSettings(void)
1241 configSettings
->beginGroup(name());
1242 configSettings
->writeEntry("/window x", pos().x());
1243 configSettings
->writeEntry("/window y", pos().y());
1244 configSettings
->writeEntry("/window width", size().width());
1245 configSettings
->writeEntry("/window height", size().height());
1246 configSettings
->writeSizes("/split", split
->sizes());
1247 configSettings
->endGroup();
1251 void ConfigSearchWindow::search(void)
1254 struct property
*prop
;
1255 ConfigItem
*lastItem
= NULL
;
1258 list
->list
->clear();
1261 result
= sym_re_search(editField
->text().latin1());
1264 for (p
= result
; *p
; p
++) {
1265 for_all_prompts((*p
), prop
)
1266 lastItem
= new ConfigItem(list
->list
, lastItem
, prop
->menu
,
1267 menu_is_visible(prop
->menu
));
1272 * Construct the complete config widget
1274 ConfigMainWindow::ConfigMainWindow(void)
1279 int x
, y
, width
, height
;
1282 QDesktopWidget
*d
= configApp
->desktop();
1283 snprintf(title
, sizeof(title
), "%s%s",
1284 rootmenu
.prompt
->text
,
1285 #if QT_VERSION < 0x040000
1293 width
= configSettings
->readNumEntry("/window width", d
->width() - 64);
1294 height
= configSettings
->readNumEntry("/window height", d
->height() - 64);
1295 resize(width
, height
);
1296 x
= configSettings
->readNumEntry("/window x", 0, &ok
);
1298 y
= configSettings
->readNumEntry("/window y", 0, &ok
);
1302 split1
= new QSplitter(this);
1303 split1
->setOrientation(Qt::Horizontal
);
1304 setCentralWidget(split1
);
1306 menuView
= new ConfigView(split1
, "menu");
1307 menuList
= menuView
->list
;
1309 split2
= new QSplitter(split1
);
1310 split2
->setOrientation(Qt::Vertical
);
1312 // create config tree
1313 configView
= new ConfigView(split2
, "config");
1314 configList
= configView
->list
;
1316 helpText
= new ConfigInfoView(split2
, "help");
1317 helpText
->setTextFormat(Qt::RichText
);
1319 setTabOrder(configList
, helpText
);
1320 configList
->setFocus();
1323 toolBar
= new Q3ToolBar("Tools", this);
1325 backAction
= new Q3Action("Back", QPixmap(xpm_back
), _("Back"), 0, this);
1326 connect(backAction
, SIGNAL(activated()), SLOT(goBack()));
1327 backAction
->setEnabled(FALSE
);
1328 Q3Action
*quitAction
= new Q3Action("Quit", _("&Quit"), Qt::CTRL
+ Qt::Key_Q
, this);
1329 connect(quitAction
, SIGNAL(activated()), SLOT(close()));
1330 Q3Action
*loadAction
= new Q3Action("Load", QPixmap(xpm_load
), _("&Load"), Qt::CTRL
+ Qt::Key_L
, this);
1331 connect(loadAction
, SIGNAL(activated()), SLOT(loadConfig()));
1332 saveAction
= new Q3Action("Save", QPixmap(xpm_save
), _("&Save"), Qt::CTRL
+ Qt::Key_S
, this);
1333 connect(saveAction
, SIGNAL(activated()), SLOT(saveConfig()));
1334 conf_set_changed_callback(conf_changed
);
1335 // Set saveAction's initial state
1337 Q3Action
*saveAsAction
= new Q3Action("Save As...", _("Save &As..."), 0, this);
1338 connect(saveAsAction
, SIGNAL(activated()), SLOT(saveConfigAs()));
1339 Q3Action
*searchAction
= new Q3Action("Find", _("&Find"), Qt::CTRL
+ Qt::Key_F
, this);
1340 connect(searchAction
, SIGNAL(activated()), SLOT(searchConfig()));
1341 Q3Action
*singleViewAction
= new Q3Action("Single View", QPixmap(xpm_single_view
), _("Single View"), 0, this);
1342 connect(singleViewAction
, SIGNAL(activated()), SLOT(showSingleView()));
1343 Q3Action
*splitViewAction
= new Q3Action("Split View", QPixmap(xpm_split_view
), _("Split View"), 0, this);
1344 connect(splitViewAction
, SIGNAL(activated()), SLOT(showSplitView()));
1345 Q3Action
*fullViewAction
= new Q3Action("Full View", QPixmap(xpm_tree_view
), _("Full View"), 0, this);
1346 connect(fullViewAction
, SIGNAL(activated()), SLOT(showFullView()));
1348 Q3Action
*showNameAction
= new Q3Action(NULL
, _("Show Name"), 0, this);
1349 showNameAction
->setToggleAction(TRUE
);
1350 connect(showNameAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowName(bool)));
1351 connect(configView
, SIGNAL(showNameChanged(bool)), showNameAction
, SLOT(setOn(bool)));
1352 showNameAction
->setOn(configView
->showName());
1353 Q3Action
*showRangeAction
= new Q3Action(NULL
, _("Show Range"), 0, this);
1354 showRangeAction
->setToggleAction(TRUE
);
1355 connect(showRangeAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowRange(bool)));
1356 connect(configView
, SIGNAL(showRangeChanged(bool)), showRangeAction
, SLOT(setOn(bool)));
1357 showRangeAction
->setOn(configList
->showRange
);
1358 Q3Action
*showDataAction
= new Q3Action(NULL
, _("Show Data"), 0, this);
1359 showDataAction
->setToggleAction(TRUE
);
1360 connect(showDataAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowData(bool)));
1361 connect(configView
, SIGNAL(showDataChanged(bool)), showDataAction
, SLOT(setOn(bool)));
1362 showDataAction
->setOn(configList
->showData
);
1364 QActionGroup
*optGroup
= new QActionGroup(this);
1365 optGroup
->setExclusive(TRUE
);
1366 connect(optGroup
, SIGNAL(selected(QAction
*)), configView
,
1367 SLOT(setOptionMode(QAction
*)));
1368 connect(optGroup
, SIGNAL(selected(QAction
*)), menuView
,
1369 SLOT(setOptionMode(QAction
*)));
1371 #if QT_VERSION >= 0x040000
1372 configView
->showNormalAction
= new QAction(_("Show Normal Options"), optGroup
);
1373 configView
->showAllAction
= new QAction(_("Show All Options"), optGroup
);
1374 configView
->showPromptAction
= new QAction(_("Show Prompt Options"), optGroup
);
1376 configView
->showNormalAction
= new QAction(_("Show Normal Options"), 0, optGroup
);
1377 configView
->showAllAction
= new QAction(_("Show All Options"), 0, optGroup
);
1378 configView
->showPromptAction
= new QAction(_("Show Prompt Options"), 0, optGroup
);
1380 configView
->showNormalAction
->setToggleAction(TRUE
);
1381 configView
->showNormalAction
->setOn(configList
->optMode
== normalOpt
);
1382 configView
->showAllAction
->setToggleAction(TRUE
);
1383 configView
->showAllAction
->setOn(configList
->optMode
== allOpt
);
1384 configView
->showPromptAction
->setToggleAction(TRUE
);
1385 configView
->showPromptAction
->setOn(configList
->optMode
== promptOpt
);
1387 Q3Action
*showDebugAction
= new Q3Action(NULL
, _("Show Debug Info"), 0, this);
1388 showDebugAction
->setToggleAction(TRUE
);
1389 connect(showDebugAction
, SIGNAL(toggled(bool)), helpText
, SLOT(setShowDebug(bool)));
1390 connect(helpText
, SIGNAL(showDebugChanged(bool)), showDebugAction
, SLOT(setOn(bool)));
1391 showDebugAction
->setOn(helpText
->showDebug());
1393 Q3Action
*showIntroAction
= new Q3Action(NULL
, _("Introduction"), 0, this);
1394 connect(showIntroAction
, SIGNAL(activated()), SLOT(showIntro()));
1395 Q3Action
*showAboutAction
= new Q3Action(NULL
, _("About"), 0, this);
1396 connect(showAboutAction
, SIGNAL(activated()), SLOT(showAbout()));
1399 backAction
->addTo(toolBar
);
1400 toolBar
->addSeparator();
1401 loadAction
->addTo(toolBar
);
1402 saveAction
->addTo(toolBar
);
1403 toolBar
->addSeparator();
1404 singleViewAction
->addTo(toolBar
);
1405 splitViewAction
->addTo(toolBar
);
1406 fullViewAction
->addTo(toolBar
);
1408 // create config menu
1409 Q3PopupMenu
* config
= new Q3PopupMenu(this);
1410 menu
->insertItem(_("&File"), config
);
1411 loadAction
->addTo(config
);
1412 saveAction
->addTo(config
);
1413 saveAsAction
->addTo(config
);
1414 config
->insertSeparator();
1415 quitAction
->addTo(config
);
1418 Q3PopupMenu
* editMenu
= new Q3PopupMenu(this);
1419 menu
->insertItem(_("&Edit"), editMenu
);
1420 searchAction
->addTo(editMenu
);
1422 // create options menu
1423 Q3PopupMenu
* optionMenu
= new Q3PopupMenu(this);
1424 menu
->insertItem(_("&Option"), optionMenu
);
1425 showNameAction
->addTo(optionMenu
);
1426 showRangeAction
->addTo(optionMenu
);
1427 showDataAction
->addTo(optionMenu
);
1428 optionMenu
->insertSeparator();
1429 optGroup
->addTo(optionMenu
);
1430 optionMenu
->insertSeparator();
1433 Q3PopupMenu
* helpMenu
= new Q3PopupMenu(this);
1434 menu
->insertSeparator();
1435 menu
->insertItem(_("&Help"), helpMenu
);
1436 showIntroAction
->addTo(helpMenu
);
1437 showAboutAction
->addTo(helpMenu
);
1439 connect(configList
, SIGNAL(menuChanged(struct menu
*)),
1440 helpText
, SLOT(setInfo(struct menu
*)));
1441 connect(configList
, SIGNAL(menuSelected(struct menu
*)),
1442 SLOT(changeMenu(struct menu
*)));
1443 connect(configList
, SIGNAL(parentSelected()),
1445 connect(menuList
, SIGNAL(menuChanged(struct menu
*)),
1446 helpText
, SLOT(setInfo(struct menu
*)));
1447 connect(menuList
, SIGNAL(menuSelected(struct menu
*)),
1448 SLOT(changeMenu(struct menu
*)));
1450 connect(configList
, SIGNAL(gotFocus(struct menu
*)),
1451 helpText
, SLOT(setInfo(struct menu
*)));
1452 connect(menuList
, SIGNAL(gotFocus(struct menu
*)),
1453 helpText
, SLOT(setInfo(struct menu
*)));
1454 connect(menuList
, SIGNAL(gotFocus(struct menu
*)),
1455 SLOT(listFocusChanged(void)));
1456 connect(helpText
, SIGNAL(menuSelected(struct menu
*)),
1457 SLOT(setMenuLink(struct menu
*)));
1459 QString listMode
= configSettings
->readEntry("/listMode", "symbol");
1460 if (listMode
== "single")
1462 else if (listMode
== "full")
1464 else /*if (listMode == "split")*/
1467 // UI setup done, restore splitter positions
1468 Q3ValueList
<int> sizes
= configSettings
->readSizes("/split1", &ok
);
1470 split1
->setSizes(sizes
);
1472 sizes
= configSettings
->readSizes("/split2", &ok
);
1474 split2
->setSizes(sizes
);
1477 void ConfigMainWindow::loadConfig(void)
1479 QString s
= Q3FileDialog::getOpenFileName(conf_get_configname(), NULL
, this);
1482 if (conf_read(QFile::encodeName(s
)))
1483 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1484 ConfigView::updateListAll();
1487 bool ConfigMainWindow::saveConfig(void)
1489 if (conf_write(NULL
)) {
1490 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1496 void ConfigMainWindow::saveConfigAs(void)
1498 QString s
= Q3FileDialog::getSaveFileName(conf_get_configname(), NULL
, this);
1504 void ConfigMainWindow::searchConfig(void)
1507 searchWindow
= new ConfigSearchWindow(this, "search");
1508 searchWindow
->show();
1511 void ConfigMainWindow::changeMenu(struct menu
*menu
)
1513 configList
->setRootMenu(menu
);
1514 if (configList
->rootEntry
->parent
== &rootmenu
)
1515 backAction
->setEnabled(FALSE
);
1517 backAction
->setEnabled(TRUE
);
1520 void ConfigMainWindow::setMenuLink(struct menu
*menu
)
1522 struct menu
*parent
;
1523 ConfigList
* list
= NULL
;
1526 if (configList
->menuSkip(menu
))
1529 switch (configList
->mode
) {
1532 parent
= menu_get_parent_menu(menu
);
1535 list
->setRootMenu(parent
);
1538 if (menu
->flags
& MENU_ROOT
) {
1539 configList
->setRootMenu(menu
);
1540 configList
->clearSelection();
1544 parent
= menu_get_parent_menu(menu
->parent
);
1547 item
= menuList
->findConfigItem(parent
);
1549 menuList
->setSelected(item
, TRUE
);
1550 menuList
->ensureItemVisible(item
);
1552 list
->setRootMenu(parent
);
1563 item
= list
->findConfigItem(menu
);
1565 list
->setSelected(item
, TRUE
);
1566 list
->ensureItemVisible(item
);
1572 void ConfigMainWindow::listFocusChanged(void)
1574 if (menuList
->mode
== menuMode
)
1575 configList
->clearSelection();
1578 void ConfigMainWindow::goBack(void)
1582 configList
->setParentMenu();
1583 if (configList
->rootEntry
== &rootmenu
)
1584 backAction
->setEnabled(FALSE
);
1585 item
= (ConfigItem
*)menuList
->selectedItem();
1587 if (item
->menu
== configList
->rootEntry
) {
1588 menuList
->setSelected(item
, TRUE
);
1591 item
= (ConfigItem
*)item
->parent();
1595 void ConfigMainWindow::showSingleView(void)
1598 menuList
->setRootMenu(0);
1599 configList
->mode
= singleMode
;
1600 if (configList
->rootEntry
== &rootmenu
)
1601 configList
->updateListAll();
1603 configList
->setRootMenu(&rootmenu
);
1604 configList
->setAllOpen(TRUE
);
1605 configList
->setFocus();
1608 void ConfigMainWindow::showSplitView(void)
1610 configList
->mode
= symbolMode
;
1611 if (configList
->rootEntry
== &rootmenu
)
1612 configList
->updateListAll();
1614 configList
->setRootMenu(&rootmenu
);
1615 configList
->setAllOpen(TRUE
);
1616 configApp
->processEvents();
1617 menuList
->mode
= menuMode
;
1618 menuList
->setRootMenu(&rootmenu
);
1619 menuList
->setAllOpen(TRUE
);
1621 menuList
->setFocus();
1624 void ConfigMainWindow::showFullView(void)
1627 menuList
->setRootMenu(0);
1628 configList
->mode
= fullMode
;
1629 if (configList
->rootEntry
== &rootmenu
)
1630 configList
->updateListAll();
1632 configList
->setRootMenu(&rootmenu
);
1633 configList
->setAllOpen(FALSE
);
1634 configList
->setFocus();
1638 * ask for saving configuration before quitting
1639 * TODO ask only when something changed
1641 void ConfigMainWindow::closeEvent(QCloseEvent
* e
)
1643 if (!conf_get_changed()) {
1647 QMessageBox
mb("qconf", _("Save configuration?"), QMessageBox::Warning
,
1648 QMessageBox::Yes
| QMessageBox::Default
, QMessageBox::No
, QMessageBox::Cancel
| QMessageBox::Escape
);
1649 mb
.setButtonText(QMessageBox::Yes
, _("&Save Changes"));
1650 mb
.setButtonText(QMessageBox::No
, _("&Discard Changes"));
1651 mb
.setButtonText(QMessageBox::Cancel
, _("Cancel Exit"));
1652 switch (mb
.exec()) {
1653 case QMessageBox::Yes
:
1659 case QMessageBox::No
:
1662 case QMessageBox::Cancel
:
1668 void ConfigMainWindow::showIntro(void)
1670 static const QString str
= _("Welcome to the qconf graphical configuration tool.\n\n"
1671 "For each option, a blank box indicates the feature is disabled, a check\n"
1672 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1673 "as a module. Clicking on the box will cycle through the three states.\n\n"
1674 "If you do not see an option (e.g., a device driver) that you believe\n"
1675 "should be present, try turning on Show All Options under the Options menu.\n"
1676 "Although there is no cross reference yet to help you figure out what other\n"
1677 "options must be enabled to support the option you are interested in, you can\n"
1678 "still view the help of a grayed-out option.\n\n"
1679 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1680 "which you can then match by examining other options.\n\n");
1682 QMessageBox::information(this, "qconf", str
);
1685 void ConfigMainWindow::showAbout(void)
1687 static const QString str
= _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1688 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1690 QMessageBox::information(this, "qconf", str
);
1693 void ConfigMainWindow::saveSettings(void)
1695 configSettings
->writeEntry("/window x", pos().x());
1696 configSettings
->writeEntry("/window y", pos().y());
1697 configSettings
->writeEntry("/window width", size().width());
1698 configSettings
->writeEntry("/window height", size().height());
1701 switch(configList
->mode
) {
1717 configSettings
->writeEntry("/listMode", entry
);
1719 configSettings
->writeSizes("/split1", split1
->sizes());
1720 configSettings
->writeSizes("/split2", split2
->sizes());
1723 void ConfigMainWindow::conf_changed(void)
1726 saveAction
->setEnabled(conf_get_changed());
1729 void fixup_rootmenu(struct menu
*menu
)
1732 static int menu_cnt
= 0;
1734 menu
->flags
|= MENU_ROOT
;
1735 for (child
= menu
->list
; child
; child
= child
->next
) {
1736 if (child
->prompt
&& child
->prompt
->type
== P_MENU
) {
1738 fixup_rootmenu(child
);
1740 } else if (!menu_cnt
)
1741 fixup_rootmenu(child
);
1745 static const char *progname
;
1747 static void usage(void)
1749 printf(_("%s <config>\n"), progname
);
1753 int main(int ac
, char** av
)
1755 ConfigMainWindow
* v
;
1758 bindtextdomain(PACKAGE
, LOCALEDIR
);
1759 textdomain(PACKAGE
);
1762 configApp
= new QApplication(ac
, av
);
1763 if (ac
> 1 && av
[1][0] == '-') {
1776 fixup_rootmenu(&rootmenu
);
1778 //zconfdump(stdout);
1780 configSettings
= new ConfigSettings();
1781 configSettings
->beginGroup("/kconfig/qconf");
1782 v
= new ConfigMainWindow();
1784 //zconfdump(stdout);
1785 configApp
->setMainWidget(v
);
1786 configApp
->connect(configApp
, SIGNAL(lastWindowClosed()), SLOT(quit()));
1787 configApp
->connect(configApp
, SIGNAL(aboutToQuit()), v
, SLOT(saveSettings()));
1791 configSettings
->endGroup();
1792 delete configSettings
;