1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 /* 2 /* 3 * Copyright (C) 2002 Roman Zippel <zippel@lin 3 * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org> 4 * Copyright (C) 2015 Boris Barbulovski <bbarb 4 * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com> 5 */ 5 */ 6 6 7 #include <QAction> 7 #include <QAction> 8 #include <QActionGroup> << 9 #include <QApplication> 8 #include <QApplication> 10 #include <QCloseEvent> 9 #include <QCloseEvent> 11 #include <QDebug> 10 #include <QDebug> >> 11 #include <QDesktopWidget> 12 #include <QFileDialog> 12 #include <QFileDialog> 13 #include <QLabel> 13 #include <QLabel> 14 #include <QLayout> 14 #include <QLayout> 15 #include <QList> 15 #include <QList> 16 #include <QMenu> 16 #include <QMenu> 17 #include <QMenuBar> 17 #include <QMenuBar> 18 #include <QMessageBox> 18 #include <QMessageBox> 19 #include <QRegularExpression> << 20 #include <QScreen> << 21 #include <QToolBar> 19 #include <QToolBar> 22 20 23 #include <stdlib.h> 21 #include <stdlib.h> 24 22 25 #include <xalloc.h> << 26 #include "lkc.h" 23 #include "lkc.h" 27 #include "qconf.h" 24 #include "qconf.h" 28 25 29 #include "images.h" 26 #include "images.h" 30 27 31 28 32 static QApplication *configApp; 29 static QApplication *configApp; 33 static ConfigSettings *configSettings; 30 static ConfigSettings *configSettings; 34 31 35 QAction *ConfigMainWindow::saveAction; 32 QAction *ConfigMainWindow::saveAction; 36 33 37 ConfigSettings::ConfigSettings() 34 ConfigSettings::ConfigSettings() 38 : QSettings("kernel.org", "qconf") 35 : QSettings("kernel.org", "qconf") 39 { 36 { 40 } 37 } 41 38 42 /** 39 /** 43 * Reads a list of integer values from the app 40 * Reads a list of integer values from the application settings. 44 */ 41 */ 45 QList<int> ConfigSettings::readSizes(const QSt 42 QList<int> ConfigSettings::readSizes(const QString& key, bool *ok) 46 { 43 { 47 QList<int> result; 44 QList<int> result; 48 45 49 if (contains(key)) 46 if (contains(key)) 50 { 47 { 51 QStringList entryList = value( 48 QStringList entryList = value(key).toStringList(); 52 QStringList::Iterator it; 49 QStringList::Iterator it; 53 50 54 for (it = entryList.begin(); i 51 for (it = entryList.begin(); it != entryList.end(); ++it) 55 result.push_back((*it) 52 result.push_back((*it).toInt()); 56 53 57 *ok = true; 54 *ok = true; 58 } 55 } 59 else 56 else 60 *ok = false; 57 *ok = false; 61 58 62 return result; 59 return result; 63 } 60 } 64 61 65 /** 62 /** 66 * Writes a list of integer values to the appl 63 * Writes a list of integer values to the application settings. 67 */ 64 */ 68 bool ConfigSettings::writeSizes(const QString& 65 bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value) 69 { 66 { 70 QStringList stringList; 67 QStringList stringList; 71 QList<int>::ConstIterator it; 68 QList<int>::ConstIterator it; 72 69 73 for (it = value.begin(); it != value.e 70 for (it = value.begin(); it != value.end(); ++it) 74 stringList.push_back(QString:: 71 stringList.push_back(QString::number(*it)); 75 setValue(key, stringList); 72 setValue(key, stringList); 76 73 77 return true; 74 return true; 78 } 75 } 79 76 80 QIcon ConfigItem::symbolYesIcon; 77 QIcon ConfigItem::symbolYesIcon; 81 QIcon ConfigItem::symbolModIcon; 78 QIcon ConfigItem::symbolModIcon; 82 QIcon ConfigItem::symbolNoIcon; 79 QIcon ConfigItem::symbolNoIcon; 83 QIcon ConfigItem::choiceYesIcon; 80 QIcon ConfigItem::choiceYesIcon; 84 QIcon ConfigItem::choiceNoIcon; 81 QIcon ConfigItem::choiceNoIcon; 85 QIcon ConfigItem::menuIcon; 82 QIcon ConfigItem::menuIcon; 86 QIcon ConfigItem::menubackIcon; 83 QIcon ConfigItem::menubackIcon; 87 84 88 /* 85 /* 89 * update the displayed of a menu entry 86 * update the displayed of a menu entry 90 */ 87 */ 91 void ConfigItem::updateMenu(void) 88 void ConfigItem::updateMenu(void) 92 { 89 { 93 ConfigList* list; 90 ConfigList* list; 94 struct symbol* sym; 91 struct symbol* sym; 95 struct property *prop; 92 struct property *prop; 96 QString prompt; 93 QString prompt; 97 int type; 94 int type; 98 tristate expr; 95 tristate expr; 99 96 100 list = listView(); 97 list = listView(); 101 if (goParent) { 98 if (goParent) { 102 setIcon(promptColIdx, menuback 99 setIcon(promptColIdx, menubackIcon); 103 prompt = ".."; 100 prompt = ".."; 104 goto set_prompt; 101 goto set_prompt; 105 } 102 } 106 103 107 sym = menu->sym; 104 sym = menu->sym; 108 prop = menu->prompt; 105 prop = menu->prompt; 109 prompt = menu_get_prompt(menu); 106 prompt = menu_get_prompt(menu); 110 107 111 if (prop) switch (prop->type) { 108 if (prop) switch (prop->type) { 112 case P_MENU: 109 case P_MENU: 113 if (list->mode == singleMode | 110 if (list->mode == singleMode || list->mode == symbolMode) { 114 /* a menuconfig entry 111 /* a menuconfig entry is displayed differently 115 * depending whether i 112 * depending whether it's at the view root or a child. 116 */ 113 */ 117 if (sym && list->rootE 114 if (sym && list->rootEntry == menu) 118 break; 115 break; 119 setIcon(promptColIdx, 116 setIcon(promptColIdx, menuIcon); 120 } else { 117 } else { 121 if (sym) 118 if (sym) 122 break; 119 break; 123 setIcon(promptColIdx, 120 setIcon(promptColIdx, QIcon()); 124 } 121 } 125 goto set_prompt; 122 goto set_prompt; 126 case P_COMMENT: 123 case P_COMMENT: 127 setIcon(promptColIdx, QIcon()) 124 setIcon(promptColIdx, QIcon()); 128 prompt = "*** " + prompt + " * 125 prompt = "*** " + prompt + " ***"; 129 goto set_prompt; 126 goto set_prompt; 130 default: 127 default: 131 ; 128 ; 132 } 129 } 133 if (!sym) 130 if (!sym) 134 goto set_prompt; 131 goto set_prompt; 135 132 136 setText(nameColIdx, sym->name); 133 setText(nameColIdx, sym->name); 137 134 138 type = sym_get_type(sym); 135 type = sym_get_type(sym); 139 switch (type) { 136 switch (type) { 140 case S_BOOLEAN: 137 case S_BOOLEAN: 141 case S_TRISTATE: 138 case S_TRISTATE: 142 char ch; 139 char ch; 143 140 144 if (!sym_is_changeable(sym) && 141 if (!sym_is_changeable(sym) && list->optMode == normalOpt) { 145 setIcon(promptColIdx, 142 setIcon(promptColIdx, QIcon()); 146 break; 143 break; 147 } 144 } 148 expr = sym_get_tristate_value( 145 expr = sym_get_tristate_value(sym); 149 switch (expr) { 146 switch (expr) { 150 case yes: 147 case yes: 151 if (sym_is_choice_valu !! 148 if (sym_is_choice_value(sym) && type == S_BOOLEAN) 152 setIcon(prompt 149 setIcon(promptColIdx, choiceYesIcon); 153 else 150 else 154 setIcon(prompt 151 setIcon(promptColIdx, symbolYesIcon); 155 ch = 'Y'; 152 ch = 'Y'; 156 break; 153 break; 157 case mod: 154 case mod: 158 setIcon(promptColIdx, 155 setIcon(promptColIdx, symbolModIcon); 159 ch = 'M'; 156 ch = 'M'; 160 break; 157 break; 161 default: 158 default: 162 if (sym_is_choice_valu 159 if (sym_is_choice_value(sym) && type == S_BOOLEAN) 163 setIcon(prompt 160 setIcon(promptColIdx, choiceNoIcon); 164 else 161 else 165 setIcon(prompt 162 setIcon(promptColIdx, symbolNoIcon); 166 ch = 'N'; 163 ch = 'N'; 167 break; 164 break; 168 } 165 } 169 166 170 setText(dataColIdx, QChar(ch)) 167 setText(dataColIdx, QChar(ch)); 171 break; 168 break; 172 case S_INT: 169 case S_INT: 173 case S_HEX: 170 case S_HEX: 174 case S_STRING: 171 case S_STRING: 175 setText(dataColIdx, sym_get_st 172 setText(dataColIdx, sym_get_string_value(sym)); 176 break; 173 break; 177 } 174 } 178 if (!sym_has_value(sym) && visible) 175 if (!sym_has_value(sym) && visible) 179 prompt += " (NEW)"; 176 prompt += " (NEW)"; 180 set_prompt: 177 set_prompt: 181 setText(promptColIdx, prompt); 178 setText(promptColIdx, prompt); 182 } 179 } 183 180 184 void ConfigItem::testUpdateMenu(bool v) 181 void ConfigItem::testUpdateMenu(bool v) 185 { 182 { 186 ConfigItem* i; 183 ConfigItem* i; 187 184 188 visible = v; 185 visible = v; 189 if (!menu) 186 if (!menu) 190 return; 187 return; 191 188 192 sym_calc_value(menu->sym); 189 sym_calc_value(menu->sym); 193 if (menu->flags & MENU_CHANGED) { 190 if (menu->flags & MENU_CHANGED) { 194 /* the menu entry changed, so 191 /* the menu entry changed, so update all list items */ 195 menu->flags &= ~MENU_CHANGED; 192 menu->flags &= ~MENU_CHANGED; 196 for (i = (ConfigItem*)menu->da 193 for (i = (ConfigItem*)menu->data; i; i = i->nextItem) 197 i->updateMenu(); 194 i->updateMenu(); 198 } else if (listView()->updateAll) 195 } else if (listView()->updateAll) 199 updateMenu(); 196 updateMenu(); 200 } 197 } 201 198 202 199 203 /* 200 /* 204 * construct a menu entry 201 * construct a menu entry 205 */ 202 */ 206 void ConfigItem::init(void) 203 void ConfigItem::init(void) 207 { 204 { 208 if (menu) { 205 if (menu) { 209 ConfigList* list = listView(); 206 ConfigList* list = listView(); 210 nextItem = (ConfigItem*)menu-> 207 nextItem = (ConfigItem*)menu->data; 211 menu->data = this; 208 menu->data = this; 212 209 213 if (list->mode != fullMode) 210 if (list->mode != fullMode) 214 setExpanded(true); 211 setExpanded(true); 215 sym_calc_value(menu->sym); 212 sym_calc_value(menu->sym); 216 213 217 if (menu->sym) { 214 if (menu->sym) { 218 enum symbol_type type 215 enum symbol_type type = menu->sym->type; 219 216 220 // Allow to edit "int" 217 // Allow to edit "int", "hex", and "string" in-place in 221 // the data column. Un 218 // the data column. Unfortunately, you cannot specify 222 // the flags per colum 219 // the flags per column. Set ItemIsEditable for all 223 // columns here, and c 220 // columns here, and check the column in createEditor(). 224 if (type == S_INT || t 221 if (type == S_INT || type == S_HEX || type == S_STRING) 225 setFlags(flags 222 setFlags(flags() | Qt::ItemIsEditable); 226 } 223 } 227 } 224 } 228 updateMenu(); 225 updateMenu(); 229 } 226 } 230 227 231 /* 228 /* 232 * destruct a menu entry 229 * destruct a menu entry 233 */ 230 */ 234 ConfigItem::~ConfigItem(void) 231 ConfigItem::~ConfigItem(void) 235 { 232 { 236 if (menu) { 233 if (menu) { 237 ConfigItem** ip = (ConfigItem* 234 ConfigItem** ip = (ConfigItem**)&menu->data; 238 for (; *ip; ip = &(*ip)->nextI 235 for (; *ip; ip = &(*ip)->nextItem) { 239 if (*ip == this) { 236 if (*ip == this) { 240 *ip = nextItem 237 *ip = nextItem; 241 break; 238 break; 242 } 239 } 243 } 240 } 244 } 241 } 245 } 242 } 246 243 247 QWidget *ConfigItemDelegate::createEditor(QWid 244 QWidget *ConfigItemDelegate::createEditor(QWidget *parent, 248 cons 245 const QStyleOptionViewItem &option, 249 cons 246 const QModelIndex &index) const 250 { 247 { 251 ConfigItem *item; 248 ConfigItem *item; 252 249 253 // Only the data column is editable 250 // Only the data column is editable 254 if (index.column() != dataColIdx) 251 if (index.column() != dataColIdx) 255 return nullptr; 252 return nullptr; 256 253 257 // You cannot edit invisible menus 254 // You cannot edit invisible menus 258 item = static_cast<ConfigItem *>(index 255 item = static_cast<ConfigItem *>(index.internalPointer()); 259 if (!item || !item->menu || !menu_is_v 256 if (!item || !item->menu || !menu_is_visible(item->menu)) 260 return nullptr; 257 return nullptr; 261 258 262 return QStyledItemDelegate::createEdit 259 return QStyledItemDelegate::createEditor(parent, option, index); 263 } 260 } 264 261 265 void ConfigItemDelegate::setModelData(QWidget 262 void ConfigItemDelegate::setModelData(QWidget *editor, 266 QAbstrac 263 QAbstractItemModel *model, 267 const QM 264 const QModelIndex &index) const 268 { 265 { 269 QLineEdit *lineEdit; 266 QLineEdit *lineEdit; 270 ConfigItem *item; 267 ConfigItem *item; 271 struct symbol *sym; 268 struct symbol *sym; 272 bool success; 269 bool success; 273 270 274 lineEdit = qobject_cast<QLineEdit *>(e 271 lineEdit = qobject_cast<QLineEdit *>(editor); 275 // If this is not a QLineEdit, use the 272 // If this is not a QLineEdit, use the parent's default. 276 // (does this happen?) 273 // (does this happen?) 277 if (!lineEdit) 274 if (!lineEdit) 278 goto parent; 275 goto parent; 279 276 280 item = static_cast<ConfigItem *>(index 277 item = static_cast<ConfigItem *>(index.internalPointer()); 281 if (!item || !item->menu) 278 if (!item || !item->menu) 282 goto parent; 279 goto parent; 283 280 284 sym = item->menu->sym; 281 sym = item->menu->sym; 285 if (!sym) 282 if (!sym) 286 goto parent; 283 goto parent; 287 284 288 success = sym_set_string_value(sym, li 285 success = sym_set_string_value(sym, lineEdit->text().toUtf8().data()); 289 if (success) { 286 if (success) { 290 ConfigList::updateListForAll() 287 ConfigList::updateListForAll(); 291 } else { 288 } else { 292 QMessageBox::information(edito 289 QMessageBox::information(editor, "qconf", 293 "Cannot set the data ( 290 "Cannot set the data (maybe due to out of range).\n" 294 "Setting the old value 291 "Setting the old value."); 295 lineEdit->setText(sym_get_stri 292 lineEdit->setText(sym_get_string_value(sym)); 296 } 293 } 297 294 298 parent: 295 parent: 299 QStyledItemDelegate::setModelData(edit 296 QStyledItemDelegate::setModelData(editor, model, index); 300 } 297 } 301 298 302 ConfigList::ConfigList(QWidget *parent, const 299 ConfigList::ConfigList(QWidget *parent, const char *name) 303 : QTreeWidget(parent), 300 : QTreeWidget(parent), 304 updateAll(false), 301 updateAll(false), 305 showName(false), mode(singleMode), o 302 showName(false), mode(singleMode), optMode(normalOpt), 306 rootEntry(0), headerPopup(0) 303 rootEntry(0), headerPopup(0) 307 { 304 { 308 setObjectName(name); 305 setObjectName(name); 309 setSortingEnabled(false); 306 setSortingEnabled(false); 310 setRootIsDecorated(true); 307 setRootIsDecorated(true); 311 308 312 setVerticalScrollMode(ScrollPerPixel); 309 setVerticalScrollMode(ScrollPerPixel); 313 setHorizontalScrollMode(ScrollPerPixel 310 setHorizontalScrollMode(ScrollPerPixel); 314 311 315 setHeaderLabels(QStringList() << "Opti 312 setHeaderLabels(QStringList() << "Option" << "Name" << "Value"); 316 313 317 connect(this, &ConfigList::itemSelecti 314 connect(this, &ConfigList::itemSelectionChanged, 318 this, &ConfigList::updateSelec 315 this, &ConfigList::updateSelection); 319 316 320 if (name) { 317 if (name) { 321 configSettings->beginGroup(nam 318 configSettings->beginGroup(name); 322 showName = configSettings->val 319 showName = configSettings->value("/showName", false).toBool(); 323 optMode = (enum optionMode)con 320 optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt(); 324 configSettings->endGroup(); 321 configSettings->endGroup(); 325 connect(configApp, &QApplicati 322 connect(configApp, &QApplication::aboutToQuit, 326 this, &ConfigList::sav 323 this, &ConfigList::saveSettings); 327 } 324 } 328 325 329 showColumn(promptColIdx); 326 showColumn(promptColIdx); 330 327 331 setItemDelegate(new ConfigItemDelegate 328 setItemDelegate(new ConfigItemDelegate(this)); 332 329 333 allLists.append(this); 330 allLists.append(this); 334 331 335 reinit(); 332 reinit(); 336 } 333 } 337 334 338 ConfigList::~ConfigList() 335 ConfigList::~ConfigList() 339 { 336 { 340 allLists.removeOne(this); 337 allLists.removeOne(this); 341 } 338 } 342 339 343 bool ConfigList::menuSkip(struct menu *menu) 340 bool ConfigList::menuSkip(struct menu *menu) 344 { 341 { 345 if (optMode == normalOpt && menu_is_vi 342 if (optMode == normalOpt && menu_is_visible(menu)) 346 return false; 343 return false; 347 if (optMode == promptOpt && menu_has_p 344 if (optMode == promptOpt && menu_has_prompt(menu)) 348 return false; 345 return false; 349 if (optMode == allOpt) 346 if (optMode == allOpt) 350 return false; 347 return false; 351 return true; 348 return true; 352 } 349 } 353 350 354 void ConfigList::reinit(void) 351 void ConfigList::reinit(void) 355 { 352 { 356 hideColumn(nameColIdx); 353 hideColumn(nameColIdx); 357 354 358 if (showName) 355 if (showName) 359 showColumn(nameColIdx); 356 showColumn(nameColIdx); 360 357 361 updateListAll(); 358 updateListAll(); 362 } 359 } 363 360 364 void ConfigList::setOptionMode(QAction *action 361 void ConfigList::setOptionMode(QAction *action) 365 { 362 { 366 if (action == showNormalAction) 363 if (action == showNormalAction) 367 optMode = normalOpt; 364 optMode = normalOpt; 368 else if (action == showAllAction) 365 else if (action == showAllAction) 369 optMode = allOpt; 366 optMode = allOpt; 370 else 367 else 371 optMode = promptOpt; 368 optMode = promptOpt; 372 369 373 updateListAll(); 370 updateListAll(); 374 } 371 } 375 372 376 void ConfigList::saveSettings(void) 373 void ConfigList::saveSettings(void) 377 { 374 { 378 if (!objectName().isEmpty()) { 375 if (!objectName().isEmpty()) { 379 configSettings->beginGroup(obj 376 configSettings->beginGroup(objectName()); 380 configSettings->setValue("/sho 377 configSettings->setValue("/showName", showName); 381 configSettings->setValue("/opt 378 configSettings->setValue("/optionMode", (int)optMode); 382 configSettings->endGroup(); 379 configSettings->endGroup(); 383 } 380 } 384 } 381 } 385 382 386 ConfigItem* ConfigList::findConfigItem(struct 383 ConfigItem* ConfigList::findConfigItem(struct menu *menu) 387 { 384 { 388 ConfigItem* item = (ConfigItem*)menu-> 385 ConfigItem* item = (ConfigItem*)menu->data; 389 386 390 for (; item; item = item->nextItem) { 387 for (; item; item = item->nextItem) { 391 if (this == item->listView()) 388 if (this == item->listView()) 392 break; 389 break; 393 } 390 } 394 391 395 return item; 392 return item; 396 } 393 } 397 394 398 void ConfigList::updateSelection(void) 395 void ConfigList::updateSelection(void) 399 { 396 { 400 struct menu *menu; 397 struct menu *menu; 401 enum prop_type type; 398 enum prop_type type; 402 399 403 if (selectedItems().count() == 0) 400 if (selectedItems().count() == 0) 404 return; 401 return; 405 402 406 ConfigItem* item = (ConfigItem*)select 403 ConfigItem* item = (ConfigItem*)selectedItems().first(); 407 if (!item) 404 if (!item) 408 return; 405 return; 409 406 410 menu = item->menu; 407 menu = item->menu; 411 emit menuChanged(menu); 408 emit menuChanged(menu); 412 if (!menu) 409 if (!menu) 413 return; 410 return; 414 type = menu->prompt ? menu->prompt->ty 411 type = menu->prompt ? menu->prompt->type : P_UNKNOWN; 415 if (mode == menuMode && type == P_MENU 412 if (mode == menuMode && type == P_MENU) 416 emit menuSelected(menu); 413 emit menuSelected(menu); 417 } 414 } 418 415 419 void ConfigList::updateList() 416 void ConfigList::updateList() 420 { 417 { 421 ConfigItem* last = 0; 418 ConfigItem* last = 0; 422 ConfigItem *item; 419 ConfigItem *item; 423 420 424 if (!rootEntry) { 421 if (!rootEntry) { 425 if (mode != listMode) 422 if (mode != listMode) 426 goto update; 423 goto update; 427 QTreeWidgetItemIterator it(thi 424 QTreeWidgetItemIterator it(this); 428 425 429 while (*it) { 426 while (*it) { 430 item = (ConfigItem*)(* 427 item = (ConfigItem*)(*it); 431 if (!item->menu) 428 if (!item->menu) 432 continue; 429 continue; 433 item->testUpdateMenu(m 430 item->testUpdateMenu(menu_is_visible(item->menu)); 434 431 435 ++it; 432 ++it; 436 } 433 } 437 return; 434 return; 438 } 435 } 439 436 440 if (rootEntry != &rootmenu && (mode == 437 if (rootEntry != &rootmenu && (mode == singleMode || 441 (mode == symbolMode && rootEntry-> 438 (mode == symbolMode && rootEntry->parent != &rootmenu))) { 442 item = (ConfigItem *)topLevelI 439 item = (ConfigItem *)topLevelItem(0); 443 if (!item) 440 if (!item) 444 item = new ConfigItem( 441 item = new ConfigItem(this, 0, true); 445 last = item; 442 last = item; 446 } 443 } 447 if ((mode == singleMode || (mode == sy 444 if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) && 448 rootEntry->sym && rootEntry->promp 445 rootEntry->sym && rootEntry->prompt) { 449 item = last ? last->nextSiblin 446 item = last ? last->nextSibling() : nullptr; 450 if (!item) 447 if (!item) 451 item = new ConfigItem( 448 item = new ConfigItem(this, last, rootEntry, true); 452 else 449 else 453 item->testUpdateMenu(t 450 item->testUpdateMenu(true); 454 451 455 updateMenuList(item, rootEntry 452 updateMenuList(item, rootEntry); 456 update(); 453 update(); 457 resizeColumnToContents(0); 454 resizeColumnToContents(0); 458 return; 455 return; 459 } 456 } 460 update: 457 update: 461 updateMenuList(rootEntry); 458 updateMenuList(rootEntry); 462 update(); 459 update(); 463 resizeColumnToContents(0); 460 resizeColumnToContents(0); 464 } 461 } 465 462 466 void ConfigList::updateListForAll() 463 void ConfigList::updateListForAll() 467 { 464 { 468 QListIterator<ConfigList *> it(allList 465 QListIterator<ConfigList *> it(allLists); 469 466 470 while (it.hasNext()) { 467 while (it.hasNext()) { 471 ConfigList *list = it.next(); 468 ConfigList *list = it.next(); 472 469 473 list->updateList(); 470 list->updateList(); 474 } 471 } 475 } 472 } 476 473 477 void ConfigList::updateListAllForAll() 474 void ConfigList::updateListAllForAll() 478 { 475 { 479 QListIterator<ConfigList *> it(allList 476 QListIterator<ConfigList *> it(allLists); 480 477 481 while (it.hasNext()) { 478 while (it.hasNext()) { 482 ConfigList *list = it.next(); 479 ConfigList *list = it.next(); 483 480 484 list->updateList(); 481 list->updateList(); 485 } 482 } 486 } 483 } 487 484 488 void ConfigList::setValue(ConfigItem* item, tr 485 void ConfigList::setValue(ConfigItem* item, tristate val) 489 { 486 { 490 struct symbol* sym; 487 struct symbol* sym; 491 int type; 488 int type; 492 tristate oldval; 489 tristate oldval; 493 490 494 sym = item->menu ? item->menu->sym : 0 491 sym = item->menu ? item->menu->sym : 0; 495 if (!sym) 492 if (!sym) 496 return; 493 return; 497 494 498 type = sym_get_type(sym); 495 type = sym_get_type(sym); 499 switch (type) { 496 switch (type) { 500 case S_BOOLEAN: 497 case S_BOOLEAN: 501 case S_TRISTATE: 498 case S_TRISTATE: 502 oldval = sym_get_tristate_valu 499 oldval = sym_get_tristate_value(sym); 503 500 504 if (!sym_set_tristate_value(sy 501 if (!sym_set_tristate_value(sym, val)) 505 return; 502 return; 506 if (oldval == no && item->menu 503 if (oldval == no && item->menu->list) 507 item->setExpanded(true 504 item->setExpanded(true); 508 ConfigList::updateListForAll() 505 ConfigList::updateListForAll(); 509 break; 506 break; 510 } 507 } 511 } 508 } 512 509 513 void ConfigList::changeValue(ConfigItem* item) 510 void ConfigList::changeValue(ConfigItem* item) 514 { 511 { 515 struct symbol* sym; 512 struct symbol* sym; 516 struct menu* menu; 513 struct menu* menu; 517 int type, oldexpr, newexpr; 514 int type, oldexpr, newexpr; 518 515 519 menu = item->menu; 516 menu = item->menu; 520 if (!menu) 517 if (!menu) 521 return; 518 return; 522 sym = menu->sym; 519 sym = menu->sym; 523 if (!sym) { 520 if (!sym) { 524 if (item->menu->list) 521 if (item->menu->list) 525 item->setExpanded(!ite 522 item->setExpanded(!item->isExpanded()); 526 return; 523 return; 527 } 524 } 528 525 529 type = sym_get_type(sym); 526 type = sym_get_type(sym); 530 switch (type) { 527 switch (type) { 531 case S_BOOLEAN: 528 case S_BOOLEAN: 532 case S_TRISTATE: 529 case S_TRISTATE: 533 oldexpr = sym_get_tristate_val 530 oldexpr = sym_get_tristate_value(sym); 534 newexpr = sym_toggle_tristate_ 531 newexpr = sym_toggle_tristate_value(sym); 535 if (item->menu->list) { 532 if (item->menu->list) { 536 if (oldexpr == newexpr 533 if (oldexpr == newexpr) 537 item->setExpan 534 item->setExpanded(!item->isExpanded()); 538 else if (oldexpr == no 535 else if (oldexpr == no) 539 item->setExpan 536 item->setExpanded(true); 540 } 537 } 541 if (oldexpr != newexpr) 538 if (oldexpr != newexpr) 542 ConfigList::updateList 539 ConfigList::updateListForAll(); 543 break; 540 break; 544 default: 541 default: 545 break; 542 break; 546 } 543 } 547 } 544 } 548 545 549 void ConfigList::setRootMenu(struct menu *menu 546 void ConfigList::setRootMenu(struct menu *menu) 550 { 547 { 551 enum prop_type type; 548 enum prop_type type; 552 549 553 if (rootEntry == menu) 550 if (rootEntry == menu) 554 return; 551 return; 555 type = menu && menu->prompt ? menu->pr 552 type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN; 556 if (type != P_MENU) 553 if (type != P_MENU) 557 return; 554 return; 558 updateMenuList(0); 555 updateMenuList(0); 559 rootEntry = menu; 556 rootEntry = menu; 560 updateListAll(); 557 updateListAll(); 561 if (currentItem()) { 558 if (currentItem()) { 562 setSelected(currentItem(), has 559 setSelected(currentItem(), hasFocus()); 563 scrollToItem(currentItem()); 560 scrollToItem(currentItem()); 564 } 561 } 565 } 562 } 566 563 567 void ConfigList::setParentMenu(void) 564 void ConfigList::setParentMenu(void) 568 { 565 { 569 ConfigItem* item; 566 ConfigItem* item; 570 struct menu *oldroot; 567 struct menu *oldroot; 571 568 572 oldroot = rootEntry; 569 oldroot = rootEntry; 573 if (rootEntry == &rootmenu) 570 if (rootEntry == &rootmenu) 574 return; 571 return; 575 setRootMenu(menu_get_parent_menu(rootE 572 setRootMenu(menu_get_parent_menu(rootEntry->parent)); 576 573 577 QTreeWidgetItemIterator it(this); 574 QTreeWidgetItemIterator it(this); 578 while (*it) { 575 while (*it) { 579 item = (ConfigItem *)(*it); 576 item = (ConfigItem *)(*it); 580 if (item->menu == oldroot) { 577 if (item->menu == oldroot) { 581 setCurrentItem(item); 578 setCurrentItem(item); 582 scrollToItem(item); 579 scrollToItem(item); 583 break; 580 break; 584 } 581 } 585 582 586 ++it; 583 ++it; 587 } 584 } 588 } 585 } 589 586 590 /* 587 /* 591 * update all the children of a menu entry 588 * update all the children of a menu entry 592 * removes/adds the entries from the parent 589 * removes/adds the entries from the parent widget as necessary 593 * 590 * 594 * parent: either the menu list widget or a me 591 * parent: either the menu list widget or a menu entry widget 595 * menu: entry to be updated 592 * menu: entry to be updated 596 */ 593 */ 597 void ConfigList::updateMenuList(ConfigItem *pa 594 void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu) 598 { 595 { 599 struct menu* child; 596 struct menu* child; 600 ConfigItem* item; 597 ConfigItem* item; 601 ConfigItem* last; 598 ConfigItem* last; 602 bool visible; 599 bool visible; 603 enum prop_type type; 600 enum prop_type type; 604 601 605 if (!menu) { 602 if (!menu) { 606 while (parent->childCount() > 603 while (parent->childCount() > 0) 607 { 604 { 608 delete parent->takeChi 605 delete parent->takeChild(0); 609 } 606 } 610 607 611 return; 608 return; 612 } 609 } 613 610 614 last = parent->firstChild(); 611 last = parent->firstChild(); 615 if (last && !last->goParent) 612 if (last && !last->goParent) 616 last = 0; 613 last = 0; 617 for (child = menu->list; child; child 614 for (child = menu->list; child; child = child->next) { 618 item = last ? last->nextSiblin 615 item = last ? last->nextSibling() : parent->firstChild(); 619 type = child->prompt ? child-> 616 type = child->prompt ? child->prompt->type : P_UNKNOWN; 620 617 621 switch (mode) { 618 switch (mode) { 622 case menuMode: 619 case menuMode: 623 if (!(child->flags & M 620 if (!(child->flags & MENU_ROOT)) 624 goto hide; 621 goto hide; 625 break; 622 break; 626 case symbolMode: 623 case symbolMode: 627 if (child->flags & MEN 624 if (child->flags & MENU_ROOT) 628 goto hide; 625 goto hide; 629 break; 626 break; 630 default: 627 default: 631 break; 628 break; 632 } 629 } 633 630 634 visible = menu_is_visible(chil 631 visible = menu_is_visible(child); 635 if (!menuSkip(child)) { 632 if (!menuSkip(child)) { 636 if (!child->sym && !ch 633 if (!child->sym && !child->list && !child->prompt) 637 continue; 634 continue; 638 if (!item || item->men 635 if (!item || item->menu != child) 639 item = new Con 636 item = new ConfigItem(parent, last, child, visible); 640 else 637 else 641 item->testUpda 638 item->testUpdateMenu(visible); 642 639 643 if (mode == fullMode | 640 if (mode == fullMode || mode == menuMode || type != P_MENU) 644 updateMenuList 641 updateMenuList(item, child); 645 else 642 else 646 updateMenuList 643 updateMenuList(item, 0); 647 last = item; 644 last = item; 648 continue; 645 continue; 649 } 646 } 650 hide: 647 hide: 651 if (item && item->menu == chil 648 if (item && item->menu == child) { 652 last = parent->firstCh 649 last = parent->firstChild(); 653 if (last == item) 650 if (last == item) 654 last = 0; 651 last = 0; 655 else while (last->next 652 else while (last->nextSibling() != item) 656 last = last->n 653 last = last->nextSibling(); 657 delete item; 654 delete item; 658 } 655 } 659 } 656 } 660 } 657 } 661 658 662 void ConfigList::updateMenuList(struct menu *m 659 void ConfigList::updateMenuList(struct menu *menu) 663 { 660 { 664 struct menu* child; 661 struct menu* child; 665 ConfigItem* item; 662 ConfigItem* item; 666 ConfigItem* last; 663 ConfigItem* last; 667 bool visible; 664 bool visible; 668 enum prop_type type; 665 enum prop_type type; 669 666 670 if (!menu) { 667 if (!menu) { 671 while (topLevelItemCount() > 0 668 while (topLevelItemCount() > 0) 672 { 669 { 673 delete takeTopLevelIte 670 delete takeTopLevelItem(0); 674 } 671 } 675 672 676 return; 673 return; 677 } 674 } 678 675 679 last = (ConfigItem *)topLevelItem(0); 676 last = (ConfigItem *)topLevelItem(0); 680 if (last && !last->goParent) 677 if (last && !last->goParent) 681 last = 0; 678 last = 0; 682 for (child = menu->list; child; child 679 for (child = menu->list; child; child = child->next) { 683 item = last ? last->nextSiblin 680 item = last ? last->nextSibling() : (ConfigItem *)topLevelItem(0); 684 type = child->prompt ? child-> 681 type = child->prompt ? child->prompt->type : P_UNKNOWN; 685 682 686 switch (mode) { 683 switch (mode) { 687 case menuMode: 684 case menuMode: 688 if (!(child->flags & M 685 if (!(child->flags & MENU_ROOT)) 689 goto hide; 686 goto hide; 690 break; 687 break; 691 case symbolMode: 688 case symbolMode: 692 if (child->flags & MEN 689 if (child->flags & MENU_ROOT) 693 goto hide; 690 goto hide; 694 break; 691 break; 695 default: 692 default: 696 break; 693 break; 697 } 694 } 698 695 699 visible = menu_is_visible(chil 696 visible = menu_is_visible(child); 700 if (!menuSkip(child)) { 697 if (!menuSkip(child)) { 701 if (!child->sym && !ch 698 if (!child->sym && !child->list && !child->prompt) 702 continue; 699 continue; 703 if (!item || item->men 700 if (!item || item->menu != child) 704 item = new Con 701 item = new ConfigItem(this, last, child, visible); 705 else 702 else 706 item->testUpda 703 item->testUpdateMenu(visible); 707 704 708 if (mode == fullMode | 705 if (mode == fullMode || mode == menuMode || type != P_MENU) 709 updateMenuList 706 updateMenuList(item, child); 710 else 707 else 711 updateMenuList 708 updateMenuList(item, 0); 712 last = item; 709 last = item; 713 continue; 710 continue; 714 } 711 } 715 hide: 712 hide: 716 if (item && item->menu == chil 713 if (item && item->menu == child) { 717 last = (ConfigItem *)t 714 last = (ConfigItem *)topLevelItem(0); 718 if (last == item) 715 if (last == item) 719 last = 0; 716 last = 0; 720 else while (last->next 717 else while (last->nextSibling() != item) 721 last = last->n 718 last = last->nextSibling(); 722 delete item; 719 delete item; 723 } 720 } 724 } 721 } 725 } 722 } 726 723 727 void ConfigList::keyPressEvent(QKeyEvent* ev) 724 void ConfigList::keyPressEvent(QKeyEvent* ev) 728 { 725 { 729 QTreeWidgetItem* i = currentItem(); 726 QTreeWidgetItem* i = currentItem(); 730 ConfigItem* item; 727 ConfigItem* item; 731 struct menu *menu; 728 struct menu *menu; 732 enum prop_type type; 729 enum prop_type type; 733 730 734 if (ev->key() == Qt::Key_Escape && mod 731 if (ev->key() == Qt::Key_Escape && mode != fullMode && mode != listMode) { 735 emit parentSelected(); 732 emit parentSelected(); 736 ev->accept(); 733 ev->accept(); 737 return; 734 return; 738 } 735 } 739 736 740 if (!i) { 737 if (!i) { 741 Parent::keyPressEvent(ev); 738 Parent::keyPressEvent(ev); 742 return; 739 return; 743 } 740 } 744 item = (ConfigItem*)i; 741 item = (ConfigItem*)i; 745 742 746 switch (ev->key()) { 743 switch (ev->key()) { 747 case Qt::Key_Return: 744 case Qt::Key_Return: 748 case Qt::Key_Enter: 745 case Qt::Key_Enter: 749 if (item->goParent) { 746 if (item->goParent) { 750 emit parentSelected(); 747 emit parentSelected(); 751 break; 748 break; 752 } 749 } 753 menu = item->menu; 750 menu = item->menu; 754 if (!menu) 751 if (!menu) 755 break; 752 break; 756 type = menu->prompt ? menu->pr 753 type = menu->prompt ? menu->prompt->type : P_UNKNOWN; 757 if (type == P_MENU && rootEntr 754 if (type == P_MENU && rootEntry != menu && 758 mode != fullMode && mode ! 755 mode != fullMode && mode != menuMode) { 759 if (mode == menuMode) 756 if (mode == menuMode) 760 emit menuSelec 757 emit menuSelected(menu); 761 else 758 else 762 emit itemSelec 759 emit itemSelected(menu); 763 break; 760 break; 764 } 761 } 765 case Qt::Key_Space: 762 case Qt::Key_Space: 766 changeValue(item); 763 changeValue(item); 767 break; 764 break; 768 case Qt::Key_N: 765 case Qt::Key_N: 769 setValue(item, no); 766 setValue(item, no); 770 break; 767 break; 771 case Qt::Key_M: 768 case Qt::Key_M: 772 setValue(item, mod); 769 setValue(item, mod); 773 break; 770 break; 774 case Qt::Key_Y: 771 case Qt::Key_Y: 775 setValue(item, yes); 772 setValue(item, yes); 776 break; 773 break; 777 default: 774 default: 778 Parent::keyPressEvent(ev); 775 Parent::keyPressEvent(ev); 779 return; 776 return; 780 } 777 } 781 ev->accept(); 778 ev->accept(); 782 } 779 } 783 780 784 void ConfigList::mousePressEvent(QMouseEvent* 781 void ConfigList::mousePressEvent(QMouseEvent* e) 785 { 782 { 786 //QPoint p(contentsToViewport(e->pos() 783 //QPoint p(contentsToViewport(e->pos())); 787 //printf("contentsMousePressEvent: %d, 784 //printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y()); 788 Parent::mousePressEvent(e); 785 Parent::mousePressEvent(e); 789 } 786 } 790 787 791 void ConfigList::mouseReleaseEvent(QMouseEvent 788 void ConfigList::mouseReleaseEvent(QMouseEvent* e) 792 { 789 { 793 QPoint p = e->pos(); 790 QPoint p = e->pos(); 794 ConfigItem* item = (ConfigItem*)itemAt 791 ConfigItem* item = (ConfigItem*)itemAt(p); 795 struct menu *menu; 792 struct menu *menu; 796 enum prop_type ptype; 793 enum prop_type ptype; 797 QIcon icon; 794 QIcon icon; 798 int idx, x; 795 int idx, x; 799 796 800 if (!item) 797 if (!item) 801 goto skip; 798 goto skip; 802 799 803 menu = item->menu; 800 menu = item->menu; 804 x = header()->offset() + p.x(); 801 x = header()->offset() + p.x(); 805 idx = header()->logicalIndexAt(x); 802 idx = header()->logicalIndexAt(x); 806 switch (idx) { 803 switch (idx) { 807 case promptColIdx: 804 case promptColIdx: 808 icon = item->icon(promptColIdx 805 icon = item->icon(promptColIdx); 809 if (!icon.isNull()) { 806 if (!icon.isNull()) { 810 int off = header()->se 807 int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly. 811 if (x >= off && x < of 808 if (x >= off && x < off + icon.availableSizes().first().width()) { 812 if (item->goPa 809 if (item->goParent) { 813 emit p 810 emit parentSelected(); 814 break; 811 break; 815 } else if (!me 812 } else if (!menu) 816 break; 813 break; 817 ptype = menu-> 814 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; 818 if (ptype == P 815 if (ptype == P_MENU && rootEntry != menu && 819 mode != fu 816 mode != fullMode && mode != menuMode && 820 mode != li 817 mode != listMode) 821 emit m 818 emit menuSelected(menu); 822 else 819 else 823 change 820 changeValue(item); 824 } 821 } 825 } 822 } 826 break; 823 break; 827 case dataColIdx: 824 case dataColIdx: 828 changeValue(item); 825 changeValue(item); 829 break; 826 break; 830 } 827 } 831 828 832 skip: 829 skip: 833 //printf("contentsMouseReleaseEvent: % 830 //printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y()); 834 Parent::mouseReleaseEvent(e); 831 Parent::mouseReleaseEvent(e); 835 } 832 } 836 833 837 void ConfigList::mouseMoveEvent(QMouseEvent* e 834 void ConfigList::mouseMoveEvent(QMouseEvent* e) 838 { 835 { 839 //QPoint p(contentsToViewport(e->pos() 836 //QPoint p(contentsToViewport(e->pos())); 840 //printf("contentsMouseMoveEvent: %d,% 837 //printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y()); 841 Parent::mouseMoveEvent(e); 838 Parent::mouseMoveEvent(e); 842 } 839 } 843 840 844 void ConfigList::mouseDoubleClickEvent(QMouseE 841 void ConfigList::mouseDoubleClickEvent(QMouseEvent* e) 845 { 842 { 846 QPoint p = e->pos(); 843 QPoint p = e->pos(); 847 ConfigItem* item = (ConfigItem*)itemAt 844 ConfigItem* item = (ConfigItem*)itemAt(p); 848 struct menu *menu; 845 struct menu *menu; 849 enum prop_type ptype; 846 enum prop_type ptype; 850 847 851 if (!item) 848 if (!item) 852 goto skip; 849 goto skip; 853 if (item->goParent) { 850 if (item->goParent) { 854 emit parentSelected(); 851 emit parentSelected(); 855 goto skip; 852 goto skip; 856 } 853 } 857 menu = item->menu; 854 menu = item->menu; 858 if (!menu) 855 if (!menu) 859 goto skip; 856 goto skip; 860 ptype = menu->prompt ? menu->prompt->t 857 ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN; 861 if (ptype == P_MENU && mode != listMod 858 if (ptype == P_MENU && mode != listMode) { 862 if (mode == singleMode) 859 if (mode == singleMode) 863 emit itemSelected(menu 860 emit itemSelected(menu); 864 else if (mode == symbolMode) 861 else if (mode == symbolMode) 865 emit menuSelected(menu 862 emit menuSelected(menu); 866 } else if (menu->sym) 863 } else if (menu->sym) 867 changeValue(item); 864 changeValue(item); 868 865 869 skip: 866 skip: 870 //printf("contentsMouseDoubleClickEven 867 //printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y()); 871 Parent::mouseDoubleClickEvent(e); 868 Parent::mouseDoubleClickEvent(e); 872 } 869 } 873 870 874 void ConfigList::focusInEvent(QFocusEvent *e) 871 void ConfigList::focusInEvent(QFocusEvent *e) 875 { 872 { 876 struct menu *menu = NULL; 873 struct menu *menu = NULL; 877 874 878 Parent::focusInEvent(e); 875 Parent::focusInEvent(e); 879 876 880 ConfigItem* item = (ConfigItem *)curre 877 ConfigItem* item = (ConfigItem *)currentItem(); 881 if (item) { 878 if (item) { 882 setSelected(item, true); 879 setSelected(item, true); 883 menu = item->menu; 880 menu = item->menu; 884 } 881 } 885 emit gotFocus(menu); 882 emit gotFocus(menu); 886 } 883 } 887 884 888 void ConfigList::contextMenuEvent(QContextMenu 885 void ConfigList::contextMenuEvent(QContextMenuEvent *e) 889 { 886 { 890 if (!headerPopup) { 887 if (!headerPopup) { 891 QAction *action; 888 QAction *action; 892 889 893 headerPopup = new QMenu(this); 890 headerPopup = new QMenu(this); 894 action = new QAction("Show Nam 891 action = new QAction("Show Name", this); 895 action->setCheckable(true); 892 action->setCheckable(true); 896 connect(action, &QAction::togg 893 connect(action, &QAction::toggled, 897 this, &ConfigList::set 894 this, &ConfigList::setShowName); 898 connect(this, &ConfigList::sho 895 connect(this, &ConfigList::showNameChanged, 899 action, &QAction::setC 896 action, &QAction::setChecked); 900 action->setChecked(showName); 897 action->setChecked(showName); 901 headerPopup->addAction(action) 898 headerPopup->addAction(action); 902 } 899 } 903 900 904 headerPopup->exec(e->globalPos()); 901 headerPopup->exec(e->globalPos()); 905 e->accept(); 902 e->accept(); 906 } 903 } 907 904 908 void ConfigList::setShowName(bool on) 905 void ConfigList::setShowName(bool on) 909 { 906 { 910 if (showName == on) 907 if (showName == on) 911 return; 908 return; 912 909 913 showName = on; 910 showName = on; 914 reinit(); 911 reinit(); 915 emit showNameChanged(on); 912 emit showNameChanged(on); 916 } 913 } 917 914 918 QList<ConfigList *> ConfigList::allLists; 915 QList<ConfigList *> ConfigList::allLists; 919 QAction *ConfigList::showNormalAction; 916 QAction *ConfigList::showNormalAction; 920 QAction *ConfigList::showAllAction; 917 QAction *ConfigList::showAllAction; 921 QAction *ConfigList::showPromptAction; 918 QAction *ConfigList::showPromptAction; 922 919 923 void ConfigList::setAllOpen(bool open) 920 void ConfigList::setAllOpen(bool open) 924 { 921 { 925 QTreeWidgetItemIterator it(this); 922 QTreeWidgetItemIterator it(this); 926 923 927 while (*it) { 924 while (*it) { 928 (*it)->setExpanded(open); 925 (*it)->setExpanded(open); 929 926 930 ++it; 927 ++it; 931 } 928 } 932 } 929 } 933 930 934 ConfigInfoView::ConfigInfoView(QWidget* parent 931 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name) 935 : Parent(parent), sym(0), _menu(0) 932 : Parent(parent), sym(0), _menu(0) 936 { 933 { 937 setObjectName(name); 934 setObjectName(name); 938 setOpenLinks(false); 935 setOpenLinks(false); 939 936 940 if (!objectName().isEmpty()) { 937 if (!objectName().isEmpty()) { 941 configSettings->beginGroup(obj 938 configSettings->beginGroup(objectName()); 942 setShowDebug(configSettings->v 939 setShowDebug(configSettings->value("/showDebug", false).toBool()); 943 configSettings->endGroup(); 940 configSettings->endGroup(); 944 connect(configApp, &QApplicati 941 connect(configApp, &QApplication::aboutToQuit, 945 this, &ConfigInfoView: 942 this, &ConfigInfoView::saveSettings); 946 } 943 } 947 944 948 contextMenu = createStandardContextMen 945 contextMenu = createStandardContextMenu(); 949 QAction *action = new QAction("Show De 946 QAction *action = new QAction("Show Debug Info", contextMenu); 950 947 951 action->setCheckable(true); 948 action->setCheckable(true); 952 connect(action, &QAction::toggled, 949 connect(action, &QAction::toggled, 953 this, &ConfigInfoView::setShow 950 this, &ConfigInfoView::setShowDebug); 954 connect(this, &ConfigInfoView::showDeb 951 connect(this, &ConfigInfoView::showDebugChanged, 955 action, &QAction::setChecked); 952 action, &QAction::setChecked); 956 action->setChecked(showDebug()); 953 action->setChecked(showDebug()); 957 contextMenu->addSeparator(); 954 contextMenu->addSeparator(); 958 contextMenu->addAction(action); 955 contextMenu->addAction(action); 959 } 956 } 960 957 961 void ConfigInfoView::saveSettings(void) 958 void ConfigInfoView::saveSettings(void) 962 { 959 { 963 if (!objectName().isEmpty()) { 960 if (!objectName().isEmpty()) { 964 configSettings->beginGroup(obj 961 configSettings->beginGroup(objectName()); 965 configSettings->setValue("/sho 962 configSettings->setValue("/showDebug", showDebug()); 966 configSettings->endGroup(); 963 configSettings->endGroup(); 967 } 964 } 968 } 965 } 969 966 970 void ConfigInfoView::setShowDebug(bool b) 967 void ConfigInfoView::setShowDebug(bool b) 971 { 968 { 972 if (_showDebug != b) { 969 if (_showDebug != b) { 973 _showDebug = b; 970 _showDebug = b; 974 if (_menu) 971 if (_menu) 975 menuInfo(); 972 menuInfo(); 976 else if (sym) 973 else if (sym) 977 symbolInfo(); 974 symbolInfo(); 978 emit showDebugChanged(b); 975 emit showDebugChanged(b); 979 } 976 } 980 } 977 } 981 978 982 void ConfigInfoView::setInfo(struct menu *m) 979 void ConfigInfoView::setInfo(struct menu *m) 983 { 980 { 984 if (_menu == m) 981 if (_menu == m) 985 return; 982 return; 986 _menu = m; 983 _menu = m; 987 sym = NULL; 984 sym = NULL; 988 if (!_menu) 985 if (!_menu) 989 clear(); 986 clear(); 990 else 987 else 991 menuInfo(); 988 menuInfo(); 992 } 989 } 993 990 994 void ConfigInfoView::symbolInfo(void) 991 void ConfigInfoView::symbolInfo(void) 995 { 992 { 996 QString str; 993 QString str; 997 994 998 str += "<big>Symbol: <b>"; 995 str += "<big>Symbol: <b>"; 999 str += print_filter(sym->name); 996 str += print_filter(sym->name); 1000 str += "</b></big><br><br>value: "; 997 str += "</b></big><br><br>value: "; 1001 str += print_filter(sym_get_string_va 998 str += print_filter(sym_get_string_value(sym)); 1002 str += "<br>visibility: "; 999 str += "<br>visibility: "; 1003 str += sym->visible == yes ? "y" : sy 1000 str += sym->visible == yes ? "y" : sym->visible == mod ? "m" : "n"; 1004 str += "<br>"; 1001 str += "<br>"; 1005 str += debug_info(sym); 1002 str += debug_info(sym); 1006 1003 1007 setText(str); 1004 setText(str); 1008 } 1005 } 1009 1006 1010 void ConfigInfoView::menuInfo(void) 1007 void ConfigInfoView::menuInfo(void) 1011 { 1008 { 1012 struct symbol* sym; 1009 struct symbol* sym; 1013 QString info; 1010 QString info; 1014 QTextStream stream(&info); 1011 QTextStream stream(&info); 1015 1012 1016 sym = _menu->sym; 1013 sym = _menu->sym; 1017 if (sym) { 1014 if (sym) { 1018 if (_menu->prompt) { 1015 if (_menu->prompt) { 1019 stream << "<big><b>"; 1016 stream << "<big><b>"; 1020 stream << print_filte 1017 stream << print_filter(_menu->prompt->text); 1021 stream << "</b></big> 1018 stream << "</b></big>"; 1022 if (sym->name) { 1019 if (sym->name) { 1023 stream << " ( 1020 stream << " ("; 1024 if (showDebug 1021 if (showDebug()) 1025 strea 1022 stream << "<a href=\"s" << sym->name << "\">"; 1026 stream << pri 1023 stream << print_filter(sym->name); 1027 if (showDebug 1024 if (showDebug()) 1028 strea 1025 stream << "</a>"; 1029 stream << ")" 1026 stream << ")"; 1030 } 1027 } 1031 } else if (sym->name) { 1028 } else if (sym->name) { 1032 stream << "<big><b>"; 1029 stream << "<big><b>"; 1033 if (showDebug()) 1030 if (showDebug()) 1034 stream << "<a 1031 stream << "<a href=\"s" << sym->name << "\">"; 1035 stream << print_filte 1032 stream << print_filter(sym->name); 1036 if (showDebug()) 1033 if (showDebug()) 1037 stream << "</ 1034 stream << "</a>"; 1038 stream << "</b></big> 1035 stream << "</b></big>"; 1039 } 1036 } 1040 stream << "<br><br>"; 1037 stream << "<br><br>"; 1041 1038 1042 if (showDebug()) 1039 if (showDebug()) 1043 stream << debug_info( 1040 stream << debug_info(sym); 1044 1041 1045 struct gstr help_gstr = str_n 1042 struct gstr help_gstr = str_new(); 1046 1043 1047 menu_get_ext_help(_menu, &hel 1044 menu_get_ext_help(_menu, &help_gstr); 1048 stream << print_filter(str_ge 1045 stream << print_filter(str_get(&help_gstr)); 1049 str_free(&help_gstr); 1046 str_free(&help_gstr); 1050 } else if (_menu->prompt) { 1047 } else if (_menu->prompt) { 1051 stream << "<big><b>"; 1048 stream << "<big><b>"; 1052 stream << print_filter(_menu- 1049 stream << print_filter(_menu->prompt->text); 1053 stream << "</b></big><br><br> 1050 stream << "</b></big><br><br>"; 1054 if (showDebug()) { 1051 if (showDebug()) { 1055 if (_menu->prompt->vi 1052 if (_menu->prompt->visible.expr) { 1056 stream << "&n 1053 stream << " dep: "; 1057 expr_print(_m 1054 expr_print(_menu->prompt->visible.expr, 1058 ex 1055 expr_print_help, &stream, E_NONE); 1059 stream << "<b 1056 stream << "<br><br>"; 1060 } 1057 } 1061 1058 1062 stream << "defined at !! 1059 stream << "defined at " << _menu->file->name << ":" 1063 << _menu->line 1060 << _menu->lineno << "<br><br>"; 1064 } 1061 } 1065 } 1062 } 1066 1063 1067 setText(info); 1064 setText(info); 1068 } 1065 } 1069 1066 1070 QString ConfigInfoView::debug_info(struct sym 1067 QString ConfigInfoView::debug_info(struct symbol *sym) 1071 { 1068 { 1072 QString debug; 1069 QString debug; 1073 QTextStream stream(&debug); 1070 QTextStream stream(&debug); 1074 1071 1075 stream << "type: "; 1072 stream << "type: "; 1076 stream << print_filter(sym_type_name( 1073 stream << print_filter(sym_type_name(sym->type)); 1077 if (sym_is_choice(sym)) 1074 if (sym_is_choice(sym)) 1078 stream << " (choice)"; 1075 stream << " (choice)"; 1079 debug += "<br>"; 1076 debug += "<br>"; 1080 if (sym->rev_dep.expr) { 1077 if (sym->rev_dep.expr) { 1081 stream << "reverse dep: "; 1078 stream << "reverse dep: "; 1082 expr_print(sym->rev_dep.expr, 1079 expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE); 1083 stream << "<br>"; 1080 stream << "<br>"; 1084 } 1081 } 1085 for (struct property *prop = sym->pro 1082 for (struct property *prop = sym->prop; prop; prop = prop->next) { 1086 switch (prop->type) { 1083 switch (prop->type) { 1087 case P_PROMPT: 1084 case P_PROMPT: 1088 case P_MENU: 1085 case P_MENU: 1089 stream << "prompt: <a 1086 stream << "prompt: <a href=\"m" << sym->name << "\">"; 1090 stream << print_filte 1087 stream << print_filter(prop->text); 1091 stream << "</a><br>"; 1088 stream << "</a><br>"; 1092 break; 1089 break; 1093 case P_DEFAULT: 1090 case P_DEFAULT: 1094 case P_SELECT: 1091 case P_SELECT: 1095 case P_RANGE: 1092 case P_RANGE: 1096 case P_COMMENT: 1093 case P_COMMENT: 1097 case P_IMPLY: 1094 case P_IMPLY: >> 1095 case P_SYMBOL: 1098 stream << prop_get_ty 1096 stream << prop_get_type_name(prop->type); 1099 stream << ": "; 1097 stream << ": "; 1100 expr_print(prop->expr 1098 expr_print(prop->expr, expr_print_help, 1101 &stream, E 1099 &stream, E_NONE); 1102 stream << "<br>"; 1100 stream << "<br>"; 1103 break; 1101 break; >> 1102 case P_CHOICE: >> 1103 if (sym_is_choice(sym)) { >> 1104 stream << "choice: "; >> 1105 expr_print(prop->expr, expr_print_help, >> 1106 &stream, E_NONE); >> 1107 stream << "<br>"; >> 1108 } >> 1109 break; 1104 default: 1110 default: 1105 stream << "unknown pr 1111 stream << "unknown property: "; 1106 stream << prop_get_ty 1112 stream << prop_get_type_name(prop->type); 1107 stream << "<br>"; 1113 stream << "<br>"; 1108 } 1114 } 1109 if (prop->visible.expr) { 1115 if (prop->visible.expr) { 1110 stream << " &nbs 1116 stream << " dep: "; 1111 expr_print(prop->visi 1117 expr_print(prop->visible.expr, expr_print_help, 1112 &stream, E 1118 &stream, E_NONE); 1113 stream << "<br>"; 1119 stream << "<br>"; 1114 } 1120 } 1115 } 1121 } 1116 stream << "<br>"; 1122 stream << "<br>"; 1117 1123 1118 return debug; 1124 return debug; 1119 } 1125 } 1120 1126 1121 QString ConfigInfoView::print_filter(const QS 1127 QString ConfigInfoView::print_filter(const QString &str) 1122 { 1128 { 1123 QRegularExpression re("[<>&\"\\n]"); !! 1129 QRegExp re("[<>&\"\\n]"); 1124 QString res = str; 1130 QString res = str; 1125 for (int i = 0; (i = res.indexOf(re, 1131 for (int i = 0; (i = res.indexOf(re, i)) >= 0;) { 1126 switch (res[i].toLatin1()) { 1132 switch (res[i].toLatin1()) { 1127 case '<': 1133 case '<': 1128 res.replace(i, 1, "&l 1134 res.replace(i, 1, "<"); 1129 i += 4; 1135 i += 4; 1130 break; 1136 break; 1131 case '>': 1137 case '>': 1132 res.replace(i, 1, "&g 1138 res.replace(i, 1, ">"); 1133 i += 4; 1139 i += 4; 1134 break; 1140 break; 1135 case '&': 1141 case '&': 1136 res.replace(i, 1, "&a 1142 res.replace(i, 1, "&"); 1137 i += 5; 1143 i += 5; 1138 break; 1144 break; 1139 case '"': 1145 case '"': 1140 res.replace(i, 1, "&q 1146 res.replace(i, 1, """); 1141 i += 6; 1147 i += 6; 1142 break; 1148 break; 1143 case '\n': 1149 case '\n': 1144 res.replace(i, 1, "<b 1150 res.replace(i, 1, "<br>"); 1145 i += 4; 1151 i += 4; 1146 break; 1152 break; 1147 } 1153 } 1148 } 1154 } 1149 return res; 1155 return res; 1150 } 1156 } 1151 1157 1152 void ConfigInfoView::expr_print_help(void *da 1158 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str) 1153 { 1159 { 1154 QTextStream *stream = reinterpret_cas 1160 QTextStream *stream = reinterpret_cast<QTextStream *>(data); 1155 1161 1156 if (sym && sym->name && !(sym->flags 1162 if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) { 1157 *stream << "<a href=\"s" << s 1163 *stream << "<a href=\"s" << sym->name << "\">"; 1158 *stream << print_filter(str); 1164 *stream << print_filter(str); 1159 *stream << "</a>"; 1165 *stream << "</a>"; 1160 } else { 1166 } else { 1161 *stream << print_filter(str); 1167 *stream << print_filter(str); 1162 } 1168 } 1163 } 1169 } 1164 1170 1165 void ConfigInfoView::clicked(const QUrl &url) 1171 void ConfigInfoView::clicked(const QUrl &url) 1166 { 1172 { 1167 QByteArray str = url.toEncoded(); 1173 QByteArray str = url.toEncoded(); 1168 const std::size_t count = str.size(); 1174 const std::size_t count = str.size(); 1169 char *data = new char[count + 2]; // !! 1175 char *data = new char[count + 1]; 1170 struct symbol **result; 1176 struct symbol **result; 1171 struct menu *m = NULL; 1177 struct menu *m = NULL; 1172 1178 1173 if (count < 1) { 1179 if (count < 1) { 1174 delete[] data; 1180 delete[] data; 1175 return; 1181 return; 1176 } 1182 } 1177 1183 1178 memcpy(data, str.constData(), count); 1184 memcpy(data, str.constData(), count); 1179 data[count] = '\0'; 1185 data[count] = '\0'; 1180 1186 1181 /* Seek for exact match */ 1187 /* Seek for exact match */ 1182 data[0] = '^'; 1188 data[0] = '^'; 1183 strcat(data, "$"); 1189 strcat(data, "$"); 1184 result = sym_re_search(data); 1190 result = sym_re_search(data); 1185 if (!result) { 1191 if (!result) { 1186 delete[] data; 1192 delete[] data; 1187 return; 1193 return; 1188 } 1194 } 1189 1195 1190 sym = *result; 1196 sym = *result; 1191 1197 1192 /* Seek for the menu which holds the 1198 /* Seek for the menu which holds the symbol */ 1193 for (struct property *prop = sym->pro 1199 for (struct property *prop = sym->prop; prop; prop = prop->next) { 1194 if (prop->type != P_PROMP 1200 if (prop->type != P_PROMPT && prop->type != P_MENU) 1195 continue; 1201 continue; 1196 m = prop->menu; 1202 m = prop->menu; 1197 break; 1203 break; 1198 } 1204 } 1199 1205 1200 if (!m) { 1206 if (!m) { 1201 /* Symbol is not visible as a 1207 /* Symbol is not visible as a menu */ 1202 symbolInfo(); 1208 symbolInfo(); 1203 emit showDebugChanged(true); 1209 emit showDebugChanged(true); 1204 } else { 1210 } else { 1205 emit menuSelected(m); 1211 emit menuSelected(m); 1206 } 1212 } 1207 1213 1208 free(result); 1214 free(result); 1209 delete[] data; 1215 delete[] data; 1210 } 1216 } 1211 1217 1212 void ConfigInfoView::contextMenuEvent(QContex 1218 void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event) 1213 { 1219 { 1214 contextMenu->popup(event->globalPos() 1220 contextMenu->popup(event->globalPos()); 1215 event->accept(); 1221 event->accept(); 1216 } 1222 } 1217 1223 1218 ConfigSearchWindow::ConfigSearchWindow(Config 1224 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent) 1219 : Parent(parent), result(NULL) 1225 : Parent(parent), result(NULL) 1220 { 1226 { 1221 setObjectName("search"); 1227 setObjectName("search"); 1222 setWindowTitle("Search Config"); 1228 setWindowTitle("Search Config"); 1223 1229 1224 QVBoxLayout* layout1 = new QVBoxLayou 1230 QVBoxLayout* layout1 = new QVBoxLayout(this); 1225 layout1->setContentsMargins(11, 11, 1 1231 layout1->setContentsMargins(11, 11, 11, 11); 1226 layout1->setSpacing(6); 1232 layout1->setSpacing(6); 1227 1233 1228 QHBoxLayout* layout2 = new QHBoxLayou 1234 QHBoxLayout* layout2 = new QHBoxLayout(); 1229 layout2->setContentsMargins(0, 0, 0, 1235 layout2->setContentsMargins(0, 0, 0, 0); 1230 layout2->setSpacing(6); 1236 layout2->setSpacing(6); 1231 layout2->addWidget(new QLabel("Find:" 1237 layout2->addWidget(new QLabel("Find:", this)); 1232 editField = new QLineEdit(this); 1238 editField = new QLineEdit(this); 1233 connect(editField, &QLineEdit::return 1239 connect(editField, &QLineEdit::returnPressed, 1234 this, &ConfigSearchWindow::se 1240 this, &ConfigSearchWindow::search); 1235 layout2->addWidget(editField); 1241 layout2->addWidget(editField); 1236 searchButton = new QPushButton("Searc 1242 searchButton = new QPushButton("Search", this); 1237 searchButton->setAutoDefault(false); 1243 searchButton->setAutoDefault(false); 1238 connect(searchButton, &QPushButton::c 1244 connect(searchButton, &QPushButton::clicked, 1239 this, &ConfigSearchWindow::se 1245 this, &ConfigSearchWindow::search); 1240 layout2->addWidget(searchButton); 1246 layout2->addWidget(searchButton); 1241 layout1->addLayout(layout2); 1247 layout1->addLayout(layout2); 1242 1248 1243 split = new QSplitter(this); 1249 split = new QSplitter(this); 1244 split->setOrientation(Qt::Vertical); 1250 split->setOrientation(Qt::Vertical); 1245 list = new ConfigList(split, "search" 1251 list = new ConfigList(split, "search"); 1246 list->mode = listMode; 1252 list->mode = listMode; 1247 info = new ConfigInfoView(split, "sea 1253 info = new ConfigInfoView(split, "search"); 1248 connect(list, &ConfigList::menuChange 1254 connect(list, &ConfigList::menuChanged, 1249 info, &ConfigInfoView::setInf 1255 info, &ConfigInfoView::setInfo); 1250 connect(list, &ConfigList::menuChange 1256 connect(list, &ConfigList::menuChanged, 1251 parent, &ConfigMainWindow::se 1257 parent, &ConfigMainWindow::setMenuLink); 1252 1258 1253 layout1->addWidget(split); 1259 layout1->addWidget(split); 1254 1260 1255 QVariant x, y; 1261 QVariant x, y; 1256 int width, height; 1262 int width, height; 1257 bool ok; 1263 bool ok; 1258 1264 1259 configSettings->beginGroup("search"); 1265 configSettings->beginGroup("search"); 1260 width = configSettings->value("/windo 1266 width = configSettings->value("/window width", parent->width() / 2).toInt(); 1261 height = configSettings->value("/wind 1267 height = configSettings->value("/window height", parent->height() / 2).toInt(); 1262 resize(width, height); 1268 resize(width, height); 1263 x = configSettings->value("/window x" 1269 x = configSettings->value("/window x"); 1264 y = configSettings->value("/window y" 1270 y = configSettings->value("/window y"); 1265 if (x.isValid() && y.isValid()) 1271 if (x.isValid() && y.isValid()) 1266 move(x.toInt(), y.toInt()); 1272 move(x.toInt(), y.toInt()); 1267 QList<int> sizes = configSettings->re 1273 QList<int> sizes = configSettings->readSizes("/split", &ok); 1268 if (ok) 1274 if (ok) 1269 split->setSizes(sizes); 1275 split->setSizes(sizes); 1270 configSettings->endGroup(); 1276 configSettings->endGroup(); 1271 connect(configApp, &QApplication::abo 1277 connect(configApp, &QApplication::aboutToQuit, 1272 this, &ConfigSearchWindow::sa 1278 this, &ConfigSearchWindow::saveSettings); 1273 } 1279 } 1274 1280 1275 void ConfigSearchWindow::saveSettings(void) 1281 void ConfigSearchWindow::saveSettings(void) 1276 { 1282 { 1277 if (!objectName().isEmpty()) { 1283 if (!objectName().isEmpty()) { 1278 configSettings->beginGroup(ob 1284 configSettings->beginGroup(objectName()); 1279 configSettings->setValue("/wi 1285 configSettings->setValue("/window x", pos().x()); 1280 configSettings->setValue("/wi 1286 configSettings->setValue("/window y", pos().y()); 1281 configSettings->setValue("/wi 1287 configSettings->setValue("/window width", size().width()); 1282 configSettings->setValue("/wi 1288 configSettings->setValue("/window height", size().height()); 1283 configSettings->writeSizes("/ 1289 configSettings->writeSizes("/split", split->sizes()); 1284 configSettings->endGroup(); 1290 configSettings->endGroup(); 1285 } 1291 } 1286 } 1292 } 1287 1293 1288 void ConfigSearchWindow::search(void) 1294 void ConfigSearchWindow::search(void) 1289 { 1295 { 1290 struct symbol **p; 1296 struct symbol **p; 1291 struct property *prop; 1297 struct property *prop; 1292 ConfigItem *lastItem = NULL; 1298 ConfigItem *lastItem = NULL; 1293 1299 1294 free(result); 1300 free(result); 1295 list->clear(); 1301 list->clear(); 1296 info->clear(); 1302 info->clear(); 1297 1303 1298 result = sym_re_search(editField->tex 1304 result = sym_re_search(editField->text().toLatin1()); 1299 if (!result) 1305 if (!result) 1300 return; 1306 return; 1301 for (p = result; *p; p++) { 1307 for (p = result; *p; p++) { 1302 for_all_prompts((*p), prop) 1308 for_all_prompts((*p), prop) 1303 lastItem = new Config 1309 lastItem = new ConfigItem(list, lastItem, prop->menu, 1304 1310 menu_is_visible(prop->menu)); 1305 } 1311 } 1306 } 1312 } 1307 1313 1308 /* 1314 /* 1309 * Construct the complete config widget 1315 * Construct the complete config widget 1310 */ 1316 */ 1311 ConfigMainWindow::ConfigMainWindow(void) 1317 ConfigMainWindow::ConfigMainWindow(void) 1312 : searchWindow(0) 1318 : searchWindow(0) 1313 { 1319 { 1314 bool ok = true; 1320 bool ok = true; 1315 QVariant x, y; 1321 QVariant x, y; 1316 int width, height; 1322 int width, height; 1317 char title[256]; 1323 char title[256]; 1318 1324 >> 1325 QDesktopWidget *d = configApp->desktop(); 1319 snprintf(title, sizeof(title), "%s%s" 1326 snprintf(title, sizeof(title), "%s%s", 1320 rootmenu.prompt->text, 1327 rootmenu.prompt->text, 1321 "" 1328 "" 1322 ); 1329 ); 1323 setWindowTitle(title); 1330 setWindowTitle(title); 1324 1331 1325 QRect g = configApp->primaryScreen()- !! 1332 width = configSettings->value("/window width", d->width() - 64).toInt(); 1326 width = configSettings->value("/windo !! 1333 height = configSettings->value("/window height", d->height() - 64).toInt(); 1327 height = configSettings->value("/wind << 1328 resize(width, height); 1334 resize(width, height); 1329 x = configSettings->value("/window x" 1335 x = configSettings->value("/window x"); 1330 y = configSettings->value("/window y" 1336 y = configSettings->value("/window y"); 1331 if ((x.isValid())&&(y.isValid())) 1337 if ((x.isValid())&&(y.isValid())) 1332 move(x.toInt(), y.toInt()); 1338 move(x.toInt(), y.toInt()); 1333 1339 1334 // set up icons 1340 // set up icons 1335 ConfigItem::symbolYesIcon = QIcon(QPi 1341 ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes)); 1336 ConfigItem::symbolModIcon = QIcon(QPi 1342 ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod)); 1337 ConfigItem::symbolNoIcon = QIcon(QPix 1343 ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no)); 1338 ConfigItem::choiceYesIcon = QIcon(QPi 1344 ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes)); 1339 ConfigItem::choiceNoIcon = QIcon(QPix 1345 ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no)); 1340 ConfigItem::menuIcon = QIcon(QPixmap( 1346 ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu)); 1341 ConfigItem::menubackIcon = QIcon(QPix 1347 ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback)); 1342 1348 1343 QWidget *widget = new QWidget(this); 1349 QWidget *widget = new QWidget(this); 1344 QVBoxLayout *layout = new QVBoxLayout 1350 QVBoxLayout *layout = new QVBoxLayout(widget); 1345 setCentralWidget(widget); 1351 setCentralWidget(widget); 1346 1352 1347 split1 = new QSplitter(widget); 1353 split1 = new QSplitter(widget); 1348 split1->setOrientation(Qt::Horizontal 1354 split1->setOrientation(Qt::Horizontal); 1349 split1->setChildrenCollapsible(false) 1355 split1->setChildrenCollapsible(false); 1350 1356 1351 menuList = new ConfigList(widget, "me 1357 menuList = new ConfigList(widget, "menu"); 1352 1358 1353 split2 = new QSplitter(widget); 1359 split2 = new QSplitter(widget); 1354 split2->setChildrenCollapsible(false) 1360 split2->setChildrenCollapsible(false); 1355 split2->setOrientation(Qt::Vertical); 1361 split2->setOrientation(Qt::Vertical); 1356 1362 1357 // create config tree 1363 // create config tree 1358 configList = new ConfigList(widget, " 1364 configList = new ConfigList(widget, "config"); 1359 1365 1360 helpText = new ConfigInfoView(widget, 1366 helpText = new ConfigInfoView(widget, "help"); 1361 1367 1362 layout->addWidget(split2); 1368 layout->addWidget(split2); 1363 split2->addWidget(split1); 1369 split2->addWidget(split1); 1364 split1->addWidget(configList); 1370 split1->addWidget(configList); 1365 split1->addWidget(menuList); 1371 split1->addWidget(menuList); 1366 split2->addWidget(helpText); 1372 split2->addWidget(helpText); 1367 1373 1368 setTabOrder(configList, helpText); 1374 setTabOrder(configList, helpText); 1369 configList->setFocus(); 1375 configList->setFocus(); 1370 1376 1371 backAction = new QAction(QPixmap(xpm_ 1377 backAction = new QAction(QPixmap(xpm_back), "Back", this); 1372 connect(backAction, &QAction::trigger 1378 connect(backAction, &QAction::triggered, 1373 this, &ConfigMainWindow::goBa 1379 this, &ConfigMainWindow::goBack); 1374 1380 1375 QAction *quitAction = new QAction("&Q 1381 QAction *quitAction = new QAction("&Quit", this); 1376 quitAction->setShortcut(Qt::CTRL | Qt !! 1382 quitAction->setShortcut(Qt::CTRL + Qt::Key_Q); 1377 connect(quitAction, &QAction::trigger 1383 connect(quitAction, &QAction::triggered, 1378 this, &ConfigMainWindow::clos 1384 this, &ConfigMainWindow::close); 1379 1385 1380 QAction *loadAction = new QAction(QPi 1386 QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this); 1381 loadAction->setShortcut(Qt::CTRL | Qt !! 1387 loadAction->setShortcut(Qt::CTRL + Qt::Key_L); 1382 connect(loadAction, &QAction::trigger 1388 connect(loadAction, &QAction::triggered, 1383 this, &ConfigMainWindow::load 1389 this, &ConfigMainWindow::loadConfig); 1384 1390 1385 saveAction = new QAction(QPixmap(xpm_ 1391 saveAction = new QAction(QPixmap(xpm_save), "&Save", this); 1386 saveAction->setShortcut(Qt::CTRL | Qt !! 1392 saveAction->setShortcut(Qt::CTRL + Qt::Key_S); 1387 connect(saveAction, &QAction::trigger 1393 connect(saveAction, &QAction::triggered, 1388 this, &ConfigMainWindow::save 1394 this, &ConfigMainWindow::saveConfig); 1389 1395 1390 conf_set_changed_callback(conf_change 1396 conf_set_changed_callback(conf_changed); 1391 1397 >> 1398 // Set saveAction's initial state >> 1399 conf_changed(); 1392 configname = xstrdup(conf_get_confign 1400 configname = xstrdup(conf_get_configname()); 1393 1401 1394 QAction *saveAsAction = new QAction(" 1402 QAction *saveAsAction = new QAction("Save &As...", this); 1395 connect(saveAsAction, &QAction::trigg 1403 connect(saveAsAction, &QAction::triggered, 1396 this, &ConfigMainWindow::save 1404 this, &ConfigMainWindow::saveConfigAs); 1397 QAction *searchAction = new QAction(" 1405 QAction *searchAction = new QAction("&Find", this); 1398 searchAction->setShortcut(Qt::CTRL | !! 1406 searchAction->setShortcut(Qt::CTRL + Qt::Key_F); 1399 connect(searchAction, &QAction::trigg 1407 connect(searchAction, &QAction::triggered, 1400 this, &ConfigMainWindow::sear 1408 this, &ConfigMainWindow::searchConfig); 1401 singleViewAction = new QAction(QPixma 1409 singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this); 1402 singleViewAction->setCheckable(true); 1410 singleViewAction->setCheckable(true); 1403 connect(singleViewAction, &QAction::t 1411 connect(singleViewAction, &QAction::triggered, 1404 this, &ConfigMainWindow::show 1412 this, &ConfigMainWindow::showSingleView); 1405 splitViewAction = new QAction(QPixmap 1413 splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this); 1406 splitViewAction->setCheckable(true); 1414 splitViewAction->setCheckable(true); 1407 connect(splitViewAction, &QAction::tr 1415 connect(splitViewAction, &QAction::triggered, 1408 this, &ConfigMainWindow::show 1416 this, &ConfigMainWindow::showSplitView); 1409 fullViewAction = new QAction(QPixmap( 1417 fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this); 1410 fullViewAction->setCheckable(true); 1418 fullViewAction->setCheckable(true); 1411 connect(fullViewAction, &QAction::tri 1419 connect(fullViewAction, &QAction::triggered, 1412 this, &ConfigMainWindow::show 1420 this, &ConfigMainWindow::showFullView); 1413 1421 1414 QAction *showNameAction = new QAction 1422 QAction *showNameAction = new QAction("Show Name", this); 1415 showNameAction->setCheckable(true); 1423 showNameAction->setCheckable(true); 1416 connect(showNameAction, &QAction::tog 1424 connect(showNameAction, &QAction::toggled, 1417 configList, &ConfigList::setS 1425 configList, &ConfigList::setShowName); 1418 showNameAction->setChecked(configList 1426 showNameAction->setChecked(configList->showName); 1419 1427 1420 QActionGroup *optGroup = new QActionG 1428 QActionGroup *optGroup = new QActionGroup(this); 1421 optGroup->setExclusive(true); 1429 optGroup->setExclusive(true); 1422 connect(optGroup, &QActionGroup::trig 1430 connect(optGroup, &QActionGroup::triggered, 1423 configList, &ConfigList::setO 1431 configList, &ConfigList::setOptionMode); 1424 connect(optGroup, &QActionGroup::trig 1432 connect(optGroup, &QActionGroup::triggered, 1425 menuList, &ConfigList::setOpt 1433 menuList, &ConfigList::setOptionMode); 1426 1434 1427 ConfigList::showNormalAction = new QA 1435 ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup); 1428 ConfigList::showNormalAction->setChec 1436 ConfigList::showNormalAction->setCheckable(true); 1429 ConfigList::showAllAction = new QActi 1437 ConfigList::showAllAction = new QAction("Show All Options", optGroup); 1430 ConfigList::showAllAction->setCheckab 1438 ConfigList::showAllAction->setCheckable(true); 1431 ConfigList::showPromptAction = new QA 1439 ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup); 1432 ConfigList::showPromptAction->setChec 1440 ConfigList::showPromptAction->setCheckable(true); 1433 1441 1434 QAction *showDebugAction = new QActio 1442 QAction *showDebugAction = new QAction("Show Debug Info", this); 1435 showDebugAction->setCheckable(true) 1443 showDebugAction->setCheckable(true); 1436 connect(showDebugAction, &QAction::to 1444 connect(showDebugAction, &QAction::toggled, 1437 helpText, &ConfigInfoView::se 1445 helpText, &ConfigInfoView::setShowDebug); 1438 showDebugAction->setChecked(helpTex 1446 showDebugAction->setChecked(helpText->showDebug()); 1439 1447 1440 QAction *showIntroAction = new QActio 1448 QAction *showIntroAction = new QAction("Introduction", this); 1441 connect(showIntroAction, &QAction::tr 1449 connect(showIntroAction, &QAction::triggered, 1442 this, &ConfigMainWindow::show 1450 this, &ConfigMainWindow::showIntro); 1443 QAction *showAboutAction = new QActio 1451 QAction *showAboutAction = new QAction("About", this); 1444 connect(showAboutAction, &QAction::tr 1452 connect(showAboutAction, &QAction::triggered, 1445 this, &ConfigMainWindow::show 1453 this, &ConfigMainWindow::showAbout); 1446 1454 1447 // init tool bar 1455 // init tool bar 1448 QToolBar *toolBar = addToolBar("Tools 1456 QToolBar *toolBar = addToolBar("Tools"); 1449 toolBar->addAction(backAction); 1457 toolBar->addAction(backAction); 1450 toolBar->addSeparator(); 1458 toolBar->addSeparator(); 1451 toolBar->addAction(loadAction); 1459 toolBar->addAction(loadAction); 1452 toolBar->addAction(saveAction); 1460 toolBar->addAction(saveAction); 1453 toolBar->addSeparator(); 1461 toolBar->addSeparator(); 1454 toolBar->addAction(singleViewAction); 1462 toolBar->addAction(singleViewAction); 1455 toolBar->addAction(splitViewAction); 1463 toolBar->addAction(splitViewAction); 1456 toolBar->addAction(fullViewAction); 1464 toolBar->addAction(fullViewAction); 1457 1465 1458 // create file menu 1466 // create file menu 1459 QMenu *menu = menuBar()->addMenu("&Fi 1467 QMenu *menu = menuBar()->addMenu("&File"); 1460 menu->addAction(loadAction); 1468 menu->addAction(loadAction); 1461 menu->addAction(saveAction); 1469 menu->addAction(saveAction); 1462 menu->addAction(saveAsAction); 1470 menu->addAction(saveAsAction); 1463 menu->addSeparator(); 1471 menu->addSeparator(); 1464 menu->addAction(quitAction); 1472 menu->addAction(quitAction); 1465 1473 1466 // create edit menu 1474 // create edit menu 1467 menu = menuBar()->addMenu("&Edit"); 1475 menu = menuBar()->addMenu("&Edit"); 1468 menu->addAction(searchAction); 1476 menu->addAction(searchAction); 1469 1477 1470 // create options menu 1478 // create options menu 1471 menu = menuBar()->addMenu("&Option"); 1479 menu = menuBar()->addMenu("&Option"); 1472 menu->addAction(showNameAction); 1480 menu->addAction(showNameAction); 1473 menu->addSeparator(); 1481 menu->addSeparator(); 1474 menu->addActions(optGroup->actions()) 1482 menu->addActions(optGroup->actions()); 1475 menu->addSeparator(); 1483 menu->addSeparator(); 1476 menu->addAction(showDebugAction); 1484 menu->addAction(showDebugAction); 1477 1485 1478 // create help menu 1486 // create help menu 1479 menu = menuBar()->addMenu("&Help"); 1487 menu = menuBar()->addMenu("&Help"); 1480 menu->addAction(showIntroAction); 1488 menu->addAction(showIntroAction); 1481 menu->addAction(showAboutAction); 1489 menu->addAction(showAboutAction); 1482 1490 1483 connect(helpText, &ConfigInfoView::an 1491 connect(helpText, &ConfigInfoView::anchorClicked, 1484 helpText, &ConfigInfoView::cl 1492 helpText, &ConfigInfoView::clicked); 1485 1493 1486 connect(configList, &ConfigList::menu 1494 connect(configList, &ConfigList::menuChanged, 1487 helpText, &ConfigInfoView::se 1495 helpText, &ConfigInfoView::setInfo); 1488 connect(configList, &ConfigList::menu 1496 connect(configList, &ConfigList::menuSelected, 1489 this, &ConfigMainWindow::chan 1497 this, &ConfigMainWindow::changeMenu); 1490 connect(configList, &ConfigList::item 1498 connect(configList, &ConfigList::itemSelected, 1491 this, &ConfigMainWindow::chan 1499 this, &ConfigMainWindow::changeItens); 1492 connect(configList, &ConfigList::pare 1500 connect(configList, &ConfigList::parentSelected, 1493 this, &ConfigMainWindow::goBa 1501 this, &ConfigMainWindow::goBack); 1494 connect(menuList, &ConfigList::menuCh 1502 connect(menuList, &ConfigList::menuChanged, 1495 helpText, &ConfigInfoView::se 1503 helpText, &ConfigInfoView::setInfo); 1496 connect(menuList, &ConfigList::menuSe 1504 connect(menuList, &ConfigList::menuSelected, 1497 this, &ConfigMainWindow::chan 1505 this, &ConfigMainWindow::changeMenu); 1498 1506 1499 connect(configList, &ConfigList::gotF 1507 connect(configList, &ConfigList::gotFocus, 1500 helpText, &ConfigInfoView::se 1508 helpText, &ConfigInfoView::setInfo); 1501 connect(menuList, &ConfigList::gotFoc 1509 connect(menuList, &ConfigList::gotFocus, 1502 helpText, &ConfigInfoView::se 1510 helpText, &ConfigInfoView::setInfo); 1503 connect(menuList, &ConfigList::gotFoc 1511 connect(menuList, &ConfigList::gotFocus, 1504 this, &ConfigMainWindow::list 1512 this, &ConfigMainWindow::listFocusChanged); 1505 connect(helpText, &ConfigInfoView::me 1513 connect(helpText, &ConfigInfoView::menuSelected, 1506 this, &ConfigMainWindow::setM 1514 this, &ConfigMainWindow::setMenuLink); 1507 1515 1508 conf_read(NULL); << 1509 << 1510 QString listMode = configSettings->va 1516 QString listMode = configSettings->value("/listMode", "symbol").toString(); 1511 if (listMode == "single") 1517 if (listMode == "single") 1512 showSingleView(); 1518 showSingleView(); 1513 else if (listMode == "full") 1519 else if (listMode == "full") 1514 showFullView(); 1520 showFullView(); 1515 else /*if (listMode == "split")*/ 1521 else /*if (listMode == "split")*/ 1516 showSplitView(); 1522 showSplitView(); 1517 1523 1518 // UI setup done, restore splitter po 1524 // UI setup done, restore splitter positions 1519 QList<int> sizes = configSettings->re 1525 QList<int> sizes = configSettings->readSizes("/split1", &ok); 1520 if (ok) 1526 if (ok) 1521 split1->setSizes(sizes); 1527 split1->setSizes(sizes); 1522 1528 1523 sizes = configSettings->readSizes("/s 1529 sizes = configSettings->readSizes("/split2", &ok); 1524 if (ok) 1530 if (ok) 1525 split2->setSizes(sizes); 1531 split2->setSizes(sizes); 1526 } 1532 } 1527 1533 1528 void ConfigMainWindow::loadConfig(void) 1534 void ConfigMainWindow::loadConfig(void) 1529 { 1535 { 1530 QString str; 1536 QString str; 1531 QByteArray ba; 1537 QByteArray ba; 1532 const char *name; 1538 const char *name; 1533 1539 1534 str = QFileDialog::getOpenFileName(th 1540 str = QFileDialog::getOpenFileName(this, "", configname); 1535 if (str.isNull()) 1541 if (str.isNull()) 1536 return; 1542 return; 1537 1543 1538 ba = str.toLocal8Bit(); 1544 ba = str.toLocal8Bit(); 1539 name = ba.data(); 1545 name = ba.data(); 1540 1546 1541 if (conf_read(name)) 1547 if (conf_read(name)) 1542 QMessageBox::information(this 1548 QMessageBox::information(this, "qconf", "Unable to load configuration!"); 1543 1549 1544 free(configname); 1550 free(configname); 1545 configname = xstrdup(name); 1551 configname = xstrdup(name); 1546 1552 1547 ConfigList::updateListAllForAll(); 1553 ConfigList::updateListAllForAll(); 1548 } 1554 } 1549 1555 1550 bool ConfigMainWindow::saveConfig(void) 1556 bool ConfigMainWindow::saveConfig(void) 1551 { 1557 { 1552 if (conf_write(configname)) { 1558 if (conf_write(configname)) { 1553 QMessageBox::information(this 1559 QMessageBox::information(this, "qconf", "Unable to save configuration!"); 1554 return false; 1560 return false; 1555 } 1561 } 1556 conf_write_autoconf(0); 1562 conf_write_autoconf(0); 1557 1563 1558 return true; 1564 return true; 1559 } 1565 } 1560 1566 1561 void ConfigMainWindow::saveConfigAs(void) 1567 void ConfigMainWindow::saveConfigAs(void) 1562 { 1568 { 1563 QString str; 1569 QString str; 1564 QByteArray ba; 1570 QByteArray ba; 1565 const char *name; 1571 const char *name; 1566 1572 1567 str = QFileDialog::getSaveFileName(th 1573 str = QFileDialog::getSaveFileName(this, "", configname); 1568 if (str.isNull()) 1574 if (str.isNull()) 1569 return; 1575 return; 1570 1576 1571 ba = str.toLocal8Bit(); 1577 ba = str.toLocal8Bit(); 1572 name = ba.data(); 1578 name = ba.data(); 1573 1579 1574 if (conf_write(name)) { 1580 if (conf_write(name)) { 1575 QMessageBox::information(this 1581 QMessageBox::information(this, "qconf", "Unable to save configuration!"); 1576 } 1582 } 1577 conf_write_autoconf(0); 1583 conf_write_autoconf(0); 1578 1584 1579 free(configname); 1585 free(configname); 1580 configname = xstrdup(name); 1586 configname = xstrdup(name); 1581 } 1587 } 1582 1588 1583 void ConfigMainWindow::searchConfig(void) 1589 void ConfigMainWindow::searchConfig(void) 1584 { 1590 { 1585 if (!searchWindow) 1591 if (!searchWindow) 1586 searchWindow = new ConfigSear 1592 searchWindow = new ConfigSearchWindow(this); 1587 searchWindow->show(); 1593 searchWindow->show(); 1588 } 1594 } 1589 1595 1590 void ConfigMainWindow::changeItens(struct men 1596 void ConfigMainWindow::changeItens(struct menu *menu) 1591 { 1597 { 1592 configList->setRootMenu(menu); 1598 configList->setRootMenu(menu); 1593 } 1599 } 1594 1600 1595 void ConfigMainWindow::changeMenu(struct menu 1601 void ConfigMainWindow::changeMenu(struct menu *menu) 1596 { 1602 { 1597 menuList->setRootMenu(menu); 1603 menuList->setRootMenu(menu); 1598 } 1604 } 1599 1605 1600 void ConfigMainWindow::setMenuLink(struct men 1606 void ConfigMainWindow::setMenuLink(struct menu *menu) 1601 { 1607 { 1602 struct menu *parent; 1608 struct menu *parent; 1603 ConfigList* list = NULL; 1609 ConfigList* list = NULL; 1604 ConfigItem* item; 1610 ConfigItem* item; 1605 1611 1606 if (configList->menuSkip(menu)) 1612 if (configList->menuSkip(menu)) 1607 return; 1613 return; 1608 1614 1609 switch (configList->mode) { 1615 switch (configList->mode) { 1610 case singleMode: 1616 case singleMode: 1611 list = configList; 1617 list = configList; 1612 parent = menu_get_parent_menu 1618 parent = menu_get_parent_menu(menu); 1613 if (!parent) 1619 if (!parent) 1614 return; 1620 return; 1615 list->setRootMenu(parent); 1621 list->setRootMenu(parent); 1616 break; 1622 break; 1617 case menuMode: 1623 case menuMode: 1618 if (menu->flags & MENU_ROOT) 1624 if (menu->flags & MENU_ROOT) { 1619 menuList->setRootMenu 1625 menuList->setRootMenu(menu); 1620 configList->clearSele 1626 configList->clearSelection(); 1621 list = configList; 1627 list = configList; 1622 } else { 1628 } else { 1623 parent = menu_get_par 1629 parent = menu_get_parent_menu(menu->parent); 1624 if (!parent) 1630 if (!parent) 1625 return; 1631 return; 1626 1632 1627 /* Select the config 1633 /* Select the config view */ 1628 item = configList->fi 1634 item = configList->findConfigItem(parent); 1629 if (item) { 1635 if (item) { 1630 configList->s 1636 configList->setSelected(item, true); 1631 configList->s 1637 configList->scrollToItem(item); 1632 } 1638 } 1633 1639 1634 menuList->setRootMenu 1640 menuList->setRootMenu(parent); 1635 menuList->clearSelect 1641 menuList->clearSelection(); 1636 list = menuList; 1642 list = menuList; 1637 } 1643 } 1638 break; 1644 break; 1639 case fullMode: 1645 case fullMode: 1640 list = configList; 1646 list = configList; 1641 break; 1647 break; 1642 default: 1648 default: 1643 break; 1649 break; 1644 } 1650 } 1645 1651 1646 if (list) { 1652 if (list) { 1647 item = list->findConfigItem(m 1653 item = list->findConfigItem(menu); 1648 if (item) { 1654 if (item) { 1649 list->setSelected(ite 1655 list->setSelected(item, true); 1650 list->scrollToItem(it 1656 list->scrollToItem(item); 1651 list->setFocus(); 1657 list->setFocus(); 1652 helpText->setInfo(men 1658 helpText->setInfo(menu); 1653 } 1659 } 1654 } 1660 } 1655 } 1661 } 1656 1662 1657 void ConfigMainWindow::listFocusChanged(void) 1663 void ConfigMainWindow::listFocusChanged(void) 1658 { 1664 { 1659 if (menuList->mode == menuMode) 1665 if (menuList->mode == menuMode) 1660 configList->clearSelection(); 1666 configList->clearSelection(); 1661 } 1667 } 1662 1668 1663 void ConfigMainWindow::goBack(void) 1669 void ConfigMainWindow::goBack(void) 1664 { 1670 { 1665 if (configList->rootEntry == &rootmen 1671 if (configList->rootEntry == &rootmenu) 1666 return; 1672 return; 1667 1673 1668 configList->setParentMenu(); 1674 configList->setParentMenu(); 1669 } 1675 } 1670 1676 1671 void ConfigMainWindow::showSingleView(void) 1677 void ConfigMainWindow::showSingleView(void) 1672 { 1678 { 1673 singleViewAction->setEnabled(false); 1679 singleViewAction->setEnabled(false); 1674 singleViewAction->setChecked(true); 1680 singleViewAction->setChecked(true); 1675 splitViewAction->setEnabled(true); 1681 splitViewAction->setEnabled(true); 1676 splitViewAction->setChecked(false); 1682 splitViewAction->setChecked(false); 1677 fullViewAction->setEnabled(true); 1683 fullViewAction->setEnabled(true); 1678 fullViewAction->setChecked(false); 1684 fullViewAction->setChecked(false); 1679 1685 1680 backAction->setEnabled(true); 1686 backAction->setEnabled(true); 1681 1687 1682 menuList->hide(); 1688 menuList->hide(); 1683 menuList->setRootMenu(0); 1689 menuList->setRootMenu(0); 1684 configList->mode = singleMode; 1690 configList->mode = singleMode; 1685 if (configList->rootEntry == &rootmen 1691 if (configList->rootEntry == &rootmenu) 1686 configList->updateListAll(); 1692 configList->updateListAll(); 1687 else 1693 else 1688 configList->setRootMenu(&root 1694 configList->setRootMenu(&rootmenu); 1689 configList->setFocus(); 1695 configList->setFocus(); 1690 } 1696 } 1691 1697 1692 void ConfigMainWindow::showSplitView(void) 1698 void ConfigMainWindow::showSplitView(void) 1693 { 1699 { 1694 singleViewAction->setEnabled(true); 1700 singleViewAction->setEnabled(true); 1695 singleViewAction->setChecked(false); 1701 singleViewAction->setChecked(false); 1696 splitViewAction->setEnabled(false); 1702 splitViewAction->setEnabled(false); 1697 splitViewAction->setChecked(true); 1703 splitViewAction->setChecked(true); 1698 fullViewAction->setEnabled(true); 1704 fullViewAction->setEnabled(true); 1699 fullViewAction->setChecked(false); 1705 fullViewAction->setChecked(false); 1700 1706 1701 backAction->setEnabled(false); 1707 backAction->setEnabled(false); 1702 1708 1703 configList->mode = menuMode; 1709 configList->mode = menuMode; 1704 if (configList->rootEntry == &rootmen 1710 if (configList->rootEntry == &rootmenu) 1705 configList->updateListAll(); 1711 configList->updateListAll(); 1706 else 1712 else 1707 configList->setRootMenu(&root 1713 configList->setRootMenu(&rootmenu); 1708 configList->setAllOpen(true); 1714 configList->setAllOpen(true); 1709 configApp->processEvents(); 1715 configApp->processEvents(); 1710 menuList->mode = symbolMode; 1716 menuList->mode = symbolMode; 1711 menuList->setRootMenu(&rootmenu); 1717 menuList->setRootMenu(&rootmenu); 1712 menuList->setAllOpen(true); 1718 menuList->setAllOpen(true); 1713 menuList->show(); 1719 menuList->show(); 1714 menuList->setFocus(); 1720 menuList->setFocus(); 1715 } 1721 } 1716 1722 1717 void ConfigMainWindow::showFullView(void) 1723 void ConfigMainWindow::showFullView(void) 1718 { 1724 { 1719 singleViewAction->setEnabled(true); 1725 singleViewAction->setEnabled(true); 1720 singleViewAction->setChecked(false); 1726 singleViewAction->setChecked(false); 1721 splitViewAction->setEnabled(true); 1727 splitViewAction->setEnabled(true); 1722 splitViewAction->setChecked(false); 1728 splitViewAction->setChecked(false); 1723 fullViewAction->setEnabled(false); 1729 fullViewAction->setEnabled(false); 1724 fullViewAction->setChecked(true); 1730 fullViewAction->setChecked(true); 1725 1731 1726 backAction->setEnabled(false); 1732 backAction->setEnabled(false); 1727 1733 1728 menuList->hide(); 1734 menuList->hide(); 1729 menuList->setRootMenu(0); 1735 menuList->setRootMenu(0); 1730 configList->mode = fullMode; 1736 configList->mode = fullMode; 1731 if (configList->rootEntry == &rootmen 1737 if (configList->rootEntry == &rootmenu) 1732 configList->updateListAll(); 1738 configList->updateListAll(); 1733 else 1739 else 1734 configList->setRootMenu(&root 1740 configList->setRootMenu(&rootmenu); 1735 configList->setFocus(); 1741 configList->setFocus(); 1736 } 1742 } 1737 1743 1738 /* 1744 /* 1739 * ask for saving configuration before quitti 1745 * ask for saving configuration before quitting 1740 */ 1746 */ 1741 void ConfigMainWindow::closeEvent(QCloseEvent 1747 void ConfigMainWindow::closeEvent(QCloseEvent* e) 1742 { 1748 { 1743 if (!conf_get_changed()) { 1749 if (!conf_get_changed()) { 1744 e->accept(); 1750 e->accept(); 1745 return; 1751 return; 1746 } 1752 } 1747 !! 1753 QMessageBox mb("qconf", "Save configuration?", QMessageBox::Warning, 1748 QMessageBox mb(QMessageBox::Icon::War !! 1754 QMessageBox::Yes | QMessageBox::Default, QMessageBox::No, QMessageBox::Cancel | QMessageBox::Escape); 1749 "Save configuration?") !! 1755 mb.setButtonText(QMessageBox::Yes, "&Save Changes"); 1750 !! 1756 mb.setButtonText(QMessageBox::No, "&Discard Changes"); 1751 QPushButton *yb = mb.addButton(QMessa !! 1757 mb.setButtonText(QMessageBox::Cancel, "Cancel Exit"); 1752 QPushButton *db = mb.addButton(QMessa << 1753 QPushButton *cb = mb.addButton(QMessa << 1754 << 1755 yb->setText("&Save Changes"); << 1756 db->setText("&Discard Changes"); << 1757 cb->setText("Cancel Exit"); << 1758 << 1759 mb.setDefaultButton(yb); << 1760 mb.setEscapeButton(cb); << 1761 << 1762 switch (mb.exec()) { 1758 switch (mb.exec()) { 1763 case QMessageBox::Yes: 1759 case QMessageBox::Yes: 1764 if (saveConfig()) 1760 if (saveConfig()) 1765 e->accept(); 1761 e->accept(); 1766 else 1762 else 1767 e->ignore(); 1763 e->ignore(); 1768 break; 1764 break; 1769 case QMessageBox::No: 1765 case QMessageBox::No: 1770 e->accept(); 1766 e->accept(); 1771 break; 1767 break; 1772 case QMessageBox::Cancel: 1768 case QMessageBox::Cancel: 1773 e->ignore(); 1769 e->ignore(); 1774 break; 1770 break; 1775 } 1771 } 1776 } 1772 } 1777 1773 1778 void ConfigMainWindow::showIntro(void) 1774 void ConfigMainWindow::showIntro(void) 1779 { 1775 { 1780 static const QString str = 1776 static const QString str = 1781 "Welcome to the qconf graphic 1777 "Welcome to the qconf graphical configuration tool.\n" 1782 "\n" 1778 "\n" 1783 "For bool and tristate option 1779 "For bool and tristate options, a blank box indicates the " 1784 "feature is disabled, a check 1780 "feature is disabled, a check indicates it is enabled, and a " 1785 "dot indicates that it is to 1781 "dot indicates that it is to be compiled as a module. Clicking " 1786 "on the box will cycle throug 1782 "on the box will cycle through the three states. For int, hex, " 1787 "and string options, double-c 1783 "and string options, double-clicking or pressing F2 on the " 1788 "Value cell will allow you to 1784 "Value cell will allow you to edit the value.\n" 1789 "\n" 1785 "\n" 1790 "If you do not see an option 1786 "If you do not see an option (e.g., a device driver) that you " 1791 "believe should be present, t 1787 "believe should be present, try turning on Show All Options " 1792 "under the Options menu. Enab 1788 "under the Options menu. Enabling Show Debug Info will help you" 1793 "figure out what other option 1789 "figure out what other options must be enabled to support the " 1794 "option you are interested in 1790 "option you are interested in, and hyperlinks will navigate to " 1795 "them.\n" 1791 "them.\n" 1796 "\n" 1792 "\n" 1797 "Toggling Show Debug Info und 1793 "Toggling Show Debug Info under the Options menu will show the " 1798 "dependencies, which you can 1794 "dependencies, which you can then match by examining other " 1799 "options.\n"; 1795 "options.\n"; 1800 1796 1801 QMessageBox::information(this, "qconf 1797 QMessageBox::information(this, "qconf", str); 1802 } 1798 } 1803 1799 1804 void ConfigMainWindow::showAbout(void) 1800 void ConfigMainWindow::showAbout(void) 1805 { 1801 { 1806 static const QString str = "qconf is 1802 static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n" 1807 "Copyright (C) 2015 Boris Bar 1803 "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n" 1808 "\n" 1804 "\n" 1809 "Bug reports and feature requ 1805 "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n" 1810 "\n" 1806 "\n" 1811 "Qt Version: "; 1807 "Qt Version: "; 1812 1808 1813 QMessageBox::information(this, "qconf 1809 QMessageBox::information(this, "qconf", str + qVersion()); 1814 } 1810 } 1815 1811 1816 void ConfigMainWindow::saveSettings(void) 1812 void ConfigMainWindow::saveSettings(void) 1817 { 1813 { 1818 configSettings->setValue("/window x", 1814 configSettings->setValue("/window x", pos().x()); 1819 configSettings->setValue("/window y", 1815 configSettings->setValue("/window y", pos().y()); 1820 configSettings->setValue("/window wid 1816 configSettings->setValue("/window width", size().width()); 1821 configSettings->setValue("/window hei 1817 configSettings->setValue("/window height", size().height()); 1822 1818 1823 QString entry; 1819 QString entry; 1824 switch(configList->mode) { 1820 switch(configList->mode) { 1825 case singleMode : 1821 case singleMode : 1826 entry = "single"; 1822 entry = "single"; 1827 break; 1823 break; 1828 1824 1829 case symbolMode : 1825 case symbolMode : 1830 entry = "split"; 1826 entry = "split"; 1831 break; 1827 break; 1832 1828 1833 case fullMode : 1829 case fullMode : 1834 entry = "full"; 1830 entry = "full"; 1835 break; 1831 break; 1836 1832 1837 default: 1833 default: 1838 break; 1834 break; 1839 } 1835 } 1840 configSettings->setValue("/listMode", 1836 configSettings->setValue("/listMode", entry); 1841 1837 1842 configSettings->writeSizes("/split1", 1838 configSettings->writeSizes("/split1", split1->sizes()); 1843 configSettings->writeSizes("/split2", 1839 configSettings->writeSizes("/split2", split2->sizes()); 1844 } 1840 } 1845 1841 1846 void ConfigMainWindow::conf_changed(bool dirt !! 1842 void ConfigMainWindow::conf_changed(void) 1847 { 1843 { 1848 if (saveAction) 1844 if (saveAction) 1849 saveAction->setEnabled(dirty) !! 1845 saveAction->setEnabled(conf_get_changed()); 1850 } 1846 } 1851 1847 1852 void fixup_rootmenu(struct menu *menu) 1848 void fixup_rootmenu(struct menu *menu) 1853 { 1849 { 1854 struct menu *child; 1850 struct menu *child; 1855 static int menu_cnt = 0; 1851 static int menu_cnt = 0; 1856 1852 1857 menu->flags |= MENU_ROOT; 1853 menu->flags |= MENU_ROOT; 1858 for (child = menu->list; child; child 1854 for (child = menu->list; child; child = child->next) { 1859 if (child->prompt && child->p 1855 if (child->prompt && child->prompt->type == P_MENU) { 1860 menu_cnt++; 1856 menu_cnt++; 1861 fixup_rootmenu(child) 1857 fixup_rootmenu(child); 1862 menu_cnt--; 1858 menu_cnt--; 1863 } else if (!menu_cnt) 1859 } else if (!menu_cnt) 1864 fixup_rootmenu(child) 1860 fixup_rootmenu(child); 1865 } 1861 } 1866 } 1862 } 1867 1863 1868 static const char *progname; 1864 static const char *progname; 1869 1865 1870 static void usage(void) 1866 static void usage(void) 1871 { 1867 { 1872 printf("%s [-s] <config>\n", progname 1868 printf("%s [-s] <config>\n", progname); 1873 exit(0); 1869 exit(0); 1874 } 1870 } 1875 1871 1876 int main(int ac, char** av) 1872 int main(int ac, char** av) 1877 { 1873 { 1878 ConfigMainWindow* v; 1874 ConfigMainWindow* v; 1879 const char *name; 1875 const char *name; 1880 1876 1881 progname = av[0]; 1877 progname = av[0]; 1882 if (ac > 1 && av[1][0] == '-') { 1878 if (ac > 1 && av[1][0] == '-') { 1883 switch (av[1][1]) { 1879 switch (av[1][1]) { 1884 case 's': 1880 case 's': 1885 conf_set_message_call 1881 conf_set_message_callback(NULL); 1886 break; 1882 break; 1887 case 'h': 1883 case 'h': 1888 case '?': 1884 case '?': 1889 usage(); 1885 usage(); 1890 } 1886 } 1891 name = av[2]; 1887 name = av[2]; 1892 } else 1888 } else 1893 name = av[1]; 1889 name = av[1]; 1894 if (!name) 1890 if (!name) 1895 usage(); 1891 usage(); 1896 1892 1897 conf_parse(name); 1893 conf_parse(name); 1898 fixup_rootmenu(&rootmenu); 1894 fixup_rootmenu(&rootmenu); >> 1895 conf_read(NULL); 1899 //zconfdump(stdout); 1896 //zconfdump(stdout); 1900 1897 1901 configApp = new QApplication(ac, av); 1898 configApp = new QApplication(ac, av); 1902 1899 1903 configSettings = new ConfigSettings() 1900 configSettings = new ConfigSettings(); 1904 configSettings->beginGroup("/kconfig/ 1901 configSettings->beginGroup("/kconfig/qconf"); 1905 v = new ConfigMainWindow(); 1902 v = new ConfigMainWindow(); 1906 1903 1907 //zconfdump(stdout); 1904 //zconfdump(stdout); 1908 configApp->connect(configApp, SIGNAL( 1905 configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit())); 1909 configApp->connect(configApp, SIGNAL( 1906 configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings())); 1910 << 1911 v->show(); 1907 v->show(); 1912 configApp->exec(); 1908 configApp->exec(); 1913 1909 1914 configSettings->endGroup(); 1910 configSettings->endGroup(); 1915 delete configSettings; 1911 delete configSettings; 1916 delete v; 1912 delete v; 1917 delete configApp; 1913 delete configApp; 1918 1914 1919 return 0; 1915 return 0; 1920 } 1916 } 1921 1917
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.