From 8ecd3c91f0c1cfb92d79604ae92dddf6d44dbb2f Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Wed, 8 Jul 2020 17:24:45 +0200 Subject: [PATCH 01/13] Coding style --- src/YMenuButton.cc | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/YMenuButton.cc b/src/YMenuButton.cc index 4a9917556..7db00c13a 100644 --- a/src/YMenuButton.cc +++ b/src/YMenuButton.cc @@ -136,9 +136,11 @@ YMenuButton::findMenuItem( int wantedIndex, YItemConstIterator begin, YItemConst return 0; } -static void resolveShortcutsConflictFlat(YItemConstIterator begin, YItemConstIterator end) + +static void resolveShortcutsConflictFlat( YItemConstIterator begin, YItemConstIterator end ) { bool used[ sizeof( char ) << 8 ]; + for ( unsigned i=0; i < sizeof( char ) << 8; i++ ) used[i] = false; std::vector conflicts; @@ -151,34 +153,34 @@ static void resolveShortcutsConflictFlat(YItemConstIterator begin, YItemConstIte { if ( item->hasChildren() ) { - resolveShortcutsConflictFlat(item->childrenBegin(), item->childrenEnd() ); + resolveShortcutsConflictFlat( item->childrenBegin(), item->childrenEnd() ); } char shortcut = YShortcut::normalized(YShortcut::findShortcut(item->label())); - if (shortcut == 0) + if ( shortcut == 0 ) { conflicts.push_back(item); yuiMilestone() << "No or invalid shortcut found " << item->label() << endl; } - else if (used[(unsigned)shortcut]) + else if ( used[ (unsigned)shortcut ] ) { conflicts.push_back(item); yuiWarning() << "Conflicting shortcut found " << item->label() << endl; } else { - used[(unsigned)shortcut] = true; + used[ (unsigned) shortcut ] = true; } } else { - yuiWarning() << "non menu item used in call " << (*it)->label() << endl; + yuiWarning() << "non menu item used in call " << (*it)->label() << endl; } } - // cannot use YShortcut directly as YItem is not YWidget - for(YMenuItem *i: conflicts) + // cannot use YShortcut directly as an YItem is not a YWidget + for( YMenuItem *i: conflicts ) { string clean = YShortcut::cleanShortcutString(i->label()); char new_c = 0; @@ -186,9 +188,9 @@ static void resolveShortcutsConflictFlat(YItemConstIterator begin, YItemConstIte size_t index = 0; for (; index < clean.size(); ++index) { - char ch = YShortcut::normalized(clean[index]); - // ch is set to 0 by normalized if not valid - if (ch != 0 && !used[(unsigned)ch]) + char ch = YShortcut::normalized( clean[index] ); + // ch is set to 0 by normalized() if not valid + if ( ch != 0 && ! used[ (unsigned)ch ] ) { new_c = ch; used[(unsigned)ch] = true; @@ -201,14 +203,16 @@ static void resolveShortcutsConflictFlat(YItemConstIterator begin, YItemConstIte clean.insert(index, 1, YShortcut::shortcutMarker()); yuiMilestone() << "New label used: " << clean << endl; } - i->setLabel(clean); + + i->setLabel( clean ); } } + void YMenuButton::resolveShortcutConflicts() { - resolveShortcutsConflictFlat(itemsBegin(), itemsEnd()); + resolveShortcutsConflictFlat( itemsBegin(), itemsEnd() ); } From a33caccf38cdf0560b787e4d819b59f021841520 Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Thu, 9 Jul 2020 15:34:47 +0200 Subject: [PATCH 02/13] Added YMenuBar widget --- SOURCECONF.cmake | 2 + src/YItem.h | 2 + src/YMenuBar.cc | 318 ++++++++++++++++++++++++++++++++++++++++++ src/YMenuBar.h | 230 ++++++++++++++++++++++++++++++ src/YMenuButton.cc | 82 ++++++----- src/YMenuButton.h | 37 +++-- src/YUISymbols.h | 1 + src/YWidgetFactory.cc | 16 +++ src/YWidgetFactory.h | 4 + 9 files changed, 639 insertions(+), 53 deletions(-) create mode 100644 src/YMenuBar.cc create mode 100644 src/YMenuBar.h diff --git a/SOURCECONF.cmake b/SOURCECONF.cmake index a006c038c..70aff6ba0 100644 --- a/SOURCECONF.cmake +++ b/SOURCECONF.cmake @@ -54,6 +54,7 @@ SET( ${TARGETLIB}_SOURCES YLabel.cc YLayoutBox.cc YLogView.cc + YMenuBar.cc YMenuButton.cc YMultiLineEdit.cc YMultiProgressMeter.cc @@ -154,6 +155,7 @@ SET( ${TARGETLIB}_HEADERS YLabel.h YLayoutBox.h YLogView.h + YMenuBar.h YMenuButton.h YMultiLineEdit.h YMultiProgressMeter.h diff --git a/src/YItem.h b/src/YItem.h index 2f8096731..49b42ef20 100644 --- a/src/YItem.h +++ b/src/YItem.h @@ -36,8 +36,10 @@ class YItem; //! Collection of pointers to YItem. typedef std::vector YItemCollection; + //! Mutable iterator over @ref YItemCollection. typedef YItemCollection::iterator YItemIterator; + //! Const iterator over @ref YItemCollection. typedef YItemCollection::const_iterator YItemConstIterator; diff --git a/src/YMenuBar.cc b/src/YMenuBar.cc new file mode 100644 index 000000000..993fea27f --- /dev/null +++ b/src/YMenuBar.cc @@ -0,0 +1,318 @@ +/* + 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: YMenuBar.cc + + Author: Stefan Hundhammer + +/-*/ + + +#define YUILogComponent "ui" +#include "YUILog.h" + +#include "YUISymbols.h" +#include "YShortcut.h" +#include "YMenuBar.h" + + +using std::string; + + +struct YMenuBarPrivate +{ + YMenuBarPrivate() + : nextSerialNo( 0 ) + {} + + int nextSerialNo; +}; + + +YMenuBar::YMenuBar( YWidget * parent ) + : YSelectionWidget( parent, + "", // label + false ) // enforceSingleSelection + , priv( new YMenuBarPrivate() ) +{ + YUI_CHECK_NEW( priv ); +} + + + + +YMenuBar::~YMenuBar() +{ + // NOP +} + + +void +YMenuBar::addItems( const YItemCollection & itemCollection ) +{ + YSelectionWidget::addItems( itemCollection ); + resolveShortcutConflicts(); + rebuildMenuTree(); +} + + +void +YMenuBar::addItem( YItem * item ) +{ + YSelectionWidget::addItem( item ); + item->setIndex( ++(priv->nextSerialNo) ); + + if ( item->hasChildren() ) + assignUniqueIndex( item->childrenBegin(), item->childrenEnd() ); +} + + +void +YMenuBar::assignUniqueIndex( YItemIterator begin, YItemIterator end ) +{ + for ( YItemIterator it = begin; it != end; ++it ) + { + YItem * item = *it; + + item->setIndex( ++(priv->nextSerialNo) ); + + if ( item->hasChildren() ) + assignUniqueIndex( item->childrenBegin(), item->childrenEnd() ); + } +} + + +void +YMenuBar::deleteAllItems() +{ + YSelectionWidget::deleteAllItems(); + priv->nextSerialNo = 0; +} + + +YMenuItem * +YMenuBar::findMenuItem( int index ) +{ + return findMenuItem( index, itemsBegin(), itemsEnd() ); +} + + +YMenuItem * +YMenuBar::findMenuItem( int wantedIndex, + YItemConstIterator begin, + YItemConstIterator end ) +{ + for ( YItemConstIterator it = begin; it != end; ++it ) + { + YMenuItem * item = dynamic_cast (*it); + + if ( item ) + { + if ( item->index() == wantedIndex ) + return item; + + if ( item->hasChildren() ) + { + YMenuItem * result = findMenuItem( wantedIndex, + item->childrenBegin(), + item->childrenEnd() ); + if ( result ) + return result; + } + } + } + + return 0; +} + + +static void resolveShortcutsConflict( YItemConstIterator begin, + YItemConstIterator end ) +{ + bool used[ sizeof( char ) << 8 ]; + + for ( unsigned i=0; i < sizeof( char ) << 8; i++ ) + used[i] = false; + std::vector conflicts; + + for ( YItemConstIterator it = begin; it != end; ++it ) + { + YMenuItem * item = dynamic_cast (*it); + + if ( item ) + { + if ( item->hasChildren() ) + { + resolveShortcutsConflict( item->childrenBegin(), item->childrenEnd() ); + } + + char shortcut = YShortcut::normalized(YShortcut::findShortcut(item->label())); + + if ( shortcut == 0 ) + { + conflicts.push_back(item); + yuiMilestone() << "No or invalid shortcut found " << item->label() << endl; + } + else if ( used[ (unsigned)shortcut ] ) + { + conflicts.push_back(item); + yuiWarning() << "Conflicting shortcut found " << item->label() << endl; + } + else + { + used[ (unsigned) shortcut ] = true; + } + } + else + { + yuiWarning() << "non menu item used in call " << (*it)->label() << endl; + } + } + + // cannot use YShortcut directly as an YItem is not a YWidget + for( YMenuItem *i: conflicts ) + { + string clean = YShortcut::cleanShortcutString(i->label()); + char new_c = 0; + + size_t index = 0; + for (; index < clean.size(); ++index) + { + char ch = YShortcut::normalized( clean[index] ); + // ch is set to 0 by normalized() if not valid + if ( ch != 0 && ! used[ (unsigned)ch ] ) + { + new_c = ch; + used[(unsigned)ch] = true; + break; + } + } + + if (new_c != 0) + { + clean.insert(index, 1, YShortcut::shortcutMarker()); + yuiMilestone() << "New label used: " << clean << endl; + } + + i->setLabel( clean ); + } +} + + +void +YMenuBar::resolveShortcutConflicts() +{ + resolveShortcutsConflict( itemsBegin(), itemsEnd() ); +} + + +YMenuItem * +YMenuBar::findItem( std::vector & path ) const +{ + return findItem( path.begin(), path.end(), + itemsBegin(), itemsEnd() ); +} + + +YMenuItem * +YMenuBar::findItem( std::vector::iterator path_begin, + std::vector::iterator path_end, + YItemConstIterator begin, + YItemConstIterator end ) const +{ + for ( YItemConstIterator it = begin; it != end; ++it ) + { + YMenuItem * item = dynamic_cast(*it); + // Test that dynamic_cast didn't fail + + if ( !item ) + return 0; + + if ( item->label() == *path_begin ) + { + if ( std::next(path_begin) == path_end ) + { + // Only return items which can trigger an action. + // Intermediate items only open a submenu, so continue looking. + if( item->hasChildren() ) + continue; + + return item; + } + + // Look in child nodes and return if found one + YMenuItem * result = findItem( ++path_begin, path_end, + item->childrenBegin(), item->childrenEnd() ); + if ( result ) + return result; + } + } + return 0; +} + + +const YPropertySet & +YMenuBar::propertySet() +{ + static YPropertySet propSet; + + if ( propSet.isEmpty() ) + { + /* + * @property itemList Items All menu items and submenus + * @property string IconPath Base path for icons (on menu items) + */ + propSet.add( YProperty( YUIProperty_Items, YOtherProperty ) ); + propSet.add( YProperty( YUIProperty_IconPath, YStringProperty ) ); + propSet.add( YWidget::propertySet() ); + } + + return propSet; +} + + +bool +YMenuBar::setProperty( const string & propertyName, const YPropertyValue & val ) +{ + propertySet().check( propertyName, val.type() ); // throws exceptions if not found or type mismatch + + if ( propertyName == YUIProperty_Items ) return false; // Needs special handling + else if ( propertyName == YUIProperty_IconPath ) setIconBasePath( val.stringVal() ); + else + { + return YWidget::setProperty( propertyName, val ); + } + + return true; // success -- no special processing necessary +} + + +YPropertyValue +YMenuBar::getProperty( const string & propertyName ) +{ + propertySet().check( propertyName ); // throws exceptions if not found + + if ( propertyName == YUIProperty_Label ) return YPropertyValue( label() ); + else if ( propertyName == YUIProperty_Items ) return YPropertyValue( YOtherProperty ); + else if ( propertyName == YUIProperty_IconPath ) return YPropertyValue( iconBasePath() ); + else + { + return YWidget::getProperty( propertyName ); + } +} + diff --git a/src/YMenuBar.h b/src/YMenuBar.h new file mode 100644 index 000000000..39d668ca2 --- /dev/null +++ b/src/YMenuBar.h @@ -0,0 +1,230 @@ +/* + 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: YMenuBar.h + + Author: Stefan Hundhammer + +/-*/ + +#ifndef YMenuBar_h +#define YMenuBar_h + +#include "YSelectionWidget.h" +#include "YMenuItem.h" + +class YMenuBarPrivate; + + +/** + * A classical menu bar for pulldown menus. + * + * Use this only when appropriate: In most places, YaST follows a wizard-driven + * UI strategy, asking the user (ideally) one question at a time, with a [Next] + * and a [Back] button to move between wizard steps. One of the last steps is + * usually presenting the collected information to the user until everything is + * applied. + * + * A menu bar OTOH is meant for the opposite UI strategy: Presenting some kind + * of document (which may also be a number of input fields) to the user as the + * central point and providing lots of different operations on that document. + * The two concepts don't mix very well, so use this widget with caution. + * + * A menu bar should only contain menus, no direct actions. + **/ +class YMenuBar: public YSelectionWidget +{ +protected: + /** + * Constructor. + **/ + YMenuBar( YWidget * parent ); + +public: + /** + * Destructor. + **/ + virtual ~YMenuBar(); + + /** + * Returns a descriptive name of this widget class for logging, + * debugging etc. + **/ + virtual const char * widgetClass() const { return "YMenuBar"; } + + /** + * Rebuild the displayed menu tree from the internally stored YMenuItems. + * + * The application should call this (once) after all items have been added + * with addItem(). YMenuButton::addItems() calls this automatically. + * + * Derived classes are required to implement this. + **/ + virtual void rebuildMenuTree() = 0; + + /** + * Add multiple items. For some UIs, this can be more efficient than + * calling addItem() multiple times. This function also automatically calls + * resolveShortcutConflicts() and rebuildMenuTree() at the end. + * + * Derived classes can overwrite this function, but they should call this + * base class function at the end of the new implementation. + * + * Reimplemented from YSelectionWidget. + **/ + virtual void addItems( const YItemCollection & itemCollection ); + + /** + * Add one item. This widget assumes ownership of the item object and will + * delete it in its destructor. + * + * This reimplementation will an index to the item that is unique for all + * items in this MenuButton. That index can be used later with + * findMenuItem() to find the item by that index. + * + * @note please do not forget to call after adding all elements + * #resolveShortcutConflicts and #rebuildMenuTree in this order. It is + * important to call it after all submenus are added otherwise it won't + * have proper shortcuts and won't be rendered. + * @see examples/MenuButton.cc. + * + * Reimplemented from YSelectionWidget. + **/ + virtual void addItem( YItem * item_disown ); + + /** + * Delete all items. + * + * Reimplemented from YSelectionWidget. + **/ + virtual void deleteAllItems(); + + /** + * Resolve keyboard shortcut conflicts: Change shortcuts of menu items if + * there are duplicates in the respective menu level. + * + * This has to be called after all items are added, but before rebuildMenuTree() + * (see above). YMenuButton::addItems() calls this automatically. + **/ + void resolveShortcutConflicts(); + + /** + * Set a property. + * Reimplemented from YWidget. + * + * This function may throw YUIPropertyExceptions. + * + * This function returns 'true' if the value was successfully set and + * 'false' if that value requires special handling (not in error cases: + * those are covered by exceptions). + **/ + virtual bool setProperty( const std::string & propertyName, + const YPropertyValue & val ); + + /** + * Get a property. + * Reimplemented from YWidget. + * + * This method may throw YUIPropertyExceptions. + **/ + virtual YPropertyValue getProperty( const std::string & propertyName ); + + /** + * Return this class's property set. + * This also initializes the property upon the first call. + * + * Reimplemented from YWidget. + **/ + virtual const YPropertySet & propertySet(); + + /** + * Support for the Rest API for UI testing: + * + * Return the item in the tree which matches a path of labels. This + * returns 0 if there is no such item or if it is not a leaf menu item. + * + * 'path' specifies the user-visible labels (i.e. the translated texts) of + * each menu level ( ["File", "Export", "As XML"] ). + **/ + YMenuItem * findItem( std::vector & path ) const; + + /** + * Support for the Rest API for UI testing: + * + * Activate the item selected in the tree. + * This can be used in tests to simulate user input. + * + * Derived classes are required to implement this. + **/ + virtual void activateItem( YMenuItem * item ) = 0; + + /** + * Recursively find the first menu item with the specified index. + * Returns 0 if there is no such item. + **/ + YMenuItem * findMenuItem( int index ); + +protected: + /** + * Check if all toplevel items are really menus, i.e. YMenuItems that have + * children. This may throw a YUIException. + **/ + void sanityCheck(); + + /** + * Recursively find the first menu item with the specified index + * from iterator 'begin' to iterator 'end'. + * + * Returns 0 if there is no such item. + **/ + YMenuItem * findMenuItem( int index, + YItemConstIterator begin, + YItemConstIterator end ); + + /** + * Recursively looks for the first item in the tree of the menu items + * using depth first search. + * Return nullptr if item which matches full path is not found. + * Path is a vector of strings, where next element is a child item, so + * in case one needs to select File->Export->As PDF, for instance, + * Vector will look like [ "File", "Export", "As PDF" ]. + */ + YMenuItem * findItem( std::vector::iterator path_begin, + std::vector::iterator path_end, + YItemConstIterator begin, + YItemConstIterator end ) const; + + /** + * Alias for findMenuItem(). Reimplemented to ensure consistent behaviour + * with YSelectionWidget::itemAt(). + **/ + YMenuItem * itemAt( int index ) + { return findMenuItem( index ); } + + /** + * Assign a unique index to all items from iterator 'begin' to iterator 'end'. + **/ + void assignUniqueIndex( YItemIterator begin, YItemIterator end ); + +private: + + ImplPtr priv; +}; + + +#endif // YMenuBar_h diff --git a/src/YMenuButton.cc b/src/YMenuButton.cc index 7db00c13a..98779ea49 100644 --- a/src/YMenuButton.cc +++ b/src/YMenuButton.cc @@ -216,6 +216,50 @@ YMenuButton::resolveShortcutConflicts() } +YMenuItem * +YMenuButton::findItem( std::vector & path ) const +{ + return findItem( path.begin(), path.end(), + itemsBegin(), itemsEnd() ); +} + + +YMenuItem * +YMenuButton::findItem( std::vector::iterator path_begin, + std::vector::iterator path_end, + YItemConstIterator begin, + YItemConstIterator end ) const +{ + for ( YItemConstIterator it = begin; it != end; ++it ) + { + YMenuItem * item = dynamic_cast(*it); + // Test that dynamic_cast didn't fail + if ( !item ) + return nullptr; + + if ( item->label() == *path_begin ) + { + if ( std::next(path_begin) == path_end ) + { + // Only return items which can trigger an action. + // Intermediate items only open a submenu, so continue looking. + + if( item->hasChildren() ) + continue; + + return item; + } + + // Look in child nodes and return if found one + YMenuItem * result = findItem( ++path_begin, path_end, item->childrenBegin(), item->childrenEnd() ); + if ( result ) + return result; + } + } + return nullptr; +} + + const YPropertySet & YMenuButton::propertySet() { @@ -268,41 +312,3 @@ YMenuButton::getProperty( const string & propertyName ) return YWidget::getProperty( propertyName ); } } - - -YMenuItem * -YMenuButton::findItem( std::vector & path ) const -{ - return findItem( path.begin(), path.end(), itemsBegin(), itemsEnd()); -} - -YMenuItem * -YMenuButton::findItem( std::vector::iterator path_begin, - std::vector::iterator path_end, - YItemConstIterator begin, - YItemConstIterator end ) const -{ - for ( YItemConstIterator it = begin; it != end; ++it ) - { - YMenuItem * item = dynamic_cast(*it); - // Test that dynamic_cast didn't fail - if ( !item ) - return nullptr; - - if( item->label() == *path_begin ) - { - if ( std::next(path_begin) == path_end ) { - // Only return items which can trigger action, intermediate items only open nested popup, so continue looking - if( item->hasChildren() ) - continue; - - return item; - } - // Look in child nodes and return if found one - YMenuItem * result = findItem( ++path_begin, path_end, item->childrenBegin(), item->childrenEnd() ); - if ( result ) - return result; - } - } - return nullptr; -} diff --git a/src/YMenuButton.h b/src/YMenuButton.h index d302c9c0b..6f1477ef0 100644 --- a/src/YMenuButton.h +++ b/src/YMenuButton.h @@ -28,7 +28,6 @@ #include "YSelectionWidget.h" #include "YMenuItem.h" -class YMenuItem; class YMenuButtonPrivate; @@ -134,7 +133,7 @@ class YMenuButton : public YSelectionWidget * 'false' if that value requires special handling (not in error cases: * those are covered by exceptions). **/ - virtual bool setProperty( const std::string & propertyName, + virtual bool setProperty( const std::string & propertyName, const YPropertyValue & val ); /** @@ -154,18 +153,24 @@ class YMenuButton : public YSelectionWidget virtual const YPropertySet & propertySet(); /** - * Return item in the tree which matches path of labels or nullptr in case no - * item with such label was found and is a leaf, as other nodes do not trigger - * actions except showing children items. - * Accepts vector of strings which denote path to the node. + * Support for the Rest API for UI testing: + * + * Return the item in the tree which matches a path of labels. This + * returns 0 if there is no such item or if it is not a leaf menu item. + * + * 'path' specifies the user-visible labels (i.e. the translated texts) of + * each menu level ( ["File", "Export", "As XML"] ). **/ YMenuItem * findItem( std::vector & path ) const; /** - * Activate the item selected in the tree. Can be used in tests to simulate user input. - * - * Derived classes are required to implement this. - **/ + * Support for the Rest API for UI testing: + * + * Activate the item selected in the tree. + * This can be used in tests to simulate user input. + * + * Derived classes are required to implement this. + **/ virtual void activateItem( YMenuItem * item ) = 0; /** @@ -175,14 +180,15 @@ class YMenuButton : public YSelectionWidget YMenuItem * findMenuItem( int index ); protected: - /** * Recursively find the first menu item with the specified index * from iterator 'begin' to iterator 'end'. * * Returns 0 if there is no such item. **/ - YMenuItem * findMenuItem( int index, YItemConstIterator begin, YItemConstIterator end ); + YMenuItem * findMenuItem( int index, + YItemConstIterator begin, + YItemConstIterator end ); /** * Recursively looks for the first item in the tree of the menu items @@ -194,8 +200,8 @@ class YMenuButton : public YSelectionWidget */ YMenuItem * findItem( std::vector::iterator path_begin, std::vector::iterator path_end, - YItemConstIterator begin, - YItemConstIterator end ) const; + YItemConstIterator begin, + YItemConstIterator end ) const; /** * Alias for findMenuItem(). Reimplemented to ensure consistent behaviour @@ -204,13 +210,14 @@ class YMenuButton : public YSelectionWidget YMenuItem * itemAt( int index ) { return findMenuItem( index ); } -private: /** * Assign a unique index to all items from iterator 'begin' to iterator 'end'. **/ void assignUniqueIndex( YItemIterator begin, YItemIterator end ); + +private: ImplPtr priv; }; diff --git a/src/YUISymbols.h b/src/YUISymbols.h index 83930c154..44acefa86 100644 --- a/src/YUISymbols.h +++ b/src/YUISymbols.h @@ -108,6 +108,7 @@ #define YUIWidget_Left "Left" #define YUIWidget_LogView "LogView" #define YUIWidget_MarginBox "MarginBox" +#define YUIWidget_MenuBar "MenuBar" #define YUIWidget_MenuButton "MenuButton" #define YUIWidget_MinHeight "MinHeight" #define YUIWidget_MinSize "MinSize" diff --git a/src/YWidgetFactory.cc b/src/YWidgetFactory.cc index a6b484d7f..76d933b3f 100644 --- a/src/YWidgetFactory.cc +++ b/src/YWidgetFactory.cc @@ -316,3 +316,19 @@ YWidgetFactory::createCustomStatusItemSelector( YWidget * parent, return createItemSelector( parent, false ); // enforceSingleSelection } + + +YMenuBar * +YWidgetFactory::createMenuBar( YWidget * parent ) +{ + (void) parent; + + // Default implementation returning 0 to give community-maintained UIs + // (libyui-gtk) a chance to catch up with development. Remove this and make + // it pure virtual when this is implemented there as well. + + yuiError() << "YMenuBar not implemented in this UI" << endl; + + return 0; +} + diff --git a/src/YWidgetFactory.h b/src/YWidgetFactory.h index d19a4f1ce..bec86ba87 100644 --- a/src/YWidgetFactory.h +++ b/src/YWidgetFactory.h @@ -48,6 +48,7 @@ class YItemSelector; class YLabel; class YLayoutBox; class YLogView; +class YMenuBar; class YMenuButton; class YMultiLineEdit; class YMultiSelectionBox; @@ -190,6 +191,9 @@ class YWidgetFactory YItemSelector * createMultiItemSelector ( YWidget * parent ); virtual YItemSelector * createCustomStatusItemSelector ( YWidget * parent, const YItemCustomStatusVector & customStates ); + virtual YMenuBar * createMenuBar ( YWidget * parent ); + + protected: /** From 51cba89455eb4cf442cfeefa8d3303be0416ac35 Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Thu, 9 Jul 2020 18:37:32 +0200 Subject: [PATCH 03/13] Set stretchability --- src/YMenuBar.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/YMenuBar.cc b/src/YMenuBar.cc index 993fea27f..bf54f92b1 100644 --- a/src/YMenuBar.cc +++ b/src/YMenuBar.cc @@ -44,6 +44,8 @@ struct YMenuBarPrivate }; + + YMenuBar::YMenuBar( YWidget * parent ) : YSelectionWidget( parent, "", // label @@ -51,9 +53,10 @@ YMenuBar::YMenuBar( YWidget * parent ) , priv( new YMenuBarPrivate() ) { YUI_CHECK_NEW( priv ); -} - + setStretchable( YD_HORIZ, true ); + setStretchable( YD_VERT, false ); +} YMenuBar::~YMenuBar() @@ -239,7 +242,7 @@ YMenuBar::findItem( std::vector::iterator path_begin, { YMenuItem * item = dynamic_cast(*it); // Test that dynamic_cast didn't fail - + if ( !item ) return 0; From 044dec1e59fa7ece6d361babf5bba2d2f43a9dad Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Sat, 11 Jul 2020 11:45:51 +0200 Subject: [PATCH 04/13] Fixed function naming --- src/YMenuBar.cc | 9 +++++---- src/YMenuBar.h | 12 +++++++++++- src/YMenuButton.cc | 11 ++++++----- src/YMenuButton.h | 11 ++++++++++- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/YMenuBar.cc b/src/YMenuBar.cc index bf54f92b1..3b9220eb7 100644 --- a/src/YMenuBar.cc +++ b/src/YMenuBar.cc @@ -144,8 +144,9 @@ YMenuBar::findMenuItem( int wantedIndex, } -static void resolveShortcutsConflict( YItemConstIterator begin, - YItemConstIterator end ) +void +YMenuBar::resolveShortcutConflicts( YItemConstIterator begin, + YItemConstIterator end ) { bool used[ sizeof( char ) << 8 ]; @@ -161,7 +162,7 @@ static void resolveShortcutsConflict( YItemConstIterator begin, { if ( item->hasChildren() ) { - resolveShortcutsConflict( item->childrenBegin(), item->childrenEnd() ); + resolveShortcutConflicts( item->childrenBegin(), item->childrenEnd() ); } char shortcut = YShortcut::normalized(YShortcut::findShortcut(item->label())); @@ -220,7 +221,7 @@ static void resolveShortcutsConflict( YItemConstIterator begin, void YMenuBar::resolveShortcutConflicts() { - resolveShortcutsConflict( itemsBegin(), itemsEnd() ); + resolveShortcutConflicts( itemsBegin(), itemsEnd() ); } diff --git a/src/YMenuBar.h b/src/YMenuBar.h index 39d668ca2..d73e613fb 100644 --- a/src/YMenuBar.h +++ b/src/YMenuBar.h @@ -56,6 +56,7 @@ class YMenuBar: public YSelectionWidget YMenuBar( YWidget * parent ); public: + /** * Destructor. **/ @@ -99,7 +100,7 @@ class YMenuBar: public YSelectionWidget * * @note please do not forget to call after adding all elements * #resolveShortcutConflicts and #rebuildMenuTree in this order. It is - * important to call it after all submenus are added otherwise it won't + * important to call it after all submenus are added, otherwise it won't * have proper shortcuts and won't be rendered. * @see examples/MenuButton.cc. * @@ -179,13 +180,21 @@ class YMenuBar: public YSelectionWidget **/ YMenuItem * findMenuItem( int index ); + protected: + /** * Check if all toplevel items are really menus, i.e. YMenuItems that have * children. This may throw a YUIException. **/ void sanityCheck(); + /** + * Resolve keyboard shortcut conflicts between iterators 'begin' and 'end'. + **/ + void resolveShortcutConflicts( YItemConstIterator begin, + YItemConstIterator end ); + /** * Recursively find the first menu item with the specified index * from iterator 'begin' to iterator 'end'. @@ -221,6 +230,7 @@ class YMenuBar: public YSelectionWidget **/ void assignUniqueIndex( YItemIterator begin, YItemIterator end ); + private: ImplPtr priv; diff --git a/src/YMenuButton.cc b/src/YMenuButton.cc index 98779ea49..3282ad989 100644 --- a/src/YMenuButton.cc +++ b/src/YMenuButton.cc @@ -137,7 +137,8 @@ YMenuButton::findMenuItem( int wantedIndex, YItemConstIterator begin, YItemConst } -static void resolveShortcutsConflictFlat( YItemConstIterator begin, YItemConstIterator end ) +void +YMenuButton::resolveShortcutConflicts( YItemConstIterator begin, YItemConstIterator end ) { bool used[ sizeof( char ) << 8 ]; @@ -153,7 +154,7 @@ static void resolveShortcutsConflictFlat( YItemConstIterator begin, YItemConstIt { if ( item->hasChildren() ) { - resolveShortcutsConflictFlat( item->childrenBegin(), item->childrenEnd() ); + resolveShortcutConflicts( item->childrenBegin(), item->childrenEnd() ); } char shortcut = YShortcut::normalized(YShortcut::findShortcut(item->label())); @@ -212,7 +213,7 @@ static void resolveShortcutsConflictFlat( YItemConstIterator begin, YItemConstIt void YMenuButton::resolveShortcutConflicts() { - resolveShortcutsConflictFlat( itemsBegin(), itemsEnd() ); + resolveShortcutConflicts( itemsBegin(), itemsEnd() ); } @@ -243,13 +244,13 @@ YMenuButton::findItem( std::vector::iterator path_begin, { // Only return items which can trigger an action. // Intermediate items only open a submenu, so continue looking. - + if( item->hasChildren() ) continue; return item; } - + // Look in child nodes and return if found one YMenuItem * result = findItem( ++path_begin, path_end, item->childrenBegin(), item->childrenEnd() ); if ( result ) diff --git a/src/YMenuButton.h b/src/YMenuButton.h index 6f1477ef0..c3ecd6429 100644 --- a/src/YMenuButton.h +++ b/src/YMenuButton.h @@ -56,6 +56,7 @@ class YMenuButton : public YSelectionWidget YMenuButton( YWidget * parent, const std::string & label ); public: + /** * Destructor. **/ @@ -179,7 +180,15 @@ class YMenuButton : public YSelectionWidget **/ YMenuItem * findMenuItem( int index ); + protected: + + /** + * Resolve keyboard shortcut conflicts between iterators 'begin' and 'end'. + **/ + void resolveShortcutConflicts( YItemConstIterator begin, + YItemConstIterator end ); + /** * Recursively find the first menu item with the specified index * from iterator 'begin' to iterator 'end'. @@ -216,7 +225,7 @@ class YMenuButton : public YSelectionWidget **/ void assignUniqueIndex( YItemIterator begin, YItemIterator end ); - + private: ImplPtr priv; From 767786ec988e2a1518bd390febac179911d7be6e Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Sat, 11 Jul 2020 12:38:45 +0200 Subject: [PATCH 05/13] Factored common parts out to common base class --- SOURCECONF.cmake | 2 + src/YMenuBar.cc | 214 +----------------------------- src/YMenuBar.h | 128 +----------------- src/YMenuButton.cc | 206 +---------------------------- src/YMenuButton.h | 132 +------------------ src/YMenuWidget.cc | 319 +++++++++++++++++++++++++++++++++++++++++++++ src/YMenuWidget.h | 228 ++++++++++++++++++++++++++++++++ 7 files changed, 559 insertions(+), 670 deletions(-) create mode 100644 src/YMenuWidget.cc create mode 100644 src/YMenuWidget.h diff --git a/SOURCECONF.cmake b/SOURCECONF.cmake index 70aff6ba0..0b396ca55 100644 --- a/SOURCECONF.cmake +++ b/SOURCECONF.cmake @@ -56,6 +56,7 @@ SET( ${TARGETLIB}_SOURCES YLogView.cc YMenuBar.cc YMenuButton.cc + YMenuWidget.cc YMultiLineEdit.cc YMultiProgressMeter.cc YMultiSelectionBox.cc @@ -157,6 +158,7 @@ SET( ${TARGETLIB}_HEADERS YLogView.h YMenuBar.h YMenuButton.h + YMenuWidget.h YMultiLineEdit.h YMultiProgressMeter.h YMultiSelectionBox.h diff --git a/src/YMenuBar.cc b/src/YMenuBar.cc index 3b9220eb7..cb2099619 100644 --- a/src/YMenuBar.cc +++ b/src/YMenuBar.cc @@ -37,19 +37,17 @@ using std::string; struct YMenuBarPrivate { YMenuBarPrivate() - : nextSerialNo( 0 ) {} - int nextSerialNo; + int dummy; }; YMenuBar::YMenuBar( YWidget * parent ) - : YSelectionWidget( parent, - "", // label - false ) // enforceSingleSelection + : YMenuWidget( parent, + "" ) // label , priv( new YMenuBarPrivate() ) { YUI_CHECK_NEW( priv ); @@ -65,209 +63,6 @@ YMenuBar::~YMenuBar() } -void -YMenuBar::addItems( const YItemCollection & itemCollection ) -{ - YSelectionWidget::addItems( itemCollection ); - resolveShortcutConflicts(); - rebuildMenuTree(); -} - - -void -YMenuBar::addItem( YItem * item ) -{ - YSelectionWidget::addItem( item ); - item->setIndex( ++(priv->nextSerialNo) ); - - if ( item->hasChildren() ) - assignUniqueIndex( item->childrenBegin(), item->childrenEnd() ); -} - - -void -YMenuBar::assignUniqueIndex( YItemIterator begin, YItemIterator end ) -{ - for ( YItemIterator it = begin; it != end; ++it ) - { - YItem * item = *it; - - item->setIndex( ++(priv->nextSerialNo) ); - - if ( item->hasChildren() ) - assignUniqueIndex( item->childrenBegin(), item->childrenEnd() ); - } -} - - -void -YMenuBar::deleteAllItems() -{ - YSelectionWidget::deleteAllItems(); - priv->nextSerialNo = 0; -} - - -YMenuItem * -YMenuBar::findMenuItem( int index ) -{ - return findMenuItem( index, itemsBegin(), itemsEnd() ); -} - - -YMenuItem * -YMenuBar::findMenuItem( int wantedIndex, - YItemConstIterator begin, - YItemConstIterator end ) -{ - for ( YItemConstIterator it = begin; it != end; ++it ) - { - YMenuItem * item = dynamic_cast (*it); - - if ( item ) - { - if ( item->index() == wantedIndex ) - return item; - - if ( item->hasChildren() ) - { - YMenuItem * result = findMenuItem( wantedIndex, - item->childrenBegin(), - item->childrenEnd() ); - if ( result ) - return result; - } - } - } - - return 0; -} - - -void -YMenuBar::resolveShortcutConflicts( YItemConstIterator begin, - YItemConstIterator end ) -{ - bool used[ sizeof( char ) << 8 ]; - - for ( unsigned i=0; i < sizeof( char ) << 8; i++ ) - used[i] = false; - std::vector conflicts; - - for ( YItemConstIterator it = begin; it != end; ++it ) - { - YMenuItem * item = dynamic_cast (*it); - - if ( item ) - { - if ( item->hasChildren() ) - { - resolveShortcutConflicts( item->childrenBegin(), item->childrenEnd() ); - } - - char shortcut = YShortcut::normalized(YShortcut::findShortcut(item->label())); - - if ( shortcut == 0 ) - { - conflicts.push_back(item); - yuiMilestone() << "No or invalid shortcut found " << item->label() << endl; - } - else if ( used[ (unsigned)shortcut ] ) - { - conflicts.push_back(item); - yuiWarning() << "Conflicting shortcut found " << item->label() << endl; - } - else - { - used[ (unsigned) shortcut ] = true; - } - } - else - { - yuiWarning() << "non menu item used in call " << (*it)->label() << endl; - } - } - - // cannot use YShortcut directly as an YItem is not a YWidget - for( YMenuItem *i: conflicts ) - { - string clean = YShortcut::cleanShortcutString(i->label()); - char new_c = 0; - - size_t index = 0; - for (; index < clean.size(); ++index) - { - char ch = YShortcut::normalized( clean[index] ); - // ch is set to 0 by normalized() if not valid - if ( ch != 0 && ! used[ (unsigned)ch ] ) - { - new_c = ch; - used[(unsigned)ch] = true; - break; - } - } - - if (new_c != 0) - { - clean.insert(index, 1, YShortcut::shortcutMarker()); - yuiMilestone() << "New label used: " << clean << endl; - } - - i->setLabel( clean ); - } -} - - -void -YMenuBar::resolveShortcutConflicts() -{ - resolveShortcutConflicts( itemsBegin(), itemsEnd() ); -} - - -YMenuItem * -YMenuBar::findItem( std::vector & path ) const -{ - return findItem( path.begin(), path.end(), - itemsBegin(), itemsEnd() ); -} - - -YMenuItem * -YMenuBar::findItem( std::vector::iterator path_begin, - std::vector::iterator path_end, - YItemConstIterator begin, - YItemConstIterator end ) const -{ - for ( YItemConstIterator it = begin; it != end; ++it ) - { - YMenuItem * item = dynamic_cast(*it); - // Test that dynamic_cast didn't fail - - if ( !item ) - return 0; - - if ( item->label() == *path_begin ) - { - if ( std::next(path_begin) == path_end ) - { - // Only return items which can trigger an action. - // Intermediate items only open a submenu, so continue looking. - if( item->hasChildren() ) - continue; - - return item; - } - - // Look in child nodes and return if found one - YMenuItem * result = findItem( ++path_begin, path_end, - item->childrenBegin(), item->childrenEnd() ); - if ( result ) - return result; - } - } - return 0; -} const YPropertySet & @@ -311,8 +106,7 @@ YMenuBar::getProperty( const string & propertyName ) { propertySet().check( propertyName ); // throws exceptions if not found - if ( propertyName == YUIProperty_Label ) return YPropertyValue( label() ); - else if ( propertyName == YUIProperty_Items ) return YPropertyValue( YOtherProperty ); + if ( propertyName == YUIProperty_Items ) return YPropertyValue( YOtherProperty ); else if ( propertyName == YUIProperty_IconPath ) return YPropertyValue( iconBasePath() ); else { diff --git a/src/YMenuBar.h b/src/YMenuBar.h index d73e613fb..8ece41ec0 100644 --- a/src/YMenuBar.h +++ b/src/YMenuBar.h @@ -25,7 +25,7 @@ #ifndef YMenuBar_h #define YMenuBar_h -#include "YSelectionWidget.h" +#include "YMenuWidget.h" #include "YMenuItem.h" class YMenuBarPrivate; @@ -47,7 +47,7 @@ class YMenuBarPrivate; * * A menu bar should only contain menus, no direct actions. **/ -class YMenuBar: public YSelectionWidget +class YMenuBar: public YMenuWidget { protected: /** @@ -68,62 +68,6 @@ class YMenuBar: public YSelectionWidget **/ virtual const char * widgetClass() const { return "YMenuBar"; } - /** - * Rebuild the displayed menu tree from the internally stored YMenuItems. - * - * The application should call this (once) after all items have been added - * with addItem(). YMenuButton::addItems() calls this automatically. - * - * Derived classes are required to implement this. - **/ - virtual void rebuildMenuTree() = 0; - - /** - * Add multiple items. For some UIs, this can be more efficient than - * calling addItem() multiple times. This function also automatically calls - * resolveShortcutConflicts() and rebuildMenuTree() at the end. - * - * Derived classes can overwrite this function, but they should call this - * base class function at the end of the new implementation. - * - * Reimplemented from YSelectionWidget. - **/ - virtual void addItems( const YItemCollection & itemCollection ); - - /** - * Add one item. This widget assumes ownership of the item object and will - * delete it in its destructor. - * - * This reimplementation will an index to the item that is unique for all - * items in this MenuButton. That index can be used later with - * findMenuItem() to find the item by that index. - * - * @note please do not forget to call after adding all elements - * #resolveShortcutConflicts and #rebuildMenuTree in this order. It is - * important to call it after all submenus are added, otherwise it won't - * have proper shortcuts and won't be rendered. - * @see examples/MenuButton.cc. - * - * Reimplemented from YSelectionWidget. - **/ - virtual void addItem( YItem * item_disown ); - - /** - * Delete all items. - * - * Reimplemented from YSelectionWidget. - **/ - virtual void deleteAllItems(); - - /** - * Resolve keyboard shortcut conflicts: Change shortcuts of menu items if - * there are duplicates in the respective menu level. - * - * This has to be called after all items are added, but before rebuildMenuTree() - * (see above). YMenuButton::addItems() calls this automatically. - **/ - void resolveShortcutConflicts(); - /** * Set a property. * Reimplemented from YWidget. @@ -153,33 +97,6 @@ class YMenuBar: public YSelectionWidget **/ virtual const YPropertySet & propertySet(); - /** - * Support for the Rest API for UI testing: - * - * Return the item in the tree which matches a path of labels. This - * returns 0 if there is no such item or if it is not a leaf menu item. - * - * 'path' specifies the user-visible labels (i.e. the translated texts) of - * each menu level ( ["File", "Export", "As XML"] ). - **/ - YMenuItem * findItem( std::vector & path ) const; - - /** - * Support for the Rest API for UI testing: - * - * Activate the item selected in the tree. - * This can be used in tests to simulate user input. - * - * Derived classes are required to implement this. - **/ - virtual void activateItem( YMenuItem * item ) = 0; - - /** - * Recursively find the first menu item with the specified index. - * Returns 0 if there is no such item. - **/ - YMenuItem * findMenuItem( int index ); - protected: @@ -189,47 +106,6 @@ class YMenuBar: public YSelectionWidget **/ void sanityCheck(); - /** - * Resolve keyboard shortcut conflicts between iterators 'begin' and 'end'. - **/ - void resolveShortcutConflicts( YItemConstIterator begin, - YItemConstIterator end ); - - /** - * Recursively find the first menu item with the specified index - * from iterator 'begin' to iterator 'end'. - * - * Returns 0 if there is no such item. - **/ - YMenuItem * findMenuItem( int index, - YItemConstIterator begin, - YItemConstIterator end ); - - /** - * Recursively looks for the first item in the tree of the menu items - * using depth first search. - * Return nullptr if item which matches full path is not found. - * Path is a vector of strings, where next element is a child item, so - * in case one needs to select File->Export->As PDF, for instance, - * Vector will look like [ "File", "Export", "As PDF" ]. - */ - YMenuItem * findItem( std::vector::iterator path_begin, - std::vector::iterator path_end, - YItemConstIterator begin, - YItemConstIterator end ) const; - - /** - * Alias for findMenuItem(). Reimplemented to ensure consistent behaviour - * with YSelectionWidget::itemAt(). - **/ - YMenuItem * itemAt( int index ) - { return findMenuItem( index ); } - - /** - * Assign a unique index to all items from iterator 'begin' to iterator 'end'. - **/ - void assignUniqueIndex( YItemIterator begin, YItemIterator end ); - private: diff --git a/src/YMenuButton.cc b/src/YMenuButton.cc index 3282ad989..5c07749f1 100644 --- a/src/YMenuButton.cc +++ b/src/YMenuButton.cc @@ -37,18 +37,16 @@ using std::string; struct YMenuButtonPrivate { YMenuButtonPrivate() - : nextSerialNo( 0 ) {} - int nextSerialNo; + int dummy; }; YMenuButton::YMenuButton( YWidget * parent, const string & label ) - : YSelectionWidget( parent, label, - false ) // enforceSingleSelection + : YMenuWidget( parent, label ) , priv( new YMenuButtonPrivate() ) { YUI_CHECK_NEW( priv ); @@ -61,206 +59,6 @@ YMenuButton::~YMenuButton() } -void -YMenuButton::addItems( const YItemCollection & itemCollection ) -{ - YSelectionWidget::addItems( itemCollection ); - resolveShortcutConflicts(); - rebuildMenuTree(); -} - - -void -YMenuButton::addItem( YItem * item ) -{ - YSelectionWidget::addItem( item ); - item->setIndex( ++(priv->nextSerialNo) ); - - if ( item->hasChildren() ) - assignUniqueIndex( item->childrenBegin(), item->childrenEnd() ); -} - - -void -YMenuButton::assignUniqueIndex( YItemIterator begin, YItemIterator end ) -{ - for ( YItemIterator it = begin; it != end; ++it ) - { - YItem * item = *it; - - item->setIndex( ++(priv->nextSerialNo) ); - - if ( item->hasChildren() ) - assignUniqueIndex( item->childrenBegin(), item->childrenEnd() ); - } -} - - -void -YMenuButton::deleteAllItems() -{ - YSelectionWidget::deleteAllItems(); - priv->nextSerialNo = 0; -} - - -YMenuItem * -YMenuButton::findMenuItem( int index ) -{ - return findMenuItem( index, itemsBegin(), itemsEnd() ); -} - - -YMenuItem * -YMenuButton::findMenuItem( int wantedIndex, YItemConstIterator begin, YItemConstIterator end ) -{ - for ( YItemConstIterator it = begin; it != end; ++it ) - { - YMenuItem * item = dynamic_cast (*it); - - if ( item ) - { - if ( item->index() == wantedIndex ) - return item; - - if ( item->hasChildren() ) - { - YMenuItem * result = findMenuItem( wantedIndex, item->childrenBegin(), item->childrenEnd() ); - - if ( result ) - return result; - } - } - } - - return 0; -} - - -void -YMenuButton::resolveShortcutConflicts( YItemConstIterator begin, YItemConstIterator end ) -{ - bool used[ sizeof( char ) << 8 ]; - - for ( unsigned i=0; i < sizeof( char ) << 8; i++ ) - used[i] = false; - std::vector conflicts; - - for ( YItemConstIterator it = begin; it != end; ++it ) - { - YMenuItem * item = dynamic_cast (*it); - - if ( item ) - { - if ( item->hasChildren() ) - { - resolveShortcutConflicts( item->childrenBegin(), item->childrenEnd() ); - } - - char shortcut = YShortcut::normalized(YShortcut::findShortcut(item->label())); - - if ( shortcut == 0 ) - { - conflicts.push_back(item); - yuiMilestone() << "No or invalid shortcut found " << item->label() << endl; - } - else if ( used[ (unsigned)shortcut ] ) - { - conflicts.push_back(item); - yuiWarning() << "Conflicting shortcut found " << item->label() << endl; - } - else - { - used[ (unsigned) shortcut ] = true; - } - } - else - { - yuiWarning() << "non menu item used in call " << (*it)->label() << endl; - } - } - - // cannot use YShortcut directly as an YItem is not a YWidget - for( YMenuItem *i: conflicts ) - { - string clean = YShortcut::cleanShortcutString(i->label()); - char new_c = 0; - - size_t index = 0; - for (; index < clean.size(); ++index) - { - char ch = YShortcut::normalized( clean[index] ); - // ch is set to 0 by normalized() if not valid - if ( ch != 0 && ! used[ (unsigned)ch ] ) - { - new_c = ch; - used[(unsigned)ch] = true; - break; - } - } - - if (new_c != 0) - { - clean.insert(index, 1, YShortcut::shortcutMarker()); - yuiMilestone() << "New label used: " << clean << endl; - } - - i->setLabel( clean ); - } -} - - -void -YMenuButton::resolveShortcutConflicts() -{ - resolveShortcutConflicts( itemsBegin(), itemsEnd() ); -} - - -YMenuItem * -YMenuButton::findItem( std::vector & path ) const -{ - return findItem( path.begin(), path.end(), - itemsBegin(), itemsEnd() ); -} - - -YMenuItem * -YMenuButton::findItem( std::vector::iterator path_begin, - std::vector::iterator path_end, - YItemConstIterator begin, - YItemConstIterator end ) const -{ - for ( YItemConstIterator it = begin; it != end; ++it ) - { - YMenuItem * item = dynamic_cast(*it); - // Test that dynamic_cast didn't fail - if ( !item ) - return nullptr; - - if ( item->label() == *path_begin ) - { - if ( std::next(path_begin) == path_end ) - { - // Only return items which can trigger an action. - // Intermediate items only open a submenu, so continue looking. - - if( item->hasChildren() ) - continue; - - return item; - } - - // Look in child nodes and return if found one - YMenuItem * result = findItem( ++path_begin, path_end, item->childrenBegin(), item->childrenEnd() ); - if ( result ) - return result; - } - } - return nullptr; -} - - const YPropertySet & YMenuButton::propertySet() { diff --git a/src/YMenuButton.h b/src/YMenuButton.h index c3ecd6429..38012659d 100644 --- a/src/YMenuButton.h +++ b/src/YMenuButton.h @@ -25,7 +25,7 @@ #ifndef YMenuButton_h #define YMenuButton_h -#include "YSelectionWidget.h" +#include "YMenuWidget.h" #include "YMenuItem.h" class YMenuButtonPrivate; @@ -44,7 +44,7 @@ class YMenuButtonPrivate; * it with the keyboard). Items that have a submenu never send an event, they * simply open their submenu when activated. **/ -class YMenuButton : public YSelectionWidget +class YMenuButton : public YMenuWidget { protected: /** @@ -68,62 +68,6 @@ class YMenuButton : public YSelectionWidget **/ virtual const char * widgetClass() const { return "YMenuButton"; } - /** - * Rebuild the displayed menu tree from the internally stored YMenuItems. - * - * The application should call this (once) after all items have been added - * with addItem(). YMenuButton::addItems() calls this automatically. - * - * Derived classes are required to implement this. - **/ - virtual void rebuildMenuTree() = 0; - - /** - * Add multiple items. For some UIs, this can be more efficient than - * calling addItem() multiple times. This function also automatically calls - * resolveShortcutConflicts() and rebuildMenuTree() at the end. - * - * Derived classes can overwrite this function, but they should call this - * base class function at the end of the new implementation. - * - * Reimplemented from YSelectionWidget. - **/ - virtual void addItems( const YItemCollection & itemCollection ); - - /** - * Add one item. This widget assumes ownership of the item object and will - * delete it in its destructor. - * - * This reimplementation will an index to the item that is unique for all - * items in this MenuButton. That index can be used later with - * findMenuItem() to find the item by that index. - * - * @note please do not forget to call after adding all elements - * #resolveShortcutConflicts and #rebuildMenuTree in this order. It is - * important to call it after all submenus are added otherwise it won't - * have proper shortcuts and won't be rendered. - * @see examples/MenuButton.cc. - * - * Reimplemented from YSelectionWidget. - **/ - virtual void addItem( YItem * item_disown ); - - /** - * Delete all items. - * - * Reimplemented from YSelectionWidget. - **/ - virtual void deleteAllItems(); - - /** - * Resolve keyboard shortcut conflicts: Change shortcuts of menu items if - * there are duplicates in the respective menu level. - * - * This has to be called after all items are added, but before rebuildMenuTree() - * (see above). YMenuButton::addItems() calls this automatically. - **/ - void resolveShortcutConflicts(); - /** * Set a property. * Reimplemented from YWidget. @@ -153,78 +97,6 @@ class YMenuButton : public YSelectionWidget **/ virtual const YPropertySet & propertySet(); - /** - * Support for the Rest API for UI testing: - * - * Return the item in the tree which matches a path of labels. This - * returns 0 if there is no such item or if it is not a leaf menu item. - * - * 'path' specifies the user-visible labels (i.e. the translated texts) of - * each menu level ( ["File", "Export", "As XML"] ). - **/ - YMenuItem * findItem( std::vector & path ) const; - - /** - * Support for the Rest API for UI testing: - * - * Activate the item selected in the tree. - * This can be used in tests to simulate user input. - * - * Derived classes are required to implement this. - **/ - virtual void activateItem( YMenuItem * item ) = 0; - - /** - * Recursively find the first menu item with the specified index. - * Returns 0 if there is no such item. - **/ - YMenuItem * findMenuItem( int index ); - - -protected: - - /** - * Resolve keyboard shortcut conflicts between iterators 'begin' and 'end'. - **/ - void resolveShortcutConflicts( YItemConstIterator begin, - YItemConstIterator end ); - - /** - * Recursively find the first menu item with the specified index - * from iterator 'begin' to iterator 'end'. - * - * Returns 0 if there is no such item. - **/ - YMenuItem * findMenuItem( int index, - YItemConstIterator begin, - YItemConstIterator end ); - - /** - * Recursively looks for the first item in the tree of the menu items - * using depth first search. - * Return nullptr if item which matches full path is not found. - * Path is a vector of strings, where next element is a child item, so - * in case one needs to select File->Export->As PDF, for instance, - * Vector will look like [ "File", "Export", "As PDF" ]. - */ - YMenuItem * findItem( std::vector::iterator path_begin, - std::vector::iterator path_end, - YItemConstIterator begin, - YItemConstIterator end ) const; - - /** - * Alias for findMenuItem(). Reimplemented to ensure consistent behaviour - * with YSelectionWidget::itemAt(). - **/ - YMenuItem * itemAt( int index ) - { return findMenuItem( index ); } - - - /** - * Assign a unique index to all items from iterator 'begin' to iterator 'end'. - **/ - void assignUniqueIndex( YItemIterator begin, YItemIterator end ); - private: diff --git a/src/YMenuWidget.cc b/src/YMenuWidget.cc new file mode 100644 index 000000000..27ca45a95 --- /dev/null +++ b/src/YMenuWidget.cc @@ -0,0 +1,319 @@ +/* + 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: YMenuWidget.cc + + Author: Stefan Hundhammer + +/-*/ + + +#define YUILogComponent "ui" +#include "YUILog.h" + +#include "YUISymbols.h" +#include "YShortcut.h" +#include "YMenuWidget.h" + + +using std::string; + + +struct YMenuWidgetPrivate +{ + YMenuWidgetPrivate() + : nextSerialNo( 0 ) + {} + + int nextSerialNo; +}; + + + + +YMenuWidget::YMenuWidget( YWidget * parent, const string & label ) + : YSelectionWidget( parent, + label, + false ) // enforceSingleSelection + , priv( new YMenuWidgetPrivate() ) +{ + YUI_CHECK_NEW( priv ); +} + + +YMenuWidget::~YMenuWidget() +{ + // NOP +} + + +void +YMenuWidget::addItems( const YItemCollection & itemCollection ) +{ + YSelectionWidget::addItems( itemCollection ); + resolveShortcutConflicts(); + rebuildMenuTree(); +} + + +void +YMenuWidget::addItem( YItem * item ) +{ + YSelectionWidget::addItem( item ); + item->setIndex( ++(priv->nextSerialNo) ); + + if ( item->hasChildren() ) + assignUniqueIndex( item->childrenBegin(), item->childrenEnd() ); +} + + +void +YMenuWidget::assignUniqueIndex( YItemIterator begin, YItemIterator end ) +{ + for ( YItemIterator it = begin; it != end; ++it ) + { + YItem * item = *it; + + item->setIndex( ++(priv->nextSerialNo) ); + + if ( item->hasChildren() ) + assignUniqueIndex( item->childrenBegin(), item->childrenEnd() ); + } +} + + +void +YMenuWidget::deleteAllItems() +{ + YSelectionWidget::deleteAllItems(); + priv->nextSerialNo = 0; +} + + +YMenuItem * +YMenuWidget::findMenuItem( int index ) +{ + return findMenuItem( index, itemsBegin(), itemsEnd() ); +} + + +YMenuItem * +YMenuWidget::findMenuItem( int wantedIndex, + YItemConstIterator begin, + YItemConstIterator end ) +{ + for ( YItemConstIterator it = begin; it != end; ++it ) + { + YMenuItem * item = dynamic_cast (*it); + + if ( item ) + { + if ( item->index() == wantedIndex ) + return item; + + if ( item->hasChildren() ) + { + YMenuItem * result = findMenuItem( wantedIndex, + item->childrenBegin(), + item->childrenEnd() ); + if ( result ) + return result; + } + } + } + + return 0; +} + + +void +YMenuWidget::resolveShortcutConflicts( YItemConstIterator begin, + YItemConstIterator end ) +{ + bool used[ sizeof( char ) << 8 ]; + + for ( unsigned i=0; i < sizeof( char ) << 8; i++ ) + used[i] = false; + std::vector conflicts; + + for ( YItemConstIterator it = begin; it != end; ++it ) + { + YMenuItem * item = dynamic_cast (*it); + + if ( item ) + { + if ( item->hasChildren() ) + { + resolveShortcutConflicts( item->childrenBegin(), item->childrenEnd() ); + } + + char shortcut = YShortcut::normalized(YShortcut::findShortcut(item->label())); + + if ( shortcut == 0 ) + { + conflicts.push_back(item); + yuiMilestone() << "No or invalid shortcut found " << item->label() << endl; + } + else if ( used[ (unsigned)shortcut ] ) + { + conflicts.push_back(item); + yuiWarning() << "Conflicting shortcut found " << item->label() << endl; + } + else + { + used[ (unsigned) shortcut ] = true; + } + } + else + { + yuiWarning() << "non menu item used in call " << (*it)->label() << endl; + } + } + + // cannot use YShortcut directly as an YItem is not a YWidget + for( YMenuItem *i: conflicts ) + { + string clean = YShortcut::cleanShortcutString(i->label()); + char new_c = 0; + + size_t index = 0; + for (; index < clean.size(); ++index) + { + char ch = YShortcut::normalized( clean[index] ); + // ch is set to 0 by normalized() if not valid + if ( ch != 0 && ! used[ (unsigned)ch ] ) + { + new_c = ch; + used[(unsigned)ch] = true; + break; + } + } + + if (new_c != 0) + { + clean.insert(index, 1, YShortcut::shortcutMarker()); + yuiMilestone() << "New label used: " << clean << endl; + } + + i->setLabel( clean ); + } +} + + +void +YMenuWidget::resolveShortcutConflicts() +{ + resolveShortcutConflicts( itemsBegin(), itemsEnd() ); +} + + +YMenuItem * +YMenuWidget::findItem( std::vector & path ) const +{ + return findItem( path.begin(), path.end(), + itemsBegin(), itemsEnd() ); +} + + +YMenuItem * +YMenuWidget::findItem( std::vector::iterator path_begin, + std::vector::iterator path_end, + YItemConstIterator begin, + YItemConstIterator end ) const +{ + for ( YItemConstIterator it = begin; it != end; ++it ) + { + YMenuItem * item = dynamic_cast(*it); + // Test that dynamic_cast didn't fail + + if ( !item ) + return 0; + + if ( item->label() == *path_begin ) + { + if ( std::next(path_begin) == path_end ) + { + // Only return items which can trigger an action. + // Intermediate items only open a submenu, so continue looking. + if( item->hasChildren() ) + continue; + + return item; + } + + // Look in child nodes and return if found one + YMenuItem * result = findItem( ++path_begin, path_end, + item->childrenBegin(), item->childrenEnd() ); + if ( result ) + return result; + } + } + return 0; +} + + +const YPropertySet & +YMenuWidget::propertySet() +{ + static YPropertySet propSet; + + if ( propSet.isEmpty() ) + { + /* + * @property itemList Items All menu items and submenus + * @property string IconPath Base path for icons (on menu items) + */ + propSet.add( YProperty( YUIProperty_Items, YOtherProperty ) ); + propSet.add( YProperty( YUIProperty_IconPath, YStringProperty ) ); + propSet.add( YWidget::propertySet() ); + } + + return propSet; +} + + +bool +YMenuWidget::setProperty( const string & propertyName, const YPropertyValue & val ) +{ + propertySet().check( propertyName, val.type() ); // throws exceptions if not found or type mismatch + + if ( propertyName == YUIProperty_Items ) return false; // Needs special handling + else if ( propertyName == YUIProperty_IconPath ) setIconBasePath( val.stringVal() ); + else + { + return YWidget::setProperty( propertyName, val ); + } + + return true; // success -- no special processing necessary +} + + +YPropertyValue +YMenuWidget::getProperty( const string & propertyName ) +{ + propertySet().check( propertyName ); // throws exceptions if not found + + if ( propertyName == YUIProperty_Label ) return YPropertyValue( label() ); + else if ( propertyName == YUIProperty_Items ) return YPropertyValue( YOtherProperty ); + else if ( propertyName == YUIProperty_IconPath ) return YPropertyValue( iconBasePath() ); + else + { + return YWidget::getProperty( propertyName ); + } +} + diff --git a/src/YMenuWidget.h b/src/YMenuWidget.h new file mode 100644 index 000000000..a1f7b059d --- /dev/null +++ b/src/YMenuWidget.h @@ -0,0 +1,228 @@ +/* + 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: YMenuWidget.h + + Author: Stefan Hundhammer + +/-*/ + +#ifndef YMenuWidget_h +#define YMenuWidget_h + +#include "YSelectionWidget.h" +#include "YMenuItem.h" + +class YMenuWidgetPrivate; + + +/** + * Abstract base class for widgets that handle menus, e.g. YMenuButton or + * YMenuBar. + **/ +class YMenuWidget: public YSelectionWidget +{ +protected: + /** + * Constructor. + * + * 'label' is only passed through to the inherited class. For a menu + * button, this would be the label on the button; a menu bar does not have + * a label. + **/ + YMenuWidget( YWidget * parent, const std::string & label = "" ); + +public: + + /** + * Destructor. + **/ + virtual ~YMenuWidget(); + + /** + * Returns a descriptive name of this widget class for logging, + * debugging etc. + **/ + virtual const char * widgetClass() const { return "YMenuWidget"; } + + /** + * Rebuild the displayed menu tree from the internally stored YMenuItems. + * + * The application should call this (once) after all items have been added + * with addItem(). YMenuButton::addItems() calls this automatically. + * + * Derived classes are required to implement this. + **/ + virtual void rebuildMenuTree() = 0; + + /** + * Add multiple items. For some UIs, this can be more efficient than + * calling addItem() multiple times. This function also automatically calls + * resolveShortcutConflicts() and rebuildMenuTree() at the end. + * + * Derived classes can overwrite this function, but they should call this + * base class function at the end of the new implementation. + * + * Reimplemented from YSelectionWidget. + **/ + virtual void addItems( const YItemCollection & itemCollection ); + + /** + * Add one item. This widget assumes ownership of the item object and will + * delete it in its destructor. + * + * This reimplementation will an index to the item that is unique for all + * items in this MenuButton. That index can be used later with + * findMenuItem() to find the item by that index. + * + * @note please do not forget to call after adding all elements + * #resolveShortcutConflicts and #rebuildMenuTree in this order. It is + * important to call it after all submenus are added, otherwise it won't + * have proper shortcuts and won't be rendered. + * @see examples/MenuButton.cc. + * + * Reimplemented from YSelectionWidget. + **/ + virtual void addItem( YItem * item_disown ); + + /** + * Delete all items. + * + * Reimplemented from YSelectionWidget. + **/ + virtual void deleteAllItems(); + + /** + * Resolve keyboard shortcut conflicts: Change shortcuts of menu items if + * there are duplicates in the respective menu level. + * + * This has to be called after all items are added, but before + * rebuildMenuTree() (see above). YMenuWidget::addItems() calls this + * automatically. + **/ + void resolveShortcutConflicts(); + + /** + * Set a property. + * Reimplemented from YWidget. + * + * This function may throw YUIPropertyExceptions. + * + * This function returns 'true' if the value was successfully set and + * 'false' if that value requires special handling (not in error cases: + * those are covered by exceptions). + **/ + virtual bool setProperty( const std::string & propertyName, + const YPropertyValue & val ); + + /** + * Get a property. + * Reimplemented from YWidget. + * + * This method may throw YUIPropertyExceptions. + **/ + virtual YPropertyValue getProperty( const std::string & propertyName ); + + /** + * Return this class's property set. + * This also initializes the property upon the first call. + * + * Reimplemented from YWidget. + **/ + virtual const YPropertySet & propertySet(); + + /** + * Support for the Rest API for UI testing: + * + * Return the item in the tree which matches a path of labels. This + * returns 0 if there is no such item or if it is not a leaf menu item. + * + * 'path' specifies the user-visible labels (i.e. the translated texts) of + * each menu level ( ["File", "Export", "As XML"] ). + **/ + YMenuItem * findItem( std::vector & path ) const; + + /** + * Support for the Rest API for UI testing: + * + * Activate the item selected in the tree. + * This can be used in tests to simulate user input. + * + * Derived classes are required to implement this. + **/ + virtual void activateItem( YMenuItem * item ) = 0; + + /** + * Recursively find the first menu item with the specified index. + * Returns 0 if there is no such item. + **/ + YMenuItem * findMenuItem( int index ); + + +protected: + + /** + * Resolve keyboard shortcut conflicts between iterators 'begin' and 'end'. + **/ + void resolveShortcutConflicts( YItemConstIterator begin, + YItemConstIterator end ); + + /** + * Recursively find the first menu item with the specified index + * from iterator 'begin' to iterator 'end'. + * + * Returns 0 if there is no such item. + **/ + YMenuItem * findMenuItem( int index, + YItemConstIterator begin, + YItemConstIterator end ); + + /** + * Recursively looks for the first item in the tree of the menu items + * using depth first search. + * Return nullptr if item which matches full path is not found. + * Path is a vector of strings, where next element is a child item, so + * in case one needs to select File->Export->As PDF, for instance, + * Vector will look like [ "File", "Export", "As PDF" ]. + */ + YMenuItem * findItem( std::vector::iterator path_begin, + std::vector::iterator path_end, + YItemConstIterator begin, + YItemConstIterator end ) const; + + /** + * Alias for findMenuItem(). Reimplemented to ensure consistent behaviour + * with YSelectionWidget::itemAt(). + **/ + YMenuItem * itemAt( int index ) + { return findMenuItem( index ); } + + /** + * Assign a unique index to all items from iterator 'begin' to iterator + * 'end'. + **/ + void assignUniqueIndex( YItemIterator begin, YItemIterator end ); + + +private: + + ImplPtr priv; +}; + + +#endif // YMenuWidget_h From a3c8a6f0f97fbc296441754edd91f026f87dd068 Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Mon, 13 Jul 2020 13:05:06 +0200 Subject: [PATCH 06/13] New example for MenuBar --- SOURCECONF.cmake | 3 +- examples/MenuBar1.cc | 223 ++++++++++++++++++++ examples/{MenuButtons.cc => MenuButton1.cc} | 2 +- 3 files changed, 226 insertions(+), 2 deletions(-) create mode 100644 examples/MenuBar1.cc rename examples/{MenuButtons.cc => MenuButton1.cc} (97%) diff --git a/SOURCECONF.cmake b/SOURCECONF.cmake index 0b396ca55..a178867e9 100644 --- a/SOURCECONF.cmake +++ b/SOURCECONF.cmake @@ -202,7 +202,8 @@ SET( EXAMPLES_LIST ItemSelector1.cc ItemSelector2-minimalistic.cc ManyWidgets.cc - MenuButtons.cc + MenuBar1.cc + MenuButton1.cc PollEvent.cc SelectionBox1.cc SelectionBox2.cc diff --git a/examples/MenuBar1.cc b/examples/MenuBar1.cc new file mode 100644 index 000000000..b960c1c20 --- /dev/null +++ b/examples/MenuBar1.cc @@ -0,0 +1,223 @@ +/* + 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 +*/ + + +// MenuBar example. +// +// Compile with: +// +// g++ -I/usr/include/yui -lyui MenuBar1.cc -o MenuBar1 + +#define YUILogComponent "example" +#include "YUILog.h" + +#include "YUI.h" +#include "YAlignment.h" +#include "YDialog.h" +#include "YLabel.h" +#include "YLayoutBox.h" +#include "YMenuBar.h" +#include "YSquash.h" +#include "YWidgetFactory.h" +#include "YShortcut.h" +#include "YEvent.h" + + +using std::string; + + +// Widgets + +YDialog * dialog = 0; +YLabel * lastEventLabel = 0; + + +// Menus and Menu Items + +YMenuItem * fileMenu = 0; +YMenuItem * editMenu = 0; +YMenuItem * viewMenu = 0; +YMenuItem * optionsMenu = 0; + + +// "File" menu + +YMenuItem * actionOpen = 0; +YMenuItem * actionSave = 0; +YMenuItem * actionSaveAs = 0; +YMenuItem * actionQuit = 0; + + +// "Edit" menu + +YMenuItem * actionCut = 0; +YMenuItem * actionCopy = 0; +YMenuItem * actionPaste = 0; + + +// "View" menu + +YMenuItem * actionViewNormal = 0; +YMenuItem * actionViewCompact = 0; +YMenuItem * actionViewDetailed = 0; + + +// "View" -> "Zoom" submenu + +YMenuItem * zoomMenu = 0; +YMenuItem * actionZoomIn = 0; +YMenuItem * actionZoomOut = 0; +YMenuItem * actionZoomDefault = 0; + +// "Options" menu + +YMenuItem * actionSettings = 0; + + +// Function Prototypes + +void createWidgets(); +void addMenus( YMenuBar * menuBar ); +void handleEvents(); +void showEvent( YMenuEvent * event ); + + + + +int main( int argc, char **argv ) +{ + YUILog::setLogFileName( "/tmp/libyui-examples.log" ); + YUILog::enableDebugLogging(); + + createWidgets(); + handleEvents(); + + dialog->destroy(); +} + + +/** + * Create the widget tree for the main dialog + **/ +void createWidgets() +{ + yuiMilestone() << endl; + + YWidgetFactory * fac = YUI::widgetFactory(); + + dialog = fac->createPopupDialog(); + YAlignment * minSize = fac->createMinSize( dialog, 50, 20 ); + YLayoutBox * vbox1 = fac->createVBox( minSize ); + YMenuBar * menuBar = fac->createMenuBar( vbox1 ); + + addMenus( menuBar ); + + YAlignment * center = fac->createHVCenter( vbox1 ); + YSquash * squash = fac->createHVSquash( center ); + YLayoutBox * vbox2 = fac->createVBox( squash ); + + YAlignment * left = fac->createLeft( vbox2 ); + fac->createLabel ( left, "Last Event:" ); + fac->createHSpacing( vbox2, 1 ); + lastEventLabel = fac->createOutputField( vbox2, "" ); + lastEventLabel->setStretchable( YD_HORIZ, true ); + fac->createMinWidth( vbox2, 20 ); +} + + +void addMenus( YMenuBar * menuBar ) +{ + fileMenu = new YMenuItem( "&File" ); + editMenu = new YMenuItem( "&Edit" ); + viewMenu = new YMenuItem( "&View" ); + optionsMenu = new YMenuItem( "&Options" ); + + actionOpen = new YMenuItem( fileMenu, "&Open..." ); + actionSave = new YMenuItem( fileMenu, "&Save" ); + actionSaveAs = new YMenuItem( fileMenu, "Save &As..." ); + actionQuit = new YMenuItem( fileMenu, "&Quit" ); + + actionCut = new YMenuItem( editMenu, "C&ut" ); + actionCopy = new YMenuItem( editMenu, "&Copy" ); + actionPaste = new YMenuItem( editMenu, "&Paste" ); + + actionViewNormal = new YMenuItem( viewMenu, "&Normal" ); + actionViewCompact = new YMenuItem( viewMenu, "&Compact" ); + actionViewDetailed = new YMenuItem( viewMenu, "&Detailed" ); + + zoomMenu = new YMenuItem( viewMenu, "&Zoom" ); + actionZoomIn = new YMenuItem( zoomMenu, "Zoom &In" ); + actionZoomOut = new YMenuItem( zoomMenu, "Zoom &Out" ); + actionZoomDefault = new YMenuItem( zoomMenu, "Zoom &Default" ); + + actionSettings = new YMenuItem( optionsMenu, "&Settings..." ); + + menuBar->addItem( fileMenu ); + menuBar->addItem( editMenu ); + menuBar->addItem( viewMenu ); + menuBar->addItem( optionsMenu ); + + // Do NOT add all the individual items separately to the menu bar: + // They are owned by their parent menu. + + menuBar->resolveShortcutConflicts(); + menuBar->rebuildMenuTree(); +} + + +/** + * Event loop and event handling for the main dialog + **/ +void handleEvents() +{ + yuiMilestone() << endl; + + while ( true ) + { + YEvent * event = dialog->waitForEvent(); + + if ( event ) + { + if ( event->eventType() == YEvent::CancelEvent ) // window manager "close window" button + { + break; // leave event loop + } + + if ( event->eventType() == YEvent::MenuEvent ) + { + YMenuEvent * menuEvent = dynamic_cast( event ); + + if ( menuEvent ) + { + showEvent( menuEvent ); + + if ( menuEvent->item() == actionQuit ) + break; // leave event loop + } + } + } + } +} + + +void showEvent( YMenuEvent * event ) +{ + if ( event && event->item() ) + { + string text = YShortcut::cleanShortcutString( event->item()->label() ); + + lastEventLabel->setLabel( text ); + } +} diff --git a/examples/MenuButtons.cc b/examples/MenuButton1.cc similarity index 97% rename from examples/MenuButtons.cc rename to examples/MenuButton1.cc index a6c74e541..da3a2ac42 100644 --- a/examples/MenuButtons.cc +++ b/examples/MenuButton1.cc @@ -26,7 +26,7 @@ // // Compile with: // -// g++ -I/usr/include/yui -lyui MenuButtons.cc -o MenuButtons +// g++ -I/usr/include/yui -lyui MenuButton1.cc -o MenuButton1 #include "YUI.h" #include "YWidgetFactory.h" From b9e7b08599e6fa656bafc41ee2498d6b103d0472 Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Mon, 13 Jul 2020 15:02:57 +0200 Subject: [PATCH 07/13] Added easier to use API for menus --- SOURCECONF.cmake | 4 +- examples/MenuBar1.cc | 56 ++++----- examples/MenuBar2.cc | 243 ++++++++++++++++++++++++++++++++++++++++ examples/MenuButton1.cc | 47 +++++--- src/YMenuBar.cc | 9 ++ src/YMenuBar.h | 6 + src/YMenuButton.cc | 33 +++++- src/YMenuButton.h | 17 +++ src/YMenuItem.cc | 46 ++++++++ src/YMenuItem.h | 67 ++++++++--- src/YMenuWidget.h | 7 +- 11 files changed, 470 insertions(+), 65 deletions(-) create mode 100644 examples/MenuBar2.cc create mode 100644 src/YMenuItem.cc diff --git a/SOURCECONF.cmake b/SOURCECONF.cmake index a178867e9..d98ebb8a3 100644 --- a/SOURCECONF.cmake +++ b/SOURCECONF.cmake @@ -15,6 +15,7 @@ SET( ${TARGETLIB}_SOURCES YItem.cc YIconLoader.cc YMacro.cc + YMenuItem.cc YProperty.cc YShortcut.cc YShortcutManager.cc @@ -109,10 +110,10 @@ SET( ${TARGETLIB}_HEADERS YItem.h YItemCustomStatus.h YIconLoader.h - YMenuItem.h YMacro.h YMacroPlayer.h YMacroRecorder.h + YMenuItem.h YPackageSelectorPlugin.h YGraphPlugin.h YProperty.h @@ -203,6 +204,7 @@ SET( EXAMPLES_LIST ItemSelector2-minimalistic.cc ManyWidgets.cc MenuBar1.cc + MenuBar2.cc MenuButton1.cc PollEvent.cc SelectionBox1.cc diff --git a/examples/MenuBar1.cc b/examples/MenuBar1.cc index b960c1c20..0a647ce2f 100644 --- a/examples/MenuBar1.cc +++ b/examples/MenuBar1.cc @@ -139,38 +139,35 @@ void createWidgets() void addMenus( YMenuBar * menuBar ) { - fileMenu = new YMenuItem( "&File" ); - editMenu = new YMenuItem( "&Edit" ); - viewMenu = new YMenuItem( "&View" ); - optionsMenu = new YMenuItem( "&Options" ); + // The difference between a menu and a plain menu item is just that the + // menu has child items whild the plain item does not. - actionOpen = new YMenuItem( fileMenu, "&Open..." ); - actionSave = new YMenuItem( fileMenu, "&Save" ); - actionSaveAs = new YMenuItem( fileMenu, "Save &As..." ); - actionQuit = new YMenuItem( fileMenu, "&Quit" ); + fileMenu = menuBar->addMenu( "&File" ); + editMenu = menuBar->addMenu( "&Edit" ); + viewMenu = menuBar->addMenu( "&View" ); + optionsMenu = menuBar->addMenu( "&Options" ); - actionCut = new YMenuItem( editMenu, "C&ut" ); - actionCopy = new YMenuItem( editMenu, "&Copy" ); - actionPaste = new YMenuItem( editMenu, "&Paste" ); + actionOpen = fileMenu->addItem( "&Open..." ); + actionSave = fileMenu->addItem( "&Save" ); + actionSaveAs = fileMenu->addItem( "Save &As..." ); + fileMenu->addSeparator(); + actionQuit = fileMenu->addItem( "&Quit" ); - actionViewNormal = new YMenuItem( viewMenu, "&Normal" ); - actionViewCompact = new YMenuItem( viewMenu, "&Compact" ); - actionViewDetailed = new YMenuItem( viewMenu, "&Detailed" ); + actionCut = editMenu->addItem( "C&ut" ); + actionCopy = editMenu->addItem( "&Copy" ); + actionPaste = editMenu->addItem( "&Paste" ); - zoomMenu = new YMenuItem( viewMenu, "&Zoom" ); - actionZoomIn = new YMenuItem( zoomMenu, "Zoom &In" ); - actionZoomOut = new YMenuItem( zoomMenu, "Zoom &Out" ); - actionZoomDefault = new YMenuItem( zoomMenu, "Zoom &Default" ); + actionViewNormal = viewMenu->addItem( "&Normal" ); + actionViewCompact = viewMenu->addItem( "&Compact" ); + actionViewDetailed = viewMenu->addItem( "&Detailed" ); + viewMenu->addSeparator(); + zoomMenu = viewMenu->addMenu( "&Zoom" ); - actionSettings = new YMenuItem( optionsMenu, "&Settings..." ); + actionZoomIn = zoomMenu->addItem( "Zoom &In" ); + actionZoomOut = zoomMenu->addItem( "Zoom &Out" ); + actionZoomDefault = zoomMenu->addItem( "Zoom &Default" ); - menuBar->addItem( fileMenu ); - menuBar->addItem( editMenu ); - menuBar->addItem( viewMenu ); - menuBar->addItem( optionsMenu ); - - // Do NOT add all the individual items separately to the menu bar: - // They are owned by their parent menu. + actionSettings = optionsMenu->addItem( "&Settings..." ); menuBar->resolveShortcutConflicts(); menuBar->rebuildMenuTree(); @@ -202,7 +199,7 @@ void handleEvents() if ( menuEvent ) { showEvent( menuEvent ); - + if ( menuEvent->item() == actionQuit ) break; // leave event loop } @@ -212,12 +209,15 @@ void handleEvents() } +/** + * Show the (label of) the item causing a menu event in the 'lastEventLabel' + * widget. + **/ void showEvent( YMenuEvent * event ) { if ( event && event->item() ) { string text = YShortcut::cleanShortcutString( event->item()->label() ); - lastEventLabel->setLabel( text ); } } diff --git a/examples/MenuBar2.cc b/examples/MenuBar2.cc new file mode 100644 index 000000000..90537a4aa --- /dev/null +++ b/examples/MenuBar2.cc @@ -0,0 +1,243 @@ +/* + 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 +*/ + + +// MenuBar example. +// +// Compile with: +// +// g++ -I/usr/include/yui -lyui MenuBar2.cc -o MenuBar2 + +#define YUILogComponent "example" +#include "YUILog.h" + +#include "YUI.h" +#include "YAlignment.h" +#include "YDialog.h" +#include "YLabel.h" +#include "YLayoutBox.h" +#include "YMenuBar.h" +#include "YSquash.h" +#include "YWidgetFactory.h" +#include "YShortcut.h" +#include "YEvent.h" + + +using std::string; + + +// Widgets + +YDialog * dialog = 0; +YLabel * lastEventLabel = 0; + + +// Menus and Menu Items + +YMenuItem * fileMenu = 0; +YMenuItem * editMenu = 0; +YMenuItem * viewMenu = 0; +YMenuItem * optionsMenu = 0; + + +// "File" menu + +YMenuItem * actionOpen = 0; +YMenuItem * actionSave = 0; +YMenuItem * actionSaveAs = 0; +YMenuItem * actionQuit = 0; + + +// "Edit" menu + +YMenuItem * actionCut = 0; +YMenuItem * actionCopy = 0; +YMenuItem * actionPaste = 0; + + +// "View" menu + +YMenuItem * actionViewNormal = 0; +YMenuItem * actionViewCompact = 0; +YMenuItem * actionViewDetailed = 0; + + +// "View" -> "Zoom" submenu + +YMenuItem * zoomMenu = 0; +YMenuItem * actionZoomIn = 0; +YMenuItem * actionZoomOut = 0; +YMenuItem * actionZoomDefault = 0; + +// "Options" menu + +YMenuItem * actionSettings = 0; + + +// Function Prototypes + +void createWidgets(); +void addMenus( YMenuBar * menuBar ); +void handleEvents(); +void showEvent( YMenuEvent * event ); + + + + +int main( int argc, char **argv ) +{ + YUILog::setLogFileName( "/tmp/libyui-examples.log" ); + YUILog::enableDebugLogging(); + + createWidgets(); + handleEvents(); + + dialog->destroy(); +} + + +/** + * Create the widget tree for the main dialog + **/ +void createWidgets() +{ + yuiMilestone() << endl; + + YWidgetFactory * fac = YUI::widgetFactory(); + + dialog = fac->createPopupDialog(); + YAlignment * minSize = fac->createMinSize( dialog, 50, 20 ); + YLayoutBox * vbox1 = fac->createVBox( minSize ); + YMenuBar * menuBar = fac->createMenuBar( vbox1 ); + + addMenus( menuBar ); + + YAlignment * center = fac->createHVCenter( vbox1 ); + YSquash * squash = fac->createHVSquash( center ); + YLayoutBox * vbox2 = fac->createVBox( squash ); + + YAlignment * left = fac->createLeft( vbox2 ); + fac->createLabel ( left, "Last Event:" ); + fac->createHSpacing( vbox2, 1 ); + lastEventLabel = fac->createOutputField( vbox2, "" ); + lastEventLabel->setStretchable( YD_HORIZ, true ); + fac->createMinWidth( vbox2, 20 ); +} + + +void addMenus( YMenuBar * menuBar ) +{ + // This uses the more generic, but also more clumsy API: + // + // Each object in a menu is just a YMenuItem, no matter if it's a + // menu/submenu, a plain item or a separator. + // + // The difference between a menu and a plain menu item is just that the + // menu has child items whild the plain item does not. A separator is just + // a menu item with an empty label. + // + // For the more elagant and more self-descriptive API, see the MenuBar1.cc + // example. + + fileMenu = new YMenuItem( "&File" ); + editMenu = new YMenuItem( "&Edit" ); + viewMenu = new YMenuItem( "&View" ); + optionsMenu = new YMenuItem( "&Options" ); + + actionOpen = new YMenuItem( fileMenu, "&Open..." ); + actionSave = new YMenuItem( fileMenu, "&Save" ); + actionSaveAs = new YMenuItem( fileMenu, "Save &As..." ); + + new YMenuItem( fileMenu, "" ); // separator + + actionQuit = new YMenuItem( fileMenu, "&Quit" ); + + actionCut = new YMenuItem( editMenu, "C&ut" ); + actionCopy = new YMenuItem( editMenu, "&Copy" ); + actionPaste = new YMenuItem( editMenu, "&Paste" ); + + actionViewNormal = new YMenuItem( viewMenu, "&Normal" ); + actionViewCompact = new YMenuItem( viewMenu, "&Compact" ); + actionViewDetailed = new YMenuItem( viewMenu, "&Detailed" ); + + new YMenuItem( viewMenu, "" ); // separator + + zoomMenu = new YMenuItem( viewMenu, "&Zoom" ); + actionZoomIn = new YMenuItem( zoomMenu, "Zoom &In" ); + actionZoomOut = new YMenuItem( zoomMenu, "Zoom &Out" ); + actionZoomDefault = new YMenuItem( zoomMenu, "Zoom &Default" ); + + actionSettings = new YMenuItem( optionsMenu, "&Settings..." ); + + menuBar->addItem( fileMenu ); + menuBar->addItem( editMenu ); + menuBar->addItem( viewMenu ); + menuBar->addItem( optionsMenu ); + + // Do NOT add all the individual items separately to the menu bar: + // They are owned by their parent menu. + + menuBar->resolveShortcutConflicts(); + menuBar->rebuildMenuTree(); +} + + +/** + * Event loop and event handling for the main dialog + **/ +void handleEvents() +{ + yuiMilestone() << endl; + + while ( true ) + { + YEvent * event = dialog->waitForEvent(); + + if ( event ) + { + if ( event->eventType() == YEvent::CancelEvent ) // window manager "close window" button + { + break; // leave event loop + } + + if ( event->eventType() == YEvent::MenuEvent ) + { + YMenuEvent * menuEvent = dynamic_cast( event ); + + if ( menuEvent ) + { + showEvent( menuEvent ); + + if ( menuEvent->item() == actionQuit ) + break; // leave event loop + } + } + } + } +} + + +/** + * Show the (label of) the item causing a menu event in the 'lastEventLabel' + * widget. + **/ +void showEvent( YMenuEvent * event ) +{ + if ( event && event->item() ) + { + string text = YShortcut::cleanShortcutString( event->item()->label() ); + lastEventLabel->setLabel( text ); + } +} diff --git a/examples/MenuButton1.cc b/examples/MenuButton1.cc index da3a2ac42..a068b5e99 100644 --- a/examples/MenuButton1.cc +++ b/examples/MenuButton1.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2016 SUSE LCC + Copyright (c) [2016-2020] SUSE LCC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the @@ -28,6 +28,9 @@ // // g++ -I/usr/include/yui -lyui MenuButton1.cc -o MenuButton1 +#define YUILogComponent "example" +#include "YUILog.h" + #include "YUI.h" #include "YWidgetFactory.h" #include "YDialog.h" @@ -38,22 +41,32 @@ int main( int argc, char **argv ) { - YDialog * dialog = YUI::widgetFactory()->createPopupDialog(); - YLayoutBox * vbox = YUI::widgetFactory()->createVBox( dialog ); - YUI::widgetFactory()->createLabel( vbox, "Hello, World!" ); - YMenuButton* top = YUI::widgetFactory()->createMenuButton( vbox, "Menu!" ); - YMenuItem *inner_item = new YMenuItem("&menu1"); - top->addItem(inner_item); - top->addItem(new YMenuItem("&menu2")); - top->addItem(new YMenuItem("&Menu3")); // test upper letter as shortcut - top->addItem(new YMenuItem("menu4")); // even without shortcut marker it should find shortcut if possible - new YMenuItem(inner_item, "&submenu1"); - new YMenuItem(inner_item, "&submenu2"); - new YMenuItem(inner_item, "&submenu3"); - new YMenuItem(inner_item, "&submenu4"); - - top->resolveShortcutConflicts(); - top->rebuildMenuTree(); + YUILog::setLogFileName( "/tmp/libyui-examples.log" ); + YUILog::enableDebugLogging(); + + YWidgetFactory * fac = YUI::widgetFactory(); + + YDialog * dialog = fac->createPopupDialog(); + YLayoutBox * vbox = fac->createVBox( dialog ); + fac->createHeading( vbox, " Menu Button Example " ); + fac->createVSpacing( vbox, 1 ); + + YMenuButton * menuButton = fac->createMenuButton( vbox, "Menu" ); + fac->createVSpacing( vbox, 2 ); + + YMenuItem * submenu = menuButton->addMenu( "&menu1" ); + menuButton->addItem( "&menu2" ); + menuButton->addItem( "&Menu3" ); // Test uppercase letter as shortcut + menuButton->addItem( "menu4" ); // Even without a shortcut marker it should find a shortcut if possible + + submenu->addItem( "&submenu1" ); + submenu->addItem( "&submenu2" ); + submenu->addSeparator(); + submenu->addItem( "&submenu3" ); + submenu->addItem( "&submenu4" ); + + menuButton->resolveShortcutConflicts(); + menuButton->rebuildMenuTree(); dialog->waitForEvent(); dialog->destroy(); diff --git a/src/YMenuBar.cc b/src/YMenuBar.cc index cb2099619..f9d848293 100644 --- a/src/YMenuBar.cc +++ b/src/YMenuBar.cc @@ -63,6 +63,15 @@ YMenuBar::~YMenuBar() } +YMenuItem * +YMenuBar::addMenu( const std::string & label, + const std::string & iconName ) +{ + YMenuItem * menu = new YMenuItem( label, iconName ); + addItem( menu ); + + return menu; +} const YPropertySet & diff --git a/src/YMenuBar.h b/src/YMenuBar.h index 8ece41ec0..72da1bb90 100644 --- a/src/YMenuBar.h +++ b/src/YMenuBar.h @@ -62,6 +62,12 @@ class YMenuBar: public YMenuWidget **/ virtual ~YMenuBar(); + /** + * Create a new menu and add it. + **/ + YMenuItem * addMenu( const std::string & label, + const std::string & iconName = "" ); + /** * Returns a descriptive name of this widget class for logging, * debugging etc. diff --git a/src/YMenuButton.cc b/src/YMenuButton.cc index 5c07749f1..c434b2a97 100644 --- a/src/YMenuButton.cc +++ b/src/YMenuButton.cc @@ -29,7 +29,6 @@ #include "YUISymbols.h" #include "YMenuButton.h" #include "YMenuItem.h" -#include "YShortcut.h" using std::string; @@ -59,6 +58,38 @@ YMenuButton::~YMenuButton() } +YMenuItem * +YMenuButton::addItem( const std::string & label, + const std::string & iconName ) +{ + YMenuItem * item = new YMenuItem( label, iconName ); + YMenuWidget::addItem( item ); + + return item; +} + + +YMenuItem * +YMenuButton::addMenu( const std::string & label, + const std::string & iconName ) +{ + YMenuItem * menu = new YMenuItem( label, iconName ); + YMenuWidget::addItem( menu ); + + return menu; +} + + +YMenuItem * +YMenuButton::addSeparator() +{ + YMenuItem * separator = new YMenuItem( "" ); + YMenuWidget::addItem( separator ); + + return separator; +} + + const YPropertySet & YMenuButton::propertySet() { diff --git a/src/YMenuButton.h b/src/YMenuButton.h index 38012659d..fbea5a6fb 100644 --- a/src/YMenuButton.h +++ b/src/YMenuButton.h @@ -62,6 +62,23 @@ class YMenuButton : public YMenuWidget **/ virtual ~YMenuButton(); + /** + * Create a new menu item and add it. + **/ + YMenuItem * addItem( const std::string & label, + const std::string & iconName = "" ); + + /** + * Create a new submenu and add it. + **/ + YMenuItem * addMenu( const std::string & label, + const std::string & iconName = "" ); + + /** + * Create a new menu separator and add it. + **/ + YMenuItem * addSeparator(); + /** * Returns a descriptive name of this widget class for logging, * debugging etc. diff --git a/src/YMenuItem.cc b/src/YMenuItem.cc new file mode 100644 index 000000000..c3b40e43f --- /dev/null +++ b/src/YMenuItem.cc @@ -0,0 +1,46 @@ +/* + 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: YMenuItem.cc + + Author: Stefan Hundhammer + +/-*/ + + +#include "YMenuItem.h" + + +YMenuItem * YMenuItem::addItem( const std::string & label, + const std::string & iconName ) +{ + return new YMenuItem( this, label, iconName ); +} + + +YMenuItem * YMenuItem::addMenu( const std::string & label, + const std::string & iconName ) +{ + return new YMenuItem( this, label, iconName ); +} + + +YMenuItem * YMenuItem::addSeparator() +{ + return new YMenuItem( this, "" ); +} diff --git a/src/YMenuItem.h b/src/YMenuItem.h index 9778e3c29..bbf8a42ab 100644 --- a/src/YMenuItem.h +++ b/src/YMenuItem.h @@ -1,5 +1,6 @@ /* - Copyright (C) 2000-2012 Novell, Inc + Copyright (C) 2000-2018 Novell, Inc + Copyright (c) [2019-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 @@ -31,19 +32,22 @@ /** * Item class for menu items. + * + * This is used for plain menu items as well as for menus as well as for menu + * separators: + * + * A menu is a menu item with child items. + * A plain menu item does not have child items. + * A menu separator has an empty label. **/ class YMenuItem: public YTreeItem { public: /** - * Constructors for toplevel items. + * Constructor for toplevel items. **/ - YMenuItem( const std::string & label ) - : YTreeItem( label ) - {} - YMenuItem( const std::string & label, - const std::string & iconName ) + const std::string & iconName = "" ) : YTreeItem( label, iconName ) {} @@ -53,18 +57,16 @@ class YMenuItem: public YTreeItem * They will automatically register this item with the parent item. The * parent assumes ownership of this item and will delete it in its (the * parent's) destructor. + * + * Consider using addItem() or addMenu() instead. **/ - YMenuItem( YMenuItem * parent, - const std::string & label ) - : YTreeItem( parent, label ) - {} - YMenuItem( YMenuItem * parent, const std::string & label, - const std::string & iconName ) + const std::string & iconName = "" ) : YTreeItem( parent, label, iconName ) {} + /** * Destructor. * @@ -72,6 +74,27 @@ class YMenuItem: public YTreeItem **/ virtual ~YMenuItem() {} + /** + * Create a new menu item as a child of the current instance and return it. + * The newly created object is owned by this instance. + * This is meant for plain menu items, not for submenus. + **/ + YMenuItem * addItem( const std::string & label, + const std::string & iconName = "" ); + + /** + * Create a new submenu as a child of the current instance and return it. + * The newly created object is owned by this instance. + * This is meant to be used for menu items that have children. + **/ + YMenuItem * addMenu( const std::string & label, + const std::string & iconName = "" ); + + /** + * Create a menu separator as a child of the current instance and return it. + * The newly created object is owned by this instance. + **/ + YMenuItem * addSeparator(); /** * Returns this item's parent item or 0 if it is a toplevel item. @@ -79,6 +102,24 @@ class YMenuItem: public YTreeItem YMenuItem * parent() const { return dynamic_cast ( YTreeItem::parent() ); } + /** + * Return 'true' if this is a menu (or submenu), i.e. if it has any child + * items. + **/ + bool isMenu() const { return hasChildren(); } + + /** + * Return 'true' if this is a menu separator, i.e. if it has an empty label. + **/ + bool isSeparator() const { return label().empty(); } + + /** + * Create a menu separator item and return it. The new separator is owned + * by 'parent'. + **/ + static YMenuItem * createSeparator( YMenuItem * parent) + { return new YMenuItem( parent, "" ); } + private: diff --git a/src/YMenuWidget.h b/src/YMenuWidget.h index a1f7b059d..cae0b4f3e 100644 --- a/src/YMenuWidget.h +++ b/src/YMenuWidget.h @@ -90,11 +90,8 @@ class YMenuWidget: public YSelectionWidget * items in this MenuButton. That index can be used later with * findMenuItem() to find the item by that index. * - * @note please do not forget to call after adding all elements - * #resolveShortcutConflicts and #rebuildMenuTree in this order. It is - * important to call it after all submenus are added, otherwise it won't - * have proper shortcuts and won't be rendered. - * @see examples/MenuButton.cc. + * @note Do not forget to call #resolveShortcutConflicts and + * #rebuildMenuTree (in this order!) after adding all elements. * * Reimplemented from YSelectionWidget. **/ From 680858801b5e1295b48e5c21e14b5255e4773d45 Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Mon, 13 Jul 2020 17:46:54 +0200 Subject: [PATCH 08/13] Examples fine tuning --- examples/MenuBar1.cc | 7 +++---- examples/MenuBar2.cc | 7 +++---- src/YMenuBar.h | 9 --------- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/examples/MenuBar1.cc b/examples/MenuBar1.cc index 0a647ce2f..0f07a1c76 100644 --- a/examples/MenuBar1.cc +++ b/examples/MenuBar1.cc @@ -130,10 +130,9 @@ void createWidgets() YAlignment * left = fac->createLeft( vbox2 ); fac->createLabel ( left, "Last Event:" ); - fac->createHSpacing( vbox2, 1 ); - lastEventLabel = fac->createOutputField( vbox2, "" ); - lastEventLabel->setStretchable( YD_HORIZ, true ); - fac->createMinWidth( vbox2, 20 ); + fac->createVSpacing( vbox2, 0.2 ); + YAlignment * minWidth = fac->createMinWidth( vbox2, 15 ); + lastEventLabel = fac->createOutputField( minWidth, "" ); } diff --git a/examples/MenuBar2.cc b/examples/MenuBar2.cc index 90537a4aa..57f91ff14 100644 --- a/examples/MenuBar2.cc +++ b/examples/MenuBar2.cc @@ -130,10 +130,9 @@ void createWidgets() YAlignment * left = fac->createLeft( vbox2 ); fac->createLabel ( left, "Last Event:" ); - fac->createHSpacing( vbox2, 1 ); - lastEventLabel = fac->createOutputField( vbox2, "" ); - lastEventLabel->setStretchable( YD_HORIZ, true ); - fac->createMinWidth( vbox2, 20 ); + fac->createVSpacing( vbox2, 0.2 ); + YAlignment * minWidth = fac->createMinWidth( vbox2, 15 ); + lastEventLabel = fac->createOutputField( minWidth, "" ); } diff --git a/src/YMenuBar.h b/src/YMenuBar.h index 72da1bb90..9a8a89ec2 100644 --- a/src/YMenuBar.h +++ b/src/YMenuBar.h @@ -104,15 +104,6 @@ class YMenuBar: public YMenuWidget virtual const YPropertySet & propertySet(); -protected: - - /** - * Check if all toplevel items are really menus, i.e. YMenuItems that have - * children. This may throw a YUIException. - **/ - void sanityCheck(); - - private: ImplPtr priv; From 0fc350e51173bdabe9623fd04648dc17eb197ff2 Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Tue, 14 Jul 2020 10:44:41 +0200 Subject: [PATCH 09/13] Added new widget property --- src/YUISymbols.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/YUISymbols.h b/src/YUISymbols.h index 44acefa86..b9365a296 100644 --- a/src/YUISymbols.h +++ b/src/YUISymbols.h @@ -1,6 +1,6 @@ /* Copyright (C) 2000-2012 Novell, Inc - Copyright (C) 2019 SUSE LLC + Copyright (C) 2019-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 @@ -174,6 +174,7 @@ #define YUIProperty_DebugLabel "DebugLabel" #define YUIProperty_EasterEgg "EasterEgg" #define YUIProperty_Enabled "Enabled" +#define YUIProperty_EnabledItems "EnabledItems" #define YUIProperty_ExpectedSize "ExpectedSize" #define YUIProperty_Filename "Filename" #define YUIProperty_Layout "Layout" From 411eadc07b7a2707ef5da485eda7e151db2230cd Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Tue, 14 Jul 2020 10:47:16 +0200 Subject: [PATCH 10/13] Fixed outdated old e-mail address --- src/TreeItem.h | 2 +- src/YAlignment.cc | 2 +- src/YAlignment.h | 2 +- src/YApplication.cc | 2 +- src/YApplication.h | 2 +- src/YBarGraph.cc | 2 +- src/YBarGraph.h | 2 +- src/YBothDim.h | 2 +- src/YBuiltinCaller.h | 2 +- src/YButtonBox.cc | 2 +- src/YButtonBox.h | 2 +- src/YCheckBox.cc | 2 +- src/YCheckBox.h | 2 +- src/YCheckBoxFrame.cc | 2 +- src/YCheckBoxFrame.h | 2 +- src/YChildrenManager.h | 2 +- src/YColor.h | 2 +- src/YComboBox.cc | 2 +- src/YComboBox.h | 2 +- src/YCommandLine.cc | 2 +- src/YCommandLine.h | 2 +- src/YContextMenu.h | 2 +- src/YDateField.cc | 2 +- src/YDateField.h | 2 +- src/YDialog.cc | 2 +- src/YDialog.h | 2 +- src/YDialogSpy.cc | 2 +- src/YDialogSpy.h | 2 +- src/YDownloadProgress.cc | 2 +- src/YDownloadProgress.h | 2 +- src/YDumbTab.cc | 2 +- src/YDumbTab.h | 2 +- src/YEmpty.cc | 2 +- src/YEmpty.h | 2 +- src/YEnvVar.cc | 2 +- src/YEnvVar.h | 2 +- src/YEvent.cc | 2 +- src/YEvent.h | 2 +- src/YEventFilter.cc | 2 +- src/YEventFilter.h | 2 +- src/YFrame.cc | 2 +- src/YFrame.h | 2 +- src/YImage.cc | 2 +- src/YImage.h | 2 +- src/YInputField.cc | 2 +- src/YInputField.h | 2 +- src/YIntField.cc | 2 +- src/YIntField.h | 2 +- src/YItem.cc | 2 +- src/YItem.h | 2 +- src/YLabel.cc | 2 +- src/YLabel.h | 2 +- src/YLayoutBox.cc | 2 +- src/YLayoutBox.h | 2 +- src/YLogView.cc | 2 +- src/YLogView.h | 2 +- src/YMacro.cc | 2 +- src/YMacro.h | 2 +- src/YMacroPlayer.h | 2 +- src/YMacroRecorder.h | 2 +- src/YMenuButton.cc | 2 +- src/YMenuButton.h | 2 +- src/YMenuItem.cc | 2 +- src/YMenuItem.h | 2 +- src/YMultiLineEdit.cc | 2 +- src/YMultiLineEdit.h | 2 +- src/YMultiProgressMeter.cc | 2 +- src/YMultiProgressMeter.h | 2 +- src/YMultiSelectionBox.cc | 2 +- src/YMultiSelectionBox.h | 2 +- src/YOptionalWidgetFactory.cc | 2 +- src/YOptionalWidgetFactory.h | 2 +- src/YPackageSelector.cc | 2 +- src/YPackageSelector.h | 2 +- src/YPackageSelectorPlugin.h | 2 +- src/YPartitionSplitter.cc | 2 +- src/YPartitionSplitter.h | 2 +- src/YProgressBar.cc | 2 +- src/YProgressBar.h | 2 +- src/YProperty.cc | 2 +- src/YProperty.h | 2 +- src/YPushButton.cc | 2 +- src/YPushButton.h | 2 +- src/YRadioButton.cc | 2 +- src/YRadioButton.h | 2 +- src/YRadioButtonGroup.cc | 2 +- src/YRadioButtonGroup.h | 2 +- src/YReplacePoint.cc | 2 +- src/YReplacePoint.h | 2 +- src/YRichText.cc | 2 +- src/YRichText.h | 2 +- src/YRpmGroupsTree.cc | 2 +- src/YRpmGroupsTree.h | 2 +- src/YSelectionBox.cc | 2 +- src/YSelectionBox.h | 2 +- src/YSelectionWidget.h | 2 +- src/YShortcut.cc | 2 +- src/YShortcut.h | 2 +- src/YShortcutManager.cc | 2 +- src/YShortcutManager.h | 2 +- src/YSimpleEventHandler.cc | 2 +- src/YSimpleEventHandler.h | 2 +- src/YSimpleInputField.cc | 2 +- src/YSimpleInputField.h | 2 +- src/YSingleChildContainerWidget.cc | 2 +- src/YSingleChildContainerWidget.h | 2 +- src/YSlider.cc | 2 +- src/YSlider.h | 2 +- src/YSpacing.cc | 2 +- src/YSpacing.h | 2 +- src/YSquash.cc | 2 +- src/YSquash.h | 2 +- src/YStringTree.cc | 2 +- src/YStringTree.h | 2 +- src/YTable.cc | 2 +- src/YTable.h | 2 +- src/YTableHeader.cc | 2 +- src/YTableHeader.h | 2 +- src/YTableItem.cc | 2 +- src/YTableItem.h | 2 +- src/YTimeField.cc | 2 +- src/YTimeField.h | 2 +- src/YTransText.h | 2 +- src/YTree.cc | 2 +- src/YTree.h | 2 +- src/YTreeItem.cc | 2 +- src/YTreeItem.h | 2 +- src/YTypes.h | 2 +- src/YUI.cc | 2 +- src/YUI.h | 2 +- src/YUIException.cc | 2 +- src/YUIException.h | 2 +- src/YUILoader.cc | 2 +- src/YUILoader.h | 2 +- src/YUILog.cc | 2 +- src/YUILog.h | 2 +- src/YUIPlugin.cc | 2 +- src/YUIPlugin.h | 2 +- src/YUISymbols.h | 2 +- src/YWidget.cc | 2 +- src/YWidget.h | 2 +- src/YWidgetFactory.cc | 2 +- src/YWidgetFactory.h | 2 +- src/YWidgetID.cc | 2 +- src/YWidgetID.h | 2 +- src/YWizard.cc | 2 +- src/YWizard.h | 2 +- 147 files changed, 147 insertions(+), 147 deletions(-) diff --git a/src/TreeItem.h b/src/TreeItem.h index 8780f49ee..d58a84490 100644 --- a/src/TreeItem.h +++ b/src/TreeItem.h @@ -18,7 +18,7 @@ File: TreeItem.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YAlignment.cc b/src/YAlignment.cc index a55652673..61c683dc0 100644 --- a/src/YAlignment.cc +++ b/src/YAlignment.cc @@ -18,7 +18,7 @@ File: YAlignment.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YAlignment.h b/src/YAlignment.h index d716c771e..be55438f1 100644 --- a/src/YAlignment.h +++ b/src/YAlignment.h @@ -18,7 +18,7 @@ File: YAlignment.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YApplication.cc b/src/YApplication.cc index daff48a95..56177a404 100644 --- a/src/YApplication.cc +++ b/src/YApplication.cc @@ -18,7 +18,7 @@ File: YApplication.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YApplication.h b/src/YApplication.h index 5553aa5e4..37d8d0640 100644 --- a/src/YApplication.h +++ b/src/YApplication.h @@ -18,7 +18,7 @@ File: YApplication.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YBarGraph.cc b/src/YBarGraph.cc index cdb44df0f..ae35f9e80 100644 --- a/src/YBarGraph.cc +++ b/src/YBarGraph.cc @@ -18,7 +18,7 @@ File: YBarGraph.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YBarGraph.h b/src/YBarGraph.h index 29f7f26b8..b95e2dde9 100644 --- a/src/YBarGraph.h +++ b/src/YBarGraph.h @@ -18,7 +18,7 @@ File: YBarGraph.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YBothDim.h b/src/YBothDim.h index 9c44058ab..4ac2e4f0f 100644 --- a/src/YBothDim.h +++ b/src/YBothDim.h @@ -18,7 +18,7 @@ File: YBothDim.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YBuiltinCaller.h b/src/YBuiltinCaller.h index 2949b4901..eac9d3ded 100644 --- a/src/YBuiltinCaller.h +++ b/src/YBuiltinCaller.h @@ -18,7 +18,7 @@ File: YBuiltinCaller.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YButtonBox.cc b/src/YButtonBox.cc index d430bd843..599d3174d 100644 --- a/src/YButtonBox.cc +++ b/src/YButtonBox.cc @@ -18,7 +18,7 @@ File: YButtonBox.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YButtonBox.h b/src/YButtonBox.h index 84f8dbbf2..71f39392f 100644 --- a/src/YButtonBox.h +++ b/src/YButtonBox.h @@ -18,7 +18,7 @@ File: YButtonBox.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YCheckBox.cc b/src/YCheckBox.cc index 26d980797..917dbc15b 100644 --- a/src/YCheckBox.cc +++ b/src/YCheckBox.cc @@ -18,7 +18,7 @@ File: YCheckBox.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YCheckBox.h b/src/YCheckBox.h index 793cc778e..d62da1e1d 100644 --- a/src/YCheckBox.h +++ b/src/YCheckBox.h @@ -18,7 +18,7 @@ File: YCheckBox.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YCheckBoxFrame.cc b/src/YCheckBoxFrame.cc index 6fa769c9b..5ad3b5884 100644 --- a/src/YCheckBoxFrame.cc +++ b/src/YCheckBoxFrame.cc @@ -18,7 +18,7 @@ File: YCheckBoxFrame.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YCheckBoxFrame.h b/src/YCheckBoxFrame.h index 243f1a044..edf10d18b 100644 --- a/src/YCheckBoxFrame.h +++ b/src/YCheckBoxFrame.h @@ -18,7 +18,7 @@ File: YCheckBoxFrame.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YChildrenManager.h b/src/YChildrenManager.h index a2801607e..8fbcea77e 100644 --- a/src/YChildrenManager.h +++ b/src/YChildrenManager.h @@ -18,7 +18,7 @@ File: YChildrenManager.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YColor.h b/src/YColor.h index 4ea89f95d..f1a3e2e58 100644 --- a/src/YColor.h +++ b/src/YColor.h @@ -18,7 +18,7 @@ File: YColor.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YComboBox.cc b/src/YComboBox.cc index 6697424ee..955e2ae4b 100644 --- a/src/YComboBox.cc +++ b/src/YComboBox.cc @@ -18,7 +18,7 @@ File: YComboBox.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YComboBox.h b/src/YComboBox.h index 416359a5d..8f4321784 100644 --- a/src/YComboBox.h +++ b/src/YComboBox.h @@ -18,7 +18,7 @@ File: YComboBox.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YCommandLine.cc b/src/YCommandLine.cc index 2f1c3f1ef..482f0b2c4 100644 --- a/src/YCommandLine.cc +++ b/src/YCommandLine.cc @@ -18,7 +18,7 @@ File: YCommandLine.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YCommandLine.h b/src/YCommandLine.h index 70cb4fe82..b372e6b7b 100644 --- a/src/YCommandLine.h +++ b/src/YCommandLine.h @@ -18,7 +18,7 @@ File: YCommandLine.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YContextMenu.h b/src/YContextMenu.h index a4acb1cda..7e1eb1157 100644 --- a/src/YContextMenu.h +++ b/src/YContextMenu.h @@ -18,7 +18,7 @@ File: YContextMenu.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YDateField.cc b/src/YDateField.cc index d20e68555..86320112d 100644 --- a/src/YDateField.cc +++ b/src/YDateField.cc @@ -18,7 +18,7 @@ File: YDateField.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YDateField.h b/src/YDateField.h index e5a468d36..81e0b0b2f 100644 --- a/src/YDateField.h +++ b/src/YDateField.h @@ -18,7 +18,7 @@ File: YDateField.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YDialog.cc b/src/YDialog.cc index 7ef45efbe..9e3f03d3e 100644 --- a/src/YDialog.cc +++ b/src/YDialog.cc @@ -18,7 +18,7 @@ File: YDialog.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YDialog.h b/src/YDialog.h index b381e0a70..ade822a04 100644 --- a/src/YDialog.h +++ b/src/YDialog.h @@ -18,7 +18,7 @@ File: YDialog.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YDialogSpy.cc b/src/YDialogSpy.cc index 78cc9d95f..59dfce723 100644 --- a/src/YDialogSpy.cc +++ b/src/YDialogSpy.cc @@ -18,7 +18,7 @@ File: YDialogSpy.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YDialogSpy.h b/src/YDialogSpy.h index 9cfaa682c..c10b6f145 100644 --- a/src/YDialogSpy.h +++ b/src/YDialogSpy.h @@ -18,7 +18,7 @@ File: YDialogSpy.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YDownloadProgress.cc b/src/YDownloadProgress.cc index e531c45d9..571c3293b 100644 --- a/src/YDownloadProgress.cc +++ b/src/YDownloadProgress.cc @@ -18,7 +18,7 @@ File: YDownloadProgress.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YDownloadProgress.h b/src/YDownloadProgress.h index c47ec4f83..f75cd01a3 100644 --- a/src/YDownloadProgress.h +++ b/src/YDownloadProgress.h @@ -18,7 +18,7 @@ File: YDownloadProgress.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YDumbTab.cc b/src/YDumbTab.cc index c23c87e91..0efbb0b90 100644 --- a/src/YDumbTab.cc +++ b/src/YDumbTab.cc @@ -18,7 +18,7 @@ File: YDumbTab.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YDumbTab.h b/src/YDumbTab.h index 734ea040b..52d22bf42 100644 --- a/src/YDumbTab.h +++ b/src/YDumbTab.h @@ -18,7 +18,7 @@ File: YDumbTab.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YEmpty.cc b/src/YEmpty.cc index f5362c930..de3c48c25 100644 --- a/src/YEmpty.cc +++ b/src/YEmpty.cc @@ -18,7 +18,7 @@ File: YEmpty.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YEmpty.h b/src/YEmpty.h index 9a3cb3603..82b736119 100644 --- a/src/YEmpty.h +++ b/src/YEmpty.h @@ -18,7 +18,7 @@ File: YEmpty.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YEnvVar.cc b/src/YEnvVar.cc index fb3dbee03..f64ee2d2c 100644 --- a/src/YEnvVar.cc +++ b/src/YEnvVar.cc @@ -18,7 +18,7 @@ File: YEnvVar.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YEnvVar.h b/src/YEnvVar.h index fa24535dd..fe00b8f6a 100644 --- a/src/YEnvVar.h +++ b/src/YEnvVar.h @@ -18,7 +18,7 @@ File: YEnvVar.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YEvent.cc b/src/YEvent.cc index dd51d7d0c..a9af470c6 100644 --- a/src/YEvent.cc +++ b/src/YEvent.cc @@ -18,7 +18,7 @@ File: YEvent.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YEvent.h b/src/YEvent.h index 192b3394b..d7a6dac9e 100644 --- a/src/YEvent.h +++ b/src/YEvent.h @@ -18,7 +18,7 @@ File: YEvent.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YEventFilter.cc b/src/YEventFilter.cc index ac163e83f..226a6edae 100644 --- a/src/YEventFilter.cc +++ b/src/YEventFilter.cc @@ -18,7 +18,7 @@ File: YEventFilter.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YEventFilter.h b/src/YEventFilter.h index 3dc180370..c79d8d76a 100644 --- a/src/YEventFilter.h +++ b/src/YEventFilter.h @@ -18,7 +18,7 @@ File: YEventFilter.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YFrame.cc b/src/YFrame.cc index 834fedac0..35de49f2a 100644 --- a/src/YFrame.cc +++ b/src/YFrame.cc @@ -18,7 +18,7 @@ File: YFrame.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YFrame.h b/src/YFrame.h index 111e8ec8b..004765c82 100644 --- a/src/YFrame.h +++ b/src/YFrame.h @@ -18,7 +18,7 @@ File: YFrame.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YImage.cc b/src/YImage.cc index a533a90e3..26992a7fa 100644 --- a/src/YImage.cc +++ b/src/YImage.cc @@ -18,7 +18,7 @@ File: YImage.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YImage.h b/src/YImage.h index 17bea2174..5744c6e46 100644 --- a/src/YImage.h +++ b/src/YImage.h @@ -18,7 +18,7 @@ File: YImage.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YInputField.cc b/src/YInputField.cc index 086f3d577..bcaec1d07 100644 --- a/src/YInputField.cc +++ b/src/YInputField.cc @@ -18,7 +18,7 @@ File: YInputField.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YInputField.h b/src/YInputField.h index 70641cef2..494f22142 100644 --- a/src/YInputField.h +++ b/src/YInputField.h @@ -18,7 +18,7 @@ File: YInputField.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YIntField.cc b/src/YIntField.cc index 97d00045e..58fcc6051 100644 --- a/src/YIntField.cc +++ b/src/YIntField.cc @@ -18,7 +18,7 @@ File: YIntField.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YIntField.h b/src/YIntField.h index 9da053771..eaa5bdd7d 100644 --- a/src/YIntField.h +++ b/src/YIntField.h @@ -18,7 +18,7 @@ File: YIntField.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YItem.cc b/src/YItem.cc index 88a1588c6..6499a76a9 100644 --- a/src/YItem.cc +++ b/src/YItem.cc @@ -18,7 +18,7 @@ File: YItem.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YItem.h b/src/YItem.h index 49b42ef20..d377f7d15 100644 --- a/src/YItem.h +++ b/src/YItem.h @@ -18,7 +18,7 @@ File: YItem.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YLabel.cc b/src/YLabel.cc index 81734c4f9..95e2e1370 100644 --- a/src/YLabel.cc +++ b/src/YLabel.cc @@ -18,7 +18,7 @@ File: YLabel.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YLabel.h b/src/YLabel.h index 4114a76c7..5fe2825eb 100644 --- a/src/YLabel.h +++ b/src/YLabel.h @@ -18,7 +18,7 @@ File: YLabel.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YLayoutBox.cc b/src/YLayoutBox.cc index b62815f1f..640b27e81 100644 --- a/src/YLayoutBox.cc +++ b/src/YLayoutBox.cc @@ -18,7 +18,7 @@ File: YLayoutBox.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YLayoutBox.h b/src/YLayoutBox.h index e652a4530..1e62c5f0d 100644 --- a/src/YLayoutBox.h +++ b/src/YLayoutBox.h @@ -18,7 +18,7 @@ File: YLayoutBox.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YLogView.cc b/src/YLogView.cc index ca33969a9..22a568803 100644 --- a/src/YLogView.cc +++ b/src/YLogView.cc @@ -18,7 +18,7 @@ File: YLogView.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YLogView.h b/src/YLogView.h index 53fb9eeda..72c651e58 100644 --- a/src/YLogView.h +++ b/src/YLogView.h @@ -18,7 +18,7 @@ File: YLogView.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMacro.cc b/src/YMacro.cc index 7618bcbc5..37111ce59 100644 --- a/src/YMacro.cc +++ b/src/YMacro.cc @@ -18,7 +18,7 @@ File: YMacro.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMacro.h b/src/YMacro.h index 7efd1c8aa..cb58cfb73 100644 --- a/src/YMacro.h +++ b/src/YMacro.h @@ -18,7 +18,7 @@ File: YMacro.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMacroPlayer.h b/src/YMacroPlayer.h index 494167905..4414650cd 100644 --- a/src/YMacroPlayer.h +++ b/src/YMacroPlayer.h @@ -18,7 +18,7 @@ File: YMacroPlayer.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMacroRecorder.h b/src/YMacroRecorder.h index c072a206c..146652835 100644 --- a/src/YMacroRecorder.h +++ b/src/YMacroRecorder.h @@ -18,7 +18,7 @@ File: YMacroRecorder.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMenuButton.cc b/src/YMenuButton.cc index c434b2a97..66a47a4b7 100644 --- a/src/YMenuButton.cc +++ b/src/YMenuButton.cc @@ -18,7 +18,7 @@ File: YMenuButton.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMenuButton.h b/src/YMenuButton.h index fbea5a6fb..226c37250 100644 --- a/src/YMenuButton.h +++ b/src/YMenuButton.h @@ -18,7 +18,7 @@ File: YMenuButton.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMenuItem.cc b/src/YMenuItem.cc index c3b40e43f..e3a2da91d 100644 --- a/src/YMenuItem.cc +++ b/src/YMenuItem.cc @@ -18,7 +18,7 @@ File: YMenuItem.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMenuItem.h b/src/YMenuItem.h index bbf8a42ab..a3241198c 100644 --- a/src/YMenuItem.h +++ b/src/YMenuItem.h @@ -19,7 +19,7 @@ File: YMenuItem.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMultiLineEdit.cc b/src/YMultiLineEdit.cc index 56e0e13ea..b4292acf8 100644 --- a/src/YMultiLineEdit.cc +++ b/src/YMultiLineEdit.cc @@ -18,7 +18,7 @@ File: YMultiLineEdit.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMultiLineEdit.h b/src/YMultiLineEdit.h index c52a6ae81..2c0766a2d 100644 --- a/src/YMultiLineEdit.h +++ b/src/YMultiLineEdit.h @@ -18,7 +18,7 @@ File: YMultiLineEdit.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMultiProgressMeter.cc b/src/YMultiProgressMeter.cc index ba6a0ed93..3d5fc62c8 100644 --- a/src/YMultiProgressMeter.cc +++ b/src/YMultiProgressMeter.cc @@ -18,7 +18,7 @@ File: YMultiProgressMeter.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMultiProgressMeter.h b/src/YMultiProgressMeter.h index 57c758d95..9cf663f9f 100644 --- a/src/YMultiProgressMeter.h +++ b/src/YMultiProgressMeter.h @@ -18,7 +18,7 @@ File: YMultiProgressMeter.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMultiSelectionBox.cc b/src/YMultiSelectionBox.cc index 978a34339..57977f1c4 100644 --- a/src/YMultiSelectionBox.cc +++ b/src/YMultiSelectionBox.cc @@ -18,7 +18,7 @@ File: YMultiSelectionBox.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YMultiSelectionBox.h b/src/YMultiSelectionBox.h index bbe5a2068..ef0f0e4f8 100644 --- a/src/YMultiSelectionBox.h +++ b/src/YMultiSelectionBox.h @@ -18,7 +18,7 @@ File: YSelectionBox.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YOptionalWidgetFactory.cc b/src/YOptionalWidgetFactory.cc index f111f4be2..7bf536218 100644 --- a/src/YOptionalWidgetFactory.cc +++ b/src/YOptionalWidgetFactory.cc @@ -18,7 +18,7 @@ File: YOptionalWidgetFactory.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YOptionalWidgetFactory.h b/src/YOptionalWidgetFactory.h index c4da002c6..40e9a2c9c 100644 --- a/src/YOptionalWidgetFactory.h +++ b/src/YOptionalWidgetFactory.h @@ -18,7 +18,7 @@ File: YOptionalWidgetFactory.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YPackageSelector.cc b/src/YPackageSelector.cc index 79f20a88b..e3dd1f8c8 100644 --- a/src/YPackageSelector.cc +++ b/src/YPackageSelector.cc @@ -18,7 +18,7 @@ File: YPackageSelector.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YPackageSelector.h b/src/YPackageSelector.h index 942767b97..e5f476a7c 100644 --- a/src/YPackageSelector.h +++ b/src/YPackageSelector.h @@ -18,7 +18,7 @@ File: YPackageSelector.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YPackageSelectorPlugin.h b/src/YPackageSelectorPlugin.h index 7336f5b7e..de9c1f636 100644 --- a/src/YPackageSelectorPlugin.h +++ b/src/YPackageSelectorPlugin.h @@ -18,7 +18,7 @@ File: YPackageSelectorPlugin.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YPartitionSplitter.cc b/src/YPartitionSplitter.cc index e71174d39..7f728ae86 100644 --- a/src/YPartitionSplitter.cc +++ b/src/YPartitionSplitter.cc @@ -18,7 +18,7 @@ File: YPartitionSplitter.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YPartitionSplitter.h b/src/YPartitionSplitter.h index 2839bbc68..0c14de8f1 100644 --- a/src/YPartitionSplitter.h +++ b/src/YPartitionSplitter.h @@ -18,7 +18,7 @@ File: YPartitionSplitter.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YProgressBar.cc b/src/YProgressBar.cc index 2961b2ef6..e62fd21d0 100644 --- a/src/YProgressBar.cc +++ b/src/YProgressBar.cc @@ -18,7 +18,7 @@ File: YProgressBar.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YProgressBar.h b/src/YProgressBar.h index 718352f23..b6f7099fd 100644 --- a/src/YProgressBar.h +++ b/src/YProgressBar.h @@ -18,7 +18,7 @@ File: YProgressBar.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YProperty.cc b/src/YProperty.cc index 0a8722a3d..be0cb6945 100644 --- a/src/YProperty.cc +++ b/src/YProperty.cc @@ -18,7 +18,7 @@ File: YProperty.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YProperty.h b/src/YProperty.h index 0bba5fdaa..8007712f9 100644 --- a/src/YProperty.h +++ b/src/YProperty.h @@ -18,7 +18,7 @@ File: YProperty.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YPushButton.cc b/src/YPushButton.cc index 6e87fbd67..8514c9cbd 100644 --- a/src/YPushButton.cc +++ b/src/YPushButton.cc @@ -18,7 +18,7 @@ File: YPushButton.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YPushButton.h b/src/YPushButton.h index c2e2a9669..2d5a0fa38 100644 --- a/src/YPushButton.h +++ b/src/YPushButton.h @@ -18,7 +18,7 @@ File: YPushButton.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YRadioButton.cc b/src/YRadioButton.cc index f93b378e5..ba76d9606 100644 --- a/src/YRadioButton.cc +++ b/src/YRadioButton.cc @@ -18,7 +18,7 @@ File: YRadioButton.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YRadioButton.h b/src/YRadioButton.h index 9dc62de6f..dea67b8a6 100644 --- a/src/YRadioButton.h +++ b/src/YRadioButton.h @@ -18,7 +18,7 @@ File: YRadioButton.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YRadioButtonGroup.cc b/src/YRadioButtonGroup.cc index c46d6ee0a..0e36ba602 100644 --- a/src/YRadioButtonGroup.cc +++ b/src/YRadioButtonGroup.cc @@ -18,7 +18,7 @@ File: YRadioButtonGroup.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YRadioButtonGroup.h b/src/YRadioButtonGroup.h index 063a52e6c..a1ee9df9d 100644 --- a/src/YRadioButtonGroup.h +++ b/src/YRadioButtonGroup.h @@ -18,7 +18,7 @@ File: YRadioButtonGroup.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YReplacePoint.cc b/src/YReplacePoint.cc index ffdb525cc..1ffd62454 100644 --- a/src/YReplacePoint.cc +++ b/src/YReplacePoint.cc @@ -18,7 +18,7 @@ File: YReplacePoint.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YReplacePoint.h b/src/YReplacePoint.h index 32f90f4c0..b7686a60c 100644 --- a/src/YReplacePoint.h +++ b/src/YReplacePoint.h @@ -18,7 +18,7 @@ File: YReplacePoint.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YRichText.cc b/src/YRichText.cc index 5eb3da494..387aacfa2 100644 --- a/src/YRichText.cc +++ b/src/YRichText.cc @@ -19,7 +19,7 @@ File: YRichText.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YRichText.h b/src/YRichText.h index 12374ccad..9514182b4 100644 --- a/src/YRichText.h +++ b/src/YRichText.h @@ -19,7 +19,7 @@ File: YRichText.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YRpmGroupsTree.cc b/src/YRpmGroupsTree.cc index 670f3d653..7fc1023d2 100644 --- a/src/YRpmGroupsTree.cc +++ b/src/YRpmGroupsTree.cc @@ -18,7 +18,7 @@ File: YRpmGroupsTree.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YRpmGroupsTree.h b/src/YRpmGroupsTree.h index cfae009e4..6a825dc22 100644 --- a/src/YRpmGroupsTree.h +++ b/src/YRpmGroupsTree.h @@ -18,7 +18,7 @@ File: YRpmGroupsTree.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSelectionBox.cc b/src/YSelectionBox.cc index c55452c84..7764109c0 100644 --- a/src/YSelectionBox.cc +++ b/src/YSelectionBox.cc @@ -18,7 +18,7 @@ File: YSelectionBox.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSelectionBox.h b/src/YSelectionBox.h index f90b85f5d..eb4883eed 100644 --- a/src/YSelectionBox.h +++ b/src/YSelectionBox.h @@ -18,7 +18,7 @@ File: YSelectionBox.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSelectionWidget.h b/src/YSelectionWidget.h index f47c96c25..eca616b93 100644 --- a/src/YSelectionWidget.h +++ b/src/YSelectionWidget.h @@ -18,7 +18,7 @@ File: YSelectionWidget.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YShortcut.cc b/src/YShortcut.cc index 3617722be..289be67de 100644 --- a/src/YShortcut.cc +++ b/src/YShortcut.cc @@ -18,7 +18,7 @@ File: YShortcut.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YShortcut.h b/src/YShortcut.h index 319dfb62d..770ca0ae9 100644 --- a/src/YShortcut.h +++ b/src/YShortcut.h @@ -18,7 +18,7 @@ File: YShortcut.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YShortcutManager.cc b/src/YShortcutManager.cc index 9cb8a08f0..0579e7859 100644 --- a/src/YShortcutManager.cc +++ b/src/YShortcutManager.cc @@ -18,7 +18,7 @@ File: YShortcutManager.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YShortcutManager.h b/src/YShortcutManager.h index e988f7a73..c2b0026bd 100644 --- a/src/YShortcutManager.h +++ b/src/YShortcutManager.h @@ -18,7 +18,7 @@ File: YShortcutManager.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSimpleEventHandler.cc b/src/YSimpleEventHandler.cc index 9312b5ca1..92f51542b 100644 --- a/src/YSimpleEventHandler.cc +++ b/src/YSimpleEventHandler.cc @@ -18,7 +18,7 @@ File: YEvent.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSimpleEventHandler.h b/src/YSimpleEventHandler.h index e8018b779..283f0d699 100644 --- a/src/YSimpleEventHandler.h +++ b/src/YSimpleEventHandler.h @@ -18,7 +18,7 @@ File: YSimpleEventHandler.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSimpleInputField.cc b/src/YSimpleInputField.cc index a07d0fe53..3be09856d 100644 --- a/src/YSimpleInputField.cc +++ b/src/YSimpleInputField.cc @@ -18,7 +18,7 @@ File: YSimpleInputField.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSimpleInputField.h b/src/YSimpleInputField.h index 6d926d4d1..d1dca3bec 100644 --- a/src/YSimpleInputField.h +++ b/src/YSimpleInputField.h @@ -18,7 +18,7 @@ File: YSimpleInputField.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSingleChildContainerWidget.cc b/src/YSingleChildContainerWidget.cc index 82a02cf5d..df40c1f06 100644 --- a/src/YSingleChildContainerWidget.cc +++ b/src/YSingleChildContainerWidget.cc @@ -18,7 +18,7 @@ File: YSingleChildContainerWidget.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSingleChildContainerWidget.h b/src/YSingleChildContainerWidget.h index a28c80557..8f7f157f0 100644 --- a/src/YSingleChildContainerWidget.h +++ b/src/YSingleChildContainerWidget.h @@ -18,7 +18,7 @@ File: YSingleChildContainerWidget.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSlider.cc b/src/YSlider.cc index 0dd2eed87..b40e9c1e6 100644 --- a/src/YSlider.cc +++ b/src/YSlider.cc @@ -18,7 +18,7 @@ File: YSlider.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSlider.h b/src/YSlider.h index d29f6b846..e539f9ddd 100644 --- a/src/YSlider.h +++ b/src/YSlider.h @@ -18,7 +18,7 @@ File: YSlider.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSpacing.cc b/src/YSpacing.cc index 61b846147..cd1ad0263 100644 --- a/src/YSpacing.cc +++ b/src/YSpacing.cc @@ -18,7 +18,7 @@ File: YEmpty.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSpacing.h b/src/YSpacing.h index e8aafd3a4..b8c4d1c4a 100644 --- a/src/YSpacing.h +++ b/src/YSpacing.h @@ -18,7 +18,7 @@ File: YSpacing.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSquash.cc b/src/YSquash.cc index 90c630f3f..9d0332e2a 100644 --- a/src/YSquash.cc +++ b/src/YSquash.cc @@ -18,7 +18,7 @@ File: YSquash.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YSquash.h b/src/YSquash.h index 4bd0fb6c3..4802d5a33 100644 --- a/src/YSquash.h +++ b/src/YSquash.h @@ -18,7 +18,7 @@ File: YSquash.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YStringTree.cc b/src/YStringTree.cc index 8b19cfcd4..43c5c4dbc 100644 --- a/src/YStringTree.cc +++ b/src/YStringTree.cc @@ -18,7 +18,7 @@ File: YStringTree.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YStringTree.h b/src/YStringTree.h index 48cb29dce..0a64a36ae 100644 --- a/src/YStringTree.h +++ b/src/YStringTree.h @@ -18,7 +18,7 @@ File: YStringTree.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTable.cc b/src/YTable.cc index 1352cc1e6..25c1b0acf 100644 --- a/src/YTable.cc +++ b/src/YTable.cc @@ -18,7 +18,7 @@ File: YTable.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTable.h b/src/YTable.h index 762dbba52..2aacb17d5 100644 --- a/src/YTable.h +++ b/src/YTable.h @@ -18,7 +18,7 @@ File: YTable.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTableHeader.cc b/src/YTableHeader.cc index 44cddec41..1c25c2081 100644 --- a/src/YTableHeader.cc +++ b/src/YTableHeader.cc @@ -18,7 +18,7 @@ File: YTableHeader.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTableHeader.h b/src/YTableHeader.h index 70166c2c6..07c48254c 100644 --- a/src/YTableHeader.h +++ b/src/YTableHeader.h @@ -18,7 +18,7 @@ File: YTableHeader.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTableItem.cc b/src/YTableItem.cc index 45e5b11a8..85d2ddc89 100644 --- a/src/YTableItem.cc +++ b/src/YTableItem.cc @@ -18,7 +18,7 @@ File: YTableItem.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTableItem.h b/src/YTableItem.h index 511f6893f..299cd09b4 100644 --- a/src/YTableItem.h +++ b/src/YTableItem.h @@ -18,7 +18,7 @@ File: YTableItem.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTimeField.cc b/src/YTimeField.cc index 930602c12..d16d7a877 100644 --- a/src/YTimeField.cc +++ b/src/YTimeField.cc @@ -18,7 +18,7 @@ File: YTimeField.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTimeField.h b/src/YTimeField.h index ab2f9a3e6..1296dca6a 100644 --- a/src/YTimeField.h +++ b/src/YTimeField.h @@ -18,7 +18,7 @@ File: YTimeField.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTransText.h b/src/YTransText.h index 92f77073c..6285bc729 100644 --- a/src/YTransText.h +++ b/src/YTransText.h @@ -18,7 +18,7 @@ File: YTransText.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTree.cc b/src/YTree.cc index 36e5b5810..0aafad207 100644 --- a/src/YTree.cc +++ b/src/YTree.cc @@ -18,7 +18,7 @@ File: YTree.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTree.h b/src/YTree.h index cdf06f887..815fdef36 100644 --- a/src/YTree.h +++ b/src/YTree.h @@ -18,7 +18,7 @@ File: YTree.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTreeItem.cc b/src/YTreeItem.cc index a90cf8231..2e4047c4e 100644 --- a/src/YTreeItem.cc +++ b/src/YTreeItem.cc @@ -18,7 +18,7 @@ File: YTreeItem.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTreeItem.h b/src/YTreeItem.h index 1f718b97a..f635ec912 100644 --- a/src/YTreeItem.h +++ b/src/YTreeItem.h @@ -18,7 +18,7 @@ File: YTreeItem.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YTypes.h b/src/YTypes.h index fce4fb1d7..1d3e05cda 100644 --- a/src/YTypes.h +++ b/src/YTypes.h @@ -17,7 +17,7 @@ /** @file YTypes.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer Header file for frequently used simple types to reduce interdependencies between important headers (e.g., YWidget.h, YUI.h). diff --git a/src/YUI.cc b/src/YUI.cc index 105173dac..cf9cf2033 100644 --- a/src/YUI.cc +++ b/src/YUI.cc @@ -18,7 +18,7 @@ File: YUI.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YUI.h b/src/YUI.h index 464ee075d..a0789e522 100644 --- a/src/YUI.h +++ b/src/YUI.h @@ -18,7 +18,7 @@ File: YUI.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YUIException.cc b/src/YUIException.cc index 551a41edc..110d376a1 100644 --- a/src/YUIException.cc +++ b/src/YUIException.cc @@ -21,7 +21,7 @@ Stolen from zypp/libzypp/base/Exception.cc Author: Michael Andres - Maintainer: Stefan Hundhammer + Maintainer: Stefan Hundhammer /-*/ diff --git a/src/YUIException.h b/src/YUIException.h index 71b023868..909661673 100644 --- a/src/YUIException.h +++ b/src/YUIException.h @@ -21,7 +21,7 @@ Stolen from zypp/libzypp/base/Exception.h Author: Michael Andres - Maintainer: Stefan Hundhammer + Maintainer: Stefan Hundhammer /-*/ diff --git a/src/YUILoader.cc b/src/YUILoader.cc index 2084940fd..c18e25da3 100644 --- a/src/YUILoader.cc +++ b/src/YUILoader.cc @@ -18,7 +18,7 @@ File: YUILoader.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YUILoader.h b/src/YUILoader.h index 19c77f0b7..3cbcc2883 100644 --- a/src/YUILoader.h +++ b/src/YUILoader.h @@ -18,7 +18,7 @@ File: YUILoader.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YUILog.cc b/src/YUILog.cc index c2c1a1533..b00ff9954 100644 --- a/src/YUILog.cc +++ b/src/YUILog.cc @@ -18,7 +18,7 @@ File: YUILog.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YUILog.h b/src/YUILog.h index 1ed30113d..aa928e1ff 100644 --- a/src/YUILog.h +++ b/src/YUILog.h @@ -18,7 +18,7 @@ File: YUILog.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YUIPlugin.cc b/src/YUIPlugin.cc index 84bb9ba70..a41b20cc9 100644 --- a/src/YUIPlugin.cc +++ b/src/YUIPlugin.cc @@ -18,7 +18,7 @@ File: YUIPlugin.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YUIPlugin.h b/src/YUIPlugin.h index aac121743..e826f91e1 100644 --- a/src/YUIPlugin.h +++ b/src/YUIPlugin.h @@ -18,7 +18,7 @@ File: YUIPlugin.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YUISymbols.h b/src/YUISymbols.h index b9365a296..312d20c9e 100644 --- a/src/YUISymbols.h +++ b/src/YUISymbols.h @@ -19,7 +19,7 @@ File: YUISymbols.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YWidget.cc b/src/YWidget.cc index 4c3da29c9..b771af3da 100644 --- a/src/YWidget.cc +++ b/src/YWidget.cc @@ -18,7 +18,7 @@ File: YWidget.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YWidget.h b/src/YWidget.h index 5b285d041..26c253ed1 100644 --- a/src/YWidget.h +++ b/src/YWidget.h @@ -18,7 +18,7 @@ File: YWidget.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YWidgetFactory.cc b/src/YWidgetFactory.cc index 76d933b3f..2039cc7ea 100644 --- a/src/YWidgetFactory.cc +++ b/src/YWidgetFactory.cc @@ -18,7 +18,7 @@ File: YWidgetFactory.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YWidgetFactory.h b/src/YWidgetFactory.h index bec86ba87..4659d1a67 100644 --- a/src/YWidgetFactory.h +++ b/src/YWidgetFactory.h @@ -18,7 +18,7 @@ File: YWidgetFactory.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YWidgetID.cc b/src/YWidgetID.cc index b0075e894..4ab8eef0c 100644 --- a/src/YWidgetID.cc +++ b/src/YWidgetID.cc @@ -18,7 +18,7 @@ File: YWidgetID.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YWidgetID.h b/src/YWidgetID.h index c5a012dee..c4a36017e 100644 --- a/src/YWidgetID.h +++ b/src/YWidgetID.h @@ -18,7 +18,7 @@ File: YWidgetID.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YWizard.cc b/src/YWizard.cc index 4bab56441..a2ab9ad93 100644 --- a/src/YWizard.cc +++ b/src/YWizard.cc @@ -18,7 +18,7 @@ File: YWizard.cc - Author: Stefan Hundhammer + Author: Stefan Hundhammer /-*/ diff --git a/src/YWizard.h b/src/YWizard.h index 699176cec..e51872b53 100644 --- a/src/YWizard.h +++ b/src/YWizard.h @@ -18,7 +18,7 @@ @file YWizard.h - Author: Stefan Hundhammer + Author: Stefan Hundhammer **/ From aad18f7aa28eaa22283be2f0792b6d7b46f824e3 Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Tue, 14 Jul 2020 12:07:19 +0200 Subject: [PATCH 11/13] Added support for enabling / disabling menu items --- examples/MenuBar1.cc | 138 +++++++++++++++++++++++++------------------ src/YMenuBar.cc | 4 ++ src/YMenuItem.h | 37 ++++++++++-- src/YMenuWidget.cc | 106 +++++++++++++-------------------- src/YMenuWidget.h | 39 +++++------- 5 files changed, 173 insertions(+), 151 deletions(-) diff --git a/examples/MenuBar1.cc b/examples/MenuBar1.cc index 0f07a1c76..2d0dd5a1a 100644 --- a/examples/MenuBar1.cc +++ b/examples/MenuBar1.cc @@ -27,6 +27,7 @@ #include "YAlignment.h" #include "YDialog.h" #include "YLabel.h" +#include "YCheckBox.h" #include "YLayoutBox.h" #include "YMenuBar.h" #include "YSquash.h" @@ -40,50 +41,52 @@ using std::string; // Widgets -YDialog * dialog = 0; -YLabel * lastEventLabel = 0; +YDialog * dialog = 0; +YMenuBar * menuBar = 0; +YLabel * lastEventLabel = 0; +YCheckBox * readOnlyCheckBox = 0; // Menus and Menu Items -YMenuItem * fileMenu = 0; -YMenuItem * editMenu = 0; -YMenuItem * viewMenu = 0; -YMenuItem * optionsMenu = 0; +YMenuItem * fileMenu = 0; +YMenuItem * editMenu = 0; +YMenuItem * viewMenu = 0; +YMenuItem * optionsMenu = 0; // "File" menu -YMenuItem * actionOpen = 0; -YMenuItem * actionSave = 0; -YMenuItem * actionSaveAs = 0; -YMenuItem * actionQuit = 0; +YMenuItem * actionOpen = 0; +YMenuItem * actionSave = 0; +YMenuItem * actionSaveAs = 0; +YMenuItem * actionQuit = 0; // "Edit" menu -YMenuItem * actionCut = 0; -YMenuItem * actionCopy = 0; -YMenuItem * actionPaste = 0; +YMenuItem * actionCut = 0; +YMenuItem * actionCopy = 0; +YMenuItem * actionPaste = 0; // "View" menu -YMenuItem * actionViewNormal = 0; -YMenuItem * actionViewCompact = 0; -YMenuItem * actionViewDetailed = 0; +YMenuItem * actionViewNormal = 0; +YMenuItem * actionViewCompact = 0; +YMenuItem * actionViewDetailed = 0; // "View" -> "Zoom" submenu -YMenuItem * zoomMenu = 0; -YMenuItem * actionZoomIn = 0; -YMenuItem * actionZoomOut = 0; -YMenuItem * actionZoomDefault = 0; +YMenuItem * zoomMenu = 0; +YMenuItem * actionZoomIn = 0; +YMenuItem * actionZoomOut = 0; +YMenuItem * actionZoomDefault = 0; // "Options" menu -YMenuItem * actionSettings = 0; +YMenuItem * actionSettings = 0; // Function Prototypes @@ -92,6 +95,7 @@ void createWidgets(); void addMenus( YMenuBar * menuBar ); void handleEvents(); void showEvent( YMenuEvent * event ); +void updateActions(); @@ -102,6 +106,7 @@ int main( int argc, char **argv ) YUILog::enableDebugLogging(); createWidgets(); + updateActions(); handleEvents(); dialog->destroy(); @@ -119,20 +124,24 @@ void createWidgets() dialog = fac->createPopupDialog(); YAlignment * minSize = fac->createMinSize( dialog, 50, 20 ); - YLayoutBox * vbox1 = fac->createVBox( minSize ); - YMenuBar * menuBar = fac->createMenuBar( vbox1 ); + YLayoutBox * vbox1 = fac->createVBox( minSize ); + menuBar = fac->createMenuBar( vbox1 ); addMenus( menuBar ); - YAlignment * center = fac->createHVCenter( vbox1 ); - YSquash * squash = fac->createHVSquash( center ); - YLayoutBox * vbox2 = fac->createVBox( squash ); + YAlignment * center = fac->createHVCenter( vbox1 ); + YSquash * squash = fac->createHVSquash( center ); + YLayoutBox * vbox2 = fac->createVBox( squash ); YAlignment * left = fac->createLeft( vbox2 ); fac->createLabel ( left, "Last Event:" ); fac->createVSpacing( vbox2, 0.2 ); YAlignment * minWidth = fac->createMinWidth( vbox2, 15 ); lastEventLabel = fac->createOutputField( minWidth, "" ); + + fac->createVSpacing( vbox2, 2 ); + readOnlyCheckBox = fac->createCheckBox( vbox2, "Read &Only", true ); + readOnlyCheckBox->setNotify( true ); } @@ -141,32 +150,32 @@ void addMenus( YMenuBar * menuBar ) // The difference between a menu and a plain menu item is just that the // menu has child items whild the plain item does not. - fileMenu = menuBar->addMenu( "&File" ); - editMenu = menuBar->addMenu( "&Edit" ); - viewMenu = menuBar->addMenu( "&View" ); + fileMenu = menuBar->addMenu( "&File" ); + editMenu = menuBar->addMenu( "&Edit" ); + viewMenu = menuBar->addMenu( "&View" ); optionsMenu = menuBar->addMenu( "&Options" ); - actionOpen = fileMenu->addItem( "&Open..." ); - actionSave = fileMenu->addItem( "&Save" ); - actionSaveAs = fileMenu->addItem( "Save &As..." ); + actionOpen = fileMenu->addItem( "&Open..." ); + actionSave = fileMenu->addItem( "&Save" ); + actionSaveAs = fileMenu->addItem( "Save &As..." ); fileMenu->addSeparator(); - actionQuit = fileMenu->addItem( "&Quit" ); + actionQuit = fileMenu->addItem( "&Quit" ); - actionCut = editMenu->addItem( "C&ut" ); - actionCopy = editMenu->addItem( "&Copy" ); - actionPaste = editMenu->addItem( "&Paste" ); + actionCut = editMenu->addItem( "C&ut" ); + actionCopy = editMenu->addItem( "&Copy" ); + actionPaste = editMenu->addItem( "&Paste" ); - actionViewNormal = viewMenu->addItem( "&Normal" ); - actionViewCompact = viewMenu->addItem( "&Compact" ); - actionViewDetailed = viewMenu->addItem( "&Detailed" ); + actionViewNormal = viewMenu->addItem( "&Normal" ); + actionViewCompact = viewMenu->addItem( "&Compact" ); + actionViewDetailed = viewMenu->addItem( "&Detailed" ); viewMenu->addSeparator(); - zoomMenu = viewMenu->addMenu( "&Zoom" ); + zoomMenu = viewMenu->addMenu( "&Zoom" ); - actionZoomIn = zoomMenu->addItem( "Zoom &In" ); - actionZoomOut = zoomMenu->addItem( "Zoom &Out" ); - actionZoomDefault = zoomMenu->addItem( "Zoom &Default" ); + actionZoomIn = zoomMenu->addItem( "Zoom &In" ); + actionZoomOut = zoomMenu->addItem( "Zoom &Out" ); + actionZoomDefault = zoomMenu->addItem( "Zoom &Default" ); - actionSettings = optionsMenu->addItem( "&Settings..." ); + actionSettings = optionsMenu->addItem( "&Settings..." ); menuBar->resolveShortcutConflicts(); menuBar->rebuildMenuTree(); @@ -191,18 +200,21 @@ void handleEvents() break; // leave event loop } - if ( event->eventType() == YEvent::MenuEvent ) - { - YMenuEvent * menuEvent = dynamic_cast( event ); + if ( event->eventType() == YEvent::MenuEvent ) + { + YMenuEvent * menuEvent = dynamic_cast( event ); + + if ( menuEvent ) + { + showEvent( menuEvent ); - if ( menuEvent ) - { - showEvent( menuEvent ); + if ( menuEvent->item() == actionQuit ) + break; // leave event loop + } + } - if ( menuEvent->item() == actionQuit ) - break; // leave event loop - } - } + if ( event->widget() == readOnlyCheckBox ) + updateActions(); } } } @@ -216,7 +228,21 @@ void showEvent( YMenuEvent * event ) { if ( event && event->item() ) { - string text = YShortcut::cleanShortcutString( event->item()->label() ); - lastEventLabel->setLabel( text ); + string text = YShortcut::cleanShortcutString( event->item()->label() ); + lastEventLabel->setLabel( text ); } } + + +/** + * Update the available menu actions: Enable or disable some of them according + * to the current status of the "Read Only" check box. + **/ +void updateActions() +{ + bool readOnly = readOnlyCheckBox->isChecked(); + + menuBar->setItemEnabled( actionSave, ! readOnly ); + menuBar->setItemEnabled( actionCut, ! readOnly ); + menuBar->setItemEnabled( actionPaste, ! readOnly ); +} diff --git a/src/YMenuBar.cc b/src/YMenuBar.cc index f9d848293..32a90e83c 100644 --- a/src/YMenuBar.cc +++ b/src/YMenuBar.cc @@ -83,9 +83,11 @@ YMenuBar::propertySet() { /* * @property itemList Items All menu items and submenus + * @property itemList EnabledItems Enabled or disabled status for items * @property string IconPath Base path for icons (on menu items) */ propSet.add( YProperty( YUIProperty_Items, YOtherProperty ) ); + propSet.add( YProperty( YUIProperty_EnabledItems, YOtherProperty ) ); propSet.add( YProperty( YUIProperty_IconPath, YStringProperty ) ); propSet.add( YWidget::propertySet() ); } @@ -100,6 +102,7 @@ YMenuBar::setProperty( const string & propertyName, const YPropertyValue & val ) propertySet().check( propertyName, val.type() ); // throws exceptions if not found or type mismatch if ( propertyName == YUIProperty_Items ) return false; // Needs special handling + else if ( propertyName == YUIProperty_EnabledItems ) return false; // Needs special handling else if ( propertyName == YUIProperty_IconPath ) setIconBasePath( val.stringVal() ); else { @@ -116,6 +119,7 @@ YMenuBar::getProperty( const string & propertyName ) propertySet().check( propertyName ); // throws exceptions if not found if ( propertyName == YUIProperty_Items ) return YPropertyValue( YOtherProperty ); + else if ( propertyName == YUIProperty_EnabledItems ) return YPropertyValue( YOtherProperty ); else if ( propertyName == YUIProperty_IconPath ) return YPropertyValue( iconBasePath() ); else { diff --git a/src/YMenuItem.h b/src/YMenuItem.h index a3241198c..aabc7f5f0 100644 --- a/src/YMenuItem.h +++ b/src/YMenuItem.h @@ -49,6 +49,8 @@ class YMenuItem: public YTreeItem YMenuItem( const std::string & label, const std::string & iconName = "" ) : YTreeItem( label, iconName ) + , _enabled( true ) + , _uiItem( 0 ) {} /** @@ -64,6 +66,8 @@ class YMenuItem: public YTreeItem const std::string & label, const std::string & iconName = "" ) : YTreeItem( parent, label, iconName ) + , _enabled( true ) + , _uiItem( 0 ) {} @@ -114,11 +118,30 @@ class YMenuItem: public YTreeItem bool isSeparator() const { return label().empty(); } /** - * Create a menu separator item and return it. The new separator is owned - * by 'parent'. + * Return 'true' if this item is enabled (which is the default). **/ - static YMenuItem * createSeparator( YMenuItem * parent) - { return new YMenuItem( parent, "" ); } + bool isEnabled() const { return _enabled; } + + /** + * Enable or disable this item. + * + * Applications should use YMenuWidget::setItemEnabled() instead because + * that will also notify the widget so it can update the item's visual + * representation. + **/ + void setEnabled( bool enabled = true ) { _enabled = enabled; } + + /** + * Return the UI counterpart of this item (if the UI set any). + **/ + void * uiItem() const { return _uiItem; } + + /** + * Set the UI counterpart of this item. This can be used to store a pointer + * to the equivalent of this item in the concrete UI: For example, the Qt + * UI will store a pointer to the corresponding QMenu or QAction. + **/ + void setUiItem( void * uiItem ) { _uiItem = uiItem; } private: @@ -127,6 +150,12 @@ class YMenuItem: public YTreeItem bool isOpen() const { return false; } void setOpen( bool ) {} + + + // Data members + + bool _enabled; + void * _uiItem; }; diff --git a/src/YMenuWidget.cc b/src/YMenuWidget.cc index 27ca45a95..8e2812c89 100644 --- a/src/YMenuWidget.cc +++ b/src/YMenuWidget.cc @@ -105,6 +105,14 @@ YMenuWidget::deleteAllItems() } +void +YMenuWidget::setItemEnabled( YMenuItem * item, bool enabled ) +{ + if ( item ) + item->setEnabled( enabled ); +} + + YMenuItem * YMenuWidget::findMenuItem( int index ) { @@ -141,20 +149,26 @@ YMenuWidget::findMenuItem( int wantedIndex, } +// FIXME: This is ugly code; candidate for refactoring. void YMenuWidget::resolveShortcutConflicts( YItemConstIterator begin, - YItemConstIterator end ) + YItemConstIterator end ) { - bool used[ sizeof( char ) << 8 ]; +#define USED_SIZE ((int) sizeof( char ) << 8) + bool used[ USED_SIZE ]; - for ( unsigned i=0; i < sizeof( char ) << 8; i++ ) + for ( int i = 0; i < USED_SIZE; i++ ) used[i] = false; + std::vector conflicts; for ( YItemConstIterator it = begin; it != end; ++it ) { YMenuItem * item = dynamic_cast (*it); + if ( item->isSeparator() ) + continue; + if ( item ) { if ( item->hasChildren() ) @@ -162,17 +176,22 @@ YMenuWidget::resolveShortcutConflicts( YItemConstIterator begin, resolveShortcutConflicts( item->childrenBegin(), item->childrenEnd() ); } - char shortcut = YShortcut::normalized(YShortcut::findShortcut(item->label())); + char shortcut = YShortcut::normalized( YShortcut::findShortcut( item->label() ) ) ; if ( shortcut == 0 ) { conflicts.push_back(item); - yuiMilestone() << "No or invalid shortcut found " << item->label() << endl; + yuiMilestone() << "No or invalid shortcut found: \"" + << item->label() << "\"" + << endl; } - else if ( used[ (unsigned)shortcut ] ) + else if ( used[ (unsigned) shortcut ] ) { conflicts.push_back(item); - yuiWarning() << "Conflicting shortcut found " << item->label() << endl; + + yuiWarning() << "Conflicting shortcut found: \"" + << item->label() << "\"" + << endl; } else { @@ -181,12 +200,15 @@ YMenuWidget::resolveShortcutConflicts( YItemConstIterator begin, } else { - yuiWarning() << "non menu item used in call " << (*it)->label() << endl; + yuiWarning() << "Non-menu item used in call: \"" + << (*it)->label() << "\"" + << endl; } } - // cannot use YShortcut directly as an YItem is not a YWidget - for( YMenuItem *i: conflicts ) + // Cannot use YShortcut directly as an YItem is not a YWidget + + for ( YMenuItem *i: conflicts ) { string clean = YShortcut::cleanShortcutString(i->label()); char new_c = 0; @@ -194,19 +216,20 @@ YMenuWidget::resolveShortcutConflicts( YItemConstIterator begin, size_t index = 0; for (; index < clean.size(); ++index) { - char ch = YShortcut::normalized( clean[index] ); + char ch = YShortcut::normalized( clean[ index ] ); + // ch is set to 0 by normalized() if not valid - if ( ch != 0 && ! used[ (unsigned)ch ] ) + if ( ch != 0 && ! used[ (unsigned) ch ] ) { new_c = ch; - used[(unsigned)ch] = true; + used[ (unsigned) ch ] = true; break; } } - if (new_c != 0) + if ( new_c != 0 ) { - clean.insert(index, 1, YShortcut::shortcutMarker()); + clean.insert( index, 1, YShortcut::shortcutMarker() ); yuiMilestone() << "New label used: " << clean << endl; } @@ -214,6 +237,8 @@ YMenuWidget::resolveShortcutConflicts( YItemConstIterator begin, } } +// FIXME End + void YMenuWidget::resolveShortcutConflicts() @@ -266,54 +291,3 @@ YMenuWidget::findItem( std::vector::iterator path_begin, return 0; } - -const YPropertySet & -YMenuWidget::propertySet() -{ - static YPropertySet propSet; - - if ( propSet.isEmpty() ) - { - /* - * @property itemList Items All menu items and submenus - * @property string IconPath Base path for icons (on menu items) - */ - propSet.add( YProperty( YUIProperty_Items, YOtherProperty ) ); - propSet.add( YProperty( YUIProperty_IconPath, YStringProperty ) ); - propSet.add( YWidget::propertySet() ); - } - - return propSet; -} - - -bool -YMenuWidget::setProperty( const string & propertyName, const YPropertyValue & val ) -{ - propertySet().check( propertyName, val.type() ); // throws exceptions if not found or type mismatch - - if ( propertyName == YUIProperty_Items ) return false; // Needs special handling - else if ( propertyName == YUIProperty_IconPath ) setIconBasePath( val.stringVal() ); - else - { - return YWidget::setProperty( propertyName, val ); - } - - return true; // success -- no special processing necessary -} - - -YPropertyValue -YMenuWidget::getProperty( const string & propertyName ) -{ - propertySet().check( propertyName ); // throws exceptions if not found - - if ( propertyName == YUIProperty_Label ) return YPropertyValue( label() ); - else if ( propertyName == YUIProperty_Items ) return YPropertyValue( YOtherProperty ); - else if ( propertyName == YUIProperty_IconPath ) return YPropertyValue( iconBasePath() ); - else - { - return YWidget::getProperty( propertyName ); - } -} - diff --git a/src/YMenuWidget.h b/src/YMenuWidget.h index cae0b4f3e..59c5d6ef2 100644 --- a/src/YMenuWidget.h +++ b/src/YMenuWidget.h @@ -115,33 +115,14 @@ class YMenuWidget: public YSelectionWidget void resolveShortcutConflicts(); /** - * Set a property. - * Reimplemented from YWidget. + * Enable or disable an item. This default implementation only updates the + * item's 'enabled' field. * - * This function may throw YUIPropertyExceptions. - * - * This function returns 'true' if the value was successfully set and - * 'false' if that value requires special handling (not in error cases: - * those are covered by exceptions). - **/ - virtual bool setProperty( const std::string & propertyName, - const YPropertyValue & val ); - - /** - * Get a property. - * Reimplemented from YWidget. - * - * This method may throw YUIPropertyExceptions. + * Derived classes should overwrite this method and either update the + * item's 'enabled' field in their implementation or call this default + * implementation. **/ - virtual YPropertyValue getProperty( const std::string & propertyName ); - - /** - * Return this class's property set. - * This also initializes the property upon the first call. - * - * Reimplemented from YWidget. - **/ - virtual const YPropertySet & propertySet(); + virtual void setItemEnabled( YMenuItem * item, bool enabled ); /** * Support for the Rest API for UI testing: @@ -171,6 +152,14 @@ class YMenuWidget: public YSelectionWidget YMenuItem * findMenuItem( int index ); + // No propertySet(), setProperty(), getProperty() on this level: + // + // This is left to derived widgets (very much like for YSelectionWidget) + // so they can be tailored to what they really can provide. + // + // There is infrastructure for properties like "EnabledItems" here and in + // the UI bindings, though, to easily support those properties. + protected: /** From 6b575c440cd1f00393d11b4da995114169e5a413 Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Thu, 16 Jul 2020 14:02:17 +0200 Subject: [PATCH 12/13] Fixed misleading comments --- src/YMenuWidget.cc | 2 +- src/YMenuWidget.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/YMenuWidget.cc b/src/YMenuWidget.cc index 8e2812c89..a021dc059 100644 --- a/src/YMenuWidget.cc +++ b/src/YMenuWidget.cc @@ -281,7 +281,7 @@ YMenuWidget::findItem( std::vector::iterator path_begin, return item; } - // Look in child nodes and return if found one + // Look in child nodes YMenuItem * result = findItem( ++path_begin, path_end, item->childrenBegin(), item->childrenEnd() ); if ( result ) diff --git a/src/YMenuWidget.h b/src/YMenuWidget.h index 59c5d6ef2..05834781e 100644 --- a/src/YMenuWidget.h +++ b/src/YMenuWidget.h @@ -86,8 +86,8 @@ class YMenuWidget: public YSelectionWidget * Add one item. This widget assumes ownership of the item object and will * delete it in its destructor. * - * This reimplementation will an index to the item that is unique for all - * items in this MenuButton. That index can be used later with + * This reimplementation will assign an index to the item that is unique + * for all items in this MenuButton. That index can be used later with * findMenuItem() to find the item by that index. * * @note Do not forget to call #resolveShortcutConflicts and From 404e7f8f83bfc2f87e37069a962f1ed1586f403f Mon Sep 17 00:00:00 2001 From: Stefan Hundhammer Date: Tue, 11 Aug 2020 15:28:38 +0200 Subject: [PATCH 13/13] SO bump, version bump, change log --- VERSION.cmake | 6 +++--- package/libyui-doc.spec | 4 ++-- package/libyui.changes | 8 ++++++++ package/libyui.spec | 4 ++-- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/VERSION.cmake b/VERSION.cmake index 724d905d0..02b645334 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -1,6 +1,6 @@ SET( VERSION_MAJOR "3") -SET( VERSION_MINOR "10" ) -SET( VERSION_PATCH "1" ) +SET( VERSION_MINOR "11" ) +SET( VERSION_PATCH "0" ) SET( VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${GIT_SHA1_VERSION}" ) ##### This is need for the libyui core, ONLY. @@ -8,7 +8,7 @@ SET( VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}${GIT_SHA1_VERSI # Currently you must also change so_version in libyui.spec # *and also in **all** other* libyui-*.spec files in the other repositories. # Yes, such a design is suboptimal. -SET( SONAME_MAJOR "12" ) +SET( SONAME_MAJOR "13" ) SET( SONAME_MINOR "0" ) SET( SONAME_PATCH "0" ) SET( SONAME "${SONAME_MAJOR}.${SONAME_MINOR}.${SONAME_PATCH}" ) diff --git a/package/libyui-doc.spec b/package/libyui-doc.spec index 9216685b5..0873ed0da 100644 --- a/package/libyui-doc.spec +++ b/package/libyui-doc.spec @@ -17,10 +17,10 @@ %define parent libyui -%define so_version 12 +%define so_version 13 Name: %{parent}-doc -Version: 3.10.1 +Version: 3.11.0 Release: 0 Source: %{parent}-%{version}.tar.bz2 diff --git a/package/libyui.changes b/package/libyui.changes index b19213ce3..b845f79a0 100644 --- a/package/libyui.changes +++ b/package/libyui.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Tue Aug 11 13:26:18 UTC 2020 - Stefan Hundhammer + +- Added MenuBar widget (bsc#1175115) +- Bumped SO version to 13 +- 3.11.0 + +------------------------------------------------------------------- Fri Jun 5 12:46:43 UTC 2020 - riafarov - Make itemAt method public for YSelectionWidget (bsc#1132247) diff --git a/package/libyui.spec b/package/libyui.spec index cc98c13ff..63aad8c49 100644 --- a/package/libyui.spec +++ b/package/libyui.spec @@ -16,11 +16,11 @@ # Name: libyui -Version: 3.10.1 +Version: 3.11.0 Release: 0 Source: %{name}-%{version}.tar.bz2 -%define so_version 12 +%define so_version 13 %define bin_name %{name}%{so_version} # optionally build with code coverage reporting,