author | kergoth <kergoth> | 2002-10-31 17:11:35 (UTC) |
---|---|---|
committer | kergoth <kergoth> | 2002-10-31 17:11:35 (UTC) |
commit | d955226c2197578f69c510282a4e9ad1ea8fe771 (patch) (unidiff) | |
tree | 0d8f210dd012559df4e3432ccc8ce96e9bd15853 /scripts/kconfig/qconf.cc | |
parent | 16fcb285f9ba7c514fc3f2695768a82feeb7182b (diff) | |
download | opie-d955226c2197578f69c510282a4e9ad1ea8fe771.zip opie-d955226c2197578f69c510282a4e9ad1ea8fe771.tar.gz opie-d955226c2197578f69c510282a4e9ad1ea8fe771.tar.bz2 |
Initial bits to start work on revamping the buildsystem
-rw-r--r-- | scripts/kconfig/qconf.cc | 1073 |
1 files changed, 1073 insertions, 0 deletions
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc new file mode 100644 index 0000000..feefa1c --- a/dev/null +++ b/scripts/kconfig/qconf.cc | |||
@@ -0,0 +1,1073 @@ | |||
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 | #include <stdlib.h> | ||
21 | |||
22 | #include "lkc.h" | ||
23 | #include "qconf.h" | ||
24 | |||
25 | #include "qconf.moc" | ||
26 | #include "images.c" | ||
27 | |||
28 | static QApplication *configApp; | ||
29 | |||
30 | /* | ||
31 | * update all the children of a menu entry | ||
32 | * removes/adds the entries from the parent widget as necessary | ||
33 | * | ||
34 | * parent: either the menu list widget or a menu entry widget | ||
35 | * menu: entry to be updated | ||
36 | */ | ||
37 | template <class P> | ||
38 | static void updateMenuList(P* parent, struct menu* menu) | ||
39 | { | ||
40 | struct menu* child; | ||
41 | ConfigList* list = parent->listView(); | ||
42 | ConfigItem* item; | ||
43 | ConfigItem* last; | ||
44 | bool visible; | ||
45 | bool showAll = list->showAll; | ||
46 | enum listMode mode = list->mode; | ||
47 | enum prop_type type; | ||
48 | |||
49 | if (!menu) { | ||
50 | while ((item = parent->firstChild())) | ||
51 | delete item; | ||
52 | return; | ||
53 | } | ||
54 | |||
55 | last = 0; | ||
56 | for (child = menu->list; child; child = child->next) { | ||
57 | item = last ? last->nextSibling() : parent->firstChild(); | ||
58 | type = child->prompt ? child->prompt->type : P_UNKNOWN; | ||
59 | |||
60 | switch (mode) { | ||
61 | case menuMode: | ||
62 | if (type != P_ROOTMENU) | ||
63 | goto hide; | ||
64 | break; | ||
65 | case symbolMode: | ||
66 | if (type == P_ROOTMENU) | ||
67 | goto hide; | ||
68 | break; | ||
69 | default: | ||
70 | break; | ||
71 | } | ||
72 | |||
73 | visible = menu_is_visible(child); | ||
74 | if (showAll || visible) { | ||
75 | if (!item || item->menu != child) | ||
76 | item = new ConfigItem(parent, last, child); | ||
77 | item->visible = visible; | ||
78 | item->updateMenu(); | ||
79 | |||
80 | if (mode == fullMode || mode == menuMode || | ||
81 | (type != P_MENU && type != P_ROOTMENU)) | ||
82 | updateMenuList(item, child); | ||
83 | else | ||
84 | updateMenuList(item, 0); | ||
85 | last = item; | ||
86 | continue; | ||
87 | } | ||
88 | hide: | ||
89 | if (item && item->menu == child) { | ||
90 | last = parent->firstChild(); | ||
91 | if (last == item) | ||
92 | last = 0; | ||
93 | else while (last->nextSibling() != item) | ||
94 | last = last->nextSibling(); | ||
95 | delete item; | ||
96 | } | ||
97 | } | ||
98 | } | ||
99 | |||
100 | #if QT_VERSION >= 300 | ||
101 | /* | ||
102 | * set the new data | ||
103 | * TODO check the value | ||
104 | */ | ||
105 | void ConfigItem::okRename(int col) | ||
106 | { | ||
107 | Parent::okRename(col); | ||
108 | sym_set_string_value(menu->sym, text(dataColIdx).latin1()); | ||
109 | } | ||
110 | #endif | ||
111 | |||
112 | /* | ||
113 | * update the displayed of a menu entry | ||
114 | */ | ||
115 | void ConfigItem::updateMenu(void) | ||
116 | { | ||
117 | ConfigList* list; | ||
118 | struct symbol* sym; | ||
119 | QString prompt; | ||
120 | int type; | ||
121 | enum prop_type ptype; | ||
122 | tristate expr; | ||
123 | bool update; | ||
124 | |||
125 | list = listView(); | ||
126 | update = doInit; | ||
127 | if (update) | ||
128 | doInit = false; | ||
129 | else | ||
130 | update = list->updateAll; | ||
131 | |||
132 | sym = menu->sym; | ||
133 | if (!sym) { | ||
134 | if (update) { | ||
135 | setText(promptColIdx, menu_get_prompt(menu)); | ||
136 | ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; | ||
137 | if ((ptype == P_ROOTMENU || ptype == P_MENU) && | ||
138 | (list->mode == singleMode || list->mode == symbolMode)) | ||
139 | setPixmap(promptColIdx, list->menuPix); | ||
140 | else | ||
141 | setPixmap(promptColIdx, 0); | ||
142 | } | ||
143 | return; | ||
144 | } | ||
145 | |||
146 | sym_calc_value(sym); | ||
147 | if (!(sym->flags & SYMBOL_CHANGED) && !update) | ||
148 | return; | ||
149 | |||
150 | sym->flags &= ~SYMBOL_CHANGED; | ||
151 | |||
152 | setText(nameColIdx, menu->sym->name); | ||
153 | |||
154 | type = sym_get_type(sym); | ||
155 | switch (type) { | ||
156 | case S_BOOLEAN: | ||
157 | case S_TRISTATE: | ||
158 | char ch; | ||
159 | |||
160 | prompt = menu_get_prompt(menu); | ||
161 | if (!sym_is_changable(sym) && !list->showAll) { | ||
162 | setText(noColIdx, 0); | ||
163 | setText(modColIdx, 0); | ||
164 | setText(yesColIdx, 0); | ||
165 | break; | ||
166 | } | ||
167 | expr = sym_get_tristate_value(sym); | ||
168 | switch (expr) { | ||
169 | case yes: | ||
170 | if (sym_is_choice_value(sym) && type == S_BOOLEAN) | ||
171 | setPixmap(promptColIdx, list->choiceYesPix); | ||
172 | else | ||
173 | setPixmap(promptColIdx, list->symbolYesPix); | ||
174 | setText(yesColIdx, "Y"); | ||
175 | ch = 'Y'; | ||
176 | break; | ||
177 | case mod: | ||
178 | setPixmap(promptColIdx, list->symbolModPix); | ||
179 | setText(modColIdx, "M"); | ||
180 | ch = 'M'; | ||
181 | break; | ||
182 | default: | ||
183 | if (sym_is_choice_value(sym) && type == S_BOOLEAN) | ||
184 | setPixmap(promptColIdx, list->choiceNoPix); | ||
185 | else | ||
186 | setPixmap(promptColIdx, list->symbolNoPix); | ||
187 | setText(noColIdx, "N"); | ||
188 | ch = 'N'; | ||
189 | break; | ||
190 | } | ||
191 | if (expr != no) | ||
192 | setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0); | ||
193 | if (expr != mod) | ||
194 | setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0); | ||
195 | if (expr != yes) | ||
196 | setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0); | ||
197 | |||
198 | setText(dataColIdx, QChar(ch)); | ||
199 | break; | ||
200 | case S_INT: | ||
201 | case S_HEX: | ||
202 | case S_STRING: | ||
203 | const char* data; | ||
204 | |||
205 | data = sym_get_string_value(sym); | ||
206 | #if QT_VERSION >= 300 | ||
207 | setRenameEnabled(list->mapIdx(dataColIdx), TRUE); | ||
208 | #endif | ||
209 | setText(dataColIdx, data); | ||
210 | if (type == S_STRING) | ||
211 | prompt.sprintf("%s: %s", menu_get_prompt(menu), data); | ||
212 | else | ||
213 | prompt.sprintf("(%s) %s", data, menu_get_prompt(menu)); | ||
214 | break; | ||
215 | } | ||
216 | if (!sym_has_value(sym) && visible) | ||
217 | prompt += " (NEW)"; | ||
218 | setText(promptColIdx, prompt); | ||
219 | } | ||
220 | |||
221 | void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align) | ||
222 | { | ||
223 | ConfigList* list = listView(); | ||
224 | |||
225 | if (visible) { | ||
226 | if (isSelected() && !list->hasFocus() && list->mode == menuMode) | ||
227 | Parent::paintCell(p, list->inactivedColorGroup, column, width, align); | ||
228 | else | ||
229 | Parent::paintCell(p, cg, column, width, align); | ||
230 | } else | ||
231 | Parent::paintCell(p, list->disabledColorGroup, column, width, align); | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * construct a menu entry | ||
236 | */ | ||
237 | void ConfigItem::init(void) | ||
238 | { | ||
239 | ConfigList* list = listView(); | ||
240 | #if QT_VERSION < 300 | ||
241 | visible = TRUE; | ||
242 | #endif | ||
243 | //menu->data = this; | ||
244 | if (list->mode != fullMode) | ||
245 | setOpen(TRUE); | ||
246 | doInit= true; | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | * destruct a menu entry | ||
251 | */ | ||
252 | ConfigItem::~ConfigItem(void) | ||
253 | { | ||
254 | //menu->data = 0; | ||
255 | } | ||
256 | |||
257 | void ConfigLineEdit::show(ConfigItem* i) | ||
258 | { | ||
259 | item = i; | ||
260 | if (sym_get_string_value(item->menu->sym)) | ||
261 | setText(sym_get_string_value(item->menu->sym)); | ||
262 | else | ||
263 | setText(0); | ||
264 | Parent::show(); | ||
265 | setFocus(); | ||
266 | } | ||
267 | |||
268 | void ConfigLineEdit::keyPressEvent(QKeyEvent* e) | ||
269 | { | ||
270 | switch (e->key()) { | ||
271 | case Key_Escape: | ||
272 | break; | ||
273 | case Key_Return: | ||
274 | case Key_Enter: | ||
275 | sym_set_string_value(item->menu->sym, text().latin1()); | ||
276 | emit lineChanged(item); | ||
277 | break; | ||
278 | default: | ||
279 | Parent::keyPressEvent(e); | ||
280 | return; | ||
281 | } | ||
282 | e->accept(); | ||
283 | hide(); | ||
284 | } | ||
285 | |||
286 | ConfigList::ConfigList(QWidget* p, ConfigView* cv) | ||
287 | : Parent(p), cview(cv), | ||
288 | updateAll(false), | ||
289 | symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no), | ||
290 | choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no), menuPix(xpm_menu), menuInvPix(xpm_menu_inv), | ||
291 | showAll(false), showName(false), showRange(false), showData(false), | ||
292 | rootEntry(0) | ||
293 | { | ||
294 | int i; | ||
295 | |||
296 | setSorting(-1); | ||
297 | setRootIsDecorated(TRUE); | ||
298 | disabledColorGroup = palette().active(); | ||
299 | disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text()); | ||
300 | inactivedColorGroup = palette().active(); | ||
301 | inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight()); | ||
302 | |||
303 | connect(this, SIGNAL(selectionChanged(void)), | ||
304 | SLOT(updateSelection(void))); | ||
305 | |||
306 | for (i = 0; i < colNr; i++) | ||
307 | colMap[i] = colRevMap[i] = -1; | ||
308 | addColumn(promptColIdx, "Option"); | ||
309 | |||
310 | reinit(); | ||
311 | } | ||
312 | |||
313 | void ConfigList::reinit(void) | ||
314 | { | ||
315 | removeColumn(dataColIdx); | ||
316 | removeColumn(yesColIdx); | ||
317 | removeColumn(modColIdx); | ||
318 | removeColumn(noColIdx); | ||
319 | removeColumn(nameColIdx); | ||
320 | |||
321 | if (showName) | ||
322 | addColumn(nameColIdx, "Name"); | ||
323 | if (showRange) { | ||
324 | addColumn(noColIdx, "N"); | ||
325 | addColumn(modColIdx, "M"); | ||
326 | addColumn(yesColIdx, "Y"); | ||
327 | } | ||
328 | if (showData) | ||
329 | addColumn(dataColIdx, "Value"); | ||
330 | |||
331 | updateListAll(); | ||
332 | } | ||
333 | |||
334 | void ConfigList::updateSelection(void) | ||
335 | { | ||
336 | struct menu *menu; | ||
337 | enum prop_type type; | ||
338 | |||
339 | ConfigItem* item = (ConfigItem*)selectedItem(); | ||
340 | if (!item) | ||
341 | return; | ||
342 | |||
343 | cview->setHelp(item); | ||
344 | |||
345 | menu = item->menu; | ||
346 | type = menu->prompt ? menu->prompt->type : P_UNKNOWN; | ||
347 | if (mode == menuMode && (type == P_MENU || type == P_ROOTMENU)) | ||
348 | emit menuSelected(menu); | ||
349 | } | ||
350 | |||
351 | void ConfigList::updateList(ConfigItem* item) | ||
352 | { | ||
353 | (void)item;// unused so far | ||
354 | updateMenuList(this, rootEntry); | ||
355 | } | ||
356 | |||
357 | void ConfigList::setAllOpen(bool open) | ||
358 | { | ||
359 | QListViewItemIterator it(this); | ||
360 | |||
361 | for (; it.current(); it++) | ||
362 | it.current()->setOpen(open); | ||
363 | } | ||
364 | |||
365 | void ConfigList::setValue(ConfigItem* item, tristate val) | ||
366 | { | ||
367 | struct symbol* sym; | ||
368 | int type; | ||
369 | tristate oldval; | ||
370 | |||
371 | sym = item->menu->sym; | ||
372 | if (!sym) | ||
373 | return; | ||
374 | |||
375 | type = sym_get_type(sym); | ||
376 | switch (type) { | ||
377 | case S_BOOLEAN: | ||
378 | case S_TRISTATE: | ||
379 | oldval = sym_get_tristate_value(sym); | ||
380 | |||
381 | if (!sym_set_tristate_value(sym, val)) | ||
382 | return; | ||
383 | if (oldval == no && item->menu->list) | ||
384 | item->setOpen(TRUE); | ||
385 | emit symbolChanged(item); | ||
386 | break; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | void ConfigList::changeValue(ConfigItem* item) | ||
391 | { | ||
392 | struct symbol* sym; | ||
393 | struct menu* menu; | ||
394 | int type, oldexpr, newexpr; | ||
395 | |||
396 | menu = item->menu; | ||
397 | sym = menu->sym; | ||
398 | if (!sym) { | ||
399 | if (item->menu->list) | ||
400 | item->setOpen(!item->isOpen()); | ||
401 | return; | ||
402 | } | ||
403 | |||
404 | type = sym_get_type(sym); | ||
405 | switch (type) { | ||
406 | case S_BOOLEAN: | ||
407 | case S_TRISTATE: | ||
408 | oldexpr = sym_get_tristate_value(sym); | ||
409 | newexpr = sym_toggle_tristate_value(sym); | ||
410 | if (item->menu->list) { | ||
411 | if (oldexpr == newexpr) | ||
412 | item->setOpen(!item->isOpen()); | ||
413 | else if (oldexpr == no) | ||
414 | item->setOpen(TRUE); | ||
415 | } | ||
416 | if (oldexpr != newexpr) | ||
417 | emit symbolChanged(item); | ||
418 | break; | ||
419 | case S_INT: | ||
420 | case S_HEX: | ||
421 | case S_STRING: | ||
422 | #if QT_VERSION >= 300 | ||
423 | if (colMap[dataColIdx] >= 0) | ||
424 | item->startRename(colMap[dataColIdx]); | ||
425 | else | ||
426 | #endif | ||
427 | lineEdit->show(item); | ||
428 | break; | ||
429 | } | ||
430 | } | ||
431 | |||
432 | void ConfigList::setRootMenu(struct menu *menu) | ||
433 | { | ||
434 | enum prop_type type; | ||
435 | |||
436 | if (rootEntry == menu) | ||
437 | return; | ||
438 | type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN; | ||
439 | if (type != P_MENU && type != P_ROOTMENU) | ||
440 | return; | ||
441 | updateMenuList(this, 0); | ||
442 | rootEntry = menu; | ||
443 | updateListAll(); | ||
444 | setSelected(currentItem(), hasFocus()); | ||
445 | } | ||
446 | |||
447 | void ConfigList::setParentMenu(void) | ||
448 | { | ||
449 | ConfigItem* item; | ||
450 | struct menu *oldroot, *newroot; | ||
451 | |||
452 | oldroot = rootEntry; | ||
453 | newroot = menu_get_parent_menu(oldroot); | ||
454 | if (newroot == oldroot) | ||
455 | return; | ||
456 | setRootMenu(newroot); | ||
457 | |||
458 | QListViewItemIterator it(this); | ||
459 | for (; (item = (ConfigItem*)it.current()); it++) { | ||
460 | if (item->menu == oldroot) { | ||
461 | setCurrentItem(item); | ||
462 | ensureItemVisible(item); | ||
463 | break; | ||
464 | } | ||
465 | } | ||
466 | } | ||
467 | |||
468 | void ConfigList::keyPressEvent(QKeyEvent* ev) | ||
469 | { | ||
470 | QListViewItem* i = currentItem(); | ||
471 | ConfigItem* item; | ||
472 | struct menu *menu; | ||
473 | enum prop_type type; | ||
474 | |||
475 | if (ev->key() == Key_Escape && mode != fullMode) { | ||
476 | emit parentSelected(); | ||
477 | ev->accept(); | ||
478 | return; | ||
479 | } | ||
480 | |||
481 | if (!i) { | ||
482 | Parent::keyPressEvent(ev); | ||
483 | return; | ||
484 | } | ||
485 | item = (ConfigItem*)i; | ||
486 | |||
487 | switch (ev->key()) { | ||
488 | case Key_Return: | ||
489 | case Key_Enter: | ||
490 | menu = item->menu; | ||
491 | type = menu->prompt ? menu->prompt->type : P_UNKNOWN; | ||
492 | if ((type == P_MENU || type == P_ROOTMENU) && mode != fullMode) { | ||
493 | emit menuSelected(menu); | ||
494 | break; | ||
495 | } | ||
496 | case Key_Space: | ||
497 | changeValue(item); | ||
498 | break; | ||
499 | case Key_N: | ||
500 | setValue(item, no); | ||
501 | break; | ||
502 | case Key_M: | ||
503 | setValue(item, mod); | ||
504 | break; | ||
505 | case Key_Y: | ||
506 | setValue(item, yes); | ||
507 | break; | ||
508 | default: | ||
509 | Parent::keyPressEvent(ev); | ||
510 | return; | ||
511 | } | ||
512 | ev->accept(); | ||
513 | } | ||
514 | |||
515 | void ConfigList::contentsMousePressEvent(QMouseEvent* e) | ||
516 | { | ||
517 | //QPoint p(contentsToViewport(e->pos())); | ||
518 | //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y()); | ||
519 | QListView::contentsMousePressEvent(e); | ||
520 | } | ||
521 | |||
522 | void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e) | ||
523 | { | ||
524 | QPoint p(contentsToViewport(e->pos())); | ||
525 | ConfigItem* item = (ConfigItem*)itemAt(p); | ||
526 | struct menu *menu; | ||
527 | const QPixmap* pm; | ||
528 | int idx, x; | ||
529 | |||
530 | if (!item) | ||
531 | goto skip; | ||
532 | |||
533 | menu = item->menu; | ||
534 | x = header()->offset() + p.x(); | ||
535 | idx = colRevMap[header()->sectionAt(x)]; | ||
536 | switch (idx) { | ||
537 | case promptColIdx: | ||
538 | pm = item->pixmap(promptColIdx); | ||
539 | if (pm) { | ||
540 | int off = header()->sectionPos(0) + itemMargin() + | ||
541 | treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0)); | ||
542 | if (x >= off && x < off + pm->width()) { | ||
543 | if (menu->sym) | ||
544 | changeValue(item); | ||
545 | else | ||
546 | emit menuSelected(menu); | ||
547 | } | ||
548 | } | ||
549 | break; | ||
550 | case noColIdx: | ||
551 | setValue(item, no); | ||
552 | break; | ||
553 | case modColIdx: | ||
554 | setValue(item, mod); | ||
555 | break; | ||
556 | case yesColIdx: | ||
557 | setValue(item, yes); | ||
558 | break; | ||
559 | case dataColIdx: | ||
560 | changeValue(item); | ||
561 | break; | ||
562 | } | ||
563 | |||
564 | skip: | ||
565 | //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y()); | ||
566 | QListView::contentsMouseReleaseEvent(e); | ||
567 | } | ||
568 | |||
569 | void ConfigList::contentsMouseMoveEvent(QMouseEvent* e) | ||
570 | { | ||
571 | //QPoint p(contentsToViewport(e->pos())); | ||
572 | //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y()); | ||
573 | QListView::contentsMouseMoveEvent(e); | ||
574 | } | ||
575 | |||
576 | void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e) | ||
577 | { | ||
578 | QPoint p(contentsToViewport(e->pos())); | ||
579 | ConfigItem* item = (ConfigItem*)itemAt(p); | ||
580 | struct menu *menu; | ||
581 | enum prop_type ptype; | ||
582 | |||
583 | if (!item) | ||
584 | goto skip; | ||
585 | menu = item->menu; | ||
586 | ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; | ||
587 | if ((ptype == P_ROOTMENU || ptype == P_MENU) && | ||
588 | (mode == singleMode || mode == symbolMode)) | ||
589 | emit menuSelected(menu); | ||
590 | |||
591 | skip: | ||
592 | //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y()); | ||
593 | QListView::contentsMouseDoubleClickEvent(e); | ||
594 | } | ||
595 | |||
596 | void ConfigList::focusInEvent(QFocusEvent *e) | ||
597 | { | ||
598 | Parent::focusInEvent(e); | ||
599 | |||
600 | QListViewItem* item = currentItem(); | ||
601 | if (!item) | ||
602 | return; | ||
603 | |||
604 | setSelected(item, TRUE); | ||
605 | emit gotFocus(); | ||
606 | } | ||
607 | |||
608 | /* | ||
609 | * Construct the complete config widget | ||
610 | */ | ||
611 | ConfigView::ConfigView(void) | ||
612 | { | ||
613 | QMenuBar* menu; | ||
614 | QSplitter* split1; | ||
615 | QSplitter* split2; | ||
616 | |||
617 | showDebug = false; | ||
618 | |||
619 | split1 = new QSplitter(this); | ||
620 | split1->setOrientation(QSplitter::Horizontal); | ||
621 | setCentralWidget(split1); | ||
622 | |||
623 | menuList = new ConfigList(split1, this); | ||
624 | |||
625 | split2 = new QSplitter(split1); | ||
626 | split2->setOrientation(QSplitter::Vertical); | ||
627 | |||
628 | // create config tree | ||
629 | QVBox* box = new QVBox(split2); | ||
630 | configList = new ConfigList(box, this); | ||
631 | configList->lineEdit = new ConfigLineEdit(box); | ||
632 | configList->lineEdit->hide(); | ||
633 | configList->connect(configList, SIGNAL(symbolChanged(ConfigItem*)), | ||
634 | configList, SLOT(updateList(ConfigItem*))); | ||
635 | configList->connect(configList, SIGNAL(symbolChanged(ConfigItem*)), | ||
636 | menuList, SLOT(updateList(ConfigItem*))); | ||
637 | configList->connect(configList->lineEdit, SIGNAL(lineChanged(ConfigItem*)), | ||
638 | SLOT(updateList(ConfigItem*))); | ||
639 | |||
640 | helpText = new QTextView(split2); | ||
641 | helpText->setTextFormat(Qt::RichText); | ||
642 | |||
643 | setTabOrder(configList, helpText); | ||
644 | configList->setFocus(); | ||
645 | |||
646 | menu = menuBar(); | ||
647 | toolBar = new QToolBar("Tools", this); | ||
648 | |||
649 | backAction = new QAction("Back", QPixmap(xpm_back), "Back", 0, this); | ||
650 | connect(backAction, SIGNAL(activated()), SLOT(goBack())); | ||
651 | backAction->setEnabled(FALSE); | ||
652 | QAction *quitAction = new QAction("Quit", "&Quit", CTRL+Key_Q, this); | ||
653 | connect(quitAction, SIGNAL(activated()), SLOT(close())); | ||
654 | QAction *loadAction = new QAction("Load", QPixmap(xpm_load), "&Load", CTRL+Key_L, this); | ||
655 | connect(loadAction, SIGNAL(activated()), SLOT(loadConfig())); | ||
656 | QAction *saveAction = new QAction("Save", QPixmap(xpm_save), "&Save", CTRL+Key_S, this); | ||
657 | connect(saveAction, SIGNAL(activated()), SLOT(saveConfig())); | ||
658 | QAction *saveAsAction = new QAction("Save As...", "Save &As...", 0, this); | ||
659 | connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs())); | ||
660 | QAction *singleViewAction = new QAction("Single View", QPixmap(xpm_single_view), "Split View", 0, this); | ||
661 | connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView())); | ||
662 | QAction *splitViewAction = new QAction("Split View", QPixmap(xpm_split_view), "Split View", 0, this); | ||
663 | connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView())); | ||
664 | QAction *fullViewAction = new QAction("Full View", QPixmap(xpm_tree_view), "Full View", 0, this); | ||
665 | connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView())); | ||
666 | |||
667 | QAction *showNameAction = new QAction(NULL, "Show Name", 0, this); | ||
668 | showNameAction->setToggleAction(TRUE); | ||
669 | showNameAction->setOn(configList->showName); | ||
670 | connect(showNameAction, SIGNAL(toggled(bool)), SLOT(setShowName(bool))); | ||
671 | QAction *showRangeAction = new QAction(NULL, "Show Range", 0, this); | ||
672 | showRangeAction->setToggleAction(TRUE); | ||
673 | showRangeAction->setOn(configList->showRange); | ||
674 | connect(showRangeAction, SIGNAL(toggled(bool)), SLOT(setShowRange(bool))); | ||
675 | QAction *showDataAction = new QAction(NULL, "Show Data", 0, this); | ||
676 | showDataAction->setToggleAction(TRUE); | ||
677 | showDataAction->setOn(configList->showData); | ||
678 | connect(showDataAction, SIGNAL(toggled(bool)), SLOT(setShowData(bool))); | ||
679 | QAction *showAllAction = new QAction(NULL, "Show All Options", 0, this); | ||
680 | showAllAction->setToggleAction(TRUE); | ||
681 | showAllAction->setOn(configList->showAll); | ||
682 | connect(showAllAction, SIGNAL(toggled(bool)), SLOT(setShowAll(bool))); | ||
683 | QAction *showDebugAction = new QAction(NULL, "Show Debug Info", 0, this); | ||
684 | showDebugAction->setToggleAction(TRUE); | ||
685 | showDebugAction->setOn(showDebug); | ||
686 | connect(showDebugAction, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool))); | ||
687 | |||
688 | // init tool bar | ||
689 | backAction->addTo(toolBar); | ||
690 | toolBar->addSeparator(); | ||
691 | loadAction->addTo(toolBar); | ||
692 | saveAction->addTo(toolBar); | ||
693 | toolBar->addSeparator(); | ||
694 | singleViewAction->addTo(toolBar); | ||
695 | splitViewAction->addTo(toolBar); | ||
696 | fullViewAction->addTo(toolBar); | ||
697 | |||
698 | // create config menu | ||
699 | QPopupMenu* config = new QPopupMenu(this); | ||
700 | menu->insertItem("&File", config); | ||
701 | loadAction->addTo(config); | ||
702 | saveAction->addTo(config); | ||
703 | saveAsAction->addTo(config); | ||
704 | config->insertSeparator(); | ||
705 | quitAction->addTo(config); | ||
706 | |||
707 | // create options menu | ||
708 | QPopupMenu* optionMenu = new QPopupMenu(this); | ||
709 | menu->insertItem("&Option", optionMenu); | ||
710 | showNameAction->addTo(optionMenu); | ||
711 | showRangeAction->addTo(optionMenu); | ||
712 | showDataAction->addTo(optionMenu); | ||
713 | optionMenu->insertSeparator(); | ||
714 | showAllAction->addTo(optionMenu); | ||
715 | showDebugAction->addTo(optionMenu); | ||
716 | |||
717 | connect(configList, SIGNAL(menuSelected(struct menu *)), | ||
718 | SLOT(changeMenu(struct menu *))); | ||
719 | connect(configList, SIGNAL(parentSelected()), | ||
720 | SLOT(goBack())); | ||
721 | connect(menuList, SIGNAL(menuSelected(struct menu *)), | ||
722 | SLOT(changeMenu(struct menu *))); | ||
723 | |||
724 | connect(configList, SIGNAL(gotFocus(void)), | ||
725 | SLOT(listFocusChanged(void))); | ||
726 | connect(menuList, SIGNAL(gotFocus(void)), | ||
727 | SLOT(listFocusChanged(void))); | ||
728 | |||
729 | //showFullView(); | ||
730 | showSplitView(); | ||
731 | } | ||
732 | |||
733 | static QString print_filter(const char *str) | ||
734 | { | ||
735 | QRegExp re("[<>&\"\\n]"); | ||
736 | QString res = str; | ||
737 | for (int i = 0; (i = res.find(re, i)) >= 0;) { | ||
738 | switch (res[i].latin1()) { | ||
739 | case '<': | ||
740 | res.replace(i, 1, "<"); | ||
741 | i += 4; | ||
742 | break; | ||
743 | case '>': | ||
744 | res.replace(i, 1, ">"); | ||
745 | i += 4; | ||
746 | break; | ||
747 | case '&': | ||
748 | res.replace(i, 1, "&"); | ||
749 | i += 5; | ||
750 | break; | ||
751 | case '"': | ||
752 | res.replace(i, 1, """); | ||
753 | i += 6; | ||
754 | break; | ||
755 | case '\n': | ||
756 | res.replace(i, 1, "<br>"); | ||
757 | i += 4; | ||
758 | break; | ||
759 | } | ||
760 | } | ||
761 | return res; | ||
762 | } | ||
763 | |||
764 | static void expr_print_help(void *data, const char *str) | ||
765 | { | ||
766 | ((QString*)data)->append(print_filter(str)); | ||
767 | } | ||
768 | |||
769 | /* | ||
770 | * display a new help entry as soon as a new menu entry is selected | ||
771 | */ | ||
772 | void ConfigView::setHelp(QListViewItem* item) | ||
773 | { | ||
774 | struct symbol* sym; | ||
775 | struct menu* menu; | ||
776 | |||
777 | configList->lineEdit->hide(); | ||
778 | if (item) { | ||
779 | QString head, debug, help; | ||
780 | menu = ((ConfigItem*)item)->menu; | ||
781 | sym = menu->sym; | ||
782 | if (sym) { | ||
783 | if (menu->prompt) { | ||
784 | head += "<big><b>"; | ||
785 | head += print_filter(menu->prompt->text); | ||
786 | head += "</b></big>"; | ||
787 | if (sym->name) { | ||
788 | head += " ("; | ||
789 | head += print_filter(sym->name); | ||
790 | head += ")"; | ||
791 | } | ||
792 | } else if (sym->name) { | ||
793 | head += "<big><b>"; | ||
794 | head += print_filter(sym->name); | ||
795 | head += "</b></big>"; | ||
796 | } | ||
797 | head += "<br><br>"; | ||
798 | |||
799 | if (showDebug) { | ||
800 | debug += "type: "; | ||
801 | debug += print_filter(sym_type_name(sym->type)); | ||
802 | debug += "<br>"; | ||
803 | for (struct property *prop = sym->prop; prop; prop = prop->next) { | ||
804 | switch (prop->type) { | ||
805 | case P_PROMPT: | ||
806 | debug += "prompt: "; | ||
807 | debug += print_filter(prop->text); | ||
808 | debug += "<br>"; | ||
809 | if (prop->visible.expr) { | ||
810 | debug += " dep: "; | ||
811 | expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); | ||
812 | debug += "<br>"; | ||
813 | } | ||
814 | break; | ||
815 | case P_DEFAULT: | ||
816 | debug += "default: "; | ||
817 | if (sym_is_choice(sym)) | ||
818 | debug += print_filter(prop->def->name); | ||
819 | else { | ||
820 | sym_calc_value(prop->def); | ||
821 | debug += print_filter(sym_get_string_value(prop->def)); | ||
822 | } | ||
823 | debug += "<br>"; | ||
824 | if (prop->visible.expr) { | ||
825 | debug += " dep: "; | ||
826 | expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE); | ||
827 | debug += "<br>"; | ||
828 | } | ||
829 | break; | ||
830 | case P_CHOICE: | ||
831 | break; | ||
832 | default: | ||
833 | debug += "unknown property: "; | ||
834 | debug += prop_get_type_name(prop->type); | ||
835 | debug += "<br>"; | ||
836 | } | ||
837 | } | ||
838 | debug += "<br>"; | ||
839 | } | ||
840 | |||
841 | help = print_filter(sym->help); | ||
842 | } else if (menu->prompt) { | ||
843 | head += "<big><b>"; | ||
844 | head += print_filter(menu->prompt->text); | ||
845 | head += "</b></big><br><br>"; | ||
846 | if (showDebug) { | ||
847 | if (menu->prompt->visible.expr) { | ||
848 | debug += " dep: "; | ||
849 | expr_print(menu->prompt->visible.expr, expr_print_help, &debug, E_NONE); | ||
850 | debug += "<br>"; | ||
851 | } | ||
852 | } | ||
853 | } | ||
854 | helpText->setText(head + debug + help); | ||
855 | return; | ||
856 | } | ||
857 | helpText->setText(NULL); | ||
858 | } | ||
859 | |||
860 | void ConfigView::loadConfig(void) | ||
861 | { | ||
862 | QString s = QFileDialog::getOpenFileName(".config", NULL, this); | ||
863 | if (s.isNull()) | ||
864 | return; | ||
865 | if (conf_read(s.latin1())) | ||
866 | QMessageBox::information(this, "qconf", "Unable to load configuration!"); | ||
867 | } | ||
868 | |||
869 | void ConfigView::saveConfig(void) | ||
870 | { | ||
871 | if (conf_write(NULL)) | ||
872 | QMessageBox::information(this, "qconf", "Unable to save configuration!"); | ||
873 | } | ||
874 | |||
875 | void ConfigView::saveConfigAs(void) | ||
876 | { | ||
877 | QString s = QFileDialog::getSaveFileName(".config", NULL, this); | ||
878 | if (s.isNull()) | ||
879 | return; | ||
880 | if (conf_write(s.latin1())) | ||
881 | QMessageBox::information(this, "qconf", "Unable to save configuration!"); | ||
882 | } | ||
883 | |||
884 | void ConfigView::changeMenu(struct menu *menu) | ||
885 | { | ||
886 | configList->setRootMenu(menu); | ||
887 | backAction->setEnabled(TRUE); | ||
888 | } | ||
889 | |||
890 | void ConfigView::listFocusChanged(void) | ||
891 | { | ||
892 | if (menuList->hasFocus()) { | ||
893 | if (menuList->mode == menuMode) | ||
894 | configList->clearSelection(); | ||
895 | setHelp(menuList->selectedItem()); | ||
896 | } else if (configList->hasFocus()) { | ||
897 | setHelp(configList->selectedItem()); | ||
898 | } | ||
899 | } | ||
900 | |||
901 | void ConfigView::goBack(void) | ||
902 | { | ||
903 | ConfigItem* item; | ||
904 | |||
905 | configList->setParentMenu(); | ||
906 | if (configList->rootEntry == &rootmenu) | ||
907 | backAction->setEnabled(FALSE); | ||
908 | item = (ConfigItem*)menuList->selectedItem(); | ||
909 | while (item) { | ||
910 | if (item->menu == configList->rootEntry) { | ||
911 | menuList->setSelected(item, TRUE); | ||
912 | break; | ||
913 | } | ||
914 | item = (ConfigItem*)item->parent(); | ||
915 | } | ||
916 | } | ||
917 | |||
918 | void ConfigView::showSingleView(void) | ||
919 | { | ||
920 | menuList->hide(); | ||
921 | menuList->setRootMenu(0); | ||
922 | configList->mode = singleMode; | ||
923 | if (configList->rootEntry == &rootmenu) | ||
924 | configList->updateListAll(); | ||
925 | else | ||
926 | configList->setRootMenu(&rootmenu); | ||
927 | configList->setAllOpen(TRUE); | ||
928 | configList->setFocus(); | ||
929 | } | ||
930 | |||
931 | void ConfigView::showSplitView(void) | ||
932 | { | ||
933 | configList->mode = symbolMode; | ||
934 | if (configList->rootEntry == &rootmenu) | ||
935 | configList->updateListAll(); | ||
936 | else | ||
937 | configList->setRootMenu(&rootmenu); | ||
938 | configList->setAllOpen(TRUE); | ||
939 | configApp->processEvents(); | ||
940 | menuList->mode = menuMode; | ||
941 | menuList->setRootMenu(&rootmenu); | ||
942 | menuList->show(); | ||
943 | menuList->setAllOpen(TRUE); | ||
944 | menuList->setFocus(); | ||
945 | } | ||
946 | |||
947 | void ConfigView::showFullView(void) | ||
948 | { | ||
949 | menuList->hide(); | ||
950 | menuList->setRootMenu(0); | ||
951 | configList->mode = fullMode; | ||
952 | if (configList->rootEntry == &rootmenu) | ||
953 | configList->updateListAll(); | ||
954 | else | ||
955 | configList->setRootMenu(&rootmenu); | ||
956 | configList->setAllOpen(FALSE); | ||
957 | configList->setFocus(); | ||
958 | } | ||
959 | |||
960 | void ConfigView::setShowAll(bool b) | ||
961 | { | ||
962 | if (configList->showAll == b) | ||
963 | return; | ||
964 | configList->showAll = b; | ||
965 | configList->updateListAll(); | ||
966 | menuList->showAll = b; | ||
967 | menuList->updateListAll(); | ||
968 | } | ||
969 | |||
970 | void ConfigView::setShowDebug(bool b) | ||
971 | { | ||
972 | if (showDebug == b) | ||
973 | return; | ||
974 | showDebug = b; | ||
975 | } | ||
976 | |||
977 | void ConfigView::setShowName(bool b) | ||
978 | { | ||
979 | if (configList->showName == b) | ||
980 | return; | ||
981 | configList->showName = b; | ||
982 | configList->reinit(); | ||
983 | } | ||
984 | |||
985 | void ConfigView::setShowRange(bool b) | ||
986 | { | ||
987 | if (configList->showRange == b) | ||
988 | return; | ||
989 | configList->showRange = b; | ||
990 | configList->reinit(); | ||
991 | } | ||
992 | |||
993 | void ConfigView::setShowData(bool b) | ||
994 | { | ||
995 | if (configList->showData == b) | ||
996 | return; | ||
997 | configList->showData = b; | ||
998 | configList->reinit(); | ||
999 | } | ||
1000 | |||
1001 | /* | ||
1002 | * ask for saving configuration before quitting | ||
1003 | * TODO ask only when something changed | ||
1004 | */ | ||
1005 | void ConfigView::closeEvent(QCloseEvent* e) | ||
1006 | { | ||
1007 | if (!sym_change_count) { | ||
1008 | e->accept(); | ||
1009 | return; | ||
1010 | } | ||
1011 | QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning, | ||
1012 | QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); | ||
1013 | mb.setButtonText(QMessageBox::Yes, "&Save Changes"); | ||
1014 | mb.setButtonText(QMessageBox::No, "&Discard Changes"); | ||
1015 | mb.setButtonText(QMessageBox::Cancel, "Cancel Exit"); | ||
1016 | switch (mb.exec()) { | ||
1017 | case QMessageBox::Yes: | ||
1018 | conf_write(NULL); | ||
1019 | case QMessageBox::No: | ||
1020 | e->accept(); | ||
1021 | break; | ||
1022 | case QMessageBox::Cancel: | ||
1023 | e->ignore(); | ||
1024 | break; | ||
1025 | } | ||
1026 | } | ||
1027 | |||
1028 | void fixup_rootmenu(struct menu *menu) | ||
1029 | { | ||
1030 | struct menu *child; | ||
1031 | |||
1032 | if (!menu->prompt || menu->prompt->type != P_MENU) | ||
1033 | return; | ||
1034 | menu->prompt->type = P_ROOTMENU; | ||
1035 | for (child = menu->list; child; child = child->next) | ||
1036 | fixup_rootmenu(child); | ||
1037 | } | ||
1038 | |||
1039 | int main(int ac, char** av) | ||
1040 | { | ||
1041 | ConfigView* v; | ||
1042 | const char *name; | ||
1043 | |||
1044 | #ifndef LKC_DIRECT_LINK | ||
1045 | kconfig_load(); | ||
1046 | #endif | ||
1047 | |||
1048 | configApp = new QApplication(ac, av); | ||
1049 | if (ac > 1 && av[1][0] == '-') { | ||
1050 | switch (av[1][1]) { | ||
1051 | case 'a': | ||
1052 | //showAll = 1; | ||
1053 | break; | ||
1054 | case 'h': | ||
1055 | case '?': | ||
1056 | printf("%s <config>\n", av[0]); | ||
1057 | exit(0); | ||
1058 | } | ||
1059 | name = av[2]; | ||
1060 | } else | ||
1061 | name = av[1]; | ||
1062 | conf_parse(name); | ||
1063 | fixup_rootmenu(&rootmenu); | ||
1064 | conf_read(NULL); | ||
1065 | //zconfdump(stdout); | ||
1066 | v = new ConfigView(); | ||
1067 | |||
1068 | //zconfdump(stdout); | ||
1069 | v->show(); | ||
1070 | configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); | ||
1071 | configApp->exec(); | ||
1072 | return 0; | ||
1073 | } | ||