1862 lines · 42.2 KB · C++
RawDownload
// SPDX-License-Identifier: GPL-2.0/* * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com> */ #include <QAction>#include <QActionGroup>#include <QApplication>#include <QCloseEvent>#include <QDebug>#include <QFileDialog>#include <QLabel>#include <QLayout>#include <QList>#include <QMenu>#include <QMenuBar>#include <QMessageBox>#include <QRegularExpression>#include <QScreen>#include <QToolBar> #include <stdlib.h> #include <xalloc.h>#include "lkc.h"#include "qconf.h"  static QApplication *configApp;static ConfigSettings *configSettings; QAction *ConfigMainWindow::saveAction; ConfigSettings::ConfigSettings()	: QSettings("kernel.org", "qconf"){	beginGroup("/kconfig/qconf");} ConfigSettings::~ConfigSettings(){	endGroup();} /** * Reads a list of integer values from the application settings. */QList<int> ConfigSettings::readSizes(const QString& key, bool *ok){	QList<int> result; 	if (contains(key))	{		QStringList entryList = value(key).toStringList();		QStringList::Iterator it; 		for (it = entryList.begin(); it != entryList.end(); ++it)			result.push_back((*it).toInt()); 		*ok = true;	}	else		*ok = false; 	return result;} /** * Writes a list of integer values to the application settings. */bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value){	QStringList stringList;	QList<int>::ConstIterator it; 	for (it = value.begin(); it != value.end(); ++it)		stringList.push_back(QString::number(*it));	setValue(key, stringList); 	return true;} QIcon ConfigItem::symbolYesIcon;QIcon ConfigItem::symbolModIcon;QIcon ConfigItem::symbolNoIcon;QIcon ConfigItem::choiceYesIcon;QIcon ConfigItem::choiceNoIcon;QIcon ConfigItem::menuIcon;QIcon ConfigItem::menubackIcon; /* * update the displayed of a menu entry */void ConfigItem::updateMenu(void){	ConfigList* list;	struct symbol* sym;	QString prompt;	int type;	tristate expr; 	list = listView();	if (goParent) {		setIcon(promptColIdx, menubackIcon);		prompt = "..";		goto set_prompt;	} 	sym = menu->sym;	prompt = menu_get_prompt(menu); 	switch (menu->type) {	case M_MENU:		if (list->mode == singleMode) {			/* a menuconfig entry is displayed differently			 * depending whether it's at the view root or a child.			 */			if (sym && list->rootEntry == menu)				break;			setIcon(promptColIdx, menuIcon);		} else {			if (sym)				break;			setIcon(promptColIdx, QIcon());		}		goto set_prompt;	case M_COMMENT:		setIcon(promptColIdx, QIcon());		prompt = "*** " + prompt + " ***";		goto set_prompt;	case M_CHOICE:		setIcon(promptColIdx, QIcon());		sym = sym_calc_choice(menu);		if (sym)			setText(dataColIdx, sym->name);		goto set_prompt;	default:		;	}	if (!sym)		goto set_prompt; 	setText(nameColIdx, sym->name); 	type = sym_get_type(sym);	switch (type) {	case S_BOOLEAN:	case S_TRISTATE:		char ch; 		if (!sym_is_changeable(sym) && list->optMode == normalOpt) {			setIcon(promptColIdx, QIcon());			break;		}		expr = sym_get_tristate_value(sym);		switch (expr) {		case yes:			if (sym_is_choice_value(sym))				setIcon(promptColIdx, choiceYesIcon);			else				setIcon(promptColIdx, symbolYesIcon);			ch = 'Y';			break;		case mod:			setIcon(promptColIdx, symbolModIcon);			ch = 'M';			break;		default:			if (sym_is_choice_value(sym))				setIcon(promptColIdx, choiceNoIcon);			else				setIcon(promptColIdx, symbolNoIcon);			ch = 'N';			break;		} 		setText(dataColIdx, QChar(ch));		break;	case S_INT:	case S_HEX:	case S_STRING:		setText(dataColIdx, sym_get_string_value(sym));		break;	}	if (!sym_has_value(sym))		prompt += " (NEW)";set_prompt:	setText(promptColIdx, prompt);} void ConfigItem::testUpdateMenu(void){	ConfigItem* i; 	if (!menu)		return; 	if (menu->type == M_CHOICE)		sym_calc_choice(menu);	else		sym_calc_value(menu->sym); 	if (menu->flags & MENU_CHANGED) {		/* the menu entry changed, so update all list items */		menu->flags &= ~MENU_CHANGED;		for (i = (ConfigItem*)menu->data; i; i = i->nextItem)			i->updateMenu();	} else if (listView()->updateAll)		updateMenu();}  /* * construct a menu entry */void ConfigItem::init(void){	if (menu) {		ConfigList* list = listView();		nextItem = (ConfigItem*)menu->data;		menu->data = this; 		if (list->mode != fullMode)			setExpanded(true);		sym_calc_value(menu->sym); 		if (menu->sym) {			enum symbol_type type = menu->sym->type; 			// Allow to edit "int", "hex", and "string" in-place in			// the data column. Unfortunately, you cannot specify			// the flags per column. Set ItemIsEditable for all			// columns here, and check the column in createEditor().			if (type == S_INT || type == S_HEX || type == S_STRING)				setFlags(flags() | Qt::ItemIsEditable);		}	}	updateMenu();} /* * destruct a menu entry */ConfigItem::~ConfigItem(void){	if (menu) {		ConfigItem** ip = (ConfigItem**)&menu->data;		for (; *ip; ip = &(*ip)->nextItem) {			if (*ip == this) {				*ip = nextItem;				break;			}		}	}} QWidget *ConfigItemDelegate::createEditor(QWidget *parent,					  const QStyleOptionViewItem &option,					  const QModelIndex &index) const{	ConfigItem *item; 	// Only the data column is editable	if (index.column() != dataColIdx)		return nullptr; 	// You cannot edit invisible menus	item = static_cast<ConfigItem *>(index.internalPointer());	if (!item || !item->menu || !menu_is_visible(item->menu))		return nullptr; 	return QStyledItemDelegate::createEditor(parent, option, index);} void ConfigItemDelegate::setModelData(QWidget *editor,				      QAbstractItemModel *model,				      const QModelIndex &index) const{	QLineEdit *lineEdit;	ConfigItem *item;	struct symbol *sym;	bool success; 	lineEdit = qobject_cast<QLineEdit *>(editor);	// If this is not a QLineEdit, use the parent's default.	// (does this happen?)	if (!lineEdit)		goto parent; 	item = static_cast<ConfigItem *>(index.internalPointer());	if (!item || !item->menu)		goto parent; 	sym = item->menu->sym;	if (!sym)		goto parent; 	success = sym_set_string_value(sym, lineEdit->text().toUtf8().data());	if (success) {		ConfigList::updateListForAll();	} else {		QMessageBox::information(editor, "qconf",			"Cannot set the data (maybe due to out of range).\n"			"Setting the old value.");		lineEdit->setText(sym_get_string_value(sym));	} parent:	QStyledItemDelegate::setModelData(editor, model, index);} ConfigList::ConfigList(QWidget *parent, const char *name)	: QTreeWidget(parent),	  updateAll(false),	  showName(false), mode(singleMode), optMode(normalOpt),	  rootEntry(0), headerPopup(0){	setObjectName(name);	setSortingEnabled(false); 	setVerticalScrollMode(ScrollPerPixel);	setHorizontalScrollMode(ScrollPerPixel); 	setHeaderLabels(QStringList() << "Option" << "Name" << "Value"); 	connect(this, &ConfigList::itemSelectionChanged,		this, &ConfigList::updateSelection); 	if (name) {		configSettings->beginGroup(name);		showName = configSettings->value("/showName", false).toBool();		optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();		configSettings->endGroup();		connect(configApp, &QApplication::aboutToQuit,			this, &ConfigList::saveSettings);	} 	showColumn(promptColIdx); 	setItemDelegate(new ConfigItemDelegate(this)); 	allLists.append(this); 	reinit();} ConfigList::~ConfigList(){	allLists.removeOne(this);} bool ConfigList::menuSkip(struct menu *menu){	if (optMode == normalOpt && menu_is_visible(menu))		return false;	if (optMode == promptOpt && menu_has_prompt(menu))		return false;	if (optMode == allOpt)		return false;	return true;} void ConfigList::reinit(void){	hideColumn(nameColIdx); 	if (showName)		showColumn(nameColIdx); 	updateListAll();} void ConfigList::setOptionMode(QAction *action){	if (action == showNormalAction)		optMode = normalOpt;	else if (action == showAllAction)		optMode = allOpt;	else		optMode = promptOpt; 	updateListAll();} void ConfigList::saveSettings(void){	if (!objectName().isEmpty()) {		configSettings->beginGroup(objectName());		configSettings->setValue("/showName", showName);		configSettings->setValue("/optionMode", (int)optMode);		configSettings->endGroup();	}} ConfigItem* ConfigList::findConfigItem(struct menu *menu){	ConfigItem* item = (ConfigItem*)menu->data; 	for (; item; item = item->nextItem) {		if (this == item->listView())			break;	} 	return item;} void ConfigList::updateSelection(void){	struct menu *menu;	enum prop_type type; 	if (selectedItems().count() == 0)		return; 	ConfigItem* item = (ConfigItem*)selectedItems().first();	if (!item)		return; 	menu = item->menu;	emit menuChanged(menu);	if (!menu)		return;	type = menu->prompt ? menu->prompt->type : P_UNKNOWN;	if (mode == menuMode && type == P_MENU)		emit menuSelected(menu);} void ConfigList::updateList(){	ConfigItem* last = 0;	ConfigItem *item; 	if (!rootEntry) {		if (mode != listMode)			goto update;		QTreeWidgetItemIterator it(this); 		while (*it) {			item = (ConfigItem*)(*it);			if (!item->menu)				continue;			item->testUpdateMenu(); 			++it;		}		return;	} 	if (rootEntry != &rootmenu && mode == singleMode) {		item = (ConfigItem *)topLevelItem(0);		if (!item)			item = new ConfigItem(this, 0);		last = item;	}	if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&	    rootEntry->sym && rootEntry->prompt) {		item = last ? last->nextSibling() : nullptr;		if (!item)			item = new ConfigItem(this, last, rootEntry);		else			item->testUpdateMenu(); 		updateMenuList(item, rootEntry);		update();		resizeColumnToContents(0);		return;	}update:	updateMenuList(rootEntry);	update();	resizeColumnToContents(0);} void ConfigList::updateListForAll(){	QListIterator<ConfigList *> it(allLists); 	while (it.hasNext()) {		ConfigList *list = it.next(); 		list->updateList();	}} void ConfigList::updateListAllForAll(){	QListIterator<ConfigList *> it(allLists); 	while (it.hasNext()) {		ConfigList *list = it.next(); 		list->updateListAll();	}} void ConfigList::setValue(ConfigItem* item, tristate val){	struct symbol* sym;	int type;

Lines 1–500 of 1862.