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());
96 * update the displayed of a menu entry
98 void ConfigItem::updateMenu(void)
102 struct property
*prop
;
109 setPixmap(promptColIdx
, list
->menuBackPix
);
116 prompt
= QString::fromLocal8Bit(menu_get_prompt(menu
));
118 if (prop
) switch (prop
->type
) {
120 if (list
->mode
== singleMode
|| list
->mode
== symbolMode
) {
121 /* a menuconfig entry is displayed differently
122 * depending whether it's at the view root or a child.
124 if (sym
&& list
->rootEntry
== menu
)
126 setPixmap(promptColIdx
, list
->menuPix
);
130 setPixmap(promptColIdx
, 0);
134 setPixmap(promptColIdx
, 0);
142 setText(nameColIdx
, QString::fromLocal8Bit(sym
->name
));
144 type
= sym_get_type(sym
);
150 if (!sym_is_changable(sym
) && !list
->showAll
) {
151 setPixmap(promptColIdx
, 0);
152 setText(noColIdx
, QString::null
);
153 setText(modColIdx
, QString::null
);
154 setText(yesColIdx
, QString::null
);
157 expr
= sym_get_tristate_value(sym
);
160 if (sym_is_choice_value(sym
) && type
== S_BOOLEAN
)
161 setPixmap(promptColIdx
, list
->choiceYesPix
);
163 setPixmap(promptColIdx
, list
->symbolYesPix
);
164 setText(yesColIdx
, "Y");
168 setPixmap(promptColIdx
, list
->symbolModPix
);
169 setText(modColIdx
, "M");
173 if (sym_is_choice_value(sym
) && type
== S_BOOLEAN
)
174 setPixmap(promptColIdx
, list
->choiceNoPix
);
176 setPixmap(promptColIdx
, list
->symbolNoPix
);
177 setText(noColIdx
, "N");
182 setText(noColIdx
, sym_tristate_within_range(sym
, no
) ? "_" : 0);
184 setText(modColIdx
, sym_tristate_within_range(sym
, mod
) ? "_" : 0);
186 setText(yesColIdx
, sym_tristate_within_range(sym
, yes
) ? "_" : 0);
188 setText(dataColIdx
, QChar(ch
));
195 data
= sym_get_string_value(sym
);
197 #if QT_VERSION >= 300
198 int i
= list
->mapIdx(dataColIdx
);
200 setRenameEnabled(i
, TRUE
);
202 setText(dataColIdx
, data
);
203 if (type
== S_STRING
)
204 prompt
= QString("%1: %2").arg(prompt
).arg(data
);
206 prompt
= QString("(%2) %1").arg(prompt
).arg(data
);
209 if (!sym_has_value(sym
) && visible
)
212 setText(promptColIdx
, prompt
);
215 void ConfigItem::testUpdateMenu(bool v
)
223 sym_calc_value(menu
->sym
);
224 if (menu
->flags
& MENU_CHANGED
) {
225 /* the menu entry changed, so update all list items */
226 menu
->flags
&= ~MENU_CHANGED
;
227 for (i
= (ConfigItem
*)menu
->data
; i
; i
= i
->nextItem
)
229 } else if (listView()->updateAll
)
233 void ConfigItem::paintCell(QPainter
* p
, const QColorGroup
& cg
, int column
, int width
, int align
)
235 ConfigList
* list
= listView();
238 if (isSelected() && !list
->hasFocus() && list
->mode
== menuMode
)
239 Parent::paintCell(p
, list
->inactivedColorGroup
, column
, width
, align
);
241 Parent::paintCell(p
, cg
, column
, width
, align
);
243 Parent::paintCell(p
, list
->disabledColorGroup
, column
, width
, align
);
247 * construct a menu entry
249 void ConfigItem::init(void)
252 ConfigList
* list
= listView();
253 nextItem
= (ConfigItem
*)menu
->data
;
256 if (list
->mode
!= fullMode
)
258 sym_calc_value(menu
->sym
);
264 * destruct a menu entry
266 ConfigItem::~ConfigItem(void)
269 ConfigItem
** ip
= (ConfigItem
**)&menu
->data
;
270 for (; *ip
; ip
= &(*ip
)->nextItem
) {
279 ConfigLineEdit::ConfigLineEdit(ConfigView
* parent
)
282 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
285 void ConfigLineEdit::show(ConfigItem
* i
)
288 if (sym_get_string_value(item
->menu
->sym
))
289 setText(QString::fromLocal8Bit(sym_get_string_value(item
->menu
->sym
)));
291 setText(QString::null
);
296 void ConfigLineEdit::keyPressEvent(QKeyEvent
* e
)
303 sym_set_string_value(item
->menu
->sym
, text().latin1());
304 parent()->updateList(item
);
307 Parent::keyPressEvent(e
);
311 parent()->list
->setFocus();
315 ConfigList::ConfigList(ConfigView
* p
, const char *name
)
318 symbolYesPix(xpm_symbol_yes
), symbolModPix(xpm_symbol_mod
), symbolNoPix(xpm_symbol_no
),
319 choiceYesPix(xpm_choice_yes
), choiceNoPix(xpm_choice_no
),
320 menuPix(xpm_menu
), menuInvPix(xpm_menu_inv
), menuBackPix(xpm_menuback
), voidPix(xpm_void
),
321 showAll(false), showName(false), showRange(false), showData(false),
322 rootEntry(0), headerPopup(0)
327 setRootIsDecorated(TRUE
);
328 disabledColorGroup
= palette().active();
329 disabledColorGroup
.setColor(QColorGroup::Text
, palette().disabled().text());
330 inactivedColorGroup
= palette().active();
331 inactivedColorGroup
.setColor(QColorGroup::Highlight
, palette().disabled().highlight());
333 connect(this, SIGNAL(selectionChanged(void)),
334 SLOT(updateSelection(void)));
337 configSettings
->beginGroup(name
);
338 showAll
= configSettings
->readBoolEntry("/showAll", false);
339 showName
= configSettings
->readBoolEntry("/showName", false);
340 showRange
= configSettings
->readBoolEntry("/showRange", false);
341 showData
= configSettings
->readBoolEntry("/showData", false);
342 configSettings
->endGroup();
343 connect(configApp
, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
346 for (i
= 0; i
< colNr
; i
++)
347 colMap
[i
] = colRevMap
[i
] = -1;
348 addColumn(promptColIdx
, "Option");
353 void ConfigList::reinit(void)
355 removeColumn(dataColIdx
);
356 removeColumn(yesColIdx
);
357 removeColumn(modColIdx
);
358 removeColumn(noColIdx
);
359 removeColumn(nameColIdx
);
362 addColumn(nameColIdx
, "Name");
364 addColumn(noColIdx
, "N");
365 addColumn(modColIdx
, "M");
366 addColumn(yesColIdx
, "Y");
369 addColumn(dataColIdx
, "Value");
374 void ConfigList::saveSettings(void)
377 configSettings
->beginGroup(name());
378 configSettings
->writeEntry("/showName", showName
);
379 configSettings
->writeEntry("/showRange", showRange
);
380 configSettings
->writeEntry("/showData", showData
);
381 configSettings
->writeEntry("/showAll", showAll
);
382 configSettings
->endGroup();
386 ConfigItem
* ConfigList::findConfigItem(struct menu
*menu
)
388 ConfigItem
* item
= (ConfigItem
*)menu
->data
;
390 for (; item
; item
= item
->nextItem
) {
391 if (this == item
->listView())
398 void ConfigList::updateSelection(void)
403 ConfigItem
* item
= (ConfigItem
*)selectedItem();
408 emit
menuChanged(menu
);
411 type
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
412 if (mode
== menuMode
&& type
== P_MENU
)
413 emit
menuSelected(menu
);
416 void ConfigList::updateList(ConfigItem
* item
)
418 ConfigItem
* last
= 0;
421 if (mode
!= listMode
)
423 QListViewItemIterator
it(this);
426 for (; it
.current(); ++it
) {
427 item
= (ConfigItem
*)it
.current();
430 item
->testUpdateMenu(menu_is_visible(item
->menu
));
435 if (rootEntry
!= &rootmenu
&& (mode
== singleMode
||
436 (mode
== symbolMode
&& rootEntry
->parent
!= &rootmenu
))) {
439 item
= new ConfigItem(this, 0, true);
442 if ((mode
== singleMode
|| (mode
== symbolMode
&& !(rootEntry
->flags
& MENU_ROOT
))) &&
443 rootEntry
->sym
&& rootEntry
->prompt
) {
444 item
= last
? last
->nextSibling() : firstChild();
446 item
= new ConfigItem(this, last
, rootEntry
, true);
448 item
->testUpdateMenu(true);
450 updateMenuList(item
, rootEntry
);
455 updateMenuList(this, rootEntry
);
459 void ConfigList::setValue(ConfigItem
* item
, tristate val
)
465 sym
= item
->menu
? item
->menu
->sym
: 0;
469 type
= sym_get_type(sym
);
473 oldval
= sym_get_tristate_value(sym
);
475 if (!sym_set_tristate_value(sym
, val
))
477 if (oldval
== no
&& item
->menu
->list
)
479 parent()->updateList(item
);
484 void ConfigList::changeValue(ConfigItem
* item
)
488 int type
, oldexpr
, newexpr
;
495 if (item
->menu
->list
)
496 item
->setOpen(!item
->isOpen());
500 type
= sym_get_type(sym
);
504 oldexpr
= sym_get_tristate_value(sym
);
505 newexpr
= sym_toggle_tristate_value(sym
);
506 if (item
->menu
->list
) {
507 if (oldexpr
== newexpr
)
508 item
->setOpen(!item
->isOpen());
509 else if (oldexpr
== no
)
512 if (oldexpr
!= newexpr
)
513 parent()->updateList(item
);
518 #if QT_VERSION >= 300
519 if (colMap
[dataColIdx
] >= 0)
520 item
->startRename(colMap
[dataColIdx
]);
523 parent()->lineEdit
->show(item
);
528 void ConfigList::setRootMenu(struct menu
*menu
)
532 if (rootEntry
== menu
)
534 type
= menu
&& menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
537 updateMenuList(this, 0);
540 setSelected(currentItem(), hasFocus());
541 ensureItemVisible(currentItem());
544 void ConfigList::setParentMenu(void)
547 struct menu
*oldroot
;
550 if (rootEntry
== &rootmenu
)
552 setRootMenu(menu_get_parent_menu(rootEntry
->parent
));
554 QListViewItemIterator
it(this);
555 for (; (item
= (ConfigItem
*)it
.current()); it
++) {
556 if (item
->menu
== oldroot
) {
557 setCurrentItem(item
);
558 ensureItemVisible(item
);
565 * update all the children of a menu entry
566 * removes/adds the entries from the parent widget as necessary
568 * parent: either the menu list widget or a menu entry widget
569 * menu: entry to be updated
572 void ConfigList::updateMenuList(P
* parent
, struct menu
* menu
)
581 while ((item
= parent
->firstChild()))
586 last
= parent
->firstChild();
587 if (last
&& !last
->goParent
)
589 for (child
= menu
->list
; child
; child
= child
->next
) {
590 item
= last
? last
->nextSibling() : parent
->firstChild();
591 type
= child
->prompt
? child
->prompt
->type
: P_UNKNOWN
;
595 if (!(child
->flags
& MENU_ROOT
))
599 if (child
->flags
& MENU_ROOT
)
606 visible
= menu_is_visible(child
);
607 if (showAll
|| visible
) {
608 if (!item
|| item
->menu
!= child
)
609 item
= new ConfigItem(parent
, last
, child
, visible
);
611 item
->testUpdateMenu(visible
);
613 if (mode
== fullMode
|| mode
== menuMode
|| type
!= P_MENU
)
614 updateMenuList(item
, child
);
616 updateMenuList(item
, 0);
621 if (item
&& item
->menu
== child
) {
622 last
= parent
->firstChild();
625 else while (last
->nextSibling() != item
)
626 last
= last
->nextSibling();
632 void ConfigList::keyPressEvent(QKeyEvent
* ev
)
634 QListViewItem
* i
= currentItem();
639 if (ev
->key() == Key_Escape
&& mode
!= fullMode
&& mode
!= listMode
) {
640 emit
parentSelected();
646 Parent::keyPressEvent(ev
);
649 item
= (ConfigItem
*)i
;
654 if (item
->goParent
) {
655 emit
parentSelected();
661 type
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
662 if (type
== P_MENU
&& rootEntry
!= menu
&&
663 mode
!= fullMode
&& mode
!= menuMode
) {
664 emit
menuSelected(menu
);
680 Parent::keyPressEvent(ev
);
686 void ConfigList::contentsMousePressEvent(QMouseEvent
* e
)
688 //QPoint p(contentsToViewport(e->pos()));
689 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
690 Parent::contentsMousePressEvent(e
);
693 void ConfigList::contentsMouseReleaseEvent(QMouseEvent
* e
)
695 QPoint
p(contentsToViewport(e
->pos()));
696 ConfigItem
* item
= (ConfigItem
*)itemAt(p
);
698 enum prop_type ptype
;
706 x
= header()->offset() + p
.x();
707 idx
= colRevMap
[header()->sectionAt(x
)];
710 pm
= item
->pixmap(promptColIdx
);
712 int off
= header()->sectionPos(0) + itemMargin() +
713 treeStepSize() * (item
->depth() + (rootIsDecorated() ? 1 : 0));
714 if (x
>= off
&& x
< off
+ pm
->width()) {
715 if (item
->goParent
) {
716 emit
parentSelected();
720 ptype
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
721 if (ptype
== P_MENU
&& rootEntry
!= menu
&&
722 mode
!= fullMode
&& mode
!= menuMode
)
723 emit
menuSelected(menu
);
744 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
745 Parent::contentsMouseReleaseEvent(e
);
748 void ConfigList::contentsMouseMoveEvent(QMouseEvent
* e
)
750 //QPoint p(contentsToViewport(e->pos()));
751 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
752 Parent::contentsMouseMoveEvent(e
);
755 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent
* e
)
757 QPoint
p(contentsToViewport(e
->pos()));
758 ConfigItem
* item
= (ConfigItem
*)itemAt(p
);
760 enum prop_type ptype
;
764 if (item
->goParent
) {
765 emit
parentSelected();
771 ptype
= menu
->prompt
? menu
->prompt
->type
: P_UNKNOWN
;
772 if (ptype
== P_MENU
&& (mode
== singleMode
|| mode
== symbolMode
))
773 emit
menuSelected(menu
);
778 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
779 Parent::contentsMouseDoubleClickEvent(e
);
782 void ConfigList::focusInEvent(QFocusEvent
*e
)
784 struct menu
*menu
= NULL
;
786 Parent::focusInEvent(e
);
788 ConfigItem
* item
= (ConfigItem
*)currentItem();
790 setSelected(item
, TRUE
);
796 void ConfigList::contextMenuEvent(QContextMenuEvent
*e
)
798 if (e
->y() <= header()->geometry().bottom()) {
802 headerPopup
= new QPopupMenu(this);
803 action
= new QAction(NULL
, "Show Name", 0, this);
804 action
->setToggleAction(TRUE
);
805 connect(action
, SIGNAL(toggled(bool)),
806 parent(), SLOT(setShowName(bool)));
807 connect(parent(), SIGNAL(showNameChanged(bool)),
808 action
, SLOT(setOn(bool)));
809 action
->setOn(showName
);
810 action
->addTo(headerPopup
);
811 action
= new QAction(NULL
, "Show Range", 0, this);
812 action
->setToggleAction(TRUE
);
813 connect(action
, SIGNAL(toggled(bool)),
814 parent(), SLOT(setShowRange(bool)));
815 connect(parent(), SIGNAL(showRangeChanged(bool)),
816 action
, SLOT(setOn(bool)));
817 action
->setOn(showRange
);
818 action
->addTo(headerPopup
);
819 action
= new QAction(NULL
, "Show Data", 0, this);
820 action
->setToggleAction(TRUE
);
821 connect(action
, SIGNAL(toggled(bool)),
822 parent(), SLOT(setShowData(bool)));
823 connect(parent(), SIGNAL(showDataChanged(bool)),
824 action
, SLOT(setOn(bool)));
825 action
->setOn(showData
);
826 action
->addTo(headerPopup
);
828 headerPopup
->exec(e
->globalPos());
834 ConfigView
* ConfigView::viewList
;
836 ConfigView::ConfigView(QWidget
* parent
, const char *name
)
837 : Parent(parent
, name
)
839 list
= new ConfigList(this, name
);
840 lineEdit
= new ConfigLineEdit(this);
843 this->nextView
= viewList
;
847 ConfigView::~ConfigView(void)
851 for (vp
= &viewList
; *vp
; vp
= &(*vp
)->nextView
) {
859 void ConfigView::setShowAll(bool b
)
861 if (list
->showAll
!= b
) {
863 list
->updateListAll();
864 emit
showAllChanged(b
);
868 void ConfigView::setShowName(bool b
)
870 if (list
->showName
!= b
) {
873 emit
showNameChanged(b
);
877 void ConfigView::setShowRange(bool b
)
879 if (list
->showRange
!= b
) {
882 emit
showRangeChanged(b
);
886 void ConfigView::setShowData(bool b
)
888 if (list
->showData
!= b
) {
891 emit
showDataChanged(b
);
895 void ConfigList::setAllOpen(bool open
)
897 QListViewItemIterator
it(this);
899 for (; it
.current(); it
++)
900 it
.current()->setOpen(open
);
903 void ConfigView::updateList(ConfigItem
* item
)
907 for (v
= viewList
; v
; v
= v
->nextView
)
908 v
->list
->updateList(item
);
911 void ConfigView::updateListAll(void)
915 for (v
= viewList
; v
; v
= v
->nextView
)
916 v
->list
->updateListAll();
919 ConfigInfoView::ConfigInfoView(QWidget
* parent
, const char *name
)
920 : Parent(parent
, name
), menu(0)
923 configSettings
->beginGroup(name
);
924 _showDebug
= configSettings
->readBoolEntry("/showDebug", false);
925 configSettings
->endGroup();
926 connect(configApp
, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
930 void ConfigInfoView::saveSettings(void)
933 configSettings
->beginGroup(name());
934 configSettings
->writeEntry("/showDebug", showDebug());
935 configSettings
->endGroup();
939 void ConfigInfoView::setShowDebug(bool b
)
941 if (_showDebug
!= b
) {
947 emit
showDebugChanged(b
);
951 void ConfigInfoView::setInfo(struct menu
*m
)
962 void ConfigInfoView::setSource(const QString
& name
)
964 const char *p
= name
.latin1();
973 if (sscanf(p
, "m%p", &m
) == 1 && menu
!= m
) {
976 emit
menuSelected(menu
);
982 if (sscanf(p
, "s%p", &s
) == 1 && sym
!= s
) {
990 void ConfigInfoView::symbolInfo(void)
994 str
+= "<big>Symbol: <b>";
995 str
+= print_filter(sym
->name
);
996 str
+= "</b></big><br><br>value: ";
997 str
+= print_filter(sym_get_string_value(sym
));
998 str
+= "<br>visibility: ";
999 str
+= sym
->visible
== yes
? "y" : sym
->visible
== mod
? "m" : "n";
1001 str
+= debug_info(sym
);
1006 void ConfigInfoView::menuInfo(void)
1009 QString head
, debug
, help
;
1015 head
+= print_filter(_(menu
->prompt
->text
));
1016 head
+= "</b></big>";
1020 head
+= QString().sprintf("<a href=\"s%p\">", sym
);
1021 head
+= print_filter(sym
->name
);
1026 } else if (sym
->name
) {
1029 head
+= QString().sprintf("<a href=\"s%p\">", sym
);
1030 head
+= print_filter(sym
->name
);
1033 head
+= "</b></big>";
1038 debug
= debug_info(sym
);
1040 help
= print_filter(_(sym
->help
));
1041 } else if (menu
->prompt
) {
1043 head
+= print_filter(_(menu
->prompt
->text
));
1044 head
+= "</b></big><br><br>";
1046 if (menu
->prompt
->visible
.expr
) {
1047 debug
+= " dep: ";
1048 expr_print(menu
->prompt
->visible
.expr
, expr_print_help
, &debug
, E_NONE
);
1049 debug
+= "<br><br>";
1054 debug
+= QString().sprintf("defined at %s:%d<br><br>", menu
->file
->name
, menu
->lineno
);
1056 setText(head
+ debug
+ help
);
1059 QString
ConfigInfoView::debug_info(struct symbol
*sym
)
1064 debug
+= print_filter(sym_type_name(sym
->type
));
1065 if (sym_is_choice(sym
))
1066 debug
+= " (choice)";
1068 if (sym
->rev_dep
.expr
) {
1069 debug
+= "reverse dep: ";
1070 expr_print(sym
->rev_dep
.expr
, expr_print_help
, &debug
, E_NONE
);
1073 for (struct property
*prop
= sym
->prop
; prop
; prop
= prop
->next
) {
1074 switch (prop
->type
) {
1077 debug
+= QString().sprintf("prompt: <a href=\"m%p\">", prop
->menu
);
1078 debug
+= print_filter(_(prop
->text
));
1079 debug
+= "</a><br>";
1082 debug
+= "default: ";
1083 expr_print(prop
->expr
, expr_print_help
, &debug
, E_NONE
);
1087 if (sym_is_choice(sym
)) {
1088 debug
+= "choice: ";
1089 expr_print(prop
->expr
, expr_print_help
, &debug
, E_NONE
);
1094 debug
+= "select: ";
1095 expr_print(prop
->expr
, expr_print_help
, &debug
, E_NONE
);
1100 expr_print(prop
->expr
, expr_print_help
, &debug
, E_NONE
);
1104 debug
+= "unknown property: ";
1105 debug
+= prop_get_type_name(prop
->type
);
1108 if (prop
->visible
.expr
) {
1109 debug
+= " dep: ";
1110 expr_print(prop
->visible
.expr
, expr_print_help
, &debug
, E_NONE
);
1119 QString
ConfigInfoView::print_filter(const QString
&str
)
1121 QRegExp
re("[<>&\"\\n]");
1123 for (int i
= 0; (i
= res
.find(re
, i
)) >= 0;) {
1124 switch (res
[i
].latin1()) {
1126 res
.replace(i
, 1, "<");
1130 res
.replace(i
, 1, ">");
1134 res
.replace(i
, 1, "&");
1138 res
.replace(i
, 1, """);
1142 res
.replace(i
, 1, "<br>");
1150 void ConfigInfoView::expr_print_help(void *data
, struct symbol
*sym
, const char *str
)
1152 QString
* text
= reinterpret_cast<QString
*>(data
);
1153 QString str2
= print_filter(str
);
1155 if (sym
&& sym
->name
&& !(sym
->flags
& SYMBOL_CONST
)) {
1156 *text
+= QString().sprintf("<a href=\"s%p\">", sym
);
1163 QPopupMenu
* ConfigInfoView::createPopupMenu(const QPoint
& pos
)
1165 QPopupMenu
* popup
= Parent::createPopupMenu(pos
);
1166 QAction
* action
= new QAction(NULL
,"Show Debug Info", 0, popup
);
1167 action
->setToggleAction(TRUE
);
1168 connect(action
, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1169 connect(this, SIGNAL(showDebugChanged(bool)), action
, SLOT(setOn(bool)));
1170 action
->setOn(showDebug());
1171 popup
->insertSeparator();
1172 action
->addTo(popup
);
1176 void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent
*e
)
1178 Parent::contentsContextMenuEvent(e
);
1181 ConfigSearchWindow::ConfigSearchWindow(QWidget
* parent
, const char *name
)
1182 : Parent(parent
, name
), result(NULL
)
1184 setCaption("Search Config");
1186 QVBoxLayout
* layout1
= new QVBoxLayout(this, 11, 6);
1187 QHBoxLayout
* layout2
= new QHBoxLayout(0, 0, 6);
1188 layout2
->addWidget(new QLabel("Find:", this));
1189 editField
= new QLineEdit(this);
1190 connect(editField
, SIGNAL(returnPressed()), SLOT(search()));
1191 layout2
->addWidget(editField
);
1192 searchButton
= new QPushButton("Search", this);
1193 searchButton
->setAutoDefault(FALSE
);
1194 connect(searchButton
, SIGNAL(clicked()), SLOT(search()));
1195 layout2
->addWidget(searchButton
);
1196 layout1
->addLayout(layout2
);
1198 split
= new QSplitter(this);
1199 split
->setOrientation(QSplitter::Vertical
);
1200 list
= new ConfigView(split
, name
);
1201 list
->list
->mode
= listMode
;
1202 info
= new ConfigInfoView(split
, name
);
1203 connect(list
->list
, SIGNAL(menuChanged(struct menu
*)),
1204 info
, SLOT(setInfo(struct menu
*)));
1205 layout1
->addWidget(split
);
1208 int x
, y
, width
, height
;
1211 configSettings
->beginGroup(name
);
1212 width
= configSettings
->readNumEntry("/window width", parent
->width() / 2);
1213 height
= configSettings
->readNumEntry("/window height", parent
->height() / 2);
1214 resize(width
, height
);
1215 x
= configSettings
->readNumEntry("/window x", 0, &ok
);
1217 y
= configSettings
->readNumEntry("/window y", 0, &ok
);
1220 QValueList
<int> sizes
= configSettings
->readSizes("/split", &ok
);
1222 split
->setSizes(sizes
);
1223 configSettings
->endGroup();
1224 connect(configApp
, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1228 void ConfigSearchWindow::saveSettings(void)
1231 configSettings
->beginGroup(name());
1232 configSettings
->writeEntry("/window x", pos().x());
1233 configSettings
->writeEntry("/window y", pos().y());
1234 configSettings
->writeEntry("/window width", size().width());
1235 configSettings
->writeEntry("/window height", size().height());
1236 configSettings
->writeSizes("/split", split
->sizes());
1237 configSettings
->endGroup();
1241 void ConfigSearchWindow::search(void)
1244 struct property
*prop
;
1245 ConfigItem
*lastItem
= NULL
;
1248 list
->list
->clear();
1250 result
= sym_re_search(editField
->text().latin1());
1253 for (p
= result
; *p
; p
++) {
1254 for_all_prompts((*p
), prop
)
1255 lastItem
= new ConfigItem(list
->list
, lastItem
, prop
->menu
,
1256 menu_is_visible(prop
->menu
));
1261 * Construct the complete config widget
1263 ConfigMainWindow::ConfigMainWindow(void)
1268 int x
, y
, width
, height
;
1270 QWidget
*d
= configApp
->desktop();
1272 width
= configSettings
->readNumEntry("/window width", d
->width() - 64);
1273 height
= configSettings
->readNumEntry("/window height", d
->height() - 64);
1274 resize(width
, height
);
1275 x
= configSettings
->readNumEntry("/window x", 0, &ok
);
1277 y
= configSettings
->readNumEntry("/window y", 0, &ok
);
1281 split1
= new QSplitter(this);
1282 split1
->setOrientation(QSplitter::Horizontal
);
1283 setCentralWidget(split1
);
1285 menuView
= new ConfigView(split1
, "menu");
1286 menuList
= menuView
->list
;
1288 split2
= new QSplitter(split1
);
1289 split2
->setOrientation(QSplitter::Vertical
);
1291 // create config tree
1292 configView
= new ConfigView(split2
, "config");
1293 configList
= configView
->list
;
1295 helpText
= new ConfigInfoView(split2
, "help");
1296 helpText
->setTextFormat(Qt::RichText
);
1298 setTabOrder(configList
, helpText
);
1299 configList
->setFocus();
1302 toolBar
= new QToolBar("Tools", this);
1304 backAction
= new QAction("Back", QPixmap(xpm_back
), "Back", 0, this);
1305 connect(backAction
, SIGNAL(activated()), SLOT(goBack()));
1306 backAction
->setEnabled(FALSE
);
1307 QAction
*quitAction
= new QAction("Quit", "&Quit", CTRL
+Key_Q
, this);
1308 connect(quitAction
, SIGNAL(activated()), SLOT(close()));
1309 QAction
*loadAction
= new QAction("Load", QPixmap(xpm_load
), "&Load", CTRL
+Key_L
, this);
1310 connect(loadAction
, SIGNAL(activated()), SLOT(loadConfig()));
1311 saveAction
= new QAction("Save", QPixmap(xpm_save
), "&Save", CTRL
+Key_S
, this);
1312 connect(saveAction
, SIGNAL(activated()), SLOT(saveConfig()));
1313 conf_set_changed_callback(conf_changed
);
1314 // Set saveAction's initial state
1316 QAction
*saveAsAction
= new QAction("Save As...", "Save &As...", 0, this);
1317 connect(saveAsAction
, SIGNAL(activated()), SLOT(saveConfigAs()));
1318 QAction
*searchAction
= new QAction("Search", "&Search", CTRL
+Key_F
, this);
1319 connect(searchAction
, SIGNAL(activated()), SLOT(searchConfig()));
1320 QAction
*singleViewAction
= new QAction("Single View", QPixmap(xpm_single_view
), "Split View", 0, this);
1321 connect(singleViewAction
, SIGNAL(activated()), SLOT(showSingleView()));
1322 QAction
*splitViewAction
= new QAction("Split View", QPixmap(xpm_split_view
), "Split View", 0, this);
1323 connect(splitViewAction
, SIGNAL(activated()), SLOT(showSplitView()));
1324 QAction
*fullViewAction
= new QAction("Full View", QPixmap(xpm_tree_view
), "Full View", 0, this);
1325 connect(fullViewAction
, SIGNAL(activated()), SLOT(showFullView()));
1327 QAction
*showNameAction
= new QAction(NULL
, "Show Name", 0, this);
1328 showNameAction
->setToggleAction(TRUE
);
1329 connect(showNameAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowName(bool)));
1330 connect(configView
, SIGNAL(showNameChanged(bool)), showNameAction
, SLOT(setOn(bool)));
1331 showNameAction
->setOn(configView
->showName());
1332 QAction
*showRangeAction
= new QAction(NULL
, "Show Range", 0, this);
1333 showRangeAction
->setToggleAction(TRUE
);
1334 connect(showRangeAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowRange(bool)));
1335 connect(configView
, SIGNAL(showRangeChanged(bool)), showRangeAction
, SLOT(setOn(bool)));
1336 showRangeAction
->setOn(configList
->showRange
);
1337 QAction
*showDataAction
= new QAction(NULL
, "Show Data", 0, this);
1338 showDataAction
->setToggleAction(TRUE
);
1339 connect(showDataAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowData(bool)));
1340 connect(configView
, SIGNAL(showDataChanged(bool)), showDataAction
, SLOT(setOn(bool)));
1341 showDataAction
->setOn(configList
->showData
);
1342 QAction
*showAllAction
= new QAction(NULL
, "Show All Options", 0, this);
1343 showAllAction
->setToggleAction(TRUE
);
1344 connect(showAllAction
, SIGNAL(toggled(bool)), configView
, SLOT(setShowAll(bool)));
1345 connect(showAllAction
, SIGNAL(toggled(bool)), menuView
, SLOT(setShowAll(bool)));
1346 showAllAction
->setOn(configList
->showAll
);
1347 QAction
*showDebugAction
= new QAction(NULL
, "Show Debug Info", 0, this);
1348 showDebugAction
->setToggleAction(TRUE
);
1349 connect(showDebugAction
, SIGNAL(toggled(bool)), helpText
, SLOT(setShowDebug(bool)));
1350 connect(helpText
, SIGNAL(showDebugChanged(bool)), showDebugAction
, SLOT(setOn(bool)));
1351 showDebugAction
->setOn(helpText
->showDebug());
1353 QAction
*showIntroAction
= new QAction(NULL
, "Introduction", 0, this);
1354 connect(showIntroAction
, SIGNAL(activated()), SLOT(showIntro()));
1355 QAction
*showAboutAction
= new QAction(NULL
, "About", 0, this);
1356 connect(showAboutAction
, SIGNAL(activated()), SLOT(showAbout()));
1359 backAction
->addTo(toolBar
);
1360 toolBar
->addSeparator();
1361 loadAction
->addTo(toolBar
);
1362 saveAction
->addTo(toolBar
);
1363 toolBar
->addSeparator();
1364 singleViewAction
->addTo(toolBar
);
1365 splitViewAction
->addTo(toolBar
);
1366 fullViewAction
->addTo(toolBar
);
1368 // create config menu
1369 QPopupMenu
* config
= new QPopupMenu(this);
1370 menu
->insertItem("&File", config
);
1371 loadAction
->addTo(config
);
1372 saveAction
->addTo(config
);
1373 saveAsAction
->addTo(config
);
1374 config
->insertSeparator();
1375 searchAction
->addTo(config
);
1376 config
->insertSeparator();
1377 quitAction
->addTo(config
);
1379 // create options menu
1380 QPopupMenu
* optionMenu
= new QPopupMenu(this);
1381 menu
->insertItem("&Option", optionMenu
);
1382 showNameAction
->addTo(optionMenu
);
1383 showRangeAction
->addTo(optionMenu
);
1384 showDataAction
->addTo(optionMenu
);
1385 optionMenu
->insertSeparator();
1386 showAllAction
->addTo(optionMenu
);
1387 showDebugAction
->addTo(optionMenu
);
1390 QPopupMenu
* helpMenu
= new QPopupMenu(this);
1391 menu
->insertSeparator();
1392 menu
->insertItem("&Help", helpMenu
);
1393 showIntroAction
->addTo(helpMenu
);
1394 showAboutAction
->addTo(helpMenu
);
1396 connect(configList
, SIGNAL(menuChanged(struct menu
*)),
1397 helpText
, SLOT(setInfo(struct menu
*)));
1398 connect(configList
, SIGNAL(menuSelected(struct menu
*)),
1399 SLOT(changeMenu(struct menu
*)));
1400 connect(configList
, SIGNAL(parentSelected()),
1402 connect(menuList
, SIGNAL(menuChanged(struct menu
*)),
1403 helpText
, SLOT(setInfo(struct menu
*)));
1404 connect(menuList
, SIGNAL(menuSelected(struct menu
*)),
1405 SLOT(changeMenu(struct menu
*)));
1407 connect(configList
, SIGNAL(gotFocus(struct menu
*)),
1408 helpText
, SLOT(setInfo(struct menu
*)));
1409 connect(menuList
, SIGNAL(gotFocus(struct menu
*)),
1410 helpText
, SLOT(setInfo(struct menu
*)));
1411 connect(menuList
, SIGNAL(gotFocus(struct menu
*)),
1412 SLOT(listFocusChanged(void)));
1413 connect(helpText
, SIGNAL(menuSelected(struct menu
*)),
1414 SLOT(setMenuLink(struct menu
*)));
1416 QString listMode
= configSettings
->readEntry("/listMode", "symbol");
1417 if (listMode
== "single")
1419 else if (listMode
== "full")
1421 else /*if (listMode == "split")*/
1424 // UI setup done, restore splitter positions
1425 QValueList
<int> sizes
= configSettings
->readSizes("/split1", &ok
);
1427 split1
->setSizes(sizes
);
1429 sizes
= configSettings
->readSizes("/split2", &ok
);
1431 split2
->setSizes(sizes
);
1434 void ConfigMainWindow::loadConfig(void)
1436 QString s
= QFileDialog::getOpenFileName(".config", NULL
, this);
1439 if (conf_read(QFile::encodeName(s
)))
1440 QMessageBox::information(this, "qconf", "Unable to load configuration!");
1441 ConfigView::updateListAll();
1444 void ConfigMainWindow::saveConfig(void)
1446 if (conf_write(NULL
))
1447 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1450 void ConfigMainWindow::saveConfigAs(void)
1452 QString s
= QFileDialog::getSaveFileName(".config", NULL
, this);
1455 if (conf_write(QFile::encodeName(s
)))
1456 QMessageBox::information(this, "qconf", "Unable to save configuration!");
1459 void ConfigMainWindow::searchConfig(void)
1462 searchWindow
= new ConfigSearchWindow(this, "search");
1463 searchWindow
->show();
1466 void ConfigMainWindow::changeMenu(struct menu
*menu
)
1468 configList
->setRootMenu(menu
);
1469 backAction
->setEnabled(TRUE
);
1472 void ConfigMainWindow::setMenuLink(struct menu
*menu
)
1474 struct menu
*parent
;
1475 ConfigList
* list
= NULL
;
1478 if (!menu_is_visible(menu
) && !configView
->showAll())
1481 switch (configList
->mode
) {
1484 parent
= menu_get_parent_menu(menu
);
1487 list
->setRootMenu(parent
);
1490 if (menu
->flags
& MENU_ROOT
) {
1491 configList
->setRootMenu(menu
);
1492 configList
->clearSelection();
1496 parent
= menu_get_parent_menu(menu
->parent
);
1499 item
= menuList
->findConfigItem(parent
);
1501 menuList
->setSelected(item
, TRUE
);
1502 menuList
->ensureItemVisible(item
);
1504 list
->setRootMenu(parent
);
1513 item
= list
->findConfigItem(menu
);
1515 list
->setSelected(item
, TRUE
);
1516 list
->ensureItemVisible(item
);
1522 void ConfigMainWindow::listFocusChanged(void)
1524 if (menuList
->mode
== menuMode
)
1525 configList
->clearSelection();
1528 void ConfigMainWindow::goBack(void)
1532 configList
->setParentMenu();
1533 if (configList
->rootEntry
== &rootmenu
)
1534 backAction
->setEnabled(FALSE
);
1535 item
= (ConfigItem
*)menuList
->selectedItem();
1537 if (item
->menu
== configList
->rootEntry
) {
1538 menuList
->setSelected(item
, TRUE
);
1541 item
= (ConfigItem
*)item
->parent();
1545 void ConfigMainWindow::showSingleView(void)
1548 menuList
->setRootMenu(0);
1549 configList
->mode
= singleMode
;
1550 if (configList
->rootEntry
== &rootmenu
)
1551 configList
->updateListAll();
1553 configList
->setRootMenu(&rootmenu
);
1554 configList
->setAllOpen(TRUE
);
1555 configList
->setFocus();
1558 void ConfigMainWindow::showSplitView(void)
1560 configList
->mode
= symbolMode
;
1561 if (configList
->rootEntry
== &rootmenu
)
1562 configList
->updateListAll();
1564 configList
->setRootMenu(&rootmenu
);
1565 configList
->setAllOpen(TRUE
);
1566 configApp
->processEvents();
1567 menuList
->mode
= menuMode
;
1568 menuList
->setRootMenu(&rootmenu
);
1569 menuList
->setAllOpen(TRUE
);
1571 menuList
->setFocus();
1574 void ConfigMainWindow::showFullView(void)
1577 menuList
->setRootMenu(0);
1578 configList
->mode
= fullMode
;
1579 if (configList
->rootEntry
== &rootmenu
)
1580 configList
->updateListAll();
1582 configList
->setRootMenu(&rootmenu
);
1583 configList
->setAllOpen(FALSE
);
1584 configList
->setFocus();
1588 * ask for saving configuration before quitting
1589 * TODO ask only when something changed
1591 void ConfigMainWindow::closeEvent(QCloseEvent
* e
)
1593 if (!conf_get_changed()) {
1597 QMessageBox
mb("qconf", "Save configuration?", QMessageBox::Warning
,
1598 QMessageBox::Yes
| QMessageBox::Default
, QMessageBox::No
, QMessageBox::Cancel
| QMessageBox::Escape
);
1599 mb
.setButtonText(QMessageBox::Yes
, "&Save Changes");
1600 mb
.setButtonText(QMessageBox::No
, "&Discard Changes");
1601 mb
.setButtonText(QMessageBox::Cancel
, "Cancel Exit");
1602 switch (mb
.exec()) {
1603 case QMessageBox::Yes
:
1605 case QMessageBox::No
:
1608 case QMessageBox::Cancel
:
1614 void ConfigMainWindow::showIntro(void)
1616 static char str
[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n"
1617 "For each option, a blank box indicates the feature is disabled, a check\n"
1618 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1619 "as a module. Clicking on the box will cycle through the three states.\n\n"
1620 "If you do not see an option (e.g., a device driver) that you believe\n"
1621 "should be present, try turning on Show All Options under the Options menu.\n"
1622 "Although there is no cross reference yet to help you figure out what other\n"
1623 "options must be enabled to support the option you are interested in, you can\n"
1624 "still view the help of a grayed-out option.\n\n"
1625 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1626 "which you can then match by examining other options.\n\n";
1628 QMessageBox::information(this, "qconf", str
);
1631 void ConfigMainWindow::showAbout(void)
1633 static char str
[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1634 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
1636 QMessageBox::information(this, "qconf", str
);
1639 void ConfigMainWindow::saveSettings(void)
1641 configSettings
->writeEntry("/window x", pos().x());
1642 configSettings
->writeEntry("/window y", pos().y());
1643 configSettings
->writeEntry("/window width", size().width());
1644 configSettings
->writeEntry("/window height", size().height());
1647 switch(configList
->mode
) {
1660 configSettings
->writeEntry("/listMode", entry
);
1662 configSettings
->writeSizes("/split1", split1
->sizes());
1663 configSettings
->writeSizes("/split2", split2
->sizes());
1666 void ConfigMainWindow::conf_changed(void)
1669 saveAction
->setEnabled(conf_get_changed());
1672 void fixup_rootmenu(struct menu
*menu
)
1675 static int menu_cnt
= 0;
1677 menu
->flags
|= MENU_ROOT
;
1678 for (child
= menu
->list
; child
; child
= child
->next
) {
1679 if (child
->prompt
&& child
->prompt
->type
== P_MENU
) {
1681 fixup_rootmenu(child
);
1683 } else if (!menu_cnt
)
1684 fixup_rootmenu(child
);
1688 static const char *progname
;
1690 static void usage(void)
1692 printf("%s <config>\n", progname
);
1696 int main(int ac
, char** av
)
1698 ConfigMainWindow
* v
;
1701 bindtextdomain(PACKAGE
, LOCALEDIR
);
1702 textdomain(PACKAGE
);
1704 #ifndef LKC_DIRECT_LINK
1709 configApp
= new QApplication(ac
, av
);
1710 if (ac
> 1 && av
[1][0] == '-') {
1723 fixup_rootmenu(&rootmenu
);
1725 //zconfdump(stdout);
1727 configSettings
= new ConfigSettings();
1728 configSettings
->beginGroup("/kconfig/qconf");
1729 v
= new ConfigMainWindow();
1731 //zconfdump(stdout);
1732 configApp
->setMainWidget(v
);
1733 configApp
->connect(configApp
, SIGNAL(lastWindowClosed()), SLOT(quit()));
1734 configApp
->connect(configApp
, SIGNAL(aboutToQuit()), v
, SLOT(saveSettings()));
1738 configSettings
->endGroup();
1739 delete configSettings
;