Port xconfig to Qt5 - Use QTextBrowser
[deliverable/linux.git] / scripts / kconfig / qconf.cc
CommitLineData
1da177e4
LT
1/*
2 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3 * Released under the terms of the GNU GPL v2.0.
4 */
5
133c5f7c
AS
6#include <qglobal.h>
7
b1f8a45b 8#include <QMainWindow>
133c5f7c 9#include <q3vbox.h>
041fbdc2 10#include <QList>
924bbb53 11#include <qtextbrowser.h>
85eaf28a 12#include <QAction>
133c5f7c 13#include <q3header.h>
bea00771 14#include <QFileDialog>
133c5f7c
AS
15#include <q3dragobject.h>
16#include <q3popupmenu.h>
133c5f7c
AS
17
18#include <qapplication.h>
8d90c97e 19#include <qdesktopwidget.h>
1da177e4 20#include <qtoolbar.h>
43bf612a 21#include <qlayout.h>
1da177e4 22#include <qsplitter.h>
1da177e4 23#include <qlineedit.h>
43bf612a
RZ
24#include <qlabel.h>
25#include <qpushbutton.h>
1da177e4
LT
26#include <qmenubar.h>
27#include <qmessagebox.h>
1da177e4 28#include <qregexp.h>
133c5f7c 29#include <qevent.h>
1da177e4
LT
30
31#include <stdlib.h>
32
33#include "lkc.h"
34#include "qconf.h"
35
36#include "qconf.moc"
37#include "images.c"
38
3b9fa093
ACM
39#ifdef _
40# undef _
41# define _ qgettext
42#endif
43
1da177e4 44static QApplication *configApp;
7fc925fd 45static ConfigSettings *configSettings;
1da177e4 46
85eaf28a 47QAction *ConfigMainWindow::saveAction;
3b354c55 48
3b9fa093
ACM
49static inline QString qgettext(const char* str)
50{
43bf612a 51 return QString::fromLocal8Bit(gettext(str));
3b9fa093
ACM
52}
53
54static inline QString qgettext(const QString& str)
55{
43bf612a 56 return QString::fromLocal8Bit(gettext(str.latin1()));
3b9fa093
ACM
57}
58
00d4f8fc
BH
59ConfigSettings::ConfigSettings()
60 : QSettings("kernel.org", "qconf")
61{
62}
63
1da177e4
LT
64/**
65 * Reads a list of integer values from the application settings.
66 */
041fbdc2 67QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
1da177e4 68{
041fbdc2 69 QList<int> result;
1da177e4 70 QStringList entryList = readListEntry(key, ok);
c1f96f09
LZ
71 QStringList::Iterator it;
72
73 for (it = entryList.begin(); it != entryList.end(); ++it)
74 result.push_back((*it).toInt());
1da177e4
LT
75
76 return result;
77}
78
79/**
80 * Writes a list of integer values to the application settings.
81 */
041fbdc2 82bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
1da177e4
LT
83{
84 QStringList stringList;
041fbdc2 85 QList<int>::ConstIterator it;
1da177e4
LT
86
87 for (it = value.begin(); it != value.end(); ++it)
88 stringList.push_back(QString::number(*it));
89 return writeEntry(key, stringList);
90}
1da177e4 91
1da177e4 92
1da177e4
LT
93/*
94 * set the new data
95 * TODO check the value
96 */
97void ConfigItem::okRename(int col)
98{
99 Parent::okRename(col);
100 sym_set_string_value(menu->sym, text(dataColIdx).latin1());
49e5646d 101 listView()->updateList(this);
1da177e4 102}
1da177e4
LT
103
104/*
105 * update the displayed of a menu entry
106 */
107void ConfigItem::updateMenu(void)
108{
109 ConfigList* list;
110 struct symbol* sym;
111 struct property *prop;
112 QString prompt;
113 int type;
114 tristate expr;
115
116 list = listView();
117 if (goParent) {
118 setPixmap(promptColIdx, list->menuBackPix);
119 prompt = "..";
120 goto set_prompt;
121 }
122
123 sym = menu->sym;
124 prop = menu->prompt;
c21a2d95 125 prompt = _(menu_get_prompt(menu));
1da177e4
LT
126
127 if (prop) switch (prop->type) {
128 case P_MENU:
129 if (list->mode == singleMode || list->mode == symbolMode) {
130 /* a menuconfig entry is displayed differently
131 * depending whether it's at the view root or a child.
132 */
133 if (sym && list->rootEntry == menu)
134 break;
135 setPixmap(promptColIdx, list->menuPix);
136 } else {
137 if (sym)
138 break;
139 setPixmap(promptColIdx, 0);
140 }
141 goto set_prompt;
142 case P_COMMENT:
143 setPixmap(promptColIdx, 0);
144 goto set_prompt;
145 default:
146 ;
147 }
148 if (!sym)
149 goto set_prompt;
150
3b9fa093 151 setText(nameColIdx, QString::fromLocal8Bit(sym->name));
1da177e4
LT
152
153 type = sym_get_type(sym);
154 switch (type) {
155 case S_BOOLEAN:
156 case S_TRISTATE:
157 char ch;
158
39a4897c 159 if (!sym_is_changable(sym) && list->optMode == normalOpt) {
1da177e4 160 setPixmap(promptColIdx, 0);
3b9fa093
ACM
161 setText(noColIdx, QString::null);
162 setText(modColIdx, QString::null);
163 setText(yesColIdx, QString::null);
1da177e4
LT
164 break;
165 }
166 expr = sym_get_tristate_value(sym);
167 switch (expr) {
168 case yes:
169 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
170 setPixmap(promptColIdx, list->choiceYesPix);
171 else
172 setPixmap(promptColIdx, list->symbolYesPix);
173 setText(yesColIdx, "Y");
174 ch = 'Y';
175 break;
176 case mod:
177 setPixmap(promptColIdx, list->symbolModPix);
178 setText(modColIdx, "M");
179 ch = 'M';
180 break;
181 default:
182 if (sym_is_choice_value(sym) && type == S_BOOLEAN)
183 setPixmap(promptColIdx, list->choiceNoPix);
184 else
185 setPixmap(promptColIdx, list->symbolNoPix);
186 setText(noColIdx, "N");
187 ch = 'N';
188 break;
189 }
190 if (expr != no)
191 setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
192 if (expr != mod)
193 setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
194 if (expr != yes)
195 setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
196
197 setText(dataColIdx, QChar(ch));
198 break;
199 case S_INT:
200 case S_HEX:
201 case S_STRING:
202 const char* data;
203
204 data = sym_get_string_value(sym);
3b9fa093 205
1da177e4
LT
206 int i = list->mapIdx(dataColIdx);
207 if (i >= 0)
208 setRenameEnabled(i, TRUE);
1da177e4
LT
209 setText(dataColIdx, data);
210 if (type == S_STRING)
3b9fa093 211 prompt = QString("%1: %2").arg(prompt).arg(data);
1da177e4 212 else
3b9fa093 213 prompt = QString("(%2) %1").arg(prompt).arg(data);
1da177e4
LT
214 break;
215 }
216 if (!sym_has_value(sym) && visible)
c21a2d95 217 prompt += _(" (NEW)");
1da177e4
LT
218set_prompt:
219 setText(promptColIdx, prompt);
220}
221
222void ConfigItem::testUpdateMenu(bool v)
223{
224 ConfigItem* i;
225
226 visible = v;
227 if (!menu)
228 return;
229
230 sym_calc_value(menu->sym);
231 if (menu->flags & MENU_CHANGED) {
232 /* the menu entry changed, so update all list items */
233 menu->flags &= ~MENU_CHANGED;
234 for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
235 i->updateMenu();
236 } else if (listView()->updateAll)
237 updateMenu();
238}
239
240void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
241{
242 ConfigList* list = listView();
243
244 if (visible) {
245 if (isSelected() && !list->hasFocus() && list->mode == menuMode)
246 Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
247 else
248 Parent::paintCell(p, cg, column, width, align);
249 } else
250 Parent::paintCell(p, list->disabledColorGroup, column, width, align);
251}
252
253/*
254 * construct a menu entry
255 */
256void ConfigItem::init(void)
257{
258 if (menu) {
259 ConfigList* list = listView();
260 nextItem = (ConfigItem*)menu->data;
261 menu->data = this;
262
263 if (list->mode != fullMode)
264 setOpen(TRUE);
265 sym_calc_value(menu->sym);
266 }
267 updateMenu();
268}
269
270/*
271 * destruct a menu entry
272 */
273ConfigItem::~ConfigItem(void)
274{
275 if (menu) {
276 ConfigItem** ip = (ConfigItem**)&menu->data;
277 for (; *ip; ip = &(*ip)->nextItem) {
278 if (*ip == this) {
279 *ip = nextItem;
280 break;
281 }
282 }
283 }
284}
285
43bf612a
RZ
286ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
287 : Parent(parent)
288{
289 connect(this, SIGNAL(lostFocus()), SLOT(hide()));
290}
291
1da177e4
LT
292void ConfigLineEdit::show(ConfigItem* i)
293{
294 item = i;
295 if (sym_get_string_value(item->menu->sym))
3b9fa093 296 setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
1da177e4 297 else
3b9fa093 298 setText(QString::null);
1da177e4
LT
299 Parent::show();
300 setFocus();
301}
302
303void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
304{
305 switch (e->key()) {
fbb86374 306 case Qt::Key_Escape:
1da177e4 307 break;
fbb86374
MH
308 case Qt::Key_Return:
309 case Qt::Key_Enter:
1da177e4
LT
310 sym_set_string_value(item->menu->sym, text().latin1());
311 parent()->updateList(item);
312 break;
313 default:
314 Parent::keyPressEvent(e);
315 return;
316 }
317 e->accept();
318 parent()->list->setFocus();
319 hide();
320}
321
7fc925fd
RZ
322ConfigList::ConfigList(ConfigView* p, const char *name)
323 : Parent(p, name),
1da177e4
LT
324 updateAll(false),
325 symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
326 choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
327 menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
39a4897c 328 showName(false), showRange(false), showData(false), optMode(normalOpt),
7fc925fd 329 rootEntry(0), headerPopup(0)
1da177e4
LT
330{
331 int i;
332
333 setSorting(-1);
334 setRootIsDecorated(TRUE);
335 disabledColorGroup = palette().active();
336 disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
337 inactivedColorGroup = palette().active();
338 inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
339
340 connect(this, SIGNAL(selectionChanged(void)),
341 SLOT(updateSelection(void)));
342
7fc925fd
RZ
343 if (name) {
344 configSettings->beginGroup(name);
7fc925fd
RZ
345 showName = configSettings->readBoolEntry("/showName", false);
346 showRange = configSettings->readBoolEntry("/showRange", false);
347 showData = configSettings->readBoolEntry("/showData", false);
39a4897c 348 optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
7fc925fd
RZ
349 configSettings->endGroup();
350 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1da177e4
LT
351 }
352
353 for (i = 0; i < colNr; i++)
354 colMap[i] = colRevMap[i] = -1;
c21a2d95 355 addColumn(promptColIdx, _("Option"));
1da177e4
LT
356
357 reinit();
358}
359
39a4897c
LZ
360bool ConfigList::menuSkip(struct menu *menu)
361{
362 if (optMode == normalOpt && menu_is_visible(menu))
363 return false;
364 if (optMode == promptOpt && menu_has_prompt(menu))
365 return false;
366 if (optMode == allOpt)
367 return false;
368 return true;
369}
370
1da177e4
LT
371void ConfigList::reinit(void)
372{
373 removeColumn(dataColIdx);
374 removeColumn(yesColIdx);
375 removeColumn(modColIdx);
376 removeColumn(noColIdx);
377 removeColumn(nameColIdx);
378
379 if (showName)
c21a2d95 380 addColumn(nameColIdx, _("Name"));
1da177e4
LT
381 if (showRange) {
382 addColumn(noColIdx, "N");
383 addColumn(modColIdx, "M");
384 addColumn(yesColIdx, "Y");
385 }
386 if (showData)
c21a2d95 387 addColumn(dataColIdx, _("Value"));
1da177e4
LT
388
389 updateListAll();
390}
391
7fc925fd
RZ
392void ConfigList::saveSettings(void)
393{
394 if (name()) {
395 configSettings->beginGroup(name());
396 configSettings->writeEntry("/showName", showName);
397 configSettings->writeEntry("/showRange", showRange);
398 configSettings->writeEntry("/showData", showData);
39a4897c 399 configSettings->writeEntry("/optionMode", (int)optMode);
7fc925fd
RZ
400 configSettings->endGroup();
401 }
402}
403
b65a47e1
RZ
404ConfigItem* ConfigList::findConfigItem(struct menu *menu)
405{
406 ConfigItem* item = (ConfigItem*)menu->data;
407
408 for (; item; item = item->nextItem) {
409 if (this == item->listView())
410 break;
411 }
412
413 return item;
414}
415
1da177e4
LT
416void ConfigList::updateSelection(void)
417{
418 struct menu *menu;
419 enum prop_type type;
420
421 ConfigItem* item = (ConfigItem*)selectedItem();
422 if (!item)
423 return;
424
1da177e4 425 menu = item->menu;
43bf612a 426 emit menuChanged(menu);
1da177e4
LT
427 if (!menu)
428 return;
429 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
430 if (mode == menuMode && type == P_MENU)
431 emit menuSelected(menu);
432}
433
434void ConfigList::updateList(ConfigItem* item)
435{
436 ConfigItem* last = 0;
437
43bf612a
RZ
438 if (!rootEntry) {
439 if (mode != listMode)
440 goto update;
133c5f7c 441 Q3ListViewItemIterator it(this);
43bf612a
RZ
442 ConfigItem* item;
443
444 for (; it.current(); ++it) {
445 item = (ConfigItem*)it.current();
446 if (!item->menu)
447 continue;
448 item->testUpdateMenu(menu_is_visible(item->menu));
449 }
450 return;
451 }
1da177e4
LT
452
453 if (rootEntry != &rootmenu && (mode == singleMode ||
454 (mode == symbolMode && rootEntry->parent != &rootmenu))) {
455 item = firstChild();
456 if (!item)
457 item = new ConfigItem(this, 0, true);
458 last = item;
459 }
460 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
461 rootEntry->sym && rootEntry->prompt) {
462 item = last ? last->nextSibling() : firstChild();
463 if (!item)
464 item = new ConfigItem(this, last, rootEntry, true);
465 else
466 item->testUpdateMenu(true);
467
468 updateMenuList(item, rootEntry);
469 triggerUpdate();
470 return;
471 }
472update:
473 updateMenuList(this, rootEntry);
474 triggerUpdate();
475}
476
1da177e4
LT
477void ConfigList::setValue(ConfigItem* item, tristate val)
478{
479 struct symbol* sym;
480 int type;
481 tristate oldval;
482
483 sym = item->menu ? item->menu->sym : 0;
484 if (!sym)
485 return;
486
487 type = sym_get_type(sym);
488 switch (type) {
489 case S_BOOLEAN:
490 case S_TRISTATE:
491 oldval = sym_get_tristate_value(sym);
492
493 if (!sym_set_tristate_value(sym, val))
494 return;
495 if (oldval == no && item->menu->list)
496 item->setOpen(TRUE);
497 parent()->updateList(item);
498 break;
499 }
500}
501
502void ConfigList::changeValue(ConfigItem* item)
503{
504 struct symbol* sym;
505 struct menu* menu;
506 int type, oldexpr, newexpr;
507
508 menu = item->menu;
509 if (!menu)
510 return;
511 sym = menu->sym;
512 if (!sym) {
513 if (item->menu->list)
514 item->setOpen(!item->isOpen());
515 return;
516 }
517
518 type = sym_get_type(sym);
519 switch (type) {
520 case S_BOOLEAN:
521 case S_TRISTATE:
522 oldexpr = sym_get_tristate_value(sym);
523 newexpr = sym_toggle_tristate_value(sym);
524 if (item->menu->list) {
525 if (oldexpr == newexpr)
526 item->setOpen(!item->isOpen());
527 else if (oldexpr == no)
528 item->setOpen(TRUE);
529 }
530 if (oldexpr != newexpr)
531 parent()->updateList(item);
532 break;
533 case S_INT:
534 case S_HEX:
535 case S_STRING:
1da177e4
LT
536 if (colMap[dataColIdx] >= 0)
537 item->startRename(colMap[dataColIdx]);
538 else
1da177e4
LT
539 parent()->lineEdit->show(item);
540 break;
541 }
542}
543
544void ConfigList::setRootMenu(struct menu *menu)
545{
546 enum prop_type type;
547
548 if (rootEntry == menu)
549 return;
550 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
551 if (type != P_MENU)
552 return;
553 updateMenuList(this, 0);
554 rootEntry = menu;
555 updateListAll();
556 setSelected(currentItem(), hasFocus());
b65a47e1 557 ensureItemVisible(currentItem());
1da177e4
LT
558}
559
560void ConfigList::setParentMenu(void)
561{
562 ConfigItem* item;
563 struct menu *oldroot;
564
565 oldroot = rootEntry;
566 if (rootEntry == &rootmenu)
567 return;
568 setRootMenu(menu_get_parent_menu(rootEntry->parent));
569
133c5f7c 570 Q3ListViewItemIterator it(this);
1da177e4
LT
571 for (; (item = (ConfigItem*)it.current()); it++) {
572 if (item->menu == oldroot) {
573 setCurrentItem(item);
574 ensureItemVisible(item);
575 break;
576 }
577 }
578}
579
7fc925fd
RZ
580/*
581 * update all the children of a menu entry
582 * removes/adds the entries from the parent widget as necessary
583 *
584 * parent: either the menu list widget or a menu entry widget
585 * menu: entry to be updated
586 */
587template <class P>
588void ConfigList::updateMenuList(P* parent, struct menu* menu)
589{
590 struct menu* child;
591 ConfigItem* item;
592 ConfigItem* last;
593 bool visible;
594 enum prop_type type;
595
596 if (!menu) {
597 while ((item = parent->firstChild()))
598 delete item;
599 return;
600 }
601
602 last = parent->firstChild();
603 if (last && !last->goParent)
604 last = 0;
605 for (child = menu->list; child; child = child->next) {
606 item = last ? last->nextSibling() : parent->firstChild();
607 type = child->prompt ? child->prompt->type : P_UNKNOWN;
608
609 switch (mode) {
610 case menuMode:
611 if (!(child->flags & MENU_ROOT))
612 goto hide;
613 break;
614 case symbolMode:
615 if (child->flags & MENU_ROOT)
616 goto hide;
617 break;
618 default:
619 break;
620 }
621
622 visible = menu_is_visible(child);
39a4897c 623 if (!menuSkip(child)) {
ed8b4d4d
CG
624 if (!child->sym && !child->list && !child->prompt)
625 continue;
7fc925fd
RZ
626 if (!item || item->menu != child)
627 item = new ConfigItem(parent, last, child, visible);
628 else
629 item->testUpdateMenu(visible);
630
631 if (mode == fullMode || mode == menuMode || type != P_MENU)
632 updateMenuList(item, child);
633 else
634 updateMenuList(item, 0);
635 last = item;
636 continue;
637 }
638 hide:
639 if (item && item->menu == child) {
640 last = parent->firstChild();
641 if (last == item)
642 last = 0;
643 else while (last->nextSibling() != item)
644 last = last->nextSibling();
645 delete item;
646 }
647 }
648}
649
1da177e4
LT
650void ConfigList::keyPressEvent(QKeyEvent* ev)
651{
133c5f7c 652 Q3ListViewItem* i = currentItem();
1da177e4
LT
653 ConfigItem* item;
654 struct menu *menu;
655 enum prop_type type;
656
fbb86374 657 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
1da177e4
LT
658 emit parentSelected();
659 ev->accept();
660 return;
661 }
662
663 if (!i) {
664 Parent::keyPressEvent(ev);
665 return;
666 }
667 item = (ConfigItem*)i;
668
669 switch (ev->key()) {
fbb86374
MH
670 case Qt::Key_Return:
671 case Qt::Key_Enter:
1da177e4
LT
672 if (item->goParent) {
673 emit parentSelected();
674 break;
675 }
676 menu = item->menu;
677 if (!menu)
678 break;
679 type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
680 if (type == P_MENU && rootEntry != menu &&
681 mode != fullMode && mode != menuMode) {
682 emit menuSelected(menu);
683 break;
684 }
fbb86374 685 case Qt::Key_Space:
1da177e4
LT
686 changeValue(item);
687 break;
fbb86374 688 case Qt::Key_N:
1da177e4
LT
689 setValue(item, no);
690 break;
fbb86374 691 case Qt::Key_M:
1da177e4
LT
692 setValue(item, mod);
693 break;
fbb86374 694 case Qt::Key_Y:
1da177e4
LT
695 setValue(item, yes);
696 break;
697 default:
698 Parent::keyPressEvent(ev);
699 return;
700 }
701 ev->accept();
702}
703
704void ConfigList::contentsMousePressEvent(QMouseEvent* e)
705{
706 //QPoint p(contentsToViewport(e->pos()));
707 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
708 Parent::contentsMousePressEvent(e);
709}
710
711void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
712{
713 QPoint p(contentsToViewport(e->pos()));
714 ConfigItem* item = (ConfigItem*)itemAt(p);
715 struct menu *menu;
716 enum prop_type ptype;
717 const QPixmap* pm;
718 int idx, x;
719
720 if (!item)
721 goto skip;
722
723 menu = item->menu;
724 x = header()->offset() + p.x();
725 idx = colRevMap[header()->sectionAt(x)];
726 switch (idx) {
727 case promptColIdx:
728 pm = item->pixmap(promptColIdx);
729 if (pm) {
730 int off = header()->sectionPos(0) + itemMargin() +
731 treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
732 if (x >= off && x < off + pm->width()) {
733 if (item->goParent) {
734 emit parentSelected();
735 break;
736 } else if (!menu)
737 break;
738 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
739 if (ptype == P_MENU && rootEntry != menu &&
740 mode != fullMode && mode != menuMode)
741 emit menuSelected(menu);
742 else
743 changeValue(item);
744 }
745 }
746 break;
747 case noColIdx:
748 setValue(item, no);
749 break;
750 case modColIdx:
751 setValue(item, mod);
752 break;
753 case yesColIdx:
754 setValue(item, yes);
755 break;
756 case dataColIdx:
757 changeValue(item);
758 break;
759 }
760
761skip:
762 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
763 Parent::contentsMouseReleaseEvent(e);
764}
765
766void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
767{
768 //QPoint p(contentsToViewport(e->pos()));
769 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
770 Parent::contentsMouseMoveEvent(e);
771}
772
773void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
774{
775 QPoint p(contentsToViewport(e->pos()));
776 ConfigItem* item = (ConfigItem*)itemAt(p);
777 struct menu *menu;
778 enum prop_type ptype;
779
780 if (!item)
781 goto skip;
782 if (item->goParent) {
783 emit parentSelected();
784 goto skip;
785 }
786 menu = item->menu;
787 if (!menu)
788 goto skip;
789 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
790 if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
791 emit menuSelected(menu);
792 else if (menu->sym)
793 changeValue(item);
794
795skip:
796 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
797 Parent::contentsMouseDoubleClickEvent(e);
798}
799
800void ConfigList::focusInEvent(QFocusEvent *e)
801{
b65a47e1 802 struct menu *menu = NULL;
1da177e4 803
b65a47e1 804 Parent::focusInEvent(e);
1da177e4 805
b65a47e1
RZ
806 ConfigItem* item = (ConfigItem *)currentItem();
807 if (item) {
808 setSelected(item, TRUE);
809 menu = item->menu;
810 }
811 emit gotFocus(menu);
1da177e4
LT
812}
813
7fc925fd
RZ
814void ConfigList::contextMenuEvent(QContextMenuEvent *e)
815{
816 if (e->y() <= header()->geometry().bottom()) {
817 if (!headerPopup) {
85eaf28a 818 QAction *action;
7fc925fd 819
133c5f7c 820 headerPopup = new Q3PopupMenu(this);
85eaf28a 821 action = new QAction(_("Show Name"), this);
7fc925fd
RZ
822 action->setToggleAction(TRUE);
823 connect(action, SIGNAL(toggled(bool)),
824 parent(), SLOT(setShowName(bool)));
825 connect(parent(), SIGNAL(showNameChanged(bool)),
826 action, SLOT(setOn(bool)));
827 action->setOn(showName);
828 action->addTo(headerPopup);
85eaf28a 829 action = new QAction(_("Show Range"), this);
7fc925fd
RZ
830 action->setToggleAction(TRUE);
831 connect(action, SIGNAL(toggled(bool)),
832 parent(), SLOT(setShowRange(bool)));
833 connect(parent(), SIGNAL(showRangeChanged(bool)),
834 action, SLOT(setOn(bool)));
835 action->setOn(showRange);
836 action->addTo(headerPopup);
85eaf28a 837 action = new QAction( _("Show Data"), this);
7fc925fd
RZ
838 action->setToggleAction(TRUE);
839 connect(action, SIGNAL(toggled(bool)),
840 parent(), SLOT(setShowData(bool)));
841 connect(parent(), SIGNAL(showDataChanged(bool)),
842 action, SLOT(setOn(bool)));
843 action->setOn(showData);
844 action->addTo(headerPopup);
845 }
846 headerPopup->exec(e->globalPos());
847 e->accept();
848 } else
849 e->ignore();
850}
851
39a4897c
LZ
852ConfigView*ConfigView::viewList;
853QAction *ConfigView::showNormalAction;
854QAction *ConfigView::showAllAction;
855QAction *ConfigView::showPromptAction;
1da177e4 856
7fc925fd
RZ
857ConfigView::ConfigView(QWidget* parent, const char *name)
858 : Parent(parent, name)
1da177e4 859{
7fc925fd 860 list = new ConfigList(this, name);
1da177e4
LT
861 lineEdit = new ConfigLineEdit(this);
862 lineEdit->hide();
863
864 this->nextView = viewList;
865 viewList = this;
866}
867
868ConfigView::~ConfigView(void)
869{
870 ConfigView** vp;
871
872 for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
873 if (*vp == this) {
874 *vp = nextView;
875 break;
876 }
877 }
878}
879
39a4897c 880void ConfigView::setOptionMode(QAction *act)
7fc925fd 881{
39a4897c
LZ
882 if (act == showNormalAction)
883 list->optMode = normalOpt;
884 else if (act == showAllAction)
885 list->optMode = allOpt;
886 else
887 list->optMode = promptOpt;
888
889 list->updateListAll();
7fc925fd
RZ
890}
891
892void ConfigView::setShowName(bool b)
893{
894 if (list->showName != b) {
895 list->showName = b;
896 list->reinit();
897 emit showNameChanged(b);
898 }
899}
900
901void ConfigView::setShowRange(bool b)
902{
903 if (list->showRange != b) {
904 list->showRange = b;
905 list->reinit();
906 emit showRangeChanged(b);
907 }
908}
909
910void ConfigView::setShowData(bool b)
911{
912 if (list->showData != b) {
913 list->showData = b;
914 list->reinit();
915 emit showDataChanged(b);
916 }
917}
918
919void ConfigList::setAllOpen(bool open)
920{
133c5f7c 921 Q3ListViewItemIterator it(this);
7fc925fd
RZ
922
923 for (; it.current(); it++)
924 it.current()->setOpen(open);
925}
926
1da177e4
LT
927void ConfigView::updateList(ConfigItem* item)
928{
929 ConfigView* v;
930
931 for (v = viewList; v; v = v->nextView)
932 v->list->updateList(item);
933}
934
935void ConfigView::updateListAll(void)
936{
937 ConfigView* v;
938
939 for (v = viewList; v; v = v->nextView)
940 v->list->updateListAll();
941}
942
43bf612a 943ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
133c5f7c 944 : Parent(parent, name), sym(0), _menu(0)
43bf612a 945{
7fc925fd
RZ
946 if (name) {
947 configSettings->beginGroup(name);
948 _showDebug = configSettings->readBoolEntry("/showDebug", false);
949 configSettings->endGroup();
950 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
951 }
952}
953
954void ConfigInfoView::saveSettings(void)
955{
956 if (name()) {
957 configSettings->beginGroup(name());
958 configSettings->writeEntry("/showDebug", showDebug());
959 configSettings->endGroup();
960 }
43bf612a
RZ
961}
962
963void ConfigInfoView::setShowDebug(bool b)
964{
965 if (_showDebug != b) {
966 _showDebug = b;
133c5f7c 967 if (_menu)
43bf612a 968 menuInfo();
ab45d190
RZ
969 else if (sym)
970 symbolInfo();
43bf612a
RZ
971 emit showDebugChanged(b);
972 }
973}
974
975void ConfigInfoView::setInfo(struct menu *m)
976{
133c5f7c 977 if (_menu == m)
b65a47e1 978 return;
133c5f7c 979 _menu = m;
6fa1da8e 980 sym = NULL;
133c5f7c 981 if (!_menu)
43bf612a 982 clear();
6fa1da8e 983 else
43bf612a
RZ
984 menuInfo();
985}
986
ab45d190
RZ
987void ConfigInfoView::symbolInfo(void)
988{
989 QString str;
990
991 str += "<big>Symbol: <b>";
992 str += print_filter(sym->name);
993 str += "</b></big><br><br>value: ";
994 str += print_filter(sym_get_string_value(sym));
995 str += "<br>visibility: ";
996 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
997 str += "<br>";
998 str += debug_info(sym);
999
1000 setText(str);
1001}
1002
43bf612a
RZ
1003void ConfigInfoView::menuInfo(void)
1004{
1005 struct symbol* sym;
1006 QString head, debug, help;
1007
133c5f7c 1008 sym = _menu->sym;
43bf612a 1009 if (sym) {
133c5f7c 1010 if (_menu->prompt) {
43bf612a 1011 head += "<big><b>";
133c5f7c 1012 head += print_filter(_(_menu->prompt->text));
43bf612a
RZ
1013 head += "</b></big>";
1014 if (sym->name) {
1015 head += " (";
ab45d190
RZ
1016 if (showDebug())
1017 head += QString().sprintf("<a href=\"s%p\">", sym);
43bf612a 1018 head += print_filter(sym->name);
ab45d190
RZ
1019 if (showDebug())
1020 head += "</a>";
43bf612a
RZ
1021 head += ")";
1022 }
1023 } else if (sym->name) {
1024 head += "<big><b>";
ab45d190
RZ
1025 if (showDebug())
1026 head += QString().sprintf("<a href=\"s%p\">", sym);
43bf612a 1027 head += print_filter(sym->name);
ab45d190
RZ
1028 if (showDebug())
1029 head += "</a>";
43bf612a
RZ
1030 head += "</b></big>";
1031 }
1032 head += "<br><br>";
1033
1034 if (showDebug())
1035 debug = debug_info(sym);
1036
d74c15f3 1037 struct gstr help_gstr = str_new();
133c5f7c 1038 menu_get_ext_help(_menu, &help_gstr);
d74c15f3
CR
1039 help = print_filter(str_get(&help_gstr));
1040 str_free(&help_gstr);
133c5f7c 1041 } else if (_menu->prompt) {
43bf612a 1042 head += "<big><b>";
133c5f7c 1043 head += print_filter(_(_menu->prompt->text));
43bf612a
RZ
1044 head += "</b></big><br><br>";
1045 if (showDebug()) {
133c5f7c 1046 if (_menu->prompt->visible.expr) {
43bf612a 1047 debug += "&nbsp;&nbsp;dep: ";
133c5f7c 1048 expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
43bf612a
RZ
1049 debug += "<br><br>";
1050 }
1051 }
1052 }
1053 if (showDebug())
133c5f7c 1054 debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
43bf612a
RZ
1055
1056 setText(head + debug + help);
1057}
1058
1059QString ConfigInfoView::debug_info(struct symbol *sym)
1060{
1061 QString debug;
1062
1063 debug += "type: ";
1064 debug += print_filter(sym_type_name(sym->type));
1065 if (sym_is_choice(sym))
1066 debug += " (choice)";
1067 debug += "<br>";
1068 if (sym->rev_dep.expr) {
1069 debug += "reverse dep: ";
1070 expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1071 debug += "<br>";
1072 }
1073 for (struct property *prop = sym->prop; prop; prop = prop->next) {
1074 switch (prop->type) {
1075 case P_PROMPT:
1076 case P_MENU:
ab45d190 1077 debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
43bf612a 1078 debug += print_filter(_(prop->text));
ab45d190 1079 debug += "</a><br>";
43bf612a
RZ
1080 break;
1081 case P_DEFAULT:
93449082
RZ
1082 case P_SELECT:
1083 case P_RANGE:
1084 case P_ENV:
1085 debug += prop_get_type_name(prop->type);
1086 debug += ": ";
43bf612a
RZ
1087 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1088 debug += "<br>";
1089 break;
1090 case P_CHOICE:
1091 if (sym_is_choice(sym)) {
1092 debug += "choice: ";
1093 expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1094 debug += "<br>";
1095 }
1096 break;
43bf612a
RZ
1097 default:
1098 debug += "unknown property: ";
1099 debug += prop_get_type_name(prop->type);
1100 debug += "<br>";
1101 }
1102 if (prop->visible.expr) {
1103 debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1104 expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1105 debug += "<br>";
1106 }
1107 }
1108 debug += "<br>";
1109
1110 return debug;
1111}
1112
1113QString ConfigInfoView::print_filter(const QString &str)
1114{
1115 QRegExp re("[<>&\"\\n]");
1116 QString res = str;
1117 for (int i = 0; (i = res.find(re, i)) >= 0;) {
1118 switch (res[i].latin1()) {
1119 case '<':
1120 res.replace(i, 1, "&lt;");
1121 i += 4;
1122 break;
1123 case '>':
1124 res.replace(i, 1, "&gt;");
1125 i += 4;
1126 break;
1127 case '&':
1128 res.replace(i, 1, "&amp;");
1129 i += 5;
1130 break;
1131 case '"':
1132 res.replace(i, 1, "&quot;");
1133 i += 6;
1134 break;
1135 case '\n':
1136 res.replace(i, 1, "<br>");
1137 i += 4;
1138 break;
1139 }
1140 }
1141 return res;
1142}
1143
ab45d190 1144void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
43bf612a 1145{
ab45d190
RZ
1146 QString* text = reinterpret_cast<QString*>(data);
1147 QString str2 = print_filter(str);
1148
1149 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
1150 *text += QString().sprintf("<a href=\"s%p\">", sym);
1151 *text += str2;
1152 *text += "</a>";
1153 } else
1154 *text += str2;
43bf612a
RZ
1155}
1156
924bbb53 1157QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
7fc925fd 1158{
924bbb53 1159 QMenu* popup = Parent::createStandardContextMenu(pos);
85eaf28a 1160 QAction* action = new QAction(_("Show Debug Info"), popup);
7fc925fd
RZ
1161 action->setToggleAction(TRUE);
1162 connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
1163 connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
1164 action->setOn(showDebug());
924bbb53 1165 popup->addSeparator();
7fc925fd
RZ
1166 action->addTo(popup);
1167 return popup;
1168}
1169
924bbb53 1170void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
7fc925fd 1171{
924bbb53 1172 Parent::contextMenuEvent(e);
7fc925fd
RZ
1173}
1174
63431e75 1175ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
7fc925fd 1176 : Parent(parent, name), result(NULL)
43bf612a
RZ
1177{
1178 setCaption("Search Config");
1179
1180 QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
1181 QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
c21a2d95 1182 layout2->addWidget(new QLabel(_("Find:"), this));
43bf612a
RZ
1183 editField = new QLineEdit(this);
1184 connect(editField, SIGNAL(returnPressed()), SLOT(search()));
1185 layout2->addWidget(editField);
c21a2d95 1186 searchButton = new QPushButton(_("Search"), this);
43bf612a
RZ
1187 searchButton->setAutoDefault(FALSE);
1188 connect(searchButton, SIGNAL(clicked()), SLOT(search()));
1189 layout2->addWidget(searchButton);
1190 layout1->addLayout(layout2);
1191
7fc925fd 1192 split = new QSplitter(this);
7298b936 1193 split->setOrientation(Qt::Vertical);
7fc925fd 1194 list = new ConfigView(split, name);
43bf612a 1195 list->list->mode = listMode;
7fc925fd 1196 info = new ConfigInfoView(split, name);
43bf612a
RZ
1197 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1198 info, SLOT(setInfo(struct menu *)));
63431e75
MC
1199 connect(list->list, SIGNAL(menuChanged(struct menu *)),
1200 parent, SLOT(setMenuLink(struct menu *)));
1201
43bf612a 1202 layout1->addWidget(split);
7fc925fd
RZ
1203
1204 if (name) {
1205 int x, y, width, height;
1206 bool ok;
1207
1208 configSettings->beginGroup(name);
1209 width = configSettings->readNumEntry("/window width", parent->width() / 2);
1210 height = configSettings->readNumEntry("/window height", parent->height() / 2);
1211 resize(width, height);
1212 x = configSettings->readNumEntry("/window x", 0, &ok);
1213 if (ok)
1214 y = configSettings->readNumEntry("/window y", 0, &ok);
1215 if (ok)
1216 move(x, y);
041fbdc2 1217 QList<int> sizes = configSettings->readSizes("/split", &ok);
7fc925fd
RZ
1218 if (ok)
1219 split->setSizes(sizes);
1220 configSettings->endGroup();
1221 connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
1222 }
1223}
1224
1225void ConfigSearchWindow::saveSettings(void)
1226{
1227 if (name()) {
1228 configSettings->beginGroup(name());
1229 configSettings->writeEntry("/window x", pos().x());
1230 configSettings->writeEntry("/window y", pos().y());
1231 configSettings->writeEntry("/window width", size().width());
1232 configSettings->writeEntry("/window height", size().height());
1233 configSettings->writeSizes("/split", split->sizes());
1234 configSettings->endGroup();
1235 }
43bf612a
RZ
1236}
1237
1238void ConfigSearchWindow::search(void)
1239{
1240 struct symbol **p;
1241 struct property *prop;
1242 ConfigItem *lastItem = NULL;
1243
1244 free(result);
1245 list->list->clear();
786fb18d 1246 info->clear();
43bf612a
RZ
1247
1248 result = sym_re_search(editField->text().latin1());
1249 if (!result)
1250 return;
1251 for (p = result; *p; p++) {
1252 for_all_prompts((*p), prop)
1253 lastItem = new ConfigItem(list->list, lastItem, prop->menu,
1254 menu_is_visible(prop->menu));
1255 }
1256}
1257
1da177e4
LT
1258/*
1259 * Construct the complete config widget
1260 */
1261ConfigMainWindow::ConfigMainWindow(void)
f12aa704 1262 : searchWindow(0)
1da177e4
LT
1263{
1264 QMenuBar* menu;
7fc925fd 1265 bool ok;
1da177e4 1266 int x, y, width, height;
a54bb701 1267 char title[256];
1da177e4 1268
8d90c97e 1269 QDesktopWidget *d = configApp->desktop();
0954828f
AL
1270 snprintf(title, sizeof(title), "%s%s",
1271 rootmenu.prompt->text,
76a136c4 1272 ""
76a136c4 1273 );
a54bb701 1274 setCaption(title);
1da177e4 1275
7fc925fd
RZ
1276 width = configSettings->readNumEntry("/window width", d->width() - 64);
1277 height = configSettings->readNumEntry("/window height", d->height() - 64);
1da177e4 1278 resize(width, height);
7fc925fd 1279 x = configSettings->readNumEntry("/window x", 0, &ok);
1da177e4 1280 if (ok)
7fc925fd 1281 y = configSettings->readNumEntry("/window y", 0, &ok);
1da177e4
LT
1282 if (ok)
1283 move(x, y);
1da177e4
LT
1284
1285 split1 = new QSplitter(this);
7298b936 1286 split1->setOrientation(Qt::Horizontal);
1da177e4
LT
1287 setCentralWidget(split1);
1288
7fc925fd 1289 menuView = new ConfigView(split1, "menu");
1da177e4
LT
1290 menuList = menuView->list;
1291
1292 split2 = new QSplitter(split1);
7298b936 1293 split2->setOrientation(Qt::Vertical);
1da177e4
LT
1294
1295 // create config tree
7fc925fd 1296 configView = new ConfigView(split2, "config");
1da177e4
LT
1297 configList = configView->list;
1298
7fc925fd 1299 helpText = new ConfigInfoView(split2, "help");
1da177e4
LT
1300 helpText->setTextFormat(Qt::RichText);
1301
1302 setTabOrder(configList, helpText);
1303 configList->setFocus();
1304
1305 menu = menuBar();
b1f8a45b 1306 toolBar = new QToolBar("Tools", this);
1da177e4 1307
85eaf28a 1308 backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
1da177e4
LT
1309 connect(backAction, SIGNAL(activated()), SLOT(goBack()));
1310 backAction->setEnabled(FALSE);
85eaf28a
BB
1311 QAction *quitAction = new QAction(_("&Quit"), this);
1312 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
1da177e4 1313 connect(quitAction, SIGNAL(activated()), SLOT(close()));
85eaf28a
BB
1314 QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
1315 loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
1da177e4 1316 connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
85eaf28a
BB
1317 saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
1318 saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
1da177e4 1319 connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
3b354c55
KW
1320 conf_set_changed_callback(conf_changed);
1321 // Set saveAction's initial state
1322 conf_changed();
85eaf28a 1323 QAction *saveAsAction = new QAction(_("Save &As..."), this);
1da177e4 1324 connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
85eaf28a
BB
1325 QAction *searchAction = new QAction(_("&Find"), this);
1326 searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
43bf612a 1327 connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
85eaf28a 1328 QAction *singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
1da177e4 1329 connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
85eaf28a 1330 QAction *splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
1da177e4 1331 connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
85eaf28a 1332 QAction *fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
1da177e4
LT
1333 connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
1334
85eaf28a 1335 QAction *showNameAction = new QAction(_("Show Name"), this);
1da177e4 1336 showNameAction->setToggleAction(TRUE);
7fc925fd
RZ
1337 connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
1338 connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
1339 showNameAction->setOn(configView->showName());
85eaf28a 1340 QAction *showRangeAction = new QAction(_("Show Range"), this);
1da177e4 1341 showRangeAction->setToggleAction(TRUE);
7fc925fd
RZ
1342 connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
1343 connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
1da177e4 1344 showRangeAction->setOn(configList->showRange);
85eaf28a 1345 QAction *showDataAction = new QAction(_("Show Data"), this);
1da177e4 1346 showDataAction->setToggleAction(TRUE);
7fc925fd
RZ
1347 connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
1348 connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
1da177e4 1349 showDataAction->setOn(configList->showData);
39a4897c
LZ
1350
1351 QActionGroup *optGroup = new QActionGroup(this);
1352 optGroup->setExclusive(TRUE);
1353 connect(optGroup, SIGNAL(selected(QAction *)), configView,
1354 SLOT(setOptionMode(QAction *)));
1355 connect(optGroup, SIGNAL(selected(QAction *)), menuView,
1356 SLOT(setOptionMode(QAction *)));
1357
133c5f7c
AS
1358 configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
1359 configView->showAllAction = new QAction(_("Show All Options"), optGroup);
1360 configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
39a4897c
LZ
1361 configView->showNormalAction->setToggleAction(TRUE);
1362 configView->showNormalAction->setOn(configList->optMode == normalOpt);
1363 configView->showAllAction->setToggleAction(TRUE);
1364 configView->showAllAction->setOn(configList->optMode == allOpt);
1365 configView->showPromptAction->setToggleAction(TRUE);
1366 configView->showPromptAction->setOn(configList->optMode == promptOpt);
1367
85eaf28a 1368 QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
1da177e4 1369 showDebugAction->setToggleAction(TRUE);
43bf612a
RZ
1370 connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
1371 connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
7fc925fd 1372 showDebugAction->setOn(helpText->showDebug());
1da177e4 1373
85eaf28a 1374 QAction *showIntroAction = new QAction( _("Introduction"), this);
1da177e4 1375 connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
85eaf28a 1376 QAction *showAboutAction = new QAction( _("About"), this);
1da177e4
LT
1377 connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
1378
1379 // init tool bar
1380 backAction->addTo(toolBar);
1381 toolBar->addSeparator();
1382 loadAction->addTo(toolBar);
1383 saveAction->addTo(toolBar);
1384 toolBar->addSeparator();
1385 singleViewAction->addTo(toolBar);
1386 splitViewAction->addTo(toolBar);
1387 fullViewAction->addTo(toolBar);
1388
1389 // create config menu
133c5f7c 1390 Q3PopupMenu* config = new Q3PopupMenu(this);
c21a2d95 1391 menu->insertItem(_("&File"), config);
1da177e4
LT
1392 loadAction->addTo(config);
1393 saveAction->addTo(config);
1394 saveAsAction->addTo(config);
1395 config->insertSeparator();
1396 quitAction->addTo(config);
1397
66e7c723 1398 // create edit menu
133c5f7c 1399 Q3PopupMenu* editMenu = new Q3PopupMenu(this);
c21a2d95 1400 menu->insertItem(_("&Edit"), editMenu);
66e7c723
SF
1401 searchAction->addTo(editMenu);
1402
1da177e4 1403 // create options menu
133c5f7c 1404 Q3PopupMenu* optionMenu = new Q3PopupMenu(this);
c21a2d95 1405 menu->insertItem(_("&Option"), optionMenu);
1da177e4
LT
1406 showNameAction->addTo(optionMenu);
1407 showRangeAction->addTo(optionMenu);
1408 showDataAction->addTo(optionMenu);
1409 optionMenu->insertSeparator();
39a4897c
LZ
1410 optGroup->addTo(optionMenu);
1411 optionMenu->insertSeparator();
1da177e4
LT
1412
1413 // create help menu
133c5f7c 1414 Q3PopupMenu* helpMenu = new Q3PopupMenu(this);
1da177e4 1415 menu->insertSeparator();
c21a2d95 1416 menu->insertItem(_("&Help"), helpMenu);
1da177e4
LT
1417 showIntroAction->addTo(helpMenu);
1418 showAboutAction->addTo(helpMenu);
1419
43bf612a
RZ
1420 connect(configList, SIGNAL(menuChanged(struct menu *)),
1421 helpText, SLOT(setInfo(struct menu *)));
1da177e4
LT
1422 connect(configList, SIGNAL(menuSelected(struct menu *)),
1423 SLOT(changeMenu(struct menu *)));
1424 connect(configList, SIGNAL(parentSelected()),
1425 SLOT(goBack()));
43bf612a
RZ
1426 connect(menuList, SIGNAL(menuChanged(struct menu *)),
1427 helpText, SLOT(setInfo(struct menu *)));
1da177e4
LT
1428 connect(menuList, SIGNAL(menuSelected(struct menu *)),
1429 SLOT(changeMenu(struct menu *)));
1430
b65a47e1
RZ
1431 connect(configList, SIGNAL(gotFocus(struct menu *)),
1432 helpText, SLOT(setInfo(struct menu *)));
1433 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1434 helpText, SLOT(setInfo(struct menu *)));
1435 connect(menuList, SIGNAL(gotFocus(struct menu *)),
1da177e4 1436 SLOT(listFocusChanged(void)));
b65a47e1
RZ
1437 connect(helpText, SIGNAL(menuSelected(struct menu *)),
1438 SLOT(setMenuLink(struct menu *)));
1da177e4 1439
7fc925fd 1440 QString listMode = configSettings->readEntry("/listMode", "symbol");
1da177e4
LT
1441 if (listMode == "single")
1442 showSingleView();
1443 else if (listMode == "full")
1444 showFullView();
1445 else /*if (listMode == "split")*/
1446 showSplitView();
1447
1448 // UI setup done, restore splitter positions
041fbdc2 1449 QList<int> sizes = configSettings->readSizes("/split1", &ok);
1da177e4
LT
1450 if (ok)
1451 split1->setSizes(sizes);
1452
7fc925fd 1453 sizes = configSettings->readSizes("/split2", &ok);
1da177e4
LT
1454 if (ok)
1455 split2->setSizes(sizes);
1da177e4
LT
1456}
1457
1da177e4
LT
1458void ConfigMainWindow::loadConfig(void)
1459{
bea00771 1460 QString s = QFileDialog::getOpenFileName(conf_get_configname(), NULL, this);
1da177e4
LT
1461 if (s.isNull())
1462 return;
3b9fa093 1463 if (conf_read(QFile::encodeName(s)))
c21a2d95 1464 QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
1da177e4
LT
1465 ConfigView::updateListAll();
1466}
1467
bac6aa86 1468bool ConfigMainWindow::saveConfig(void)
1da177e4 1469{
bac6aa86 1470 if (conf_write(NULL)) {
c21a2d95 1471 QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
bac6aa86
MM
1472 return false;
1473 }
1474 return true;
1da177e4
LT
1475}
1476
1477void ConfigMainWindow::saveConfigAs(void)
1478{
bea00771 1479 QString s = QFileDialog::getSaveFileName(conf_get_configname(), NULL, this);
1da177e4
LT
1480 if (s.isNull())
1481 return;
d49e4687 1482 saveConfig();
1da177e4
LT
1483}
1484
43bf612a
RZ
1485void ConfigMainWindow::searchConfig(void)
1486{
1487 if (!searchWindow)
7fc925fd 1488 searchWindow = new ConfigSearchWindow(this, "search");
43bf612a
RZ
1489 searchWindow->show();
1490}
1491
1da177e4
LT
1492void ConfigMainWindow::changeMenu(struct menu *menu)
1493{
1494 configList->setRootMenu(menu);
f253f000
CG
1495 if (configList->rootEntry->parent == &rootmenu)
1496 backAction->setEnabled(FALSE);
1497 else
1498 backAction->setEnabled(TRUE);
1da177e4
LT
1499}
1500
b65a47e1 1501void ConfigMainWindow::setMenuLink(struct menu *menu)
1da177e4 1502{
b65a47e1
RZ
1503 struct menu *parent;
1504 ConfigList* list = NULL;
1505 ConfigItem* item;
1506
39a4897c 1507 if (configList->menuSkip(menu))
b65a47e1
RZ
1508 return;
1509
1510 switch (configList->mode) {
1511 case singleMode:
1512 list = configList;
1513 parent = menu_get_parent_menu(menu);
1514 if (!parent)
1515 return;
1516 list->setRootMenu(parent);
1517 break;
1518 case symbolMode:
1519 if (menu->flags & MENU_ROOT) {
1520 configList->setRootMenu(menu);
1da177e4 1521 configList->clearSelection();
b65a47e1
RZ
1522 list = menuList;
1523 } else {
1524 list = configList;
1525 parent = menu_get_parent_menu(menu->parent);
1526 if (!parent)
1527 return;
1528 item = menuList->findConfigItem(parent);
1529 if (item) {
1530 menuList->setSelected(item, TRUE);
1531 menuList->ensureItemVisible(item);
1532 }
1533 list->setRootMenu(parent);
1534 }
1535 break;
1536 case fullMode:
1537 list = configList;
1538 break;
98403a91
MH
1539 default:
1540 break;
b65a47e1
RZ
1541 }
1542
1543 if (list) {
1544 item = list->findConfigItem(menu);
1545 if (item) {
1546 list->setSelected(item, TRUE);
1547 list->ensureItemVisible(item);
1548 list->setFocus();
1549 }
1da177e4
LT
1550 }
1551}
1552
b65a47e1
RZ
1553void ConfigMainWindow::listFocusChanged(void)
1554{
1555 if (menuList->mode == menuMode)
1556 configList->clearSelection();
1557}
1558
1da177e4
LT
1559void ConfigMainWindow::goBack(void)
1560{
1561 ConfigItem* item;
1562
1563 configList->setParentMenu();
1564 if (configList->rootEntry == &rootmenu)
1565 backAction->setEnabled(FALSE);
1566 item = (ConfigItem*)menuList->selectedItem();
1567 while (item) {
1568 if (item->menu == configList->rootEntry) {
1569 menuList->setSelected(item, TRUE);
1570 break;
1571 }
1572 item = (ConfigItem*)item->parent();
1573 }
1574}
1575
1576void ConfigMainWindow::showSingleView(void)
1577{
1578 menuView->hide();
1579 menuList->setRootMenu(0);
1580 configList->mode = singleMode;
1581 if (configList->rootEntry == &rootmenu)
1582 configList->updateListAll();
1583 else
1584 configList->setRootMenu(&rootmenu);
1585 configList->setAllOpen(TRUE);
1586 configList->setFocus();
1587}
1588
1589void ConfigMainWindow::showSplitView(void)
1590{
1591 configList->mode = symbolMode;
1592 if (configList->rootEntry == &rootmenu)
1593 configList->updateListAll();
1594 else
1595 configList->setRootMenu(&rootmenu);
1596 configList->setAllOpen(TRUE);
1597 configApp->processEvents();
1598 menuList->mode = menuMode;
1599 menuList->setRootMenu(&rootmenu);
1600 menuList->setAllOpen(TRUE);
1601 menuView->show();
1602 menuList->setFocus();
1603}
1604
1605void ConfigMainWindow::showFullView(void)
1606{
1607 menuView->hide();
1608 menuList->setRootMenu(0);
1609 configList->mode = fullMode;
1610 if (configList->rootEntry == &rootmenu)
1611 configList->updateListAll();
1612 else
1613 configList->setRootMenu(&rootmenu);
1614 configList->setAllOpen(FALSE);
1615 configList->setFocus();
1616}
1617
1da177e4
LT
1618/*
1619 * ask for saving configuration before quitting
1620 * TODO ask only when something changed
1621 */
1622void ConfigMainWindow::closeEvent(QCloseEvent* e)
1623{
b3214293 1624 if (!conf_get_changed()) {
1da177e4
LT
1625 e->accept();
1626 return;
1627 }
c21a2d95 1628 QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
1da177e4 1629 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
c21a2d95
EG
1630 mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
1631 mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
1632 mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
1da177e4
LT
1633 switch (mb.exec()) {
1634 case QMessageBox::Yes:
bac6aa86
MM
1635 if (saveConfig())
1636 e->accept();
1637 else
1638 e->ignore();
1639 break;
1da177e4
LT
1640 case QMessageBox::No:
1641 e->accept();
1642 break;
1643 case QMessageBox::Cancel:
1644 e->ignore();
1645 break;
1646 }
1647}
1648
1649void ConfigMainWindow::showIntro(void)
1650{
652cf982 1651 static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
1da177e4
LT
1652 "For each option, a blank box indicates the feature is disabled, a check\n"
1653 "indicates it is enabled, and a dot indicates that it is to be compiled\n"
1654 "as a module. Clicking on the box will cycle through the three states.\n\n"
1655 "If you do not see an option (e.g., a device driver) that you believe\n"
1656 "should be present, try turning on Show All Options under the Options menu.\n"
1657 "Although there is no cross reference yet to help you figure out what other\n"
1658 "options must be enabled to support the option you are interested in, you can\n"
1659 "still view the help of a grayed-out option.\n\n"
1660 "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
c21a2d95 1661 "which you can then match by examining other options.\n\n");
1da177e4
LT
1662
1663 QMessageBox::information(this, "qconf", str);
1664}
1665
1666void ConfigMainWindow::showAbout(void)
1667{
c21a2d95
EG
1668 static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
1669 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
1da177e4
LT
1670
1671 QMessageBox::information(this, "qconf", str);
1672}
1673
1674void ConfigMainWindow::saveSettings(void)
1675{
7fc925fd
RZ
1676 configSettings->writeEntry("/window x", pos().x());
1677 configSettings->writeEntry("/window y", pos().y());
1678 configSettings->writeEntry("/window width", size().width());
1679 configSettings->writeEntry("/window height", size().height());
1da177e4
LT
1680
1681 QString entry;
1682 switch(configList->mode) {
1683 case singleMode :
1684 entry = "single";
1685 break;
1686
1687 case symbolMode :
1688 entry = "split";
1689 break;
1690
1691 case fullMode :
1692 entry = "full";
1693 break;
98403a91
MH
1694
1695 default:
1696 break;
1da177e4 1697 }
7fc925fd 1698 configSettings->writeEntry("/listMode", entry);
1da177e4 1699
7fc925fd
RZ
1700 configSettings->writeSizes("/split1", split1->sizes());
1701 configSettings->writeSizes("/split2", split2->sizes());
1da177e4
LT
1702}
1703
3b354c55
KW
1704void ConfigMainWindow::conf_changed(void)
1705{
1706 if (saveAction)
1707 saveAction->setEnabled(conf_get_changed());
1708}
1709
1da177e4
LT
1710void fixup_rootmenu(struct menu *menu)
1711{
1712 struct menu *child;
1713 static int menu_cnt = 0;
1714
1715 menu->flags |= MENU_ROOT;
1716 for (child = menu->list; child; child = child->next) {
1717 if (child->prompt && child->prompt->type == P_MENU) {
1718 menu_cnt++;
1719 fixup_rootmenu(child);
1720 menu_cnt--;
1721 } else if (!menu_cnt)
1722 fixup_rootmenu(child);
1723 }
1724}
1725
1726static const char *progname;
1727
1728static void usage(void)
1729{
0a1f00a1 1730 printf(_("%s [-s] <config>\n"), progname);
1da177e4
LT
1731 exit(0);
1732}
1733
1734int main(int ac, char** av)
1735{
1736 ConfigMainWindow* v;
1737 const char *name;
1738
3b9fa093
ACM
1739 bindtextdomain(PACKAGE, LOCALEDIR);
1740 textdomain(PACKAGE);
1741
1da177e4
LT
1742 progname = av[0];
1743 configApp = new QApplication(ac, av);
1744 if (ac > 1 && av[1][0] == '-') {
1745 switch (av[1][1]) {
0a1f00a1
MM
1746 case 's':
1747 conf_set_message_callback(NULL);
1748 break;
1da177e4
LT
1749 case 'h':
1750 case '?':
1751 usage();
1752 }
1753 name = av[2];
1754 } else
1755 name = av[1];
1756 if (!name)
1757 usage();
1758
1759 conf_parse(name);
1760 fixup_rootmenu(&rootmenu);
1761 conf_read(NULL);
1762 //zconfdump(stdout);
1763
7fc925fd
RZ
1764 configSettings = new ConfigSettings();
1765 configSettings->beginGroup("/kconfig/qconf");
1da177e4
LT
1766 v = new ConfigMainWindow();
1767
1768 //zconfdump(stdout);
43bf612a 1769 configApp->setMainWidget(v);
1da177e4
LT
1770 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1771 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
43bf612a 1772 v->show();
1da177e4
LT
1773 configApp->exec();
1774
7fc925fd
RZ
1775 configSettings->endGroup();
1776 delete configSettings;
1777
1da177e4
LT
1778 return 0;
1779}
This page took 0.718764 seconds and 5 git commands to generate.