kconfig: jump to linked menu prompt

If clicking on of the links, which leads to a visible prompt, jump to it in
the symbol list.

Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc
index 425ce5c..393f374 100644
--- a/scripts/kconfig/qconf.cc
+++ b/scripts/kconfig/qconf.cc
@@ -381,6 +381,18 @@
 	}
 }
 
+ConfigItem* ConfigList::findConfigItem(struct menu *menu)
+{
+	ConfigItem* item = (ConfigItem*)menu->data;
+
+	for (; item; item = item->nextItem) {
+		if (this == item->listView())
+			break;
+	}
+
+	return item;
+}
+
 void ConfigList::updateSelection(void)
 {
 	struct menu *menu;
@@ -524,6 +536,7 @@
 	rootEntry = menu;
 	updateListAll();
 	setSelected(currentItem(), hasFocus());
+	ensureItemVisible(currentItem());
 }
 
 void ConfigList::setParentMenu(void)
@@ -766,14 +779,16 @@
 
 void ConfigList::focusInEvent(QFocusEvent *e)
 {
+	struct menu *menu = NULL;
+
 	Parent::focusInEvent(e);
 
-	QListViewItem* item = currentItem();
-	if (!item)
-		return;
-
-	setSelected(item, TRUE);
-	emit gotFocus();
+	ConfigItem* item = (ConfigItem *)currentItem();
+	if (item) {
+		setSelected(item, TRUE);
+		menu = item->menu;
+	}
+	emit gotFocus(menu);
 }
 
 void ConfigList::contextMenuEvent(QContextMenuEvent *e)
@@ -933,6 +948,8 @@
 
 void ConfigInfoView::setInfo(struct menu *m)
 {
+	if (menu == m)
+		return;
 	menu = m;
 	if (!menu)
 		clear();
@@ -954,6 +971,7 @@
 		if (sscanf(p, "m%p", &m) == 1 && menu != m) {
 			menu = m;
 			menuInfo();
+			emit menuSelected(menu);
 		}
 		break;
 	case 's':
@@ -1380,10 +1398,14 @@
 	connect(menuList, SIGNAL(menuSelected(struct menu *)),
 		SLOT(changeMenu(struct menu *)));
 
-	connect(configList, SIGNAL(gotFocus(void)),
+	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(menuList, SIGNAL(gotFocus(void)),
-		SLOT(listFocusChanged(void)));
+	connect(helpText, SIGNAL(menuSelected(struct menu *)),
+		SLOT(setMenuLink(struct menu *)));
 
 	QString listMode = configSettings->readEntry("/listMode", "symbol");
 	if (listMode == "single")
@@ -1403,18 +1425,6 @@
 		split2->setSizes(sizes);
 }
 
-/*
- * display a new help entry as soon as a new menu entry is selected
- */
-void ConfigMainWindow::setHelp(QListViewItem* item)
-{
-	struct menu* menu = 0;
-
-	if (item)
-		menu = ((ConfigItem*)item)->menu;
-	helpText->setInfo(menu);
-}
-
 void ConfigMainWindow::loadConfig(void)
 {
 	QString s = QFileDialog::getOpenFileName(".config", NULL, this);
@@ -1453,15 +1463,60 @@
 	backAction->setEnabled(TRUE);
 }
 
+void ConfigMainWindow::setMenuLink(struct menu *menu)
+{
+	struct menu *parent;
+	ConfigList* list = NULL;
+	ConfigItem* item;
+
+	if (!menu_is_visible(menu) && !configView->showAll())
+		return;
+
+	switch (configList->mode) {
+	case singleMode:
+		list = configList;
+		parent = menu_get_parent_menu(menu);
+		if (!parent)
+			return;
+		list->setRootMenu(parent);
+		break;
+	case symbolMode:
+		if (menu->flags & MENU_ROOT) {
+			configList->setRootMenu(menu);
+			configList->clearSelection();
+			list = menuList;
+		} else {
+			list = configList;
+			parent = menu_get_parent_menu(menu->parent);
+			if (!parent)
+				return;
+			item = menuList->findConfigItem(parent);
+			if (item) {
+				menuList->setSelected(item, TRUE);
+				menuList->ensureItemVisible(item);
+			}
+			list->setRootMenu(parent);
+		}
+		break;
+	case fullMode:
+		list = configList;
+		break;
+	}
+
+	if (list) {
+		item = list->findConfigItem(menu);
+		if (item) {
+			list->setSelected(item, TRUE);
+			list->ensureItemVisible(item);
+			list->setFocus();
+		}
+	}
+}
+
 void ConfigMainWindow::listFocusChanged(void)
 {
-	if (menuList->hasFocus()) {
-		if (menuList->mode == menuMode)
-			configList->clearSelection();
-		setHelp(menuList->selectedItem());
-	} else if (configList->hasFocus()) {
-		setHelp(configList->selectedItem());
-	}
+	if (menuList->mode == menuMode)
+		configList->clearSelection();
 }
 
 void ConfigMainWindow::goBack(void)
diff --git a/scripts/kconfig/qconf.h b/scripts/kconfig/qconf.h
index b824f78..6a9e3b1 100644
--- a/scripts/kconfig/qconf.h
+++ b/scripts/kconfig/qconf.h
@@ -55,6 +55,7 @@
 	{
 		return (ConfigView*)Parent::parent();
 	}
+	ConfigItem* findConfigItem(struct menu *);
 
 protected:
 	void keyPressEvent(QKeyEvent *e);
@@ -77,7 +78,7 @@
 	void menuChanged(struct menu *menu);
 	void menuSelected(struct menu *menu);
 	void parentSelected(void);
-	void gotFocus(void);
+	void gotFocus(struct menu *);
 
 public:
 	void updateListAll(void)
@@ -258,6 +259,7 @@
 
 signals:
 	void showDebugChanged(bool);
+	void menuSelected(struct menu *);
 
 protected:
 	void symbolInfo(void);
@@ -298,8 +300,8 @@
 public:
 	ConfigMainWindow(void);
 public slots:
-	void setHelp(QListViewItem* item);
 	void changeMenu(struct menu *);
+	void setMenuLink(struct menu *);
 	void listFocusChanged(void);
 	void goBack(void);
 	void loadConfig(void);