1 /*
2  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
3  * Released under the terms of the GNU GPL v2.0.
4  */
5 
6 #include <qapplication.h>
7 #include <qmainwindow.h>
8 #include <qtoolbar.h>
9 #include <qvbox.h>
10 #include <qsplitter.h>
11 #include <qlistview.h>
12 #include <qtextview.h>
13 #include <qlineedit.h>
14 #include <qmenubar.h>
15 #include <qmessagebox.h>
16 #include <qaction.h>
17 #include <qheader.h>
18 #include <qfiledialog.h>
19 #include <qregexp.h>
20 
21 #include <stdlib.h>
22 
23 #include "lkc.h"
24 #include "qconf.h"
25 
26 #include "qconf.moc"
27 #include "images.c"
28 
29 #ifdef _
30 # undef _
31 # define _ qgettext
32 #endif
33 
34 static QApplication *configApp;
35 
qgettext(const char * str)36 static inline QString qgettext(const char* str)
37 {
38   return QString::fromLocal8Bit(gettext(str));
39 }
40 
qgettext(const QString & str)41 static inline QString qgettext(const QString& str)
42 {
43   return QString::fromLocal8Bit(gettext(str.latin1()));
44 }
45 
ConfigSettings()46 ConfigSettings::ConfigSettings()
47 	: showAll(false), showName(false), showRange(false), showData(false)
48 {
49 }
50 
51 #if QT_VERSION >= 300
52 /**
53  * Reads the list column settings from the application settings.
54  */
readListSettings()55 void ConfigSettings::readListSettings()
56 {
57 	showAll = readBoolEntry("/kconfig/qconf/showAll", false);
58 	showName = readBoolEntry("/kconfig/qconf/showName", false);
59 	showRange = readBoolEntry("/kconfig/qconf/showRange", false);
60 	showData = readBoolEntry("/kconfig/qconf/showData", false);
61 }
62 
63 /**
64  * Reads a list of integer values from the application settings.
65  */
readSizes(const QString & key,bool * ok)66 QValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
67 {
68 	QValueList<int> result;
69 	QStringList entryList = readListEntry(key, ok);
70 	if (ok) {
71 		QStringList::Iterator it;
72 		for (it = entryList.begin(); it != entryList.end(); ++it)
73 			result.push_back((*it).toInt());
74 	}
75 
76 	return result;
77 }
78 
79 /**
80  * Writes a list of integer values to the application settings.
81  */
writeSizes(const QString & key,const QValueList<int> & value)82 bool ConfigSettings::writeSizes(const QString& key, const QValueList<int>& value)
83 {
84 	QStringList stringList;
85 	QValueList<int>::ConstIterator it;
86 
87 	for (it = value.begin(); it != value.end(); ++it)
88 		stringList.push_back(QString::number(*it));
89 	return writeEntry(key, stringList);
90 }
91 #endif
92 
93 
94 /*
95  * update all the children of a menu entry
96  *   removes/adds the entries from the parent widget as necessary
97  *
98  * parent: either the menu list widget or a menu entry widget
99  * menu: entry to be updated
100  */
101 template <class P>
updateMenuList(P * parent,struct menu * menu)102 void ConfigList::updateMenuList(P* parent, struct menu* menu)
103 {
104 	struct menu* child;
105 	ConfigItem* item;
106 	ConfigItem* last;
107 	bool visible;
108 	enum prop_type type;
109 
110 	if (!menu) {
111 		while ((item = parent->firstChild()))
112 			delete item;
113 		return;
114 	}
115 
116 	last = parent->firstChild();
117 	if (last && !last->goParent)
118 		last = 0;
119 	for (child = menu->list; child; child = child->next) {
120 		item = last ? last->nextSibling() : parent->firstChild();
121 		type = child->prompt ? child->prompt->type : P_UNKNOWN;
122 
123 		switch (mode) {
124 		case menuMode:
125 			if (!(child->flags & MENU_ROOT))
126 				goto hide;
127 			break;
128 		case symbolMode:
129 			if (child->flags & MENU_ROOT)
130 				goto hide;
131 			break;
132 		default:
133 			break;
134 		}
135 
136 		visible = menu_is_visible(child);
137 		if (showAll || visible) {
138 			if (!item || item->menu != child)
139 				item = new ConfigItem(parent, last, child, visible);
140 			else
141 				item->testUpdateMenu(visible);
142 
143 			if (mode == fullMode || mode == menuMode || type != P_MENU)
144 				updateMenuList(item, child);
145 			else
146 				updateMenuList(item, 0);
147 			last = item;
148 			continue;
149 		}
150 	hide:
151 		if (item && item->menu == child) {
152 			last = parent->firstChild();
153 			if (last == item)
154 				last = 0;
155 			else while (last->nextSibling() != item)
156 				last = last->nextSibling();
157 			delete item;
158 		}
159 	}
160 }
161 
162 #if QT_VERSION >= 300
163 /*
164  * set the new data
165  * TODO check the value
166  */
okRename(int col)167 void ConfigItem::okRename(int col)
168 {
169 	Parent::okRename(col);
170 	sym_set_string_value(menu->sym, text(dataColIdx).latin1());
171 }
172 #endif
173 
174 /*
175  * update the displayed of a menu entry
176  */
updateMenu(void)177 void ConfigItem::updateMenu(void)
178 {
179 	ConfigList* list;
180 	struct symbol* sym;
181 	struct property *prop;
182 	QString prompt;
183 	int type;
184 	tristate expr;
185 
186 	list = listView();
187 	if (goParent) {
188 		setPixmap(promptColIdx, list->menuBackPix);
189 		prompt = "..";
190 		goto set_prompt;
191 	}
192 
193 	sym = menu->sym;
194 	prop = menu->prompt;
195 	prompt = QString::fromLocal8Bit(menu_get_prompt(menu));
196 
197 	if (prop) switch (prop->type) {
198 	case P_MENU:
199 		if (list->mode == singleMode || list->mode == symbolMode) {
200 			/* a menuconfig entry is displayed differently
201 			 * depending whether it's at the view root or a child.
202 			 */
203 			if (sym && list->rootEntry == menu)
204 				break;
205 			setPixmap(promptColIdx, list->menuPix);
206 		} else {
207 			if (sym)
208 				break;
209 			setPixmap(promptColIdx, 0);
210 		}
211 		goto set_prompt;
212 	case P_COMMENT:
213 		setPixmap(promptColIdx, 0);
214 		goto set_prompt;
215 	default:
216 		;
217 	}
218 	if (!sym)
219 		goto set_prompt;
220 
221 	setText(nameColIdx, QString::fromLocal8Bit(sym->name));
222 
223 	type = sym_get_type(sym);
224 	switch (type) {
225 	case S_BOOLEAN:
226 	case S_TRISTATE:
227 		char ch;
228 
229 		if (!sym_is_changable(sym) && !list->showAll) {
230 			setPixmap(promptColIdx, 0);
231 			setText(noColIdx, QString::null);
232 			setText(modColIdx, QString::null);
233 			setText(yesColIdx, QString::null);
234 			break;
235 		}
236 		expr = sym_get_tristate_value(sym);
237 		switch (expr) {
238 		case yes:
239 			if (sym_is_choice_value(sym) && type == S_BOOLEAN)
240 				setPixmap(promptColIdx, list->choiceYesPix);
241 			else
242 				setPixmap(promptColIdx, list->symbolYesPix);
243 			setText(yesColIdx, "Y");
244 			ch = 'Y';
245 			break;
246 		case mod:
247 			setPixmap(promptColIdx, list->symbolModPix);
248 			setText(modColIdx, "M");
249 			ch = 'M';
250 			break;
251 		default:
252 			if (sym_is_choice_value(sym) && type == S_BOOLEAN)
253 				setPixmap(promptColIdx, list->choiceNoPix);
254 			else
255 				setPixmap(promptColIdx, list->symbolNoPix);
256 			setText(noColIdx, "N");
257 			ch = 'N';
258 			break;
259 		}
260 		if (expr != no)
261 			setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
262 		if (expr != mod)
263 			setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
264 		if (expr != yes)
265 			setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
266 
267 		setText(dataColIdx, QChar(ch));
268 		break;
269 	case S_INT:
270 	case S_HEX:
271 	case S_STRING:
272 		const char* data;
273 
274 		data = sym_get_string_value(sym);
275 
276 #if QT_VERSION >= 300
277 		int i = list->mapIdx(dataColIdx);
278 		if (i >= 0)
279 			setRenameEnabled(i, TRUE);
280 #endif
281 		setText(dataColIdx, data);
282 		if (type == S_STRING)
283 			prompt = QString("%1: %2").arg(prompt).arg(data);
284 		else
285 			prompt = QString("(%2) %1").arg(prompt).arg(data);
286 		break;
287 	}
288 	if (!sym_has_value(sym) && visible)
289 		prompt += " (NEW)";
290 set_prompt:
291 	setText(promptColIdx, prompt);
292 }
293 
testUpdateMenu(bool v)294 void ConfigItem::testUpdateMenu(bool v)
295 {
296 	ConfigItem* i;
297 
298 	visible = v;
299 	if (!menu)
300 		return;
301 
302 	sym_calc_value(menu->sym);
303 	if (menu->flags & MENU_CHANGED) {
304 		/* the menu entry changed, so update all list items */
305 		menu->flags &= ~MENU_CHANGED;
306 		for (i = (ConfigItem*)menu->data; i; i = i->nextItem)
307 			i->updateMenu();
308 	} else if (listView()->updateAll)
309 		updateMenu();
310 }
311 
paintCell(QPainter * p,const QColorGroup & cg,int column,int width,int align)312 void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
313 {
314 	ConfigList* list = listView();
315 
316 	if (visible) {
317 		if (isSelected() && !list->hasFocus() && list->mode == menuMode)
318 			Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
319 		else
320 			Parent::paintCell(p, cg, column, width, align);
321 	} else
322 		Parent::paintCell(p, list->disabledColorGroup, column, width, align);
323 }
324 
325 /*
326  * construct a menu entry
327  */
init(void)328 void ConfigItem::init(void)
329 {
330 	if (menu) {
331 		ConfigList* list = listView();
332 		nextItem = (ConfigItem*)menu->data;
333 		menu->data = this;
334 
335 		if (list->mode != fullMode)
336 			setOpen(TRUE);
337 		sym_calc_value(menu->sym);
338 	}
339 	updateMenu();
340 }
341 
342 /*
343  * destruct a menu entry
344  */
~ConfigItem(void)345 ConfigItem::~ConfigItem(void)
346 {
347 	if (menu) {
348 		ConfigItem** ip = (ConfigItem**)&menu->data;
349 		for (; *ip; ip = &(*ip)->nextItem) {
350 			if (*ip == this) {
351 				*ip = nextItem;
352 				break;
353 			}
354 		}
355 	}
356 }
357 
show(ConfigItem * i)358 void ConfigLineEdit::show(ConfigItem* i)
359 {
360 	item = i;
361 	if (sym_get_string_value(item->menu->sym))
362 		setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
363 	else
364 		setText(QString::null);
365 	Parent::show();
366 	setFocus();
367 }
368 
keyPressEvent(QKeyEvent * e)369 void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
370 {
371 	switch (e->key()) {
372 	case Key_Escape:
373 		break;
374 	case Key_Return:
375 	case Key_Enter:
376 		sym_set_string_value(item->menu->sym, text().latin1());
377 		parent()->updateList(item);
378 		break;
379 	default:
380 		Parent::keyPressEvent(e);
381 		return;
382 	}
383 	e->accept();
384 	parent()->list->setFocus();
385 	hide();
386 }
387 
ConfigList(ConfigView * p,ConfigMainWindow * cv,ConfigSettings * configSettings)388 ConfigList::ConfigList(ConfigView* p, ConfigMainWindow* cv, ConfigSettings* configSettings)
389 	: Parent(p), cview(cv),
390 	  updateAll(false),
391 	  symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
392 	  choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
393 	  menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
394 	  showAll(false), showName(false), showRange(false), showData(false),
395 	  rootEntry(0)
396 {
397 	int i;
398 
399 	setSorting(-1);
400 	setRootIsDecorated(TRUE);
401 	disabledColorGroup = palette().active();
402 	disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
403 	inactivedColorGroup = palette().active();
404 	inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
405 
406 	connect(this, SIGNAL(selectionChanged(void)),
407 		SLOT(updateSelection(void)));
408 
409 	if (configSettings) {
410 		showAll = configSettings->showAll;
411 		showName = configSettings->showName;
412 		showRange = configSettings->showRange;
413 		showData = configSettings->showData;
414 	}
415 
416 	for (i = 0; i < colNr; i++)
417 		colMap[i] = colRevMap[i] = -1;
418 	addColumn(promptColIdx, "Option");
419 
420 	reinit();
421 }
422 
reinit(void)423 void ConfigList::reinit(void)
424 {
425 	removeColumn(dataColIdx);
426 	removeColumn(yesColIdx);
427 	removeColumn(modColIdx);
428 	removeColumn(noColIdx);
429 	removeColumn(nameColIdx);
430 
431 	if (showName)
432 		addColumn(nameColIdx, "Name");
433 	if (showRange) {
434 		addColumn(noColIdx, "N");
435 		addColumn(modColIdx, "M");
436 		addColumn(yesColIdx, "Y");
437 	}
438 	if (showData)
439 		addColumn(dataColIdx, "Value");
440 
441 	updateListAll();
442 }
443 
updateSelection(void)444 void ConfigList::updateSelection(void)
445 {
446 	struct menu *menu;
447 	enum prop_type type;
448 
449 	ConfigItem* item = (ConfigItem*)selectedItem();
450 	if (!item)
451 		return;
452 
453 	cview->setHelp(item);
454 
455 	menu = item->menu;
456 	if (!menu)
457 		return;
458 	type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
459 	if (mode == menuMode && type == P_MENU)
460 		emit menuSelected(menu);
461 }
462 
updateList(ConfigItem * item)463 void ConfigList::updateList(ConfigItem* item)
464 {
465 	ConfigItem* last = 0;
466 
467 	if (!rootEntry)
468 		goto update;
469 
470 	if (rootEntry != &rootmenu && (mode == singleMode ||
471 	    (mode == symbolMode && rootEntry->parent != &rootmenu))) {
472 		item = firstChild();
473 		if (!item)
474 			item = new ConfigItem(this, 0, true);
475 		last = item;
476 	}
477 	if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
478 	    rootEntry->sym && rootEntry->prompt) {
479 		item = last ? last->nextSibling() : firstChild();
480 		if (!item)
481 			item = new ConfigItem(this, last, rootEntry, true);
482 		else
483 			item->testUpdateMenu(true);
484 
485 		updateMenuList(item, rootEntry);
486 		triggerUpdate();
487 		return;
488 	}
489 update:
490 	updateMenuList(this, rootEntry);
491 	triggerUpdate();
492 }
493 
setAllOpen(bool open)494 void ConfigList::setAllOpen(bool open)
495 {
496 	QListViewItemIterator it(this);
497 
498 	for (; it.current(); it++)
499 		it.current()->setOpen(open);
500 }
501 
setValue(ConfigItem * item,tristate val)502 void ConfigList::setValue(ConfigItem* item, tristate val)
503 {
504 	struct symbol* sym;
505 	int type;
506 	tristate oldval;
507 
508 	sym = item->menu ? item->menu->sym : 0;
509 	if (!sym)
510 		return;
511 
512 	type = sym_get_type(sym);
513 	switch (type) {
514 	case S_BOOLEAN:
515 	case S_TRISTATE:
516 		oldval = sym_get_tristate_value(sym);
517 
518 		if (!sym_set_tristate_value(sym, val))
519 			return;
520 		if (oldval == no && item->menu->list)
521 			item->setOpen(TRUE);
522 		parent()->updateList(item);
523 		break;
524 	}
525 }
526 
changeValue(ConfigItem * item)527 void ConfigList::changeValue(ConfigItem* item)
528 {
529 	struct symbol* sym;
530 	struct menu* menu;
531 	int type, oldexpr, newexpr;
532 
533 	menu = item->menu;
534 	if (!menu)
535 		return;
536 	sym = menu->sym;
537 	if (!sym) {
538 		if (item->menu->list)
539 			item->setOpen(!item->isOpen());
540 		return;
541 	}
542 
543 	type = sym_get_type(sym);
544 	switch (type) {
545 	case S_BOOLEAN:
546 	case S_TRISTATE:
547 		oldexpr = sym_get_tristate_value(sym);
548 		newexpr = sym_toggle_tristate_value(sym);
549 		if (item->menu->list) {
550 			if (oldexpr == newexpr)
551 				item->setOpen(!item->isOpen());
552 			else if (oldexpr == no)
553 				item->setOpen(TRUE);
554 		}
555 		if (oldexpr != newexpr)
556 			parent()->updateList(item);
557 		break;
558 	case S_INT:
559 	case S_HEX:
560 	case S_STRING:
561 #if QT_VERSION >= 300
562 		if (colMap[dataColIdx] >= 0)
563 			item->startRename(colMap[dataColIdx]);
564 		else
565 #endif
566 			parent()->lineEdit->show(item);
567 		break;
568 	}
569 }
570 
setRootMenu(struct menu * menu)571 void ConfigList::setRootMenu(struct menu *menu)
572 {
573 	enum prop_type type;
574 
575 	if (rootEntry == menu)
576 		return;
577 	type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
578 	if (type != P_MENU)
579 		return;
580 	updateMenuList(this, 0);
581 	rootEntry = menu;
582 	updateListAll();
583 	setSelected(currentItem(), hasFocus());
584 }
585 
setParentMenu(void)586 void ConfigList::setParentMenu(void)
587 {
588 	ConfigItem* item;
589 	struct menu *oldroot;
590 
591 	oldroot = rootEntry;
592 	if (rootEntry == &rootmenu)
593 		return;
594 	setRootMenu(menu_get_parent_menu(rootEntry->parent));
595 
596 	QListViewItemIterator it(this);
597 	for (; (item = (ConfigItem*)it.current()); it++) {
598 		if (item->menu == oldroot) {
599 			setCurrentItem(item);
600 			ensureItemVisible(item);
601 			break;
602 		}
603 	}
604 }
605 
keyPressEvent(QKeyEvent * ev)606 void ConfigList::keyPressEvent(QKeyEvent* ev)
607 {
608 	QListViewItem* i = currentItem();
609 	ConfigItem* item;
610 	struct menu *menu;
611 	enum prop_type type;
612 
613 	if (ev->key() == Key_Escape && mode != fullMode) {
614 		emit parentSelected();
615 		ev->accept();
616 		return;
617 	}
618 
619 	if (!i) {
620 		Parent::keyPressEvent(ev);
621 		return;
622 	}
623 	item = (ConfigItem*)i;
624 
625 	switch (ev->key()) {
626 	case Key_Return:
627 	case Key_Enter:
628 		if (item->goParent) {
629 			emit parentSelected();
630 			break;
631 		}
632 		menu = item->menu;
633 		if (!menu)
634 			break;
635 		type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
636 		if (type == P_MENU && rootEntry != menu &&
637 		    mode != fullMode && mode != menuMode) {
638 			emit menuSelected(menu);
639 			break;
640 		}
641 	case Key_Space:
642 		changeValue(item);
643 		break;
644 	case Key_N:
645 		setValue(item, no);
646 		break;
647 	case Key_M:
648 		setValue(item, mod);
649 		break;
650 	case Key_Y:
651 		setValue(item, yes);
652 		break;
653 	default:
654 		Parent::keyPressEvent(ev);
655 		return;
656 	}
657 	ev->accept();
658 }
659 
contentsMousePressEvent(QMouseEvent * e)660 void ConfigList::contentsMousePressEvent(QMouseEvent* e)
661 {
662 	//QPoint p(contentsToViewport(e->pos()));
663 	//printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
664 	Parent::contentsMousePressEvent(e);
665 }
666 
contentsMouseReleaseEvent(QMouseEvent * e)667 void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
668 {
669 	QPoint p(contentsToViewport(e->pos()));
670 	ConfigItem* item = (ConfigItem*)itemAt(p);
671 	struct menu *menu;
672 	enum prop_type ptype;
673 	const QPixmap* pm;
674 	int idx, x;
675 
676 	if (!item)
677 		goto skip;
678 
679 	menu = item->menu;
680 	x = header()->offset() + p.x();
681 	idx = colRevMap[header()->sectionAt(x)];
682 	switch (idx) {
683 	case promptColIdx:
684 		pm = item->pixmap(promptColIdx);
685 		if (pm) {
686 			int off = header()->sectionPos(0) + itemMargin() +
687 				treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
688 			if (x >= off && x < off + pm->width()) {
689 				if (item->goParent) {
690 					emit parentSelected();
691 					break;
692 				} else if (!menu)
693 					break;
694 				ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
695 				if (ptype == P_MENU && rootEntry != menu &&
696 				    mode != fullMode && mode != menuMode)
697 					emit menuSelected(menu);
698 				else
699 					changeValue(item);
700 			}
701 		}
702 		break;
703 	case noColIdx:
704 		setValue(item, no);
705 		break;
706 	case modColIdx:
707 		setValue(item, mod);
708 		break;
709 	case yesColIdx:
710 		setValue(item, yes);
711 		break;
712 	case dataColIdx:
713 		changeValue(item);
714 		break;
715 	}
716 
717 skip:
718 	//printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
719 	Parent::contentsMouseReleaseEvent(e);
720 }
721 
contentsMouseMoveEvent(QMouseEvent * e)722 void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
723 {
724 	//QPoint p(contentsToViewport(e->pos()));
725 	//printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
726 	Parent::contentsMouseMoveEvent(e);
727 }
728 
contentsMouseDoubleClickEvent(QMouseEvent * e)729 void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
730 {
731 	QPoint p(contentsToViewport(e->pos()));
732 	ConfigItem* item = (ConfigItem*)itemAt(p);
733 	struct menu *menu;
734 	enum prop_type ptype;
735 
736 	if (!item)
737 		goto skip;
738 	if (item->goParent) {
739 		emit parentSelected();
740 		goto skip;
741 	}
742 	menu = item->menu;
743 	if (!menu)
744 		goto skip;
745 	ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
746 	if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
747 		emit menuSelected(menu);
748 	else if (menu->sym)
749 		changeValue(item);
750 
751 skip:
752 	//printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
753 	Parent::contentsMouseDoubleClickEvent(e);
754 }
755 
focusInEvent(QFocusEvent * e)756 void ConfigList::focusInEvent(QFocusEvent *e)
757 {
758 	Parent::focusInEvent(e);
759 
760 	QListViewItem* item = currentItem();
761 	if (!item)
762 		return;
763 
764 	setSelected(item, TRUE);
765 	emit gotFocus();
766 }
767 
768 ConfigView* ConfigView::viewList;
769 
ConfigView(QWidget * parent,ConfigMainWindow * cview,ConfigSettings * configSettings)770 ConfigView::ConfigView(QWidget* parent, ConfigMainWindow* cview,
771 		       ConfigSettings *configSettings)
772 	: Parent(parent)
773 {
774 	list = new ConfigList(this, cview, configSettings);
775 	lineEdit = new ConfigLineEdit(this);
776 	lineEdit->hide();
777 
778 	this->nextView = viewList;
779 	viewList = this;
780 }
781 
~ConfigView(void)782 ConfigView::~ConfigView(void)
783 {
784 	ConfigView** vp;
785 
786 	for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
787 		if (*vp == this) {
788 			*vp = nextView;
789 			break;
790 		}
791 	}
792 }
793 
updateList(ConfigItem * item)794 void ConfigView::updateList(ConfigItem* item)
795 {
796 	ConfigView* v;
797 
798 	for (v = viewList; v; v = v->nextView)
799 		v->list->updateList(item);
800 }
801 
updateListAll(void)802 void ConfigView::updateListAll(void)
803 {
804 	ConfigView* v;
805 
806 	for (v = viewList; v; v = v->nextView)
807 		v->list->updateListAll();
808 }
809 
810 /*
811  * Construct the complete config widget
812  */
ConfigMainWindow(void)813 ConfigMainWindow::ConfigMainWindow(void)
814 {
815 	QMenuBar* menu;
816 	bool ok;
817 	int x, y, width, height;
818 
819 	QWidget *d = configApp->desktop();
820 
821 	ConfigSettings* configSettings = new ConfigSettings();
822 #if QT_VERSION >= 300
823 	width = configSettings->readNumEntry("/kconfig/qconf/window width", d->width() - 64);
824 	height = configSettings->readNumEntry("/kconfig/qconf/window height", d->height() - 64);
825 	resize(width, height);
826 	x = configSettings->readNumEntry("/kconfig/qconf/window x", 0, &ok);
827 	if (ok)
828 		y = configSettings->readNumEntry("/kconfig/qconf/window y", 0, &ok);
829 	if (ok)
830 		move(x, y);
831 	showDebug = configSettings->readBoolEntry("/kconfig/qconf/showDebug", false);
832 
833 	// read list settings into configSettings, will be used later for ConfigList setup
834 	configSettings->readListSettings();
835 #else
836 	width = d->width() - 64;
837 	height = d->height() - 64;
838 	resize(width, height);
839 	showDebug = false;
840 #endif
841 
842 	split1 = new QSplitter(this);
843 	split1->setOrientation(QSplitter::Horizontal);
844 	setCentralWidget(split1);
845 
846 	menuView = new ConfigView(split1, this, configSettings);
847 	menuList = menuView->list;
848 
849 	split2 = new QSplitter(split1);
850 	split2->setOrientation(QSplitter::Vertical);
851 
852 	// create config tree
853 	configView = new ConfigView(split2, this, configSettings);
854 	configList = configView->list;
855 
856 	helpText = new QTextView(split2);
857 	helpText->setTextFormat(Qt::RichText);
858 
859 	setTabOrder(configList, helpText);
860 	configList->setFocus();
861 
862 	menu = menuBar();
863 	toolBar = new QToolBar("Tools", this);
864 
865 	backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this);
866 	  connect(backAction, SIGNAL(activated()), SLOT(goBack()));
867 	  backAction->setEnabled(FALSE);
868 	QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this);
869 	  connect(quitAction, SIGNAL(activated()), SLOT(close()));
870 	QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this);
871 	  connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
872 	QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this);
873 	  connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
874 	QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this);
875 	  connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
876 	QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this);
877 	  connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
878 	QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this);
879 	  connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
880 	QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this);
881 	  connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
882 
883 	QAction *showNameAction = new QAction(NULL, "Show Name", 0, this);
884 	  showNameAction->setToggleAction(TRUE);
885 	  showNameAction->setOn(configList->showName);
886 	  connect(showNameAction, SIGNAL(toggled(bool)), SLOT(setShowName(bool)));
887 	QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this);
888 	  showRangeAction->setToggleAction(TRUE);
889 	  showRangeAction->setOn(configList->showRange);
890 	  connect(showRangeAction, SIGNAL(toggled(bool)), SLOT(setShowRange(bool)));
891 	QAction *showDataAction = new QAction(NULL, "Show Data", 0, this);
892 	  showDataAction->setToggleAction(TRUE);
893 	  showDataAction->setOn(configList->showData);
894 	  connect(showDataAction, SIGNAL(toggled(bool)), SLOT(setShowData(bool)));
895 	QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this);
896 	  showAllAction->setToggleAction(TRUE);
897 	  showAllAction->setOn(configList->showAll);
898 	  connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool)));
899 	QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this);
900 	  showDebugAction->setToggleAction(TRUE);
901 	  showDebugAction->setOn(showDebug);
902 	  connect(showDebugAction, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
903 
904 	QAction *showIntroAction = new QAction(NULL, "Introduction", 0, this);
905 	  connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
906 	QAction *showAboutAction = new QAction(NULL, "About", 0, this);
907 	  connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
908 
909 	// init tool bar
910 	backAction->addTo(toolBar);
911 	toolBar->addSeparator();
912 	loadAction->addTo(toolBar);
913 	saveAction->addTo(toolBar);
914 	toolBar->addSeparator();
915 	singleViewAction->addTo(toolBar);
916 	splitViewAction->addTo(toolBar);
917 	fullViewAction->addTo(toolBar);
918 
919 	// create config menu
920 	QPopupMenu* config = new QPopupMenu(this);
921 	menu->insertItem("&File", config);
922 	loadAction->addTo(config);
923 	saveAction->addTo(config);
924 	saveAsAction->addTo(config);
925 	config->insertSeparator();
926 	quitAction->addTo(config);
927 
928 	// create options menu
929 	QPopupMenu* optionMenu = new QPopupMenu(this);
930 	menu->insertItem("&Option", optionMenu);
931 	showNameAction->addTo(optionMenu);
932 	showRangeAction->addTo(optionMenu);
933 	showDataAction->addTo(optionMenu);
934 	optionMenu->insertSeparator();
935 	showAllAction->addTo(optionMenu);
936 	showDebugAction->addTo(optionMenu);
937 
938 	// create help menu
939 	QPopupMenu* helpMenu = new QPopupMenu(this);
940 	menu->insertSeparator();
941 	menu->insertItem("&Help", helpMenu);
942 	showIntroAction->addTo(helpMenu);
943 	showAboutAction->addTo(helpMenu);
944 
945 	connect(configList, SIGNAL(menuSelected(struct menu *)),
946 		SLOT(changeMenu(struct menu *)));
947 	connect(configList, SIGNAL(parentSelected()),
948 		SLOT(goBack()));
949 	connect(menuList, SIGNAL(menuSelected(struct menu *)),
950 		SLOT(changeMenu(struct menu *)));
951 
952 	connect(configList, SIGNAL(gotFocus(void)),
953 		SLOT(listFocusChanged(void)));
954 	connect(menuList, SIGNAL(gotFocus(void)),
955 		SLOT(listFocusChanged(void)));
956 
957 #if QT_VERSION >= 300
958 	QString listMode = configSettings->readEntry("/kconfig/qconf/listMode", "symbol");
959 	if (listMode == "single")
960 		showSingleView();
961 	else if (listMode == "full")
962 		showFullView();
963 	else /*if (listMode == "split")*/
964 		showSplitView();
965 
966 	// UI setup done, restore splitter positions
967 	QValueList<int> sizes = configSettings->readSizes("/kconfig/qconf/split1", &ok);
968 	if (ok)
969 		split1->setSizes(sizes);
970 
971 	sizes = configSettings->readSizes("/kconfig/qconf/split2", &ok);
972 	if (ok)
973 		split2->setSizes(sizes);
974 #else
975 	showSplitView();
976 #endif
977 	delete configSettings;
978 }
979 
print_filter(const QString & str)980 static QString print_filter(const QString &str)
981 {
982 	QRegExp re("[<>&\"\\n]");
983 	QString res = str;
984 	for (int i = 0; (i = res.find(re, i)) >= 0;) {
985 		switch (res[i].latin1()) {
986 		case '<':
987 			res.replace(i, 1, "&lt;");
988 			i += 4;
989 			break;
990 		case '>':
991 			res.replace(i, 1, "&gt;");
992 			i += 4;
993 			break;
994 		case '&':
995 			res.replace(i, 1, "&amp;");
996 			i += 5;
997 			break;
998 		case '"':
999 			res.replace(i, 1, "&quot;");
1000 			i += 6;
1001 			break;
1002 		case '\n':
1003 			res.replace(i, 1, "<br>");
1004 			i += 4;
1005 			break;
1006 		}
1007 	}
1008 	return res;
1009 }
1010 
expr_print_help(void * data,const char * str)1011 static void expr_print_help(void *data, const char *str)
1012 {
1013 	reinterpret_cast<QString*>(data)->append(print_filter(str));
1014 }
1015 
1016 /*
1017  * display a new help entry as soon as a new menu entry is selected
1018  */
setHelp(QListViewItem * item)1019 void ConfigMainWindow::setHelp(QListViewItem* item)
1020 {
1021 	struct symbol* sym;
1022 	struct menu* menu = 0;
1023 
1024 	configList->parent()->lineEdit->hide();
1025 	if (item)
1026 		menu = ((ConfigItem*)item)->menu;
1027 	if (!menu) {
1028 		helpText->setText(QString::null);
1029 		return;
1030 	}
1031 
1032 	QString head, debug, help;
1033 	menu = ((ConfigItem*)item)->menu;
1034 	sym = menu->sym;
1035 	if (sym) {
1036 		if (menu->prompt) {
1037 			head += "<big><b>";
1038 			head += print_filter(_(menu->prompt->text));
1039 			head += "</b></big>";
1040 			if (sym->name) {
1041 				head += " (";
1042 				head += print_filter(_(sym->name));
1043 				head += ")";
1044 			}
1045 		} else if (sym->name) {
1046 			head += "<big><b>";
1047 			head += print_filter(_(sym->name));
1048 			head += "</b></big>";
1049 		}
1050 		head += "<br><br>";
1051 
1052 		if (showDebug) {
1053 			debug += "type: ";
1054 			debug += print_filter(sym_type_name(sym->type));
1055 			if (sym_is_choice(sym))
1056 				debug += " (choice)";
1057 			debug += "<br>";
1058 			if (sym->rev_dep.expr) {
1059 				debug += "reverse dep: ";
1060 				expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
1061 				debug += "<br>";
1062 			}
1063 			for (struct property *prop = sym->prop; prop; prop = prop->next) {
1064 				switch (prop->type) {
1065 				case P_PROMPT:
1066 				case P_MENU:
1067 					debug += "prompt: ";
1068 					debug += print_filter(_(prop->text));
1069 					debug += "<br>";
1070 					break;
1071 				case P_DEFAULT:
1072 					debug += "default: ";
1073 					expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1074 					debug += "<br>";
1075 					break;
1076 				case P_CHOICE:
1077 					if (sym_is_choice(sym)) {
1078 						debug += "choice: ";
1079 						expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1080 						debug += "<br>";
1081 					}
1082 					break;
1083 				case P_SELECT:
1084 					debug += "select: ";
1085 					expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1086 					debug += "<br>";
1087 					break;
1088 				case P_RANGE:
1089 					debug += "range: ";
1090 					expr_print(prop->expr, expr_print_help, &debug, E_NONE);
1091 					debug += "<br>";
1092 					break;
1093 				default:
1094 					debug += "unknown property: ";
1095 					debug += prop_get_type_name(prop->type);
1096 					debug += "<br>";
1097 				}
1098 				if (prop->visible.expr) {
1099 					debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
1100 					expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
1101 					debug += "<br>";
1102 				}
1103 			}
1104 			debug += "<br>";
1105 		}
1106 
1107 		help = print_filter(_(sym->help));
1108 	} else if (menu->prompt) {
1109 		head += "<big><b>";
1110 		head += print_filter(_(menu->prompt->text));
1111 		head += "</b></big><br><br>";
1112 		if (showDebug) {
1113 			if (menu->prompt->visible.expr) {
1114 				debug += "&nbsp;&nbsp;dep: ";
1115 				expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
1116 				debug += "<br><br>";
1117 			}
1118 		}
1119 	}
1120 	if (showDebug)
1121 		debug += QString().sprintf("defined at %s:%d<br><br>", menu->file->name, menu->lineno);
1122 	helpText->setText(head + debug + help);
1123 }
1124 
loadConfig(void)1125 void ConfigMainWindow::loadConfig(void)
1126 {
1127 	QString s = QFileDialog::getOpenFileName(".config", NULL, this);
1128 	if (s.isNull())
1129 		return;
1130 	if (conf_read(QFile::encodeName(s)))
1131 		QMessageBox::information(this, "qconf", "Unable to load configuration!");
1132 	ConfigView::updateListAll();
1133 }
1134 
saveConfig(void)1135 void ConfigMainWindow::saveConfig(void)
1136 {
1137 	if (conf_write(NULL))
1138 		QMessageBox::information(this, "qconf", "Unable to save configuration!");
1139 }
1140 
saveConfigAs(void)1141 void ConfigMainWindow::saveConfigAs(void)
1142 {
1143 	QString s = QFileDialog::getSaveFileName(".config", NULL, this);
1144 	if (s.isNull())
1145 		return;
1146 	if (conf_write(QFile::encodeName(s)))
1147 		QMessageBox::information(this, "qconf", "Unable to save configuration!");
1148 }
1149 
changeMenu(struct menu * menu)1150 void ConfigMainWindow::changeMenu(struct menu *menu)
1151 {
1152 	configList->setRootMenu(menu);
1153 	backAction->setEnabled(TRUE);
1154 }
1155 
listFocusChanged(void)1156 void ConfigMainWindow::listFocusChanged(void)
1157 {
1158 	if (menuList->hasFocus()) {
1159 		if (menuList->mode == menuMode)
1160 			configList->clearSelection();
1161 		setHelp(menuList->selectedItem());
1162 	} else if (configList->hasFocus()) {
1163 		setHelp(configList->selectedItem());
1164 	}
1165 }
1166 
goBack(void)1167 void ConfigMainWindow::goBack(void)
1168 {
1169 	ConfigItem* item;
1170 
1171 	configList->setParentMenu();
1172 	if (configList->rootEntry == &rootmenu)
1173 		backAction->setEnabled(FALSE);
1174 	item = (ConfigItem*)menuList->selectedItem();
1175 	while (item) {
1176 		if (item->menu == configList->rootEntry) {
1177 			menuList->setSelected(item, TRUE);
1178 			break;
1179 		}
1180 		item = (ConfigItem*)item->parent();
1181 	}
1182 }
1183 
showSingleView(void)1184 void ConfigMainWindow::showSingleView(void)
1185 {
1186 	menuView->hide();
1187 	menuList->setRootMenu(0);
1188 	configList->mode = singleMode;
1189 	if (configList->rootEntry == &rootmenu)
1190 		configList->updateListAll();
1191 	else
1192 		configList->setRootMenu(&rootmenu);
1193 	configList->setAllOpen(TRUE);
1194 	configList->setFocus();
1195 }
1196 
showSplitView(void)1197 void ConfigMainWindow::showSplitView(void)
1198 {
1199 	configList->mode = symbolMode;
1200 	if (configList->rootEntry == &rootmenu)
1201 		configList->updateListAll();
1202 	else
1203 		configList->setRootMenu(&rootmenu);
1204 	configList->setAllOpen(TRUE);
1205 	configApp->processEvents();
1206 	menuList->mode = menuMode;
1207 	menuList->setRootMenu(&rootmenu);
1208 	menuList->setAllOpen(TRUE);
1209 	menuView->show();
1210 	menuList->setFocus();
1211 }
1212 
showFullView(void)1213 void ConfigMainWindow::showFullView(void)
1214 {
1215 	menuView->hide();
1216 	menuList->setRootMenu(0);
1217 	configList->mode = fullMode;
1218 	if (configList->rootEntry == &rootmenu)
1219 		configList->updateListAll();
1220 	else
1221 		configList->setRootMenu(&rootmenu);
1222 	configList->setAllOpen(FALSE);
1223 	configList->setFocus();
1224 }
1225 
setShowAll(bool b)1226 void ConfigMainWindow::setShowAll(bool b)
1227 {
1228 	if (configList->showAll == b)
1229 		return;
1230 	configList->showAll = b;
1231 	configList->updateListAll();
1232 	menuList->showAll = b;
1233 	menuList->updateListAll();
1234 }
1235 
setShowDebug(bool b)1236 void ConfigMainWindow::setShowDebug(bool b)
1237 {
1238 	if (showDebug == b)
1239 		return;
1240 	showDebug = b;
1241 }
1242 
setShowName(bool b)1243 void ConfigMainWindow::setShowName(bool b)
1244 {
1245 	if (configList->showName == b)
1246 		return;
1247 	configList->showName = b;
1248 	configList->reinit();
1249 	menuList->showName = b;
1250 	menuList->reinit();
1251 }
1252 
setShowRange(bool b)1253 void ConfigMainWindow::setShowRange(bool b)
1254 {
1255 	if (configList->showRange == b)
1256 		return;
1257 	configList->showRange = b;
1258 	configList->reinit();
1259 	menuList->showRange = b;
1260 	menuList->reinit();
1261 }
1262 
setShowData(bool b)1263 void ConfigMainWindow::setShowData(bool b)
1264 {
1265 	if (configList->showData == b)
1266 		return;
1267 	configList->showData = b;
1268 	configList->reinit();
1269 	menuList->showData = b;
1270 	menuList->reinit();
1271 }
1272 
1273 /*
1274  * ask for saving configuration before quitting
1275  * TODO ask only when something changed
1276  */
closeEvent(QCloseEvent * e)1277 void ConfigMainWindow::closeEvent(QCloseEvent* e)
1278 {
1279 	if (!sym_change_count) {
1280 		e->accept();
1281 		return;
1282 	}
1283 	QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning,
1284 			QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape);
1285 	mb.setButtonText(QMessageBox::Yes, "&Save Changes");
1286 	mb.setButtonText(QMessageBox::No, "&Discard Changes");
1287 	mb.setButtonText(QMessageBox::Cancel, "Cancel Exit");
1288 	switch (mb.exec()) {
1289 	case QMessageBox::Yes:
1290 		conf_write(NULL);
1291 	case QMessageBox::No:
1292 		e->accept();
1293 		break;
1294 	case QMessageBox::Cancel:
1295 		e->ignore();
1296 		break;
1297 	}
1298 }
1299 
showIntro(void)1300 void ConfigMainWindow::showIntro(void)
1301 {
1302 	static char str[] = "Welcome to the qconf graphical configuration tool.\n\n"
1303 		"For each option, a blank box indicates the feature is disabled, a check\n"
1304 		"indicates it is enabled, and a dot indicates that it is to be compiled\n"
1305 		"as a module.  Clicking on the box will cycle through the three states.\n\n"
1306 		"If you do not see an option (e.g., a device driver) that you believe\n"
1307 		"should be present, try turning on Show All Options under the Options menu.\n"
1308 		"Although there is no cross reference yet to help you figure out what other\n"
1309 		"options must be enabled to support the option you are interested in, you can\n"
1310 		"still view the help of a grayed-out option.\n\n"
1311 		"Toggling Show Debug Info under the Options menu will show the dependencies,\n"
1312 		"which you can then match by examining other options.\n\n";
1313 
1314 	QMessageBox::information(this, "qconf", str);
1315 }
1316 
showAbout(void)1317 void ConfigMainWindow::showAbout(void)
1318 {
1319 	static char str[] = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n";
1320 
1321 	QMessageBox::information(this, "qconf", str);
1322 }
1323 
saveSettings(void)1324 void ConfigMainWindow::saveSettings(void)
1325 {
1326 #if QT_VERSION >= 300
1327 	ConfigSettings *configSettings = new ConfigSettings;
1328 	configSettings->writeEntry("/kconfig/qconf/window x", pos().x());
1329 	configSettings->writeEntry("/kconfig/qconf/window y", pos().y());
1330 	configSettings->writeEntry("/kconfig/qconf/window width", size().width());
1331 	configSettings->writeEntry("/kconfig/qconf/window height", size().height());
1332 	configSettings->writeEntry("/kconfig/qconf/showName", configList->showName);
1333 	configSettings->writeEntry("/kconfig/qconf/showRange", configList->showRange);
1334 	configSettings->writeEntry("/kconfig/qconf/showData", configList->showData);
1335 	configSettings->writeEntry("/kconfig/qconf/showAll", configList->showAll);
1336 	configSettings->writeEntry("/kconfig/qconf/showDebug", showDebug);
1337 
1338 	QString entry;
1339 	switch(configList->mode) {
1340 	case singleMode :
1341 		entry = "single";
1342 		break;
1343 
1344 	case symbolMode :
1345 		entry = "split";
1346 		break;
1347 
1348 	case fullMode :
1349 		entry = "full";
1350 		break;
1351 	}
1352 	configSettings->writeEntry("/kconfig/qconf/listMode", entry);
1353 
1354 	configSettings->writeSizes("/kconfig/qconf/split1", split1->sizes());
1355 	configSettings->writeSizes("/kconfig/qconf/split2", split2->sizes());
1356 
1357 	delete configSettings;
1358 #endif
1359 }
1360 
fixup_rootmenu(struct menu * menu)1361 void fixup_rootmenu(struct menu *menu)
1362 {
1363 	struct menu *child;
1364 	static int menu_cnt = 0;
1365 
1366 	menu->flags |= MENU_ROOT;
1367 	for (child = menu->list; child; child = child->next) {
1368 		if (child->prompt && child->prompt->type == P_MENU) {
1369 			menu_cnt++;
1370 			fixup_rootmenu(child);
1371 			menu_cnt--;
1372 		} else if (!menu_cnt)
1373 			fixup_rootmenu(child);
1374 	}
1375 }
1376 
1377 static const char *progname;
1378 
usage(void)1379 static void usage(void)
1380 {
1381 	printf("%s <config>\n", progname);
1382 	exit(0);
1383 }
1384 
main(int ac,char ** av)1385 int main(int ac, char** av)
1386 {
1387 	ConfigMainWindow* v;
1388 	const char *name;
1389 
1390 	bindtextdomain(PACKAGE, LOCALEDIR);
1391 	textdomain(PACKAGE);
1392 
1393 #ifndef LKC_DIRECT_LINK
1394 	kconfig_load();
1395 #endif
1396 
1397 	progname = av[0];
1398 	configApp = new QApplication(ac, av);
1399 	if (ac > 1 && av[1][0] == '-') {
1400 		switch (av[1][1]) {
1401 		case 'h':
1402 		case '?':
1403 			usage();
1404 		}
1405 		name = av[2];
1406 	} else
1407 		name = av[1];
1408 	if (!name)
1409 		usage();
1410 
1411 	conf_parse(name);
1412 	fixup_rootmenu(&rootmenu);
1413 	conf_read(NULL);
1414 	//zconfdump(stdout);
1415 
1416 	v = new ConfigMainWindow();
1417 
1418 	//zconfdump(stdout);
1419 	v->show();
1420 	configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
1421 	configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
1422 	configApp->exec();
1423 
1424 	return 0;
1425 }
1426