Commit 6cb8b3fc authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum

[CHANGE] - selection widget now working, template module extended.

parent 32fcf3f4
......@@ -83,7 +83,7 @@ std::ostream& operator<<( std::ostream& out, const WItemSelector& other )
bool WItemSelector::operator==( const WItemSelector& other ) const
{
return ( ( m_selection == other.m_selection ) && ( m_selected == m_selected ) );
return ( ( m_selection == other.m_selection ) && ( m_selected == other.m_selected ) );
}
size_t WItemSelector::sizeAll() const
......@@ -103,7 +103,12 @@ WItemSelection::Item WItemSelector::atAll( size_t index ) const
WItemSelection::Item WItemSelector::at( size_t index ) const
{
return m_selection->at( m_selected.at( index ) );
return m_selection->at( getItemIndexOfSelected( index ) );
}
size_t WItemSelector::getItemIndexOfSelected( size_t index ) const
{
return m_selected.at( index );
}
bool WItemSelector::empty() const
......
......@@ -140,6 +140,16 @@ public:
*/
virtual WItemSelection::Item at( size_t index ) const;
/**
* Helps to get the index of an selected item in the WItemSelection. This is somehow similar to \ref at, but does not return the item but the
* index to it.
*
* \param index the index in the selection (not the item index in WItemSelection)
*
* \return the index in WItemSelection.
*/
virtual size_t getItemIndexOfSelected( size_t index ) const;
protected:
/**
......
......@@ -38,7 +38,6 @@ namespace WPropertyHelper
namespace PC_NOTEMPTY
{
void addTo( WPropSelection prop )
{
prop->addConstraint( boost::shared_ptr< WPropertyConstraintNotEmpty< WPVBaseTypes::PV_SELECTION > >(
......
......@@ -276,7 +276,6 @@ namespace PROPERTY_TYPE_HELPER
/**
* Creates a new instance of the type from a given string. Some classes need a predecessor which is also specified here.
*
* \param old the old value
* \param str the new value as string
*
* \return the new instance
......@@ -287,7 +286,6 @@ namespace PROPERTY_TYPE_HELPER
}
};
/**
* Class helping to adapt types specified as template parameter into an enum.
*/
......
......@@ -25,25 +25,82 @@
#include <cmath>
#include <string>
#include <QtGui/QPalette>
#include <QtGui/QListWidgetItem>
#include <boost/lexical_cast.hpp>
#include "../../../common/WLogger.h"
#include "../../../common/WPropertyVariable.h"
#include "../../../common/WItemSelector.h"
#include "../../../common/WItemSelection.h"
#include "WPropertySelectionWidget.h"
WPropertySelectionWidget::WPropertySelectionWidget( WPropSelection property, QGridLayout* propertyGrid, QWidget* parent ):
WPropertyWidget( property, propertyGrid, parent ),
m_selectionProperty( property ),
m_list( &m_parameterWidgets ),
m_combo( &m_parameterWidgets ),
m_layout( &m_parameterWidgets )
m_layout( &m_parameterWidgets ),
m_update( false )
{
// initialize members
m_parameterWidgets.setLayout( &m_layout );
// layout
m_layout.addWidget( &m_combo );
m_combo = NULL;
m_list = NULL;
// initialize the proper widget
// Lists are used if the selection of multiple elements is allowed
if ( m_selectionProperty->countConstraint( PC_SELECTONLYONE ) != 0 )
{
m_combo = new QComboBox( &m_parameterWidgets );
// add all items from the selection set:
WItemSelector s = m_selectionProperty->get();
for ( size_t i = 0; i < s.sizeAll(); ++i )
{
m_combo->addItem( QString::fromStdString( s.atAll( i ).first ) );
}
// layout
m_layout.addWidget( m_combo );
// connect
connect( m_combo, SIGNAL( currentIndexChanged( int ) ), this, SLOT( comboSelectionChanged( int ) ) );
}
else
{
m_list = new QListWidget( &m_parameterWidgets );
m_list->setSelectionMode( QAbstractItemView::ExtendedSelection );
// add all items from the selection set:
WItemSelector s = m_selectionProperty->get();
for ( size_t i = 0; i < s.sizeAll(); ++i )
{
// Create a custom widget which contains the name and description
QWidget* widget = new QWidget( m_list );
QGridLayout* layoutWidget = new QGridLayout();
// Add Name and Description
layoutWidget->addWidget( new QLabel( "<b>" + QString::fromStdString( s.atAll( i ).first )+ "</b>" ), 0, 0 );
layoutWidget->addWidget( new QLabel( QString::fromStdString( s.atAll( i ).second ) ), 1, 0 );
layoutWidget->setSizeConstraint( QLayout::SetMaximumSize );
widget->setLayout( layoutWidget );
// add Item
QListWidgetItem* item = new QListWidgetItem();
item->setSizeHint( widget->sizeHint() );
m_list->addItem( item );
m_list->setItemWidget( item, widget );
m_list->setMinimumHeight( 150 );
}
// layout
m_layout.addWidget( m_list );
// connect
connect( m_list, SIGNAL( itemSelectionChanged() ), this, SLOT( listSelectionChanged() ) );
}
// set the initial values
update();
......@@ -56,6 +113,78 @@ WPropertySelectionWidget::~WPropertySelectionWidget()
void WPropertySelectionWidget::update()
{
m_update = true;
WItemSelector s = m_selectionProperty->get();
//apply selection
if ( m_combo )
{
// mark the currently selected item. Just take care that there might be no item selected.
if ( s.size() == 0 )
{
m_combo->setCurrentIndex( -1 );
}
else
{
// as there is the SELECTONLYONE constraint -> if something is selected, it always is the first one
m_combo->setCurrentIndex( s.getItemIndexOfSelected( 0 ) );
}
}
else
{
m_list->clearSelection();
// select all items
WItemSelector s = m_selectionProperty->get();
for ( size_t i = 0; i < s.size(); ++i )
{
m_list->item( s.getItemIndexOfSelected( i ) )->setSelected( true );
}
}
m_update = false;
}
void WPropertySelectionWidget::comboSelectionChanged( int index )
{
// grab the list of selected indices, it is easy here as it always is one
WItemSelector::IndexList l;
l.push_back( index );
// new selector
WItemSelector ns = m_selectionProperty->get().newSelector( l );
// set it
// NOTE: set automatically checks the validity of the value
invalidate( !m_selectionProperty->set( ns ) );
}
void WPropertySelectionWidget::listSelectionChanged()
{
// unfortunately this slot is also called if the selection gets changed by the program. We are not interested in this case.
if ( m_update )
{
return;
}
// grab the list of selected indices
WItemSelector::IndexList l;
// go through the item list
for ( int i = 0; i < m_list->count(); ++i )
{
if ( m_list->item( i )->isSelected() )
{
l.push_back( i );
}
}
// create new selector
WItemSelector ns = m_selectionProperty->get().newSelector( l );
// set it
// NOTE: set automatically checks the validity of the value
invalidate( !m_selectionProperty->set( ns ) );
}
......@@ -28,7 +28,7 @@
#include <string>
#include <QtGui/QComboBox>
#include <QtGui/QListView>
#include <QtGui/QListWidget>
#include <QtGui/QHBoxLayout>
#include "WPropertyWidget.h"
......@@ -70,22 +70,38 @@ protected:
/**
* The list holding all items
*/
QListView m_list;
QListWidget* m_list;
/**
* The combobox holding all items.
*/
QComboBox m_combo;
QComboBox* m_combo;
/**
* Layout used to position the label and the checkbox
*/
QHBoxLayout m_layout;
/**
* True if a selection update is currently in progress. This is needed as QT does not provide a signal for selection changes which is NOT
* called when changed programmatically.
*/
bool m_update;
private:
public slots:
/**
* Called whenever the selection in m_list has changed.
*/
void listSelectionChanged();
/**
* Selection of the combobox has changed.
*
* \param index the new index
*/
void comboSelectionChanged( int index );
};
#endif // WPROPERTYSELECTIONWIDGET_H
......
......@@ -159,6 +159,7 @@ public:
* Adds an widget containing another property group to this widget. It encloses it with a GroupBox.
*
* \param widget the widget
* \param asScrollArea true if the group should be embedded into a scroll area
*/
void addGroup( WQtDSBWidget* widget, bool asScrollArea = false );
......
......@@ -219,16 +219,18 @@ void WMTemplate::properties()
// algorithms to run on some data and you want the user to select which one should do the work. This might be done integer properties but it
// is simply ugly. Therefore, properties of type WPropSelection are available. First you need to define a list of alternatives:
m_possibleSelections = boost::shared_ptr< WItemSelection >( new WItemSelection() );
m_possibleSelections->addItem( "Select", "Description" );
m_possibleSelections->addItem( "Me", "Description" );
m_possibleSelections->addItem( "Please", "Description" );
m_possibleSelections->addItem( "Beer", "Cold and fresh." );
m_possibleSelections->addItem( "Steaks", "Medium please" );
m_possibleSelections->addItem( "Sausages", "With Sauerkraut" );
// This list of alternatives is NOT the actual property value. It is the list on which so called "WItemSelector" instances work. These
// selectors are the actual property. After you created the first selector instance from the list, it can't be modified anymore. This ensures
// that it is consistent among multiple threads and selection instances. The following two lines create two selectors as initial value and
// create the property:
m_aSingleSelection = m_properties->addProperty( "Select one", "Description.", m_possibleSelections->getSelectorFirst(), m_propCondition );
m_aMultiSelection = m_properties->addProperty( "Select some", "Description.", m_possibleSelections->getSelectorAll(), m_propCondition );
m_aSingleSelection = m_properties->addProperty( "I like most", "Do you like the most?", m_possibleSelections->getSelectorFirst(),
m_propCondition );
m_aMultiSelection = m_properties->addProperty( "I like", "What do you like.", m_possibleSelections->getSelectorAll(),
m_propCondition );
// Adding a lot of properties might confuse the user. Using WPropGroup, you have the possibility to group your properties together. A
// WPropGroup needs a name and can provide a description. As with properties, the name should not contain any "/" and must be unique.
......@@ -545,6 +547,22 @@ void WMTemplate::moduleMain()
// whether the change notification should be fired or not. In our case, we avoid this by providing false to the second parameter.
m_aTrigger->set( WPVBaseTypes::PV_TRIGGER_READY, false );
}
// This checks the selections.
if ( m_aMultiSelection->changed() || m_aSingleSelection->changed() )
{
// The single selector allows only one selected item and requires one item to be selected all the time. So accessing it by index
// is trivial:
WItemSelector s = m_aSingleSelection->get( true );
infoLog() << "The user likes " << s.at( 0 ).first << " the most.";
// The multi property allows the selection of several items. So, iteration needs to be done here:
s = m_aMultiSelection->get( true );
for ( size_t i = 0; i < s.size(); ++i )
{
infoLog() << "The user likes " << s.at( i ).first;
}
}
}
// At this point, the container managing this module signalled to shutdown. The main loop has ended and you should clean up. Always remove
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment