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

