2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
6 #include <qapplication.h>
7 #include <qmainwindow.h>
8 #include <qdesktopwidget.h>
12 #include <qsplitter.h>
13 #include <qlistview.h>
14 #include <qtextbrowser.h>
15 #include <qlineedit.h>
17 #include <qpushbutton.h>
19 #include <qmessagebox.h>
22 #include <qfiledialog.h>
23 #include <qdragobject.h>
39 static QApplication
*configApp
;
40 static ConfigSettings
*configSettings
;
42 QAction
*ConfigMainWindow::saveAction
;
44 static inline QString
qgettext(const char* str
)
46 return QString::fromLocal8Bit(gettext(str
));
49 static inline QString
qgettext(const QString
& str
)
51 return QString::fromLocal8Bit(gettext(str
.latin1()));
55 * Reads a list of integer values from the application settings.
57 QValueList
<int> ConfigSettings::readSizes(const QString
& key
, bool *ok
)
59 QValueList
<int> result
;
60 QStringList entryList
= readListEntry(key
, ok
);
62 QStringList::Iterator it
;
63 for (it
= entryList
.begin(); it
!= entryList
.end(); ++it
)
64 result
.push_back((*it
).toInt());
71 * Writes a list of integer values to the application settings.
73 bool ConfigSettings::writeSizes(const QString
& key
, const QValueList
<int>& value
)
75 QStringList stringList
;
76 QValueList
<int>::ConstIterator it
;
78 for (it
= value
.begin(); it
!= value
.end(); ++it
)
79 stringList
.push_back(QString::number(*it
));
80 return writeEntry(key
, stringList
);
87 * TODO check the value
89 void ConfigItem::okRename(int col
)
91 Parent::okRename(col
);
92 sym_set_string_value(menu
->sym
, text(dataColIdx
).latin1());
93 listView()->updateList(this);
98 * update the displayed of a menu entry
100 void ConfigItem::updateMenu(void)
104 struct property
*prop
;
111 setPixmap(promptColIdx
, list
->menuBackPix
);
118 prompt
= _(menu_get_prompt(menu
));
120 if (prop
) switch (prop
->type
) {
122 if (list
->mode
== singleMode
|| list
->mode
== symbolMode
) {
123 /* a menuconfig entry is displayed differently
124 * depending whether it's at the view root or a child.
126 if (sym
&& list
->rootEntry
== menu
)
128 setPixmap(promptColIdx
, list
->menuPix
);
132 setPixmap(promptColIdx
, 0);
136 setPixmap(promptColIdx
, 0);
144 setText(nameColIdx
, QString::fromLocal8Bit(sym
->name
));
146 type
= sym_get_type(sym
);
152 if (!sym_is_changable(sym
) && !list
->showAll
) {
153 setPixmap(promptColIdx
, 0);
154 setText(noColIdx
, QString::null
);
155 setText(modColIdx
, QString::null
);
156 setText(yesColIdx
, QString::null
);
159 expr
= sym_get_tristate_value(sym
);
162 if (sym_is_choice_value(sym
) && type
== S_BOOLEAN
)
163 setPixmap(promptColIdx
, list
->choiceYesPix
);
165 setPixmap(promptColIdx
, list
->symbolYesPix
);
166 setText(yesColIdx
, "Y");
170 setPixmap(promptColIdx
, list
->symbolModPix
);
171 setText(modColIdx
, "M");
175 if (sym_is_choice_value(sym
) && type
== S_BOOLEAN
)
176 setPixmap(promptColIdx
, list
->choiceNoPix
);
178 setPixmap(promptColIdx
, list
->symbolNoPix
);
179 setText(noColIdx
, "N");
184 setText(noColIdx
, sym_tristate_within_range(sym
, no
) ? "_" : 0);
186 setText(modColIdx
, sym_tristate_within_range(sym
, mod
) ? "_" : 0);
188 setText(yesColIdx
, sym_tristate_within_range(sym
, yes
) ? "_" : 0);
190 setText(dataColIdx
, QChar(ch
));
197 data
= sym_get_string_value(sym
);
199 #if QT_VERSION >= 300
200 int i
= list
->mapIdx(dataColIdx
);
202 setRenameEnabled(i
, TRUE
);
204 setText(dataColIdx
, data
);
205 if (type
== S_STRING
)
206 prompt
= QString("%1: %2").arg(prompt
).arg(data
);
208 prompt
= QString("(%2) %1").arg(prompt
).arg(data
);
211 if (!sym_has_value(sym
) && visible
)
212 prompt
+= _(" (NEW)");
214 setText(promptColIdx
, prompt
);
217 void ConfigItem::testUpdateMenu(bool v
)
225 sym_calc_value(menu
->sym
);
226 if (menu
->flags
& MENU_CHANGED
) {
227 /* the menu entry changed, so update all list items */
228 menu
->flags
&= ~MENU_CHANGED
;
229 for (i
= (ConfigItem
*)menu
->data
; i
; i
= i
->nextItem
)
231 } else if (listView()->updateAll
)
235 void ConfigItem::paintCell(QPainter
* p
, const QColorGroup
& cg
, int column
, int width
, int align
)
237 ConfigList
* list
= listView();
240 if (isSelected() && !list
->hasFocus() && list
->mode
== menuMode
)
241 Parent::paintCell(p
, list
->inactivedColorGroup
, column
, width
, align
);
243 Parent::paintCell(p
, cg
, column
, width
, align
);
245 Parent::paintCell(p
, list
->disabledColorGroup
, column
, width
, align
);
249 * construct a menu entry
251 void ConfigItem::init(void)
254 ConfigList
* list
= listView();
255 nextItem
= (ConfigItem
*)menu
->data
;
258 if (list
->mode
!= fullMode
)
260 sym_calc_value(menu
->sym
);
266 * destruct a menu entry
268 ConfigItem::~ConfigItem(void)
271 ConfigItem
** ip
= (ConfigItem
**)&menu
->data
;
272 for (; *ip
; ip
= &(*ip
)->nextItem
) {
281 ConfigLineEdit::ConfigLineEdit(ConfigView
* parent
)
284 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
287 void ConfigLineEdit::show(ConfigItem
* i
)
290 if (sym_get_string_value(item
->menu
->sym
))
291 setText(QString::fromLocal8Bit(sym_get_string_value(item
->menu
->sym
)));
293 setText(QString::null
);
298 void ConfigLineEdit::keyPressEvent(QKeyEvent
* e
)
305 sym_set_string_value(item
->menu
->sym
, text().latin1());
306 parent()->updateList(item
);
309 Parent::keyPressEvent(e
);
313 parent()->list
->setFocus();
317 ConfigList::ConfigList(ConfigView
* p
, const char *name
)
320 symbolYesPix(xpm_symbol_yes
), symbolModPix(xpm_symbol_mod
), symbolNoPix(xpm_symbol_no
),
321 choiceYesPix(xpm_choice_yes
), choiceNoPix(xpm_choice_no
),
322 menuPix(xpm_menu
), menuInvPix(xpm_menu_inv
), menuBackPix(xpm_menuback
), voidPix(xpm_void
),
323 showAll(false), showName(false), showRange(false), showData(false),
324 rootEntry(0), headerPopup(0)
329 setRootIsDecorated(TRUE
);
330 disabledColorGroup
= palette().active();
331 disabledColorGroup
.setColor(QColorGroup::Text
, palette().disabled().text());
332 inactivedColorGroup
= palette().active();
333 inactivedColorGroup
.setColor(QColorGroup::Highlight
, palette().disabled().highlight());
335 connect(this, SIGNAL(selectionChanged(void)),
336 SLOT(updateSelection(void)));
339 configSettings
->beginGroup(name
);
340 showAll
= configSettings
->readBoolEntry("/showAll", false);
341 showName
= configSettings
->readBoolEntry("/showName", false);
342 showRange
= configSettings
->readBoolEntry("/showRange", false);
343 showData
= configSettings
->readBoolEntry("/showData", false);
344 configSettings
->endGroup();
345 connect(configApp
, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
348 for (i
= 0; i
< colNr
; i
++)
349 colMap
[i
] = colRevMap
[i
] = -1;
350 addColumn(promptColIdx
, _("Option"));
355 void ConfigList::reinit(void)
357 removeColumn(dataColIdx
);
358 removeColumn(yesColIdx
);
359 removeColumn(modColIdx
);
360 removeColumn(noColIdx
);
361 removeColumn(nameColIdx
);
364 addColumn(nameColIdx
, _("Name"));
366 addColumn(noColIdx
, "N");
367 addColumn(modColIdx
, "M");
368 addColumn(yesColIdx
, "Y");
371 addColumn(dataColIdx
, _("Value"));
376 void ConfigList::saveSettings(void)
379 configSettings
->beginGroup(name());
380 configSettings
->writeEntry("/showName", showName
);
381 configSettings
->writeEntry("/showRange", showRange
);
382 configSettings
->writeEntry("/showData", showData
);
383 configSettings
->writeEntry("/showAll", showAll
);
384 configSettings
->endGroup();
388 ConfigItem
* ConfigList::findConfigItem(struct menu
*menu
)
390 ConfigItem
* item
= (ConfigItem
*)menu
->data
;
392 for (; item
; item
= item
->nextItem
) {
393 if (this == item
->listView())
400 void ConfigList::updateSelection(void)
405 ConfigItem
* item
= (ConfigItem
*)selectedItem();
410 emit
menuChanged(menu
);
413 type
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
414 if (mode
== menuMode
&& type
== P_MENU
)
415 emit
menuSelected(menu
);
418 void ConfigList::updateList(ConfigItem
* item
)
420 ConfigItem
* last
= 0;
423 if (mode
!= listMode
)
425 QListViewItemIterator
it(this);
428 for (; it
.current(); ++it
) {
429 item
= (ConfigItem
*)it
.current();
432 item
->testUpdateMenu(menu_is_visible(item
->menu
));
437 if (rootEntry
!= &rootmenu
&& (mode
== singleMode
||
438 (mode
== symbolMode
&& rootEntry
->parent
!= &rootmenu
))) {
441 item
= new ConfigItem(this, 0, true);
444 if ((mode
== singleMode
|| (mode
== symbolMode
&& !(rootEntry
->flags
& MENU_ROOT
))) &&
445 rootEntry
->sym
&& rootEntry
->prompt
) {
446 item
= last
? last
->nextSibling() : firstChild();
448 item
= new ConfigItem(this, last
, rootEntry
, true);
450 item
->testUpdateMenu(true);
452 updateMenuList(item
, rootEntry
);
457 updateMenuList(this, rootEntry
);
461 void ConfigList::setValue(ConfigItem
* item
, tristate val
)
467 sym
= item
->menu
? item
->menu
->sym
: 0;
471 type
= sym_get_type(sym
);
475 oldval
= sym_get_tristate_value(sym
);
477 if (!sym_set_tristate_value(sym
, val
))
479 if (oldval
== no
&& item
->menu
->list
)
481 parent()->updateList(item
);
486 void ConfigList::changeValue(ConfigItem
* item
)
490 int type
, oldexpr
, newexpr
;
497 if (item
->menu
->list
)
498 item
->setOpen(!item
->isOpen());
502 type
= sym_get_type(sym
);
506 oldexpr
= sym_get_tristate_value(sym
);
507 newexpr
= sym_toggle_tristate_value(sym
);
508 if (item
->menu
->list
) {
509 if (oldexpr
== newexpr
)
510 item
->setOpen(!item
->isOpen());
511 else if (oldexpr
== no
)
514 if (oldexpr
!= newexpr
)
515 parent()->updateList(item
);
520 #if QT_VERSION >= 300
521 if (colMap
[dataColIdx
] >= 0)
522 item
->startRename(colMap
[dataColIdx
]);
525 parent()->lineEdit
->show(item
);
530 void ConfigList::setRootMenu(struct menu
*menu
)
534 if (rootEntry
== menu
)
536 type
= menu
&& menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
539 updateMenuList(this, 0);
542 setSelected(currentItem(), hasFocus());
543 ensureItemVisible(currentItem());
546 void ConfigList::setParentMenu(void)
549 struct menu
*oldroot
;
552 if (rootEntry
== &rootmenu
)
554 setRootMenu(menu_get_parent_menu(rootEntry
->parent
));
556 QListViewItemIterator
it(this);
557 for (; (item
= (ConfigItem
*)it
.current()); it
++) {
558 if (item
->menu
== oldroot
) {
559 setCurrentItem(item
);
560 ensureItemVisible(item
);
567 * update all the children of a menu entry
568 * removes/adds the entries from the parent widget as necessary
570 * parent: either the menu list widget or a menu entry widget
571 * menu: entry to be updated
574 void ConfigList::updateMenuList(P
* parent
, struct menu
* menu
)
583 while ((item
= parent
->firstChild()))
588 last
= parent
->firstChild();
589 if (last
&& !last
->goParent
)
591 for (child
= menu
->list
; child
; child
= child
->next
) {
592 item
= last
? last
->nextSibling() : parent
->firstChild();
593 type
= child
->prompt
? child
->prompt
->type
: P_UNKNOWN
;
597 if (!(child
->flags
& MENU_ROOT
))
601 if (child
->flags
& MENU_ROOT
)
608 visible
= menu_is_visible(child
);
609 if (showAll
|| visible
) {
610 if (!child
->sym
&& !child
->list
&& !child
->prompt
)
612 if (!item
|| item
->menu
!= child
)
613 item
= new ConfigItem(parent
, last
, child
, visible
);
615 item
->testUpdateMenu(visible
);
617 if (mode
== fullMode
|| mode
== menuMode
|| type
!= P_MENU
)
618 updateMenuList(item
, child
);
620 updateMenuList(item
, 0);
625 if (item
&& item
->menu
== child
) {
626 last
= parent
->firstChild();
629 else while (last
->nextSibling() != item
)
630 last
= last
->nextSibling();
636 void ConfigList::keyPressEvent(QKeyEvent
* ev
)
638 QListViewItem
* i
= currentItem();
643 if (ev
->key() == Qt::Key_Escape
&& mode
!= fullMode
&& mode
!= listMode
) {
644 emit
parentSelected();
650 Parent::keyPressEvent(ev
);
653 item
= (ConfigItem
*)i
;
658 if (item
->goParent
) {
659 emit
parentSelected();
665 type
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
666 if (type
== P_MENU
&& rootEntry
!= menu
&&
667 mode
!= fullMode
&& mode
!= menuMode
) {
668 emit
menuSelected(menu
);
684 Parent::keyPressEvent(ev
);
690 void ConfigList::contentsMousePressEvent(QMouseEvent
* e
)
692 //QPoint p(contentsToViewport(e->pos()));
693 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
694 Parent::contentsMousePressEvent(e
);
697 void ConfigList::contentsMouseReleaseEvent(QMouseEvent
* e
)
699 QPoint
p(contentsToViewport(e
->pos()));
700 ConfigItem
* item
= (ConfigItem
*)itemAt(p
);
702 enum prop_type ptype
;
710 x
= header()->offset() + p
.x();
711 idx
= colRevMap
[header()->sectionAt(x
)];
714 pm
= item
->pixmap(promptColIdx
);
716 int off
= header()->sectionPos(0) + itemMargin() +
717 treeStepSize() * (item
->depth() + (rootIsDecorated() ? 1 : 0));
718 if (x
>= off
&& x
< off
+ pm
->width()) {
719 if (item
->goParent
) {
720 emit
parentSelected();
724 ptype
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
725 if (ptype
== P_MENU
&& rootEntry
!= menu
&&
726 mode
!= fullMode
&& mode
!= menuMode
)
727 emit
menuSelected(menu
);
748 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
749 Parent::contentsMouseReleaseEvent(e
);
752 void ConfigList::contentsMouseMoveEvent(QMouseEvent
* e
)
754 //QPoint p(contentsToViewport(e->pos()));
755 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
756 Parent::contentsMouseMoveEvent(e
);
759 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent
* e
)
761 QPoint
p(contentsToViewport(e
->pos()));
762 ConfigItem
* item
= (ConfigItem
*)itemAt(p
);
764 enum prop_type ptype
;
768 if (item
->goParent
) {
769 emit
parentSelected();
775 ptype
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
776 if (ptype
== P_MENU
&& (mode
== singleMode
|| mode
== symbolMode
))
777 emit
menuSelected(menu
);
782 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
783 Parent::contentsMouseDoubleClickEvent(e
);
786 void ConfigList::focusInEvent(QFocusEvent
*e
)
788 struct menu
*menu
= NULL
;
790 Parent::focusInEvent(e
);
792 ConfigItem
* item
= (ConfigItem
*)currentItem();
794 setSelected(item
, TRUE
);
800 void ConfigList::contextMenuEvent(QContextMenuEvent
*e
)
802 if (e
->y() <= header()->geometry().bottom()) {
806 headerPopup
= new QPopupMenu(this);
807 action
= new QAction(NULL
, _("Show Name"), 0, this);
808 action
->setToggleAction(TRUE
);
809 connect(action
, SIGNAL(toggled(bool)),
810 parent(), SLOT(setShowName(bool)));
811 connect(parent(), SIGNAL(showNameChanged(bool)),
812 action
, SLOT(setOn(bool)));
813 action
->setOn(showName
);
814 action
->addTo(headerPopup
);
815 action
= new QAction(NULL
, _("Show Range"), 0, this);
816 action
->setToggleAction(TRUE
);
817 connect(action
, SIGNAL(toggled(bool)),
818 parent(), SLOT(setShowRange(bool)));
819 connect(parent(), SIGNAL(showRangeChanged(bool)),
820 action
, SLOT(setOn(bool)));
821 action
->setOn(showRange
);
822 action
->addTo(headerPopup
);
823 action
= new QAction(NULL
, _("Show Data"), 0, this);
824 action
->setToggleAction(TRUE
);
825 connect(action
, SIGNAL(toggled(bool)),
826 parent(), SLOT(setShowData(bool)));
827 connect(parent(), SIGNAL(showDataChanged(bool)),
828 action
, SLOT(setOn(bool)));
829 action
->setOn(showData
);
830 action
->addTo(headerPopup
);
832 headerPopup
->exec(e
->globalPos());
838 ConfigView
* ConfigView::viewList
;
840 ConfigView::ConfigView(QWidget
* parent
, const char *name
)
841 : Parent(parent
, name
)
843 list
= new ConfigList(this, name
);
844 lineEdit
= new ConfigLineEdit(this);
847 this->nextView
= viewList
;
851 ConfigView::~ConfigView(void)
855 for (vp
= &viewList
; *vp
; vp
= &(*vp
)->nextView
) {
863 void ConfigView::setShowAll(bool b
)
865 if (list
->showAll
!= b
) {
867 list
->updateListAll();
868 emit
showAllChanged(b
);
872 void ConfigView::setShowName(bool b
)
874 if (list
->showName
!= b
) {
877 emit
showNameChanged(b
);
881 void ConfigView::setShowRange(bool b
)
883 if (list
->showRange
!= b
) {
886 emit
showRangeChanged(b
);
890 void ConfigView::setShowData(bool b
)
892 if (list
->showData
!= b
) {
895 emit
showDataChanged(b
);
899 void ConfigList::setAllOpen(bool open
)
901 QListViewItemIterator
it(this);
903 for (; it
.current(); it
++)
904 it
.current()->setOpen(open
);
907 void ConfigView::updateList(ConfigItem
* item
)
911 for (v
= viewList
; v
; v
= v
->nextView
)
912 v
->list
->updateList(item
);
915 void ConfigView::updateListAll(void)
919 for (v
= viewList
; v
; v
= v
->nextView
)
920 v
->list
->updateListAll();
923 ConfigInfoView::ConfigInfoView(QWidget
* parent
, const char *name
)
924 : Parent(parent
, name
), sym(0), menu(0)
927 configSettings
->beginGroup(name
);
928 _showDebug
= configSettings
->readBoolEntry("/showDebug", false);
929 configSettings
->endGroup();
930 connect(configApp
, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
934 void ConfigInfoView::saveSettings(void)
937 configSettings
->beginGroup(name());
938 configSettings
->writeEntry("/showDebug", showDebug());
939 configSettings
->endGroup();
943 void ConfigInfoView::setShowDebug(bool b
)
945 if (_showDebug
!= b
) {
951 emit
showDebugChanged(b
);
955 void ConfigInfoView::setInfo(struct menu
*m
)
967 void ConfigInfoView::setSource(const QString
& name
)
969 const char *p
= name
.latin1();
978 if (sscanf(p
, "m%p", &m
) == 1 && menu
!= m
) {
981 emit
menuSelected(menu
);
987 if (sscanf(p
, "s%p", &s
) == 1 && sym
!= s
) {
995 void ConfigInfoView::symbolInfo(void)
999 str
+= "<big>Symbol: <b>";
1000 str
+= print_filter(sym
->name
);
1001 str
+= "</b></big><br><br>value: ";
1002 str
+= print_filter(sym_get_string_value(sym
));
1003 str
+= "<br>visibility: ";
1004 str
+= sym
->visible
== yes
? "y" : sym
->visible
== mod
? "m" : "n";
1006 str
+= debug_info(sym
);
1011 void ConfigInfoView::menuInfo(void)
1014 QString head
, debug
, help
;
1020 head
+= print_filter(_(menu
->prompt
->text
));
1021 head
+= "</b></big>";
1025 head
+= QString().sprintf("<a href=\"s%p\">", sym
);
1026 head
+= print_filter(sym
->name
);
1031 } else if (sym
->name
) {
1034 head
+= QString().sprintf("<a href=\"s%p\">", sym
);
1035 head
+= print_filter(sym
->name
);
1038 head
+= "</b></big>";
1043 debug
= debug_info(sym
);
1045 struct gstr help_gstr
= str_new();
1046 menu_get_ext_help(menu
, &help_gstr
);
1047 help
= print_filter(str_get(&help_gstr
));
1048 str_free(&help_gstr
);
1049 } else if (menu
->prompt
) {
1051 head
+= print_filter(_(menu
->prompt
->text
));
1052 head
+= "</b></big><br><br>";
1054 if (menu
->prompt
->visible
.expr
) {
1055 debug
+= " dep: ";
1056 expr_print(menu
->prompt
->visible
.expr
, expr_print_help
, &debug
, E_NONE
);
1057 debug
+= "<br><br>";
1062 debug
+= QString().sprintf("defined at %s:%d<br><br>", menu
->file
->name
, menu
->lineno
);
1064 setText(head
+ debug
+ help
);
1067 QString
ConfigInfoView::debug_info(struct symbol
*sym
)
1072 debug
+= print_filter(sym_type_name(sym
->type
));
1073 if (sym_is_choice(sym
))
1074 debug
+= " (choice)";
1076 if (sym
->rev_dep
.expr
) {
1077 debug
+= "reverse dep: ";
1078 expr_print(sym
->rev_dep
.expr
, expr_print_help
, &debug
, E_NONE
);
1081 for (struct property
*prop
= sym
->prop
; prop
; prop
= prop
->next
) {
1082 switch (prop
->type
) {
1085 debug
+= QString().sprintf("prompt: <a href=\"m%p\">", prop
->menu
);
1086 debug
+= print_filter(_(prop
->text
));
1087 debug
+= "</a><br>";
1093 debug
+= prop_get_type_name(prop
->type
);
1095 expr_print(prop
->expr
, expr_print_help
, &debug
, E_NONE
);
1099 if (sym_is_choice(sym
)) {
1100 debug
+= "choice: ";
1101 expr_print(prop
->expr
, expr_print_help
, &debug
, E_NONE
);
1106 debug
+= "unknown property: ";
1107 debug
+= prop_get_type_name(prop
->type
);
1110 if (prop
->visible
.expr
) {
1111 debug
+= " dep: ";
1112 expr_print(prop
->visible
.expr
, expr_print_help
, &debug
, E_NONE
);
1121 QString
ConfigInfoView::print_filter(const QString
&str
)
1123 QRegExp
re("[<>&\"\\n]");
1125 for (int i
= 0; (i
= res
.find(re
, i
)) >= 0;) {
1126 switch (res
[i
].latin1()) {
1128 res
.replace(i
, 1, "<");
1132 res
.replace(i
, 1, ">");
1136 res
.replace(i
, 1, "&");
1140 res
.replace(i
, 1, """);
1144 res
.replace(i
, 1, "<br>");
1152 void ConfigInfoView::expr_print_help(void *data
, struct symbol
*sym
, const char *str
)
1154 QString
* text
= reinterpret_cast<QString
*>(data
);
1155 QString str2
= print_filter(str
);
1157 if (sym
&& sym
->name
&& !(sym
->flags
& SYMBOL_CONST
)) {
1158 *text
+= QString().sprintf("<a href=\"s%p\">", sym
);
1165 QPopupMenu
* ConfigInfoView::createPopupMenu(const QPoint
& pos
)
1167 QPopupMenu
* popup
= Parent::createPopupMenu(pos
);
1168 QAction
* action
= new QAction(NULL
, _("Show Debug Info"), 0, popup
);
1169 action
->setToggleAction(TRUE
);
1170 connect(action
, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1171 connect(this, SIGNAL(showDebugChanged(bool)), action
, SLOT(setOn(bool)));
1172 action
->setOn(showDebug());
1173 popup
->insertSeparator();
1174 action
->addTo(popup
);
1178 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent
*e
)
1180 Parent::contentsContextMenuEvent(e
);
1183 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow
* parent
, const char *name
)
1184 : Parent(parent
, name
), result(NULL
)
1186 setCaption("Search Config");
1188 QVBoxLayout
* layout1
= new QVBoxLayout(this, 11, 6);
1189 QHBoxLayout
* layout2
= new QHBoxLayout(0, 0, 6);
1190 layout2
->addWidget(new QLabel(_("Find:"), this));
1191 editField
= new QLineEdit(this);
1192 connect(editField
, SIGNAL(returnPressed()), SLOT(search()));
1193 layout2
->addWidget(editField
);
1194 searchButton
= new QPushButton(_("Search"), this);
1195 searchButton
->setAutoDefault(FALSE
);
1196 connect(searchButton
, SIGNAL(clicked()), SLOT(search()));
1197 layout2
->addWidget(searchButton
);
1198 layout1
->addLayout(layout2
);
1200 split
= new QSplitter(this);
1201 split
->setOrientation(Qt::Vertical
);
1202 list
= new ConfigView(split
, name
);
1203 list
->list
->mode
= listMode
;
1204 info
= new ConfigInfoView(split
, name
);
1205 connect(list
->list
, SIGNAL(menuChanged(struct menu
*)),
1206 info
, SLOT(setInfo(struct menu
*)));
1207 connect(list
->list
, SIGNAL(menuChanged(struct menu
*)),
1208 parent
, SLOT(setMenuLink(struct menu
*)));
1210 layout1
->addWidget(split
);
1213 int x
, y
, width
, height
;
1216 configSettings
->beginGroup(name
);
1217 width
= configSettings
->readNumEntry("/window width", parent
->width() / 2);
1218 height
= configSettings
->readNumEntry("/window height", parent
->height() / 2);
1219 resize(width
, height
);
1220 x
= configSettings
->readNumEntry("/window x", 0, &ok
);
1222 y
= configSettings
->readNumEntry("/window y", 0, &ok
);
1225 QValueList
<int> sizes
= configSettings
->readSizes("/split", &ok
);
1227 split
->setSizes(sizes
);
1228 configSettings
->endGroup();
1229 connect(configApp
, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1233 void ConfigSearchWindow::saveSettings(void)
1236 configSettings
->beginGroup(name());
1237 configSettings
->writeEntry("/window x", pos().x());
1238 configSettings
->writeEntry("/window y", pos().y());
1239 configSettings
->writeEntry("/window width", size().width());
1240 configSettings
->writeEntry("/window height", size().height());
1241 configSettings
->writeSizes("/split", split
->sizes());
1242 configSettings
->endGroup();
1246 void ConfigSearchWindow::search(void)
1249 struct property
*prop
;
1250 ConfigItem
*lastItem
= NULL
;
1253 list
->list
->clear();
1256 result
= sym_re_search(editField
->text().latin1());
1259 for (p
= result
; *p
; p
++) {
1260 for_all_prompts((*p
), prop
)
1261 lastItem
= new ConfigItem(list
->list
, lastItem
, prop
->menu
,
1262 menu_is_visible(prop
->menu
));
1267 * Construct the complete config widget
1269 ConfigMainWindow::ConfigMainWindow(void)
1274 int x
, y
, width
, height
;
1277 QDesktopWidget
*d
= configApp
->desktop();
1278 snprintf(title
, sizeof(title
), _("Linux Kernel v%s Configuration"),
1279 getenv("KERNELVERSION"));
1282 width
= configSettings
->readNumEntry("/window width", d
->width() - 64);
1283 height
= configSettings
->readNumEntry("/window height", d
->height() - 64);
1284 resize(width
, height
);
1285 x
= configSettings
->readNumEntry("/window x", 0, &ok
);
1287 y
= configSettings
->readNumEntry("/window y", 0, &ok
);
1291 split1
= new QSplitter(this);
1292 split1
->setOrientation(Qt::Horizontal
);
1293 setCentralWidget(split1
);
1295 menuView
= new ConfigView(split1
, "menu");
1296 menuList
= menuView
->list
;
1298 split2
= new QSplitter(split1
);
1299 split2
->setOrientation(Qt::Vertical
);
1301 // create config tree
1302 configView
= new ConfigView(split2
, "config");
1303 configList
= configView
->list
;
1305 helpText
= new ConfigInfoView(split2
, "help");
1306 helpText
->setTextFormat(Qt::RichText
);
1308 setTabOrder(configList
, helpText
);
1309 configList
->setFocus();
1312 toolBar
= new QToolBar("Tools", this);
1314 backAction
= new QAction("Back", QPixmap(xpm_back
), _("Back"), 0, this);
1315 connect(backAction
, SIGNAL(activated()), SLOT(goBack()));
1316 backAction
->setEnabled(FALSE
);
1317 QAction
*quitAction
= new QAction("Quit", _("&Quit"), Qt::CTRL
+ Qt::Key_Q
, this);
1318 connect(quitAction
, SIGNAL(activated()), SLOT(close()));
1319 QAction
*loadAction
= new QAction("Load", QPixmap(xpm_load
), _("&Load"), Qt::CTRL
+ Qt::Key_L
, this);
1320 connect(loadAction
, SIGNAL(activated()), SLOT(loadConfig()));
1321 saveAction
= new QAction("Save", QPixmap(xpm_save
), _("&Save"), Qt::CTRL
+ Qt::Key_S
, this);
1322 connect(saveAction
, SIGNAL(activated()), SLOT(saveConfig()));
1323 conf_set_changed_callback(conf_changed
);
1324 // Set saveAction's initial state
1326 QAction
*saveAsAction
= new QAction("Save As...", _("Save &As..."), 0, this);
1327 connect(saveAsAction
, SIGNAL(activated()), SLOT(saveConfigAs()));
1328 QAction
*searchAction
= new QAction("Find", _("&Find"), Qt::CTRL
+ Qt::Key_F
, this);
1329 connect(searchAction
, SIGNAL(activated()), SLOT(searchConfig()));
1330 QAction
*singleViewAction
= new QAction("Single View", QPixmap(xpm_single_view
), _("Single View"), 0, this);
1331 connect(singleViewAction
, SIGNAL(activated()), SLOT(showSingleView()));
1332 QAction
*splitViewAction
= new QAction("Split View", QPixmap(xpm_split_view
), _("Split View"), 0, this);
1333 connect(splitViewAction
, SIGNAL(activated()), SLOT(showSplitView()));
1334 QAction
*fullViewAction
= new QAction("Full View", QPixmap(xpm_tree_view
), _("Full View"), 0, this);
1335 connect(fullViewAction
, SIGNAL(activated()), SLOT(showFullView()));
1337 QAction
*showNameAction
= new QAction(NULL
, _("Show Name"), 0, this);
1338 showNameAction
->setToggleAction(TRUE
);
1339 connect(showNameAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowName(bool)));
1340 connect(configView
, SIGNAL(showNameChanged(bool)), showNameAction
, SLOT(setOn(bool)));
1341 showNameAction
->setOn(configView
->showName());
1342 QAction
*showRangeAction
= new QAction(NULL
, _("Show Range"), 0, this);
1343 showRangeAction
->setToggleAction(TRUE
);
1344 connect(showRangeAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowRange(bool)));
1345 connect(configView
, SIGNAL(showRangeChanged(bool)), showRangeAction
, SLOT(setOn(bool)));
1346 showRangeAction
->setOn(configList
->showRange
);
1347 QAction
*showDataAction
= new QAction(NULL
, _("Show Data"), 0, this);
1348 showDataAction
->setToggleAction(TRUE
);
1349 connect(showDataAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowData(bool)));
1350 connect(configView
, SIGNAL(showDataChanged(bool)), showDataAction
, SLOT(setOn(bool)));
1351 showDataAction
->setOn(configList
->showData
);
1352 QAction
*showAllAction
= new QAction(NULL
, _("Show All Options"), 0, this);
1353 showAllAction
->setToggleAction(TRUE
);
1354 connect(showAllAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowAll(bool)));
1355 connect(showAllAction
, SIGNAL(toggled(bool)), menuView
, SLOT(setShowAll(bool)));
1356 showAllAction
->setOn(configList
->showAll
);
1357 QAction
*showDebugAction
= new QAction(NULL
, _("Show Debug Info"), 0, this);
1358 showDebugAction
->setToggleAction(TRUE
);
1359 connect(showDebugAction
, SIGNAL(toggled(bool)), helpText
, SLOT(setShowDebug(bool)));
1360 connect(helpText
, SIGNAL(showDebugChanged(bool)), showDebugAction
, SLOT(setOn(bool)));
1361 showDebugAction
->setOn(helpText
->showDebug());
1363 QAction
*showIntroAction
= new QAction(NULL
, _("Introduction"), 0, this);
1364 connect(showIntroAction
, SIGNAL(activated()), SLOT(showIntro()));
1365 QAction
*showAboutAction
= new QAction(NULL
, _("About"), 0, this);
1366 connect(showAboutAction
, SIGNAL(activated()), SLOT(showAbout()));
1369 backAction
->addTo(toolBar
);
1370 toolBar
->addSeparator();
1371 loadAction
->addTo(toolBar
);
1372 saveAction
->addTo(toolBar
);
1373 toolBar
->addSeparator();
1374 singleViewAction
->addTo(toolBar
);
1375 splitViewAction
->addTo(toolBar
);
1376 fullViewAction
->addTo(toolBar
);
1378 // create config menu
1379 QPopupMenu
* config
= new QPopupMenu(this);
1380 menu
->insertItem(_("&File"), config
);
1381 loadAction
->addTo(config
);
1382 saveAction
->addTo(config
);
1383 saveAsAction
->addTo(config
);
1384 config
->insertSeparator();
1385 quitAction
->addTo(config
);
1388 QPopupMenu
* editMenu
= new QPopupMenu(this);
1389 menu
->insertItem(_("&Edit"), editMenu
);
1390 searchAction
->addTo(editMenu
);
1392 // create options menu
1393 QPopupMenu
* optionMenu
= new QPopupMenu(this);
1394 menu
->insertItem(_("&Option"), optionMenu
);
1395 showNameAction
->addTo(optionMenu
);
1396 showRangeAction
->addTo(optionMenu
);
1397 showDataAction
->addTo(optionMenu
);
1398 optionMenu
->insertSeparator();
1399 showAllAction
->addTo(optionMenu
);
1400 showDebugAction
->addTo(optionMenu
);
1403 QPopupMenu
* helpMenu
= new QPopupMenu(this);
1404 menu
->insertSeparator();
1405 menu
->insertItem(_("&Help"), helpMenu
);
1406 showIntroAction
->addTo(helpMenu
);
1407 showAboutAction
->addTo(helpMenu
);
1409 connect(configList
, SIGNAL(menuChanged(struct menu
*)),
1410 helpText
, SLOT(setInfo(struct menu
*)));
1411 connect(configList
, SIGNAL(menuSelected(struct menu
*)),
1412 SLOT(changeMenu(struct menu
*)));
1413 connect(configList
, SIGNAL(parentSelected()),
1415 connect(menuList
, SIGNAL(menuChanged(struct menu
*)),
1416 helpText
, SLOT(setInfo(struct menu
*)));
1417 connect(menuList
, SIGNAL(menuSelected(struct menu
*)),
1418 SLOT(changeMenu(struct menu
*)));
1420 connect(configList
, SIGNAL(gotFocus(struct menu
*)),
1421 helpText
, SLOT(setInfo(struct menu
*)));
1422 connect(menuList
, SIGNAL(gotFocus(struct menu
*)),
1423 helpText
, SLOT(setInfo(struct menu
*)));
1424 connect(menuList
, SIGNAL(gotFocus(struct menu
*)),
1425 SLOT(listFocusChanged(void)));
1426 connect(helpText
, SIGNAL(menuSelected(struct menu
*)),
1427 SLOT(setMenuLink(struct menu
*)));
1429 QString listMode
= configSettings
->readEntry("/listMode", "symbol");
1430 if (listMode
== "single")
1432 else if (listMode
== "full")
1434 else /*if (listMode == "split")*/
1437 // UI setup done, restore splitter positions
1438 QValueList
<int> sizes
= configSettings
->readSizes("/split1", &ok
);
1440 split1
->setSizes(sizes
);
1442 sizes
= configSettings
->readSizes("/split2", &ok
);
1444 split2
->setSizes(sizes
);
1447 void ConfigMainWindow::loadConfig(void)
1449 QString s
= QFileDialog::getOpenFileName(conf_get_configname(), NULL
, this);
1452 if (conf_read(QFile::encodeName(s
)))
1453 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1454 ConfigView::updateListAll();
1457 void ConfigMainWindow::saveConfig(void)
1459 if (conf_write(NULL
))
1460 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1463 void ConfigMainWindow::saveConfigAs(void)
1465 QString s
= QFileDialog::getSaveFileName(conf_get_configname(), NULL
, this);
1468 if (conf_write(QFile::encodeName(s
)))
1469 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1472 void ConfigMainWindow::searchConfig(void)
1475 searchWindow
= new ConfigSearchWindow(this, "search");
1476 searchWindow
->show();
1479 void ConfigMainWindow::changeMenu(struct menu
*menu
)
1481 configList
->setRootMenu(menu
);
1482 if (configList
->rootEntry
->parent
== &rootmenu
)
1483 backAction
->setEnabled(FALSE
);
1485 backAction
->setEnabled(TRUE
);
1488 void ConfigMainWindow::setMenuLink(struct menu
*menu
)
1490 struct menu
*parent
;
1491 ConfigList
* list
= NULL
;
1494 if (!menu_is_visible(menu
) && !configView
->showAll())
1497 switch (configList
->mode
) {
1500 parent
= menu_get_parent_menu(menu
);
1503 list
->setRootMenu(parent
);
1506 if (menu
->flags
& MENU_ROOT
) {
1507 configList
->setRootMenu(menu
);
1508 configList
->clearSelection();
1512 parent
= menu_get_parent_menu(menu
->parent
);
1515 item
= menuList
->findConfigItem(parent
);
1517 menuList
->setSelected(item
, TRUE
);
1518 menuList
->ensureItemVisible(item
);
1520 list
->setRootMenu(parent
);
1531 item
= list
->findConfigItem(menu
);
1533 list
->setSelected(item
, TRUE
);
1534 list
->ensureItemVisible(item
);
1540 void ConfigMainWindow::listFocusChanged(void)
1542 if (menuList
->mode
== menuMode
)
1543 configList
->clearSelection();
1546 void ConfigMainWindow::goBack(void)
1550 configList
->setParentMenu();
1551 if (configList
->rootEntry
== &rootmenu
)
1552 backAction
->setEnabled(FALSE
);
1553 item
= (ConfigItem
*)menuList
->selectedItem();
1555 if (item
->menu
== configList
->rootEntry
) {
1556 menuList
->setSelected(item
, TRUE
);
1559 item
= (ConfigItem
*)item
->parent();
1563 void ConfigMainWindow::showSingleView(void)
1566 menuList
->setRootMenu(0);
1567 configList
->mode
= singleMode
;
1568 if (configList
->rootEntry
== &rootmenu
)
1569 configList
->updateListAll();
1571 configList
->setRootMenu(&rootmenu
);
1572 configList
->setAllOpen(TRUE
);
1573 configList
->setFocus();
1576 void ConfigMainWindow::showSplitView(void)
1578 configList
->mode
= symbolMode
;
1579 if (configList
->rootEntry
== &rootmenu
)
1580 configList
->updateListAll();
1582 configList
->setRootMenu(&rootmenu
);
1583 configList
->setAllOpen(TRUE
);
1584 configApp
->processEvents();
1585 menuList
->mode
= menuMode
;
1586 menuList
->setRootMenu(&rootmenu
);
1587 menuList
->setAllOpen(TRUE
);
1589 menuList
->setFocus();
1592 void ConfigMainWindow::showFullView(void)
1595 menuList
->setRootMenu(0);
1596 configList
->mode
= fullMode
;
1597 if (configList
->rootEntry
== &rootmenu
)
1598 configList
->updateListAll();
1600 configList
->setRootMenu(&rootmenu
);
1601 configList
->setAllOpen(FALSE
);
1602 configList
->setFocus();
1606 * ask for saving configuration before quitting
1607 * TODO ask only when something changed
1609 void ConfigMainWindow::closeEvent(QCloseEvent
* e
)
1611 if (!conf_get_changed()) {
1615 QMessageBox
mb("qconf", _("Save configuration?"), QMessageBox::Warning
,
1616 QMessageBox::Yes
| QMessageBox::Default
, QMessageBox::No
, QMessageBox::Cancel
| QMessageBox::Escape
);
1617 mb
.setButtonText(QMessageBox::Yes
, _("&Save Changes"));
1618 mb
.setButtonText(QMessageBox::No
, _("&Discard Changes"));
1619 mb
.setButtonText(QMessageBox::Cancel
, _("Cancel Exit"));
1620 switch (mb
.exec()) {
1621 case QMessageBox::Yes
:
1623 case QMessageBox::No
:
1626 case QMessageBox::Cancel
:
1632 void ConfigMainWindow::showIntro(void)
1634 static const QString str
= _("Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1635 "For each option, a blank box indicates the feature is disabled, a check\n"
1636 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1637 "as a module. Clicking on the box will cycle through the three states.\n\n"
1638 "If you do not see an option (e.g., a device driver) that you believe\n"
1639 "should be present, try turning on Show All Options under the Options menu.\n"
1640 "Although there is no cross reference yet to help you figure out what other\n"
1641 "options must be enabled to support the option you are interested in, you can\n"
1642 "still view the help of a grayed-out option.\n\n"
1643 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1644 "which you can then match by examining other options.\n\n");
1646 QMessageBox::information(this, "qconf", str
);
1649 void ConfigMainWindow::showAbout(void)
1651 static const QString str
= _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1652 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1654 QMessageBox::information(this, "qconf", str
);
1657 void ConfigMainWindow::saveSettings(void)
1659 configSettings
->writeEntry("/window x", pos().x());
1660 configSettings
->writeEntry("/window y", pos().y());
1661 configSettings
->writeEntry("/window width", size().width());
1662 configSettings
->writeEntry("/window height", size().height());
1665 switch(configList
->mode
) {
1681 configSettings
->writeEntry("/listMode", entry
);
1683 configSettings
->writeSizes("/split1", split1
->sizes());
1684 configSettings
->writeSizes("/split2", split2
->sizes());
1687 void ConfigMainWindow::conf_changed(void)
1690 saveAction
->setEnabled(conf_get_changed());
1693 void fixup_rootmenu(struct menu
*menu
)
1696 static int menu_cnt
= 0;
1698 menu
->flags
|= MENU_ROOT
;
1699 for (child
= menu
->list
; child
; child
= child
->next
) {
1700 if (child
->prompt
&& child
->prompt
->type
== P_MENU
) {
1702 fixup_rootmenu(child
);
1704 } else if (!menu_cnt
)
1705 fixup_rootmenu(child
);
1709 static const char *progname
;
1711 static void usage(void)
1713 printf(_("%s <config>\n"), progname
);
1717 int main(int ac
, char** av
)
1719 ConfigMainWindow
* v
;
1722 bindtextdomain(PACKAGE
, LOCALEDIR
);
1723 textdomain(PACKAGE
);
1725 #ifndef LKC_DIRECT_LINK
1730 configApp
= new QApplication(ac
, av
);
1731 if (ac
> 1 && av
[1][0] == '-') {
1744 fixup_rootmenu(&rootmenu
);
1746 //zconfdump(stdout);
1748 configSettings
= new ConfigSettings();
1749 configSettings
->beginGroup("/kconfig/qconf");
1750 v
= new ConfigMainWindow();
1752 //zconfdump(stdout);
1753 configApp
->setMainWidget(v
);
1754 configApp
->connect(configApp
, SIGNAL(lastWindowClosed()), SLOT(quit()));
1755 configApp
->connect(configApp
, SIGNAL(aboutToQuit()), v
, SLOT(saveSettings()));
1759 configSettings
->endGroup();
1760 delete configSettings
;