162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
462306a36Sopenharmony_ci * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <QAction>
862306a36Sopenharmony_ci#include <QActionGroup>
962306a36Sopenharmony_ci#include <QApplication>
1062306a36Sopenharmony_ci#include <QCloseEvent>
1162306a36Sopenharmony_ci#include <QDebug>
1262306a36Sopenharmony_ci#include <QFileDialog>
1362306a36Sopenharmony_ci#include <QLabel>
1462306a36Sopenharmony_ci#include <QLayout>
1562306a36Sopenharmony_ci#include <QList>
1662306a36Sopenharmony_ci#include <QMenu>
1762306a36Sopenharmony_ci#include <QMenuBar>
1862306a36Sopenharmony_ci#include <QMessageBox>
1962306a36Sopenharmony_ci#include <QRegularExpression>
2062306a36Sopenharmony_ci#include <QScreen>
2162306a36Sopenharmony_ci#include <QToolBar>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#include <stdlib.h>
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#include "lkc.h"
2662306a36Sopenharmony_ci#include "qconf.h"
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#include "images.h"
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_cistatic QApplication *configApp;
3262306a36Sopenharmony_cistatic ConfigSettings *configSettings;
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ciQAction *ConfigMainWindow::saveAction;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ciConfigSettings::ConfigSettings()
3762306a36Sopenharmony_ci	: QSettings("kernel.org", "qconf")
3862306a36Sopenharmony_ci{
3962306a36Sopenharmony_ci}
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/**
4262306a36Sopenharmony_ci * Reads a list of integer values from the application settings.
4362306a36Sopenharmony_ci */
4462306a36Sopenharmony_ciQList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
4562306a36Sopenharmony_ci{
4662306a36Sopenharmony_ci	QList<int> result;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	if (contains(key))
4962306a36Sopenharmony_ci	{
5062306a36Sopenharmony_ci		QStringList entryList = value(key).toStringList();
5162306a36Sopenharmony_ci		QStringList::Iterator it;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci		for (it = entryList.begin(); it != entryList.end(); ++it)
5462306a36Sopenharmony_ci			result.push_back((*it).toInt());
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci		*ok = true;
5762306a36Sopenharmony_ci	}
5862306a36Sopenharmony_ci	else
5962306a36Sopenharmony_ci		*ok = false;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	return result;
6262306a36Sopenharmony_ci}
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci/**
6562306a36Sopenharmony_ci * Writes a list of integer values to the application settings.
6662306a36Sopenharmony_ci */
6762306a36Sopenharmony_cibool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	QStringList stringList;
7062306a36Sopenharmony_ci	QList<int>::ConstIterator it;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	for (it = value.begin(); it != value.end(); ++it)
7362306a36Sopenharmony_ci		stringList.push_back(QString::number(*it));
7462306a36Sopenharmony_ci	setValue(key, stringList);
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci	return true;
7762306a36Sopenharmony_ci}
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ciQIcon ConfigItem::symbolYesIcon;
8062306a36Sopenharmony_ciQIcon ConfigItem::symbolModIcon;
8162306a36Sopenharmony_ciQIcon ConfigItem::symbolNoIcon;
8262306a36Sopenharmony_ciQIcon ConfigItem::choiceYesIcon;
8362306a36Sopenharmony_ciQIcon ConfigItem::choiceNoIcon;
8462306a36Sopenharmony_ciQIcon ConfigItem::menuIcon;
8562306a36Sopenharmony_ciQIcon ConfigItem::menubackIcon;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci/*
8862306a36Sopenharmony_ci * update the displayed of a menu entry
8962306a36Sopenharmony_ci */
9062306a36Sopenharmony_civoid ConfigItem::updateMenu(void)
9162306a36Sopenharmony_ci{
9262306a36Sopenharmony_ci	ConfigList* list;
9362306a36Sopenharmony_ci	struct symbol* sym;
9462306a36Sopenharmony_ci	struct property *prop;
9562306a36Sopenharmony_ci	QString prompt;
9662306a36Sopenharmony_ci	int type;
9762306a36Sopenharmony_ci	tristate expr;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	list = listView();
10062306a36Sopenharmony_ci	if (goParent) {
10162306a36Sopenharmony_ci		setIcon(promptColIdx, menubackIcon);
10262306a36Sopenharmony_ci		prompt = "..";
10362306a36Sopenharmony_ci		goto set_prompt;
10462306a36Sopenharmony_ci	}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	sym = menu->sym;
10762306a36Sopenharmony_ci	prop = menu->prompt;
10862306a36Sopenharmony_ci	prompt = menu_get_prompt(menu);
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci	if (prop) switch (prop->type) {
11162306a36Sopenharmony_ci	case P_MENU:
11262306a36Sopenharmony_ci		if (list->mode == singleMode || list->mode == symbolMode) {
11362306a36Sopenharmony_ci			/* a menuconfig entry is displayed differently
11462306a36Sopenharmony_ci			 * depending whether it's at the view root or a child.
11562306a36Sopenharmony_ci			 */
11662306a36Sopenharmony_ci			if (sym && list->rootEntry == menu)
11762306a36Sopenharmony_ci				break;
11862306a36Sopenharmony_ci			setIcon(promptColIdx, menuIcon);
11962306a36Sopenharmony_ci		} else {
12062306a36Sopenharmony_ci			if (sym)
12162306a36Sopenharmony_ci				break;
12262306a36Sopenharmony_ci			setIcon(promptColIdx, QIcon());
12362306a36Sopenharmony_ci		}
12462306a36Sopenharmony_ci		goto set_prompt;
12562306a36Sopenharmony_ci	case P_COMMENT:
12662306a36Sopenharmony_ci		setIcon(promptColIdx, QIcon());
12762306a36Sopenharmony_ci		prompt = "*** " + prompt + " ***";
12862306a36Sopenharmony_ci		goto set_prompt;
12962306a36Sopenharmony_ci	default:
13062306a36Sopenharmony_ci		;
13162306a36Sopenharmony_ci	}
13262306a36Sopenharmony_ci	if (!sym)
13362306a36Sopenharmony_ci		goto set_prompt;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	setText(nameColIdx, sym->name);
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci	type = sym_get_type(sym);
13862306a36Sopenharmony_ci	switch (type) {
13962306a36Sopenharmony_ci	case S_BOOLEAN:
14062306a36Sopenharmony_ci	case S_TRISTATE:
14162306a36Sopenharmony_ci		char ch;
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci		if (!sym_is_changeable(sym) && list->optMode == normalOpt) {
14462306a36Sopenharmony_ci			setIcon(promptColIdx, QIcon());
14562306a36Sopenharmony_ci			break;
14662306a36Sopenharmony_ci		}
14762306a36Sopenharmony_ci		expr = sym_get_tristate_value(sym);
14862306a36Sopenharmony_ci		switch (expr) {
14962306a36Sopenharmony_ci		case yes:
15062306a36Sopenharmony_ci			if (sym_is_choice_value(sym) && type == S_BOOLEAN)
15162306a36Sopenharmony_ci				setIcon(promptColIdx, choiceYesIcon);
15262306a36Sopenharmony_ci			else
15362306a36Sopenharmony_ci				setIcon(promptColIdx, symbolYesIcon);
15462306a36Sopenharmony_ci			ch = 'Y';
15562306a36Sopenharmony_ci			break;
15662306a36Sopenharmony_ci		case mod:
15762306a36Sopenharmony_ci			setIcon(promptColIdx, symbolModIcon);
15862306a36Sopenharmony_ci			ch = 'M';
15962306a36Sopenharmony_ci			break;
16062306a36Sopenharmony_ci		default:
16162306a36Sopenharmony_ci			if (sym_is_choice_value(sym) && type == S_BOOLEAN)
16262306a36Sopenharmony_ci				setIcon(promptColIdx, choiceNoIcon);
16362306a36Sopenharmony_ci			else
16462306a36Sopenharmony_ci				setIcon(promptColIdx, symbolNoIcon);
16562306a36Sopenharmony_ci			ch = 'N';
16662306a36Sopenharmony_ci			break;
16762306a36Sopenharmony_ci		}
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci		setText(dataColIdx, QChar(ch));
17062306a36Sopenharmony_ci		break;
17162306a36Sopenharmony_ci	case S_INT:
17262306a36Sopenharmony_ci	case S_HEX:
17362306a36Sopenharmony_ci	case S_STRING:
17462306a36Sopenharmony_ci		setText(dataColIdx, sym_get_string_value(sym));
17562306a36Sopenharmony_ci		break;
17662306a36Sopenharmony_ci	}
17762306a36Sopenharmony_ci	if (!sym_has_value(sym) && visible)
17862306a36Sopenharmony_ci		prompt += " (NEW)";
17962306a36Sopenharmony_ciset_prompt:
18062306a36Sopenharmony_ci	setText(promptColIdx, prompt);
18162306a36Sopenharmony_ci}
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_civoid ConfigItem::testUpdateMenu(bool v)
18462306a36Sopenharmony_ci{
18562306a36Sopenharmony_ci	ConfigItem* i;
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_ci	visible = v;
18862306a36Sopenharmony_ci	if (!menu)
18962306a36Sopenharmony_ci		return;
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	sym_calc_value(menu->sym);
19262306a36Sopenharmony_ci	if (menu->flags & MENU_CHANGED) {
19362306a36Sopenharmony_ci		/* the menu entry changed, so update all list items */
19462306a36Sopenharmony_ci		menu->flags &= ~MENU_CHANGED;
19562306a36Sopenharmony_ci		for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
19662306a36Sopenharmony_ci			i->updateMenu();
19762306a36Sopenharmony_ci	} else if (listView()->updateAll)
19862306a36Sopenharmony_ci		updateMenu();
19962306a36Sopenharmony_ci}
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci/*
20362306a36Sopenharmony_ci * construct a menu entry
20462306a36Sopenharmony_ci */
20562306a36Sopenharmony_civoid ConfigItem::init(void)
20662306a36Sopenharmony_ci{
20762306a36Sopenharmony_ci	if (menu) {
20862306a36Sopenharmony_ci		ConfigList* list = listView();
20962306a36Sopenharmony_ci		nextItem = (ConfigItem*)menu->data;
21062306a36Sopenharmony_ci		menu->data = this;
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci		if (list->mode != fullMode)
21362306a36Sopenharmony_ci			setExpanded(true);
21462306a36Sopenharmony_ci		sym_calc_value(menu->sym);
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci		if (menu->sym) {
21762306a36Sopenharmony_ci			enum symbol_type type = menu->sym->type;
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci			// Allow to edit "int", "hex", and "string" in-place in
22062306a36Sopenharmony_ci			// the data column. Unfortunately, you cannot specify
22162306a36Sopenharmony_ci			// the flags per column. Set ItemIsEditable for all
22262306a36Sopenharmony_ci			// columns here, and check the column in createEditor().
22362306a36Sopenharmony_ci			if (type == S_INT || type == S_HEX || type == S_STRING)
22462306a36Sopenharmony_ci				setFlags(flags() | Qt::ItemIsEditable);
22562306a36Sopenharmony_ci		}
22662306a36Sopenharmony_ci	}
22762306a36Sopenharmony_ci	updateMenu();
22862306a36Sopenharmony_ci}
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci/*
23162306a36Sopenharmony_ci * destruct a menu entry
23262306a36Sopenharmony_ci */
23362306a36Sopenharmony_ciConfigItem::~ConfigItem(void)
23462306a36Sopenharmony_ci{
23562306a36Sopenharmony_ci	if (menu) {
23662306a36Sopenharmony_ci		ConfigItem** ip = (ConfigItem**)&menu->data;
23762306a36Sopenharmony_ci		for (; *ip; ip = &(*ip)->nextItem) {
23862306a36Sopenharmony_ci			if (*ip == this) {
23962306a36Sopenharmony_ci				*ip = nextItem;
24062306a36Sopenharmony_ci				break;
24162306a36Sopenharmony_ci			}
24262306a36Sopenharmony_ci		}
24362306a36Sopenharmony_ci	}
24462306a36Sopenharmony_ci}
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ciQWidget *ConfigItemDelegate::createEditor(QWidget *parent,
24762306a36Sopenharmony_ci					  const QStyleOptionViewItem &option,
24862306a36Sopenharmony_ci					  const QModelIndex &index) const
24962306a36Sopenharmony_ci{
25062306a36Sopenharmony_ci	ConfigItem *item;
25162306a36Sopenharmony_ci
25262306a36Sopenharmony_ci	// Only the data column is editable
25362306a36Sopenharmony_ci	if (index.column() != dataColIdx)
25462306a36Sopenharmony_ci		return nullptr;
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci	// You cannot edit invisible menus
25762306a36Sopenharmony_ci	item = static_cast<ConfigItem *>(index.internalPointer());
25862306a36Sopenharmony_ci	if (!item || !item->menu || !menu_is_visible(item->menu))
25962306a36Sopenharmony_ci		return nullptr;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	return QStyledItemDelegate::createEditor(parent, option, index);
26262306a36Sopenharmony_ci}
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_civoid ConfigItemDelegate::setModelData(QWidget *editor,
26562306a36Sopenharmony_ci				      QAbstractItemModel *model,
26662306a36Sopenharmony_ci				      const QModelIndex &index) const
26762306a36Sopenharmony_ci{
26862306a36Sopenharmony_ci	QLineEdit *lineEdit;
26962306a36Sopenharmony_ci	ConfigItem *item;
27062306a36Sopenharmony_ci	struct symbol *sym;
27162306a36Sopenharmony_ci	bool success;
27262306a36Sopenharmony_ci
27362306a36Sopenharmony_ci	lineEdit = qobject_cast<QLineEdit *>(editor);
27462306a36Sopenharmony_ci	// If this is not a QLineEdit, use the parent's default.
27562306a36Sopenharmony_ci	// (does this happen?)
27662306a36Sopenharmony_ci	if (!lineEdit)
27762306a36Sopenharmony_ci		goto parent;
27862306a36Sopenharmony_ci
27962306a36Sopenharmony_ci	item = static_cast<ConfigItem *>(index.internalPointer());
28062306a36Sopenharmony_ci	if (!item || !item->menu)
28162306a36Sopenharmony_ci		goto parent;
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci	sym = item->menu->sym;
28462306a36Sopenharmony_ci	if (!sym)
28562306a36Sopenharmony_ci		goto parent;
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	success = sym_set_string_value(sym, lineEdit->text().toUtf8().data());
28862306a36Sopenharmony_ci	if (success) {
28962306a36Sopenharmony_ci		ConfigList::updateListForAll();
29062306a36Sopenharmony_ci	} else {
29162306a36Sopenharmony_ci		QMessageBox::information(editor, "qconf",
29262306a36Sopenharmony_ci			"Cannot set the data (maybe due to out of range).\n"
29362306a36Sopenharmony_ci			"Setting the old value.");
29462306a36Sopenharmony_ci		lineEdit->setText(sym_get_string_value(sym));
29562306a36Sopenharmony_ci	}
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ciparent:
29862306a36Sopenharmony_ci	QStyledItemDelegate::setModelData(editor, model, index);
29962306a36Sopenharmony_ci}
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ciConfigList::ConfigList(QWidget *parent, const char *name)
30262306a36Sopenharmony_ci	: QTreeWidget(parent),
30362306a36Sopenharmony_ci	  updateAll(false),
30462306a36Sopenharmony_ci	  showName(false), mode(singleMode), optMode(normalOpt),
30562306a36Sopenharmony_ci	  rootEntry(0), headerPopup(0)
30662306a36Sopenharmony_ci{
30762306a36Sopenharmony_ci	setObjectName(name);
30862306a36Sopenharmony_ci	setSortingEnabled(false);
30962306a36Sopenharmony_ci	setRootIsDecorated(true);
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	setVerticalScrollMode(ScrollPerPixel);
31262306a36Sopenharmony_ci	setHorizontalScrollMode(ScrollPerPixel);
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci	setHeaderLabels(QStringList() << "Option" << "Name" << "Value");
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci	connect(this, &ConfigList::itemSelectionChanged,
31762306a36Sopenharmony_ci		this, &ConfigList::updateSelection);
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci	if (name) {
32062306a36Sopenharmony_ci		configSettings->beginGroup(name);
32162306a36Sopenharmony_ci		showName = configSettings->value("/showName", false).toBool();
32262306a36Sopenharmony_ci		optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
32362306a36Sopenharmony_ci		configSettings->endGroup();
32462306a36Sopenharmony_ci		connect(configApp, &QApplication::aboutToQuit,
32562306a36Sopenharmony_ci			this, &ConfigList::saveSettings);
32662306a36Sopenharmony_ci	}
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	showColumn(promptColIdx);
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci	setItemDelegate(new ConfigItemDelegate(this));
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci	allLists.append(this);
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	reinit();
33562306a36Sopenharmony_ci}
33662306a36Sopenharmony_ci
33762306a36Sopenharmony_ciConfigList::~ConfigList()
33862306a36Sopenharmony_ci{
33962306a36Sopenharmony_ci	allLists.removeOne(this);
34062306a36Sopenharmony_ci}
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_cibool ConfigList::menuSkip(struct menu *menu)
34362306a36Sopenharmony_ci{
34462306a36Sopenharmony_ci	if (optMode == normalOpt && menu_is_visible(menu))
34562306a36Sopenharmony_ci		return false;
34662306a36Sopenharmony_ci	if (optMode == promptOpt && menu_has_prompt(menu))
34762306a36Sopenharmony_ci		return false;
34862306a36Sopenharmony_ci	if (optMode == allOpt)
34962306a36Sopenharmony_ci		return false;
35062306a36Sopenharmony_ci	return true;
35162306a36Sopenharmony_ci}
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_civoid ConfigList::reinit(void)
35462306a36Sopenharmony_ci{
35562306a36Sopenharmony_ci	hideColumn(nameColIdx);
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_ci	if (showName)
35862306a36Sopenharmony_ci		showColumn(nameColIdx);
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	updateListAll();
36162306a36Sopenharmony_ci}
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_civoid ConfigList::setOptionMode(QAction *action)
36462306a36Sopenharmony_ci{
36562306a36Sopenharmony_ci	if (action == showNormalAction)
36662306a36Sopenharmony_ci		optMode = normalOpt;
36762306a36Sopenharmony_ci	else if (action == showAllAction)
36862306a36Sopenharmony_ci		optMode = allOpt;
36962306a36Sopenharmony_ci	else
37062306a36Sopenharmony_ci		optMode = promptOpt;
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci	updateListAll();
37362306a36Sopenharmony_ci}
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_civoid ConfigList::saveSettings(void)
37662306a36Sopenharmony_ci{
37762306a36Sopenharmony_ci	if (!objectName().isEmpty()) {
37862306a36Sopenharmony_ci		configSettings->beginGroup(objectName());
37962306a36Sopenharmony_ci		configSettings->setValue("/showName", showName);
38062306a36Sopenharmony_ci		configSettings->setValue("/optionMode", (int)optMode);
38162306a36Sopenharmony_ci		configSettings->endGroup();
38262306a36Sopenharmony_ci	}
38362306a36Sopenharmony_ci}
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ciConfigItem* ConfigList::findConfigItem(struct menu *menu)
38662306a36Sopenharmony_ci{
38762306a36Sopenharmony_ci	ConfigItem* item = (ConfigItem*)menu->data;
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci	for (; item; item = item->nextItem) {
39062306a36Sopenharmony_ci		if (this == item->listView())
39162306a36Sopenharmony_ci			break;
39262306a36Sopenharmony_ci	}
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci	return item;
39562306a36Sopenharmony_ci}
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_civoid ConfigList::updateSelection(void)
39862306a36Sopenharmony_ci{
39962306a36Sopenharmony_ci	struct menu *menu;
40062306a36Sopenharmony_ci	enum prop_type type;
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci	if (selectedItems().count() == 0)
40362306a36Sopenharmony_ci		return;
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci	ConfigItem* item = (ConfigItem*)selectedItems().first();
40662306a36Sopenharmony_ci	if (!item)
40762306a36Sopenharmony_ci		return;
40862306a36Sopenharmony_ci
40962306a36Sopenharmony_ci	menu = item->menu;
41062306a36Sopenharmony_ci	emit menuChanged(menu);
41162306a36Sopenharmony_ci	if (!menu)
41262306a36Sopenharmony_ci		return;
41362306a36Sopenharmony_ci	type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
41462306a36Sopenharmony_ci	if (mode == menuMode && type == P_MENU)
41562306a36Sopenharmony_ci		emit menuSelected(menu);
41662306a36Sopenharmony_ci}
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_civoid ConfigList::updateList()
41962306a36Sopenharmony_ci{
42062306a36Sopenharmony_ci	ConfigItem* last = 0;
42162306a36Sopenharmony_ci	ConfigItem *item;
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci	if (!rootEntry) {
42462306a36Sopenharmony_ci		if (mode != listMode)
42562306a36Sopenharmony_ci			goto update;
42662306a36Sopenharmony_ci		QTreeWidgetItemIterator it(this);
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_ci		while (*it) {
42962306a36Sopenharmony_ci			item = (ConfigItem*)(*it);
43062306a36Sopenharmony_ci			if (!item->menu)
43162306a36Sopenharmony_ci				continue;
43262306a36Sopenharmony_ci			item->testUpdateMenu(menu_is_visible(item->menu));
43362306a36Sopenharmony_ci
43462306a36Sopenharmony_ci			++it;
43562306a36Sopenharmony_ci		}
43662306a36Sopenharmony_ci		return;
43762306a36Sopenharmony_ci	}
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci	if (rootEntry != &rootmenu && (mode == singleMode ||
44062306a36Sopenharmony_ci	    (mode == symbolMode && rootEntry->parent != &rootmenu))) {
44162306a36Sopenharmony_ci		item = (ConfigItem *)topLevelItem(0);
44262306a36Sopenharmony_ci		if (!item)
44362306a36Sopenharmony_ci			item = new ConfigItem(this, 0, true);
44462306a36Sopenharmony_ci		last = item;
44562306a36Sopenharmony_ci	}
44662306a36Sopenharmony_ci	if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
44762306a36Sopenharmony_ci	    rootEntry->sym && rootEntry->prompt) {
44862306a36Sopenharmony_ci		item = last ? last->nextSibling() : nullptr;
44962306a36Sopenharmony_ci		if (!item)
45062306a36Sopenharmony_ci			item = new ConfigItem(this, last, rootEntry, true);
45162306a36Sopenharmony_ci		else
45262306a36Sopenharmony_ci			item->testUpdateMenu(true);
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci		updateMenuList(item, rootEntry);
45562306a36Sopenharmony_ci		update();
45662306a36Sopenharmony_ci		resizeColumnToContents(0);
45762306a36Sopenharmony_ci		return;
45862306a36Sopenharmony_ci	}
45962306a36Sopenharmony_ciupdate:
46062306a36Sopenharmony_ci	updateMenuList(rootEntry);
46162306a36Sopenharmony_ci	update();
46262306a36Sopenharmony_ci	resizeColumnToContents(0);
46362306a36Sopenharmony_ci}
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_civoid ConfigList::updateListForAll()
46662306a36Sopenharmony_ci{
46762306a36Sopenharmony_ci	QListIterator<ConfigList *> it(allLists);
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci	while (it.hasNext()) {
47062306a36Sopenharmony_ci		ConfigList *list = it.next();
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci		list->updateList();
47362306a36Sopenharmony_ci	}
47462306a36Sopenharmony_ci}
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_civoid ConfigList::updateListAllForAll()
47762306a36Sopenharmony_ci{
47862306a36Sopenharmony_ci	QListIterator<ConfigList *> it(allLists);
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci	while (it.hasNext()) {
48162306a36Sopenharmony_ci		ConfigList *list = it.next();
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci		list->updateList();
48462306a36Sopenharmony_ci	}
48562306a36Sopenharmony_ci}
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_civoid ConfigList::setValue(ConfigItem* item, tristate val)
48862306a36Sopenharmony_ci{
48962306a36Sopenharmony_ci	struct symbol* sym;
49062306a36Sopenharmony_ci	int type;
49162306a36Sopenharmony_ci	tristate oldval;
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci	sym = item->menu ? item->menu->sym : 0;
49462306a36Sopenharmony_ci	if (!sym)
49562306a36Sopenharmony_ci		return;
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci	type = sym_get_type(sym);
49862306a36Sopenharmony_ci	switch (type) {
49962306a36Sopenharmony_ci	case S_BOOLEAN:
50062306a36Sopenharmony_ci	case S_TRISTATE:
50162306a36Sopenharmony_ci		oldval = sym_get_tristate_value(sym);
50262306a36Sopenharmony_ci
50362306a36Sopenharmony_ci		if (!sym_set_tristate_value(sym, val))
50462306a36Sopenharmony_ci			return;
50562306a36Sopenharmony_ci		if (oldval == no && item->menu->list)
50662306a36Sopenharmony_ci			item->setExpanded(true);
50762306a36Sopenharmony_ci		ConfigList::updateListForAll();
50862306a36Sopenharmony_ci		break;
50962306a36Sopenharmony_ci	}
51062306a36Sopenharmony_ci}
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_civoid ConfigList::changeValue(ConfigItem* item)
51362306a36Sopenharmony_ci{
51462306a36Sopenharmony_ci	struct symbol* sym;
51562306a36Sopenharmony_ci	struct menu* menu;
51662306a36Sopenharmony_ci	int type, oldexpr, newexpr;
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci	menu = item->menu;
51962306a36Sopenharmony_ci	if (!menu)
52062306a36Sopenharmony_ci		return;
52162306a36Sopenharmony_ci	sym = menu->sym;
52262306a36Sopenharmony_ci	if (!sym) {
52362306a36Sopenharmony_ci		if (item->menu->list)
52462306a36Sopenharmony_ci			item->setExpanded(!item->isExpanded());
52562306a36Sopenharmony_ci		return;
52662306a36Sopenharmony_ci	}
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci	type = sym_get_type(sym);
52962306a36Sopenharmony_ci	switch (type) {
53062306a36Sopenharmony_ci	case S_BOOLEAN:
53162306a36Sopenharmony_ci	case S_TRISTATE:
53262306a36Sopenharmony_ci		oldexpr = sym_get_tristate_value(sym);
53362306a36Sopenharmony_ci		newexpr = sym_toggle_tristate_value(sym);
53462306a36Sopenharmony_ci		if (item->menu->list) {
53562306a36Sopenharmony_ci			if (oldexpr == newexpr)
53662306a36Sopenharmony_ci				item->setExpanded(!item->isExpanded());
53762306a36Sopenharmony_ci			else if (oldexpr == no)
53862306a36Sopenharmony_ci				item->setExpanded(true);
53962306a36Sopenharmony_ci		}
54062306a36Sopenharmony_ci		if (oldexpr != newexpr)
54162306a36Sopenharmony_ci			ConfigList::updateListForAll();
54262306a36Sopenharmony_ci		break;
54362306a36Sopenharmony_ci	default:
54462306a36Sopenharmony_ci		break;
54562306a36Sopenharmony_ci	}
54662306a36Sopenharmony_ci}
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_civoid ConfigList::setRootMenu(struct menu *menu)
54962306a36Sopenharmony_ci{
55062306a36Sopenharmony_ci	enum prop_type type;
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci	if (rootEntry == menu)
55362306a36Sopenharmony_ci		return;
55462306a36Sopenharmony_ci	type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
55562306a36Sopenharmony_ci	if (type != P_MENU)
55662306a36Sopenharmony_ci		return;
55762306a36Sopenharmony_ci	updateMenuList(0);
55862306a36Sopenharmony_ci	rootEntry = menu;
55962306a36Sopenharmony_ci	updateListAll();
56062306a36Sopenharmony_ci	if (currentItem()) {
56162306a36Sopenharmony_ci		setSelected(currentItem(), hasFocus());
56262306a36Sopenharmony_ci		scrollToItem(currentItem());
56362306a36Sopenharmony_ci	}
56462306a36Sopenharmony_ci}
56562306a36Sopenharmony_ci
56662306a36Sopenharmony_civoid ConfigList::setParentMenu(void)
56762306a36Sopenharmony_ci{
56862306a36Sopenharmony_ci	ConfigItem* item;
56962306a36Sopenharmony_ci	struct menu *oldroot;
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ci	oldroot = rootEntry;
57262306a36Sopenharmony_ci	if (rootEntry == &rootmenu)
57362306a36Sopenharmony_ci		return;
57462306a36Sopenharmony_ci	setRootMenu(menu_get_parent_menu(rootEntry->parent));
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci	QTreeWidgetItemIterator it(this);
57762306a36Sopenharmony_ci	while (*it) {
57862306a36Sopenharmony_ci		item = (ConfigItem *)(*it);
57962306a36Sopenharmony_ci		if (item->menu == oldroot) {
58062306a36Sopenharmony_ci			setCurrentItem(item);
58162306a36Sopenharmony_ci			scrollToItem(item);
58262306a36Sopenharmony_ci			break;
58362306a36Sopenharmony_ci		}
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci		++it;
58662306a36Sopenharmony_ci	}
58762306a36Sopenharmony_ci}
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci/*
59062306a36Sopenharmony_ci * update all the children of a menu entry
59162306a36Sopenharmony_ci *   removes/adds the entries from the parent widget as necessary
59262306a36Sopenharmony_ci *
59362306a36Sopenharmony_ci * parent: either the menu list widget or a menu entry widget
59462306a36Sopenharmony_ci * menu: entry to be updated
59562306a36Sopenharmony_ci */
59662306a36Sopenharmony_civoid ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
59762306a36Sopenharmony_ci{
59862306a36Sopenharmony_ci	struct menu* child;
59962306a36Sopenharmony_ci	ConfigItem* item;
60062306a36Sopenharmony_ci	ConfigItem* last;
60162306a36Sopenharmony_ci	bool visible;
60262306a36Sopenharmony_ci	enum prop_type type;
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci	if (!menu) {
60562306a36Sopenharmony_ci		while (parent->childCount() > 0)
60662306a36Sopenharmony_ci		{
60762306a36Sopenharmony_ci			delete parent->takeChild(0);
60862306a36Sopenharmony_ci		}
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci		return;
61162306a36Sopenharmony_ci	}
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci	last = parent->firstChild();
61462306a36Sopenharmony_ci	if (last && !last->goParent)
61562306a36Sopenharmony_ci		last = 0;
61662306a36Sopenharmony_ci	for (child = menu->list; child; child = child->next) {
61762306a36Sopenharmony_ci		item = last ? last->nextSibling() : parent->firstChild();
61862306a36Sopenharmony_ci		type = child->prompt ? child->prompt->type : P_UNKNOWN;
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_ci		switch (mode) {
62162306a36Sopenharmony_ci		case menuMode:
62262306a36Sopenharmony_ci			if (!(child->flags & MENU_ROOT))
62362306a36Sopenharmony_ci				goto hide;
62462306a36Sopenharmony_ci			break;
62562306a36Sopenharmony_ci		case symbolMode:
62662306a36Sopenharmony_ci			if (child->flags & MENU_ROOT)
62762306a36Sopenharmony_ci				goto hide;
62862306a36Sopenharmony_ci			break;
62962306a36Sopenharmony_ci		default:
63062306a36Sopenharmony_ci			break;
63162306a36Sopenharmony_ci		}
63262306a36Sopenharmony_ci
63362306a36Sopenharmony_ci		visible = menu_is_visible(child);
63462306a36Sopenharmony_ci		if (!menuSkip(child)) {
63562306a36Sopenharmony_ci			if (!child->sym && !child->list && !child->prompt)
63662306a36Sopenharmony_ci				continue;
63762306a36Sopenharmony_ci			if (!item || item->menu != child)
63862306a36Sopenharmony_ci				item = new ConfigItem(parent, last, child, visible);
63962306a36Sopenharmony_ci			else
64062306a36Sopenharmony_ci				item->testUpdateMenu(visible);
64162306a36Sopenharmony_ci
64262306a36Sopenharmony_ci			if (mode == fullMode || mode == menuMode || type != P_MENU)
64362306a36Sopenharmony_ci				updateMenuList(item, child);
64462306a36Sopenharmony_ci			else
64562306a36Sopenharmony_ci				updateMenuList(item, 0);
64662306a36Sopenharmony_ci			last = item;
64762306a36Sopenharmony_ci			continue;
64862306a36Sopenharmony_ci		}
64962306a36Sopenharmony_cihide:
65062306a36Sopenharmony_ci		if (item && item->menu == child) {
65162306a36Sopenharmony_ci			last = parent->firstChild();
65262306a36Sopenharmony_ci			if (last == item)
65362306a36Sopenharmony_ci				last = 0;
65462306a36Sopenharmony_ci			else while (last->nextSibling() != item)
65562306a36Sopenharmony_ci				last = last->nextSibling();
65662306a36Sopenharmony_ci			delete item;
65762306a36Sopenharmony_ci		}
65862306a36Sopenharmony_ci	}
65962306a36Sopenharmony_ci}
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_civoid ConfigList::updateMenuList(struct menu *menu)
66262306a36Sopenharmony_ci{
66362306a36Sopenharmony_ci	struct menu* child;
66462306a36Sopenharmony_ci	ConfigItem* item;
66562306a36Sopenharmony_ci	ConfigItem* last;
66662306a36Sopenharmony_ci	bool visible;
66762306a36Sopenharmony_ci	enum prop_type type;
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ci	if (!menu) {
67062306a36Sopenharmony_ci		while (topLevelItemCount() > 0)
67162306a36Sopenharmony_ci		{
67262306a36Sopenharmony_ci			delete takeTopLevelItem(0);
67362306a36Sopenharmony_ci		}
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci		return;
67662306a36Sopenharmony_ci	}
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_ci	last = (ConfigItem *)topLevelItem(0);
67962306a36Sopenharmony_ci	if (last && !last->goParent)
68062306a36Sopenharmony_ci		last = 0;
68162306a36Sopenharmony_ci	for (child = menu->list; child; child = child->next) {
68262306a36Sopenharmony_ci		item = last ? last->nextSibling() : (ConfigItem *)topLevelItem(0);
68362306a36Sopenharmony_ci		type = child->prompt ? child->prompt->type : P_UNKNOWN;
68462306a36Sopenharmony_ci
68562306a36Sopenharmony_ci		switch (mode) {
68662306a36Sopenharmony_ci		case menuMode:
68762306a36Sopenharmony_ci			if (!(child->flags & MENU_ROOT))
68862306a36Sopenharmony_ci				goto hide;
68962306a36Sopenharmony_ci			break;
69062306a36Sopenharmony_ci		case symbolMode:
69162306a36Sopenharmony_ci			if (child->flags & MENU_ROOT)
69262306a36Sopenharmony_ci				goto hide;
69362306a36Sopenharmony_ci			break;
69462306a36Sopenharmony_ci		default:
69562306a36Sopenharmony_ci			break;
69662306a36Sopenharmony_ci		}
69762306a36Sopenharmony_ci
69862306a36Sopenharmony_ci		visible = menu_is_visible(child);
69962306a36Sopenharmony_ci		if (!menuSkip(child)) {
70062306a36Sopenharmony_ci			if (!child->sym && !child->list && !child->prompt)
70162306a36Sopenharmony_ci				continue;
70262306a36Sopenharmony_ci			if (!item || item->menu != child)
70362306a36Sopenharmony_ci				item = new ConfigItem(this, last, child, visible);
70462306a36Sopenharmony_ci			else
70562306a36Sopenharmony_ci				item->testUpdateMenu(visible);
70662306a36Sopenharmony_ci
70762306a36Sopenharmony_ci			if (mode == fullMode || mode == menuMode || type != P_MENU)
70862306a36Sopenharmony_ci				updateMenuList(item, child);
70962306a36Sopenharmony_ci			else
71062306a36Sopenharmony_ci				updateMenuList(item, 0);
71162306a36Sopenharmony_ci			last = item;
71262306a36Sopenharmony_ci			continue;
71362306a36Sopenharmony_ci		}
71462306a36Sopenharmony_cihide:
71562306a36Sopenharmony_ci		if (item && item->menu == child) {
71662306a36Sopenharmony_ci			last = (ConfigItem *)topLevelItem(0);
71762306a36Sopenharmony_ci			if (last == item)
71862306a36Sopenharmony_ci				last = 0;
71962306a36Sopenharmony_ci			else while (last->nextSibling() != item)
72062306a36Sopenharmony_ci				last = last->nextSibling();
72162306a36Sopenharmony_ci			delete item;
72262306a36Sopenharmony_ci		}
72362306a36Sopenharmony_ci	}
72462306a36Sopenharmony_ci}
72562306a36Sopenharmony_ci
72662306a36Sopenharmony_civoid ConfigList::keyPressEvent(QKeyEvent* ev)
72762306a36Sopenharmony_ci{
72862306a36Sopenharmony_ci	QTreeWidgetItem* i = currentItem();
72962306a36Sopenharmony_ci	ConfigItem* item;
73062306a36Sopenharmony_ci	struct menu *menu;
73162306a36Sopenharmony_ci	enum prop_type type;
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) {
73462306a36Sopenharmony_ci		emit parentSelected();
73562306a36Sopenharmony_ci		ev->accept();
73662306a36Sopenharmony_ci		return;
73762306a36Sopenharmony_ci	}
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci	if (!i) {
74062306a36Sopenharmony_ci		Parent::keyPressEvent(ev);
74162306a36Sopenharmony_ci		return;
74262306a36Sopenharmony_ci	}
74362306a36Sopenharmony_ci	item = (ConfigItem*)i;
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_ci	switch (ev->key()) {
74662306a36Sopenharmony_ci	case Qt::Key_Return:
74762306a36Sopenharmony_ci	case Qt::Key_Enter:
74862306a36Sopenharmony_ci		if (item->goParent) {
74962306a36Sopenharmony_ci			emit parentSelected();
75062306a36Sopenharmony_ci			break;
75162306a36Sopenharmony_ci		}
75262306a36Sopenharmony_ci		menu = item->menu;
75362306a36Sopenharmony_ci		if (!menu)
75462306a36Sopenharmony_ci			break;
75562306a36Sopenharmony_ci		type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
75662306a36Sopenharmony_ci		if (type == P_MENU && rootEntry != menu &&
75762306a36Sopenharmony_ci		    mode != fullMode && mode != menuMode) {
75862306a36Sopenharmony_ci			if (mode == menuMode)
75962306a36Sopenharmony_ci				emit menuSelected(menu);
76062306a36Sopenharmony_ci			else
76162306a36Sopenharmony_ci				emit itemSelected(menu);
76262306a36Sopenharmony_ci			break;
76362306a36Sopenharmony_ci		}
76462306a36Sopenharmony_ci	case Qt::Key_Space:
76562306a36Sopenharmony_ci		changeValue(item);
76662306a36Sopenharmony_ci		break;
76762306a36Sopenharmony_ci	case Qt::Key_N:
76862306a36Sopenharmony_ci		setValue(item, no);
76962306a36Sopenharmony_ci		break;
77062306a36Sopenharmony_ci	case Qt::Key_M:
77162306a36Sopenharmony_ci		setValue(item, mod);
77262306a36Sopenharmony_ci		break;
77362306a36Sopenharmony_ci	case Qt::Key_Y:
77462306a36Sopenharmony_ci		setValue(item, yes);
77562306a36Sopenharmony_ci		break;
77662306a36Sopenharmony_ci	default:
77762306a36Sopenharmony_ci		Parent::keyPressEvent(ev);
77862306a36Sopenharmony_ci		return;
77962306a36Sopenharmony_ci	}
78062306a36Sopenharmony_ci	ev->accept();
78162306a36Sopenharmony_ci}
78262306a36Sopenharmony_ci
78362306a36Sopenharmony_civoid ConfigList::mousePressEvent(QMouseEvent* e)
78462306a36Sopenharmony_ci{
78562306a36Sopenharmony_ci	//QPoint p(contentsToViewport(e->pos()));
78662306a36Sopenharmony_ci	//printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
78762306a36Sopenharmony_ci	Parent::mousePressEvent(e);
78862306a36Sopenharmony_ci}
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_civoid ConfigList::mouseReleaseEvent(QMouseEvent* e)
79162306a36Sopenharmony_ci{
79262306a36Sopenharmony_ci	QPoint p = e->pos();
79362306a36Sopenharmony_ci	ConfigItem* item = (ConfigItem*)itemAt(p);
79462306a36Sopenharmony_ci	struct menu *menu;
79562306a36Sopenharmony_ci	enum prop_type ptype;
79662306a36Sopenharmony_ci	QIcon icon;
79762306a36Sopenharmony_ci	int idx, x;
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ci	if (!item)
80062306a36Sopenharmony_ci		goto skip;
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci	menu = item->menu;
80362306a36Sopenharmony_ci	x = header()->offset() + p.x();
80462306a36Sopenharmony_ci	idx = header()->logicalIndexAt(x);
80562306a36Sopenharmony_ci	switch (idx) {
80662306a36Sopenharmony_ci	case promptColIdx:
80762306a36Sopenharmony_ci		icon = item->icon(promptColIdx);
80862306a36Sopenharmony_ci		if (!icon.isNull()) {
80962306a36Sopenharmony_ci			int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
81062306a36Sopenharmony_ci			if (x >= off && x < off + icon.availableSizes().first().width()) {
81162306a36Sopenharmony_ci				if (item->goParent) {
81262306a36Sopenharmony_ci					emit parentSelected();
81362306a36Sopenharmony_ci					break;
81462306a36Sopenharmony_ci				} else if (!menu)
81562306a36Sopenharmony_ci					break;
81662306a36Sopenharmony_ci				ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
81762306a36Sopenharmony_ci				if (ptype == P_MENU && rootEntry != menu &&
81862306a36Sopenharmony_ci				    mode != fullMode && mode != menuMode &&
81962306a36Sopenharmony_ci                                    mode != listMode)
82062306a36Sopenharmony_ci					emit menuSelected(menu);
82162306a36Sopenharmony_ci				else
82262306a36Sopenharmony_ci					changeValue(item);
82362306a36Sopenharmony_ci			}
82462306a36Sopenharmony_ci		}
82562306a36Sopenharmony_ci		break;
82662306a36Sopenharmony_ci	case dataColIdx:
82762306a36Sopenharmony_ci		changeValue(item);
82862306a36Sopenharmony_ci		break;
82962306a36Sopenharmony_ci	}
83062306a36Sopenharmony_ci
83162306a36Sopenharmony_ciskip:
83262306a36Sopenharmony_ci	//printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
83362306a36Sopenharmony_ci	Parent::mouseReleaseEvent(e);
83462306a36Sopenharmony_ci}
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_civoid ConfigList::mouseMoveEvent(QMouseEvent* e)
83762306a36Sopenharmony_ci{
83862306a36Sopenharmony_ci	//QPoint p(contentsToViewport(e->pos()));
83962306a36Sopenharmony_ci	//printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
84062306a36Sopenharmony_ci	Parent::mouseMoveEvent(e);
84162306a36Sopenharmony_ci}
84262306a36Sopenharmony_ci
84362306a36Sopenharmony_civoid ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
84462306a36Sopenharmony_ci{
84562306a36Sopenharmony_ci	QPoint p = e->pos();
84662306a36Sopenharmony_ci	ConfigItem* item = (ConfigItem*)itemAt(p);
84762306a36Sopenharmony_ci	struct menu *menu;
84862306a36Sopenharmony_ci	enum prop_type ptype;
84962306a36Sopenharmony_ci
85062306a36Sopenharmony_ci	if (!item)
85162306a36Sopenharmony_ci		goto skip;
85262306a36Sopenharmony_ci	if (item->goParent) {
85362306a36Sopenharmony_ci		emit parentSelected();
85462306a36Sopenharmony_ci		goto skip;
85562306a36Sopenharmony_ci	}
85662306a36Sopenharmony_ci	menu = item->menu;
85762306a36Sopenharmony_ci	if (!menu)
85862306a36Sopenharmony_ci		goto skip;
85962306a36Sopenharmony_ci	ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
86062306a36Sopenharmony_ci	if (ptype == P_MENU && mode != listMode) {
86162306a36Sopenharmony_ci		if (mode == singleMode)
86262306a36Sopenharmony_ci			emit itemSelected(menu);
86362306a36Sopenharmony_ci		else if (mode == symbolMode)
86462306a36Sopenharmony_ci			emit menuSelected(menu);
86562306a36Sopenharmony_ci	} else if (menu->sym)
86662306a36Sopenharmony_ci		changeValue(item);
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ciskip:
86962306a36Sopenharmony_ci	//printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
87062306a36Sopenharmony_ci	Parent::mouseDoubleClickEvent(e);
87162306a36Sopenharmony_ci}
87262306a36Sopenharmony_ci
87362306a36Sopenharmony_civoid ConfigList::focusInEvent(QFocusEvent *e)
87462306a36Sopenharmony_ci{
87562306a36Sopenharmony_ci	struct menu *menu = NULL;
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci	Parent::focusInEvent(e);
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_ci	ConfigItem* item = (ConfigItem *)currentItem();
88062306a36Sopenharmony_ci	if (item) {
88162306a36Sopenharmony_ci		setSelected(item, true);
88262306a36Sopenharmony_ci		menu = item->menu;
88362306a36Sopenharmony_ci	}
88462306a36Sopenharmony_ci	emit gotFocus(menu);
88562306a36Sopenharmony_ci}
88662306a36Sopenharmony_ci
88762306a36Sopenharmony_civoid ConfigList::contextMenuEvent(QContextMenuEvent *e)
88862306a36Sopenharmony_ci{
88962306a36Sopenharmony_ci	if (!headerPopup) {
89062306a36Sopenharmony_ci		QAction *action;
89162306a36Sopenharmony_ci
89262306a36Sopenharmony_ci		headerPopup = new QMenu(this);
89362306a36Sopenharmony_ci		action = new QAction("Show Name", this);
89462306a36Sopenharmony_ci		action->setCheckable(true);
89562306a36Sopenharmony_ci		connect(action, &QAction::toggled,
89662306a36Sopenharmony_ci			this, &ConfigList::setShowName);
89762306a36Sopenharmony_ci		connect(this, &ConfigList::showNameChanged,
89862306a36Sopenharmony_ci			action, &QAction::setChecked);
89962306a36Sopenharmony_ci		action->setChecked(showName);
90062306a36Sopenharmony_ci		headerPopup->addAction(action);
90162306a36Sopenharmony_ci	}
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_ci	headerPopup->exec(e->globalPos());
90462306a36Sopenharmony_ci	e->accept();
90562306a36Sopenharmony_ci}
90662306a36Sopenharmony_ci
90762306a36Sopenharmony_civoid ConfigList::setShowName(bool on)
90862306a36Sopenharmony_ci{
90962306a36Sopenharmony_ci	if (showName == on)
91062306a36Sopenharmony_ci		return;
91162306a36Sopenharmony_ci
91262306a36Sopenharmony_ci	showName = on;
91362306a36Sopenharmony_ci	reinit();
91462306a36Sopenharmony_ci	emit showNameChanged(on);
91562306a36Sopenharmony_ci}
91662306a36Sopenharmony_ci
91762306a36Sopenharmony_ciQList<ConfigList *> ConfigList::allLists;
91862306a36Sopenharmony_ciQAction *ConfigList::showNormalAction;
91962306a36Sopenharmony_ciQAction *ConfigList::showAllAction;
92062306a36Sopenharmony_ciQAction *ConfigList::showPromptAction;
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_civoid ConfigList::setAllOpen(bool open)
92362306a36Sopenharmony_ci{
92462306a36Sopenharmony_ci	QTreeWidgetItemIterator it(this);
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_ci	while (*it) {
92762306a36Sopenharmony_ci		(*it)->setExpanded(open);
92862306a36Sopenharmony_ci
92962306a36Sopenharmony_ci		++it;
93062306a36Sopenharmony_ci	}
93162306a36Sopenharmony_ci}
93262306a36Sopenharmony_ci
93362306a36Sopenharmony_ciConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
93462306a36Sopenharmony_ci	: Parent(parent), sym(0), _menu(0)
93562306a36Sopenharmony_ci{
93662306a36Sopenharmony_ci	setObjectName(name);
93762306a36Sopenharmony_ci	setOpenLinks(false);
93862306a36Sopenharmony_ci
93962306a36Sopenharmony_ci	if (!objectName().isEmpty()) {
94062306a36Sopenharmony_ci		configSettings->beginGroup(objectName());
94162306a36Sopenharmony_ci		setShowDebug(configSettings->value("/showDebug", false).toBool());
94262306a36Sopenharmony_ci		configSettings->endGroup();
94362306a36Sopenharmony_ci		connect(configApp, &QApplication::aboutToQuit,
94462306a36Sopenharmony_ci			this, &ConfigInfoView::saveSettings);
94562306a36Sopenharmony_ci	}
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci	contextMenu = createStandardContextMenu();
94862306a36Sopenharmony_ci	QAction *action = new QAction("Show Debug Info", contextMenu);
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_ci	action->setCheckable(true);
95162306a36Sopenharmony_ci	connect(action, &QAction::toggled,
95262306a36Sopenharmony_ci		this, &ConfigInfoView::setShowDebug);
95362306a36Sopenharmony_ci	connect(this, &ConfigInfoView::showDebugChanged,
95462306a36Sopenharmony_ci		action, &QAction::setChecked);
95562306a36Sopenharmony_ci	action->setChecked(showDebug());
95662306a36Sopenharmony_ci	contextMenu->addSeparator();
95762306a36Sopenharmony_ci	contextMenu->addAction(action);
95862306a36Sopenharmony_ci}
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_civoid ConfigInfoView::saveSettings(void)
96162306a36Sopenharmony_ci{
96262306a36Sopenharmony_ci	if (!objectName().isEmpty()) {
96362306a36Sopenharmony_ci		configSettings->beginGroup(objectName());
96462306a36Sopenharmony_ci		configSettings->setValue("/showDebug", showDebug());
96562306a36Sopenharmony_ci		configSettings->endGroup();
96662306a36Sopenharmony_ci	}
96762306a36Sopenharmony_ci}
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_civoid ConfigInfoView::setShowDebug(bool b)
97062306a36Sopenharmony_ci{
97162306a36Sopenharmony_ci	if (_showDebug != b) {
97262306a36Sopenharmony_ci		_showDebug = b;
97362306a36Sopenharmony_ci		if (_menu)
97462306a36Sopenharmony_ci			menuInfo();
97562306a36Sopenharmony_ci		else if (sym)
97662306a36Sopenharmony_ci			symbolInfo();
97762306a36Sopenharmony_ci		emit showDebugChanged(b);
97862306a36Sopenharmony_ci	}
97962306a36Sopenharmony_ci}
98062306a36Sopenharmony_ci
98162306a36Sopenharmony_civoid ConfigInfoView::setInfo(struct menu *m)
98262306a36Sopenharmony_ci{
98362306a36Sopenharmony_ci	if (_menu == m)
98462306a36Sopenharmony_ci		return;
98562306a36Sopenharmony_ci	_menu = m;
98662306a36Sopenharmony_ci	sym = NULL;
98762306a36Sopenharmony_ci	if (!_menu)
98862306a36Sopenharmony_ci		clear();
98962306a36Sopenharmony_ci	else
99062306a36Sopenharmony_ci		menuInfo();
99162306a36Sopenharmony_ci}
99262306a36Sopenharmony_ci
99362306a36Sopenharmony_civoid ConfigInfoView::symbolInfo(void)
99462306a36Sopenharmony_ci{
99562306a36Sopenharmony_ci	QString str;
99662306a36Sopenharmony_ci
99762306a36Sopenharmony_ci	str += "<big>Symbol: <b>";
99862306a36Sopenharmony_ci	str += print_filter(sym->name);
99962306a36Sopenharmony_ci	str += "</b></big><br><br>value: ";
100062306a36Sopenharmony_ci	str += print_filter(sym_get_string_value(sym));
100162306a36Sopenharmony_ci	str += "<br>visibility: ";
100262306a36Sopenharmony_ci	str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
100362306a36Sopenharmony_ci	str += "<br>";
100462306a36Sopenharmony_ci	str += debug_info(sym);
100562306a36Sopenharmony_ci
100662306a36Sopenharmony_ci	setText(str);
100762306a36Sopenharmony_ci}
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_civoid ConfigInfoView::menuInfo(void)
101062306a36Sopenharmony_ci{
101162306a36Sopenharmony_ci	struct symbol* sym;
101262306a36Sopenharmony_ci	QString info;
101362306a36Sopenharmony_ci	QTextStream stream(&info);
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_ci	sym = _menu->sym;
101662306a36Sopenharmony_ci	if (sym) {
101762306a36Sopenharmony_ci		if (_menu->prompt) {
101862306a36Sopenharmony_ci			stream << "<big><b>";
101962306a36Sopenharmony_ci			stream << print_filter(_menu->prompt->text);
102062306a36Sopenharmony_ci			stream << "</b></big>";
102162306a36Sopenharmony_ci			if (sym->name) {
102262306a36Sopenharmony_ci				stream << " (";
102362306a36Sopenharmony_ci				if (showDebug())
102462306a36Sopenharmony_ci					stream << "<a href=\"s" << sym->name << "\">";
102562306a36Sopenharmony_ci				stream << print_filter(sym->name);
102662306a36Sopenharmony_ci				if (showDebug())
102762306a36Sopenharmony_ci					stream << "</a>";
102862306a36Sopenharmony_ci				stream << ")";
102962306a36Sopenharmony_ci			}
103062306a36Sopenharmony_ci		} else if (sym->name) {
103162306a36Sopenharmony_ci			stream << "<big><b>";
103262306a36Sopenharmony_ci			if (showDebug())
103362306a36Sopenharmony_ci				stream << "<a href=\"s" << sym->name << "\">";
103462306a36Sopenharmony_ci			stream << print_filter(sym->name);
103562306a36Sopenharmony_ci			if (showDebug())
103662306a36Sopenharmony_ci				stream << "</a>";
103762306a36Sopenharmony_ci			stream << "</b></big>";
103862306a36Sopenharmony_ci		}
103962306a36Sopenharmony_ci		stream << "<br><br>";
104062306a36Sopenharmony_ci
104162306a36Sopenharmony_ci		if (showDebug())
104262306a36Sopenharmony_ci			stream << debug_info(sym);
104362306a36Sopenharmony_ci
104462306a36Sopenharmony_ci		struct gstr help_gstr = str_new();
104562306a36Sopenharmony_ci
104662306a36Sopenharmony_ci		menu_get_ext_help(_menu, &help_gstr);
104762306a36Sopenharmony_ci		stream << print_filter(str_get(&help_gstr));
104862306a36Sopenharmony_ci		str_free(&help_gstr);
104962306a36Sopenharmony_ci	} else if (_menu->prompt) {
105062306a36Sopenharmony_ci		stream << "<big><b>";
105162306a36Sopenharmony_ci		stream << print_filter(_menu->prompt->text);
105262306a36Sopenharmony_ci		stream << "</b></big><br><br>";
105362306a36Sopenharmony_ci		if (showDebug()) {
105462306a36Sopenharmony_ci			if (_menu->prompt->visible.expr) {
105562306a36Sopenharmony_ci				stream << "&nbsp;&nbsp;dep: ";
105662306a36Sopenharmony_ci				expr_print(_menu->prompt->visible.expr,
105762306a36Sopenharmony_ci					   expr_print_help, &stream, E_NONE);
105862306a36Sopenharmony_ci				stream << "<br><br>";
105962306a36Sopenharmony_ci			}
106062306a36Sopenharmony_ci
106162306a36Sopenharmony_ci			stream << "defined at " << _menu->file->name << ":"
106262306a36Sopenharmony_ci			       << _menu->lineno << "<br><br>";
106362306a36Sopenharmony_ci		}
106462306a36Sopenharmony_ci	}
106562306a36Sopenharmony_ci
106662306a36Sopenharmony_ci	setText(info);
106762306a36Sopenharmony_ci}
106862306a36Sopenharmony_ci
106962306a36Sopenharmony_ciQString ConfigInfoView::debug_info(struct symbol *sym)
107062306a36Sopenharmony_ci{
107162306a36Sopenharmony_ci	QString debug;
107262306a36Sopenharmony_ci	QTextStream stream(&debug);
107362306a36Sopenharmony_ci
107462306a36Sopenharmony_ci	stream << "type: ";
107562306a36Sopenharmony_ci	stream << print_filter(sym_type_name(sym->type));
107662306a36Sopenharmony_ci	if (sym_is_choice(sym))
107762306a36Sopenharmony_ci		stream << " (choice)";
107862306a36Sopenharmony_ci	debug += "<br>";
107962306a36Sopenharmony_ci	if (sym->rev_dep.expr) {
108062306a36Sopenharmony_ci		stream << "reverse dep: ";
108162306a36Sopenharmony_ci		expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE);
108262306a36Sopenharmony_ci		stream << "<br>";
108362306a36Sopenharmony_ci	}
108462306a36Sopenharmony_ci	for (struct property *prop = sym->prop; prop; prop = prop->next) {
108562306a36Sopenharmony_ci		switch (prop->type) {
108662306a36Sopenharmony_ci		case P_PROMPT:
108762306a36Sopenharmony_ci		case P_MENU:
108862306a36Sopenharmony_ci			stream << "prompt: <a href=\"m" << sym->name << "\">";
108962306a36Sopenharmony_ci			stream << print_filter(prop->text);
109062306a36Sopenharmony_ci			stream << "</a><br>";
109162306a36Sopenharmony_ci			break;
109262306a36Sopenharmony_ci		case P_DEFAULT:
109362306a36Sopenharmony_ci		case P_SELECT:
109462306a36Sopenharmony_ci		case P_RANGE:
109562306a36Sopenharmony_ci		case P_COMMENT:
109662306a36Sopenharmony_ci		case P_IMPLY:
109762306a36Sopenharmony_ci		case P_SYMBOL:
109862306a36Sopenharmony_ci			stream << prop_get_type_name(prop->type);
109962306a36Sopenharmony_ci			stream << ": ";
110062306a36Sopenharmony_ci			expr_print(prop->expr, expr_print_help,
110162306a36Sopenharmony_ci				   &stream, E_NONE);
110262306a36Sopenharmony_ci			stream << "<br>";
110362306a36Sopenharmony_ci			break;
110462306a36Sopenharmony_ci		case P_CHOICE:
110562306a36Sopenharmony_ci			if (sym_is_choice(sym)) {
110662306a36Sopenharmony_ci				stream << "choice: ";
110762306a36Sopenharmony_ci				expr_print(prop->expr, expr_print_help,
110862306a36Sopenharmony_ci					   &stream, E_NONE);
110962306a36Sopenharmony_ci				stream << "<br>";
111062306a36Sopenharmony_ci			}
111162306a36Sopenharmony_ci			break;
111262306a36Sopenharmony_ci		default:
111362306a36Sopenharmony_ci			stream << "unknown property: ";
111462306a36Sopenharmony_ci			stream << prop_get_type_name(prop->type);
111562306a36Sopenharmony_ci			stream << "<br>";
111662306a36Sopenharmony_ci		}
111762306a36Sopenharmony_ci		if (prop->visible.expr) {
111862306a36Sopenharmony_ci			stream << "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
111962306a36Sopenharmony_ci			expr_print(prop->visible.expr, expr_print_help,
112062306a36Sopenharmony_ci				   &stream, E_NONE);
112162306a36Sopenharmony_ci			stream << "<br>";
112262306a36Sopenharmony_ci		}
112362306a36Sopenharmony_ci	}
112462306a36Sopenharmony_ci	stream << "<br>";
112562306a36Sopenharmony_ci
112662306a36Sopenharmony_ci	return debug;
112762306a36Sopenharmony_ci}
112862306a36Sopenharmony_ci
112962306a36Sopenharmony_ciQString ConfigInfoView::print_filter(const QString &str)
113062306a36Sopenharmony_ci{
113162306a36Sopenharmony_ci	QRegularExpression re("[<>&\"\\n]");
113262306a36Sopenharmony_ci	QString res = str;
113362306a36Sopenharmony_ci	for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
113462306a36Sopenharmony_ci		switch (res[i].toLatin1()) {
113562306a36Sopenharmony_ci		case '<':
113662306a36Sopenharmony_ci			res.replace(i, 1, "&lt;");
113762306a36Sopenharmony_ci			i += 4;
113862306a36Sopenharmony_ci			break;
113962306a36Sopenharmony_ci		case '>':
114062306a36Sopenharmony_ci			res.replace(i, 1, "&gt;");
114162306a36Sopenharmony_ci			i += 4;
114262306a36Sopenharmony_ci			break;
114362306a36Sopenharmony_ci		case '&':
114462306a36Sopenharmony_ci			res.replace(i, 1, "&amp;");
114562306a36Sopenharmony_ci			i += 5;
114662306a36Sopenharmony_ci			break;
114762306a36Sopenharmony_ci		case '"':
114862306a36Sopenharmony_ci			res.replace(i, 1, "&quot;");
114962306a36Sopenharmony_ci			i += 6;
115062306a36Sopenharmony_ci			break;
115162306a36Sopenharmony_ci		case '\n':
115262306a36Sopenharmony_ci			res.replace(i, 1, "<br>");
115362306a36Sopenharmony_ci			i += 4;
115462306a36Sopenharmony_ci			break;
115562306a36Sopenharmony_ci		}
115662306a36Sopenharmony_ci	}
115762306a36Sopenharmony_ci	return res;
115862306a36Sopenharmony_ci}
115962306a36Sopenharmony_ci
116062306a36Sopenharmony_civoid ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
116162306a36Sopenharmony_ci{
116262306a36Sopenharmony_ci	QTextStream *stream = reinterpret_cast<QTextStream *>(data);
116362306a36Sopenharmony_ci
116462306a36Sopenharmony_ci	if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
116562306a36Sopenharmony_ci		*stream << "<a href=\"s" << sym->name << "\">";
116662306a36Sopenharmony_ci		*stream << print_filter(str);
116762306a36Sopenharmony_ci		*stream << "</a>";
116862306a36Sopenharmony_ci	} else {
116962306a36Sopenharmony_ci		*stream << print_filter(str);
117062306a36Sopenharmony_ci	}
117162306a36Sopenharmony_ci}
117262306a36Sopenharmony_ci
117362306a36Sopenharmony_civoid ConfigInfoView::clicked(const QUrl &url)
117462306a36Sopenharmony_ci{
117562306a36Sopenharmony_ci	QByteArray str = url.toEncoded();
117662306a36Sopenharmony_ci	const std::size_t count = str.size();
117762306a36Sopenharmony_ci	char *data = new char[count + 1];
117862306a36Sopenharmony_ci	struct symbol **result;
117962306a36Sopenharmony_ci	struct menu *m = NULL;
118062306a36Sopenharmony_ci
118162306a36Sopenharmony_ci	if (count < 1) {
118262306a36Sopenharmony_ci		delete[] data;
118362306a36Sopenharmony_ci		return;
118462306a36Sopenharmony_ci	}
118562306a36Sopenharmony_ci
118662306a36Sopenharmony_ci	memcpy(data, str.constData(), count);
118762306a36Sopenharmony_ci	data[count] = '\0';
118862306a36Sopenharmony_ci
118962306a36Sopenharmony_ci	/* Seek for exact match */
119062306a36Sopenharmony_ci	data[0] = '^';
119162306a36Sopenharmony_ci	strcat(data, "$");
119262306a36Sopenharmony_ci	result = sym_re_search(data);
119362306a36Sopenharmony_ci	if (!result) {
119462306a36Sopenharmony_ci		delete[] data;
119562306a36Sopenharmony_ci		return;
119662306a36Sopenharmony_ci	}
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_ci	sym = *result;
119962306a36Sopenharmony_ci
120062306a36Sopenharmony_ci	/* Seek for the menu which holds the symbol */
120162306a36Sopenharmony_ci	for (struct property *prop = sym->prop; prop; prop = prop->next) {
120262306a36Sopenharmony_ci		    if (prop->type != P_PROMPT && prop->type != P_MENU)
120362306a36Sopenharmony_ci			    continue;
120462306a36Sopenharmony_ci		    m = prop->menu;
120562306a36Sopenharmony_ci		    break;
120662306a36Sopenharmony_ci	}
120762306a36Sopenharmony_ci
120862306a36Sopenharmony_ci	if (!m) {
120962306a36Sopenharmony_ci		/* Symbol is not visible as a menu */
121062306a36Sopenharmony_ci		symbolInfo();
121162306a36Sopenharmony_ci		emit showDebugChanged(true);
121262306a36Sopenharmony_ci	} else {
121362306a36Sopenharmony_ci		emit menuSelected(m);
121462306a36Sopenharmony_ci	}
121562306a36Sopenharmony_ci
121662306a36Sopenharmony_ci	free(result);
121762306a36Sopenharmony_ci	delete[] data;
121862306a36Sopenharmony_ci}
121962306a36Sopenharmony_ci
122062306a36Sopenharmony_civoid ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
122162306a36Sopenharmony_ci{
122262306a36Sopenharmony_ci	contextMenu->popup(event->globalPos());
122362306a36Sopenharmony_ci	event->accept();
122462306a36Sopenharmony_ci}
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_ciConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
122762306a36Sopenharmony_ci	: Parent(parent), result(NULL)
122862306a36Sopenharmony_ci{
122962306a36Sopenharmony_ci	setObjectName("search");
123062306a36Sopenharmony_ci	setWindowTitle("Search Config");
123162306a36Sopenharmony_ci
123262306a36Sopenharmony_ci	QVBoxLayout* layout1 = new QVBoxLayout(this);
123362306a36Sopenharmony_ci	layout1->setContentsMargins(11, 11, 11, 11);
123462306a36Sopenharmony_ci	layout1->setSpacing(6);
123562306a36Sopenharmony_ci
123662306a36Sopenharmony_ci	QHBoxLayout* layout2 = new QHBoxLayout();
123762306a36Sopenharmony_ci	layout2->setContentsMargins(0, 0, 0, 0);
123862306a36Sopenharmony_ci	layout2->setSpacing(6);
123962306a36Sopenharmony_ci	layout2->addWidget(new QLabel("Find:", this));
124062306a36Sopenharmony_ci	editField = new QLineEdit(this);
124162306a36Sopenharmony_ci	connect(editField, &QLineEdit::returnPressed,
124262306a36Sopenharmony_ci		this, &ConfigSearchWindow::search);
124362306a36Sopenharmony_ci	layout2->addWidget(editField);
124462306a36Sopenharmony_ci	searchButton = new QPushButton("Search", this);
124562306a36Sopenharmony_ci	searchButton->setAutoDefault(false);
124662306a36Sopenharmony_ci	connect(searchButton, &QPushButton::clicked,
124762306a36Sopenharmony_ci		this, &ConfigSearchWindow::search);
124862306a36Sopenharmony_ci	layout2->addWidget(searchButton);
124962306a36Sopenharmony_ci	layout1->addLayout(layout2);
125062306a36Sopenharmony_ci
125162306a36Sopenharmony_ci	split = new QSplitter(this);
125262306a36Sopenharmony_ci	split->setOrientation(Qt::Vertical);
125362306a36Sopenharmony_ci	list = new ConfigList(split, "search");
125462306a36Sopenharmony_ci	list->mode = listMode;
125562306a36Sopenharmony_ci	info = new ConfigInfoView(split, "search");
125662306a36Sopenharmony_ci	connect(list, &ConfigList::menuChanged,
125762306a36Sopenharmony_ci		info, &ConfigInfoView::setInfo);
125862306a36Sopenharmony_ci	connect(list, &ConfigList::menuChanged,
125962306a36Sopenharmony_ci		parent, &ConfigMainWindow::setMenuLink);
126062306a36Sopenharmony_ci
126162306a36Sopenharmony_ci	layout1->addWidget(split);
126262306a36Sopenharmony_ci
126362306a36Sopenharmony_ci	QVariant x, y;
126462306a36Sopenharmony_ci	int width, height;
126562306a36Sopenharmony_ci	bool ok;
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci	configSettings->beginGroup("search");
126862306a36Sopenharmony_ci	width = configSettings->value("/window width", parent->width() / 2).toInt();
126962306a36Sopenharmony_ci	height = configSettings->value("/window height", parent->height() / 2).toInt();
127062306a36Sopenharmony_ci	resize(width, height);
127162306a36Sopenharmony_ci	x = configSettings->value("/window x");
127262306a36Sopenharmony_ci	y = configSettings->value("/window y");
127362306a36Sopenharmony_ci	if (x.isValid() && y.isValid())
127462306a36Sopenharmony_ci		move(x.toInt(), y.toInt());
127562306a36Sopenharmony_ci	QList<int> sizes = configSettings->readSizes("/split", &ok);
127662306a36Sopenharmony_ci	if (ok)
127762306a36Sopenharmony_ci		split->setSizes(sizes);
127862306a36Sopenharmony_ci	configSettings->endGroup();
127962306a36Sopenharmony_ci	connect(configApp, &QApplication::aboutToQuit,
128062306a36Sopenharmony_ci		this, &ConfigSearchWindow::saveSettings);
128162306a36Sopenharmony_ci}
128262306a36Sopenharmony_ci
128362306a36Sopenharmony_civoid ConfigSearchWindow::saveSettings(void)
128462306a36Sopenharmony_ci{
128562306a36Sopenharmony_ci	if (!objectName().isEmpty()) {
128662306a36Sopenharmony_ci		configSettings->beginGroup(objectName());
128762306a36Sopenharmony_ci		configSettings->setValue("/window x", pos().x());
128862306a36Sopenharmony_ci		configSettings->setValue("/window y", pos().y());
128962306a36Sopenharmony_ci		configSettings->setValue("/window width", size().width());
129062306a36Sopenharmony_ci		configSettings->setValue("/window height", size().height());
129162306a36Sopenharmony_ci		configSettings->writeSizes("/split", split->sizes());
129262306a36Sopenharmony_ci		configSettings->endGroup();
129362306a36Sopenharmony_ci	}
129462306a36Sopenharmony_ci}
129562306a36Sopenharmony_ci
129662306a36Sopenharmony_civoid ConfigSearchWindow::search(void)
129762306a36Sopenharmony_ci{
129862306a36Sopenharmony_ci	struct symbol **p;
129962306a36Sopenharmony_ci	struct property *prop;
130062306a36Sopenharmony_ci	ConfigItem *lastItem = NULL;
130162306a36Sopenharmony_ci
130262306a36Sopenharmony_ci	free(result);
130362306a36Sopenharmony_ci	list->clear();
130462306a36Sopenharmony_ci	info->clear();
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_ci	result = sym_re_search(editField->text().toLatin1());
130762306a36Sopenharmony_ci	if (!result)
130862306a36Sopenharmony_ci		return;
130962306a36Sopenharmony_ci	for (p = result; *p; p++) {
131062306a36Sopenharmony_ci		for_all_prompts((*p), prop)
131162306a36Sopenharmony_ci			lastItem = new ConfigItem(list, lastItem, prop->menu,
131262306a36Sopenharmony_ci						  menu_is_visible(prop->menu));
131362306a36Sopenharmony_ci	}
131462306a36Sopenharmony_ci}
131562306a36Sopenharmony_ci
131662306a36Sopenharmony_ci/*
131762306a36Sopenharmony_ci * Construct the complete config widget
131862306a36Sopenharmony_ci */
131962306a36Sopenharmony_ciConfigMainWindow::ConfigMainWindow(void)
132062306a36Sopenharmony_ci	: searchWindow(0)
132162306a36Sopenharmony_ci{
132262306a36Sopenharmony_ci	bool ok = true;
132362306a36Sopenharmony_ci	QVariant x, y;
132462306a36Sopenharmony_ci	int width, height;
132562306a36Sopenharmony_ci	char title[256];
132662306a36Sopenharmony_ci
132762306a36Sopenharmony_ci	snprintf(title, sizeof(title), "%s%s",
132862306a36Sopenharmony_ci		rootmenu.prompt->text,
132962306a36Sopenharmony_ci		""
133062306a36Sopenharmony_ci		);
133162306a36Sopenharmony_ci	setWindowTitle(title);
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_ci	QRect g = configApp->primaryScreen()->geometry();
133462306a36Sopenharmony_ci	width = configSettings->value("/window width", g.width() - 64).toInt();
133562306a36Sopenharmony_ci	height = configSettings->value("/window height", g.height() - 64).toInt();
133662306a36Sopenharmony_ci	resize(width, height);
133762306a36Sopenharmony_ci	x = configSettings->value("/window x");
133862306a36Sopenharmony_ci	y = configSettings->value("/window y");
133962306a36Sopenharmony_ci	if ((x.isValid())&&(y.isValid()))
134062306a36Sopenharmony_ci		move(x.toInt(), y.toInt());
134162306a36Sopenharmony_ci
134262306a36Sopenharmony_ci	// set up icons
134362306a36Sopenharmony_ci	ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
134462306a36Sopenharmony_ci	ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
134562306a36Sopenharmony_ci	ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
134662306a36Sopenharmony_ci	ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
134762306a36Sopenharmony_ci	ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
134862306a36Sopenharmony_ci	ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
134962306a36Sopenharmony_ci	ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	QWidget *widget = new QWidget(this);
135262306a36Sopenharmony_ci	QVBoxLayout *layout = new QVBoxLayout(widget);
135362306a36Sopenharmony_ci	setCentralWidget(widget);
135462306a36Sopenharmony_ci
135562306a36Sopenharmony_ci	split1 = new QSplitter(widget);
135662306a36Sopenharmony_ci	split1->setOrientation(Qt::Horizontal);
135762306a36Sopenharmony_ci	split1->setChildrenCollapsible(false);
135862306a36Sopenharmony_ci
135962306a36Sopenharmony_ci	menuList = new ConfigList(widget, "menu");
136062306a36Sopenharmony_ci
136162306a36Sopenharmony_ci	split2 = new QSplitter(widget);
136262306a36Sopenharmony_ci	split2->setChildrenCollapsible(false);
136362306a36Sopenharmony_ci	split2->setOrientation(Qt::Vertical);
136462306a36Sopenharmony_ci
136562306a36Sopenharmony_ci	// create config tree
136662306a36Sopenharmony_ci	configList = new ConfigList(widget, "config");
136762306a36Sopenharmony_ci
136862306a36Sopenharmony_ci	helpText = new ConfigInfoView(widget, "help");
136962306a36Sopenharmony_ci
137062306a36Sopenharmony_ci	layout->addWidget(split2);
137162306a36Sopenharmony_ci	split2->addWidget(split1);
137262306a36Sopenharmony_ci	split1->addWidget(configList);
137362306a36Sopenharmony_ci	split1->addWidget(menuList);
137462306a36Sopenharmony_ci	split2->addWidget(helpText);
137562306a36Sopenharmony_ci
137662306a36Sopenharmony_ci	setTabOrder(configList, helpText);
137762306a36Sopenharmony_ci	configList->setFocus();
137862306a36Sopenharmony_ci
137962306a36Sopenharmony_ci	backAction = new QAction(QPixmap(xpm_back), "Back", this);
138062306a36Sopenharmony_ci	connect(backAction, &QAction::triggered,
138162306a36Sopenharmony_ci		this, &ConfigMainWindow::goBack);
138262306a36Sopenharmony_ci
138362306a36Sopenharmony_ci	QAction *quitAction = new QAction("&Quit", this);
138462306a36Sopenharmony_ci	quitAction->setShortcut(Qt::CTRL | Qt::Key_Q);
138562306a36Sopenharmony_ci	connect(quitAction, &QAction::triggered,
138662306a36Sopenharmony_ci		this, &ConfigMainWindow::close);
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_ci	QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
138962306a36Sopenharmony_ci	loadAction->setShortcut(Qt::CTRL | Qt::Key_L);
139062306a36Sopenharmony_ci	connect(loadAction, &QAction::triggered,
139162306a36Sopenharmony_ci		this, &ConfigMainWindow::loadConfig);
139262306a36Sopenharmony_ci
139362306a36Sopenharmony_ci	saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
139462306a36Sopenharmony_ci	saveAction->setShortcut(Qt::CTRL | Qt::Key_S);
139562306a36Sopenharmony_ci	connect(saveAction, &QAction::triggered,
139662306a36Sopenharmony_ci		this, &ConfigMainWindow::saveConfig);
139762306a36Sopenharmony_ci
139862306a36Sopenharmony_ci	conf_set_changed_callback(conf_changed);
139962306a36Sopenharmony_ci
140062306a36Sopenharmony_ci	// Set saveAction's initial state
140162306a36Sopenharmony_ci	conf_changed();
140262306a36Sopenharmony_ci	configname = xstrdup(conf_get_configname());
140362306a36Sopenharmony_ci
140462306a36Sopenharmony_ci	QAction *saveAsAction = new QAction("Save &As...", this);
140562306a36Sopenharmony_ci	connect(saveAsAction, &QAction::triggered,
140662306a36Sopenharmony_ci		this, &ConfigMainWindow::saveConfigAs);
140762306a36Sopenharmony_ci	QAction *searchAction = new QAction("&Find", this);
140862306a36Sopenharmony_ci	searchAction->setShortcut(Qt::CTRL | Qt::Key_F);
140962306a36Sopenharmony_ci	connect(searchAction, &QAction::triggered,
141062306a36Sopenharmony_ci		this, &ConfigMainWindow::searchConfig);
141162306a36Sopenharmony_ci	singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
141262306a36Sopenharmony_ci	singleViewAction->setCheckable(true);
141362306a36Sopenharmony_ci	connect(singleViewAction, &QAction::triggered,
141462306a36Sopenharmony_ci		this, &ConfigMainWindow::showSingleView);
141562306a36Sopenharmony_ci	splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
141662306a36Sopenharmony_ci	splitViewAction->setCheckable(true);
141762306a36Sopenharmony_ci	connect(splitViewAction, &QAction::triggered,
141862306a36Sopenharmony_ci		this, &ConfigMainWindow::showSplitView);
141962306a36Sopenharmony_ci	fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
142062306a36Sopenharmony_ci	fullViewAction->setCheckable(true);
142162306a36Sopenharmony_ci	connect(fullViewAction, &QAction::triggered,
142262306a36Sopenharmony_ci		this, &ConfigMainWindow::showFullView);
142362306a36Sopenharmony_ci
142462306a36Sopenharmony_ci	QAction *showNameAction = new QAction("Show Name", this);
142562306a36Sopenharmony_ci	  showNameAction->setCheckable(true);
142662306a36Sopenharmony_ci	connect(showNameAction, &QAction::toggled,
142762306a36Sopenharmony_ci		configList, &ConfigList::setShowName);
142862306a36Sopenharmony_ci	showNameAction->setChecked(configList->showName);
142962306a36Sopenharmony_ci
143062306a36Sopenharmony_ci	QActionGroup *optGroup = new QActionGroup(this);
143162306a36Sopenharmony_ci	optGroup->setExclusive(true);
143262306a36Sopenharmony_ci	connect(optGroup, &QActionGroup::triggered,
143362306a36Sopenharmony_ci		configList, &ConfigList::setOptionMode);
143462306a36Sopenharmony_ci	connect(optGroup, &QActionGroup::triggered,
143562306a36Sopenharmony_ci		menuList, &ConfigList::setOptionMode);
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ci	ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup);
143862306a36Sopenharmony_ci	ConfigList::showNormalAction->setCheckable(true);
143962306a36Sopenharmony_ci	ConfigList::showAllAction = new QAction("Show All Options", optGroup);
144062306a36Sopenharmony_ci	ConfigList::showAllAction->setCheckable(true);
144162306a36Sopenharmony_ci	ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
144262306a36Sopenharmony_ci	ConfigList::showPromptAction->setCheckable(true);
144362306a36Sopenharmony_ci
144462306a36Sopenharmony_ci	QAction *showDebugAction = new QAction("Show Debug Info", this);
144562306a36Sopenharmony_ci	  showDebugAction->setCheckable(true);
144662306a36Sopenharmony_ci	connect(showDebugAction, &QAction::toggled,
144762306a36Sopenharmony_ci		helpText, &ConfigInfoView::setShowDebug);
144862306a36Sopenharmony_ci	  showDebugAction->setChecked(helpText->showDebug());
144962306a36Sopenharmony_ci
145062306a36Sopenharmony_ci	QAction *showIntroAction = new QAction("Introduction", this);
145162306a36Sopenharmony_ci	connect(showIntroAction, &QAction::triggered,
145262306a36Sopenharmony_ci		this, &ConfigMainWindow::showIntro);
145362306a36Sopenharmony_ci	QAction *showAboutAction = new QAction("About", this);
145462306a36Sopenharmony_ci	connect(showAboutAction, &QAction::triggered,
145562306a36Sopenharmony_ci		this, &ConfigMainWindow::showAbout);
145662306a36Sopenharmony_ci
145762306a36Sopenharmony_ci	// init tool bar
145862306a36Sopenharmony_ci	QToolBar *toolBar = addToolBar("Tools");
145962306a36Sopenharmony_ci	toolBar->addAction(backAction);
146062306a36Sopenharmony_ci	toolBar->addSeparator();
146162306a36Sopenharmony_ci	toolBar->addAction(loadAction);
146262306a36Sopenharmony_ci	toolBar->addAction(saveAction);
146362306a36Sopenharmony_ci	toolBar->addSeparator();
146462306a36Sopenharmony_ci	toolBar->addAction(singleViewAction);
146562306a36Sopenharmony_ci	toolBar->addAction(splitViewAction);
146662306a36Sopenharmony_ci	toolBar->addAction(fullViewAction);
146762306a36Sopenharmony_ci
146862306a36Sopenharmony_ci	// create file menu
146962306a36Sopenharmony_ci	QMenu *menu = menuBar()->addMenu("&File");
147062306a36Sopenharmony_ci	menu->addAction(loadAction);
147162306a36Sopenharmony_ci	menu->addAction(saveAction);
147262306a36Sopenharmony_ci	menu->addAction(saveAsAction);
147362306a36Sopenharmony_ci	menu->addSeparator();
147462306a36Sopenharmony_ci	menu->addAction(quitAction);
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_ci	// create edit menu
147762306a36Sopenharmony_ci	menu = menuBar()->addMenu("&Edit");
147862306a36Sopenharmony_ci	menu->addAction(searchAction);
147962306a36Sopenharmony_ci
148062306a36Sopenharmony_ci	// create options menu
148162306a36Sopenharmony_ci	menu = menuBar()->addMenu("&Option");
148262306a36Sopenharmony_ci	menu->addAction(showNameAction);
148362306a36Sopenharmony_ci	menu->addSeparator();
148462306a36Sopenharmony_ci	menu->addActions(optGroup->actions());
148562306a36Sopenharmony_ci	menu->addSeparator();
148662306a36Sopenharmony_ci	menu->addAction(showDebugAction);
148762306a36Sopenharmony_ci
148862306a36Sopenharmony_ci	// create help menu
148962306a36Sopenharmony_ci	menu = menuBar()->addMenu("&Help");
149062306a36Sopenharmony_ci	menu->addAction(showIntroAction);
149162306a36Sopenharmony_ci	menu->addAction(showAboutAction);
149262306a36Sopenharmony_ci
149362306a36Sopenharmony_ci	connect(helpText, &ConfigInfoView::anchorClicked,
149462306a36Sopenharmony_ci		helpText, &ConfigInfoView::clicked);
149562306a36Sopenharmony_ci
149662306a36Sopenharmony_ci	connect(configList, &ConfigList::menuChanged,
149762306a36Sopenharmony_ci		helpText, &ConfigInfoView::setInfo);
149862306a36Sopenharmony_ci	connect(configList, &ConfigList::menuSelected,
149962306a36Sopenharmony_ci		this, &ConfigMainWindow::changeMenu);
150062306a36Sopenharmony_ci	connect(configList, &ConfigList::itemSelected,
150162306a36Sopenharmony_ci		this, &ConfigMainWindow::changeItens);
150262306a36Sopenharmony_ci	connect(configList, &ConfigList::parentSelected,
150362306a36Sopenharmony_ci		this, &ConfigMainWindow::goBack);
150462306a36Sopenharmony_ci	connect(menuList, &ConfigList::menuChanged,
150562306a36Sopenharmony_ci		helpText, &ConfigInfoView::setInfo);
150662306a36Sopenharmony_ci	connect(menuList, &ConfigList::menuSelected,
150762306a36Sopenharmony_ci		this, &ConfigMainWindow::changeMenu);
150862306a36Sopenharmony_ci
150962306a36Sopenharmony_ci	connect(configList, &ConfigList::gotFocus,
151062306a36Sopenharmony_ci		helpText, &ConfigInfoView::setInfo);
151162306a36Sopenharmony_ci	connect(menuList, &ConfigList::gotFocus,
151262306a36Sopenharmony_ci		helpText, &ConfigInfoView::setInfo);
151362306a36Sopenharmony_ci	connect(menuList, &ConfigList::gotFocus,
151462306a36Sopenharmony_ci		this, &ConfigMainWindow::listFocusChanged);
151562306a36Sopenharmony_ci	connect(helpText, &ConfigInfoView::menuSelected,
151662306a36Sopenharmony_ci		this, &ConfigMainWindow::setMenuLink);
151762306a36Sopenharmony_ci
151862306a36Sopenharmony_ci	QString listMode = configSettings->value("/listMode", "symbol").toString();
151962306a36Sopenharmony_ci	if (listMode == "single")
152062306a36Sopenharmony_ci		showSingleView();
152162306a36Sopenharmony_ci	else if (listMode == "full")
152262306a36Sopenharmony_ci		showFullView();
152362306a36Sopenharmony_ci	else /*if (listMode == "split")*/
152462306a36Sopenharmony_ci		showSplitView();
152562306a36Sopenharmony_ci
152662306a36Sopenharmony_ci	// UI setup done, restore splitter positions
152762306a36Sopenharmony_ci	QList<int> sizes = configSettings->readSizes("/split1", &ok);
152862306a36Sopenharmony_ci	if (ok)
152962306a36Sopenharmony_ci		split1->setSizes(sizes);
153062306a36Sopenharmony_ci
153162306a36Sopenharmony_ci	sizes = configSettings->readSizes("/split2", &ok);
153262306a36Sopenharmony_ci	if (ok)
153362306a36Sopenharmony_ci		split2->setSizes(sizes);
153462306a36Sopenharmony_ci}
153562306a36Sopenharmony_ci
153662306a36Sopenharmony_civoid ConfigMainWindow::loadConfig(void)
153762306a36Sopenharmony_ci{
153862306a36Sopenharmony_ci	QString str;
153962306a36Sopenharmony_ci	QByteArray ba;
154062306a36Sopenharmony_ci	const char *name;
154162306a36Sopenharmony_ci
154262306a36Sopenharmony_ci	str = QFileDialog::getOpenFileName(this, "", configname);
154362306a36Sopenharmony_ci	if (str.isNull())
154462306a36Sopenharmony_ci		return;
154562306a36Sopenharmony_ci
154662306a36Sopenharmony_ci	ba = str.toLocal8Bit();
154762306a36Sopenharmony_ci	name = ba.data();
154862306a36Sopenharmony_ci
154962306a36Sopenharmony_ci	if (conf_read(name))
155062306a36Sopenharmony_ci		QMessageBox::information(this, "qconf", "Unable to load configuration!");
155162306a36Sopenharmony_ci
155262306a36Sopenharmony_ci	free(configname);
155362306a36Sopenharmony_ci	configname = xstrdup(name);
155462306a36Sopenharmony_ci
155562306a36Sopenharmony_ci	ConfigList::updateListAllForAll();
155662306a36Sopenharmony_ci}
155762306a36Sopenharmony_ci
155862306a36Sopenharmony_cibool ConfigMainWindow::saveConfig(void)
155962306a36Sopenharmony_ci{
156062306a36Sopenharmony_ci	if (conf_write(configname)) {
156162306a36Sopenharmony_ci		QMessageBox::information(this, "qconf", "Unable to save configuration!");
156262306a36Sopenharmony_ci		return false;
156362306a36Sopenharmony_ci	}
156462306a36Sopenharmony_ci	conf_write_autoconf(0);
156562306a36Sopenharmony_ci
156662306a36Sopenharmony_ci	return true;
156762306a36Sopenharmony_ci}
156862306a36Sopenharmony_ci
156962306a36Sopenharmony_civoid ConfigMainWindow::saveConfigAs(void)
157062306a36Sopenharmony_ci{
157162306a36Sopenharmony_ci	QString str;
157262306a36Sopenharmony_ci	QByteArray ba;
157362306a36Sopenharmony_ci	const char *name;
157462306a36Sopenharmony_ci
157562306a36Sopenharmony_ci	str = QFileDialog::getSaveFileName(this, "", configname);
157662306a36Sopenharmony_ci	if (str.isNull())
157762306a36Sopenharmony_ci		return;
157862306a36Sopenharmony_ci
157962306a36Sopenharmony_ci	ba = str.toLocal8Bit();
158062306a36Sopenharmony_ci	name = ba.data();
158162306a36Sopenharmony_ci
158262306a36Sopenharmony_ci	if (conf_write(name)) {
158362306a36Sopenharmony_ci		QMessageBox::information(this, "qconf", "Unable to save configuration!");
158462306a36Sopenharmony_ci	}
158562306a36Sopenharmony_ci	conf_write_autoconf(0);
158662306a36Sopenharmony_ci
158762306a36Sopenharmony_ci	free(configname);
158862306a36Sopenharmony_ci	configname = xstrdup(name);
158962306a36Sopenharmony_ci}
159062306a36Sopenharmony_ci
159162306a36Sopenharmony_civoid ConfigMainWindow::searchConfig(void)
159262306a36Sopenharmony_ci{
159362306a36Sopenharmony_ci	if (!searchWindow)
159462306a36Sopenharmony_ci		searchWindow = new ConfigSearchWindow(this);
159562306a36Sopenharmony_ci	searchWindow->show();
159662306a36Sopenharmony_ci}
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_civoid ConfigMainWindow::changeItens(struct menu *menu)
159962306a36Sopenharmony_ci{
160062306a36Sopenharmony_ci	configList->setRootMenu(menu);
160162306a36Sopenharmony_ci}
160262306a36Sopenharmony_ci
160362306a36Sopenharmony_civoid ConfigMainWindow::changeMenu(struct menu *menu)
160462306a36Sopenharmony_ci{
160562306a36Sopenharmony_ci	menuList->setRootMenu(menu);
160662306a36Sopenharmony_ci}
160762306a36Sopenharmony_ci
160862306a36Sopenharmony_civoid ConfigMainWindow::setMenuLink(struct menu *menu)
160962306a36Sopenharmony_ci{
161062306a36Sopenharmony_ci	struct menu *parent;
161162306a36Sopenharmony_ci	ConfigList* list = NULL;
161262306a36Sopenharmony_ci	ConfigItem* item;
161362306a36Sopenharmony_ci
161462306a36Sopenharmony_ci	if (configList->menuSkip(menu))
161562306a36Sopenharmony_ci		return;
161662306a36Sopenharmony_ci
161762306a36Sopenharmony_ci	switch (configList->mode) {
161862306a36Sopenharmony_ci	case singleMode:
161962306a36Sopenharmony_ci		list = configList;
162062306a36Sopenharmony_ci		parent = menu_get_parent_menu(menu);
162162306a36Sopenharmony_ci		if (!parent)
162262306a36Sopenharmony_ci			return;
162362306a36Sopenharmony_ci		list->setRootMenu(parent);
162462306a36Sopenharmony_ci		break;
162562306a36Sopenharmony_ci	case menuMode:
162662306a36Sopenharmony_ci		if (menu->flags & MENU_ROOT) {
162762306a36Sopenharmony_ci			menuList->setRootMenu(menu);
162862306a36Sopenharmony_ci			configList->clearSelection();
162962306a36Sopenharmony_ci			list = configList;
163062306a36Sopenharmony_ci		} else {
163162306a36Sopenharmony_ci			parent = menu_get_parent_menu(menu->parent);
163262306a36Sopenharmony_ci			if (!parent)
163362306a36Sopenharmony_ci				return;
163462306a36Sopenharmony_ci
163562306a36Sopenharmony_ci			/* Select the config view */
163662306a36Sopenharmony_ci			item = configList->findConfigItem(parent);
163762306a36Sopenharmony_ci			if (item) {
163862306a36Sopenharmony_ci				configList->setSelected(item, true);
163962306a36Sopenharmony_ci				configList->scrollToItem(item);
164062306a36Sopenharmony_ci			}
164162306a36Sopenharmony_ci
164262306a36Sopenharmony_ci			menuList->setRootMenu(parent);
164362306a36Sopenharmony_ci			menuList->clearSelection();
164462306a36Sopenharmony_ci			list = menuList;
164562306a36Sopenharmony_ci		}
164662306a36Sopenharmony_ci		break;
164762306a36Sopenharmony_ci	case fullMode:
164862306a36Sopenharmony_ci		list = configList;
164962306a36Sopenharmony_ci		break;
165062306a36Sopenharmony_ci	default:
165162306a36Sopenharmony_ci		break;
165262306a36Sopenharmony_ci	}
165362306a36Sopenharmony_ci
165462306a36Sopenharmony_ci	if (list) {
165562306a36Sopenharmony_ci		item = list->findConfigItem(menu);
165662306a36Sopenharmony_ci		if (item) {
165762306a36Sopenharmony_ci			list->setSelected(item, true);
165862306a36Sopenharmony_ci			list->scrollToItem(item);
165962306a36Sopenharmony_ci			list->setFocus();
166062306a36Sopenharmony_ci			helpText->setInfo(menu);
166162306a36Sopenharmony_ci		}
166262306a36Sopenharmony_ci	}
166362306a36Sopenharmony_ci}
166462306a36Sopenharmony_ci
166562306a36Sopenharmony_civoid ConfigMainWindow::listFocusChanged(void)
166662306a36Sopenharmony_ci{
166762306a36Sopenharmony_ci	if (menuList->mode == menuMode)
166862306a36Sopenharmony_ci		configList->clearSelection();
166962306a36Sopenharmony_ci}
167062306a36Sopenharmony_ci
167162306a36Sopenharmony_civoid ConfigMainWindow::goBack(void)
167262306a36Sopenharmony_ci{
167362306a36Sopenharmony_ci	if (configList->rootEntry == &rootmenu)
167462306a36Sopenharmony_ci		return;
167562306a36Sopenharmony_ci
167662306a36Sopenharmony_ci	configList->setParentMenu();
167762306a36Sopenharmony_ci}
167862306a36Sopenharmony_ci
167962306a36Sopenharmony_civoid ConfigMainWindow::showSingleView(void)
168062306a36Sopenharmony_ci{
168162306a36Sopenharmony_ci	singleViewAction->setEnabled(false);
168262306a36Sopenharmony_ci	singleViewAction->setChecked(true);
168362306a36Sopenharmony_ci	splitViewAction->setEnabled(true);
168462306a36Sopenharmony_ci	splitViewAction->setChecked(false);
168562306a36Sopenharmony_ci	fullViewAction->setEnabled(true);
168662306a36Sopenharmony_ci	fullViewAction->setChecked(false);
168762306a36Sopenharmony_ci
168862306a36Sopenharmony_ci	backAction->setEnabled(true);
168962306a36Sopenharmony_ci
169062306a36Sopenharmony_ci	menuList->hide();
169162306a36Sopenharmony_ci	menuList->setRootMenu(0);
169262306a36Sopenharmony_ci	configList->mode = singleMode;
169362306a36Sopenharmony_ci	if (configList->rootEntry == &rootmenu)
169462306a36Sopenharmony_ci		configList->updateListAll();
169562306a36Sopenharmony_ci	else
169662306a36Sopenharmony_ci		configList->setRootMenu(&rootmenu);
169762306a36Sopenharmony_ci	configList->setFocus();
169862306a36Sopenharmony_ci}
169962306a36Sopenharmony_ci
170062306a36Sopenharmony_civoid ConfigMainWindow::showSplitView(void)
170162306a36Sopenharmony_ci{
170262306a36Sopenharmony_ci	singleViewAction->setEnabled(true);
170362306a36Sopenharmony_ci	singleViewAction->setChecked(false);
170462306a36Sopenharmony_ci	splitViewAction->setEnabled(false);
170562306a36Sopenharmony_ci	splitViewAction->setChecked(true);
170662306a36Sopenharmony_ci	fullViewAction->setEnabled(true);
170762306a36Sopenharmony_ci	fullViewAction->setChecked(false);
170862306a36Sopenharmony_ci
170962306a36Sopenharmony_ci	backAction->setEnabled(false);
171062306a36Sopenharmony_ci
171162306a36Sopenharmony_ci	configList->mode = menuMode;
171262306a36Sopenharmony_ci	if (configList->rootEntry == &rootmenu)
171362306a36Sopenharmony_ci		configList->updateListAll();
171462306a36Sopenharmony_ci	else
171562306a36Sopenharmony_ci		configList->setRootMenu(&rootmenu);
171662306a36Sopenharmony_ci	configList->setAllOpen(true);
171762306a36Sopenharmony_ci	configApp->processEvents();
171862306a36Sopenharmony_ci	menuList->mode = symbolMode;
171962306a36Sopenharmony_ci	menuList->setRootMenu(&rootmenu);
172062306a36Sopenharmony_ci	menuList->setAllOpen(true);
172162306a36Sopenharmony_ci	menuList->show();
172262306a36Sopenharmony_ci	menuList->setFocus();
172362306a36Sopenharmony_ci}
172462306a36Sopenharmony_ci
172562306a36Sopenharmony_civoid ConfigMainWindow::showFullView(void)
172662306a36Sopenharmony_ci{
172762306a36Sopenharmony_ci	singleViewAction->setEnabled(true);
172862306a36Sopenharmony_ci	singleViewAction->setChecked(false);
172962306a36Sopenharmony_ci	splitViewAction->setEnabled(true);
173062306a36Sopenharmony_ci	splitViewAction->setChecked(false);
173162306a36Sopenharmony_ci	fullViewAction->setEnabled(false);
173262306a36Sopenharmony_ci	fullViewAction->setChecked(true);
173362306a36Sopenharmony_ci
173462306a36Sopenharmony_ci	backAction->setEnabled(false);
173562306a36Sopenharmony_ci
173662306a36Sopenharmony_ci	menuList->hide();
173762306a36Sopenharmony_ci	menuList->setRootMenu(0);
173862306a36Sopenharmony_ci	configList->mode = fullMode;
173962306a36Sopenharmony_ci	if (configList->rootEntry == &rootmenu)
174062306a36Sopenharmony_ci		configList->updateListAll();
174162306a36Sopenharmony_ci	else
174262306a36Sopenharmony_ci		configList->setRootMenu(&rootmenu);
174362306a36Sopenharmony_ci	configList->setFocus();
174462306a36Sopenharmony_ci}
174562306a36Sopenharmony_ci
174662306a36Sopenharmony_ci/*
174762306a36Sopenharmony_ci * ask for saving configuration before quitting
174862306a36Sopenharmony_ci */
174962306a36Sopenharmony_civoid ConfigMainWindow::closeEvent(QCloseEvent* e)
175062306a36Sopenharmony_ci{
175162306a36Sopenharmony_ci	if (!conf_get_changed()) {
175262306a36Sopenharmony_ci		e->accept();
175362306a36Sopenharmony_ci		return;
175462306a36Sopenharmony_ci	}
175562306a36Sopenharmony_ci
175662306a36Sopenharmony_ci	QMessageBox mb(QMessageBox::Icon::Warning, "qconf",
175762306a36Sopenharmony_ci		       "Save configuration?");
175862306a36Sopenharmony_ci
175962306a36Sopenharmony_ci	QPushButton *yb = mb.addButton(QMessageBox::Yes);
176062306a36Sopenharmony_ci	QPushButton *db = mb.addButton(QMessageBox::No);
176162306a36Sopenharmony_ci	QPushButton *cb = mb.addButton(QMessageBox::Cancel);
176262306a36Sopenharmony_ci
176362306a36Sopenharmony_ci	yb->setText("&Save Changes");
176462306a36Sopenharmony_ci	db->setText("&Discard Changes");
176562306a36Sopenharmony_ci	cb->setText("Cancel Exit");
176662306a36Sopenharmony_ci
176762306a36Sopenharmony_ci	mb.setDefaultButton(yb);
176862306a36Sopenharmony_ci	mb.setEscapeButton(cb);
176962306a36Sopenharmony_ci
177062306a36Sopenharmony_ci	switch (mb.exec()) {
177162306a36Sopenharmony_ci	case QMessageBox::Yes:
177262306a36Sopenharmony_ci		if (saveConfig())
177362306a36Sopenharmony_ci			e->accept();
177462306a36Sopenharmony_ci		else
177562306a36Sopenharmony_ci			e->ignore();
177662306a36Sopenharmony_ci		break;
177762306a36Sopenharmony_ci	case QMessageBox::No:
177862306a36Sopenharmony_ci		e->accept();
177962306a36Sopenharmony_ci		break;
178062306a36Sopenharmony_ci	case QMessageBox::Cancel:
178162306a36Sopenharmony_ci		e->ignore();
178262306a36Sopenharmony_ci		break;
178362306a36Sopenharmony_ci	}
178462306a36Sopenharmony_ci}
178562306a36Sopenharmony_ci
178662306a36Sopenharmony_civoid ConfigMainWindow::showIntro(void)
178762306a36Sopenharmony_ci{
178862306a36Sopenharmony_ci	static const QString str =
178962306a36Sopenharmony_ci		"Welcome to the qconf graphical configuration tool.\n"
179062306a36Sopenharmony_ci		"\n"
179162306a36Sopenharmony_ci		"For bool and tristate options, a blank box indicates the "
179262306a36Sopenharmony_ci		"feature is disabled, a check indicates it is enabled, and a "
179362306a36Sopenharmony_ci		"dot indicates that it is to be compiled as a module. Clicking "
179462306a36Sopenharmony_ci		"on the box will cycle through the three states. For int, hex, "
179562306a36Sopenharmony_ci		"and string options, double-clicking or pressing F2 on the "
179662306a36Sopenharmony_ci		"Value cell will allow you to edit the value.\n"
179762306a36Sopenharmony_ci		"\n"
179862306a36Sopenharmony_ci		"If you do not see an option (e.g., a device driver) that you "
179962306a36Sopenharmony_ci		"believe should be present, try turning on Show All Options "
180062306a36Sopenharmony_ci		"under the Options menu. Enabling Show Debug Info will help you"
180162306a36Sopenharmony_ci		"figure out what other options must be enabled to support the "
180262306a36Sopenharmony_ci		"option you are interested in, and hyperlinks will navigate to "
180362306a36Sopenharmony_ci		"them.\n"
180462306a36Sopenharmony_ci		"\n"
180562306a36Sopenharmony_ci		"Toggling Show Debug Info under the Options menu will show the "
180662306a36Sopenharmony_ci		"dependencies, which you can then match by examining other "
180762306a36Sopenharmony_ci		"options.\n";
180862306a36Sopenharmony_ci
180962306a36Sopenharmony_ci	QMessageBox::information(this, "qconf", str);
181062306a36Sopenharmony_ci}
181162306a36Sopenharmony_ci
181262306a36Sopenharmony_civoid ConfigMainWindow::showAbout(void)
181362306a36Sopenharmony_ci{
181462306a36Sopenharmony_ci	static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
181562306a36Sopenharmony_ci		"Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n"
181662306a36Sopenharmony_ci		"\n"
181762306a36Sopenharmony_ci		"Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"
181862306a36Sopenharmony_ci		"\n"
181962306a36Sopenharmony_ci		"Qt Version: ";
182062306a36Sopenharmony_ci
182162306a36Sopenharmony_ci	QMessageBox::information(this, "qconf", str + qVersion());
182262306a36Sopenharmony_ci}
182362306a36Sopenharmony_ci
182462306a36Sopenharmony_civoid ConfigMainWindow::saveSettings(void)
182562306a36Sopenharmony_ci{
182662306a36Sopenharmony_ci	configSettings->setValue("/window x", pos().x());
182762306a36Sopenharmony_ci	configSettings->setValue("/window y", pos().y());
182862306a36Sopenharmony_ci	configSettings->setValue("/window width", size().width());
182962306a36Sopenharmony_ci	configSettings->setValue("/window height", size().height());
183062306a36Sopenharmony_ci
183162306a36Sopenharmony_ci	QString entry;
183262306a36Sopenharmony_ci	switch(configList->mode) {
183362306a36Sopenharmony_ci	case singleMode :
183462306a36Sopenharmony_ci		entry = "single";
183562306a36Sopenharmony_ci		break;
183662306a36Sopenharmony_ci
183762306a36Sopenharmony_ci	case symbolMode :
183862306a36Sopenharmony_ci		entry = "split";
183962306a36Sopenharmony_ci		break;
184062306a36Sopenharmony_ci
184162306a36Sopenharmony_ci	case fullMode :
184262306a36Sopenharmony_ci		entry = "full";
184362306a36Sopenharmony_ci		break;
184462306a36Sopenharmony_ci
184562306a36Sopenharmony_ci	default:
184662306a36Sopenharmony_ci		break;
184762306a36Sopenharmony_ci	}
184862306a36Sopenharmony_ci	configSettings->setValue("/listMode", entry);
184962306a36Sopenharmony_ci
185062306a36Sopenharmony_ci	configSettings->writeSizes("/split1", split1->sizes());
185162306a36Sopenharmony_ci	configSettings->writeSizes("/split2", split2->sizes());
185262306a36Sopenharmony_ci}
185362306a36Sopenharmony_ci
185462306a36Sopenharmony_civoid ConfigMainWindow::conf_changed(void)
185562306a36Sopenharmony_ci{
185662306a36Sopenharmony_ci	if (saveAction)
185762306a36Sopenharmony_ci		saveAction->setEnabled(conf_get_changed());
185862306a36Sopenharmony_ci}
185962306a36Sopenharmony_ci
186062306a36Sopenharmony_civoid fixup_rootmenu(struct menu *menu)
186162306a36Sopenharmony_ci{
186262306a36Sopenharmony_ci	struct menu *child;
186362306a36Sopenharmony_ci	static int menu_cnt = 0;
186462306a36Sopenharmony_ci
186562306a36Sopenharmony_ci	menu->flags |= MENU_ROOT;
186662306a36Sopenharmony_ci	for (child = menu->list; child; child = child->next) {
186762306a36Sopenharmony_ci		if (child->prompt && child->prompt->type == P_MENU) {
186862306a36Sopenharmony_ci			menu_cnt++;
186962306a36Sopenharmony_ci			fixup_rootmenu(child);
187062306a36Sopenharmony_ci			menu_cnt--;
187162306a36Sopenharmony_ci		} else if (!menu_cnt)
187262306a36Sopenharmony_ci			fixup_rootmenu(child);
187362306a36Sopenharmony_ci	}
187462306a36Sopenharmony_ci}
187562306a36Sopenharmony_ci
187662306a36Sopenharmony_cistatic const char *progname;
187762306a36Sopenharmony_ci
187862306a36Sopenharmony_cistatic void usage(void)
187962306a36Sopenharmony_ci{
188062306a36Sopenharmony_ci	printf("%s [-s] <config>\n", progname);
188162306a36Sopenharmony_ci	exit(0);
188262306a36Sopenharmony_ci}
188362306a36Sopenharmony_ci
188462306a36Sopenharmony_ciint main(int ac, char** av)
188562306a36Sopenharmony_ci{
188662306a36Sopenharmony_ci	ConfigMainWindow* v;
188762306a36Sopenharmony_ci	const char *name;
188862306a36Sopenharmony_ci
188962306a36Sopenharmony_ci	progname = av[0];
189062306a36Sopenharmony_ci	if (ac > 1 && av[1][0] == '-') {
189162306a36Sopenharmony_ci		switch (av[1][1]) {
189262306a36Sopenharmony_ci		case 's':
189362306a36Sopenharmony_ci			conf_set_message_callback(NULL);
189462306a36Sopenharmony_ci			break;
189562306a36Sopenharmony_ci		case 'h':
189662306a36Sopenharmony_ci		case '?':
189762306a36Sopenharmony_ci			usage();
189862306a36Sopenharmony_ci		}
189962306a36Sopenharmony_ci		name = av[2];
190062306a36Sopenharmony_ci	} else
190162306a36Sopenharmony_ci		name = av[1];
190262306a36Sopenharmony_ci	if (!name)
190362306a36Sopenharmony_ci		usage();
190462306a36Sopenharmony_ci
190562306a36Sopenharmony_ci	conf_parse(name);
190662306a36Sopenharmony_ci	fixup_rootmenu(&rootmenu);
190762306a36Sopenharmony_ci	conf_read(NULL);
190862306a36Sopenharmony_ci	//zconfdump(stdout);
190962306a36Sopenharmony_ci
191062306a36Sopenharmony_ci	configApp = new QApplication(ac, av);
191162306a36Sopenharmony_ci
191262306a36Sopenharmony_ci	configSettings = new ConfigSettings();
191362306a36Sopenharmony_ci	configSettings->beginGroup("/kconfig/qconf");
191462306a36Sopenharmony_ci	v = new ConfigMainWindow();
191562306a36Sopenharmony_ci
191662306a36Sopenharmony_ci	//zconfdump(stdout);
191762306a36Sopenharmony_ci	configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
191862306a36Sopenharmony_ci	configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
191962306a36Sopenharmony_ci	v->show();
192062306a36Sopenharmony_ci	configApp->exec();
192162306a36Sopenharmony_ci
192262306a36Sopenharmony_ci	configSettings->endGroup();
192362306a36Sopenharmony_ci	delete configSettings;
192462306a36Sopenharmony_ci	delete v;
192562306a36Sopenharmony_ci	delete configApp;
192662306a36Sopenharmony_ci
192762306a36Sopenharmony_ci	return 0;
192862306a36Sopenharmony_ci}
1929