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