Linux Audio

Check our new training course

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