build: scripts/config - update to kconfig-v5.14
[openwrt/staging/jow.git] / scripts / config / qconf.cc
index a1e4d263e3c0df651a812959e62a0deb2f524c0f..ed7b3e3e20e9b5ec19514aa1e745a562de847bac 100644 (file)
@@ -4,34 +4,25 @@
  * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
  */
 
-#include <qglobal.h>
-
-#include <QMainWindow>
-#include <QList>
-#include <qtextbrowser.h>
 #include <QAction>
+#include <QApplication>
+#include <QCloseEvent>
+#include <QDebug>
+#include <QDesktopWidget>
 #include <QFileDialog>
+#include <QLabel>
+#include <QLayout>
+#include <QList>
 #include <QMenu>
-
-#include <qapplication.h>
-#include <qdesktopwidget.h>
-#include <qtoolbar.h>
-#include <qlayout.h>
-#include <qsplitter.h>
-#include <qlineedit.h>
-#include <qlabel.h>
-#include <qpushbutton.h>
-#include <qmenubar.h>
-#include <qmessagebox.h>
-#include <qregexp.h>
-#include <qevent.h>
+#include <QMenuBar>
+#include <QMessageBox>
+#include <QToolBar>
 
 #include <stdlib.h>
 
 #include "lkc.h"
 #include "qconf.h"
 
-#include "qconf.moc"
 #include "images.h"
 
 
@@ -40,11 +31,6 @@ static ConfigSettings *configSettings;
 
 QAction *ConfigMainWindow::saveAction;
 
-static inline QString qgettext(const char* str)
-{
-       return QString::fromLocal8Bit(str);
-}
-
 ConfigSettings::ConfigSettings()
        : QSettings("kernel.org", "qconf")
 {
@@ -88,14 +74,13 @@ bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
        return true;
 }
 
-
-/*
- * set the new data
- * TODO check the value
- */
-void ConfigItem::okRename(int col)
-{
-}
+QIcon ConfigItem::symbolYesIcon;
+QIcon ConfigItem::symbolModIcon;
+QIcon ConfigItem::symbolNoIcon;
+QIcon ConfigItem::choiceYesIcon;
+QIcon ConfigItem::choiceNoIcon;
+QIcon ConfigItem::menuIcon;
+QIcon ConfigItem::menubackIcon;
 
 /*
  * update the displayed of a menu entry
@@ -111,14 +96,14 @@ void ConfigItem::updateMenu(void)
 
        list = listView();
        if (goParent) {
-               setPixmap(promptColIdx, list->menuBackPix);
+               setIcon(promptColIdx, menubackIcon);
                prompt = "..";
                goto set_prompt;
        }
 
        sym = menu->sym;
        prop = menu->prompt;
-       prompt = qgettext(menu_get_prompt(menu));
+       prompt = menu_get_prompt(menu);
 
        if (prop) switch (prop->type) {
        case P_MENU:
@@ -128,15 +113,16 @@ void ConfigItem::updateMenu(void)
                         */
                        if (sym && list->rootEntry == menu)
                                break;
-                       setPixmap(promptColIdx, list->menuPix);
+                       setIcon(promptColIdx, menuIcon);
                } else {
                        if (sym)
                                break;
-                       setPixmap(promptColIdx, QIcon());
+                       setIcon(promptColIdx, QIcon());
                }
                goto set_prompt;
        case P_COMMENT:
-               setPixmap(promptColIdx, QIcon());
+               setIcon(promptColIdx, QIcon());
+               prompt = "*** " + prompt + " ***";
                goto set_prompt;
        default:
                ;
@@ -144,7 +130,7 @@ void ConfigItem::updateMenu(void)
        if (!sym)
                goto set_prompt;
 
-       setText(nameColIdx, QString::fromLocal8Bit(sym->name));
+       setText(nameColIdx, sym->name);
 
        type = sym_get_type(sym);
        switch (type) {
@@ -153,57 +139,37 @@ void ConfigItem::updateMenu(void)
                char ch;
 
                if (!sym_is_changeable(sym) && list->optMode == normalOpt) {
-                       setPixmap(promptColIdx, QIcon());
-                       setText(noColIdx, QString::null);
-                       setText(modColIdx, QString::null);
-                       setText(yesColIdx, QString::null);
+                       setIcon(promptColIdx, QIcon());
                        break;
                }
                expr = sym_get_tristate_value(sym);
                switch (expr) {
                case yes:
                        if (sym_is_choice_value(sym) && type == S_BOOLEAN)
-                               setPixmap(promptColIdx, list->choiceYesPix);
+                               setIcon(promptColIdx, choiceYesIcon);
                        else
-                               setPixmap(promptColIdx, list->symbolYesPix);
-                       setText(yesColIdx, "Y");
+                               setIcon(promptColIdx, symbolYesIcon);
                        ch = 'Y';
                        break;
                case mod:
-                       setPixmap(promptColIdx, list->symbolModPix);
-                       setText(modColIdx, "M");
+                       setIcon(promptColIdx, symbolModIcon);
                        ch = 'M';
                        break;
                default:
                        if (sym_is_choice_value(sym) && type == S_BOOLEAN)
-                               setPixmap(promptColIdx, list->choiceNoPix);
+                               setIcon(promptColIdx, choiceNoIcon);
                        else
-                               setPixmap(promptColIdx, list->symbolNoPix);
-                       setText(noColIdx, "N");
+                               setIcon(promptColIdx, symbolNoIcon);
                        ch = 'N';
                        break;
                }
-               if (expr != no)
-                       setText(noColIdx, sym_tristate_within_range(sym, no) ? "_" : 0);
-               if (expr != mod)
-                       setText(modColIdx, sym_tristate_within_range(sym, mod) ? "_" : 0);
-               if (expr != yes)
-                       setText(yesColIdx, sym_tristate_within_range(sym, yes) ? "_" : 0);
 
                setText(dataColIdx, QChar(ch));
                break;
        case S_INT:
        case S_HEX:
        case S_STRING:
-               const char* data;
-
-               data = sym_get_string_value(sym);
-
-               setText(dataColIdx, data);
-               if (type == S_STRING)
-                       prompt = QString("%1: %2").arg(prompt).arg(data);
-               else
-                       prompt = QString("(%2) %1").arg(prompt).arg(data);
+               setText(dataColIdx, sym_get_string_value(sym));
                break;
        }
        if (!sym_has_value(sym) && visible)
@@ -244,6 +210,17 @@ void ConfigItem::init(void)
                if (list->mode != fullMode)
                        setExpanded(true);
                sym_calc_value(menu->sym);
+
+               if (menu->sym) {
+                       enum symbol_type type = menu->sym->type;
+
+                       // Allow to edit "int", "hex", and "string" in-place in
+                       // the data column. Unfortunately, you cannot specify
+                       // the flags per column. Set ItemIsEditable for all
+                       // columns here, and check the column in createEditor().
+                       if (type == S_INT || type == S_HEX || type == S_STRING)
+                               setFlags(flags() | Qt::ItemIsEditable);
+               }
        }
        updateMenu();
 }
@@ -264,53 +241,67 @@ ConfigItem::~ConfigItem(void)
        }
 }
 
-ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
-       : Parent(parent)
+QWidget *ConfigItemDelegate::createEditor(QWidget *parent,
+                                         const QStyleOptionViewItem &option,
+                                         const QModelIndex &index) const
 {
-       connect(this, SIGNAL(editingFinished()), SLOT(hide()));
-}
+       ConfigItem *item;
 
-void ConfigLineEdit::show(ConfigItem* i)
-{
-       item = i;
-       if (sym_get_string_value(item->menu->sym))
-               setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym)));
-       else
-               setText(QString::null);
-       Parent::show();
-       setFocus();
+       // Only the data column is editable
+       if (index.column() != dataColIdx)
+               return nullptr;
+
+       // You cannot edit invisible menus
+       item = static_cast<ConfigItem *>(index.internalPointer());
+       if (!item || !item->menu || !menu_is_visible(item->menu))
+               return nullptr;
+
+       return QStyledItemDelegate::createEditor(parent, option, index);
 }
 
-void ConfigLineEdit::keyPressEvent(QKeyEvent* e)
+void ConfigItemDelegate::setModelData(QWidget *editor,
+                                     QAbstractItemModel *model,
+                                     const QModelIndex &index) const
 {
-       switch (e->key()) {
-       case Qt::Key_Escape:
-               break;
-       case Qt::Key_Return:
-       case Qt::Key_Enter:
-               sym_set_string_value(item->menu->sym, text().toLatin1());
-               parent()->updateList(item);
-               break;
-       default:
-               Parent::keyPressEvent(e);
-               return;
+       QLineEdit *lineEdit;
+       ConfigItem *item;
+       struct symbol *sym;
+       bool success;
+
+       lineEdit = qobject_cast<QLineEdit *>(editor);
+       // If this is not a QLineEdit, use the parent's default.
+       // (does this happen?)
+       if (!lineEdit)
+               goto parent;
+
+       item = static_cast<ConfigItem *>(index.internalPointer());
+       if (!item || !item->menu)
+               goto parent;
+
+       sym = item->menu->sym;
+       if (!sym)
+               goto parent;
+
+       success = sym_set_string_value(sym, lineEdit->text().toUtf8().data());
+       if (success) {
+               ConfigList::updateListForAll();
+       } else {
+               QMessageBox::information(editor, "qconf",
+                       "Cannot set the data (maybe due to out of range).\n"
+                       "Setting the old value.");
+               lineEdit->setText(sym_get_string_value(sym));
        }
-       e->accept();
-       parent()->list->setFocus();
-       hide();
+
+parent:
+       QStyledItemDelegate::setModelData(editor, model, index);
 }
 
-ConfigList::ConfigList(ConfigView* p, const char *name)
-       : Parent(p),
+ConfigList::ConfigList(QWidget *parent, const char *name)
+       : QTreeWidget(parent),
          updateAll(false),
-         symbolYesPix(xpm_symbol_yes), symbolModPix(xpm_symbol_mod), symbolNoPix(xpm_symbol_no),
-         choiceYesPix(xpm_choice_yes), choiceNoPix(xpm_choice_no),
-         menuPix(xpm_menu), menuInvPix(xpm_menu_inv), menuBackPix(xpm_menuback), voidPix(xpm_void),
-         showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
+         showName(false), mode(singleMode), optMode(normalOpt),
          rootEntry(0), headerPopup(0)
 {
-       int i;
-
        setObjectName(name);
        setSortingEnabled(false);
        setRootIsDecorated(true);
@@ -318,26 +309,34 @@ ConfigList::ConfigList(ConfigView* p, const char *name)
        setVerticalScrollMode(ScrollPerPixel);
        setHorizontalScrollMode(ScrollPerPixel);
 
-       setHeaderLabels(QStringList() << "Option" << "Name" << "N" << "M" << "Y" << "Value");
+       setHeaderLabels(QStringList() << "Option" << "Name" << "Value");
 
-       connect(this, SIGNAL(itemSelectionChanged(void)),
-               SLOT(updateSelection(void)));
+       connect(this, &ConfigList::itemSelectionChanged,
+               this, &ConfigList::updateSelection);
 
        if (name) {
                configSettings->beginGroup(name);
                showName = configSettings->value("/showName", false).toBool();
-               showRange = configSettings->value("/showRange", false).toBool();
-               showData = configSettings->value("/showData", false).toBool();
                optMode = (enum optionMode)configSettings->value("/optionMode", 0).toInt();
                configSettings->endGroup();
-               connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
+               connect(configApp, &QApplication::aboutToQuit,
+                       this, &ConfigList::saveSettings);
        }
 
-       addColumn(promptColIdx);
+       showColumn(promptColIdx);
+
+       setItemDelegate(new ConfigItemDelegate(this));
+
+       allLists.append(this);
 
        reinit();
 }
 
+ConfigList::~ConfigList()
+{
+       allLists.removeOne(this);
+}
+
 bool ConfigList::menuSkip(struct menu *menu)
 {
        if (optMode == normalOpt && menu_is_visible(menu))
@@ -351,21 +350,22 @@ bool ConfigList::menuSkip(struct menu *menu)
 
 void ConfigList::reinit(void)
 {
-       removeColumn(dataColIdx);
-       removeColumn(yesColIdx);
-       removeColumn(modColIdx);
-       removeColumn(noColIdx);
-       removeColumn(nameColIdx);
+       hideColumn(nameColIdx);
 
        if (showName)
-               addColumn(nameColIdx);
-       if (showRange) {
-               addColumn(noColIdx);
-               addColumn(modColIdx);
-               addColumn(yesColIdx);
-       }
-       if (showData)
-               addColumn(dataColIdx);
+               showColumn(nameColIdx);
+
+       updateListAll();
+}
+
+void ConfigList::setOptionMode(QAction *action)
+{
+       if (action == showNormalAction)
+               optMode = normalOpt;
+       else if (action == showAllAction)
+               optMode = allOpt;
+       else
+               optMode = promptOpt;
 
        updateListAll();
 }
@@ -375,8 +375,6 @@ void ConfigList::saveSettings(void)
        if (!objectName().isEmpty()) {
                configSettings->beginGroup(objectName());
                configSettings->setValue("/showName", showName);
-               configSettings->setValue("/showRange", showRange);
-               configSettings->setValue("/showData", showData);
                configSettings->setValue("/optionMode", (int)optMode);
                configSettings->endGroup();
        }
@@ -415,15 +413,15 @@ void ConfigList::updateSelection(void)
                emit menuSelected(menu);
 }
 
-void ConfigList::updateList(ConfigItem* item)
+void ConfigList::updateList()
 {
        ConfigItem* last = 0;
+       ConfigItem *item;
 
        if (!rootEntry) {
                if (mode != listMode)
                        goto update;
                QTreeWidgetItemIterator it(this);
-               ConfigItem* item;
 
                while (*it) {
                        item = (ConfigItem*)(*it);
@@ -445,7 +443,7 @@ void ConfigList::updateList(ConfigItem* item)
        }
        if ((mode == singleMode || (mode == symbolMode && !(rootEntry->flags & MENU_ROOT))) &&
            rootEntry->sym && rootEntry->prompt) {
-               item = last ? last->nextSibling() : firstChild();
+               item = last ? last->nextSibling() : nullptr;
                if (!item)
                        item = new ConfigItem(this, last, rootEntry, true);
                else
@@ -457,11 +455,33 @@ void ConfigList::updateList(ConfigItem* item)
                return;
        }
 update:
-       updateMenuList(this, rootEntry);
+       updateMenuList(rootEntry);
        update();
        resizeColumnToContents(0);
 }
 
+void ConfigList::updateListForAll()
+{
+       QListIterator<ConfigList *> it(allLists);
+
+       while (it.hasNext()) {
+               ConfigList *list = it.next();
+
+               list->updateList();
+       }
+}
+
+void ConfigList::updateListAllForAll()
+{
+       QListIterator<ConfigList *> it(allLists);
+
+       while (it.hasNext()) {
+               ConfigList *list = it.next();
+
+               list->updateList();
+       }
+}
+
 void ConfigList::setValue(ConfigItem* item, tristate val)
 {
        struct symbol* sym;
@@ -482,7 +502,7 @@ void ConfigList::setValue(ConfigItem* item, tristate val)
                        return;
                if (oldval == no && item->menu->list)
                        item->setExpanded(true);
-               parent()->updateList(item);
+               ConfigList::updateListForAll();
                break;
        }
 }
@@ -516,12 +536,9 @@ void ConfigList::changeValue(ConfigItem* item)
                                item->setExpanded(true);
                }
                if (oldexpr != newexpr)
-                       parent()->updateList(item);
+                       ConfigList::updateListForAll();
                break;
-       case S_INT:
-       case S_HEX:
-       case S_STRING:
-               parent()->lineEdit->show(item);
+       default:
                break;
        }
 }
@@ -535,11 +552,11 @@ void ConfigList::setRootMenu(struct menu *menu)
        type = menu && menu->prompt ? menu->prompt->type : P_UNKNOWN;
        if (type != P_MENU)
                return;
-       updateMenuList(this, 0);
+       updateMenuList(0);
        rootEntry = menu;
        updateListAll();
        if (currentItem()) {
-               currentItem()->setSelected(hasFocus());
+               setSelected(currentItem(), hasFocus());
                scrollToItem(currentItem());
        }
 }
@@ -627,7 +644,7 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
                        last = item;
                        continue;
                }
-       hide:
+hide:
                if (item && item->menu == child) {
                        last = parent->firstChild();
                        if (last == item)
@@ -639,7 +656,7 @@ void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
        }
 }
 
-void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
+void ConfigList::updateMenuList(struct menu *menu)
 {
        struct menu* child;
        ConfigItem* item;
@@ -648,19 +665,19 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
        enum prop_type type;
 
        if (!menu) {
-               while (parent->topLevelItemCount() > 0)
+               while (topLevelItemCount() > 0)
                {
-                       delete parent->takeTopLevelItem(0);
+                       delete takeTopLevelItem(0);
                }
 
                return;
        }
 
-       last = (ConfigItem*)parent->topLevelItem(0);
+       last = (ConfigItem *)topLevelItem(0);
        if (last && !last->goParent)
                last = 0;
        for (child = menu->list; child; child = child->next) {
-               item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
+               item = last ? last->nextSibling() : (ConfigItem *)topLevelItem(0);
                type = child->prompt ? child->prompt->type : P_UNKNOWN;
 
                switch (mode) {
@@ -681,7 +698,7 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
                        if (!child->sym && !child->list && !child->prompt)
                                continue;
                        if (!item || item->menu != child)
-                               item = new ConfigItem(parent, last, child, visible);
+                               item = new ConfigItem(this, last, child, visible);
                        else
                                item->testUpdateMenu(visible);
 
@@ -692,9 +709,9 @@ void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
                        last = item;
                        continue;
                }
-       hide:
+hide:
                if (item && item->menu == child) {
-                       last = (ConfigItem*)parent->topLevelItem(0);
+                       last = (ConfigItem *)topLevelItem(0);
                        if (last == item)
                                last = 0;
                        else while (last->nextSibling() != item)
@@ -736,7 +753,10 @@ void ConfigList::keyPressEvent(QKeyEvent* ev)
                type = menu->prompt ? menu->prompt->type : P_UNKNOWN;
                if (type == P_MENU && rootEntry != menu &&
                    mode != fullMode && mode != menuMode) {
-                       emit menuSelected(menu);
+                       if (mode == menuMode)
+                               emit menuSelected(menu);
+                       else
+                               emit itemSelected(menu);
                        break;
                }
        case Qt::Key_Space:
@@ -782,7 +802,7 @@ void ConfigList::mouseReleaseEvent(QMouseEvent* e)
        idx = header()->logicalIndexAt(x);
        switch (idx) {
        case promptColIdx:
-               icon = item->pixmap(promptColIdx);
+               icon = item->icon(promptColIdx);
                if (!icon.isNull()) {
                        int off = header()->sectionPosition(0) + visualRect(indexAt(p)).x() + 4; // 4 is Hardcoded image offset. There might be a way to do it properly.
                        if (x >= off && x < off + icon.availableSizes().first().width()) {
@@ -793,22 +813,14 @@ void ConfigList::mouseReleaseEvent(QMouseEvent* e)
                                        break;
                                ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
                                if (ptype == P_MENU && rootEntry != menu &&
-                                   mode != fullMode && mode != menuMode)
+                                   mode != fullMode && mode != menuMode &&
+                                    mode != listMode)
                                        emit menuSelected(menu);
                                else
                                        changeValue(item);
                        }
                }
                break;
-       case noColIdx:
-               setValue(item, no);
-               break;
-       case modColIdx:
-               setValue(item, mod);
-               break;
-       case yesColIdx:
-               setValue(item, yes);
-               break;
        case dataColIdx:
                changeValue(item);
                break;
@@ -828,7 +840,7 @@ void ConfigList::mouseMoveEvent(QMouseEvent* e)
 
 void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
 {
-       QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
+       QPoint p = e->pos();
        ConfigItem* item = (ConfigItem*)itemAt(p);
        struct menu *menu;
        enum prop_type ptype;
@@ -843,9 +855,12 @@ void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
        if (!menu)
                goto skip;
        ptype = menu->prompt ? menu->prompt->type : P_UNKNOWN;
-       if (ptype == P_MENU && (mode == singleMode || mode == symbolMode))
-               emit menuSelected(menu);
-       else if (menu->sym)
+       if (ptype == P_MENU && mode != listMode) {
+               if (mode == singleMode)
+                       emit itemSelected(menu);
+               else if (mode == symbolMode)
+                       emit menuSelected(menu);
+       } else if (menu->sym)
                changeValue(item);
 
 skip:
@@ -861,7 +876,7 @@ void ConfigList::focusInEvent(QFocusEvent *e)
 
        ConfigItem* item = (ConfigItem *)currentItem();
        if (item) {
-               item->setSelected(true);
+               setSelected(item, true);
                menu = item->menu;
        }
        emit gotFocus(menu);
@@ -869,114 +884,38 @@ void ConfigList::focusInEvent(QFocusEvent *e)
 
 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
 {
-       if (e->y() <= header()->geometry().bottom()) {
-               if (!headerPopup) {
-                       QAction *action;
-
-                       headerPopup = new QMenu(this);
-                       action = new QAction("Show Name", this);
-                         action->setCheckable(true);
-                         connect(action, SIGNAL(toggled(bool)),
-                                 parent(), SLOT(setShowName(bool)));
-                         connect(parent(), SIGNAL(showNameChanged(bool)),
-                                 action, SLOT(setOn(bool)));
-                         action->setChecked(showName);
-                         headerPopup->addAction(action);
-                       action = new QAction("Show Range", this);
-                         action->setCheckable(true);
-                         connect(action, SIGNAL(toggled(bool)),
-                                 parent(), SLOT(setShowRange(bool)));
-                         connect(parent(), SIGNAL(showRangeChanged(bool)),
-                                 action, SLOT(setOn(bool)));
-                         action->setChecked(showRange);
-                         headerPopup->addAction(action);
-                       action = new QAction("Show Data", this);
-                         action->setCheckable(true);
-                         connect(action, SIGNAL(toggled(bool)),
-                                 parent(), SLOT(setShowData(bool)));
-                         connect(parent(), SIGNAL(showDataChanged(bool)),
-                                 action, SLOT(setOn(bool)));
-                         action->setChecked(showData);
-                         headerPopup->addAction(action);
-               }
-               headerPopup->exec(e->globalPos());
-               e->accept();
-       } else
-               e->ignore();
-}
-
-ConfigView*ConfigView::viewList;
-QAction *ConfigView::showNormalAction;
-QAction *ConfigView::showAllAction;
-QAction *ConfigView::showPromptAction;
-
-ConfigView::ConfigView(QWidget* parent, const char *name)
-       : Parent(parent)
-{
-       setObjectName(name);
-       QVBoxLayout *verticalLayout = new QVBoxLayout(this);
-       verticalLayout->setContentsMargins(0, 0, 0, 0);
-
-       list = new ConfigList(this);
-       verticalLayout->addWidget(list);
-       lineEdit = new ConfigLineEdit(this);
-       lineEdit->hide();
-       verticalLayout->addWidget(lineEdit);
-
-       this->nextView = viewList;
-       viewList = this;
-}
-
-ConfigView::~ConfigView(void)
-{
-       ConfigView** vp;
-
-       for (vp = &viewList; *vp; vp = &(*vp)->nextView) {
-               if (*vp == this) {
-                       *vp = nextView;
-                       break;
-               }
+       if (!headerPopup) {
+               QAction *action;
+
+               headerPopup = new QMenu(this);
+               action = new QAction("Show Name", this);
+               action->setCheckable(true);
+               connect(action, &QAction::toggled,
+                       this, &ConfigList::setShowName);
+               connect(this, &ConfigList::showNameChanged,
+                       action, &QAction::setChecked);
+               action->setChecked(showName);
+               headerPopup->addAction(action);
        }
-}
 
-void ConfigView::setOptionMode(QAction *act)
-{
-       if (act == showNormalAction)
-               list->optMode = normalOpt;
-       else if (act == showAllAction)
-               list->optMode = allOpt;
-       else
-               list->optMode = promptOpt;
-
-       list->updateListAll();
+       headerPopup->exec(e->globalPos());
+       e->accept();
 }
 
-void ConfigView::setShowName(bool b)
+void ConfigList::setShowName(bool on)
 {
-       if (list->showName != b) {
-               list->showName = b;
-               list->reinit();
-               emit showNameChanged(b);
-       }
-}
+       if (showName == on)
+               return;
 
-void ConfigView::setShowRange(bool b)
-{
-       if (list->showRange != b) {
-               list->showRange = b;
-               list->reinit();
-               emit showRangeChanged(b);
-       }
+       showName = on;
+       reinit();
+       emit showNameChanged(on);
 }
 
-void ConfigView::setShowData(bool b)
-{
-       if (list->showData != b) {
-               list->showData = b;
-               list->reinit();
-               emit showDataChanged(b);
-       }
-}
+QList<ConfigList *> ConfigList::allLists;
+QAction *ConfigList::showNormalAction;
+QAction *ConfigList::showAllAction;
+QAction *ConfigList::showPromptAction;
 
 void ConfigList::setAllOpen(bool open)
 {
@@ -989,34 +928,31 @@ void ConfigList::setAllOpen(bool open)
        }
 }
 
-void ConfigView::updateList(ConfigItem* item)
-{
-       ConfigView* v;
-
-       for (v = viewList; v; v = v->nextView)
-               v->list->updateList(item);
-}
-
-void ConfigView::updateListAll(void)
-{
-       ConfigView* v;
-
-       for (v = viewList; v; v = v->nextView)
-               v->list->updateListAll();
-}
-
 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
        : Parent(parent), sym(0), _menu(0)
 {
        setObjectName(name);
-
+       setOpenLinks(false);
 
        if (!objectName().isEmpty()) {
                configSettings->beginGroup(objectName());
                setShowDebug(configSettings->value("/showDebug", false).toBool());
                configSettings->endGroup();
-               connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
+               connect(configApp, &QApplication::aboutToQuit,
+                       this, &ConfigInfoView::saveSettings);
        }
+
+       contextMenu = createStandardContextMenu();
+       QAction *action = new QAction("Show Debug Info", contextMenu);
+
+       action->setCheckable(true);
+       connect(action, &QAction::toggled,
+               this, &ConfigInfoView::setShowDebug);
+       connect(this, &ConfigInfoView::showDebugChanged,
+               action, &QAction::setChecked);
+       action->setChecked(showDebug());
+       contextMenu->addSeparator();
+       contextMenu->addAction(action);
 }
 
 void ConfigInfoView::saveSettings(void)
@@ -1071,108 +1007,119 @@ void ConfigInfoView::symbolInfo(void)
 void ConfigInfoView::menuInfo(void)
 {
        struct symbol* sym;
-       QString head, debug, help;
+       QString info;
+       QTextStream stream(&info);
 
        sym = _menu->sym;
        if (sym) {
                if (_menu->prompt) {
-                       head += "<big><b>";
-                       head += print_filter(_menu->prompt->text);
-                       head += "</b></big>";
+                       stream << "<big><b>";
+                       stream << print_filter(_menu->prompt->text);
+                       stream << "</b></big>";
                        if (sym->name) {
-                               head += " (";
+                               stream << " (";
                                if (showDebug())
-                                       head += QString().sprintf("<a href=\"s%p\">", sym);
-                               head += print_filter(sym->name);
+                                       stream << "<a href=\"s" << sym->name << "\">";
+                               stream << print_filter(sym->name);
                                if (showDebug())
-                                       head += "</a>";
-                               head += ")";
+                                       stream << "</a>";
+                               stream << ")";
                        }
                } else if (sym->name) {
-                       head += "<big><b>";
+                       stream << "<big><b>";
                        if (showDebug())
-                               head += QString().sprintf("<a href=\"s%p\">", sym);
-                       head += print_filter(sym->name);
+                               stream << "<a href=\"s" << sym->name << "\">";
+                       stream << print_filter(sym->name);
                        if (showDebug())
-                               head += "</a>";
-                       head += "</b></big>";
+                               stream << "</a>";
+                       stream << "</b></big>";
                }
-               head += "<br><br>";
+               stream << "<br><br>";
 
                if (showDebug())
-                       debug = debug_info(sym);
+                       stream << debug_info(sym);
 
                struct gstr help_gstr = str_new();
+
                menu_get_ext_help(_menu, &help_gstr);
-               help = print_filter(str_get(&help_gstr));
+               stream << print_filter(str_get(&help_gstr));
                str_free(&help_gstr);
        } else if (_menu->prompt) {
-               head += "<big><b>";
-               head += print_filter(_menu->prompt->text);
-               head += "</b></big><br><br>";
+               stream << "<big><b>";
+               stream << print_filter(_menu->prompt->text);
+               stream << "</b></big><br><br>";
                if (showDebug()) {
                        if (_menu->prompt->visible.expr) {
-                               debug += "&nbsp;&nbsp;dep: ";
-                               expr_print(_menu->prompt->visible.expr, expr_print_help, &debug, E_NONE);
-                               debug += "<br><br>";
+                               stream << "&nbsp;&nbsp;dep: ";
+                               expr_print(_menu->prompt->visible.expr,
+                                          expr_print_help, &stream, E_NONE);
+                               stream << "<br><br>";
                        }
+
+                       stream << "defined at " << _menu->file->name << ":"
+                              << _menu->lineno << "<br><br>";
                }
        }
-       if (showDebug())
-               debug += QString().sprintf("defined at %s:%d<br><br>", _menu->file->name, _menu->lineno);
 
-       setText(head + debug + help);
+       setText(info);
 }
 
 QString ConfigInfoView::debug_info(struct symbol *sym)
 {
        QString debug;
+       QTextStream stream(&debug);
 
-       debug += "type: ";
-       debug += print_filter(sym_type_name(sym->type));
+       stream << "type: ";
+       stream << print_filter(sym_type_name(sym->type));
        if (sym_is_choice(sym))
-               debug += " (choice)";
+               stream << " (choice)";
        debug += "<br>";
        if (sym->rev_dep.expr) {
-               debug += "reverse dep: ";
-               expr_print(sym->rev_dep.expr, expr_print_help, &debug, E_NONE);
-               debug += "<br>";
+               stream << "reverse dep: ";
+               expr_print(sym->rev_dep.expr, expr_print_help, &stream, E_NONE);
+               stream << "<br>";
        }
        for (struct property *prop = sym->prop; prop; prop = prop->next) {
                switch (prop->type) {
                case P_PROMPT:
                case P_MENU:
-                       debug += QString().sprintf("prompt: <a href=\"m%p\">", prop->menu);
-                       debug += print_filter(prop->text);
-                       debug += "</a><br>";
+                       stream << "prompt: <a href=\"m" << sym->name << "\">";
+                       stream << print_filter(prop->text);
+                       stream << "</a><br>";
                        break;
                case P_DEFAULT:
                case P_SELECT:
                case P_RANGE:
-                       debug += prop_get_type_name(prop->type);
-                       debug += ": ";
-                       expr_print(prop->expr, expr_print_help, &debug, E_NONE);
-                       debug += "<br>";
+               case P_COMMENT:
+               case P_IMPLY:
+               case P_SYMBOL:
+                       stream << prop_get_type_name(prop->type);
+                       stream << ": ";
+                       expr_print(prop->expr, expr_print_help,
+                                  &stream, E_NONE);
+                       stream << "<br>";
                        break;
                case P_CHOICE:
                        if (sym_is_choice(sym)) {
-                               debug += "choice: ";
-                               expr_print(prop->expr, expr_print_help, &debug, E_NONE);
-                               debug += "<br>";
+                               stream << "choice: ";
+                               expr_print(prop->expr, expr_print_help,
+                                          &stream, E_NONE);
+                               stream << "<br>";
                        }
                        break;
                default:
-                       debug += "unknown property: ";
-                       debug += prop_get_type_name(prop->type);
-                       debug += "<br>";
+                       stream << "unknown property: ";
+                       stream << prop_get_type_name(prop->type);
+                       stream << "<br>";
                }
                if (prop->visible.expr) {
-                       debug += "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
-                       expr_print(prop->visible.expr, expr_print_help, &debug, E_NONE);
-                       debug += "<br>";
+                       stream << "&nbsp;&nbsp;&nbsp;&nbsp;dep: ";
+                       expr_print(prop->visible.expr, expr_print_help,
+                                  &stream, E_NONE);
+                       stream << "<br>";
                }
        }
-       debug += "<br>";
+       stream << "<br>";
 
        return debug;
 }
@@ -1210,88 +1157,125 @@ QString ConfigInfoView::print_filter(const QString &str)
 
 void ConfigInfoView::expr_print_help(void *data, struct symbol *sym, const char *str)
 {
-       QString* text = reinterpret_cast<QString*>(data);
-       QString str2 = print_filter(str);
+       QTextStream *stream = reinterpret_cast<QTextStream *>(data);
 
        if (sym && sym->name && !(sym->flags & SYMBOL_CONST)) {
-               *text += QString().sprintf("<a href=\"s%p\">", sym);
-               *text += str2;
-               *text += "</a>";
-       } else
-               *text += str2;
+               *stream << "<a href=\"s" << sym->name << "\">";
+               *stream << print_filter(str);
+               *stream << "</a>";
+       } else {
+               *stream << print_filter(str);
+       }
 }
 
-QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
+void ConfigInfoView::clicked(const QUrl &url)
 {
-       QMenu* popup = Parent::createStandardContextMenu(pos);
-       QAction* action = new QAction("Show Debug Info", popup);
-         action->setCheckable(true);
-         connect(action, SIGNAL(toggled(bool)), SLOT(setShowDebug(bool)));
-         connect(this, SIGNAL(showDebugChanged(bool)), action, SLOT(setOn(bool)));
-         action->setChecked(showDebug());
-       popup->addSeparator();
-       popup->addAction(action);
-       return popup;
+       QByteArray str = url.toEncoded();
+       const std::size_t count = str.size();
+       char *data = new char[count + 1];
+       struct symbol **result;
+       struct menu *m = NULL;
+
+       if (count < 1) {
+               delete[] data;
+               return;
+       }
+
+       memcpy(data, str.constData(), count);
+       data[count] = '\0';
+
+       /* Seek for exact match */
+       data[0] = '^';
+       strcat(data, "$");
+       result = sym_re_search(data);
+       if (!result) {
+               delete[] data;
+               return;
+       }
+
+       sym = *result;
+
+       /* Seek for the menu which holds the symbol */
+       for (struct property *prop = sym->prop; prop; prop = prop->next) {
+                   if (prop->type != P_PROMPT && prop->type != P_MENU)
+                           continue;
+                   m = prop->menu;
+                   break;
+       }
+
+       if (!m) {
+               /* Symbol is not visible as a menu */
+               symbolInfo();
+               emit showDebugChanged(true);
+       } else {
+               emit menuSelected(m);
+       }
+
+       free(result);
+       delete[] data;
 }
 
-void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
+void ConfigInfoView::contextMenuEvent(QContextMenuEvent *event)
 {
-       Parent::contextMenuEvent(e);
+       contextMenu->popup(event->globalPos());
+       event->accept();
 }
 
-ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
+ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow *parent)
        : Parent(parent), result(NULL)
 {
-       setObjectName(name);
+       setObjectName("search");
        setWindowTitle("Search Config");
 
        QVBoxLayout* layout1 = new QVBoxLayout(this);
        layout1->setContentsMargins(11, 11, 11, 11);
        layout1->setSpacing(6);
-       QHBoxLayout* layout2 = new QHBoxLayout(0);
+
+       QHBoxLayout* layout2 = new QHBoxLayout();
        layout2->setContentsMargins(0, 0, 0, 0);
        layout2->setSpacing(6);
        layout2->addWidget(new QLabel("Find:", this));
        editField = new QLineEdit(this);
-       connect(editField, SIGNAL(returnPressed()), SLOT(search()));
+       connect(editField, &QLineEdit::returnPressed,
+               this, &ConfigSearchWindow::search);
        layout2->addWidget(editField);
        searchButton = new QPushButton("Search", this);
        searchButton->setAutoDefault(false);
-       connect(searchButton, SIGNAL(clicked()), SLOT(search()));
+       connect(searchButton, &QPushButton::clicked,
+               this, &ConfigSearchWindow::search);
        layout2->addWidget(searchButton);
        layout1->addLayout(layout2);
 
        split = new QSplitter(this);
        split->setOrientation(Qt::Vertical);
-       list = new ConfigView(split, name);
-       list->list->mode = listMode;
-       info = new ConfigInfoView(split, name);
-       connect(list->list, SIGNAL(menuChanged(struct menu *)),
-               info, SLOT(setInfo(struct menu *)));
-       connect(list->list, SIGNAL(menuChanged(struct menu *)),
-               parent, SLOT(setMenuLink(struct menu *)));
+       list = new ConfigList(split, "search");
+       list->mode = listMode;
+       info = new ConfigInfoView(split, "search");
+       connect(list, &ConfigList::menuChanged,
+               info, &ConfigInfoView::setInfo);
+       connect(list, &ConfigList::menuChanged,
+               parent, &ConfigMainWindow::setMenuLink);
 
        layout1->addWidget(split);
 
-       if (name) {
-               QVariant x, y;
-               int width, height;
-               bool ok;
+       QVariant x, y;
+       int width, height;
+       bool ok;
 
-               configSettings->beginGroup(name);
-               width = configSettings->value("/window width", parent->width() / 2).toInt();
-               height = configSettings->value("/window height", parent->height() / 2).toInt();
-               resize(width, height);
-               x = configSettings->value("/window x");
-               y = configSettings->value("/window y");
-               if ((x.isValid())&&(y.isValid()))
-                       move(x.toInt(), y.toInt());
-               QList<int> sizes = configSettings->readSizes("/split", &ok);
-               if (ok)
-                       split->setSizes(sizes);
-               configSettings->endGroup();
-               connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
-       }
+       configSettings->beginGroup("search");
+       width = configSettings->value("/window width", parent->width() / 2).toInt();
+       height = configSettings->value("/window height", parent->height() / 2).toInt();
+       resize(width, height);
+       x = configSettings->value("/window x");
+       y = configSettings->value("/window y");
+       if (x.isValid() && y.isValid())
+               move(x.toInt(), y.toInt());
+       QList<int> sizes = configSettings->readSizes("/split", &ok);
+       if (ok)
+               split->setSizes(sizes);
+       configSettings->endGroup();
+       connect(configApp, &QApplication::aboutToQuit,
+               this, &ConfigSearchWindow::saveSettings);
 }
 
 void ConfigSearchWindow::saveSettings(void)
@@ -1314,7 +1298,7 @@ void ConfigSearchWindow::search(void)
        ConfigItem *lastItem = NULL;
 
        free(result);
-       list->list->clear();
+       list->clear();
        info->clear();
 
        result = sym_re_search(editField->text().toLatin1());
@@ -1322,7 +1306,7 @@ void ConfigSearchWindow::search(void)
                return;
        for (p = result; *p; p++) {
                for_all_prompts((*p), prop)
-                       lastItem = new ConfigItem(list->list, lastItem, prop->menu,
+                       lastItem = new ConfigItem(list, lastItem, prop->menu,
                                                  menu_is_visible(prop->menu));
        }
 }
@@ -1333,7 +1317,6 @@ void ConfigSearchWindow::search(void)
 ConfigMainWindow::ConfigMainWindow(void)
        : searchWindow(0)
 {
-       QMenuBar* menu;
        bool ok = true;
        QVariant x, y;
        int width, height;
@@ -1354,97 +1337,123 @@ ConfigMainWindow::ConfigMainWindow(void)
        if ((x.isValid())&&(y.isValid()))
                move(x.toInt(), y.toInt());
 
-       split1 = new QSplitter(this);
+       // set up icons
+       ConfigItem::symbolYesIcon = QIcon(QPixmap(xpm_symbol_yes));
+       ConfigItem::symbolModIcon = QIcon(QPixmap(xpm_symbol_mod));
+       ConfigItem::symbolNoIcon = QIcon(QPixmap(xpm_symbol_no));
+       ConfigItem::choiceYesIcon = QIcon(QPixmap(xpm_choice_yes));
+       ConfigItem::choiceNoIcon = QIcon(QPixmap(xpm_choice_no));
+       ConfigItem::menuIcon = QIcon(QPixmap(xpm_menu));
+       ConfigItem::menubackIcon = QIcon(QPixmap(xpm_menuback));
+
+       QWidget *widget = new QWidget(this);
+       QVBoxLayout *layout = new QVBoxLayout(widget);
+       setCentralWidget(widget);
+
+       split1 = new QSplitter(widget);
        split1->setOrientation(Qt::Horizontal);
-       setCentralWidget(split1);
+       split1->setChildrenCollapsible(false);
 
-       menuView = new ConfigView(split1, "menu");
-       menuList = menuView->list;
+       menuList = new ConfigList(widget, "menu");
 
-       split2 = new QSplitter(split1);
+       split2 = new QSplitter(widget);
+       split2->setChildrenCollapsible(false);
        split2->setOrientation(Qt::Vertical);
 
        // create config tree
-       configView = new ConfigView(split2, "config");
-       configList = configView->list;
+       configList = new ConfigList(widget, "config");
+
+       helpText = new ConfigInfoView(widget, "help");
 
-       helpText = new ConfigInfoView(split2, "help");
+       layout->addWidget(split2);
+       split2->addWidget(split1);
+       split1->addWidget(configList);
+       split1->addWidget(menuList);
+       split2->addWidget(helpText);
 
        setTabOrder(configList, helpText);
        configList->setFocus();
 
-       menu = menuBar();
-       toolBar = new QToolBar("Tools", this);
-       addToolBar(toolBar);
-
        backAction = new QAction(QPixmap(xpm_back), "Back", this);
-         connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
-         backAction->setEnabled(false);
+       connect(backAction, &QAction::triggered,
+               this, &ConfigMainWindow::goBack);
+
        QAction *quitAction = new QAction("&Quit", this);
        quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
-         connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
+       connect(quitAction, &QAction::triggered,
+               this, &ConfigMainWindow::close);
+
        QAction *loadAction = new QAction(QPixmap(xpm_load), "&Load", this);
        loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
-         connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
+       connect(loadAction, &QAction::triggered,
+               this, &ConfigMainWindow::loadConfig);
+
        saveAction = new QAction(QPixmap(xpm_save), "&Save", this);
        saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
-         connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
+       connect(saveAction, &QAction::triggered,
+               this, &ConfigMainWindow::saveConfig);
+
        conf_set_changed_callback(conf_changed);
+
        // Set saveAction's initial state
        conf_changed();
        configname = xstrdup(conf_get_configname());
 
        QAction *saveAsAction = new QAction("Save &As...", this);
-         connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
+       connect(saveAsAction, &QAction::triggered,
+               this, &ConfigMainWindow::saveConfigAs);
        QAction *searchAction = new QAction("&Find", this);
        searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
-         connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
+       connect(searchAction, &QAction::triggered,
+               this, &ConfigMainWindow::searchConfig);
        singleViewAction = new QAction(QPixmap(xpm_single_view), "Single View", this);
        singleViewAction->setCheckable(true);
-         connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
+       connect(singleViewAction, &QAction::triggered,
+               this, &ConfigMainWindow::showSingleView);
        splitViewAction = new QAction(QPixmap(xpm_split_view), "Split View", this);
        splitViewAction->setCheckable(true);
-         connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
+       connect(splitViewAction, &QAction::triggered,
+               this, &ConfigMainWindow::showSplitView);
        fullViewAction = new QAction(QPixmap(xpm_tree_view), "Full View", this);
        fullViewAction->setCheckable(true);
-         connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
+       connect(fullViewAction, &QAction::triggered,
+               this, &ConfigMainWindow::showFullView);
 
        QAction *showNameAction = new QAction("Show Name", this);
          showNameAction->setCheckable(true);
-         connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
-         showNameAction->setChecked(configView->showName());
-       QAction *showRangeAction = new QAction("Show Range", this);
-         showRangeAction->setCheckable(true);
-         connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
-       QAction *showDataAction = new QAction("Show Data", this);
-         showDataAction->setCheckable(true);
-         connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
+       connect(showNameAction, &QAction::toggled,
+               configList, &ConfigList::setShowName);
+       showNameAction->setChecked(configList->showName);
 
        QActionGroup *optGroup = new QActionGroup(this);
        optGroup->setExclusive(true);
-       connect(optGroup, SIGNAL(triggered(QAction*)), configView,
-               SLOT(setOptionMode(QAction *)));
-       connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
-               SLOT(setOptionMode(QAction *)));
-
-       configView->showNormalAction = new QAction("Show Normal Options", optGroup);
-       configView->showAllAction = new QAction("Show All Options", optGroup);
-       configView->showPromptAction = new QAction("Show Prompt Options", optGroup);
-       configView->showNormalAction->setCheckable(true);
-       configView->showAllAction->setCheckable(true);
-       configView->showPromptAction->setCheckable(true);
+       connect(optGroup, &QActionGroup::triggered,
+               configList, &ConfigList::setOptionMode);
+       connect(optGroup, &QActionGroup::triggered,
+               menuList, &ConfigList::setOptionMode);
+
+       ConfigList::showNormalAction = new QAction("Show Normal Options", optGroup);
+       ConfigList::showNormalAction->setCheckable(true);
+       ConfigList::showAllAction = new QAction("Show All Options", optGroup);
+       ConfigList::showAllAction->setCheckable(true);
+       ConfigList::showPromptAction = new QAction("Show Prompt Options", optGroup);
+       ConfigList::showPromptAction->setCheckable(true);
 
        QAction *showDebugAction = new QAction("Show Debug Info", this);
          showDebugAction->setCheckable(true);
-         connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
+       connect(showDebugAction, &QAction::toggled,
+               helpText, &ConfigInfoView::setShowDebug);
          showDebugAction->setChecked(helpText->showDebug());
 
        QAction *showIntroAction = new QAction("Introduction", this);
-         connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
+       connect(showIntroAction, &QAction::triggered,
+               this, &ConfigMainWindow::showIntro);
        QAction *showAboutAction = new QAction("About", this);
-         connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
+       connect(showAboutAction, &QAction::triggered,
+               this, &ConfigMainWindow::showAbout);
 
        // init tool bar
+       QToolBar *toolBar = addToolBar("Tools");
        toolBar->addAction(backAction);
        toolBar->addSeparator();
        toolBar->addAction(loadAction);
@@ -1454,53 +1463,55 @@ ConfigMainWindow::ConfigMainWindow(void)
        toolBar->addAction(splitViewAction);
        toolBar->addAction(fullViewAction);
 
-       // create config menu
-       QMenu* config = menu->addMenu("&File");
-       config->addAction(loadAction);
-       config->addAction(saveAction);
-       config->addAction(saveAsAction);
-       config->addSeparator();
-       config->addAction(quitAction);
+       // create file menu
+       QMenu *menu = menuBar()->addMenu("&File");
+       menu->addAction(loadAction);
+       menu->addAction(saveAction);
+       menu->addAction(saveAsAction);
+       menu->addSeparator();
+       menu->addAction(quitAction);
 
        // create edit menu
-       QMenu* editMenu = menu->addMenu("&Edit");
-       editMenu->addAction(searchAction);
+       menu = menuBar()->addMenu("&Edit");
+       menu->addAction(searchAction);
 
        // create options menu
-       QMenu* optionMenu = menu->addMenu("&Option");
-       optionMenu->addAction(showNameAction);
-       optionMenu->addAction(showRangeAction);
-       optionMenu->addAction(showDataAction);
-       optionMenu->addSeparator();
-       optionMenu->addActions(optGroup->actions());
-       optionMenu->addSeparator();
-       optionMenu->addAction(showDebugAction);
+       menu = menuBar()->addMenu("&Option");
+       menu->addAction(showNameAction);
+       menu->addSeparator();
+       menu->addActions(optGroup->actions());
+       menu->addSeparator();
+       menu->addAction(showDebugAction);
 
        // create help menu
-       menu->addSeparator();
-       QMenu* helpMenu = menu->addMenu("&Help");
-       helpMenu->addAction(showIntroAction);
-       helpMenu->addAction(showAboutAction);
-
-       connect(configList, SIGNAL(menuChanged(struct menu *)),
-               helpText, SLOT(setInfo(struct menu *)));
-       connect(configList, SIGNAL(menuSelected(struct menu *)),
-               SLOT(changeMenu(struct menu *)));
-       connect(configList, SIGNAL(parentSelected()),
-               SLOT(goBack()));
-       connect(menuList, SIGNAL(menuChanged(struct menu *)),
-               helpText, SLOT(setInfo(struct menu *)));
-       connect(menuList, SIGNAL(menuSelected(struct menu *)),
-               SLOT(changeMenu(struct menu *)));
-
-       connect(configList, SIGNAL(gotFocus(struct menu *)),
-               helpText, SLOT(setInfo(struct menu *)));
-       connect(menuList, SIGNAL(gotFocus(struct menu *)),
-               helpText, SLOT(setInfo(struct menu *)));
-       connect(menuList, SIGNAL(gotFocus(struct menu *)),
-               SLOT(listFocusChanged(void)));
-       connect(helpText, SIGNAL(menuSelected(struct menu *)),
-               SLOT(setMenuLink(struct menu *)));
+       menu = menuBar()->addMenu("&Help");
+       menu->addAction(showIntroAction);
+       menu->addAction(showAboutAction);
+
+       connect(helpText, &ConfigInfoView::anchorClicked,
+               helpText, &ConfigInfoView::clicked);
+
+       connect(configList, &ConfigList::menuChanged,
+               helpText, &ConfigInfoView::setInfo);
+       connect(configList, &ConfigList::menuSelected,
+               this, &ConfigMainWindow::changeMenu);
+       connect(configList, &ConfigList::itemSelected,
+               this, &ConfigMainWindow::changeItens);
+       connect(configList, &ConfigList::parentSelected,
+               this, &ConfigMainWindow::goBack);
+       connect(menuList, &ConfigList::menuChanged,
+               helpText, &ConfigInfoView::setInfo);
+       connect(menuList, &ConfigList::menuSelected,
+               this, &ConfigMainWindow::changeMenu);
+
+       connect(configList, &ConfigList::gotFocus,
+               helpText, &ConfigInfoView::setInfo);
+       connect(menuList, &ConfigList::gotFocus,
+               helpText, &ConfigInfoView::setInfo);
+       connect(menuList, &ConfigList::gotFocus,
+               this, &ConfigMainWindow::listFocusChanged);
+       connect(helpText, &ConfigInfoView::menuSelected,
+               this, &ConfigMainWindow::setMenuLink);
 
        QString listMode = configSettings->value("/listMode", "symbol").toString();
        if (listMode == "single")
@@ -1539,7 +1550,7 @@ void ConfigMainWindow::loadConfig(void)
        free(configname);
        configname = xstrdup(name);
 
-       ConfigView::updateListAll();
+       ConfigList::updateListAllForAll();
 }
 
 bool ConfigMainWindow::saveConfig(void)
@@ -1578,17 +1589,18 @@ void ConfigMainWindow::saveConfigAs(void)
 void ConfigMainWindow::searchConfig(void)
 {
        if (!searchWindow)
-               searchWindow = new ConfigSearchWindow(this, "search");
+               searchWindow = new ConfigSearchWindow(this);
        searchWindow->show();
 }
 
-void ConfigMainWindow::changeMenu(struct menu *menu)
+void ConfigMainWindow::changeItens(struct menu *menu)
 {
        configList->setRootMenu(menu);
-       if (configList->rootEntry->parent == &rootmenu)
-               backAction->setEnabled(false);
-       else
-               backAction->setEnabled(true);
+}
+
+void ConfigMainWindow::changeMenu(struct menu *menu)
+{
+       menuList->setRootMenu(menu);
 }
 
 void ConfigMainWindow::setMenuLink(struct menu *menu)
@@ -1608,22 +1620,26 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
                        return;
                list->setRootMenu(parent);
                break;
-       case symbolMode:
+       case menuMode:
                if (menu->flags & MENU_ROOT) {
-                       configList->setRootMenu(menu);
+                       menuList->setRootMenu(menu);
                        configList->clearSelection();
-                       list = menuList;
-               } else {
                        list = configList;
+               } else {
                        parent = menu_get_parent_menu(menu->parent);
                        if (!parent)
                                return;
-                       item = menuList->findConfigItem(parent);
+
+                       /* Select the config view */
+                       item = configList->findConfigItem(parent);
                        if (item) {
-                               item->setSelected(true);
-                               menuList->scrollToItem(item);
+                               configList->setSelected(item, true);
+                               configList->scrollToItem(item);
                        }
-                       list->setRootMenu(parent);
+
+                       menuList->setRootMenu(parent);
+                       menuList->clearSelection();
+                       list = menuList;
                }
                break;
        case fullMode:
@@ -1636,9 +1652,10 @@ void ConfigMainWindow::setMenuLink(struct menu *menu)
        if (list) {
                item = list->findConfigItem(menu);
                if (item) {
-                       item->setSelected(true);
+                       list->setSelected(item, true);
                        list->scrollToItem(item);
                        list->setFocus();
+                       helpText->setInfo(menu);
                }
        }
 }
@@ -1651,25 +1668,10 @@ void ConfigMainWindow::listFocusChanged(void)
 
 void ConfigMainWindow::goBack(void)
 {
-       ConfigItem* item, *oldSelection;
-
-       configList->setParentMenu();
        if (configList->rootEntry == &rootmenu)
-               backAction->setEnabled(false);
-
-       if (menuList->selectedItems().count() == 0)
                return;
 
-       item = (ConfigItem*)menuList->selectedItems().first();
-       oldSelection = item;
-       while (item) {
-               if (item->menu == configList->rootEntry) {
-                       oldSelection->setSelected(false);
-                       item->setSelected(true);
-                       break;
-               }
-               item = (ConfigItem*)item->parent();
-       }
+       configList->setParentMenu();
 }
 
 void ConfigMainWindow::showSingleView(void)
@@ -1681,7 +1683,9 @@ void ConfigMainWindow::showSingleView(void)
        fullViewAction->setEnabled(true);
        fullViewAction->setChecked(false);
 
-       menuView->hide();
+       backAction->setEnabled(true);
+
+       menuList->hide();
        menuList->setRootMenu(0);
        configList->mode = singleMode;
        if (configList->rootEntry == &rootmenu)
@@ -1700,17 +1704,19 @@ void ConfigMainWindow::showSplitView(void)
        fullViewAction->setEnabled(true);
        fullViewAction->setChecked(false);
 
-       configList->mode = symbolMode;
+       backAction->setEnabled(false);
+
+       configList->mode = menuMode;
        if (configList->rootEntry == &rootmenu)
                configList->updateListAll();
        else
                configList->setRootMenu(&rootmenu);
        configList->setAllOpen(true);
        configApp->processEvents();
-       menuList->mode = menuMode;
+       menuList->mode = symbolMode;
        menuList->setRootMenu(&rootmenu);
        menuList->setAllOpen(true);
-       menuView->show();
+       menuList->show();
        menuList->setFocus();
 }
 
@@ -1723,7 +1729,9 @@ void ConfigMainWindow::showFullView(void)
        fullViewAction->setEnabled(false);
        fullViewAction->setChecked(true);
 
-       menuView->hide();
+       backAction->setEnabled(false);
+
+       menuList->hide();
        menuList->setRootMenu(0);
        configList->mode = fullMode;
        if (configList->rootEntry == &rootmenu)
@@ -1735,7 +1743,6 @@ void ConfigMainWindow::showFullView(void)
 
 /*
  * ask for saving configuration before quitting
- * TODO ask only when something changed
  */
 void ConfigMainWindow::closeEvent(QCloseEvent* e)
 {
@@ -1766,17 +1773,26 @@ void ConfigMainWindow::closeEvent(QCloseEvent* e)
 
 void ConfigMainWindow::showIntro(void)
 {
-       static const QString str = "Welcome to the qconf graphical configuration tool.\n\n"
-               "For each option, a blank box indicates the feature is disabled, a check\n"
-               "indicates it is enabled, and a dot indicates that it is to be compiled\n"
-               "as a module.  Clicking on the box will cycle through the three states.\n\n"
-               "If you do not see an option (e.g., a device driver) that you believe\n"
-               "should be present, try turning on Show All Options under the Options menu.\n"
-               "Although there is no cross reference yet to help you figure out what other\n"
-               "options must be enabled to support the option you are interested in, you can\n"
-               "still view the help of a grayed-out option.\n\n"
-               "Toggling Show Debug Info under the Options menu will show the dependencies,\n"
-               "which you can then match by examining other options.\n\n";
+       static const QString str =
+               "Welcome to the qconf graphical configuration tool.\n"
+               "\n"
+               "For bool and tristate options, a blank box indicates the "
+               "feature is disabled, a check indicates it is enabled, and a "
+               "dot indicates that it is to be compiled as a module. Clicking "
+               "on the box will cycle through the three states. For int, hex, "
+               "and string options, double-clicking or pressing F2 on the "
+               "Value cell will allow you to edit the value.\n"
+               "\n"
+               "If you do not see an option (e.g., a device driver) that you "
+               "believe should be present, try turning on Show All Options "
+               "under the Options menu. Enabling Show Debug Info will help you"
+               "figure out what other options must be enabled to support the "
+               "option you are interested in, and hyperlinks will navigate to "
+               "them.\n"
+               "\n"
+               "Toggling Show Debug Info under the Options menu will show the "
+               "dependencies, which you can then match by examining other "
+               "options.\n";
 
        QMessageBox::information(this, "qconf", str);
 }
@@ -1784,10 +1800,13 @@ void ConfigMainWindow::showIntro(void)
 void ConfigMainWindow::showAbout(void)
 {
        static const QString str = "qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n"
-               "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n\n"
-               "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n";
+               "Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>.\n"
+               "\n"
+               "Bug reports and feature request can also be entered at http://bugzilla.kernel.org/\n"
+               "\n"
+               "Qt Version: ";
 
-       QMessageBox::information(this, "qconf", str);
+       QMessageBox::information(this, "qconf", str + qVersion());
 }
 
 void ConfigMainWindow::saveSettings(void)
@@ -1856,7 +1875,6 @@ int main(int ac, char** av)
        const char *name;
 
        progname = av[0];
-       configApp = new QApplication(ac, av);
        if (ac > 1 && av[1][0] == '-') {
                switch (av[1][1]) {
                case 's':
@@ -1877,6 +1895,8 @@ int main(int ac, char** av)
        conf_read(NULL);
        //zconfdump(stdout);
 
+       configApp = new QApplication(ac, av);
+
        configSettings = new ConfigSettings();
        configSettings->beginGroup("/kconfig/qconf");
        v = new ConfigMainWindow();