2017-07-21 18:21:34 +02:00
|
|
|
/******************************************************************************
|
|
|
|
* QSkinny - Copyright (C) 2016 Uwe Rathmann
|
|
|
|
* This file may be used under the terms of the QSkinny License, Version 1.0
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include "QskSimpleListBox.h"
|
|
|
|
#include "QskAspect.h"
|
|
|
|
#include <QFontMetricsF>
|
|
|
|
|
|
|
|
static inline qreal qskMaxWidth(
|
|
|
|
const QFont& font, const QStringList& list )
|
|
|
|
{
|
|
|
|
const QFontMetricsF fm( font );
|
|
|
|
|
|
|
|
qreal max = 0.0;
|
|
|
|
for ( int i = 0; i < list.size(); i++ )
|
|
|
|
{
|
|
|
|
const qreal w = fm.width( list[i] );
|
|
|
|
if ( w > max )
|
|
|
|
max = w;
|
|
|
|
}
|
|
|
|
|
|
|
|
return max;
|
|
|
|
}
|
|
|
|
|
|
|
|
class QskSimpleListBox::PrivateData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
PrivateData():
|
|
|
|
maxTextWidth( 0.0 ),
|
|
|
|
columnWidthHint( 0.0 )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
// one column at the moment only
|
|
|
|
qreal maxTextWidth;
|
|
|
|
qreal columnWidthHint;
|
|
|
|
|
|
|
|
QStringList entries;
|
|
|
|
};
|
|
|
|
|
|
|
|
QskSimpleListBox::QskSimpleListBox( QQuickItem* parent ):
|
|
|
|
Inherited( parent ),
|
|
|
|
m_data( new PrivateData() )
|
|
|
|
{
|
|
|
|
connect( this, &Inherited::selectedRowChanged,
|
|
|
|
this, [this]( int row ) { Q_EMIT selectedEntryChanged( entryAt( row ) ); } );
|
|
|
|
}
|
|
|
|
|
|
|
|
QskSimpleListBox::~QskSimpleListBox()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
QString QskSimpleListBox::entryAt( int row ) const
|
|
|
|
{
|
|
|
|
if ( row >= 0 && row < m_data->entries.size() )
|
|
|
|
return m_data->entries[row];
|
|
|
|
|
|
|
|
return QString::null;
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant QskSimpleListBox::valueAt( int row, int col ) const
|
|
|
|
{
|
|
|
|
if ( col == 0 && row >= 0 && row < m_data->entries.size() )
|
|
|
|
return m_data->entries[row];
|
|
|
|
|
|
|
|
return QVariant();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskSimpleListBox::setColumnWidthHint( int column, qreal width )
|
|
|
|
{
|
|
|
|
if ( column != 0 )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( width != m_data->columnWidthHint )
|
|
|
|
{
|
|
|
|
m_data->columnWidthHint = qMax( width, qreal( 0.0 ) );
|
|
|
|
|
|
|
|
if ( m_data->columnWidthHint > 0.0 )
|
|
|
|
m_data->maxTextWidth = m_data->columnWidthHint;
|
|
|
|
else
|
|
|
|
m_data->maxTextWidth = qskMaxWidth( effectiveFont( Text ), m_data->entries );
|
|
|
|
|
|
|
|
updateScrollableSize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
qreal QskSimpleListBox::columnWidthHint( int column ) const
|
|
|
|
{
|
|
|
|
if ( column == 0 )
|
|
|
|
return m_data->columnWidthHint;
|
|
|
|
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskSimpleListBox::insert( const QStringList& list, int index )
|
|
|
|
{
|
|
|
|
if ( list.isEmpty() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( m_data->columnWidthHint <= 0.0 )
|
|
|
|
{
|
|
|
|
const auto w = qskMaxWidth( effectiveFont( Text ), list );
|
|
|
|
if ( w > m_data->maxTextWidth )
|
|
|
|
m_data->maxTextWidth = w;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_data->entries.isEmpty() )
|
|
|
|
{
|
|
|
|
m_data->entries = list;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if ( index < 0 || index >= m_data->entries.size() )
|
|
|
|
{
|
|
|
|
m_data->entries += list;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// is there no better way ???
|
|
|
|
for ( int i = 0; i < list.size(); i++ )
|
|
|
|
m_data->entries.insert( index + i, list[i] );
|
|
|
|
}
|
|
|
|
|
|
|
|
propagateEntries();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskSimpleListBox::setEntries( const QStringList& entries )
|
|
|
|
{
|
|
|
|
if ( m_data->entries.isEmpty() && entries.isEmpty() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_data->entries.clear();
|
|
|
|
|
|
|
|
if ( m_data->columnWidthHint <= 0.0 )
|
|
|
|
m_data->maxTextWidth = 0.0;
|
|
|
|
|
|
|
|
insert( entries, -1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
QStringList QskSimpleListBox::entries() const
|
|
|
|
{
|
|
|
|
return m_data->entries;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskSimpleListBox::insert( const QString& text, int index )
|
|
|
|
{
|
|
|
|
if ( m_data->columnWidthHint <= 0.0 )
|
|
|
|
{
|
|
|
|
const auto w = QFontMetricsF( effectiveFont( Cell ) ).width( text );
|
|
|
|
if ( w > m_data->maxTextWidth )
|
|
|
|
m_data->maxTextWidth = w;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( index < 0 )
|
|
|
|
m_data->entries.append( text );
|
|
|
|
else
|
|
|
|
m_data->entries.insert( index, text );
|
|
|
|
|
|
|
|
propagateEntries();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskSimpleListBox::removeAt( int index )
|
|
|
|
{
|
|
|
|
auto& entries = m_data->entries;
|
|
|
|
|
|
|
|
if ( index < 0 || index >= entries.size() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
if ( m_data->columnWidthHint <= 0.0 )
|
|
|
|
{
|
|
|
|
const QFontMetricsF fm( effectiveFont( Cell ) );
|
|
|
|
const auto w = fm.width( entries[index] );
|
|
|
|
|
|
|
|
if ( w >= m_data->maxTextWidth )
|
|
|
|
m_data->maxTextWidth = qskMaxWidth( effectiveFont( Text ), entries );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
entries.removeAt( index );
|
|
|
|
}
|
|
|
|
|
|
|
|
propagateEntries();
|
|
|
|
|
|
|
|
int row = selectedRow();
|
|
|
|
if ( row == index )
|
|
|
|
{
|
|
|
|
row = qMin( row, m_data->entries.size() - 1 );
|
|
|
|
|
|
|
|
if ( row != selectedRow() )
|
|
|
|
setSelectedRow( row );
|
|
|
|
else
|
|
|
|
Q_EMIT selectedRowChanged( row );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskSimpleListBox::removeBulk( int from, int to )
|
|
|
|
{
|
|
|
|
if ( from < 0 )
|
|
|
|
from = 0;
|
|
|
|
|
|
|
|
if ( to < 0 || to >= m_data->entries.size() - 1 )
|
|
|
|
to = m_data->entries.size() - 1;
|
|
|
|
|
|
|
|
if ( to < from )
|
|
|
|
return;
|
|
|
|
|
|
|
|
for ( int i = to; i >= from; i-- )
|
|
|
|
m_data->entries.removeAt( i );
|
|
|
|
|
|
|
|
if ( m_data->columnWidthHint <= 0.0 )
|
|
|
|
m_data->maxTextWidth = qskMaxWidth( effectiveFont( Text ), m_data->entries );
|
|
|
|
|
|
|
|
propagateEntries();
|
|
|
|
|
|
|
|
int row = selectedRow();
|
|
|
|
if ( row >= 0 )
|
|
|
|
{
|
|
|
|
if ( m_data->entries.isEmpty() )
|
|
|
|
{
|
|
|
|
row = -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if ( row < from )
|
|
|
|
{
|
|
|
|
// nothing to do
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if ( row <= to )
|
|
|
|
{
|
|
|
|
// we might end up here with the same row TODO ...
|
|
|
|
row = qMin( from, m_data->entries.size() - 1 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
row -= ( to - from + 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( row != selectedRow() )
|
|
|
|
{
|
|
|
|
setSelectedRow( row );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskSimpleListBox::clear()
|
|
|
|
{
|
|
|
|
if ( m_data->entries.isEmpty() )
|
|
|
|
return;
|
|
|
|
|
|
|
|
m_data->entries.clear();
|
|
|
|
|
|
|
|
if ( m_data->columnWidthHint <= 0.0 )
|
|
|
|
m_data->maxTextWidth = 0.0;
|
|
|
|
|
|
|
|
propagateEntries();
|
|
|
|
setSelectedRow( -1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QskSimpleListBox::propagateEntries()
|
|
|
|
{
|
|
|
|
#if 1
|
|
|
|
// when removing we might have lost the selected row -> what to do then ?
|
|
|
|
#endif
|
|
|
|
updateScrollableSize();
|
|
|
|
update();
|
|
|
|
|
|
|
|
Q_EMIT entriesChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
int QskSimpleListBox::rowCount() const
|
|
|
|
{
|
|
|
|
return m_data->entries.size();
|
|
|
|
}
|
|
|
|
|
|
|
|
int QskSimpleListBox::columnCount() const
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
qreal QskSimpleListBox::columnWidth( int col ) const
|
|
|
|
{
|
|
|
|
if ( col >= columnCount() )
|
|
|
|
return 0.0;
|
|
|
|
|
2017-08-23 14:53:29 +02:00
|
|
|
const QMarginsF padding = marginsHint( Cell | QskAspect::Padding );
|
|
|
|
return m_data->maxTextWidth + padding.left() + padding.right();
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
qreal QskSimpleListBox::rowHeight() const
|
|
|
|
{
|
2017-08-23 14:53:29 +02:00
|
|
|
const QMarginsF padding = marginsHint( Cell | QskAspect::Padding );
|
|
|
|
const QFontMetricsF fm( effectiveFont( Text ) );
|
2017-07-21 18:21:34 +02:00
|
|
|
|
2017-08-23 14:53:29 +02:00
|
|
|
return fm.height() + padding.top() + padding.bottom();
|
2017-07-21 18:21:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#include "moc_QskSimpleListBox.cpp"
|