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>
11 #include <qsplitter.h>
12 #include <qlistview.h>
13 #include <qtextbrowser.h>
14 #include <qlineedit.h>
16 #include <qpushbutton.h>
18 #include <qmessagebox.h>
21 #include <qfiledialog.h>
22 #include <qdragobject.h>
38 static QApplication
*configApp
;
39 static ConfigSettings
*configSettings
;
41 QAction
*ConfigMainWindow::saveAction
;
43 static inline QString
qgettext(const char* str
)
45 return QString::fromLocal8Bit(gettext(str
));
48 static inline QString
qgettext(const QString
& str
)
50 return QString::fromLocal8Bit(gettext(str
.latin1()));
54 * Reads a list of integer values from the application settings.
56 QValueList
<int> ConfigSettings::readSizes(const QString
& key
, bool *ok
)
58 QValueList
<int> result
;
59 QStringList entryList
= readListEntry(key
, ok
);
61 QStringList::Iterator it
;
62 for (it
= entryList
.begin(); it
!= entryList
.end(); ++it
)
63 result
.push_back((*it
).toInt());
70 * Writes a list of integer values to the application settings.
72 bool ConfigSettings::writeSizes(const QString
& key
, const QValueList
<int>& value
)
74 QStringList stringList
;
75 QValueList
<int>::ConstIterator it
;
77 for (it
= value
.begin(); it
!= value
.end(); ++it
)
78 stringList
.push_back(QString::number(*it
));
79 return writeEntry(key
, stringList
);
86 * TODO check the value
88 void ConfigItem::okRename(int col
)
90 Parent::okRename(col
);
91 sym_set_string_value(menu
->sym
, text(dataColIdx
).latin1());
92 listView()->updateList(this);
97 * update the displayed of a menu entry
99 void ConfigItem::updateMenu(void)
103 struct property
*prop
;
110 setPixmap(promptColIdx
, list
->menuBackPix
);
117 prompt
= _(menu_get_prompt(menu
));
119 if (prop
) switch (prop
->type
) {
121 if (list
->mode
== singleMode
|| list
->mode
== symbolMode
) {
122 /* a menuconfig entry is displayed differently
123 * depending whether it's at the view root or a child.
125 if (sym
&& list
->rootEntry
== menu
)
127 setPixmap(promptColIdx
, list
->menuPix
);
131 setPixmap(promptColIdx
, 0);
135 setPixmap(promptColIdx
, 0);
143 setText(nameColIdx
, QString::fromLocal8Bit(sym
->name
));
145 type
= sym_get_type(sym
);
151 if (!sym_is_changable(sym
) && !list
->showAll
) {
152 setPixmap(promptColIdx
, 0);
153 setText(noColIdx
, QString::null
);
154 setText(modColIdx
, QString::null
);
155 setText(yesColIdx
, QString::null
);
158 expr
= sym_get_tristate_value(sym
);
161 if (sym_is_choice_value(sym
) && type
== S_BOOLEAN
)
162 setPixmap(promptColIdx
, list
->choiceYesPix
);
164 setPixmap(promptColIdx
, list
->symbolYesPix
);
165 setText(yesColIdx
, "Y");
169 setPixmap(promptColIdx
, list
->symbolModPix
);
170 setText(modColIdx
, "M");
174 if (sym_is_choice_value(sym
) && type
== S_BOOLEAN
)
175 setPixmap(promptColIdx
, list
->choiceNoPix
);
177 setPixmap(promptColIdx
, list
->symbolNoPix
);
178 setText(noColIdx
, "N");
183 setText(noColIdx
, sym_tristate_within_range(sym
, no
) ? "_" : 0);
185 setText(modColIdx
, sym_tristate_within_range(sym
, mod
) ? "_" : 0);
187 setText(yesColIdx
, sym_tristate_within_range(sym
, yes
) ? "_" : 0);
189 setText(dataColIdx
, QChar(ch
));
196 data
= sym_get_string_value(sym
);
198 #if QT_VERSION >= 300
199 int i
= list
->mapIdx(dataColIdx
);
201 setRenameEnabled(i
, TRUE
);
203 setText(dataColIdx
, data
);
204 if (type
== S_STRING
)
205 prompt
= QString("%1: %2").arg(prompt
).arg(data
);
207 prompt
= QString("(%2) %1").arg(prompt
).arg(data
);
210 if (!sym_has_value(sym
) && visible
)
211 prompt
+= _(" (NEW)");
213 setText(promptColIdx
, prompt
);
216 void ConfigItem::testUpdateMenu(bool v
)
224 sym_calc_value(menu
->sym
);
225 if (menu
->flags
& MENU_CHANGED
) {
226 /* the menu entry changed, so update all list items */
227 menu
->flags
&= ~MENU_CHANGED
;
228 for (i
= (ConfigItem
*)menu
->data
; i
; i
= i
->nextItem
)
230 } else if (listView()->updateAll
)
234 void ConfigItem::paintCell(QPainter
* p
, const QColorGroup
& cg
, int column
, int width
, int align
)
236 ConfigList
* list
= listView();
239 if (isSelected() && !list
->hasFocus() && list
->mode
== menuMode
)
240 Parent::paintCell(p
, list
->inactivedColorGroup
, column
, width
, align
);
242 Parent::paintCell(p
, cg
, column
, width
, align
);
244 Parent::paintCell(p
, list
->disabledColorGroup
, column
, width
, align
);
248 * construct a menu entry
250 void ConfigItem::init(void)
253 ConfigList
* list
= listView();
254 nextItem
= (ConfigItem
*)menu
->data
;
257 if (list
->mode
!= fullMode
)
259 sym_calc_value(menu
->sym
);
265 * destruct a menu entry
267 ConfigItem::~ConfigItem(void)
270 ConfigItem
** ip
= (ConfigItem
**)&menu
->data
;
271 for (; *ip
; ip
= &(*ip
)->nextItem
) {
280 ConfigLineEdit::ConfigLineEdit(ConfigView
* parent
)
283 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
286 void ConfigLineEdit::show(ConfigItem
* i
)
289 if (sym_get_string_value(item
->menu
->sym
))
290 setText(QString::fromLocal8Bit(sym_get_string_value(item
->menu
->sym
)));
292 setText(QString::null
);
297 void ConfigLineEdit::keyPressEvent(QKeyEvent
* e
)
304 sym_set_string_value(item
->menu
->sym
, text().latin1());
305 parent()->updateList(item
);
308 Parent::keyPressEvent(e
);
312 parent()->list
->setFocus();
316 ConfigList::ConfigList(ConfigView
* p
, const char *name
)
319 symbolYesPix(xpm_symbol_yes
), symbolModPix(xpm_symbol_mod
), symbolNoPix(xpm_symbol_no
),
320 choiceYesPix(xpm_choice_yes
), choiceNoPix(xpm_choice_no
),
321 menuPix(xpm_menu
), menuInvPix(xpm_menu_inv
), menuBackPix(xpm_menuback
), voidPix(xpm_void
),
322 showAll(false), showName(false), showRange(false), showData(false),
323 rootEntry(0), headerPopup(0)
328 setRootIsDecorated(TRUE
);
329 disabledColorGroup
= palette().active();
330 disabledColorGroup
.setColor(QColorGroup::Text
, palette().disabled().text());
331 inactivedColorGroup
= palette().active();
332 inactivedColorGroup
.setColor(QColorGroup::Highlight
, palette().disabled().highlight());
334 connect(this, SIGNAL(selectionChanged(void)),
335 SLOT(updateSelection(void)));
338 configSettings
->beginGroup(name
);
339 showAll
= configSettings
->readBoolEntry("/showAll", false);
340 showName
= configSettings
->readBoolEntry("/showName", false);
341 showRange
= configSettings
->readBoolEntry("/showRange", false);
342 showData
= configSettings
->readBoolEntry("/showData", false);
343 configSettings
->endGroup();
344 connect(configApp
, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
347 for (i
= 0; i
< colNr
; i
++)
348 colMap
[i
] = colRevMap
[i
] = -1;
349 addColumn(promptColIdx
, _("Option"));
354 void ConfigList::reinit(void)
356 removeColumn(dataColIdx
);
357 removeColumn(yesColIdx
);
358 removeColumn(modColIdx
);
359 removeColumn(noColIdx
);
360 removeColumn(nameColIdx
);
363 addColumn(nameColIdx
, _("Name"));
365 addColumn(noColIdx
, "N");
366 addColumn(modColIdx
, "M");
367 addColumn(yesColIdx
, "Y");
370 addColumn(dataColIdx
, _("Value"));
375 void ConfigList::saveSettings(void)
378 configSettings
->beginGroup(name());
379 configSettings
->writeEntry("/showName", showName
);
380 configSettings
->writeEntry("/showRange", showRange
);
381 configSettings
->writeEntry("/showData", showData
);
382 configSettings
->writeEntry("/showAll", showAll
);
383 configSettings
->endGroup();
387 ConfigItem
* ConfigList::findConfigItem(struct menu
*menu
)
389 ConfigItem
* item
= (ConfigItem
*)menu
->data
;
391 for (; item
; item
= item
->nextItem
) {
392 if (this == item
->listView())
399 void ConfigList::updateSelection(void)
404 ConfigItem
* item
= (ConfigItem
*)selectedItem();
409 emit
menuChanged(menu
);
412 type
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
413 if (mode
== menuMode
&& type
== P_MENU
)
414 emit
menuSelected(menu
);
417 void ConfigList::updateList(ConfigItem
* item
)
419 ConfigItem
* last
= 0;
422 if (mode
!= listMode
)
424 QListViewItemIterator
it(this);
427 for (; it
.current(); ++it
) {
428 item
= (ConfigItem
*)it
.current();
431 item
->testUpdateMenu(menu_is_visible(item
->menu
));
436 if (rootEntry
!= &rootmenu
&& (mode
== singleMode
||
437 (mode
== symbolMode
&& rootEntry
->parent
!= &rootmenu
))) {
440 item
= new ConfigItem(this, 0, true);
443 if ((mode
== singleMode
|| (mode
== symbolMode
&& !(rootEntry
->flags
& MENU_ROOT
))) &&
444 rootEntry
->sym
&& rootEntry
->prompt
) {
445 item
= last
? last
->nextSibling() : firstChild();
447 item
= new ConfigItem(this, last
, rootEntry
, true);
449 item
->testUpdateMenu(true);
451 updateMenuList(item
, rootEntry
);
456 updateMenuList(this, rootEntry
);
460 void ConfigList::setValue(ConfigItem
* item
, tristate val
)
466 sym
= item
->menu
? item
->menu
->sym
: 0;
470 type
= sym_get_type(sym
);
474 oldval
= sym_get_tristate_value(sym
);
476 if (!sym_set_tristate_value(sym
, val
))
478 if (oldval
== no
&& item
->menu
->list
)
480 parent()->updateList(item
);
485 void ConfigList::changeValue(ConfigItem
* item
)
489 int type
, oldexpr
, newexpr
;
496 if (item
->menu
->list
)
497 item
->setOpen(!item
->isOpen());
501 type
= sym_get_type(sym
);
505 oldexpr
= sym_get_tristate_value(sym
);
506 newexpr
= sym_toggle_tristate_value(sym
);
507 if (item
->menu
->list
) {
508 if (oldexpr
== newexpr
)
509 item
->setOpen(!item
->isOpen());
510 else if (oldexpr
== no
)
513 if (oldexpr
!= newexpr
)
514 parent()->updateList(item
);
519 #if QT_VERSION >= 300
520 if (colMap
[dataColIdx
] >= 0)
521 item
->startRename(colMap
[dataColIdx
]);
524 parent()->lineEdit
->show(item
);
529 void ConfigList::setRootMenu(struct menu
*menu
)
533 if (rootEntry
== menu
)
535 type
= menu
&& menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
538 updateMenuList(this, 0);
541 setSelected(currentItem(), hasFocus());
542 ensureItemVisible(currentItem());
545 void ConfigList::setParentMenu(void)
548 struct menu
*oldroot
;
551 if (rootEntry
== &rootmenu
)
553 setRootMenu(menu_get_parent_menu(rootEntry
->parent
));
555 QListViewItemIterator
it(this);
556 for (; (item
= (ConfigItem
*)it
.current()); it
++) {
557 if (item
->menu
== oldroot
) {
558 setCurrentItem(item
);
559 ensureItemVisible(item
);
566 * update all the children of a menu entry
567 * removes/adds the entries from the parent widget as necessary
569 * parent: either the menu list widget or a menu entry widget
570 * menu: entry to be updated
573 void ConfigList::updateMenuList(P
* parent
, struct menu
* menu
)
582 while ((item
= parent
->firstChild()))
587 last
= parent
->firstChild();
588 if (last
&& !last
->goParent
)
590 for (child
= menu
->list
; child
; child
= child
->next
) {
591 item
= last
? last
->nextSibling() : parent
->firstChild();
592 type
= child
->prompt
? child
->prompt
->type
: P_UNKNOWN
;
596 if (!(child
->flags
& MENU_ROOT
))
600 if (child
->flags
& MENU_ROOT
)
607 visible
= menu_is_visible(child
);
608 if (showAll
|| visible
) {
609 if (!child
->sym
&& !child
->list
&& !child
->prompt
)
611 if (!item
|| item
->menu
!= child
)
612 item
= new ConfigItem(parent
, last
, child
, visible
);
614 item
->testUpdateMenu(visible
);
616 if (mode
== fullMode
|| mode
== menuMode
|| type
!= P_MENU
)
617 updateMenuList(item
, child
);
619 updateMenuList(item
, 0);
624 if (item
&& item
->menu
== child
) {
625 last
= parent
->firstChild();
628 else while (last
->nextSibling() != item
)
629 last
= last
->nextSibling();
635 void ConfigList::keyPressEvent(QKeyEvent
* ev
)
637 QListViewItem
* i
= currentItem();
642 if (ev
->key() == Key_Escape
&& mode
!= fullMode
&& mode
!= listMode
) {
643 emit
parentSelected();
649 Parent::keyPressEvent(ev
);
652 item
= (ConfigItem
*)i
;
657 if (item
->goParent
) {
658 emit
parentSelected();
664 type
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
665 if (type
== P_MENU
&& rootEntry
!= menu
&&
666 mode
!= fullMode
&& mode
!= menuMode
) {
667 emit
menuSelected(menu
);
683 Parent::keyPressEvent(ev
);
689 void ConfigList::contentsMousePressEvent(QMouseEvent
* e
)
691 //QPoint p(contentsToViewport(e->pos()));
692 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
693 Parent::contentsMousePressEvent(e
);
696 void ConfigList::contentsMouseReleaseEvent(QMouseEvent
* e
)
698 QPoint
p(contentsToViewport(e
->pos()));
699 ConfigItem
* item
= (ConfigItem
*)itemAt(p
);
701 enum prop_type ptype
;
709 x
= header()->offset() + p
.x();
710 idx
= colRevMap
[header()->sectionAt(x
)];
713 pm
= item
->pixmap(promptColIdx
);
715 int off
= header()->sectionPos(0) + itemMargin() +
716 treeStepSize() * (item
->depth() + (rootIsDecorated() ? 1 : 0));
717 if (x
>= off
&& x
< off
+ pm
->width()) {
718 if (item
->goParent
) {
719 emit
parentSelected();
723 ptype
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
724 if (ptype
== P_MENU
&& rootEntry
!= menu
&&
725 mode
!= fullMode
&& mode
!= menuMode
)
726 emit
menuSelected(menu
);
747 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
748 Parent::contentsMouseReleaseEvent(e
);
751 void ConfigList::contentsMouseMoveEvent(QMouseEvent
* e
)
753 //QPoint p(contentsToViewport(e->pos()));
754 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
755 Parent::contentsMouseMoveEvent(e
);
758 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent
* e
)
760 QPoint
p(contentsToViewport(e
->pos()));
761 ConfigItem
* item
= (ConfigItem
*)itemAt(p
);
763 enum prop_type ptype
;
767 if (item
->goParent
) {
768 emit
parentSelected();
774 ptype
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
775 if (ptype
== P_MENU
&& (mode
== singleMode
|| mode
== symbolMode
))
776 emit
menuSelected(menu
);
781 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
782 Parent::contentsMouseDoubleClickEvent(e
);
785 void ConfigList::focusInEvent(QFocusEvent
*e
)
787 struct menu
*menu
= NULL
;
789 Parent::focusInEvent(e
);
791 ConfigItem
* item
= (ConfigItem
*)currentItem();
793 setSelected(item
, TRUE
);
799 void ConfigList::contextMenuEvent(QContextMenuEvent
*e
)
801 if (e
->y() <= header()->geometry().bottom()) {
805 headerPopup
= new QPopupMenu(this);
806 action
= new QAction(NULL
, _("Show Name"), 0, this);
807 action
->setToggleAction(TRUE
);
808 connect(action
, SIGNAL(toggled(bool)),
809 parent(), SLOT(setShowName(bool)));
810 connect(parent(), SIGNAL(showNameChanged(bool)),
811 action
, SLOT(setOn(bool)));
812 action
->setOn(showName
);
813 action
->addTo(headerPopup
);
814 action
= new QAction(NULL
, _("Show Range"), 0, this);
815 action
->setToggleAction(TRUE
);
816 connect(action
, SIGNAL(toggled(bool)),
817 parent(), SLOT(setShowRange(bool)));
818 connect(parent(), SIGNAL(showRangeChanged(bool)),
819 action
, SLOT(setOn(bool)));
820 action
->setOn(showRange
);
821 action
->addTo(headerPopup
);
822 action
= new QAction(NULL
, _("Show Data"), 0, this);
823 action
->setToggleAction(TRUE
);
824 connect(action
, SIGNAL(toggled(bool)),
825 parent(), SLOT(setShowData(bool)));
826 connect(parent(), SIGNAL(showDataChanged(bool)),
827 action
, SLOT(setOn(bool)));
828 action
->setOn(showData
);
829 action
->addTo(headerPopup
);
831 headerPopup
->exec(e
->globalPos());
837 ConfigView
* ConfigView::viewList
;
839 ConfigView::ConfigView(QWidget
* parent
, const char *name
)
840 : Parent(parent
, name
)
842 list
= new ConfigList(this, name
);
843 lineEdit
= new ConfigLineEdit(this);
846 this->nextView
= viewList
;
850 ConfigView::~ConfigView(void)
854 for (vp
= &viewList
; *vp
; vp
= &(*vp
)->nextView
) {
862 void ConfigView::setShowAll(bool b
)
864 if (list
->showAll
!= b
) {
866 list
->updateListAll();
867 emit
showAllChanged(b
);
871 void ConfigView::setShowName(bool b
)
873 if (list
->showName
!= b
) {
876 emit
showNameChanged(b
);
880 void ConfigView::setShowRange(bool b
)
882 if (list
->showRange
!= b
) {
885 emit
showRangeChanged(b
);
889 void ConfigView::setShowData(bool b
)
891 if (list
->showData
!= b
) {
894 emit
showDataChanged(b
);
898 void ConfigList::setAllOpen(bool open
)
900 QListViewItemIterator
it(this);
902 for (; it
.current(); it
++)
903 it
.current()->setOpen(open
);
906 void ConfigView::updateList(ConfigItem
* item
)
910 for (v
= viewList
; v
; v
= v
->nextView
)
911 v
->list
->updateList(item
);
914 void ConfigView::updateListAll(void)
918 for (v
= viewList
; v
; v
= v
->nextView
)
919 v
->list
->updateListAll();
922 ConfigInfoView::ConfigInfoView(QWidget
* parent
, const char *name
)
923 : Parent(parent
, name
), menu(0), sym(0)
926 configSettings
->beginGroup(name
);
927 _showDebug
= configSettings
->readBoolEntry("/showDebug", false);
928 configSettings
->endGroup();
929 connect(configApp
, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
933 void ConfigInfoView::saveSettings(void)
936 configSettings
->beginGroup(name());
937 configSettings
->writeEntry("/showDebug", showDebug());
938 configSettings
->endGroup();
942 void ConfigInfoView::setShowDebug(bool b
)
944 if (_showDebug
!= b
) {
950 emit
showDebugChanged(b
);
954 void ConfigInfoView::setInfo(struct menu
*m
)
966 void ConfigInfoView::setSource(const QString
& name
)
968 const char *p
= name
.latin1();
977 if (sscanf(p
, "m%p", &m
) == 1 && menu
!= m
) {
980 emit
menuSelected(menu
);
986 if (sscanf(p
, "s%p", &s
) == 1 && sym
!= s
) {
994 void ConfigInfoView::symbolInfo(void)
998 str
+= "<big>Symbol: <b>";
999 str
+= print_filter(sym
->name
);
1000 str
+= "</b></big><br><br>value: ";
1001 str
+= print_filter(sym_get_string_value(sym
));
1002 str
+= "<br>visibility: ";
1003 str
+= sym
->visible
== yes
? "y" : sym
->visible
== mod
? "m" : "n";
1005 str
+= debug_info(sym
);
1010 void ConfigInfoView::menuInfo(void)
1013 QString head
, debug
, help
;
1019 head
+= print_filter(_(menu
->prompt
->text
));
1020 head
+= "</b></big>";
1024 head
+= QString().sprintf("<a href=\"s%p\">", sym
);
1025 head
+= print_filter(sym
->name
);
1030 } else if (sym
->name
) {
1033 head
+= QString().sprintf("<a href=\"s%p\">", sym
);
1034 head
+= print_filter(sym
->name
);
1037 head
+= "</b></big>";
1042 debug
= debug_info(sym
);
1044 help
= menu_get_help(menu
);
1045 /* Gettextize if the help text not empty */
1047 help
= print_filter(menu_get_help(menu
));
1049 help
= print_filter(_(menu_get_help(menu
)));
1050 } else if (menu
->prompt
) {
1052 head
+= print_filter(_(menu
->prompt
->text
));
1053 head
+= "</b></big><br><br>";
1055 if (menu
->prompt
->visible
.expr
) {
1056 debug
+= " dep: ";
1057 expr_print(menu
->prompt
->visible
.expr
, expr_print_help
, &debug
, E_NONE
);
1058 debug
+= "<br><br>";
1063 debug
+= QString().sprintf("defined at %s:%d<br><br>", menu
->file
->name
, menu
->lineno
);
1065 setText(head
+ debug
+ help
);
1068 QString
ConfigInfoView::debug_info(struct symbol
*sym
)
1073 debug
+= print_filter(sym_type_name(sym
->type
));
1074 if (sym_is_choice(sym
))
1075 debug
+= " (choice)";
1077 if (sym
->rev_dep
.expr
) {
1078 debug
+= "reverse dep: ";
1079 expr_print(sym
->rev_dep
.expr
, expr_print_help
, &debug
, E_NONE
);
1082 for (struct property
*prop
= sym
->prop
; prop
; prop
= prop
->next
) {
1083 switch (prop
->type
) {
1086 debug
+= QString().sprintf("prompt: <a href=\"m%p\">", prop
->menu
);
1087 debug
+= print_filter(_(prop
->text
));
1088 debug
+= "</a><br>";
1094 debug
+= prop_get_type_name(prop
->type
);
1096 expr_print(prop
->expr
, expr_print_help
, &debug
, E_NONE
);
1100 if (sym_is_choice(sym
)) {
1101 debug
+= "choice: ";
1102 expr_print(prop
->expr
, expr_print_help
, &debug
, E_NONE
);
1107 debug
+= "unknown property: ";
1108 debug
+= prop_get_type_name(prop
->type
);
1111 if (prop
->visible
.expr
) {
1112 debug
+= " dep: ";
1113 expr_print(prop
->visible
.expr
, expr_print_help
, &debug
, E_NONE
);
1122 QString
ConfigInfoView::print_filter(const QString
&str
)
1124 QRegExp
re("[<>&\"\\n]");
1126 for (int i
= 0; (i
= res
.find(re
, i
)) >= 0;) {
1127 switch (res
[i
].latin1()) {
1129 res
.replace(i
, 1, "<");
1133 res
.replace(i
, 1, ">");
1137 res
.replace(i
, 1, "&");
1141 res
.replace(i
, 1, """);
1145 res
.replace(i
, 1, "<br>");
1153 void ConfigInfoView::expr_print_help(void *data
, struct symbol
*sym
, const char *str
)
1155 QString
* text
= reinterpret_cast<QString
*>(data
);
1156 QString str2
= print_filter(str
);
1158 if (sym
&& sym
->name
&& !(sym
->flags
& SYMBOL_CONST
)) {
1159 *text
+= QString().sprintf("<a href=\"s%p\">", sym
);
1166 QPopupMenu
* ConfigInfoView::createPopupMenu(const QPoint
& pos
)
1168 QPopupMenu
* popup
= Parent::createPopupMenu(pos
);
1169 QAction
* action
= new QAction(NULL
, _("Show Debug Info"), 0, popup
);
1170 action
->setToggleAction(TRUE
);
1171 connect(action
, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1172 connect(this, SIGNAL(showDebugChanged(bool)), action
, SLOT(setOn(bool)));
1173 action
->setOn(showDebug());
1174 popup
->insertSeparator();
1175 action
->addTo(popup
);
1179 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent
*e
)
1181 Parent::contentsContextMenuEvent(e
);
1184 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow
* parent
, const char *name
)
1185 : Parent(parent
, name
), result(NULL
)
1187 setCaption("Search Config");
1189 QVBoxLayout
* layout1
= new QVBoxLayout(this, 11, 6);
1190 QHBoxLayout
* layout2
= new QHBoxLayout(0, 0, 6);
1191 layout2
->addWidget(new QLabel(_("Find:"), this));
1192 editField
= new QLineEdit(this);
1193 connect(editField
, SIGNAL(returnPressed()), SLOT(search()));
1194 layout2
->addWidget(editField
);
1195 searchButton
= new QPushButton(_("Search"), this);
1196 searchButton
->setAutoDefault(FALSE
);
1197 connect(searchButton
, SIGNAL(clicked()), SLOT(search()));
1198 layout2
->addWidget(searchButton
);
1199 layout1
->addLayout(layout2
);
1201 split
= new QSplitter(this);
1202 split
->setOrientation(QSplitter::Vertical
);
1203 list
= new ConfigView(split
, name
);
1204 list
->list
->mode
= listMode
;
1205 info
= new ConfigInfoView(split
, name
);
1206 connect(list
->list
, SIGNAL(menuChanged(struct menu
*)),
1207 info
, SLOT(setInfo(struct menu
*)));
1208 connect(list
->list
, SIGNAL(menuChanged(struct menu
*)),
1209 parent
, SLOT(setMenuLink(struct menu
*)));
1211 layout1
->addWidget(split
);
1214 int x
, y
, width
, height
;
1217 configSettings
->beginGroup(name
);
1218 width
= configSettings
->readNumEntry("/window width", parent
->width() / 2);
1219 height
= configSettings
->readNumEntry("/window height", parent
->height() / 2);
1220 resize(width
, height
);
1221 x
= configSettings
->readNumEntry("/window x", 0, &ok
);
1223 y
= configSettings
->readNumEntry("/window y", 0, &ok
);
1226 QValueList
<int> sizes
= configSettings
->readSizes("/split", &ok
);
1228 split
->setSizes(sizes
);
1229 configSettings
->endGroup();
1230 connect(configApp
, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1234 void ConfigSearchWindow::saveSettings(void)
1237 configSettings
->beginGroup(name());
1238 configSettings
->writeEntry("/window x", pos().x());
1239 configSettings
->writeEntry("/window y", pos().y());
1240 configSettings
->writeEntry("/window width", size().width());
1241 configSettings
->writeEntry("/window height", size().height());
1242 configSettings
->writeSizes("/split", split
->sizes());
1243 configSettings
->endGroup();
1247 void ConfigSearchWindow::search(void)
1250 struct property
*prop
;
1251 ConfigItem
*lastItem
= NULL
;
1254 list
->list
->clear();
1257 result
= sym_re_search(editField
->text().latin1());
1260 for (p
= result
; *p
; p
++) {
1261 for_all_prompts((*p
), prop
)
1262 lastItem
= new ConfigItem(list
->list
, lastItem
, prop
->menu
,
1263 menu_is_visible(prop
->menu
));
1268 * Construct the complete config widget
1270 ConfigMainWindow::ConfigMainWindow(void)
1275 int x
, y
, width
, height
;
1278 QWidget
*d
= configApp
->desktop();
1279 snprintf(title
, sizeof(title
), _("Linux Kernel v%s Configuration"),
1280 getenv("KERNELVERSION"));
1283 width
= configSettings
->readNumEntry("/window width", d
->width() - 64);
1284 height
= configSettings
->readNumEntry("/window height", d
->height() - 64);
1285 resize(width
, height
);
1286 x
= configSettings
->readNumEntry("/window x", 0, &ok
);
1288 y
= configSettings
->readNumEntry("/window y", 0, &ok
);
1292 split1
= new QSplitter(this);
1293 split1
->setOrientation(QSplitter::Horizontal
);
1294 setCentralWidget(split1
);
1296 menuView
= new ConfigView(split1
, "menu");
1297 menuList
= menuView
->list
;
1299 split2
= new QSplitter(split1
);
1300 split2
->setOrientation(QSplitter::Vertical
);
1302 // create config tree
1303 configView
= new ConfigView(split2
, "config");
1304 configList
= configView
->list
;
1306 helpText
= new ConfigInfoView(split2
, "help");
1307 helpText
->setTextFormat(Qt::RichText
);
1309 setTabOrder(configList
, helpText
);
1310 configList
->setFocus();
1313 toolBar
= new QToolBar("Tools", this);
1315 backAction
= new QAction("Back", QPixmap(xpm_back
), _("Back"), 0, this);
1316 connect(backAction
, SIGNAL(activated()), SLOT(goBack()));
1317 backAction
->setEnabled(FALSE
);
1318 QAction
*quitAction
= new QAction("Quit", _("&Quit"), CTRL
+Key_Q
, this);
1319 connect(quitAction
, SIGNAL(activated()), SLOT(close()));
1320 QAction
*loadAction
= new QAction("Load", QPixmap(xpm_load
), _("&Load"), CTRL
+Key_L
, this);
1321 connect(loadAction
, SIGNAL(activated()), SLOT(loadConfig()));
1322 saveAction
= new QAction("Save", QPixmap(xpm_save
), _("&Save"), CTRL
+Key_S
, this);
1323 connect(saveAction
, SIGNAL(activated()), SLOT(saveConfig()));
1324 conf_set_changed_callback(conf_changed
);
1325 // Set saveAction's initial state
1327 QAction
*saveAsAction
= new QAction("Save As...", _("Save &As..."), 0, this);
1328 connect(saveAsAction
, SIGNAL(activated()), SLOT(saveConfigAs()));
1329 QAction
*searchAction
= new QAction("Find", _("&Find"), CTRL
+Key_F
, this);
1330 connect(searchAction
, SIGNAL(activated()), SLOT(searchConfig()));
1331 QAction
*singleViewAction
= new QAction("Single View", QPixmap(xpm_single_view
), _("Single View"), 0, this);
1332 connect(singleViewAction
, SIGNAL(activated()), SLOT(showSingleView()));
1333 QAction
*splitViewAction
= new QAction("Split View", QPixmap(xpm_split_view
), _("Split View"), 0, this);
1334 connect(splitViewAction
, SIGNAL(activated()), SLOT(showSplitView()));
1335 QAction
*fullViewAction
= new QAction("Full View", QPixmap(xpm_tree_view
), _("Full View"), 0, this);
1336 connect(fullViewAction
, SIGNAL(activated()), SLOT(showFullView()));
1338 QAction
*showNameAction
= new QAction(NULL
, _("Show Name"), 0, this);
1339 showNameAction
->setToggleAction(TRUE
);
1340 connect(showNameAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowName(bool)));
1341 connect(configView
, SIGNAL(showNameChanged(bool)), showNameAction
, SLOT(setOn(bool)));
1342 showNameAction
->setOn(configView
->showName());
1343 QAction
*showRangeAction
= new QAction(NULL
, _("Show Range"), 0, this);
1344 showRangeAction
->setToggleAction(TRUE
);
1345 connect(showRangeAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowRange(bool)));
1346 connect(configView
, SIGNAL(showRangeChanged(bool)), showRangeAction
, SLOT(setOn(bool)));
1347 showRangeAction
->setOn(configList
->showRange
);
1348 QAction
*showDataAction
= new QAction(NULL
, _("Show Data"), 0, this);
1349 showDataAction
->setToggleAction(TRUE
);
1350 connect(showDataAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowData(bool)));
1351 connect(configView
, SIGNAL(showDataChanged(bool)), showDataAction
, SLOT(setOn(bool)));
1352 showDataAction
->setOn(configList
->showData
);
1353 QAction
*showAllAction
= new QAction(NULL
, _("Show All Options"), 0, this);
1354 showAllAction
->setToggleAction(TRUE
);
1355 connect(showAllAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowAll(bool)));
1356 connect(showAllAction
, SIGNAL(toggled(bool)), menuView
, SLOT(setShowAll(bool)));
1357 showAllAction
->setOn(configList
->showAll
);
1358 QAction
*showDebugAction
= new QAction(NULL
, _("Show Debug Info"), 0, this);
1359 showDebugAction
->setToggleAction(TRUE
);
1360 connect(showDebugAction
, SIGNAL(toggled(bool)), helpText
, SLOT(setShowDebug(bool)));
1361 connect(helpText
, SIGNAL(showDebugChanged(bool)), showDebugAction
, SLOT(setOn(bool)));
1362 showDebugAction
->setOn(helpText
->showDebug());
1364 QAction
*showIntroAction
= new QAction(NULL
, _("Introduction"), 0, this);
1365 connect(showIntroAction
, SIGNAL(activated()), SLOT(showIntro()));
1366 QAction
*showAboutAction
= new QAction(NULL
, _("About"), 0, this);
1367 connect(showAboutAction
, SIGNAL(activated()), SLOT(showAbout()));
1370 backAction
->addTo(toolBar
);
1371 toolBar
->addSeparator();
1372 loadAction
->addTo(toolBar
);
1373 saveAction
->addTo(toolBar
);
1374 toolBar
->addSeparator();
1375 singleViewAction
->addTo(toolBar
);
1376 splitViewAction
->addTo(toolBar
);
1377 fullViewAction
->addTo(toolBar
);
1379 // create config menu
1380 QPopupMenu
* config
= new QPopupMenu(this);
1381 menu
->insertItem(_("&File"), config
);
1382 loadAction
->addTo(config
);
1383 saveAction
->addTo(config
);
1384 saveAsAction
->addTo(config
);
1385 config
->insertSeparator();
1386 quitAction
->addTo(config
);
1389 QPopupMenu
* editMenu
= new QPopupMenu(this);
1390 menu
->insertItem(_("&Edit"), editMenu
);
1391 searchAction
->addTo(editMenu
);
1393 // create options menu
1394 QPopupMenu
* optionMenu
= new QPopupMenu(this);
1395 menu
->insertItem(_("&Option"), optionMenu
);
1396 showNameAction
->addTo(optionMenu
);
1397 showRangeAction
->addTo(optionMenu
);
1398 showDataAction
->addTo(optionMenu
);
1399 optionMenu
->insertSeparator();
1400 showAllAction
->addTo(optionMenu
);
1401 showDebugAction
->addTo(optionMenu
);
1404 QPopupMenu
* helpMenu
= new QPopupMenu(this);
1405 menu
->insertSeparator();
1406 menu
->insertItem(_("&Help"), helpMenu
);
1407 showIntroAction
->addTo(helpMenu
);
1408 showAboutAction
->addTo(helpMenu
);
1410 connect(configList
, SIGNAL(menuChanged(struct menu
*)),
1411 helpText
, SLOT(setInfo(struct menu
*)));
1412 connect(configList
, SIGNAL(menuSelected(struct menu
*)),
1413 SLOT(changeMenu(struct menu
*)));
1414 connect(configList
, SIGNAL(parentSelected()),
1416 connect(menuList
, SIGNAL(menuChanged(struct menu
*)),
1417 helpText
, SLOT(setInfo(struct menu
*)));
1418 connect(menuList
, SIGNAL(menuSelected(struct menu
*)),
1419 SLOT(changeMenu(struct menu
*)));
1421 connect(configList
, SIGNAL(gotFocus(struct menu
*)),
1422 helpText
, SLOT(setInfo(struct menu
*)));
1423 connect(menuList
, SIGNAL(gotFocus(struct menu
*)),
1424 helpText
, SLOT(setInfo(struct menu
*)));
1425 connect(menuList
, SIGNAL(gotFocus(struct menu
*)),
1426 SLOT(listFocusChanged(void)));
1427 connect(helpText
, SIGNAL(menuSelected(struct menu
*)),
1428 SLOT(setMenuLink(struct menu
*)));
1430 QString listMode
= configSettings
->readEntry("/listMode", "symbol");
1431 if (listMode
== "single")
1433 else if (listMode
== "full")
1435 else /*if (listMode == "split")*/
1438 // UI setup done, restore splitter positions
1439 QValueList
<int> sizes
= configSettings
->readSizes("/split1", &ok
);
1441 split1
->setSizes(sizes
);
1443 sizes
= configSettings
->readSizes("/split2", &ok
);
1445 split2
->setSizes(sizes
);
1448 void ConfigMainWindow::loadConfig(void)
1450 QString s
= QFileDialog::getOpenFileName(".config", NULL
, this);
1453 if (conf_read(QFile::encodeName(s
)))
1454 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1455 ConfigView::updateListAll();
1458 void ConfigMainWindow::saveConfig(void)
1460 if (conf_write(NULL
))
1461 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1464 void ConfigMainWindow::saveConfigAs(void)
1466 QString s
= QFileDialog::getSaveFileName(".config", NULL
, this);
1469 if (conf_write(QFile::encodeName(s
)))
1470 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
1473 void ConfigMainWindow::searchConfig(void)
1476 searchWindow
= new ConfigSearchWindow(this, "search");
1477 searchWindow
->show();
1480 void ConfigMainWindow::changeMenu(struct menu
*menu
)
1482 configList
->setRootMenu(menu
);
1483 if (configList
->rootEntry
->parent
== &rootmenu
)
1484 backAction
->setEnabled(FALSE
);
1486 backAction
->setEnabled(TRUE
);
1489 void ConfigMainWindow::setMenuLink(struct menu
*menu
)
1491 struct menu
*parent
;
1492 ConfigList
* list
= NULL
;
1495 if (!menu_is_visible(menu
) && !configView
->showAll())
1498 switch (configList
->mode
) {
1501 parent
= menu_get_parent_menu(menu
);
1504 list
->setRootMenu(parent
);
1507 if (menu
->flags
& MENU_ROOT
) {
1508 configList
->setRootMenu(menu
);
1509 configList
->clearSelection();
1513 parent
= menu_get_parent_menu(menu
->parent
);
1516 item
= menuList
->findConfigItem(parent
);
1518 menuList
->setSelected(item
, TRUE
);
1519 menuList
->ensureItemVisible(item
);
1521 list
->setRootMenu(parent
);
1530 item
= list
->findConfigItem(menu
);
1532 list
->setSelected(item
, TRUE
);
1533 list
->ensureItemVisible(item
);
1539 void ConfigMainWindow::listFocusChanged(void)
1541 if (menuList
->mode
== menuMode
)
1542 configList
->clearSelection();
1545 void ConfigMainWindow::goBack(void)
1549 configList
->setParentMenu();
1550 if (configList
->rootEntry
== &rootmenu
)
1551 backAction
->setEnabled(FALSE
);
1552 item
= (ConfigItem
*)menuList
->selectedItem();
1554 if (item
->menu
== configList
->rootEntry
) {
1555 menuList
->setSelected(item
, TRUE
);
1558 item
= (ConfigItem
*)item
->parent();
1562 void ConfigMainWindow::showSingleView(void)
1565 menuList
->setRootMenu(0);
1566 configList
->mode
= singleMode
;
1567 if (configList
->rootEntry
== &rootmenu
)
1568 configList
->updateListAll();
1570 configList
->setRootMenu(&rootmenu
);
1571 configList
->setAllOpen(TRUE
);
1572 configList
->setFocus();
1575 void ConfigMainWindow::showSplitView(void)
1577 configList
->mode
= symbolMode
;
1578 if (configList
->rootEntry
== &rootmenu
)
1579 configList
->updateListAll();
1581 configList
->setRootMenu(&rootmenu
);
1582 configList
->setAllOpen(TRUE
);
1583 configApp
->processEvents();
1584 menuList
->mode
= menuMode
;
1585 menuList
->setRootMenu(&rootmenu
);
1586 menuList
->setAllOpen(TRUE
);
1588 menuList
->setFocus();
1591 void ConfigMainWindow::showFullView(void)
1594 menuList
->setRootMenu(0);
1595 configList
->mode
= fullMode
;
1596 if (configList
->rootEntry
== &rootmenu
)
1597 configList
->updateListAll();
1599 configList
->setRootMenu(&rootmenu
);
1600 configList
->setAllOpen(FALSE
);
1601 configList
->setFocus();
1605 * ask for saving configuration before quitting
1606 * TODO ask only when something changed
1608 void ConfigMainWindow::closeEvent(QCloseEvent
* e
)
1610 if (!conf_get_changed()) {
1614 QMessageBox
mb("qconf", _("Save configuration?"), QMessageBox::Warning
,
1615 QMessageBox::Yes
| QMessageBox::Default
, QMessageBox::No
, QMessageBox::Cancel
| QMessageBox::Escape
);
1616 mb
.setButtonText(QMessageBox::Yes
, _("&Save Changes"));
1617 mb
.setButtonText(QMessageBox::No
, _("&Discard Changes"));
1618 mb
.setButtonText(QMessageBox::Cancel
, _("Cancel Exit"));
1619 switch (mb
.exec()) {
1620 case QMessageBox::Yes
:
1622 case QMessageBox::No
:
1625 case QMessageBox::Cancel
:
1631 void ConfigMainWindow::showIntro(void)
1633 static const QString str
= _("Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1634 "For each option, a blank box indicates the feature is disabled, a check\n"
1635 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1636 "as a module. Clicking on the box will cycle through the three states.\n\n"
1637 "If you do not see an option (e.g., a device driver) that you believe\n"
1638 "should be present, try turning on Show All Options under the Options menu.\n"
1639 "Although there is no cross reference yet to help you figure out what other\n"
1640 "options must be enabled to support the option you are interested in, you can\n"
1641 "still view the help of a grayed-out option.\n\n"
1642 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1643 "which you can then match by examining other options.\n\n");
1645 QMessageBox::information(this, "qconf", str
);
1648 void ConfigMainWindow::showAbout(void)
1650 static const QString str
= _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1651 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1653 QMessageBox::information(this, "qconf", str
);
1656 void ConfigMainWindow::saveSettings(void)
1658 configSettings
->writeEntry("/window x", pos().x());
1659 configSettings
->writeEntry("/window y", pos().y());
1660 configSettings
->writeEntry("/window width", size().width());
1661 configSettings
->writeEntry("/window height", size().height());
1664 switch(configList
->mode
) {
1677 configSettings
->writeEntry("/listMode", entry
);
1679 configSettings
->writeSizes("/split1", split1
->sizes());
1680 configSettings
->writeSizes("/split2", split2
->sizes());
1683 void ConfigMainWindow::conf_changed(void)
1686 saveAction
->setEnabled(conf_get_changed());
1689 void fixup_rootmenu(struct menu
*menu
)
1692 static int menu_cnt
= 0;
1694 menu
->flags
|= MENU_ROOT
;
1695 for (child
= menu
->list
; child
; child
= child
->next
) {
1696 if (child
->prompt
&& child
->prompt
->type
== P_MENU
) {
1698 fixup_rootmenu(child
);
1700 } else if (!menu_cnt
)
1701 fixup_rootmenu(child
);
1705 static const char *progname
;
1707 static void usage(void)
1709 printf(_("%s <config>\n"), progname
);
1713 int main(int ac
, char** av
)
1715 ConfigMainWindow
* v
;
1718 bindtextdomain(PACKAGE
, LOCALEDIR
);
1719 textdomain(PACKAGE
);
1721 #ifndef LKC_DIRECT_LINK
1726 configApp
= new QApplication(ac
, av
);
1727 if (ac
> 1 && av
[1][0] == '-') {
1740 fixup_rootmenu(&rootmenu
);
1742 //zconfdump(stdout);
1744 configSettings
= new ConfigSettings();
1745 configSettings
->beginGroup("/kconfig/qconf");
1746 v
= new ConfigMainWindow();
1748 //zconfdump(stdout);
1749 configApp
->setMainWidget(v
);
1750 configApp
->connect(configApp
, SIGNAL(lastWindowClosed()), SLOT(quit()));
1751 configApp
->connect(configApp
, SIGNAL(aboutToQuit()), v
, SLOT(saveSettings()));
1755 configSettings
->endGroup();
1756 delete configSettings
;