-rw-r--r-- | scripts/kconfig/qconf.cc | 274 |
1 files changed, 202 insertions, 72 deletions
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index feefa1c..bed541d 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc @@ -12,25 +12,32 @@ #include <qtextview.h> #include <qlineedit.h> #include <qmenubar.h> #include <qmessagebox.h> #include <qaction.h> #include <qheader.h> #include <qfiledialog.h> #include <qregexp.h> +#if QT_VERSION >= 300 +#include <qsettings.h> +#endif + #include <stdlib.h> #include "lkc.h" #include "qconf.h" #include "qconf.moc" #include "images.c" static QApplication *configApp; +#if QT_VERSION >= 300 +static QSettings *configSettings; +#endif /* * update all the children of a menu entry * removes/adds the entries from the parent widget as necessary * * parent: either the menu list widget or a menu entry widget * menu: entry to be updated */ @@ -68,19 +75,27 @@ static void updateMenuList(P* parent, struct menu* menu) break; default: break; } visible = menu_is_visible(child); if (showAll || visible) { if (!item || item->menu != child) - item = new ConfigItem(parent, last, child); - item->visible = visible; - item->updateMenu(); + item = new ConfigItem(parent, last, child, visible); + else { + item->visible = visible; + if (item->updateNeeded()) { + ConfigItem* i = (ConfigItem*)child->data; + for (; i; i = i->nextItem) { + i->updateMenu(); + } + } else if (list->updateAll) + item->updateMenu(); + } if (mode == fullMode || mode == menuMode || (type != P_MENU && type != P_ROOTMENU)) updateMenuList(item, child); else updateMenuList(item, 0); last = item; continue; @@ -115,46 +130,32 @@ void ConfigItem::okRename(int col) void ConfigItem::updateMenu(void) { ConfigList* list; struct symbol* sym; QString prompt; int type; enum prop_type ptype; tristate expr; - bool update; list = listView(); - update = doInit; - if (update) - doInit = false; - else - update = list->updateAll; sym = menu->sym; if (!sym) { - if (update) { - setText(promptColIdx, menu_get_prompt(menu)); - ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; - if ((ptype == P_ROOTMENU || ptype == P_MENU) && - (list->mode == singleMode || list->mode == symbolMode)) - setPixmap(promptColIdx, list->menuPix); - else - setPixmap(promptColIdx, 0); - } + setText(promptColIdx, menu_get_prompt(menu)); + ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; + if ((ptype == P_ROOTMENU || ptype == P_MENU) && + (list->mode == singleMode || list->mode == symbolMode)) + setPixmap(promptColIdx, list->menuPix); + else + setPixmap(promptColIdx, 0); return; } - sym_calc_value(sym); - if (!(sym->flags & SYMBOL_CHANGED) && !update) - return; - - sym->flags &= ~SYMBOL_CHANGED; - - setText(nameColIdx, menu->sym->name); + setText(nameColIdx, sym->name); type = sym_get_type(sym); switch (type) { case S_BOOLEAN: case S_TRISTATE: char ch; prompt = menu_get_prompt(menu); @@ -199,30 +200,44 @@ void ConfigItem::updateMenu(void) break; case S_INT: case S_HEX: case S_STRING: const char* data; data = sym_get_string_value(sym); #if QT_VERSION >= 300 - setRenameEnabled(list->mapIdx(dataColIdx), TRUE); + int i = list->mapIdx(dataColIdx); + if (i >= 0) + setRenameEnabled(i, TRUE); #endif setText(dataColIdx, data); if (type == S_STRING) prompt.sprintf("%s: %s", menu_get_prompt(menu), data); else prompt.sprintf("(%s) %s", data, menu_get_prompt(menu)); break; } if (!sym_has_value(sym) && visible) prompt += " (NEW)"; setText(promptColIdx, prompt); } +bool ConfigItem::updateNeeded(void) +{ + struct symbol* sym = menu->sym; + if (sym) + sym_calc_value(sym); + if (menu->flags & MENU_CHANGED) { + menu->flags &= ~MENU_CHANGED; + return true; + } + return false; +} + void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align) { ConfigList* list = listView(); if (visible) { if (isSelected() && !list->hasFocus() && list->mode == menuMode) Parent::paintCell(p, list->inactivedColorGroup, column, width, align); else @@ -232,31 +247,38 @@ void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int w } /* * construct a menu entry */ void ConfigItem::init(void) { ConfigList* list = listView(); -#if QT_VERSION < 300 - visible = TRUE; -#endif - //menu->data = this; + nextItem = (ConfigItem*)menu->data; + menu->data = this; + if (list->mode != fullMode) setOpen(TRUE); - doInit= true; + if (menu->sym) + sym_calc_value(menu->sym); + updateMenu(); } /* * destruct a menu entry */ ConfigItem::~ConfigItem(void) { - //menu->data = 0; + ConfigItem** ip = &(ConfigItem*)menu->data; + for (; *ip; ip = &(*ip)->nextItem) { + if (*ip == this) { + *ip = nextItem; + break; + } + } } void ConfigLineEdit::show(ConfigItem* i) { item = i; if (sym_get_string_value(item->menu->sym)) setText(sym_get_string_value(item->menu->sym)); else @@ -268,27 +290,28 @@ void ConfigLineEdit::show(ConfigItem* i) void ConfigLineEdit::keyPressEvent(QKeyEvent* e) { switch (e->key()) { case Key_Escape: break; case Key_Return: case Key_Enter: sym_set_string_value(item->menu->sym, text().latin1()); - emit lineChanged(item); + parent()->updateList(item); break; default: Parent::keyPressEvent(e); return; } e->accept(); + parent()->list->setFocus(); hide(); } -ConfigList::ConfigList(QWidget* p, ConfigView* cv) +ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv) : Parent(p), cview(cv), updateAll(false), symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv), showAll(false), showName(false), showRange(false), showData(false), rootEntry(0) { int i; @@ -347,16 +370,17 @@ void ConfigList::updateSelection(void) if (mode == menuMode && (type == P_MENU || type == P_ROOTMENU)) emit menuSelected(menu); } void ConfigList::updateList(ConfigItem* item) { (void)item; // unused so far updateMenuList(this, rootEntry); + triggerUpdate(); } void ConfigList::setAllOpen(bool open) { QListViewItemIterator it(this); for (; it.current(); it++) it.current()->setOpen(open); @@ -377,17 +401,17 @@ void ConfigList::setValue(ConfigItem* item, tristate val) case S_BOOLEAN: case S_TRISTATE: oldval = sym_get_tristate_value(sym); if (!sym_set_tristate_value(sym, val)) return; if (oldval == no && item->menu->list) item->setOpen(TRUE); - emit symbolChanged(item); + parent()->updateList(item); break; } } void ConfigList::changeValue(ConfigItem* item) { struct symbol* sym; struct menu* menu; @@ -409,27 +433,27 @@ void ConfigList::changeValue(ConfigItem* item) newexpr = sym_toggle_tristate_value(sym); if (item->menu->list) { if (oldexpr == newexpr) item->setOpen(!item->isOpen()); else if (oldexpr == no) item->setOpen(TRUE); } if (oldexpr != newexpr) - emit symbolChanged(item); + parent()->updateList(item); break; case S_INT: case S_HEX: case S_STRING: #if QT_VERSION >= 300 if (colMap[dataColIdx] >= 0) item->startRename(colMap[dataColIdx]); else #endif - lineEdit->show(item); + parent()->lineEdit->show(item); break; } } void ConfigList::setRootMenu(struct menu *menu) { enum prop_type type; @@ -511,17 +535,17 @@ void ConfigList::keyPressEvent(QKeyEvent* ev) } ev->accept(); } void ConfigList::contentsMousePressEvent(QMouseEvent* e) { //QPoint p(contentsToViewport(e->pos())); //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y()); - QListView::contentsMousePressEvent(e); + Parent::contentsMousePressEvent(e); } void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e) { QPoint p(contentsToViewport(e->pos())); ConfigItem* item = (ConfigItem*)itemAt(p); struct menu *menu; const QPixmap* pm; @@ -558,89 +582,145 @@ void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e) break; case dataColIdx: changeValue(item); break; } skip: //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y()); - QListView::contentsMouseReleaseEvent(e); + Parent::contentsMouseReleaseEvent(e); } void ConfigList::contentsMouseMoveEvent(QMouseEvent* e) { //QPoint p(contentsToViewport(e->pos())); //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y()); - QListView::contentsMouseMoveEvent(e); + Parent::contentsMouseMoveEvent(e); } void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e) { QPoint p(contentsToViewport(e->pos())); ConfigItem* item = (ConfigItem*)itemAt(p); struct menu *menu; enum prop_type ptype; if (!item) goto skip; menu = item->menu; ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; if ((ptype == P_ROOTMENU || ptype == P_MENU) && (mode == singleMode || mode == symbolMode)) emit menuSelected(menu); + else if (menu->sym) + changeValue(item); skip: //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y()); - QListView::contentsMouseDoubleClickEvent(e); + Parent::contentsMouseDoubleClickEvent(e); } void ConfigList::focusInEvent(QFocusEvent *e) { Parent::focusInEvent(e); QListViewItem* item = currentItem(); if (!item) return; setSelected(item, TRUE); emit gotFocus(); } +ConfigView* ConfigView::viewList; + +ConfigView::ConfigView(QWidget* parent, ConfigMainWindow* cview) + : Parent(parent) +{ + list = new ConfigList(this, cview); + lineEdit = new ConfigLineEdit(this); + lineEdit->hide(); + + this->nextView = viewList; + viewList = this; +} + +ConfigView::~ConfigView(void) +{ + ConfigView** vp; + + for (vp = &viewList; *vp; vp = &(*vp)->nextView) { + if (*vp == this) { + *vp = nextView; + break; + } + } +} + +void ConfigView::updateList(ConfigItem* item) +{ + ConfigView* v; + + for (v = viewList; v; v = v->nextView) + v->list->updateList(item); +} + +void ConfigView::updateListAll(void) +{ + ConfigView* v; + + for (v = viewList; v; v = v->nextView) + v->list->updateListAll(); +} + /* * Construct the complete config widget */ -ConfigView::ConfigView(void) +ConfigMainWindow::ConfigMainWindow(void) { + ConfigView* view; QMenuBar* menu; QSplitter* split1; QSplitter* split2; + bool ok; + int x, y, width, height; + + QWidget *d = configApp->desktop(); + +#if QT_VERSION >= 300 + width = configSettings->readNumEntry("/kconfig/qconf/window width", d->width() - 64); + height = configSettings->readNumEntry("/kconfig/qconf/window height", d->height() - 64); + resize(width, height); + x = configSettings->readNumEntry("/kconfig/qconf/window x", 0, &ok); + if (ok) + y = configSettings->readNumEntry("/kconfig/qconf/window y", 0, &ok); + if (ok) + move(x, y); +#else + width = d->width() - 64; + height = d->height() - 64; + resize(width, height); +#endif showDebug = false; split1 = new QSplitter(this); split1->setOrientation(QSplitter::Horizontal); setCentralWidget(split1); - menuList = new ConfigList(split1, this); + view = new ConfigView(split1, this); + menuList = view->list; split2 = new QSplitter(split1); split2->setOrientation(QSplitter::Vertical); // create config tree - QVBox* box = new QVBox(split2); - configList = new ConfigList(box, this); - configList->lineEdit = new ConfigLineEdit(box); - configList->lineEdit->hide(); - configList->connect(configList, SIGNAL(symbolChanged(ConfigItem*)), - configList, SLOT(updateList(ConfigItem*))); - configList->connect(configList, SIGNAL(symbolChanged(ConfigItem*)), - menuList, SLOT(updateList(ConfigItem*))); - configList->connect(configList->lineEdit, SIGNAL(lineChanged(ConfigItem*)), - SLOT(updateList(ConfigItem*))); + view = new ConfigView(split2, this); + configList = view->list; helpText = new QTextView(split2); helpText->setTextFormat(Qt::RichText); setTabOrder(configList, helpText); configList->setFocus(); menu = menuBar(); @@ -680,16 +760,21 @@ ConfigView::ConfigView(void) showAllAction->setToggleAction(TRUE); showAllAction->setOn(configList->showAll); connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool))); QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this); showDebugAction->setToggleAction(TRUE); showDebugAction->setOn(showDebug); connect(showDebugAction, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); + QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this); + connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro())); + QAction *showAboutAction = new QAction(NULL, "About", 0, this); + connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout())); + // init tool bar backAction->addTo(toolBar); toolBar->addSeparator(); loadAction->addTo(toolBar); saveAction->addTo(toolBar); toolBar->addSeparator(); singleViewAction->addTo(toolBar); splitViewAction->addTo(toolBar); @@ -709,16 +794,23 @@ ConfigView::ConfigView(void) menu->insertItem("&Option", optionMenu); showNameAction->addTo(optionMenu); showRangeAction->addTo(optionMenu); showDataAction->addTo(optionMenu); optionMenu->insertSeparator(); showAllAction->addTo(optionMenu); showDebugAction->addTo(optionMenu); + // create help menu + QPopupMenu* helpMenu = new QPopupMenu(this); + menu->insertSeparator(); + menu->insertItem("&Help", helpMenu); + showIntroAction->addTo(helpMenu); + showAboutAction->addTo(helpMenu); + connect(configList, SIGNAL(menuSelected(struct menu *)), SLOT(changeMenu(struct menu *))); connect(configList, SIGNAL(parentSelected()), SLOT(goBack())); connect(menuList, SIGNAL(menuSelected(struct menu *)), SLOT(changeMenu(struct menu *))); connect(configList, SIGNAL(gotFocus(void)), @@ -764,22 +856,22 @@ static QString print_filter(const char *str) static void expr_print_help(void *data, const char *str) { ((QString*)data)->append(print_filter(str)); } /* * display a new help entry as soon as a new menu entry is selected */ -void ConfigView::setHelp(QListViewItem* item) +void ConfigMainWindow::setHelp(QListViewItem* item) { struct symbol* sym; struct menu* menu; - configList->lineEdit->hide(); + configList->parent()->lineEdit->hide(); if (item) { QString head, debug, help; menu = ((ConfigItem*)item)->menu; sym = menu->sym; if (sym) { if (menu->prompt) { head += "<big><b>"; head += print_filter(menu->prompt->text); @@ -852,162 +944,163 @@ void ConfigView::setHelp(QListViewItem* item) } } helpText->setText(head + debug + help); return; } helpText->setText(NULL); } -void ConfigView::loadConfig(void) +void ConfigMainWindow::loadConfig(void) { QString s = QFileDialog::getOpenFileName(".config", NULL, this); if (s.isNull()) return; if (conf_read(s.latin1())) QMessageBox::information(this, "qconf", "Unable to load configuration!"); + ConfigView::updateListAll(); } -void ConfigView::saveConfig(void) +void ConfigMainWindow::saveConfig(void) { if (conf_write(NULL)) QMessageBox::information(this, "qconf", "Unable to save configuration!"); } -void ConfigView::saveConfigAs(void) +void ConfigMainWindow::saveConfigAs(void) { QString s = QFileDialog::getSaveFileName(".config", NULL, this); if (s.isNull()) return; if (conf_write(s.latin1())) QMessageBox::information(this, "qconf", "Unable to save configuration!"); } -void ConfigView::changeMenu(struct menu *menu) +void ConfigMainWindow::changeMenu(struct menu *menu) { configList->setRootMenu(menu); backAction->setEnabled(TRUE); } -void ConfigView::listFocusChanged(void) +void ConfigMainWindow::listFocusChanged(void) { if (menuList->hasFocus()) { if (menuList->mode == menuMode) configList->clearSelection(); setHelp(menuList->selectedItem()); } else if (configList->hasFocus()) { setHelp(configList->selectedItem()); } } -void ConfigView::goBack(void) +void ConfigMainWindow::goBack(void) { ConfigItem* item; configList->setParentMenu(); if (configList->rootEntry == &rootmenu) backAction->setEnabled(FALSE); item = (ConfigItem*)menuList->selectedItem(); while (item) { if (item->menu == configList->rootEntry) { menuList->setSelected(item, TRUE); break; } item = (ConfigItem*)item->parent(); } } -void ConfigView::showSingleView(void) +void ConfigMainWindow::showSingleView(void) { menuList->hide(); menuList->setRootMenu(0); configList->mode = singleMode; if (configList->rootEntry == &rootmenu) configList->updateListAll(); else configList->setRootMenu(&rootmenu); configList->setAllOpen(TRUE); configList->setFocus(); } -void ConfigView::showSplitView(void) +void ConfigMainWindow::showSplitView(void) { configList->mode = symbolMode; if (configList->rootEntry == &rootmenu) configList->updateListAll(); else configList->setRootMenu(&rootmenu); configList->setAllOpen(TRUE); configApp->processEvents(); menuList->mode = menuMode; menuList->setRootMenu(&rootmenu); menuList->show(); menuList->setAllOpen(TRUE); menuList->setFocus(); } -void ConfigView::showFullView(void) +void ConfigMainWindow::showFullView(void) { menuList->hide(); menuList->setRootMenu(0); configList->mode = fullMode; if (configList->rootEntry == &rootmenu) configList->updateListAll(); else configList->setRootMenu(&rootmenu); configList->setAllOpen(FALSE); configList->setFocus(); } -void ConfigView::setShowAll(bool b) +void ConfigMainWindow::setShowAll(bool b) { if (configList->showAll == b) return; configList->showAll = b; configList->updateListAll(); menuList->showAll = b; menuList->updateListAll(); } -void ConfigView::setShowDebug(bool b) +void ConfigMainWindow::setShowDebug(bool b) { if (showDebug == b) return; showDebug = b; } -void ConfigView::setShowName(bool b) +void ConfigMainWindow::setShowName(bool b) { if (configList->showName == b) return; configList->showName = b; configList->reinit(); } -void ConfigView::setShowRange(bool b) +void ConfigMainWindow::setShowRange(bool b) { if (configList->showRange == b) return; configList->showRange = b; configList->reinit(); } -void ConfigView::setShowData(bool b) +void ConfigMainWindow::setShowData(bool b) { if (configList->showData == b) return; configList->showData = b; configList->reinit(); } /* * ask for saving configuration before quitting * TODO ask only when something changed */ -void ConfigView::closeEvent(QCloseEvent* e) +void ConfigMainWindow::closeEvent(QCloseEvent* e) { if (!sym_change_count) { e->accept(); return; } QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning, QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); mb.setButtonText(QMessageBox::Yes, "&Save Changes"); @@ -1020,37 +1113,65 @@ void ConfigView::closeEvent(QCloseEvent* e) e->accept(); break; case QMessageBox::Cancel: e->ignore(); break; } } +void ConfigMainWindow::showIntro(void) +{ + static char str[] = "Welcome to the qconf graphical kernel configuration tool for Linux.\n\n" + "For each option, a blank box indicates the feature is disabled, a check\n" + "indicates it is enabled, and a dot indicates that it is to be compiled\n" + "as a module. Clicking on the box will cycle through the three states.\n\n" + "If you do not see an option (e.g., a device driver) that you believe\n" + "should be present, try turning on Show All Options under the Options menu.\n" + "Although there is no cross reference yet to help you figure out what other\n" + "options must be enabled to support the option you are interested in, you can\n" + "still view the help of a grayed-out option.\n\n" + "Toggling Show Debug Info under the Options menu will show the dependencies,\n" + "which you can then match by examining other options.\n\n"; + + QMessageBox::information(this, "qconf", str); +} + +void ConfigMainWindow::showAbout(void) +{ + static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n" + "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"; + + QMessageBox::information(this, "qconf", str); +} + void fixup_rootmenu(struct menu *menu) { struct menu *child; if (!menu->prompt || menu->prompt->type != P_MENU) return; menu->prompt->type = P_ROOTMENU; for (child = menu->list; child; child = child->next) fixup_rootmenu(child); } int main(int ac, char** av) { - ConfigView* v; + ConfigMainWindow* v; const char *name; #ifndef LKC_DIRECT_LINK kconfig_load(); #endif configApp = new QApplication(ac, av); +#if QT_VERSION >= 300 + configSettings = new QSettings; +#endif if (ac > 1 && av[1][0] == '-') { switch (av[1][1]) { case 'a': //showAll = 1; break; case 'h': case '?': printf("%s <config>\n", av[0]); @@ -1058,16 +1179,25 @@ int main(int ac, char** av) } name = av[2]; } else name = av[1]; conf_parse(name); fixup_rootmenu(&rootmenu); conf_read(NULL); //zconfdump(stdout); - v = new ConfigView(); + + v = new ConfigMainWindow(); //zconfdump(stdout); v->show(); configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); configApp->exec(); + +#if QT_VERSION >= 300 + configSettings->writeEntry("/kconfig/qconf/window x", v->pos().x()); + configSettings->writeEntry("/kconfig/qconf/window y", v->pos().y()); + configSettings->writeEntry("/kconfig/qconf/window width", v->size().width()); + configSettings->writeEntry("/kconfig/qconf/window height", v->size().height()); + delete configSettings; +#endif return 0; } |