libyui  3.10.0
YItemSelector.cc
1 /*
2  Copyright (c) [2019] SUSE LLC
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: YItemSelector.cc
20 
21  Author: Stefan Hundhammer <shundhammer@suse.de>
22 
23 /-*/
24 
25 #define YUILogComponent "ui"
26 #include "YUILog.h"
27 
28 #include "YItemSelector.h"
29 
30 #define DEFAULT_VISIBLE_ITEMS 3
31 
32 using std::string;
33 
34 
36 {
38  : visibleItems( DEFAULT_VISIBLE_ITEMS )
39  {}
40 
41  int visibleItems;
42  YItemCustomStatusVector customStates;
43 };
44 
45 
47  bool enforceSingleSelection )
48  : YSelectionWidget( parent,
49  "", // label
50  enforceSingleSelection )
51  , priv( new YItemSelectorPrivate )
52 {
53  YUI_CHECK_NEW( priv );
54 
55  init();
56 }
57 
58 
60  const YItemCustomStatusVector & customStates )
61  : YSelectionWidget( parent,
62  "", // label
63  false ) // enforceSingleSelection )
64  , priv( new YItemSelectorPrivate )
65 {
66  YUI_CHECK_NEW( priv );
67 
68  priv->customStates = customStates;
69  init();
70  checkCustomStates();
71 }
72 
73 
75 {
76  // NOP
77 }
78 
79 
80 void YItemSelector::init()
81 {
83 
84  setDefaultStretchable( YD_HORIZ, true );
85  setDefaultStretchable( YD_VERT, true );
86 }
87 
88 
89 const char *
91 {
92  if ( usingCustomStatus() )
93  return "YCustomStatusItemSelector";
94 
95  return enforceSingleSelection() ? "YSingleItemSelector" : "YMultiItemSelector";
96 }
97 
98 
99 int
101 {
102  return priv->visibleItems;
103 }
104 
105 
107 {
108  if ( newVal < 1 )
109  newVal = 1;
110 
111  priv->visibleItems = newVal;
112 }
113 
114 
115 void YItemSelector::setItemStatus( YItem * item, int status )
116 {
117  if ( usingCustomStatus() )
118  {
119  YUI_CHECK_INDEX( status, -1, customStatusCount() - 1 );
120  item->setStatus( status );
122 
123  // Intentionally NOT calling the parent class implementation since that
124  // would only store 0 or 1 as the item's status.
125  }
126  else
127  {
128  // Let the parent class handle this and also take care of enforcing
129  // single selection (if configured).
130 
131  YSelectionWidget::setItemStatus( item, status );
132  }
133 }
134 
135 
137 {
138  return ! priv->customStates.empty();
139 }
140 
141 
143 {
144  return priv->customStates.size();
145 }
146 
147 
148 const YItemCustomStatus &
150 {
151  // std::vector::at() does bounds checking of 'index', possibly throwing a
152  // std::out_of_range exception.
153  //
154  // std::vector::operator[] does not do any checking and may just cause a
155  // segfault or misbehave in spectacular ways.
156 
157  return priv->customStates.at( (YItemCustomStatusVector::size_type) index );
158 }
159 
160 
162 {
163  return index >= 0 && index < customStatusCount();
164 }
165 
166 
167 void YItemSelector::checkCustomStates()
168 {
169  if ( priv->customStates.size() < 2 )
170  YUI_THROW( YUIException( "Need at least 2 different custom status value definitions" ) );
171 
172  int maxStatus = priv->customStates.size() - 1;
173 
174  for ( int i=0; i <= maxStatus; ++i )
175  {
176  YItemCustomStatus & status = priv->customStates.at( (YItemCustomStatusVector::size_type) i );
177 
178  if ( status.nextStatus() > maxStatus )
179  {
180  yuiError() << "Invalid nextStatus " << status.nextStatus()
181  << " for status #" << i
182  << endl;
183 
184  status.setNextStatus( -1 );
185  }
186  else if ( status.nextStatus() < -1 )
187  status.setNextStatus( -1 );
188  else
189  {
190  yuiDebug() << "Status #" << i << ": next status: #" << status.nextStatus() << endl;
191  }
192  }
193 }
194 
195 
197 {
198  if ( ! validCustomStatusIndex( oldStatus ) )
199  {
200  yuiDebug() << "Invalid old status: " << oldStatus << endl;
201  return oldStatus;
202  }
203  else
204  return priv->customStates.at( oldStatus ).nextStatus();
205 }
206 
207 
208 const YPropertySet &
210 {
211  static YPropertySet propSet;
212 
213  if ( propSet.isEmpty() )
214  {
215  /*
216  * @property itemID Value The (first) currently selected item
217  * @property itemID CurrentItem The (first) currently selected item
218  * @property itemList SelectedItems All currently selected items
219  * @property itemList Items All items
220  * @property statusMap ItemStatus The (numeric) status values of the items
221  * @property integer VisibleItems Number of items that are visible without scrolling
222  * @property string IconPath Base path for icons
223  */
224  propSet.add( YProperty( YUIProperty_Value, YOtherProperty ) );
225  propSet.add( YProperty( YUIProperty_CurrentItem, YOtherProperty ) );
226  propSet.add( YProperty( YUIProperty_SelectedItems, YOtherProperty ) );
227  propSet.add( YProperty( YUIProperty_Items, YOtherProperty ) );
228  propSet.add( YProperty( YUIProperty_ItemStatus, YOtherProperty ) );
229  propSet.add( YProperty( YUIProperty_VisibleItems, YIntegerProperty ) );
230  propSet.add( YProperty( YUIProperty_IconPath, YStringProperty ) );
231  propSet.add( YWidget::propertySet() );
232  }
233 
234  return propSet;
235 }
236 
237 
238 bool
239 YItemSelector::setProperty( const string & propertyName, const YPropertyValue & val )
240 {
241  propertySet().check( propertyName, val.type() ); // throws exceptions if not found or type mismatch
242 
243  if ( propertyName == YUIProperty_Value ) return false; // Needs special handling
244  else if ( propertyName == YUIProperty_CurrentItem ) return false; // Needs special handling
245  else if ( propertyName == YUIProperty_SelectedItems ) return false; // Needs special handling
246  else if ( propertyName == YUIProperty_Items ) return false; // Needs special handling
247  else if ( propertyName == YUIProperty_ItemStatus ) return false; // Needs special handling
248  else if ( propertyName == YUIProperty_VisibleItems ) setVisibleItems( val.integerVal() );
249  else if ( propertyName == YUIProperty_IconPath ) setIconBasePath( val.stringVal() );
250  else
251  {
252  return YWidget::setProperty( propertyName, val );
253  }
254 
255  return true; // success -- no special processing necessary
256 }
257 
258 
260 YItemSelector::getProperty( const string & propertyName )
261 {
262  propertySet().check( propertyName ); // throws exceptions if not found
263 
264  if ( propertyName == YUIProperty_Value ) return YPropertyValue( YOtherProperty );
265  else if ( propertyName == YUIProperty_CurrentItem ) return YPropertyValue( YOtherProperty );
266  else if ( propertyName == YUIProperty_SelectedItems ) return YPropertyValue( YOtherProperty );
267  else if ( propertyName == YUIProperty_Items ) return YPropertyValue( YOtherProperty );
268  else if ( propertyName == YUIProperty_ItemStatus ) return YPropertyValue( YOtherProperty );
269  else if ( propertyName == YUIProperty_VisibleItems ) return YPropertyValue( visibleItems() );
270  else if ( propertyName == YUIProperty_IconPath ) return YPropertyValue( iconBasePath() );
271  else
272  {
273  return YWidget::getProperty( propertyName );
274  }
275 }
YPropertySet::add
void add(const YProperty &prop)
Add a property to this property set.
Definition: YProperty.cc:146
YWidget
Abstract base class of all UI widgets.
Definition: YWidget.h:54
YSelectionWidget
Base class for various kinds of multi-value widgets.
Definition: YSelectionWidget.h:42
YItemSelector::setProperty
virtual bool setProperty(const std::string &propertyName, const YPropertyValue &val)
Set a property.
Definition: YItemSelector.cc:239
YItemSelector::getProperty
virtual YPropertyValue getProperty(const std::string &propertyName)
Get a property.
Definition: YItemSelector.cc:260
YSelectionWidget::setItemStatus
virtual void setItemStatus(YItem *item, int status)
Set the status of an item.
Definition: YSelectionWidget.cc:444
YItemSelector::validCustomStatusIndex
bool validCustomStatusIndex(int index) const
Return 'true' if a custom status index is within the valid range, i.e.
Definition: YItemSelector.cc:161
YItemCustomStatus
Class describing a non-binary status for an item.
Definition: YItemCustomStatus.h:44
YItemSelector::setItemStatus
virtual void setItemStatus(YItem *item, int status)
Set the status of an item.
Definition: YItemSelector.cc:115
YPropertySet
A set of properties to check names and types against.
Definition: YProperty.h:197
YPropertySet::isEmpty
bool isEmpty() const
Returns 'true' if this property set does not contain anything.
Definition: YProperty.h:263
YItemSelector::setVisibleItems
virtual void setVisibleItems(int newVal)
Set the number of visible items.
Definition: YItemSelector.cc:106
YPropertyValue::stringVal
std::string stringVal() const
Methods to get the value of this property.
Definition: YProperty.h:180
YItemSelector::updateCustomStatusIndicator
virtual void updateCustomStatusIndicator(YItem *item)
Update the status indicator (status icon or text indicator) if this widget is using custom status val...
Definition: YItemSelector.h:204
YSelectionWidget::enforceSingleSelection
bool enforceSingleSelection() const
Return 'true' if this base class should enforce single selection.
Definition: YSelectionWidget.cc:111
YPropertyValue::type
YPropertyType type() const
Returns the type of this property value.
Definition: YProperty.h:169
YSelectionWidget::iconBasePath
std::string iconBasePath() const
Return this widget's base path where to look up icons as set with setIconBasePath().
Definition: YSelectionWidget.cc:149
YItemSelector::customStatus
const YItemCustomStatus & customStatus(int index)
Return the custom status with the specified index (counting from 0).
Definition: YItemSelector.cc:149
YWidget::getProperty
virtual YPropertyValue getProperty(const std::string &propertyName)
Get a property.
Definition: YWidget.cc:457
YItemCustomStatus::nextStatus
int nextStatus() const
This returns the next status to cycle through if the user clicks on the status or cycles through stat...
Definition: YItemCustomStatus.h:82
YProperty
Class for widget properties.
Definition: YProperty.h:51
YItemSelector::propertySet
virtual const YPropertySet & propertySet()
Return this class's property set.
Definition: YItemSelector.cc:209
YItemSelector::visibleItems
int visibleItems() const
Return the number of visible items (i.e.
Definition: YItemSelector.cc:100
YItemSelector::~YItemSelector
virtual ~YItemSelector()
Destructor.
Definition: YItemSelector.cc:74
YSelectionWidget::setIconBasePath
void setIconBasePath(const std::string &basePath)
Set this widget's base path where to look up icons.
Definition: YSelectionWidget.cc:143
YItemSelector::usingCustomStatus
bool usingCustomStatus() const
Return 'true' if this widget uses custom status values, 'false' if not (i.e.
Definition: YItemSelector.cc:136
YSelectionWidget::setEnforceInitialSelection
void setEnforceInitialSelection(bool on)
In single selection mode, enforce selecting an initial item ('true' by default).
Definition: YSelectionWidget.cc:117
YPropertySet::check
void check(const std::string &propertyName) const
Check if a property 'propertyName' exists in this property set.
Definition: YProperty.cc:88
YItemCustomStatus::setNextStatus
void setNextStatus(int value)
Set the next status.
Definition: YItemCustomStatus.h:88
YItemSelector::YItemSelector
YItemSelector(YWidget *parent, bool enforceSingleSelection=true)
Standard constructor.
Definition: YItemSelector.cc:46
YItemSelector::widgetClass
virtual const char * widgetClass() const
Return a descriptive name of this widget class for logging, debugging etc.
Definition: YItemSelector.cc:90
YItemSelector::cycleCustomStatus
int cycleCustomStatus(int oldStatus)
Cycle through the custom status values according to the custom status table, i.e.
Definition: YItemSelector.cc:196
YPropertyValue
Transport class for the value of simple properties.
Definition: YProperty.h:104
YWidget::setDefaultStretchable
void setDefaultStretchable(YUIDimension dim, bool newStretch)
Set the stretchable state to "newStretch".
Definition: YWidget.cc:566
YItem::setStatus
void setStatus(int newStatus)
Set the status of this item.
Definition: YItem.h:128
YItemSelectorPrivate
Definition: YItemSelector.cc:35
YItemSelector::customStatusCount
int customStatusCount() const
Return the number of custom status values or 0 if no custom status values are used.
Definition: YItemSelector.cc:142
YWidget::setProperty
virtual bool setProperty(const std::string &propertyName, const YPropertyValue &val)
Set a property.
Definition: YWidget.cc:432
YUIException
Base class for UI Exceptions.
Definition: YUIException.h:297
YItem
Simple item class for SelectionBox, ComboBox, MultiSelectionBox etc.
Definition: YItem.h:49
YWidget::propertySet
virtual const YPropertySet & propertySet()
Return this class's property set.
Definition: YWidget.cc:395