qconf.cc 22.8 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5
/*
 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
 * Released under the terms of the GNU GPL v2.0.
 */

A
Alexander Stein 已提交
6 7
#include <qglobal.h>

8
#include <QMainWindow>
9
#include <QList>
10
#include <qtextbrowser.h>
11
#include <QAction>
12
#include <QFileDialog>
13
#include <QMenu>
A
Alexander Stein 已提交
14 15

#include <qapplication.h>
16
#include <qdesktopwidget.h>
L
Linus Torvalds 已提交
17
#include <qtoolbar.h>
18
#include <qlayout.h>
L
Linus Torvalds 已提交
19 20
#include <qsplitter.h>
#include <qlineedit.h>
21 22
#include <qlabel.h>
#include <qpushbutton.h>
L
Linus Torvalds 已提交
23 24 25
#include <qmenubar.h>
#include <qmessagebox.h>
#include <qregexp.h>
A
Alexander Stein 已提交
26
#include <qevent.h>
L
Linus Torvalds 已提交
27 28 29 30 31 32 33 34 35

#include <stdlib.h>

#include "lkc.h"
#include "qconf.h"

#include "qconf.moc"
#include "images.c"

36 37 38 39 40
#ifdef _
# undef _
# define _ qgettext
#endif

L
Linus Torvalds 已提交
41
static QApplication *configApp;
42
static ConfigSettings *configSettings;
L
Linus Torvalds 已提交
43

44
QAction *ConfigMainWindow::saveAction;
45

46 47
static inline QString qgettext(const char* str)
{
48
	return QString::fromLocal8Bit(gettext(str));
49 50 51 52
}

static inline QString qgettext(const QString& str)
{
53
	return QString::fromLocal8Bit(gettext(str.toLatin1()));
54 55
}

56 57 58 59 60
ConfigSettings::ConfigSettings()
	: QSettings("kernel.org", "qconf")
{
}

L
Linus Torvalds 已提交
61 62 63
/**
 * Reads a list of integer values from the application settings.
 */
64
QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
L
Linus Torvalds 已提交
65
{
66
	QList<int> result;
67
	QStringList entryList = value(key).toStringList();
L
Li Zefan 已提交
68 69 70 71
	QStringList::Iterator it;

	for (it = entryList.begin(); it != entryList.end(); ++it)
		result.push_back((*it).toInt());
L
Linus Torvalds 已提交
72 73 74 75 76 77 78

	return result;
}

/**
 * Writes a list of integer values to the application settings.
 */
79
bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
L
Linus Torvalds 已提交
80 81
{
	QStringList stringList;
82
	QList<int>::ConstIterator it;
L
Linus Torvalds 已提交
83 84 85

	for (it = value.begin(); it != value.end(); ++it)
		stringList.push_back(QString::number(*it));
86 87
	setValue(key, stringList);
	return true;
L
Linus Torvalds 已提交
88 89
}

90 91 92 93 94 95 96 97 98 99 100 101 102 103
/*
 * construct a menu entry
 */
void ConfigItem::init(void)
{
}

/*
 * destruct a menu entry
 */
ConfigItem::~ConfigItem(void)
{
}

104 105 106
ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
	: Parent(parent)
{
107
	connect(this, SIGNAL(editingFinished()), SLOT(hide()));
108 109
}

110
void ConfigLineEdit::show(ConfigItem* i)
L
Linus Torvalds 已提交
111 112 113 114 115 116 117 118 119
{
	item = i;
	Parent::show();
	setFocus();
}

void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
{
	switch (e->key()) {
120
	case Qt::Key_Escape:
L
Linus Torvalds 已提交
121
		break;
122 123
	case Qt::Key_Return:
	case Qt::Key_Enter:
L
Linus Torvalds 已提交
124 125 126 127 128 129 130 131 132 133 134
		parent()->updateList(item);
		break;
	default:
		Parent::keyPressEvent(e);
		return;
	}
	e->accept();
	parent()->list->setFocus();
	hide();
}

135 136 137 138
ConfigList::ConfigList(ConfigView* p, const char *name)
	: Parent(p)
{
}
139 140 141 142
ConfigView*ConfigView::viewList;
QAction *ConfigView::showNormalAction;
QAction *ConfigView::showAllAction;
QAction *ConfigView::showPromptAction;
L
Linus Torvalds 已提交
143

144
ConfigView::ConfigView(QWidget* parent, const char *name)
145
	: Parent(parent)
L
Linus Torvalds 已提交
146
{
147
	QVBoxLayout *verticalLayout = new QVBoxLayout(this);
148
	verticalLayout->setContentsMargins(0, 0, 0, 0);
149

150
	list = new ConfigList(this);
151
	verticalLayout->addWidget(list);
L
Linus Torvalds 已提交
152 153
	lineEdit = new ConfigLineEdit(this);
	lineEdit->hide();
154
	verticalLayout->addWidget(lineEdit);
L
Linus Torvalds 已提交
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171

	this->nextView = viewList;
	viewList = this;
}

ConfigView::~ConfigView(void)
{
	ConfigView** vp;

	for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
		if (*vp == this) {
			*vp = nextView;
			break;
		}
	}
}

172
void ConfigView::setOptionMode(QAction *act)
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
{
}

void ConfigView::setShowName(bool b)
{
}

void ConfigView::setShowRange(bool b)
{
}

void ConfigView::setShowData(bool b)
{
}

188
void ConfigView::updateList(ConfigItem* item)
L
Linus Torvalds 已提交
189 190 191 192 193 194 195
{
}

void ConfigView::updateListAll(void)
{
}

196
ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
197
	: Parent(parent), sym(0), _menu(0)
198
{
199 200
	if (name) {
		configSettings->beginGroup(name);
201
		_showDebug = configSettings->value("/showDebug", false).toBool();
202 203 204 205 206 207 208
		configSettings->endGroup();
		connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
	}
}

void ConfigInfoView::saveSettings(void)
{
209
	/*if (name()) {
210
		configSettings->beginGroup(name());
211
		configSettings->setValue("/showDebug", showDebug());
212
		configSettings->endGroup();
213
	}*/
214 215 216 217 218 219
}

void ConfigInfoView::setShowDebug(bool b)
{
	if (_showDebug != b) {
		_showDebug = b;
A
Alexander Stein 已提交
220
		if (_menu)
221
			menuInfo();
222 223
		else if (sym)
			symbolInfo();
224 225 226 227 228 229
		emit showDebugChanged(b);
	}
}

void ConfigInfoView::setInfo(struct menu *m)
{
A
Alexander Stein 已提交
230
	if (_menu == m)
231
		return;
A
Alexander Stein 已提交
232
	_menu = m;
233
	sym = NULL;
A
Alexander Stein 已提交
234
	if (!_menu)
235
		clear();
236
	else
237 238 239
		menuInfo();
}

240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
void ConfigInfoView::symbolInfo(void)
{
	QString str;

	str += "<big>Symbol: <b>";
	str += print_filter(sym->name);
	str += "</b></big><br><br>value: ";
	str += print_filter(sym_get_string_value(sym));
	str += "<br>visibility: ";
	str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n";
	str += "<br>";
	str += debug_info(sym);

	setText(str);
}

256 257 258 259 260
void ConfigInfoView::menuInfo(void)
{
	struct symbol* sym;
	QString head, debug, help;

A
Alexander Stein 已提交
261
	sym = _menu->sym;
262
	if (sym) {
A
Alexander Stein 已提交
263
		if (_menu->prompt) {
264
			head += "<big><b>";
A
Alexander Stein 已提交
265
			head += print_filter(_(_menu->prompt->text));
266 267 268
			head += "</b></big>";
			if (sym->name) {
				head += " (";
269 270
				if (showDebug())
					head += QString().sprintf("<a href=\"s%p\">", sym);
271
				head += print_filter(sym->name);
272 273
				if (showDebug())
					head += "</a>";
274 275 276 277
				head += ")";
			}
		} else if (sym->name) {
			head += "<big><b>";
278 279
			if (showDebug())
				head += QString().sprintf("<a href=\"s%p\">", sym);
280
			head += print_filter(sym->name);
281 282
			if (showDebug())
				head += "</a>";
283 284 285 286 287 288 289
			head += "</b></big>";
		}
		head += "<br><br>";

		if (showDebug())
			debug = debug_info(sym);

290
		struct gstr help_gstr = str_new();
A
Alexander Stein 已提交
291
		menu_get_ext_help(_menu, &help_gstr);
292 293
		help = print_filter(str_get(&help_gstr));
		str_free(&help_gstr);
A
Alexander Stein 已提交
294
	} else if (_menu->prompt) {
295
		head += "<big><b>";
A
Alexander Stein 已提交
296
		head += print_filter(_(_menu->prompt->text));
297 298
		head += "</b></big><br><br>";
		if (showDebug()) {
A
Alexander Stein 已提交
299
			if (_menu->prompt->visible.expr) {
300
				debug += "&nbsp;&nbsp;dep: ";
A
Alexander Stein 已提交
301
				expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
302 303 304 305 306
				debug += "<br><br>";
			}
		}
	}
	if (showDebug())
A
Alexander Stein 已提交
307
		debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329

	setText(head + debug + help);
}

QString ConfigInfoView::debug_info(struct symbol *sym)
{
	QString debug;

	debug += "type: ";
	debug += print_filter(sym_type_name(sym->type));
	if (sym_is_choice(sym))
		debug += " (choice)";
	debug += "<br>";
	if (sym->rev_dep.expr) {
		debug += "reverse dep: ";
		expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
		debug += "<br>";
	}
	for (struct property *prop = sym->prop; prop; prop = prop->next) {
		switch (prop->type) {
		case P_PROMPT:
		case P_MENU:
330
			debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
331
			debug += print_filter(_(prop->text));
332
			debug += "</a><br>";
333 334
			break;
		case P_DEFAULT:
335 336 337 338 339
		case P_SELECT:
		case P_RANGE:
		case P_ENV:
			debug += prop_get_type_name(prop->type);
			debug += ": ";
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369
			expr_print(prop->expr, expr_print_help, &debug, E_NONE);
			debug += "<br>";
			break;
		case P_CHOICE:
			if (sym_is_choice(sym)) {
				debug += "choice: ";
				expr_print(prop->expr, expr_print_help, &debug, E_NONE);
				debug += "<br>";
			}
			break;
		default:
			debug += "unknown property: ";
			debug += prop_get_type_name(prop->type);
			debug += "<br>";
		}
		if (prop->visible.expr) {
			debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
			expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
			debug += "<br>";
		}
	}
	debug += "<br>";

	return debug;
}

QString ConfigInfoView::print_filter(const QString &str)
{
	QRegExp re("[<>&\"\\n]");
	QString res = str;
370 371
	for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
		switch (res[i].toLatin1()) {
372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396
		case '<':
			res.replace(i, 1, "&lt;");
			i += 4;
			break;
		case '>':
			res.replace(i, 1, "&gt;");
			i += 4;
			break;
		case '&':
			res.replace(i, 1, "&amp;");
			i += 5;
			break;
		case '"':
			res.replace(i, 1, "&quot;");
			i += 6;
			break;
		case '\n':
			res.replace(i, 1, "<br>");
			i += 4;
			break;
		}
	}
	return res;
}

397
void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
398
{
399 400 401 402 403 404 405 406 407
	QString* text = reinterpret_cast<QString*>(data);
	QString str2 = print_filter(str);

	if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
		*text += QString().sprintf("<a href=\"s%p\">", sym);
		*text += str2;
		*text += "</a>";
	} else
		*text += str2;
408 409
}

410
QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
411
{
412
	QMenu* popup = Parent::createStandardContextMenu(pos);
413
	QAction* action = new QAction(_("Show Debug Info"), popup);
414
	  action->setCheckable(true);
415 416
	  connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
	  connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
417
	  action->setChecked(showDebug());
418
	popup->addSeparator();
419
	popup->addAction(action);
420 421 422
	return popup;
}

423
void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
424
{
425
	Parent::contextMenuEvent(e);
426 427
}

428
ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
429
	: Parent(parent), result(NULL)
430
{
431
	setWindowTitle("Search Config");
432

433 434 435 436 437 438
	QVBoxLayout* layout1 = new QVBoxLayout(this);
	layout1->setContentsMargins(11, 11, 11, 11);
	layout1->setSpacing(6);
	QHBoxLayout* layout2 = new QHBoxLayout(0);
	layout2->setContentsMargins(0, 0, 0, 0);
	layout2->setSpacing(6);
439
	layout2->addWidget(new QLabel(_("Find:"), this));
440 441 442
	editField = new QLineEdit(this);
	connect(editField, SIGNAL(returnPressed()), SLOT(search()));
	layout2->addWidget(editField);
443
	searchButton = new QPushButton(_("Search"), this);
444
	searchButton->setAutoDefault(false);
445 446 447 448
	connect(searchButton, SIGNAL(clicked()), SLOT(search()));
	layout2->addWidget(searchButton);
	layout1->addLayout(layout2);

449
	split = new QSplitter(this);
450
	split->setOrientation(Qt::Vertical);
451 452
	list = new ConfigView(split, name);
	info = new ConfigInfoView(split, name);
453 454
	connect(list->list, SIGNAL(menuChanged(struct menu *)),
		info, SLOT(setInfo(struct menu *)));
455 456 457
	connect(list->list, SIGNAL(menuChanged(struct menu *)),
		parent, SLOT(setMenuLink(struct menu *)));

458
	layout1->addWidget(split);
459 460

	if (name) {
461 462
		QVariant x, y;
		int width, height;
463 464 465
		bool ok;

		configSettings->beginGroup(name);
466 467
		width = configSettings->value("/window width", parent->width() / 2).toInt();
		height = configSettings->value("/window height", parent->height() / 2).toInt();
468
		resize(width, height);
469 470 471 472
		x = configSettings->value("/window x");
		y = configSettings->value("/window y");
		if ((x.isValid())&&(y.isValid()))
			move(x.toInt(), y.toInt());
473
		QList<int> sizes = configSettings->readSizes("/split", &ok);
474 475 476 477 478 479 480 481 482
		if (ok)
			split->setSizes(sizes);
		configSettings->endGroup();
		connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
	}
}

void ConfigSearchWindow::saveSettings(void)
{
483
	/*if (name()) {
484
		configSettings->beginGroup(name());
485 486 487 488
		configSettings->setValue("/window x", pos().x());
		configSettings->setValue("/window y", pos().y());
		configSettings->setValue("/window width", size().width());
		configSettings->setValue("/window height", size().height());
489 490
		configSettings->writeSizes("/split", split->sizes());
		configSettings->endGroup();
491
	}*/
492 493 494 495 496 497
}

void ConfigSearchWindow::search(void)
{
}

L
Linus Torvalds 已提交
498 499 500 501
/*
 * Construct the complete config widget
 */
ConfigMainWindow::ConfigMainWindow(void)
502
	: searchWindow(0)
L
Linus Torvalds 已提交
503 504
{
	QMenuBar* menu;
505
	bool ok = true;
506 507
	QVariant x, y;
	int width, height;
R
Randy Dunlap 已提交
508
	char title[256];
L
Linus Torvalds 已提交
509

510
	QDesktopWidget *d = configApp->desktop();
511 512
	snprintf(title, sizeof(title), "%s%s",
		rootmenu.prompt->text,
513 514
		""
		);
515
	setWindowTitle(title);
L
Linus Torvalds 已提交
516

517 518
	width = configSettings->value("/window width", d->width() - 64).toInt();
	height = configSettings->value("/window height", d->height() - 64).toInt();
L
Linus Torvalds 已提交
519
	resize(width, height);
520 521 522 523
	x = configSettings->value("/window x");
	y = configSettings->value("/window y");
	if ((x.isValid())&&(y.isValid()))
		move(x.toInt(), y.toInt());
L
Linus Torvalds 已提交
524 525

	split1 = new QSplitter(this);
526
	split1->setOrientation(Qt::Horizontal);
L
Linus Torvalds 已提交
527 528
	setCentralWidget(split1);

529
	menuView = new ConfigView(split1, "menu");
L
Linus Torvalds 已提交
530 531 532
	menuList = menuView->list;

	split2 = new QSplitter(split1);
533
	split2->setOrientation(Qt::Vertical);
L
Linus Torvalds 已提交
534 535

	// create config tree
536
	configView = new ConfigView(split2, "config");
L
Linus Torvalds 已提交
537 538
	configList = configView->list;

539
	helpText = new ConfigInfoView(split2, "help");
540
	//helpText->setTextFormat(Qt::RichText);
L
Linus Torvalds 已提交
541 542 543 544 545

	setTabOrder(configList, helpText);
	configList->setFocus();

	menu = menuBar();
546
	toolBar = new QToolBar("Tools", this);
547
	addToolBar(toolBar);
L
Linus Torvalds 已提交
548

549
	backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
550
	  connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
551
	  backAction->setEnabled(false);
552 553
	QAction *quitAction = new QAction(_("&Quit"), this);
	quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
554
	  connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
555 556
	QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
	loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
557
	  connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
558 559
	saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
	saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
560
	  connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
561 562 563
	conf_set_changed_callback(conf_changed);
	// Set saveAction's initial state
	conf_changed();
564
	QAction *saveAsAction = new QAction(_("Save &As..."), this);
565
	  connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
566 567
	QAction *searchAction = new QAction(_("&Find"), this);
	searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
568
	  connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
569
	singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
570
	singleViewAction->setCheckable(true);
571
	  connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
572
	splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
573
	splitViewAction->setCheckable(true);
574
	  connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
575
	fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
576
	fullViewAction->setCheckable(true);
577
	  connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
L
Linus Torvalds 已提交
578

579
	QAction *showNameAction = new QAction(_("Show Name"), this);
580
	  showNameAction->setCheckable(true);
581
	  connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
582
	  showNameAction->setChecked(configView->showName());
583
	QAction *showRangeAction = new QAction(_("Show Range"), this);
584
	  showRangeAction->setCheckable(true);
585
	  connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
586
	QAction *showDataAction = new QAction(_("Show Data"), this);
587
	  showDataAction->setCheckable(true);
588
	  connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
589 590

	QActionGroup *optGroup = new QActionGroup(this);
591
	optGroup->setExclusive(true);
592
	connect(optGroup, SIGNAL(triggered(QAction*)), configView,
593
		SLOT(setOptionMode(QAction *)));
594
	connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
595 596
		SLOT(setOptionMode(QAction *)));

A
Alexander Stein 已提交
597 598 599
	configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
	configView->showAllAction = new QAction(_("Show All Options"), optGroup);
	configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
600 601 602
	configView->showNormalAction->setCheckable(true);
	configView->showAllAction->setCheckable(true);
	configView->showPromptAction->setCheckable(true);
603

604
	QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
605
	  showDebugAction->setCheckable(true);
606
	  connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
607
	  showDebugAction->setChecked(helpText->showDebug());
L
Linus Torvalds 已提交
608

609
	QAction *showIntroAction = new QAction( _("Introduction"), this);
610
	  connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
611
	QAction *showAboutAction = new QAction( _("About"), this);
612
	  connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
L
Linus Torvalds 已提交
613 614

	// init tool bar
615
	toolBar->addAction(backAction);
L
Linus Torvalds 已提交
616
	toolBar->addSeparator();
617 618
	toolBar->addAction(loadAction);
	toolBar->addAction(saveAction);
L
Linus Torvalds 已提交
619
	toolBar->addSeparator();
620 621 622
	toolBar->addAction(singleViewAction);
	toolBar->addAction(splitViewAction);
	toolBar->addAction(fullViewAction);
L
Linus Torvalds 已提交
623 624

	// create config menu
625 626 627 628
	QMenu* config = menu->addMenu(_("&File"));
	config->addAction(loadAction);
	config->addAction(saveAction);
	config->addAction(saveAsAction);
629
	config->addSeparator();
630
	config->addAction(quitAction);
L
Linus Torvalds 已提交
631

632
	// create edit menu
633 634
	QMenu* editMenu = menu->addMenu(_("&Edit"));
	editMenu->addAction(searchAction);
635

L
Linus Torvalds 已提交
636
	// create options menu
637 638 639 640
	QMenu* optionMenu = menu->addMenu(_("&Option"));
	optionMenu->addAction(showNameAction);
	optionMenu->addAction(showRangeAction);
	optionMenu->addAction(showDataAction);
641
	optionMenu->addSeparator();
642
	optionMenu->addActions(optGroup->actions());
643
	optionMenu->addSeparator();
L
Linus Torvalds 已提交
644 645

	// create help menu
646
	menu->addSeparator();
647 648 649
	QMenu* helpMenu = menu->addMenu(_("&Help"));
	helpMenu->addAction(showIntroAction);
	helpMenu->addAction(showAboutAction);
L
Linus Torvalds 已提交
650

651 652
	connect(helpText, SIGNAL(menuSelected(struct menu *)),
		SLOT(setMenuLink(struct menu *)));
L
Linus Torvalds 已提交
653

654
	QString listMode = configSettings->value("/listMode", "symbol").toString();
L
Linus Torvalds 已提交
655 656 657 658 659 660 661 662
	if (listMode == "single")
		showSingleView();
	else if (listMode == "full")
		showFullView();
	else /*if (listMode == "split")*/
		showSplitView();

	// UI setup done, restore splitter positions
663
	QList<int> sizes = configSettings->readSizes("/split1", &ok);
L
Linus Torvalds 已提交
664 665 666
	if (ok)
		split1->setSizes(sizes);

667
	sizes = configSettings->readSizes("/split2", &ok);
L
Linus Torvalds 已提交
668 669 670 671 672 673
	if (ok)
		split2->setSizes(sizes);
}

void ConfigMainWindow::loadConfig(void)
{
674
	QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
L
Linus Torvalds 已提交
675 676
	if (s.isNull())
		return;
677
	if (conf_read(QFile::encodeName(s)))
678
		QMessageBox::information(this, "qconf", _("Unable to load configuration!"));
L
Linus Torvalds 已提交
679 680 681
	ConfigView::updateListAll();
}

682
bool ConfigMainWindow::saveConfig(void)
L
Linus Torvalds 已提交
683
{
684
	if (conf_write(NULL)) {
685
		QMessageBox::information(this, "qconf", _("Unable to save configuration!"));
686 687 688
		return false;
	}
	return true;
L
Linus Torvalds 已提交
689 690 691 692
}

void ConfigMainWindow::saveConfigAs(void)
{
693
	QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
L
Linus Torvalds 已提交
694 695
	if (s.isNull())
		return;
696
	saveConfig();
L
Linus Torvalds 已提交
697 698
}

699 700 701
void ConfigMainWindow::searchConfig(void)
{
	if (!searchWindow)
702
		searchWindow = new ConfigSearchWindow(this, "search");
703 704 705
	searchWindow->show();
}

L
Linus Torvalds 已提交
706 707
void ConfigMainWindow::changeMenu(struct menu *menu)
{
708

L
Linus Torvalds 已提交
709 710
}

711
void ConfigMainWindow::setMenuLink(struct menu *menu)
L
Linus Torvalds 已提交
712 713 714
{
}

715 716 717 718
void ConfigMainWindow::listFocusChanged(void)
{
}

L
Linus Torvalds 已提交
719 720 721 722 723 724
void ConfigMainWindow::goBack(void)
{
}

void ConfigMainWindow::showSingleView(void)
{
725 726 727 728 729 730 731
	singleViewAction->setEnabled(false);
	singleViewAction->setChecked(true);
	splitViewAction->setEnabled(true);
	splitViewAction->setChecked(false);
	fullViewAction->setEnabled(true);
	fullViewAction->setChecked(false);

L
Linus Torvalds 已提交
732 733 734 735 736 737
	menuView->hide();
	configList->setFocus();
}

void ConfigMainWindow::showSplitView(void)
{
738 739 740 741 742 743 744
	singleViewAction->setEnabled(true);
	singleViewAction->setChecked(false);
	splitViewAction->setEnabled(false);
	splitViewAction->setChecked(true);
	fullViewAction->setEnabled(true);
	fullViewAction->setChecked(false);

L
Linus Torvalds 已提交
745 746 747 748 749 750
	menuView->show();
	menuList->setFocus();
}

void ConfigMainWindow::showFullView(void)
{
751 752 753 754 755 756 757
	singleViewAction->setEnabled(true);
	singleViewAction->setChecked(false);
	splitViewAction->setEnabled(true);
	splitViewAction->setChecked(false);
	fullViewAction->setEnabled(false);
	fullViewAction->setChecked(true);

L
Linus Torvalds 已提交
758 759 760 761 762 763 764 765 766 767
	menuView->hide();
	configList->setFocus();
}

/*
 * ask for saving configuration before quitting
 * TODO ask only when something changed
 */
void ConfigMainWindow::closeEvent(QCloseEvent* e)
{
768
	if (!conf_get_changed()) {
L
Linus Torvalds 已提交
769 770 771
		e->accept();
		return;
	}
772
	QMessageBox mb("qconf", _("Save configuration?"), QMessageBox::Warning,
L
Linus Torvalds 已提交
773
			QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
774 775 776
	mb.setButtonText(QMessageBox::Yes, _("&Save Changes"));
	mb.setButtonText(QMessageBox::No, _("&Discard Changes"));
	mb.setButtonText(QMessageBox::Cancel, _("Cancel Exit"));
L
Linus Torvalds 已提交
777 778
	switch (mb.exec()) {
	case QMessageBox::Yes:
779 780 781 782 783
		if (saveConfig())
			e->accept();
		else
			e->ignore();
		break;
L
Linus Torvalds 已提交
784 785 786 787 788 789 790 791 792 793 794
	case QMessageBox::No:
		e->accept();
		break;
	case QMessageBox::Cancel:
		e->ignore();
		break;
	}
}

void ConfigMainWindow::showIntro(void)
{
795
	static const QString str = _("Welcome to the qconf graphical configuration tool.\n\n"
L
Linus Torvalds 已提交
796 797 798 799 800 801 802 803 804
		"For each option, a blank box indicates the feature is disabled, a check\n"
		"indicates it is enabled, and a dot indicates that it is to be compiled\n"
		"as a module.  Clicking on the box will cycle through the three states.\n\n"
		"If you do not see an option (e.g., a device driver) that you believe\n"
		"should be present, try turning on Show All Options under the Options menu.\n"
		"Although there is no cross reference yet to help you figure out what other\n"
		"options must be enabled to support the option you are interested in, you can\n"
		"still view the help of a grayed-out option.\n\n"
		"Toggling Show Debug Info under the Options menu will show the dependencies,\n"
805
		"which you can then match by examining other options.\n\n");
L
Linus Torvalds 已提交
806 807 808 809 810 811

	QMessageBox::information(this, "qconf", str);
}

void ConfigMainWindow::showAbout(void)
{
812 813
	static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
		"Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n");
L
Linus Torvalds 已提交
814 815 816 817 818 819

	QMessageBox::information(this, "qconf", str);
}

void ConfigMainWindow::saveSettings(void)
{
820 821 822 823
	configSettings->setValue("/window x", pos().x());
	configSettings->setValue("/window y", pos().y());
	configSettings->setValue("/window width", size().width());
	configSettings->setValue("/window height", size().height());
L
Linus Torvalds 已提交
824 825

	QString entry;
826

827
	configSettings->setValue("/listMode", entry);
L
Linus Torvalds 已提交
828

829 830
	configSettings->writeSizes("/split1", split1->sizes());
	configSettings->writeSizes("/split2", split2->sizes());
L
Linus Torvalds 已提交
831 832
}

833 834 835 836 837 838
void ConfigMainWindow::conf_changed(void)
{
	if (saveAction)
		saveAction->setEnabled(conf_get_changed());
}

L
Linus Torvalds 已提交
839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858
void fixup_rootmenu(struct menu *menu)
{
	struct menu *child;
	static int menu_cnt = 0;

	menu->flags |= MENU_ROOT;
	for (child = menu->list; child; child = child->next) {
		if (child->prompt && child->prompt->type == P_MENU) {
			menu_cnt++;
			fixup_rootmenu(child);
			menu_cnt--;
		} else if (!menu_cnt)
			fixup_rootmenu(child);
	}
}

static const char *progname;

static void usage(void)
{
859
	printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
L
Linus Torvalds 已提交
860 861 862 863 864 865 866 867
	exit(0);
}

int main(int ac, char** av)
{
	ConfigMainWindow* v;
	const char *name;

868 869 870
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

L
Linus Torvalds 已提交
871 872 873 874
	progname = av[0];
	configApp = new QApplication(ac, av);
	if (ac > 1 && av[1][0] == '-') {
		switch (av[1][1]) {
875 876 877
		case 's':
			conf_set_message_callback(NULL);
			break;
L
Linus Torvalds 已提交
878 879 880 881 882 883 884 885 886 887 888 889 890 891 892
		case 'h':
		case '?':
			usage();
		}
		name = av[2];
	} else
		name = av[1];
	if (!name)
		usage();

	conf_parse(name);
	fixup_rootmenu(&rootmenu);
	conf_read(NULL);
	//zconfdump(stdout);

893 894
	configSettings = new ConfigSettings();
	configSettings->beginGroup("/kconfig/qconf");
L
Linus Torvalds 已提交
895 896 897 898 899
	v = new ConfigMainWindow();

	//zconfdump(stdout);
	configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
	configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
900
	v->show();
L
Linus Torvalds 已提交
901 902
	configApp->exec();

903 904 905
	configSettings->endGroup();
	delete configSettings;

L
Linus Torvalds 已提交
906 907
	return 0;
}