Linux Audio

Check our new training course

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