Hello community,

here is the log from the commit of package libyui-ncurses for openSUSE:Factory 
checked in at 2020-08-20 22:24:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libyui-ncurses (Old)
 and      /work/SRC/openSUSE:Factory/.libyui-ncurses.new.3399 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libyui-ncurses"

Thu Aug 20 22:24:51 2020 rev:57 rq:827300 version:2.56.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/libyui-ncurses/libyui-ncurses.changes    
2020-08-14 13:08:32.653192253 +0200
+++ /work/SRC/openSUSE:Factory/.libyui-ncurses.new.3399/libyui-ncurses.changes  
2020-08-20 22:26:18.439910562 +0200
@@ -1,0 +2,7 @@
+Wed Aug 12 15:46:18 UTC 2020 - José Iván López González <[email protected]>
+
+- Handle hot-keys for top level menu options.
+- Related to bsc#1175115.
+- 2.56.1
+
+-------------------------------------------------------------------

Old:
----
  libyui-ncurses-2.56.0.tar.bz2

New:
----
  libyui-ncurses-2.56.1.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libyui-ncurses-doc.spec ++++++
--- /var/tmp/diff_new_pack.IP0O74/_old  2020-08-20 22:26:19.967911277 +0200
+++ /var/tmp/diff_new_pack.IP0O74/_new  2020-08-20 22:26:19.971911279 +0200
@@ -20,7 +20,7 @@
 %define so_version 13
 
 Name:           %{parent}-doc
-Version:        2.56.0
+Version:        2.56.1
 Release:        0
 Source:         %{parent}-%{version}.tar.bz2
 

++++++ libyui-ncurses.spec ++++++
--- /var/tmp/diff_new_pack.IP0O74/_old  2020-08-20 22:26:19.999911292 +0200
+++ /var/tmp/diff_new_pack.IP0O74/_new  2020-08-20 22:26:20.003911294 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           libyui-ncurses
-Version:        2.56.0
+Version:        2.56.1
 Release:        0
 Source:         %{name}-%{version}.tar.bz2
 

++++++ libyui-ncurses-2.56.0.tar.bz2 -> libyui-ncurses-2.56.1.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-ncurses-2.56.0/SOURCECONF.cmake 
new/libyui-ncurses-2.56.1/SOURCECONF.cmake
--- old/libyui-ncurses-2.56.0/SOURCECONF.cmake  2020-08-12 10:34:14.000000000 
+0200
+++ new/libyui-ncurses-2.56.1/SOURCECONF.cmake  2020-08-17 12:29:15.000000000 
+0200
@@ -79,6 +79,7 @@
   NCi18n.h
   tnode.h
   position.h
+  CyclicContainer.h
   YNCursesUI.h
   NCtoY2Event.h
   NCApplication.h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-ncurses-2.56.0/VERSION.cmake 
new/libyui-ncurses-2.56.1/VERSION.cmake
--- old/libyui-ncurses-2.56.0/VERSION.cmake     2020-08-12 10:34:14.000000000 
+0200
+++ new/libyui-ncurses-2.56.1/VERSION.cmake     2020-08-17 12:29:15.000000000 
+0200
@@ -1,6 +1,6 @@
 SET( VERSION_MAJOR "2" )
 SET( VERSION_MINOR "56" )
-SET( VERSION_PATCH "0" )
+SET( VERSION_PATCH "1" )
 SET( VERSION 
"${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${GIT_SHA1_VERSION}" )
 
 ##### This is needed for the libyui core ONLY.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/libyui-ncurses-2.56.0/package/libyui-ncurses-doc.spec 
new/libyui-ncurses-2.56.1/package/libyui-ncurses-doc.spec
--- old/libyui-ncurses-2.56.0/package/libyui-ncurses-doc.spec   2020-08-12 
10:34:14.000000000 +0200
+++ new/libyui-ncurses-2.56.1/package/libyui-ncurses-doc.spec   2020-08-17 
12:29:15.000000000 +0200
@@ -19,7 +19,7 @@
 %define so_version 13
 
 Name:           %{parent}-doc
-Version:        2.56.0
+Version:        2.56.1
 Release:        0
 Source:         %{parent}-%{version}.tar.bz2
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-ncurses-2.56.0/package/libyui-ncurses.changes 
new/libyui-ncurses-2.56.1/package/libyui-ncurses.changes
--- old/libyui-ncurses-2.56.0/package/libyui-ncurses.changes    2020-08-12 
10:34:14.000000000 +0200
+++ new/libyui-ncurses-2.56.1/package/libyui-ncurses.changes    2020-08-17 
12:29:15.000000000 +0200
@@ -1,4 +1,11 @@
 -------------------------------------------------------------------
+Wed Aug 12 15:46:18 UTC 2020 - José Iván López González <[email protected]>
+
+- Handle hot-keys for top level menu options.
+- Related to bsc#1175115.
+- 2.56.1
+
+-------------------------------------------------------------------
 Tue Aug 11 22:15:17 UTC 2020 - José Iván López González <[email protected]>
 
 - Add MenuBar widget (bsc#1175115).
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-ncurses-2.56.0/package/libyui-ncurses.spec 
new/libyui-ncurses-2.56.1/package/libyui-ncurses.spec
--- old/libyui-ncurses-2.56.0/package/libyui-ncurses.spec       2020-08-12 
10:34:14.000000000 +0200
+++ new/libyui-ncurses-2.56.1/package/libyui-ncurses.spec       2020-08-17 
12:29:15.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           libyui-ncurses
-Version:        2.56.0
+Version:        2.56.1
 Release:        0
 Source:         %{name}-%{version}.tar.bz2
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-ncurses-2.56.0/src/CyclicContainer.h 
new/libyui-ncurses-2.56.1/src/CyclicContainer.h
--- old/libyui-ncurses-2.56.0/src/CyclicContainer.h     1970-01-01 
01:00:00.000000000 +0100
+++ new/libyui-ncurses-2.56.1/src/CyclicContainer.h     2020-08-17 
12:29:15.000000000 +0200
@@ -0,0 +1,146 @@
+/*
+  Copyright (C) 2020 SUSE LLC
+  This library is free software; you can redistribute it and/or modify
+  it under the terms of the GNU Lesser General Public License as
+  published by the Free Software Foundation; either version 2.1 of the
+  License, or (at your option) version 3.0 of the License. This library
+  is distributed in the hope that it will be useful, but WITHOUT ANY
+  WARRANTY; without even the implied warranty of MERCHANTABILITY or
+  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+  License for more details. You should have received a copy of the GNU
+  Lesser General Public License along with this library; if not, write
+  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
+  Floor, Boston, MA 02110-1301 USA
+*/
+
+
+/*-/
+
+   File:       CyclicContainer.h
+
+   Author:     Jose Iván López <[email protected]>
+
+/-*/
+
+
+#ifndef CyclicContainer_h
+#define CyclicContainer_h
+
+#include <algorithm>
+#include <iterator>
+#include <vector>
+
+/** Container class that allows cyclic navigation between its elements by 
moving to the next/previous
+ * element.
+ *
+ * @note This class holds pointers, but it does not own the pointers.
+ **/
+template <class T>
+class CyclicContainer
+{
+public:
+
+    using Iterator = typename std::vector<T *>::iterator;
+    using ReverseIterator = std::reverse_iterator<Iterator>;
+
+    Iterator begin() { return _elements.begin(); }
+    Iterator end() { return _elements.end(); }
+
+    CyclicContainer() : _elements(), _current( nullptr )
+    {}
+
+
+    ~CyclicContainer()
+    {
+       clear();
+    }
+
+
+    void clear()
+    {
+       _elements.clear();
+       _current = nullptr;
+    }
+
+
+    void add( T * element )
+    {
+       _elements.push_back(element);
+    }
+
+
+    void setCurrent(Iterator element)
+    {
+       if ( element != _elements.end() )
+           _current = *element;
+    }
+
+
+    Iterator current()
+    {
+       return std::find( _elements.begin(), _elements.end(), _current );
+    }
+
+
+    Iterator next()
+    {
+       Iterator current = this->current();
+
+       if ( current == _elements.end() )
+           return findNext( _elements.begin() );
+
+       Iterator next = findNext( std::next( current, 1 ) );
+
+       if ( next == _elements.end() )
+           return findNext( _elements.begin() );
+
+       return next;
+    }
+
+
+    Iterator previous()
+    {
+       Iterator current = this->current();
+
+       ReverseIterator rbegin;
+
+       if ( current == _elements.end() )
+           rbegin = _elements.rbegin();
+       else
+           rbegin = ReverseIterator( current );
+
+       ReverseIterator previous = findPrevious( rbegin );
+
+       if ( previous == _elements.rend() && rbegin != _elements.rbegin() )
+           previous = findPrevious( _elements.rbegin() );
+
+       if ( previous == _elements.rend() )
+           return _elements.end();
+
+       return find( _elements.begin(), _elements.end(), *previous );
+    }
+
+private:
+
+    Iterator findNext( Iterator begin )
+    {
+       return find_if( begin, _elements.end(), [](const T * element) {
+           return element->isSelectable();
+       });
+    }
+
+
+    ReverseIterator findPrevious( ReverseIterator rbegin )
+    {
+       return find_if( rbegin, _elements.rend(), [](const T * element) {
+           return element->isSelectable();
+       });
+    }
+
+
+    std::vector<T *> _elements;
+
+    T * _current;
+};
+
+#endif // CyclicContainer_h
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-ncurses-2.56.0/src/NCMenuBar.cc 
new/libyui-ncurses-2.56.1/src/NCMenuBar.cc
--- old/libyui-ncurses-2.56.0/src/NCMenuBar.cc  2020-08-12 10:34:14.000000000 
+0200
+++ new/libyui-ncurses-2.56.1/src/NCMenuBar.cc  2020-08-17 12:29:15.000000000 
+0200
@@ -18,13 +18,12 @@
 
    File:       NCMenuBar.cc
 
-   Author:     Stefan Hundhammer <[email protected]>
+   Author:     Jose Iván López <[email protected]>
 
 /-*/
 
 
-#include <algorithm>    // std::max()
-#include <iterator>
+#include <algorithm>
 
 #define         YUILogComponent "ncurses"
 #include <yui/YUILog.h>
@@ -40,14 +39,40 @@
 #define SPACING         2
 
 
-struct NCMenuBar::Menu {
+// Helper class that represents a top level menu
+struct NCMenuBar::Menu
+{
     wpos position;
     YMenuItem* item;
+
+
+    // Whether the menu can be selected
+    bool isSelectable() const
+    {
+       if ( ! item )
+           return false;
+
+       return item->isEnabled();
+    }
+
+
+    // Whether the menu contains the given hot-key
+    bool hasHotkey( int key ) const
+    {
+       NClabel label = NCstring( item->label() );
+       label.stripHotkey();
+
+       if ( ! label.hasHotkey() )
+           return false;
+
+       return tolower( key ) == tolower( label.hotkey() );
+    }
+
 };
 
 
 NCMenuBar::NCMenuBar( YWidget* parent ) :
-    YMenuBar( parent ), NCWidget( parent ), _selectedMenu( nullptr )
+    YMenuBar( parent ), NCWidget( parent ), _menus()
 {
     defsze = wsze( 1, 10 );
 }
@@ -67,7 +92,6 @@
 
     _menus.clear();
 
-    _selectedMenu = nullptr;
     defsze = wsze( 1, 10 );
 }
 
@@ -91,7 +115,7 @@
        menu->item = item;
        menu->position = wpos( 0, width );
 
-       _menus.push_back( menu );
+       _menus.add( menu );
        item->setUiItem( menu );
 
        NClabel label( NCstring( menu->item->label() ) );
@@ -100,7 +124,7 @@
        width += label.width() + SPACING;
     }
 
-    selectMenu( findNextEnabledMenu( _menus.begin() ) );
+    selectNextMenu();
 
     defsze = wsze( 1, width );
 }
@@ -137,22 +161,22 @@
 NCursesEvent
 NCMenuBar::postMenu()
 {
-    wpos at(ScreenPos() + wpos( 1, _selectedMenu->position.C) );
+    wpos at(ScreenPos() + wpos( 1, selectedMenu()->position.C) );
 
     NCPopupMenu * dialog = new NCPopupMenu(
        at,
-       _selectedMenu->item->childrenBegin(),
-       _selectedMenu->item->childrenEnd()
+       selectedMenu()->item->childrenBegin(),
+       selectedMenu()->item->childrenEnd()
     );
 
     YUI_CHECK_NEW( dialog );
 
     NCursesEvent event;
-    int selectedIndex = dialog->post( &event );
+    dialog->post( &event );
 
     YDialog::deleteTopmostDialog();
 
-    return handlePostMenu( event, selectedIndex );
+    return handlePostMenu( event );
 }
 
 
@@ -188,12 +212,12 @@
     switch ( key )
     {
        case KEY_LEFT:
-           selectMenu( previousMenu() );
+           selectPreviousMenu();
            wRedraw();
            break;
 
        case KEY_RIGHT:
-           selectMenu( nextMenu() );
+           selectNextMenu();
            wRedraw();
            break;
 
@@ -252,134 +276,92 @@
 bool
 NCMenuBar::HasHotkey( int key )
 {
-    // TODO
-    return false;
+    if( key < 0 || UCHAR_MAX < key )
+       return false;
+
+    return findMenuWithHotkey( key ) != _menus.end();
 }
 
 
 NCursesEvent
 NCMenuBar::wHandleHotkey( wint_t key )
 {
-    // TODO
-    NCursesEvent event = NCursesEvent::none;
+    CyclicContainer<Menu>::Iterator menu = findMenuWithHotkey( key );
 
-    return event;
+    if ( menu == _menus.end() )
+       return NCursesEvent::none;
+
+    _menus.setCurrent( menu );
+
+    wRedraw();
+    return postMenu();
 }
 
 
 NCursesEvent
-NCMenuBar::handlePostMenu( const NCursesEvent & event, int selectedIndex )
+NCMenuBar::handlePostMenu( const NCursesEvent & event )
 {
-    NCursesEvent new_event = NCursesEvent::none;
+    NCursesEvent newEvent = NCursesEvent::none;
 
-    if ( event == NCursesEvent::button && selectedIndex >= 0 )
+    if ( event == NCursesEvent::button )
     {
-       YMenuItem * item = findMenuItem( selectedIndex );
-
-       if ( item && item->isEnabled() )
-       {
-           new_event = NCursesEvent::menu;
-           new_event.selection = item;
-       }
+       newEvent = NCursesEvent::menu;
+       newEvent.selection = event.selection;
     }
     else if ( event == NCursesEvent::key )
     {
        if ( event.keySymbol == "CursorLeft" )
        {
            wHandleInput( KEY_LEFT );
-           new_event = wHandleInput( KEY_DOWN );
+           newEvent = wHandleInput( KEY_DOWN );
        }
        else if ( event.keySymbol == "CursorRight" )
        {
            wHandleInput( KEY_RIGHT );
-           new_event = wHandleInput( KEY_DOWN );
+           newEvent = wHandleInput( KEY_DOWN );
        }
     }
 
-    return new_event;
+    return newEvent;
 }
 
 
-void
-NCMenuBar::selectMenu( NCMenuBar::MenuIterator menu )
-{
-    if ( menu != _menus.end() )
-       _selectedMenu = *menu;
-}
-
-
-NCMenuBar::MenuIterator
-NCMenuBar::currentMenu()
+NCMenuBar::Menu *
+NCMenuBar::selectedMenu()
 {
-    return std::find( _menus.begin(), _menus.end(), _selectedMenu );
-}
-
-
-NCMenuBar::MenuIterator
-NCMenuBar::nextMenu()
-{
-    MenuIterator current = currentMenu();
-
-    if ( current == _menus.end() )
-       return findNextEnabledMenu( _menus.begin() );
-
-    MenuIterator next = findNextEnabledMenu( std::next( current, 1 ) );
-
-    if ( next == _menus.end() )
-       return findNextEnabledMenu( _menus.begin() );
-
-    return next;
+    return *_menus.current();
 }
 
 
-NCMenuBar::MenuIterator
-NCMenuBar::previousMenu()
+void
+NCMenuBar::selectNextMenu()
 {
-    MenuIterator current = currentMenu();
-
-    ReverseMenuIterator rbegin;
-
-    if ( current == _menus.end() )
-       rbegin = _menus.rbegin();
-    else
-       rbegin = ReverseMenuIterator( current );
-
-    ReverseMenuIterator previous = findPreviousEnabledMenu( rbegin );
-
-    if ( previous == _menus.rend() && rbegin != _menus.rbegin() )
-       previous = findPreviousEnabledMenu( _menus.rbegin() );
-
-    if ( previous == _menus.rend() )
-       return _menus.end();
-
-    return find( _menus.begin(), _menus.end(), *previous );
+    _menus.setCurrent( _menus.next() );
 }
 
 
-NCMenuBar::MenuIterator
-NCMenuBar::findNextEnabledMenu( MenuIterator begin )
+void
+NCMenuBar::selectPreviousMenu()
 {
-    return find_if( begin, _menus.end(), [](const Menu * menu ) {
-       return menu->item->isEnabled();
-    });
+    _menus.setCurrent( _menus.previous() );
 }
 
 
-NCMenuBar::ReverseMenuIterator
-NCMenuBar::findPreviousEnabledMenu( ReverseMenuIterator rbegin )
+CyclicContainer<NCMenuBar::Menu>::Iterator
+NCMenuBar::findMenuWithHotkey( wint_t key )
 {
-    return find_if( rbegin, _menus.rend(), [](const Menu * menu ) {
-       return menu->item->isEnabled();
+    return std::find_if( _menus.begin(), _menus.end(), [key](Menu * menu) {
+       return menu->hasHotkey( key );
     });
 }
 
 
 const NCstyle::StWidget &
-NCMenuBar::menuStyle( const Menu * menu ) const
+NCMenuBar::menuStyle( const Menu * menu )
 {
     if ( !menu->item->isEnabled() )
        return wStyle().getWidget( NC::WSdisabled );
 
-    bool non_active = ( menu != _selectedMenu );
+    bool non_active = ( menu != selectedMenu() );
     return widgetStyle( non_active );
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-ncurses-2.56.0/src/NCMenuBar.h 
new/libyui-ncurses-2.56.1/src/NCMenuBar.h
--- old/libyui-ncurses-2.56.0/src/NCMenuBar.h   2020-08-12 10:34:14.000000000 
+0200
+++ new/libyui-ncurses-2.56.1/src/NCMenuBar.h   2020-08-17 12:29:15.000000000 
+0200
@@ -18,18 +18,17 @@
 
    File:       NCMenuBar.h
 
-   Author:     Stefan Hundhammer <[email protected]>
+   Author:     Jose Iván López <[email protected]>
 
 /-*/
 
+
 #ifndef NCMenuBar_h
 #define NCMenuBar_h
 
-#include <vector>
-
 #include <yui/YMenuBar.h>
 #include "NCWidget.h"
-
+#include "CyclicContainer.h"
 
 class NCMenuBar: public YMenuBar, public NCWidget
 {
@@ -70,6 +69,7 @@
 
     /**
      * Handle keyboard input.
+     * Reimplemented from NCWidget.
      **/
     virtual NCursesEvent wHandleInput( wint_t key );
 
@@ -103,9 +103,17 @@
      **/
     virtual bool setKeyboardFocus();
 
+    /**
+     * Handle keyboard input.
+     * Reimplemented from NCWidget.
+     **/
     virtual NCursesEvent wHandleHotkey( wint_t key );
 
-    virtual bool HasHotkey(int key) ;
+    /**
+     * Whether any menu option has the given hot-key .
+     * Reimplemented from NCWidget.
+     **/
+    virtual bool HasHotkey( int key ) ;
 
 protected:
 
@@ -116,17 +124,21 @@
 
     virtual const char * location() const { return "NCMenuBar"; }
 
+    /**
+     * Reimplemented from NCWidget.
+     **/
     virtual void wRedraw();
 
+    /**
+     * Open a menu dialog
+     * @return event from the menu dialog
+     **/
     NCursesEvent postMenu();
 
 private:
 
     struct Menu;
 
-    using MenuIterator = std::vector<Menu *>::iterator;
-    using ReverseMenuIterator = std::reverse_iterator<MenuIterator>;
-
     friend std::ostream & operator<<( std::ostream & str,
                                       const NCMenuBar & obj );
 
@@ -135,22 +147,46 @@
     NCMenuBar & operator=( const NCMenuBar & );
     NCMenuBar( const NCMenuBar & );
 
-    NCursesEvent handlePostMenu( const NCursesEvent & event, int selectedIndex 
);
+    /** Helper method to manage the menu dialog event
+     * @param event event from the menu dialog
+     * @return a new event
+     **/
+    NCursesEvent handlePostMenu( const NCursesEvent & event );
 
-    void selectMenu( MenuIterator menu );
+    /** Currently selected menu.
+     * @return selected menu
+     **/
+    Menu * selectedMenu();
 
-    MenuIterator currentMenu();
-    MenuIterator nextMenu();
-    MenuIterator previousMenu();
+    /** Select the next enabled menu option.
+     * @note When there is no selected menu, the first enabled one is selected.
+     **/
+    void selectNextMenu();
 
-    MenuIterator findNextEnabledMenu( MenuIterator begin );
-    ReverseMenuIterator findPreviousEnabledMenu( ReverseMenuIterator rbegin );
+    /** Select the previous enabled menu.
+     * @note When there is no selected menu, the last enabled one is selected.
+     **/
+    void selectPreviousMenu();
 
-    const NCstyle::StWidget & menuStyle( const Menu * menu ) const;
+    /** Find the menu with the given hot-key.
+     * @param key a hot-key
+     * @return the menu with the given hot-key.
+     **/
+    CyclicContainer<Menu>::Iterator findMenuWithHotkey( wint_t key );
 
-    std::vector<Menu*> _menus;
+    /** Style to apply to the given menu
+     * The style depends on the status of the menu (enabled or disabled).
+     * @param menu a menu
+     * @return style to apply
+     **/
+    const NCstyle::StWidget & menuStyle( const Menu * menu );
 
-    Menu* _selectedMenu;
+    /** Container of menus
+     * It allows cyclic navigation between the menus.
+     * Note that this container holds pointers to menus, but it does not own 
the pointers. The pointers
+     * are owned by the NCMenuBar object.
+     **/
+    CyclicContainer<Menu> _menus;
 
 };      // NCMenuBar
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-ncurses-2.56.0/src/NCMenuButton.cc 
new/libyui-ncurses-2.56.1/src/NCMenuButton.cc
--- old/libyui-ncurses-2.56.0/src/NCMenuButton.cc       2020-08-12 
10:34:14.000000000 +0200
+++ new/libyui-ncurses-2.56.1/src/NCMenuButton.cc       2020-08-17 
12:29:15.000000000 +0200
@@ -146,19 +146,20 @@
                                            itemsEnd() );
     YUI_CHECK_NEW( dialog );
 
-    int selection = dialog->post();
+    NCursesEvent event;
+    dialog->post( &event );
 
-    if ( selection < 0 )
+    YDialog::deleteTopmostDialog();
+
+    NCursesEvent newEvent = NCursesEvent::none;
+
+    if ( event == NCursesEvent::button )
     {
-       YDialog::deleteTopmostDialog();
-       return NCursesEvent::none;
+       newEvent = NCursesEvent::menu;
+       newEvent.selection = event.selection;
     }
 
-    NCursesEvent ret = NCursesEvent::menu;
-    ret.selection = findMenuItem( selection );
-    YDialog::deleteTopmostDialog();
-
-    return ret;
+    return newEvent;
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-ncurses-2.56.0/src/NCPopupMenu.cc 
new/libyui-ncurses-2.56.1/src/NCPopupMenu.cc
--- old/libyui-ncurses-2.56.0/src/NCPopupMenu.cc        2020-08-12 
10:34:14.000000000 +0200
+++ new/libyui-ncurses-2.56.1/src/NCPopupMenu.cc        2020-08-17 
12:29:15.000000000 +0200
@@ -22,19 +22,28 @@
 
 /-*/
 
-#include <algorithm>
-#include <iterator>
-
 #define  YUILogComponent "ncurses"
 #include <yui/YUILog.h>
 #include "NCPopupMenu.h"
 #include "NCTable.h"
 
 
+// Helper class that represents a menu item
 struct NCPopupMenu::Item
 {
     YTableItem * tableItem;
     YMenuItem * menuItem;
+
+
+    // Whether the item can be selected
+    bool isSelectable() const
+    {
+       if ( ! menuItem )
+           return false;
+
+       return menuItem->isEnabled() && !menuItem->isSeparator();
+    }
+
 };
 
 
@@ -53,10 +62,6 @@
        row[0] = menuItem->label();
        row[1] = menuItem->hasChildren() ? "..." : "";
 
-       // TODO
-       // if (menuItem->isSeparator())
-       //     row[0] = "---";
-
        YTableItem *tableItem = new YTableItem( row[0], row[1] );
        // yuiDebug() << "Add to std::map: TableItem: " << tableItem << " Menu 
item: " << item << std::endl;
 
@@ -68,10 +73,10 @@
        item->tableItem = tableItem;
        item->menuItem = menuItem;
 
-       _items.push_back( item );
+       _items.add( item );
     }
 
-    selectItem( findNextEnabledItem( _items.begin() ) );
+    selectNextItem();
 
     stripHotkeys();
 }
@@ -92,13 +97,11 @@
     {
        case KEY_RIGHT:
        {
-           ItemIterator current = currentItem();
+           Item * item = selectedItem();
 
-           if (current != _items.end())
+           if ( item )
            {
-               YMenuItem * item = (*current)->menuItem;
-
-               if ( item->hasChildren() )
+               if ( item->menuItem->hasChildren() )
                    event = NCursesEvent::button;
                else
                {
@@ -119,11 +122,11 @@
            break;
 
        case KEY_DOWN:
-           selectItem( nextItem() );
+           selectNextItem();
            break;
 
        case KEY_UP:
-           selectItem( previousItem() );
+           selectPreviousItem();
            break;
 
        default:
@@ -141,24 +144,22 @@
     bool again = false;
     int  selection = ( postevent == NCursesEvent::button ) ? getCurrentItem() 
: -1;
 
-    ItemIterator current = currentItem();
+    Item * item = selectedItem();
 
-    if ( current == _items.end() )
+    if ( ! item )
        return false;
 
-    YMenuItem * item = (*current)->menuItem;
-
-    yuiDebug() << "Menu item: " << item->label() << std::endl;
+    yuiDebug() << "Menu item: " << item->menuItem->label() << std::endl;
 
     if ( selection != -1 )
     {
-       if ( item->hasChildren() )
+       if ( item->menuItem->hasChildren() )
        {
            // post submenu
            wpos at( ScreenPos() + wpos( selection, inparent.Sze.W - 1 ) );
            NCPopupMenu * dialog = new NCPopupMenu( at,
-                                                   item->childrenBegin(),
-                                                   item->childrenEnd() );
+                                                   
item->menuItem->childrenBegin(),
+                                                   
item->menuItem->childrenEnd() );
            YUI_CHECK_NEW( dialog );
 
            again = ( dialog->post( &postevent ) == NCursesEvent::CONTINUE );
@@ -168,8 +169,7 @@
        else
        {
            // store selection
-           //postevent.detail = menu.itemList()[selection]->getIndex();
-           postevent.detail = item->index();
+           postevent.selection = item->menuItem;
        }
     }
 
@@ -177,89 +177,59 @@
 }
 
 
-NCPopupMenu::ItemIterator
-NCPopupMenu::findItem( YTableItem* tableItem )
+NCPopupMenu::Item * NCPopupMenu::selectedItem()
 {
-    return find_if(_items.begin(), _items.end(), [tableItem](const Item * 
item) {
-       return item->tableItem == tableItem;
-    });
-}
-
-
-void NCPopupMenu::selectItem( ItemIterator item )
-{
-    if ( item != _items.end() )
-    {
-       int index = std::distance(_items.begin(), item);
+    updateSelectedItem();
 
-       setCurrentItem(index);
-    }
+    return *_items.current();
 }
 
 
-NCPopupMenu::ItemIterator NCPopupMenu::currentItem()
+void NCPopupMenu::selectNextItem()
 {
-    ItemIterator current = _items.end();
-
-    YTableItem * tableItem = dynamic_cast<YTableItem *> ( 
getCurrentItemPointer() );
-
-    if ( tableItem )
-       current = findItem(tableItem);
-
-    return current;
+    selectItem( _items.next() );
 }
 
 
-NCPopupMenu::ItemIterator NCPopupMenu::nextItem()
+void NCPopupMenu::selectPreviousItem()
 {
-    ItemIterator current = currentItem();
-
-    if ( current == _items.end() )
-       return findNextEnabledItem( _items.begin() );
-
-    ItemIterator next = findNextEnabledItem( std::next( current, 1 ) );
-
-    if ( next == _items.end() )
-       return findNextEnabledItem( _items.begin() );
-
-    return next;
+    selectItem( _items.previous() );
 }
 
 
-NCPopupMenu::ItemIterator NCPopupMenu::previousItem()
+void NCPopupMenu::updateSelectedItem()
 {
-    ItemIterator current = currentItem();
-
-    ReverseItemIterator rbegin;
-
-    if ( current == _items.end() )
-       rbegin = _items.rbegin();
-    else
-       rbegin = ReverseItemIterator( current );
+     YTableItem * tableItem = dynamic_cast<YTableItem *> ( 
getCurrentItemPointer() );
 
-    ReverseItemIterator previous = findPreviousEnabledItem( rbegin );
+    if ( ! tableItem )
+       return;
 
-    if ( previous == _items.rend() && rbegin != _items.rbegin() )
-       previous = findPreviousEnabledItem( _items.rbegin() );
+    CyclicContainer<Item>::Iterator newCurrent = findItem( tableItem);
 
-    if ( previous == _items.rend() )
-       return _items.end();
+    if ( newCurrent == _items.end() )
+       return;
 
-    return find( _items.begin(), _items.end(), *previous );
+    if ( _items.current() != newCurrent )
+       selectItem( newCurrent );
 }
 
 
-NCPopupMenu::ItemIterator NCPopupMenu::findNextEnabledItem( ItemIterator begin 
)
+CyclicContainer<NCPopupMenu::Item>::Iterator NCPopupMenu::findItem( YTableItem 
* tableItem )
 {
-    return find_if( begin, _items.end(), [](const Item * item) {
-       return item->menuItem->isEnabled() && !item->menuItem->isSeparator();
+    return find_if( _items.begin(), _items.end(), [tableItem](Item * item) {
+       return item->tableItem == tableItem;
     });
 }
 
 
-NCPopupMenu::ReverseItemIterator NCPopupMenu::findPreviousEnabledItem( 
ReverseItemIterator rbegin )
+void NCPopupMenu::selectItem( CyclicContainer<Item>::Iterator item )
 {
-    return find_if( rbegin, _items.rend(), [](const Item * item) {
-       return item->menuItem->isEnabled() && !item->menuItem->isSeparator();
-    });
+    _items.setCurrent( item );
+
+    if ( item != _items.end() )
+    {
+       int index = std::distance(_items.begin(), item);
+
+       setCurrentItem(index);
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libyui-ncurses-2.56.0/src/NCPopupMenu.h 
new/libyui-ncurses-2.56.1/src/NCPopupMenu.h
--- old/libyui-ncurses-2.56.0/src/NCPopupMenu.h 2020-08-12 10:34:14.000000000 
+0200
+++ new/libyui-ncurses-2.56.1/src/NCPopupMenu.h 2020-08-17 12:29:15.000000000 
+0200
@@ -25,9 +25,8 @@
 #ifndef NCPopupMenu_h
 #define NCPopupMenu_h
 
-#include <vector>
-
 #include "NCPopupTable.h"
+#include "CyclicContainer.h"
 
 
 class NCPopupMenu : public NCPopupTable
@@ -36,24 +35,25 @@
 
     struct Item;
 
-    using ItemIterator = std::vector<NCPopupMenu::Item *>::iterator;
-    using ReverseItemIterator = std::reverse_iterator<ItemIterator>;
-
     NCPopupMenu & operator=( const NCPopupMenu & );
     NCPopupMenu( const NCPopupMenu & );
 
-    ItemIterator findItem( YTableItem * tableItem );
-
-    void selectItem( ItemIterator item );
-
-    ItemIterator currentItem();
-    ItemIterator nextItem();
-    ItemIterator previousItem();
-
-    ItemIterator findNextEnabledItem( ItemIterator begin );
-    ReverseItemIterator findPreviousEnabledItem( ReverseItemIterator rbegin );
+    Item * selectedItem();
 
-    std::vector<Item *> _items;
+    void selectNextItem();
+    void selectPreviousItem();
+    void updateSelectedItem();
+
+    CyclicContainer<Item>::Iterator findItem( YTableItem * tableItem );
+
+    void selectItem( CyclicContainer<Item>::Iterator item );
+
+    /** Container of menu items
+     * It allows cyclic navigation between the items.
+     * Note that this container holds pointers to items, but it does not own 
the pointers. The pointers
+     * are owned by the NCPopupMenu object.
+     **/
+    CyclicContainer<Item> _items;
 
 protected:
 


Reply via email to