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