Merge branch 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild

Pull kconfig updates from Michal Marek:

 - 'make xconfig' ported to Qt5, dropping support for Qt3

 - merge_config.sh supports a single-input-file mode and also respects
   $KCONFIG_CONFIG

 - Fix for incorrect display of >= and > in dependency expressions

* 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild: (44 commits)
  Add current selection check.
  Use pkg-config to find Qt 4 and 5 instead of direct qmake
  kconfig: Fix copy&paste error
  kconfig/merge_config.sh: Accept a single file
  kconfig/merge_config.sh: Support KCONFIG_CONFIG
  Update the buildsystem for KConfig finding Qt
  Port xconfig to Qt5 - Update copyright.
  Port xconfig to Qt5 - Fix goParent issue.
  Port xconfig to Qt5 - on Back clicked, deselect old item.
  Port xconfig to Qt5 - Add(back) one click checkbox toggle.
  Port xconfig to Qt5 - Add(back) lineedit editing.
  Port xconfig to Qt5 - Remove some commented code.
  Port xconfig to Qt5 - Source format.
  Port xconfig to Qt5 - Add horizontal scrollbar, and scroll per pixel.
  Port xconfig to Qt5 - Change ConfigItem constructor parent type.
  Port xconfig to Qt5 - Disable ConfigList soring
  Port xconfig to Qt5 - Remove ConfigList::updateMenuList template.
  Port xconfig to Qt5 - Add ConfigList::mode to initializer list.
  Port xconfig to Qt5 - Add ConfigItem::nextItem to initializer list.
  Port xconfig to Qt5 - Tree widget set column titles.
  ...
diff --git a/Documentation/kbuild/Kconfig.recursion-issue-01 b/Documentation/kbuild/Kconfig.recursion-issue-01
new file mode 100644
index 0000000..e8877db
--- /dev/null
+++ b/Documentation/kbuild/Kconfig.recursion-issue-01
@@ -0,0 +1,57 @@
+# Simple Kconfig recursive issue
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# Test with:
+#
+# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig
+#
+# This Kconfig file has a simple recursive dependency issue. In order to
+# understand why this recursive dependency issue occurs lets consider what
+# Kconfig needs to address. We iterate over what Kconfig needs to address
+# by stepping through the questions it needs to address sequentially.
+#
+#  * What values are possible for CORE?
+#
+# CORE_BELL_A_ADVANCED selects CORE, which means that it influences the values
+# that are possible for CORE. So for example if CORE_BELL_A_ADVANCED is 'y',
+# CORE must be 'y' too.
+#
+#  * What influences CORE_BELL_A_ADVANCED ?
+#
+# As the name implies CORE_BELL_A_ADVANCED is an advanced feature of
+# CORE_BELL_A so naturally it depends on CORE_BELL_A. So if CORE_BELL_A is 'y'
+# we know CORE_BELL_A_ADVANCED can be 'y' too.
+#
+#   * What influences CORE_BELL_A ?
+#
+# CORE_BELL_A depends on CORE, so CORE influences CORE_BELL_A.
+#
+# But that is a problem, because this means that in order to determine
+# what values are possible for CORE we ended up needing to address questions
+# regarding possible values of CORE itself again. Answering the original
+# question of what are the possible values of CORE would make the kconfig
+# tools run in a loop. When this happens Kconfig exits and complains about
+# the "recursive dependency detected" error.
+#
+# Reading the Documentation/kbuild/Kconfig.recursion-issue-01 file it may be
+# obvious that an easy to solution to this problem should just be the removal
+# of the "select CORE" from CORE_BELL_A_ADVANCED as that is implicit already
+# since CORE_BELL_A depends on CORE. Recursive dependency issues are not always
+# so trivial to resolve, we provide another example below of practical
+# implications of this recursive issue where the solution is perhaps not so
+# easy to understand. Note that matching semantics on the dependency on
+# CORE also consist of a solution to this recursive problem.
+
+mainmenu "Simple example to demo kconfig recursive dependency issue"
+
+config CORE
+	tristate
+
+config CORE_BELL_A
+	tristate
+	depends on CORE
+
+config CORE_BELL_A_ADVANCED
+	tristate
+	depends on CORE_BELL_A
+	select CORE
diff --git a/Documentation/kbuild/Kconfig.recursion-issue-02 b/Documentation/kbuild/Kconfig.recursion-issue-02
new file mode 100644
index 0000000..b9fd56c
--- /dev/null
+++ b/Documentation/kbuild/Kconfig.recursion-issue-02
@@ -0,0 +1,63 @@
+# Cumulative Kconfig recursive issue
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# Test with:
+#
+# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig
+#
+# The recursive limitations with Kconfig has some non intuitive implications on
+# kconfig sematics which are documented here. One known practical implication
+# of the recursive limitation is that drivers cannot negate features from other
+# drivers if they share a common core requirement and use disjoint semantics to
+# annotate those requirements, ie, some drivers use "depends on" while others
+# use "select". For instance it means if a driver A and driver B share the same
+# core requirement, and one uses "select" while the other uses "depends on" to
+# annotate this, all features that driver A selects cannot now be negated by
+# driver B.
+#
+# A perhaps not so obvious implication of this is that, if semantics on these
+# core requirements are not carefully synced, as drivers evolve features
+# they select or depend on end up becoming shared requirements which cannot be
+# negated by other drivers.
+#
+# The example provided in Documentation/kbuild/Kconfig.recursion-issue-02
+# describes a simple driver core layout of example features a kernel might
+# have. Let's assume we have some CORE functionality, then the kernel has a
+# series of bells and whistles it desires to implement, its not so advanced so
+# it only supports bells at this time: CORE_BELL_A and CORE_BELL_B. If
+# CORE_BELL_A has some advanced feature CORE_BELL_A_ADVANCED which selects
+# CORE_BELL_A then CORE_BELL_A ends up becoming a common BELL feature which
+# other bells in the system cannot negate. The reason for this issue is
+# due to the disjoint use of semantics on expressing each bell's relationship
+# with CORE, one uses "depends on" while the other uses "select". Another
+# more important reason is that kconfig does not check for dependencies listed
+# under 'select' for a symbol, when such symbols are selected kconfig them
+# as mandatory required symbols. For more details on the heavy handed nature
+# of select refer to Documentation/kbuild/Kconfig.select-break
+#
+# To fix this the "depends on CORE" must be changed to "select CORE", or the
+# "select CORE" must be changed to "depends on CORE".
+#
+# For an example real world scenario issue refer to the attempt to remove
+# "select FW_LOADER" [0], in the end the simple alternative solution to this
+# problem consisted on matching semantics with newly introduced features.
+#
+# [0] http://lkml.kernel.org/r/1432241149-8762-1-git-send-email-mcgrof@do-not-panic.com
+
+mainmenu "Simple example to demo cumulative kconfig recursive dependency implication"
+
+config CORE
+	tristate
+
+config CORE_BELL_A
+	tristate
+	depends on CORE
+
+config CORE_BELL_A_ADVANCED
+	tristate
+	select CORE_BELL_A
+
+config CORE_BELL_B
+	tristate
+	depends on !CORE_BELL_A
+	select CORE
diff --git a/Documentation/kbuild/Kconfig.select-break b/Documentation/kbuild/Kconfig.select-break
new file mode 100644
index 0000000..365ceb3
--- /dev/null
+++ b/Documentation/kbuild/Kconfig.select-break
@@ -0,0 +1,33 @@
+# Select broken dependency issue
+# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+#
+# Test with:
+#
+# make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.select-break menuconfig
+#
+# kconfig will not complain and enable this layout for configuration. This is
+# currently a feature of kconfig, given select was designed to be heavy handed.
+# Kconfig currently does not check the list of symbols listed on a symbol's
+# "select" list, this is done on purpose to help load a set of known required
+# symbols. Because of this use of select should be used with caution. An
+# example of this issue is below.
+#
+# The option B and C are clearly contradicting with respect to A.
+# However, when A is set, C can be set as well because Kconfig does not
+# visit the dependencies of the select target (in this case B).  And since
+# Kconfig does not visit the dependencies, it breaks the dependencies of B
+# (!A).
+
+mainmenu "Simple example to demo kconfig select broken dependency issue"
+
+config A
+	bool "CONFIG A"
+
+config B
+	bool "CONFIG B"
+	depends on !A
+
+config C
+	bool "CONFIG C"
+	depends on A
+	select B
diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt
index 350f733..c52856d 100644
--- a/Documentation/kbuild/kconfig-language.txt
+++ b/Documentation/kbuild/kconfig-language.txt
@@ -393,3 +393,164 @@
 	depends on BAR && m
 
 limits FOO to module (=m) or disabled (=n).
+
+Kconfig recursive dependency limitations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you've hit the Kconfig error: "recursive dependency detected" you've run
+into a recursive dependency issue with Kconfig, a recursive dependency can be
+summarized as a circular dependency. The kconfig tools need to ensure that
+Kconfig files comply with specified configuration requirements. In order to do
+that kconfig must determine the values that are possible for all Kconfig
+symbols, this is currently not possible if there is a circular relation
+between two or more Kconfig symbols. For more details refer to the "Simple
+Kconfig recursive issue" subsection below. Kconfig does not do recursive
+dependency resolution; this has a few implications for Kconfig file writers.
+We'll first explain why this issues exists and then provide an example
+technical limitation which this brings upon Kconfig developers. Eager
+developers wishing to try to address this limitation should read the next
+subsections.
+
+Simple Kconfig recursive issue
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Read: Documentation/kbuild/Kconfig.recursion-issue-01
+
+Test with:
+
+make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-01 allnoconfig
+
+Cumulative Kconfig recursive issue
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Read: Documentation/kbuild/Kconfig.recursion-issue-02
+
+Test with:
+
+make KBUILD_KCONFIG=Documentation/kbuild/Kconfig.recursion-issue-02 allnoconfig
+
+Practical solutions to kconfig recursive issue
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Developers who run into the recursive Kconfig issue have three options
+at their disposal. We document them below and also provide a list of
+historical issues resolved through these different solutions.
+
+  a) Remove any superfluous "select FOO" or "depends on FOO"
+  b) Match dependency semantics:
+	b1) Swap all "select FOO" to "depends on FOO" or,
+	b2) Swap all "depends on FOO" to "select FOO"
+
+The resolution to a) can be tested with the sample Kconfig file
+Documentation/kbuild/Kconfig.recursion-issue-01 through the removal
+of the "select CORE" from CORE_BELL_A_ADVANCED as that is implicit already
+since CORE_BELL_A depends on CORE. At times it may not be possible to remove
+some dependency criteria, for such cases you can work with solution b).
+
+The two different resolutions for b) can be tested in the sample Kconfig file
+Documentation/kbuild/Kconfig.recursion-issue-02.
+
+Below is a list of examples of prior fixes for these types of recursive issues;
+all errors appear to involve one or more select's and one or more "depends on".
+
+commit          fix
+======          ===
+06b718c01208    select A -> depends on A
+c22eacfe82f9    depends on A -> depends on B
+6a91e854442c    select A -> depends on A
+118c565a8f2e    select A -> select B
+f004e5594705    select A -> depends on A
+c7861f37b4c6    depends on A -> (null)
+80c69915e5fb    select A -> (null)              (1)
+c2218e26c0d0    select A -> depends on A        (1)
+d6ae99d04e1c    select A -> depends on A
+95ca19cf8cbf    select A -> depends on A
+8f057d7bca54    depends on A -> (null)
+8f057d7bca54    depends on A -> select A
+a0701f04846e    select A -> depends on A
+0c8b92f7f259    depends on A -> (null)
+e4e9e0540928    select A -> depends on A        (2)
+7453ea886e87    depends on A > (null)           (1)
+7b1fff7e4fdf    select A -> depends on A
+86c747d2a4f0    select A -> depends on A
+d9f9ab51e55e    select A -> depends on A
+0c51a4d8abd6    depends on A -> select A        (3)
+e98062ed6dc4    select A -> depends on A        (3)
+91e5d284a7f1    select A -> (null)
+
+(1) Partial (or no) quote of error.
+(2) That seems to be the gist of that fix.
+(3) Same error.
+
+Future kconfig work
+~~~~~~~~~~~~~~~~~~~
+
+Work on kconfig is welcomed on both areas of clarifying semantics and on
+evaluating the use of a full SAT solver for it. A full SAT solver can be
+desirable to enable more complex dependency mappings and / or queries,
+for instance on possible use case for a SAT solver could be that of handling
+the current known recursive dependency issues. It is not known if this would
+address such issues but such evaluation is desirable. If support for a full SAT
+solver proves too complex or that it cannot address recursive dependency issues
+Kconfig should have at least clear and well defined semantics which also
+addresses and documents limitations or requirements such as the ones dealing
+with recursive dependencies.
+
+Further work on both of these areas is welcomed on Kconfig. We elaborate
+on both of these in the next two subsections.
+
+Semantics of Kconfig
+~~~~~~~~~~~~~~~~~~~~
+
+The use of Kconfig is broad, Linux is now only one of Kconfig's users:
+one study has completed a broad analysis of Kconfig use in 12 projects [0].
+Despite its widespread use, and although this document does a reasonable job
+in documenting basic Kconfig syntax a more precise definition of Kconfig
+semantics is welcomed. One project deduced Kconfig semantics through
+the use of the xconfig configurator [1]. Work should be done to confirm if
+the deduced semantics matches our intended Kconfig design goals.
+
+Having well defined semantics can be useful for tools for practical
+evaluation of depenencies, for instance one such use known case was work to
+express in boolean abstraction of the inferred semantics of Kconfig to
+translate Kconfig logic into boolean formulas and run a SAT solver on this to
+find dead code / features (always inactive), 114 dead features were found in
+Linux using this methodology [1] (Section 8: Threats to validity).
+
+Confirming this could prove useful as Kconfig stands as one of the the leading
+industrial variability modeling languages [1] [2]. Its study would help
+evaluate practical uses of such languages, their use was only theoretical
+and real world requirements were not well understood. As it stands though
+only reverse engineering techniques have been used to deduce semantics from
+variability modeling languages such as Kconfig [3].
+
+[0] http://www.eng.uwaterloo.ca/~shshe/kconfig_semantics.pdf
+[1] http://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf
+[2] http://gsd.uwaterloo.ca/sites/default/files/ase241-berger_0.pdf
+[3] http://gsd.uwaterloo.ca/sites/default/files/icse2011.pdf
+
+Full SAT solver for Kconfig
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Although SAT solvers [0] haven't yet been used by Kconfig directly, as noted in
+the previous subsection, work has been done however to express in boolean
+abstraction the inferred semantics of Kconfig to translate Kconfig logic into
+boolean formulas and run a SAT solver on it [1]. Another known related project
+is CADOS [2] (former VAMOS [3]) and the tools, mainly undertaker [4], which has
+been introduced first with [5].  The basic concept of undertaker is to exract
+variability models from Kconfig, and put them together with a propositional
+formula extracted from CPP #ifdefs and build-rules into a SAT solver in order
+to find dead code, dead files, and dead symbols. If using a SAT solver is
+desirable on Kconfig one approach would be to evaluate repurposing such efforts
+somehow on Kconfig. There is enough interest from mentors of existing projects
+to not only help advise how to integrate this work upstream but also help
+maintain it long term. Interested developers should visit:
+
+http://kernelnewbies.org/KernelProjects/kconfig-sat
+
+[0] http://www.cs.cornell.edu/~sabhar/chapters/SATSolvers-KR-Handbook.pdf
+[1] http://gsd.uwaterloo.ca/sites/default/files/vm-2013-berger.pdf
+[2] https://cados.cs.fau.de
+[3] https://vamos.cs.fau.de
+[4] https://undertaker.cs.fau.de
+[5] https://www4.cs.fau.de/Publications/2011/tartler_11_eurosys.pdf
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile
index 3043d6b..d79cba4 100644
--- a/scripts/kconfig/Makefile
+++ b/scripts/kconfig/Makefile
@@ -229,49 +229,21 @@
 
 # Qt needs some extra effort...
 $(obj)/.tmp_qtcheck:
-	@set -e; $(kecho) "  CHECK   qt"; dir=""; pkg=""; \
-	if ! pkg-config --exists QtCore 2> /dev/null; then \
-	    echo "* Unable to find the Qt4 tool qmake. Trying to use Qt3"; \
-	    pkg-config --exists qt 2> /dev/null && pkg=qt; \
-	    pkg-config --exists qt-mt 2> /dev/null && pkg=qt-mt; \
-	    if [ -n "$$pkg" ]; then \
-	      cflags="\$$(shell pkg-config $$pkg --cflags)"; \
-	      libs="\$$(shell pkg-config $$pkg --libs)"; \
-	      moc="\$$(shell pkg-config $$pkg --variable=prefix)/bin/moc"; \
-	      dir="$$(pkg-config $$pkg --variable=prefix)"; \
-	    else \
-	      for d in $$QTDIR /usr/share/qt* /usr/lib/qt*; do \
-	        if [ -f $$d/include/qconfig.h ]; then dir=$$d; break; fi; \
-	      done; \
-	      if [ -z "$$dir" ]; then \
-	        echo >&2 "*"; \
-	        echo >&2 "* Unable to find any Qt installation. Please make sure that"; \
-	        echo >&2 "* the Qt4 or Qt3 development package is correctly installed and"; \
-	        echo >&2 "* either qmake can be found or install pkg-config or set"; \
-	        echo >&2 "* the QTDIR environment variable to the correct location."; \
-	        echo >&2 "*"; \
-	        false; \
-	      fi; \
-	      libpath=$$dir/lib; lib=qt; osdir=""; \
-	      $(HOSTCXX) -print-multi-os-directory > /dev/null 2>&1 && \
-	        osdir=x$$($(HOSTCXX) -print-multi-os-directory); \
-	      test -d $$libpath/$$osdir && libpath=$$libpath/$$osdir; \
-	      test -f $$libpath/libqt-mt.so && lib=qt-mt; \
-	      cflags="-I$$dir/include"; \
-	      libs="-L$$libpath -Wl,-rpath,$$libpath -l$$lib"; \
-	      moc="$$dir/bin/moc"; \
-	    fi; \
-	    if [ ! -x $$dir/bin/moc -a -x /usr/bin/moc ]; then \
-	      echo "*"; \
-	      echo "* Unable to find $$dir/bin/moc, using /usr/bin/moc instead."; \
-	      echo "*"; \
-	      moc="/usr/bin/moc"; \
-	    fi; \
+	@set -e; $(kecho) "  CHECK   qt"; \
+	if pkg-config --exists Qt5Core; then \
+	    cflags="-std=c++11 -fPIC `pkg-config --cflags Qt5Core Qt5Gui Qt5Widgets`"; \
+	    libs=`pkg-config --libs Qt5Core Qt5Gui Qt5Widgets`; \
+	    moc=`pkg-config --variable=host_bins Qt5Core`/moc; \
+	elif pkg-config --exists QtCore; then \
+	    cflags=`pkg-config --cflags QtCore QtGui`; \
+	    libs=`pkg-config --libs QtCore QtGui`; \
+	    moc=`pkg-config --variable=moc_location QtCore`; \
 	else \
-	  cflags="\$$(shell pkg-config QtCore QtGui Qt3Support --cflags)"; \
-	  libs="\$$(shell pkg-config QtCore QtGui Qt3Support --libs)"; \
-	  moc="\$$(shell pkg-config QtCore --variable=moc_location)"; \
-	  [ -n "$$moc" ] || moc="\$$(shell pkg-config QtCore --variable=prefix)/bin/moc"; \
+	    echo >&2 "*"; \
+	    echo >&2 "* Could not find Qt via pkg-config."; \
+	    echo >&2 "* Please install either Qt 4.8 or 5.x. and make sure it's in PKG_CONFIG_PATH"; \
+	    echo >&2 "*"; \
+	    exit 1; \
 	fi; \
 	echo "KC_QT_CFLAGS=$$cflags" > $@; \
 	echo "KC_QT_LIBS=$$libs" >> $@; \
diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c
index 667d1aa..cbf4996 100644
--- a/scripts/kconfig/expr.c
+++ b/scripts/kconfig/expr.c
@@ -1113,7 +1113,7 @@
 			fn(data, e->left.sym, e->left.sym->name);
 		else
 			fn(data, NULL, "<choice>");
-		fn(data, NULL, e->type == E_LEQ ? ">=" : ">");
+		fn(data, NULL, e->type == E_GEQ ? ">=" : ">");
 		fn(data, e->right.sym, e->right.sym->name);
 		break;
 	case E_UNEQUAL:
diff --git a/scripts/kconfig/merge_config.sh b/scripts/kconfig/merge_config.sh
index 0d883b3..67d1314 100755
--- a/scripts/kconfig/merge_config.sh
+++ b/scripts/kconfig/merge_config.sh
@@ -32,7 +32,7 @@
 	echo "  -m    only merge the fragments, do not execute the make command"
 	echo "  -n    use allnoconfig instead of alldefconfig"
 	echo "  -r    list redundant entries when merging fragments"
-	echo "  -O    dir to put generated output files"
+	echo "  -O    dir to put generated output files.  Consider setting \$KCONFIG_CONFIG instead."
 }
 
 RUNMAKE=true
@@ -77,11 +77,19 @@
 	esac
 done
 
-if [ "$#" -lt 2 ] ; then
+if [ "$#" -lt 1 ] ; then
 	usage
 	exit
 fi
 
+if [ -z "$KCONFIG_CONFIG" ]; then
+	if [ "$OUTPUT" != . ]; then
+		KCONFIG_CONFIG=$(readlink -m -- "$OUTPUT/.config")
+	else
+		KCONFIG_CONFIG=.config
+	fi
+fi
+
 INITFILE=$1
 shift;
 
@@ -124,9 +132,9 @@
 done
 
 if [ "$RUNMAKE" = "false" ]; then
-	cp $TMP_FILE $OUTPUT/.config
+	cp -T -- "$TMP_FILE" "$KCONFIG_CONFIG"
 	echo "#"
-	echo "# merged configuration written to $OUTPUT/.config (needs make)"
+	echo "# merged configuration written to $KCONFIG_CONFIG (needs make)"
 	echo "#"
 	clean_up
 	exit
@@ -150,7 +158,7 @@
 for CFG in $(sed -n "$SED_CONFIG_EXP" $TMP_FILE); do
 
 	REQUESTED_VAL=$(grep -w -e "$CFG" $TMP_FILE)
-	ACTUAL_VAL=$(grep -w -e "$CFG" $OUTPUT/.config)
+	ACTUAL_VAL=$(grep -w -e "$CFG" "$KCONFIG_CONFIG")
 	if [ "x$REQUESTED_VAL" != "x$ACTUAL_VAL" ] ; then
 		echo "Value requested for $CFG not in final .config"
 		echo "Requested value:  $REQUESTED_VAL"
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index c3bb7fe..91b7e6f 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -1,32 +1,17 @@
 /*
  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
+ * Copyright (C) 2015 Boris Barbulovski <bbarbulovski@gmail.com>
  * Released under the terms of the GNU GPL v2.0.
  */
 
 #include <qglobal.h>
 
-#if QT_VERSION < 0x040000
-#include <stddef.h>
-#include <qmainwindow.h>
-#include <qvbox.h>
-#include <qvaluelist.h>
+#include <QMainWindow>
+#include <QList>
 #include <qtextbrowser.h>
-#include <qaction.h>
-#include <qheader.h>
-#include <qfiledialog.h>
-#include <qdragobject.h>
-#include <qpopupmenu.h>
-#else
-#include <q3mainwindow.h>
-#include <q3vbox.h>
-#include <q3valuelist.h>
-#include <q3textbrowser.h>
-#include <q3action.h>
-#include <q3header.h>
-#include <q3filedialog.h>
-#include <q3dragobject.h>
-#include <q3popupmenu.h>
-#endif
+#include <QAction>
+#include <QFileDialog>
+#include <QMenu>
 
 #include <qapplication.h>
 #include <qdesktopwidget.h>
@@ -57,7 +42,7 @@
 static QApplication *configApp;
 static ConfigSettings *configSettings;
 
-Q3Action *ConfigMainWindow::saveAction;
+QAction *ConfigMainWindow::saveAction;
 
 static inline QString qgettext(const char* str)
 {
@@ -66,7 +51,7 @@
 
 static inline QString qgettext(const QString& str)
 {
-	return QString::fromLocal8Bit(gettext(str.latin1()));
+	return QString::fromLocal8Bit(gettext(str.toLatin1()));
 }
 
 ConfigSettings::ConfigSettings()
@@ -77,10 +62,10 @@
 /**
  * Reads a list of integer values from the application settings.
  */
-Q3ValueList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
+QList<int> ConfigSettings::readSizes(const QString& key, bool *ok)
 {
-	Q3ValueList<int> result;
-	QStringList entryList = readListEntry(key, ok);
+	QList<int> result;
+	QStringList entryList = value(key).toStringList();
 	QStringList::Iterator it;
 
 	for (it = entryList.begin(); it != entryList.end(); ++it)
@@ -92,14 +77,16 @@
 /**
  * Writes a list of integer values to the application settings.
  */
-bool ConfigSettings::writeSizes(const QString& key, const Q3ValueList<int>& value)
+bool ConfigSettings::writeSizes(const QString& key, const QList<int>& value)
 {
 	QStringList stringList;
-	Q3ValueList<int>::ConstIterator it;
+	QList<int>::ConstIterator it;
 
 	for (it = value.begin(); it != value.end(); ++it)
 		stringList.push_back(QString::number(*it));
-	return writeEntry(key, stringList);
+	setValue(key, stringList);
+
+	return true;
 }
 
 
@@ -109,9 +96,6 @@
  */
 void ConfigItem::okRename(int col)
 {
-	Parent::okRename(col);
-	sym_set_string_value(menu->sym, text(dataColIdx).latin1());
-	listView()->updateList(this);
 }
 
 /*
@@ -149,11 +133,11 @@
 		} else {
 			if (sym)
 				break;
-			setPixmap(promptColIdx, 0);
+			setPixmap(promptColIdx, QIcon());
 		}
 		goto set_prompt;
 	case P_COMMENT:
-		setPixmap(promptColIdx, 0);
+		setPixmap(promptColIdx, QIcon());
 		goto set_prompt;
 	default:
 		;
@@ -170,7 +154,7 @@
 		char ch;
 
 		if (!sym_is_changable(sym) && list->optMode == normalOpt) {
-			setPixmap(promptColIdx, 0);
+			setPixmap(promptColIdx, QIcon());
 			setText(noColIdx, QString::null);
 			setText(modColIdx, QString::null);
 			setText(yesColIdx, QString::null);
@@ -216,9 +200,6 @@
 
 		data = sym_get_string_value(sym);
 
-		int i = list->mapIdx(dataColIdx);
-		if (i >= 0)
-			setRenameEnabled(i, TRUE);
 		setText(dataColIdx, data);
 		if (type == S_STRING)
 			prompt = QString("%1: %2").arg(prompt).arg(data);
@@ -250,18 +231,6 @@
 		updateMenu();
 }
 
-void ConfigItem::paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align)
-{
-	ConfigList* list = listView();
-
-	if (visible) {
-		if (isSelected() && !list->hasFocus() && list->mode == menuMode)
-			Parent::paintCell(p, list->inactivedColorGroup, column, width, align);
-		else
-			Parent::paintCell(p, cg, column, width, align);
-	} else
-		Parent::paintCell(p, list->disabledColorGroup, column, width, align);
-}
 
 /*
  * construct a menu entry
@@ -274,7 +243,7 @@
 		menu->data = this;
 
 		if (list->mode != fullMode)
-			setOpen(TRUE);
+			setExpanded(true);
 		sym_calc_value(menu->sym);
 	}
 	updateMenu();
@@ -299,7 +268,7 @@
 ConfigLineEdit::ConfigLineEdit(ConfigView* parent)
 	: Parent(parent)
 {
-	connect(this, SIGNAL(lostFocus()), SLOT(hide()));
+	connect(this, SIGNAL(editingFinished()), SLOT(hide()));
 }
 
 void ConfigLineEdit::show(ConfigItem* i)
@@ -320,7 +289,7 @@
 		break;
 	case Qt::Key_Return:
 	case Qt::Key_Enter:
-		sym_set_string_value(item->menu->sym, text().latin1());
+		sym_set_string_value(item->menu->sym, text().toLatin1());
 		parent()->updateList(item);
 		break;
 	default:
@@ -333,39 +302,39 @@
 }
 
 ConfigList::ConfigList(ConfigView* p, const char *name)
-	: Parent(p, name),
+	: Parent(p),
 	  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), optMode(normalOpt),
+	  showName(false), showRange(false), showData(false), mode(singleMode), optMode(normalOpt),
 	  rootEntry(0), headerPopup(0)
 {
 	int i;
 
-	setSorting(-1);
-	setRootIsDecorated(TRUE);
-	disabledColorGroup = palette().active();
-	disabledColorGroup.setColor(QColorGroup::Text, palette().disabled().text());
-	inactivedColorGroup = palette().active();
-	inactivedColorGroup.setColor(QColorGroup::Highlight, palette().disabled().highlight());
+	setObjectName(name);
+	setSortingEnabled(false);
+	setRootIsDecorated(true);
 
-	connect(this, SIGNAL(selectionChanged(void)),
+	setVerticalScrollMode(ScrollPerPixel);
+	setHorizontalScrollMode(ScrollPerPixel);
+
+	setHeaderLabels(QStringList() << _("Option") << _("Name") << "N" << "M" << "Y" << _("Value"));
+
+	connect(this, SIGNAL(itemSelectionChanged(void)),
 		SLOT(updateSelection(void)));
 
 	if (name) {
 		configSettings->beginGroup(name);
-		showName = configSettings->readBoolEntry("/showName", false);
-		showRange = configSettings->readBoolEntry("/showRange", false);
-		showData = configSettings->readBoolEntry("/showData", false);
-		optMode = (enum optionMode)configSettings->readNumEntry("/optionMode", false);
+		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()));
 	}
 
-	for (i = 0; i < colNr; i++)
-		colMap[i] = colRevMap[i] = -1;
-	addColumn(promptColIdx, _("Option"));
+	addColumn(promptColIdx);
 
 	reinit();
 }
@@ -390,26 +359,26 @@
 	removeColumn(nameColIdx);
 
 	if (showName)
-		addColumn(nameColIdx, _("Name"));
+		addColumn(nameColIdx);
 	if (showRange) {
-		addColumn(noColIdx, "N");
-		addColumn(modColIdx, "M");
-		addColumn(yesColIdx, "Y");
+		addColumn(noColIdx);
+		addColumn(modColIdx);
+		addColumn(yesColIdx);
 	}
 	if (showData)
-		addColumn(dataColIdx, _("Value"));
+		addColumn(dataColIdx);
 
 	updateListAll();
 }
 
 void ConfigList::saveSettings(void)
 {
-	if (name()) {
-		configSettings->beginGroup(name());
-		configSettings->writeEntry("/showName", showName);
-		configSettings->writeEntry("/showRange", showRange);
-		configSettings->writeEntry("/showData", showData);
-		configSettings->writeEntry("/optionMode", (int)optMode);
+	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();
 	}
 }
@@ -431,7 +400,10 @@
 	struct menu *menu;
 	enum prop_type type;
 
-	ConfigItem* item = (ConfigItem*)selectedItem();
+	if (selectedItems().count() == 0)
+		return;
+
+	ConfigItem* item = (ConfigItem*)selectedItems().first();
 	if (!item)
 		return;
 
@@ -451,21 +423,23 @@
 	if (!rootEntry) {
 		if (mode != listMode)
 			goto update;
-		Q3ListViewItemIterator it(this);
+		QTreeWidgetItemIterator it(this);
 		ConfigItem* item;
 
-		for (; it.current(); ++it) {
-			item = (ConfigItem*)it.current();
+		while (*it) {
+			item = (ConfigItem*)(*it);
 			if (!item->menu)
 				continue;
 			item->testUpdateMenu(menu_is_visible(item->menu));
+
+			++it;
 		}
 		return;
 	}
 
 	if (rootEntry != &rootmenu && (mode == singleMode ||
 	    (mode == symbolMode && rootEntry->parent != &rootmenu))) {
-		item = firstChild();
+		item = (ConfigItem *)topLevelItem(0);
 		if (!item)
 			item = new ConfigItem(this, 0, true);
 		last = item;
@@ -479,12 +453,14 @@
 			item->testUpdateMenu(true);
 
 		updateMenuList(item, rootEntry);
-		triggerUpdate();
+		update();
+		resizeColumnToContents(0);
 		return;
 	}
 update:
 	updateMenuList(this, rootEntry);
-	triggerUpdate();
+	update();
+	resizeColumnToContents(0);
 }
 
 void ConfigList::setValue(ConfigItem* item, tristate val)
@@ -506,7 +482,7 @@
 		if (!sym_set_tristate_value(sym, val))
 			return;
 		if (oldval == no && item->menu->list)
-			item->setOpen(TRUE);
+			item->setExpanded(true);
 		parent()->updateList(item);
 		break;
 	}
@@ -524,7 +500,7 @@
 	sym = menu->sym;
 	if (!sym) {
 		if (item->menu->list)
-			item->setOpen(!item->isOpen());
+			item->setExpanded(!item->isExpanded());
 		return;
 	}
 
@@ -536,9 +512,9 @@
 		newexpr = sym_toggle_tristate_value(sym);
 		if (item->menu->list) {
 			if (oldexpr == newexpr)
-				item->setOpen(!item->isOpen());
+				item->setExpanded(!item->isExpanded());
 			else if (oldexpr == no)
-				item->setOpen(TRUE);
+				item->setExpanded(true);
 		}
 		if (oldexpr != newexpr)
 			parent()->updateList(item);
@@ -546,10 +522,7 @@
 	case S_INT:
 	case S_HEX:
 	case S_STRING:
-		if (colMap[dataColIdx] >= 0)
-			item->startRename(colMap[dataColIdx]);
-		else
-			parent()->lineEdit->show(item);
+		parent()->lineEdit->show(item);
 		break;
 	}
 }
@@ -566,8 +539,10 @@
 	updateMenuList(this, 0);
 	rootEntry = menu;
 	updateListAll();
-	setSelected(currentItem(), hasFocus());
-	ensureItemVisible(currentItem());
+	if (currentItem()) {
+		currentItem()->setSelected(hasFocus());
+		scrollToItem(currentItem());
+	}
 }
 
 void ConfigList::setParentMenu(void)
@@ -580,13 +555,16 @@
 		return;
 	setRootMenu(menu_get_parent_menu(rootEntry->parent));
 
-	Q3ListViewItemIterator it(this);
-	for (; (item = (ConfigItem*)it.current()); it++) {
+	QTreeWidgetItemIterator it(this);
+	while (*it) {
+		item = (ConfigItem *)(*it);
 		if (item->menu == oldroot) {
 			setCurrentItem(item);
-			ensureItemVisible(item);
+			scrollToItem(item);
 			break;
 		}
+
+		++it;
 	}
 }
 
@@ -597,8 +575,7 @@
  * parent: either the menu list widget or a menu entry widget
  * menu: entry to be updated
  */
-template <class P>
-void ConfigList::updateMenuList(P* parent, struct menu* menu)
+void ConfigList::updateMenuList(ConfigItem *parent, struct menu* menu)
 {
 	struct menu* child;
 	ConfigItem* item;
@@ -607,8 +584,11 @@
 	enum prop_type type;
 
 	if (!menu) {
-		while ((item = parent->firstChild()))
-			delete item;
+		while (parent->childCount() > 0)
+		{
+			delete parent->takeChild(0);
+		}
+
 		return;
 	}
 
@@ -660,9 +640,74 @@
 	}
 }
 
+void ConfigList::updateMenuList(ConfigList *parent, struct menu* menu)
+{
+	struct menu* child;
+	ConfigItem* item;
+	ConfigItem* last;
+	bool visible;
+	enum prop_type type;
+
+	if (!menu) {
+		while (parent->topLevelItemCount() > 0)
+		{
+			delete parent->takeTopLevelItem(0);
+		}
+
+		return;
+	}
+
+	last = (ConfigItem*)parent->topLevelItem(0);
+	if (last && !last->goParent)
+		last = 0;
+	for (child = menu->list; child; child = child->next) {
+		item = last ? last->nextSibling() : (ConfigItem*)parent->topLevelItem(0);
+		type = child->prompt ? child->prompt->type : P_UNKNOWN;
+
+		switch (mode) {
+		case menuMode:
+			if (!(child->flags & MENU_ROOT))
+				goto hide;
+			break;
+		case symbolMode:
+			if (child->flags & MENU_ROOT)
+				goto hide;
+			break;
+		default:
+			break;
+		}
+
+		visible = menu_is_visible(child);
+		if (!menuSkip(child)) {
+			if (!child->sym && !child->list && !child->prompt)
+				continue;
+			if (!item || item->menu != child)
+				item = new ConfigItem(parent, last, child, visible);
+			else
+				item->testUpdateMenu(visible);
+
+			if (mode == fullMode || mode == menuMode || type != P_MENU)
+				updateMenuList(item, child);
+			else
+				updateMenuList(item, 0);
+			last = item;
+			continue;
+		}
+	hide:
+		if (item && item->menu == child) {
+			last = (ConfigItem*)parent->topLevelItem(0);
+			if (last == item)
+				last = 0;
+			else while (last->nextSibling() != item)
+				last = last->nextSibling();
+			delete item;
+		}
+	}
+}
+
 void ConfigList::keyPressEvent(QKeyEvent* ev)
 {
-	Q3ListViewItem* i = currentItem();
+	QTreeWidgetItem* i = currentItem();
 	ConfigItem* item;
 	struct menu *menu;
 	enum prop_type type;
@@ -714,20 +759,20 @@
 	ev->accept();
 }
 
-void ConfigList::contentsMousePressEvent(QMouseEvent* e)
+void ConfigList::mousePressEvent(QMouseEvent* e)
 {
 	//QPoint p(contentsToViewport(e->pos()));
 	//printf("contentsMousePressEvent: %d,%d\n", p.x(), p.y());
-	Parent::contentsMousePressEvent(e);
+	Parent::mousePressEvent(e);
 }
 
-void ConfigList::contentsMouseReleaseEvent(QMouseEvent* e)
+void ConfigList::mouseReleaseEvent(QMouseEvent* e)
 {
-	QPoint p(contentsToViewport(e->pos()));
+	QPoint p = e->pos();
 	ConfigItem* item = (ConfigItem*)itemAt(p);
 	struct menu *menu;
 	enum prop_type ptype;
-	const QPixmap* pm;
+	QIcon icon;
 	int idx, x;
 
 	if (!item)
@@ -735,14 +780,13 @@
 
 	menu = item->menu;
 	x = header()->offset() + p.x();
-	idx = colRevMap[header()->sectionAt(x)];
+	idx = header()->logicalIndexAt(x);
 	switch (idx) {
 	case promptColIdx:
-		pm = item->pixmap(promptColIdx);
-		if (pm) {
-			int off = header()->sectionPos(0) + itemMargin() +
-				treeStepSize() * (item->depth() + (rootIsDecorated() ? 1 : 0));
-			if (x >= off && x < off + pm->width()) {
+		icon = item->pixmap(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()) {
 				if (item->goParent) {
 					emit parentSelected();
 					break;
@@ -773,19 +817,19 @@
 
 skip:
 	//printf("contentsMouseReleaseEvent: %d,%d\n", p.x(), p.y());
-	Parent::contentsMouseReleaseEvent(e);
+	Parent::mouseReleaseEvent(e);
 }
 
-void ConfigList::contentsMouseMoveEvent(QMouseEvent* e)
+void ConfigList::mouseMoveEvent(QMouseEvent* e)
 {
 	//QPoint p(contentsToViewport(e->pos()));
 	//printf("contentsMouseMoveEvent: %d,%d\n", p.x(), p.y());
-	Parent::contentsMouseMoveEvent(e);
+	Parent::mouseMoveEvent(e);
 }
 
-void ConfigList::contentsMouseDoubleClickEvent(QMouseEvent* e)
+void ConfigList::mouseDoubleClickEvent(QMouseEvent* e)
 {
-	QPoint p(contentsToViewport(e->pos()));
+	QPoint p = e->pos(); // TODO: Check if this works(was contentsToViewport).
 	ConfigItem* item = (ConfigItem*)itemAt(p);
 	struct menu *menu;
 	enum prop_type ptype;
@@ -807,7 +851,7 @@
 
 skip:
 	//printf("contentsMouseDoubleClickEvent: %d,%d\n", p.x(), p.y());
-	Parent::contentsMouseDoubleClickEvent(e);
+	Parent::mouseDoubleClickEvent(e);
 }
 
 void ConfigList::focusInEvent(QFocusEvent *e)
@@ -818,7 +862,7 @@
 
 	ConfigItem* item = (ConfigItem *)currentItem();
 	if (item) {
-		setSelected(item, TRUE);
+		item->setSelected(true);
 		menu = item->menu;
 	}
 	emit gotFocus(menu);
@@ -828,33 +872,33 @@
 {
 	if (e->y() <= header()->geometry().bottom()) {
 		if (!headerPopup) {
-			Q3Action *action;
+			QAction *action;
 
-			headerPopup = new Q3PopupMenu(this);
-			action = new Q3Action(NULL, _("Show Name"), 0, this);
-			  action->setToggleAction(TRUE);
+			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->setOn(showName);
-			  action->addTo(headerPopup);
-			action = new Q3Action(NULL, _("Show Range"), 0, this);
-			  action->setToggleAction(TRUE);
+			  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->setOn(showRange);
-			  action->addTo(headerPopup);
-			action = new Q3Action(NULL, _("Show Data"), 0, this);
-			  action->setToggleAction(TRUE);
+			  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->setOn(showData);
-			  action->addTo(headerPopup);
+			  action->setChecked(showData);
+			  headerPopup->addAction(action);
 		}
 		headerPopup->exec(e->globalPos());
 		e->accept();
@@ -868,11 +912,17 @@
 QAction *ConfigView::showPromptAction;
 
 ConfigView::ConfigView(QWidget* parent, const char *name)
-	: Parent(parent, name)
+	: Parent(parent)
 {
-	list = new ConfigList(this, name);
+	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;
@@ -931,10 +981,13 @@
 
 void ConfigList::setAllOpen(bool open)
 {
-	Q3ListViewItemIterator it(this);
+	QTreeWidgetItemIterator it(this);
 
-	for (; it.current(); it++)
-		it.current()->setOpen(open);
+	while (*it) {
+		(*it)->setExpanded(open);
+
+		++it;
+	}
 }
 
 void ConfigView::updateList(ConfigItem* item)
@@ -954,11 +1007,14 @@
 }
 
 ConfigInfoView::ConfigInfoView(QWidget* parent, const char *name)
-	: Parent(parent, name), sym(0), _menu(0)
+	: Parent(parent), sym(0), _menu(0)
 {
-	if (name) {
-		configSettings->beginGroup(name);
-		_showDebug = configSettings->readBoolEntry("/showDebug", false);
+	setObjectName(name);
+
+
+	if (!objectName().isEmpty()) {
+		configSettings->beginGroup(objectName());
+		_showDebug = configSettings->value("/showDebug", false).toBool();
 		configSettings->endGroup();
 		connect(configApp, SIGNAL(aboutToQuit()), SLOT(saveSettings()));
 	}
@@ -966,9 +1022,9 @@
 
 void ConfigInfoView::saveSettings(void)
 {
-	if (name()) {
-		configSettings->beginGroup(name());
-		configSettings->writeEntry("/showDebug", showDebug());
+	if (!objectName().isEmpty()) {
+		configSettings->beginGroup(objectName());
+		configSettings->setValue("/showDebug", showDebug());
 		configSettings->endGroup();
 	}
 }
@@ -1127,8 +1183,8 @@
 {
 	QRegExp re("[<>&\"\\n]");
 	QString res = str;
-	for (int i = 0; (i = res.find(re, i)) >= 0;) {
-		switch (res[i].latin1()) {
+	for (int i = 0; (i = res.indexOf(re, i)) >= 0;) {
+		switch (res[i].toLatin1()) {
 		case '<':
 			res.replace(i, 1, "&lt;");
 			i += 4;
@@ -1167,37 +1223,42 @@
 		*text += str2;
 }
 
-Q3PopupMenu* ConfigInfoView::createPopupMenu(const QPoint& pos)
+QMenu* ConfigInfoView::createStandardContextMenu(const QPoint & pos)
 {
-	Q3PopupMenu* popup = Parent::createPopupMenu(pos);
-	Q3Action* action = new Q3Action(NULL, _("Show Debug Info"), 0, popup);
-	  action->setToggleAction(TRUE);
+	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->setOn(showDebug());
-	popup->insertSeparator();
-	action->addTo(popup);
+	  action->setChecked(showDebug());
+	popup->addSeparator();
+	popup->addAction(action);
 	return popup;
 }
 
-void ConfigInfoView::contentsContextMenuEvent(QContextMenuEvent *e)
+void ConfigInfoView::contextMenuEvent(QContextMenuEvent *e)
 {
-	Parent::contentsContextMenuEvent(e);
+	Parent::contextMenuEvent(e);
 }
 
 ConfigSearchWindow::ConfigSearchWindow(ConfigMainWindow* parent, const char *name)
-	: Parent(parent, name), result(NULL)
+	: Parent(parent), result(NULL)
 {
-	setCaption("Search Config");
+	setObjectName(name);
+	setWindowTitle("Search Config");
 
-	QVBoxLayout* layout1 = new QVBoxLayout(this, 11, 6);
-	QHBoxLayout* layout2 = new QHBoxLayout(0, 0, 6);
+	QVBoxLayout* layout1 = new QVBoxLayout(this);
+	layout1->setContentsMargins(11, 11, 11, 11);
+	layout1->setSpacing(6);
+	QHBoxLayout* layout2 = new QHBoxLayout(0);
+	layout2->setContentsMargins(0, 0, 0, 0);
+	layout2->setSpacing(6);
 	layout2->addWidget(new QLabel(_("Find:"), this));
 	editField = new QLineEdit(this);
 	connect(editField, SIGNAL(returnPressed()), SLOT(search()));
 	layout2->addWidget(editField);
 	searchButton = new QPushButton(_("Search"), this);
-	searchButton->setAutoDefault(FALSE);
+	searchButton->setAutoDefault(false);
 	connect(searchButton, SIGNAL(clicked()), SLOT(search()));
 	layout2->addWidget(searchButton);
 	layout1->addLayout(layout2);
@@ -1215,19 +1276,19 @@
 	layout1->addWidget(split);
 
 	if (name) {
-		int x, y, width, height;
+		QVariant x, y;
+		int width, height;
 		bool ok;
 
 		configSettings->beginGroup(name);
-		width = configSettings->readNumEntry("/window width", parent->width() / 2);
-		height = configSettings->readNumEntry("/window height", parent->height() / 2);
+		width = configSettings->value("/window width", parent->width() / 2).toInt();
+		height = configSettings->value("/window height", parent->height() / 2).toInt();
 		resize(width, height);
-		x = configSettings->readNumEntry("/window x", 0, &ok);
-		if (ok)
-			y = configSettings->readNumEntry("/window y", 0, &ok);
-		if (ok)
-			move(x, y);
-		Q3ValueList<int> sizes = configSettings->readSizes("/split", &ok);
+		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();
@@ -1237,12 +1298,12 @@
 
 void ConfigSearchWindow::saveSettings(void)
 {
-	if (name()) {
-		configSettings->beginGroup(name());
-		configSettings->writeEntry("/window x", pos().x());
-		configSettings->writeEntry("/window y", pos().y());
-		configSettings->writeEntry("/window width", size().width());
-		configSettings->writeEntry("/window height", size().height());
+	if (!objectName().isEmpty()) {
+		configSettings->beginGroup(objectName());
+		configSettings->setValue("/window x", pos().x());
+		configSettings->setValue("/window y", pos().y());
+		configSettings->setValue("/window width", size().width());
+		configSettings->setValue("/window height", size().height());
 		configSettings->writeSizes("/split", split->sizes());
 		configSettings->endGroup();
 	}
@@ -1258,7 +1319,7 @@
 	list->list->clear();
 	info->clear();
 
-	result = sym_re_search(editField->text().latin1());
+	result = sym_re_search(editField->text().toLatin1());
 	if (!result)
 		return;
 	for (p = result; *p; p++) {
@@ -1275,29 +1336,25 @@
 	: searchWindow(0)
 {
 	QMenuBar* menu;
-	bool ok;
-	int x, y, width, height;
+	bool ok = true;
+	QVariant x, y;
+	int width, height;
 	char title[256];
 
 	QDesktopWidget *d = configApp->desktop();
 	snprintf(title, sizeof(title), "%s%s",
 		rootmenu.prompt->text,
-#if QT_VERSION < 0x040000
-		" (Qt3)"
-#else
 		""
-#endif
 		);
-	setCaption(title);
+	setWindowTitle(title);
 
-	width = configSettings->readNumEntry("/window width", d->width() - 64);
-	height = configSettings->readNumEntry("/window height", d->height() - 64);
+	width = configSettings->value("/window width", d->width() - 64).toInt();
+	height = configSettings->value("/window height", d->height() - 64).toInt();
 	resize(width, height);
-	x = configSettings->readNumEntry("/window x", 0, &ok);
-	if (ok)
-		y = configSettings->readNumEntry("/window y", 0, &ok);
-	if (ok)
-		move(x, y);
+	x = configSettings->value("/window x");
+	y = configSettings->value("/window y");
+	if ((x.isValid())&&(y.isValid()))
+		move(x.toInt(), y.toInt());
 
 	split1 = new QSplitter(this);
 	split1->setOrientation(Qt::Horizontal);
@@ -1314,127 +1371,115 @@
 	configList = configView->list;
 
 	helpText = new ConfigInfoView(split2, "help");
-	helpText->setTextFormat(Qt::RichText);
 
 	setTabOrder(configList, helpText);
 	configList->setFocus();
 
 	menu = menuBar();
-	toolBar = new Q3ToolBar("Tools", this);
+	toolBar = new QToolBar("Tools", this);
+	addToolBar(toolBar);
 
-	backAction = new Q3Action("Back", QPixmap(xpm_back), _("Back"), 0, this);
-	  connect(backAction, SIGNAL(activated()), SLOT(goBack()));
-	  backAction->setEnabled(FALSE);
-	Q3Action *quitAction = new Q3Action("Quit", _("&Quit"), Qt::CTRL + Qt::Key_Q, this);
-	  connect(quitAction, SIGNAL(activated()), SLOT(close()));
-	Q3Action *loadAction = new Q3Action("Load", QPixmap(xpm_load), _("&Load"), Qt::CTRL + Qt::Key_L, this);
-	  connect(loadAction, SIGNAL(activated()), SLOT(loadConfig()));
-	saveAction = new Q3Action("Save", QPixmap(xpm_save), _("&Save"), Qt::CTRL + Qt::Key_S, this);
-	  connect(saveAction, SIGNAL(activated()), SLOT(saveConfig()));
+	backAction = new QAction(QPixmap(xpm_back), _("Back"), this);
+	  connect(backAction, SIGNAL(triggered(bool)), SLOT(goBack()));
+	  backAction->setEnabled(false);
+	QAction *quitAction = new QAction(_("&Quit"), this);
+	quitAction->setShortcut(Qt::CTRL + Qt::Key_Q);
+	  connect(quitAction, SIGNAL(triggered(bool)), SLOT(close()));
+	QAction *loadAction = new QAction(QPixmap(xpm_load), _("&Load"), this);
+	loadAction->setShortcut(Qt::CTRL + Qt::Key_L);
+	  connect(loadAction, SIGNAL(triggered(bool)), SLOT(loadConfig()));
+	saveAction = new QAction(QPixmap(xpm_save), _("&Save"), this);
+	saveAction->setShortcut(Qt::CTRL + Qt::Key_S);
+	  connect(saveAction, SIGNAL(triggered(bool)), SLOT(saveConfig()));
 	conf_set_changed_callback(conf_changed);
 	// Set saveAction's initial state
 	conf_changed();
-	Q3Action *saveAsAction = new Q3Action("Save As...", _("Save &As..."), 0, this);
-	  connect(saveAsAction, SIGNAL(activated()), SLOT(saveConfigAs()));
-	Q3Action *searchAction = new Q3Action("Find", _("&Find"), Qt::CTRL + Qt::Key_F, this);
-	  connect(searchAction, SIGNAL(activated()), SLOT(searchConfig()));
-	Q3Action *singleViewAction = new Q3Action("Single View", QPixmap(xpm_single_view), _("Single View"), 0, this);
-	  connect(singleViewAction, SIGNAL(activated()), SLOT(showSingleView()));
-	Q3Action *splitViewAction = new Q3Action("Split View", QPixmap(xpm_split_view), _("Split View"), 0, this);
-	  connect(splitViewAction, SIGNAL(activated()), SLOT(showSplitView()));
-	Q3Action *fullViewAction = new Q3Action("Full View", QPixmap(xpm_tree_view), _("Full View"), 0, this);
-	  connect(fullViewAction, SIGNAL(activated()), SLOT(showFullView()));
+	QAction *saveAsAction = new QAction(_("Save &As..."), this);
+	  connect(saveAsAction, SIGNAL(triggered(bool)), SLOT(saveConfigAs()));
+	QAction *searchAction = new QAction(_("&Find"), this);
+	searchAction->setShortcut(Qt::CTRL + Qt::Key_F);
+	  connect(searchAction, SIGNAL(triggered(bool)), SLOT(searchConfig()));
+	singleViewAction = new QAction(QPixmap(xpm_single_view), _("Single View"), this);
+	singleViewAction->setCheckable(true);
+	  connect(singleViewAction, SIGNAL(triggered(bool)), SLOT(showSingleView()));
+	splitViewAction = new QAction(QPixmap(xpm_split_view), _("Split View"), this);
+	splitViewAction->setCheckable(true);
+	  connect(splitViewAction, SIGNAL(triggered(bool)), SLOT(showSplitView()));
+	fullViewAction = new QAction(QPixmap(xpm_tree_view), _("Full View"), this);
+	fullViewAction->setCheckable(true);
+	  connect(fullViewAction, SIGNAL(triggered(bool)), SLOT(showFullView()));
 
-	Q3Action *showNameAction = new Q3Action(NULL, _("Show Name"), 0, this);
-	  showNameAction->setToggleAction(TRUE);
+	QAction *showNameAction = new QAction(_("Show Name"), this);
+	  showNameAction->setCheckable(true);
 	  connect(showNameAction, SIGNAL(toggled(bool)), configView, SLOT(setShowName(bool)));
-	  connect(configView, SIGNAL(showNameChanged(bool)), showNameAction, SLOT(setOn(bool)));
-	  showNameAction->setOn(configView->showName());
-	Q3Action *showRangeAction = new Q3Action(NULL, _("Show Range"), 0, this);
-	  showRangeAction->setToggleAction(TRUE);
+	  showNameAction->setChecked(configView->showName());
+	QAction *showRangeAction = new QAction(_("Show Range"), this);
+	  showRangeAction->setCheckable(true);
 	  connect(showRangeAction, SIGNAL(toggled(bool)), configView, SLOT(setShowRange(bool)));
-	  connect(configView, SIGNAL(showRangeChanged(bool)), showRangeAction, SLOT(setOn(bool)));
-	  showRangeAction->setOn(configList->showRange);
-	Q3Action *showDataAction = new Q3Action(NULL, _("Show Data"), 0, this);
-	  showDataAction->setToggleAction(TRUE);
+	QAction *showDataAction = new QAction(_("Show Data"), this);
+	  showDataAction->setCheckable(true);
 	  connect(showDataAction, SIGNAL(toggled(bool)), configView, SLOT(setShowData(bool)));
-	  connect(configView, SIGNAL(showDataChanged(bool)), showDataAction, SLOT(setOn(bool)));
-	  showDataAction->setOn(configList->showData);
 
 	QActionGroup *optGroup = new QActionGroup(this);
-	optGroup->setExclusive(TRUE);
-	connect(optGroup, SIGNAL(selected(QAction *)), configView,
+	optGroup->setExclusive(true);
+	connect(optGroup, SIGNAL(triggered(QAction*)), configView,
 		SLOT(setOptionMode(QAction *)));
-	connect(optGroup, SIGNAL(selected(QAction *)), menuView,
+	connect(optGroup, SIGNAL(triggered(QAction *)), menuView,
 		SLOT(setOptionMode(QAction *)));
 
-#if QT_VERSION >= 0x040000
 	configView->showNormalAction = new QAction(_("Show Normal Options"), optGroup);
 	configView->showAllAction = new QAction(_("Show All Options"), optGroup);
 	configView->showPromptAction = new QAction(_("Show Prompt Options"), optGroup);
-#else
-	configView->showNormalAction = new QAction(_("Show Normal Options"), 0, optGroup);
-	configView->showAllAction = new QAction(_("Show All Options"), 0, optGroup);
-	configView->showPromptAction = new QAction(_("Show Prompt Options"), 0, optGroup);
-#endif
-	configView->showNormalAction->setToggleAction(TRUE);
-	configView->showNormalAction->setOn(configList->optMode == normalOpt);
-	configView->showAllAction->setToggleAction(TRUE);
-	configView->showAllAction->setOn(configList->optMode == allOpt);
-	configView->showPromptAction->setToggleAction(TRUE);
-	configView->showPromptAction->setOn(configList->optMode == promptOpt);
+	configView->showNormalAction->setCheckable(true);
+	configView->showAllAction->setCheckable(true);
+	configView->showPromptAction->setCheckable(true);
 
-	Q3Action *showDebugAction = new Q3Action(NULL, _("Show Debug Info"), 0, this);
-	  showDebugAction->setToggleAction(TRUE);
+	QAction *showDebugAction = new QAction( _("Show Debug Info"), this);
+	  showDebugAction->setCheckable(true);
 	  connect(showDebugAction, SIGNAL(toggled(bool)), helpText, SLOT(setShowDebug(bool)));
-	  connect(helpText, SIGNAL(showDebugChanged(bool)), showDebugAction, SLOT(setOn(bool)));
-	  showDebugAction->setOn(helpText->showDebug());
+	  showDebugAction->setChecked(helpText->showDebug());
 
-	Q3Action *showIntroAction = new Q3Action(NULL, _("Introduction"), 0, this);
-	  connect(showIntroAction, SIGNAL(activated()), SLOT(showIntro()));
-	Q3Action *showAboutAction = new Q3Action(NULL, _("About"), 0, this);
-	  connect(showAboutAction, SIGNAL(activated()), SLOT(showAbout()));
+	QAction *showIntroAction = new QAction( _("Introduction"), this);
+	  connect(showIntroAction, SIGNAL(triggered(bool)), SLOT(showIntro()));
+	QAction *showAboutAction = new QAction( _("About"), this);
+	  connect(showAboutAction, SIGNAL(triggered(bool)), SLOT(showAbout()));
 
 	// init tool bar
-	backAction->addTo(toolBar);
+	toolBar->addAction(backAction);
 	toolBar->addSeparator();
-	loadAction->addTo(toolBar);
-	saveAction->addTo(toolBar);
+	toolBar->addAction(loadAction);
+	toolBar->addAction(saveAction);
 	toolBar->addSeparator();
-	singleViewAction->addTo(toolBar);
-	splitViewAction->addTo(toolBar);
-	fullViewAction->addTo(toolBar);
+	toolBar->addAction(singleViewAction);
+	toolBar->addAction(splitViewAction);
+	toolBar->addAction(fullViewAction);
 
 	// create config menu
-	Q3PopupMenu* config = new Q3PopupMenu(this);
-	menu->insertItem(_("&File"), config);
-	loadAction->addTo(config);
-	saveAction->addTo(config);
-	saveAsAction->addTo(config);
-	config->insertSeparator();
-	quitAction->addTo(config);
+	QMenu* config = menu->addMenu(_("&File"));
+	config->addAction(loadAction);
+	config->addAction(saveAction);
+	config->addAction(saveAsAction);
+	config->addSeparator();
+	config->addAction(quitAction);
 
 	// create edit menu
-	Q3PopupMenu* editMenu = new Q3PopupMenu(this);
-	menu->insertItem(_("&Edit"), editMenu);
-	searchAction->addTo(editMenu);
+	QMenu* editMenu = menu->addMenu(_("&Edit"));
+	editMenu->addAction(searchAction);
 
 	// create options menu
-	Q3PopupMenu* optionMenu = new Q3PopupMenu(this);
-	menu->insertItem(_("&Option"), optionMenu);
-	showNameAction->addTo(optionMenu);
-	showRangeAction->addTo(optionMenu);
-	showDataAction->addTo(optionMenu);
-	optionMenu->insertSeparator();
-	optGroup->addTo(optionMenu);
-	optionMenu->insertSeparator();
+	QMenu* optionMenu = menu->addMenu(_("&Option"));
+	optionMenu->addAction(showNameAction);
+	optionMenu->addAction(showRangeAction);
+	optionMenu->addAction(showDataAction);
+	optionMenu->addSeparator();
+	optionMenu->addActions(optGroup->actions());
+	optionMenu->addSeparator();
 
 	// create help menu
-	Q3PopupMenu* helpMenu = new Q3PopupMenu(this);
-	menu->insertSeparator();
-	menu->insertItem(_("&Help"), helpMenu);
-	showIntroAction->addTo(helpMenu);
-	showAboutAction->addTo(helpMenu);
+	menu->addSeparator();
+	QMenu* helpMenu = menu->addMenu(_("&Help"));
+	helpMenu->addAction(showIntroAction);
+	helpMenu->addAction(showAboutAction);
 
 	connect(configList, SIGNAL(menuChanged(struct menu *)),
 		helpText, SLOT(setInfo(struct menu *)));
@@ -1456,7 +1501,7 @@
 	connect(helpText, SIGNAL(menuSelected(struct menu *)),
 		SLOT(setMenuLink(struct menu *)));
 
-	QString listMode = configSettings->readEntry("/listMode", "symbol");
+	QString listMode = configSettings->value("/listMode", "symbol").toString();
 	if (listMode == "single")
 		showSingleView();
 	else if (listMode == "full")
@@ -1465,7 +1510,7 @@
 		showSplitView();
 
 	// UI setup done, restore splitter positions
-	Q3ValueList<int> sizes = configSettings->readSizes("/split1", &ok);
+	QList<int> sizes = configSettings->readSizes("/split1", &ok);
 	if (ok)
 		split1->setSizes(sizes);
 
@@ -1476,7 +1521,7 @@
 
 void ConfigMainWindow::loadConfig(void)
 {
-	QString s = Q3FileDialog::getOpenFileName(conf_get_configname(), NULL, this);
+	QString s = QFileDialog::getOpenFileName(this, "", conf_get_configname());
 	if (s.isNull())
 		return;
 	if (conf_read(QFile::encodeName(s)))
@@ -1495,7 +1540,7 @@
 
 void ConfigMainWindow::saveConfigAs(void)
 {
-	QString s = Q3FileDialog::getSaveFileName(conf_get_configname(), NULL, this);
+	QString s = QFileDialog::getSaveFileName(this, "", conf_get_configname());
 	if (s.isNull())
 		return;
 	saveConfig();
@@ -1512,9 +1557,9 @@
 {
 	configList->setRootMenu(menu);
 	if (configList->rootEntry->parent == &rootmenu)
-		backAction->setEnabled(FALSE);
+		backAction->setEnabled(false);
 	else
-		backAction->setEnabled(TRUE);
+		backAction->setEnabled(true);
 }
 
 void ConfigMainWindow::setMenuLink(struct menu *menu)
@@ -1546,8 +1591,8 @@
 				return;
 			item = menuList->findConfigItem(parent);
 			if (item) {
-				menuList->setSelected(item, TRUE);
-				menuList->ensureItemVisible(item);
+				item->setSelected(true);
+				menuList->scrollToItem(item);
 			}
 			list->setRootMenu(parent);
 		}
@@ -1562,8 +1607,8 @@
 	if (list) {
 		item = list->findConfigItem(menu);
 		if (item) {
-			list->setSelected(item, TRUE);
-			list->ensureItemVisible(item);
+			item->setSelected(true);
+			list->scrollToItem(item);
 			list->setFocus();
 		}
 	}
@@ -1577,15 +1622,21 @@
 
 void ConfigMainWindow::goBack(void)
 {
-	ConfigItem* item;
+	ConfigItem* item, *oldSelection;
 
 	configList->setParentMenu();
 	if (configList->rootEntry == &rootmenu)
-		backAction->setEnabled(FALSE);
-	item = (ConfigItem*)menuList->selectedItem();
+		backAction->setEnabled(false);
+
+	if (menuList->selectedItems().count() == 0)
+		return;
+
+	item = (ConfigItem*)menuList->selectedItems().first();
+	oldSelection = item;
 	while (item) {
 		if (item->menu == configList->rootEntry) {
-			menuList->setSelected(item, TRUE);
+			oldSelection->setSelected(false);
+			item->setSelected(true);
 			break;
 		}
 		item = (ConfigItem*)item->parent();
@@ -1594,6 +1645,13 @@
 
 void ConfigMainWindow::showSingleView(void)
 {
+	singleViewAction->setEnabled(false);
+	singleViewAction->setChecked(true);
+	splitViewAction->setEnabled(true);
+	splitViewAction->setChecked(false);
+	fullViewAction->setEnabled(true);
+	fullViewAction->setChecked(false);
+
 	menuView->hide();
 	menuList->setRootMenu(0);
 	configList->mode = singleMode;
@@ -1601,28 +1659,41 @@
 		configList->updateListAll();
 	else
 		configList->setRootMenu(&rootmenu);
-	configList->setAllOpen(TRUE);
 	configList->setFocus();
 }
 
 void ConfigMainWindow::showSplitView(void)
 {
+	singleViewAction->setEnabled(true);
+	singleViewAction->setChecked(false);
+	splitViewAction->setEnabled(false);
+	splitViewAction->setChecked(true);
+	fullViewAction->setEnabled(true);
+	fullViewAction->setChecked(false);
+
 	configList->mode = symbolMode;
 	if (configList->rootEntry == &rootmenu)
 		configList->updateListAll();
 	else
 		configList->setRootMenu(&rootmenu);
-	configList->setAllOpen(TRUE);
+	configList->setAllOpen(true);
 	configApp->processEvents();
 	menuList->mode = menuMode;
 	menuList->setRootMenu(&rootmenu);
-	menuList->setAllOpen(TRUE);
+	menuList->setAllOpen(true);
 	menuView->show();
 	menuList->setFocus();
 }
 
 void ConfigMainWindow::showFullView(void)
 {
+	singleViewAction->setEnabled(true);
+	singleViewAction->setChecked(false);
+	splitViewAction->setEnabled(true);
+	splitViewAction->setChecked(false);
+	fullViewAction->setEnabled(false);
+	fullViewAction->setChecked(true);
+
 	menuView->hide();
 	menuList->setRootMenu(0);
 	configList->mode = fullMode;
@@ -1630,7 +1701,6 @@
 		configList->updateListAll();
 	else
 		configList->setRootMenu(&rootmenu);
-	configList->setAllOpen(FALSE);
 	configList->setFocus();
 }
 
@@ -1684,7 +1754,8 @@
 
 void ConfigMainWindow::showAbout(void)
 {
-	static const QString str = _("qconf is Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>.\n\n"
+	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");
 
 	QMessageBox::information(this, "qconf", str);
@@ -1692,10 +1763,10 @@
 
 void ConfigMainWindow::saveSettings(void)
 {
-	configSettings->writeEntry("/window x", pos().x());
-	configSettings->writeEntry("/window y", pos().y());
-	configSettings->writeEntry("/window width", size().width());
-	configSettings->writeEntry("/window height", size().height());
+	configSettings->setValue("/window x", pos().x());
+	configSettings->setValue("/window y", pos().y());
+	configSettings->setValue("/window width", size().width());
+	configSettings->setValue("/window height", size().height());
 
 	QString entry;
 	switch(configList->mode) {
@@ -1714,7 +1785,7 @@
 	default:
 		break;
 	}
-	configSettings->writeEntry("/listMode", entry);
+	configSettings->setValue("/listMode", entry);
 
 	configSettings->writeSizes("/split1", split1->sizes());
 	configSettings->writeSizes("/split2", split2->sizes());
@@ -1746,7 +1817,7 @@
 
 static void usage(void)
 {
-	printf(_("%s [-s] <config>\n"), progname);
+	printf(_("%s [-s] <config>\n").toLatin1().constData(), progname);
 	exit(0);
 }
 
@@ -1785,7 +1856,6 @@
 	v = new ConfigMainWindow();
 
 	//zconfdump(stdout);
-	configApp->setMainWidget(v);
 	configApp->connect(configApp, SIGNAL(lastWindowClosed()), SLOT(quit()));
 	configApp->connect(configApp, SIGNAL(aboutToQuit()), v, SLOT(saveSettings()));
 	v->show();
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index bde0c6b..a40036d 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -3,26 +3,18 @@
  * Released under the terms of the GNU GPL v2.0.
  */
 
-#if QT_VERSION < 0x040000
-#include <qlistview.h>
-#else
-#include <q3listview.h>
-#endif
+#include <QTextBrowser>
+#include <QTreeWidget>
+#include <QMainWindow>
+#include <QHeaderView>
 #include <qsettings.h>
-
-#if QT_VERSION < 0x040000
-#define Q3ValueList             QValueList
-#define Q3PopupMenu             QPopupMenu
-#define Q3ListView              QListView
-#define Q3ListViewItem          QListViewItem
-#define Q3VBox                  QVBox
-#define Q3TextBrowser           QTextBrowser
-#define Q3MainWindow            QMainWindow
-#define Q3Action                QAction
-#define Q3ToolBar               QToolBar
-#define Q3ListViewItemIterator  QListViewItemIterator
-#define Q3FileDialog            QFileDialog
-#endif
+#include <QPushButton>
+#include <QSettings>
+#include <QLineEdit>
+#include <QSplitter>
+#include <QCheckBox>
+#include <QDialog>
+#include "expr.h"
 
 class ConfigView;
 class ConfigList;
@@ -33,8 +25,8 @@
 class ConfigSettings : public QSettings {
 public:
 	ConfigSettings();
-	Q3ValueList<int> readSizes(const QString& key, bool *ok);
-	bool writeSizes(const QString& key, const Q3ValueList<int>& value);
+	QList<int> readSizes(const QString& key, bool *ok);
+	bool writeSizes(const QString& key, const QList<int>& value);
 };
 
 enum colIdx {
@@ -47,9 +39,9 @@
 	normalOpt = 0, allOpt, promptOpt
 };
 
-class ConfigList : public Q3ListView {
+class ConfigList : public QTreeWidget {
 	Q_OBJECT
-	typedef class Q3ListView Parent;
+	typedef class QTreeWidget Parent;
 public:
 	ConfigList(ConfigView* p, const char *name = 0);
 	void reinit(void);
@@ -61,10 +53,10 @@
 
 protected:
 	void keyPressEvent(QKeyEvent *e);
-	void contentsMousePressEvent(QMouseEvent *e);
-	void contentsMouseReleaseEvent(QMouseEvent *e);
-	void contentsMouseMoveEvent(QMouseEvent *e);
-	void contentsMouseDoubleClickEvent(QMouseEvent *e);
+	void mousePressEvent(QMouseEvent *e);
+	void mouseReleaseEvent(QMouseEvent *e);
+	void mouseMoveEvent(QMouseEvent *e);
+	void mouseDoubleClickEvent(QMouseEvent *e);
 	void focusInEvent(QFocusEvent *e);
 	void contextMenuEvent(QContextMenuEvent *e);
 
@@ -95,32 +87,23 @@
 	}
 	ConfigItem* firstChild() const
 	{
-		return (ConfigItem *)Parent::firstChild();
+		return (ConfigItem *)children().first();
 	}
-	int mapIdx(colIdx idx)
+	void addColumn(colIdx idx)
 	{
-		return colMap[idx];
-	}
-	void addColumn(colIdx idx, const QString& label)
-	{
-		colMap[idx] = Parent::addColumn(label);
-		colRevMap[colMap[idx]] = idx;
+		showColumn(idx);
 	}
 	void removeColumn(colIdx idx)
 	{
-		int col = colMap[idx];
-		if (col >= 0) {
-			Parent::removeColumn(col);
-			colRevMap[col] = colMap[idx] = -1;
-		}
+		hideColumn(idx);
 	}
 	void setAllOpen(bool open);
 	void setParentMenu(void);
 
 	bool menuSkip(struct menu *);
 
-	template <class P>
-	void updateMenuList(P*, struct menu*);
+	void updateMenuList(ConfigItem *parent, struct menu*);
+	void updateMenuList(ConfigList *parent, struct menu*);
 
 	bool updateAll;
 
@@ -132,30 +115,26 @@
 	enum listMode mode;
 	enum optionMode optMode;
 	struct menu *rootEntry;
-	QColorGroup disabledColorGroup;
-	QColorGroup inactivedColorGroup;
-	Q3PopupMenu* headerPopup;
-
-private:
-	int colMap[colNr];
-	int colRevMap[colNr];
+	QPalette disabledColorGroup;
+	QPalette inactivedColorGroup;
+	QMenu* headerPopup;
 };
 
-class ConfigItem : public Q3ListViewItem {
-	typedef class Q3ListViewItem Parent;
+class ConfigItem : public QTreeWidgetItem {
+	typedef class QTreeWidgetItem Parent;
 public:
-	ConfigItem(Q3ListView *parent, ConfigItem *after, struct menu *m, bool v)
-	: Parent(parent, after), menu(m), visible(v), goParent(false)
+	ConfigItem(ConfigList *parent, ConfigItem *after, struct menu *m, bool v)
+	: Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false)
 	{
 		init();
 	}
 	ConfigItem(ConfigItem *parent, ConfigItem *after, struct menu *m, bool v)
-	: Parent(parent, after), menu(m), visible(v), goParent(false)
+	: Parent(parent, after), nextItem(0), menu(m), visible(v), goParent(false)
 	{
 		init();
 	}
-	ConfigItem(Q3ListView *parent, ConfigItem *after, bool v)
-	: Parent(parent, after), menu(0), visible(v), goParent(true)
+	ConfigItem(ConfigList *parent, ConfigItem *after, bool v)
+	: Parent(parent, after), nextItem(0), menu(0), visible(v), goParent(true)
 	{
 		init();
 	}
@@ -166,33 +145,43 @@
 	void testUpdateMenu(bool v);
 	ConfigList* listView() const
 	{
-		return (ConfigList*)Parent::listView();
+		return (ConfigList*)Parent::treeWidget();
 	}
 	ConfigItem* firstChild() const
 	{
-		return (ConfigItem *)Parent::firstChild();
+		return (ConfigItem *)Parent::child(0);
 	}
-	ConfigItem* nextSibling() const
+	ConfigItem* nextSibling()
 	{
-		return (ConfigItem *)Parent::nextSibling();
+		ConfigItem *ret = NULL;
+		ConfigItem *_parent = (ConfigItem *)parent();
+
+		if(_parent) {
+			ret = (ConfigItem *)_parent->child(_parent->indexOfChild(this)+1);
+		} else {
+			QTreeWidget *_treeWidget = treeWidget();
+			ret = (ConfigItem *)_treeWidget->topLevelItem(_treeWidget->indexOfTopLevelItem(this)+1);
+		}
+
+		return ret;
 	}
 	void setText(colIdx idx, const QString& text)
 	{
-		Parent::setText(listView()->mapIdx(idx), text);
+		Parent::setText(idx, text);
 	}
 	QString text(colIdx idx) const
 	{
-		return Parent::text(listView()->mapIdx(idx));
+		return Parent::text(idx);
 	}
-	void setPixmap(colIdx idx, const QPixmap& pm)
+	void setPixmap(colIdx idx, const QIcon &icon)
 	{
-		Parent::setPixmap(listView()->mapIdx(idx), pm);
+		Parent::setIcon(idx, icon);
 	}
-	const QPixmap* pixmap(colIdx idx) const
+	const QIcon pixmap(colIdx idx) const
 	{
-		return Parent::pixmap(listView()->mapIdx(idx));
+		return icon(idx);
 	}
-	void paintCell(QPainter* p, const QColorGroup& cg, int column, int width, int align);
+	// TODO: Implement paintCell
 
 	ConfigItem* nextItem;
 	struct menu *menu;
@@ -216,9 +205,9 @@
 	ConfigItem *item;
 };
 
-class ConfigView : public Q3VBox {
+class ConfigView : public QWidget {
 	Q_OBJECT
-	typedef class Q3VBox Parent;
+	typedef class QWidget Parent;
 public:
 	ConfigView(QWidget* parent, const char *name = 0);
 	~ConfigView(void);
@@ -249,9 +238,9 @@
 	static QAction *showPromptAction;
 };
 
-class ConfigInfoView : public Q3TextBrowser {
+class ConfigInfoView : public QTextBrowser {
 	Q_OBJECT
-	typedef class Q3TextBrowser Parent;
+	typedef class QTextBrowser Parent;
 public:
 	ConfigInfoView(QWidget* parent, const char *name = 0);
 	bool showDebug(void) const { return _showDebug; }
@@ -271,8 +260,8 @@
 	QString debug_info(struct symbol *sym);
 	static QString print_filter(const QString &str);
 	static void expr_print_help(void *data, struct symbol *sym, const char *str);
-	Q3PopupMenu* createPopupMenu(const QPoint& pos);
-	void contentsContextMenuEvent(QContextMenuEvent *e);
+	QMenu *createStandardContextMenu(const QPoint & pos);
+	void contextMenuEvent(QContextMenuEvent *e);
 
 	struct symbol *sym;
 	struct menu *_menu;
@@ -299,10 +288,10 @@
 	struct symbol **result;
 };
 
-class ConfigMainWindow : public Q3MainWindow {
+class ConfigMainWindow : public QMainWindow {
 	Q_OBJECT
 
-	static Q3Action *saveAction;
+	static QAction *saveAction;
 	static void conf_changed(void);
 public:
 	ConfigMainWindow(void);
@@ -331,8 +320,11 @@
 	ConfigView *configView;
 	ConfigList *configList;
 	ConfigInfoView *helpText;
-	Q3ToolBar *toolBar;
-	Q3Action *backAction;
-	QSplitter* split1;
-	QSplitter* split2;
+	QToolBar *toolBar;
+	QAction *backAction;
+	QAction *singleViewAction;
+	QAction *splitViewAction;
+	QAction *fullViewAction;
+	QSplitter *split1;
+	QSplitter *split2;
 };
diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c
index 50878dc..25cf0c2 100644
--- a/scripts/kconfig/symbol.c
+++ b/scripts/kconfig/symbol.c
@@ -1116,6 +1116,8 @@
 		if (stack->sym == last_sym)
 			fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
 				prop->file->name, prop->lineno);
+			fprintf(stderr, "For a resolution refer to Documentation/kbuild/kconfig-language.txt\n");
+			fprintf(stderr, "subsection \"Kconfig recursive dependency limitations\"\n");
 		if (stack->expr) {
 			fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
 				prop->file->name, prop->lineno,