Linux Audio

Check our new training course

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