1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-19 23:39:42 +01:00

* Fixed TWK-278: Store columns after reordering and introduce ViewHeader as a base-class for self-restoring QHeaderViews.

This commit is contained in:
Christian Muehlhaeuser 2011-09-04 12:35:52 +02:00
parent 58362883b3
commit 9690276079
10 changed files with 227 additions and 280 deletions

View File

@ -129,6 +129,7 @@ set( libSources
playlist/albumview.cpp
playlist/artistview.cpp
playlist/customplaylistview.cpp
playlist/ViewHeader.cpp
playlist/topbar/topbar.cpp
playlist/topbar/clearbutton.cpp
@ -339,6 +340,7 @@ set( libHeaders
playlist/albumview.h
playlist/artistview.h
playlist/customplaylistview.h
playlist/ViewHeader.h
playlist/topbar/topbar.h
playlist/topbar/clearbutton.h

View File

@ -0,0 +1,143 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ViewHeader.h"
#include <QContextMenuEvent>
#include <QMenu>
#include "tomahawksettings.h"
#include "utils/logger.h"
ViewHeader::ViewHeader( QAbstractItemView* parent )
: QHeaderView( Qt::Horizontal, parent )
, m_parent( parent )
, m_menu( new QMenu( this ) )
, m_sigmap( new QSignalMapper( this ) )
, m_init( false )
{
setResizeMode( QHeaderView::Interactive );
setMinimumSectionSize( 60 );
setDefaultAlignment( Qt::AlignLeft );
setMovable( true );
setStretchLastSection( true );
// m_menu->addAction( tr( "Resize columns to fit window" ), this, SLOT( onToggleResizeColumns() ) );
// m_menu->addSeparator();
connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( toggleVisibility( int ) ) );
}
ViewHeader::~ViewHeader()
{
}
int
ViewHeader::visibleSectionCount() const
{
return count() - hiddenSectionCount();
}
void
ViewHeader::onSectionsChanged()
{
TomahawkSettings::instance()->setPlaylistColumnSizes( m_guid, saveState() );
}
bool
ViewHeader::checkState()
{
if ( !count() || m_init )
return false;
QByteArray state = TomahawkSettings::instance()->playlistColumnSizes( m_guid );
if ( !state.isEmpty() )
{
restoreState( state );
if ( m_guid.startsWith( "playlistview" ) ) // HACK
setSortIndicator( -1, Qt::AscendingOrder );
}
else
{
for ( int i = 0; i < count() - 1; i++ )
{
if ( isSectionHidden( i ) )
continue;
double nw = (double)m_parent->width() * m_columnWeights.at( i );
resizeSection( i, qMax( minimumSectionSize(), int( nw - 0.5 ) ) );
}
}
m_init = true;
connect( this, SIGNAL( sectionMoved( int, int, int ) ), SLOT( onSectionsChanged() ) );
connect( this, SIGNAL( sectionResized( int, int, int ) ), SLOT( onSectionsChanged() ) );
return true;
}
void
ViewHeader::addColumnToMenu( int index )
{
QString title = m_parent->model()->headerData( index, Qt::Horizontal, Qt::DisplayRole ).toString();
QAction* action = m_menu->addAction( title, m_sigmap, SLOT( map() ) );
action->setCheckable( true );
action->setChecked( !isSectionHidden( index ) );
m_visActions << action;
m_sigmap->setMapping( action, index );
}
void
ViewHeader::contextMenuEvent( QContextMenuEvent* e )
{
qDeleteAll( m_visActions );
m_visActions.clear();
for ( int i = 0; i < count(); i++ )
addColumnToMenu( i );
m_menu->popup( e->globalPos() );
}
void
ViewHeader::onToggleResizeColumns()
{
}
void
ViewHeader::toggleVisibility( int index )
{
qDebug() << Q_FUNC_INFO << index;
if ( isSectionHidden( index ) )
showSection( index );
else
hideSection( index );
}

View File

@ -0,0 +1,65 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef VIEWHEADER_H
#define VIEWHEADER_H
#include <QHeaderView>
#include <QSignalMapper>
#include "dllmacro.h"
class DLLEXPORT ViewHeader : public QHeaderView
{
Q_OBJECT
public:
explicit ViewHeader( QAbstractItemView* parent = 0 );
~ViewHeader();
int visibleSectionCount() const;
void setDefaultColumnWeights( QList<double> weights ) { m_columnWeights = weights; }
QString guid() const { return m_guid; }
void setGuid( const QString& guid ) { m_guid = guid; }
public slots:
void toggleVisibility( int index );
bool checkState();
protected:
void contextMenuEvent( QContextMenuEvent* e );
private slots:
virtual void onSectionsChanged();
void onToggleResizeColumns();
private:
void addColumnToMenu( int index );
QAbstractItemView* m_parent;
QString m_guid;
QList<double> m_columnWeights;
QMenu* m_menu;
QSignalMapper* m_sigmap;
QList<QAction*> m_visActions;
bool m_init;
};
#endif

View File

@ -128,6 +128,7 @@ ArtistView::setTreeModel( TreeModel* model )
connect( m_proxyModel, SIGNAL( filterChanged( QString ) ), SLOT( onFilterChanged( QString ) ) );
connect( m_proxyModel, SIGNAL( rowsInserted( QModelIndex, int, int ) ), SLOT( onViewChanged() ) );
guid(); // this will set the guid on the header
setAcceptDrops( false );
if ( model->columnStyle() == TreeModel::TrackOnly )
@ -350,7 +351,10 @@ QString
ArtistView::guid() const
{
if ( m_guid.isEmpty() )
{
m_guid = QString( "artistview/%1" ).arg( m_model->columnCount( QModelIndex() ) );
m_header->setGuid( m_guid );
}
return m_guid;
}

View File

@ -18,134 +18,21 @@
#include "trackheader.h"
#include <QContextMenuEvent>
#include <QMenu>
#include "tomahawksettings.h"
#include "playlist/trackmodel.h"
#include "playlist/trackview.h"
#include "utils/logger.h"
TrackHeader::TrackHeader( TrackView* parent )
: QHeaderView( Qt::Horizontal, parent )
: ViewHeader( parent )
, m_parent( parent )
, m_menu( new QMenu( this ) )
, m_sigmap( new QSignalMapper( this ) )
, m_init( false )
{
setResizeMode( QHeaderView::Interactive );
setMinimumSectionSize( 60 );
setDefaultAlignment( Qt::AlignLeft );
setMovable( true );
setStretchLastSection( true );
// setCascadingSectionResizes( true );
QList< double > columnWeights;
columnWeights << 0.18 << 0.18 << 0.17 << 0.05 << 0.05 << 0.05 << 0.05 << 0.05 << 0.05 << 0.10; // << 0.05;
// m_menu->addAction( tr( "Resize columns to fit window" ), this, SLOT( onToggleResizeColumns() ) );
// m_menu->addSeparator();
connect( this, SIGNAL( sectionResized( int, int, int ) ), SLOT( onSectionResized() ) );
connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( toggleVisibility( int ) ) );
setDefaultColumnWeights( columnWeights );
}
TrackHeader::~TrackHeader()
{
}
void
TrackHeader::onSectionResized()
{
if ( !m_init )
return;
TomahawkSettings::instance()->setPlaylistColumnSizes( m_parent->guid(), saveState() );
}
int
TrackHeader::visibleSectionCount() const
{
return count() - hiddenSectionCount();
}
bool
TrackHeader::checkState()
{
if ( !count() || m_init )
return false;
QByteArray state = TomahawkSettings::instance()->playlistColumnSizes( m_parent->guid() );
if ( !state.isEmpty() )
{
restoreState( state );
if ( m_parent->guid().startsWith( "playlistview" ) ) // HACK
setSortIndicator( -1, Qt::AscendingOrder );
}
else
{
QList< double > m_columnWeights;
m_columnWeights << 0.18 << 0.18 << 0.17 << 0.05 << 0.05 << 0.05 << 0.05 << 0.05 << 0.05 << 0.10; // << 0.05;
for ( int i = 0; i < count() - 1; i++ )
{
if ( isSectionHidden( i ) )
continue;
double nw = (double)m_parent->width() * m_columnWeights.at( i );
qDebug() << "Setting default size:" << i << nw;
resizeSection( i, qMax( minimumSectionSize(), int( nw - 0.5 ) ) );
}
}
m_init = true;
return true;
}
void
TrackHeader::addColumnToMenu( int index )
{
QString title = m_parent->model()->headerData( index, Qt::Horizontal, Qt::DisplayRole ).toString();
QAction* action = m_menu->addAction( title, m_sigmap, SLOT( map() ) );
action->setCheckable( true );
action->setChecked( !isSectionHidden( index ) );
m_visActions << action;
m_sigmap->setMapping( action, index );
}
void
TrackHeader::contextMenuEvent( QContextMenuEvent* e )
{
qDeleteAll( m_visActions );
m_visActions.clear();
for ( int i = 0; i < count(); i++ )
addColumnToMenu( i );
m_menu->popup( e->globalPos() );
}
void
TrackHeader::onToggleResizeColumns()
{
}
void
TrackHeader::toggleVisibility( int index )
{
qDebug() << Q_FUNC_INFO << index;
if ( isSectionHidden( index ) )
showSection( index );
else
hideSection( index );
}

View File

@ -19,16 +19,12 @@
#ifndef TRACKHEADER_H
#define TRACKHEADER_H
#include <QHeaderView>
#include <QSignalMapper>
#include "source.h"
#include "ViewHeader.h"
#include "dllmacro.h"
class TrackView;
class DLLEXPORT TrackHeader : public QHeaderView
class DLLEXPORT TrackHeader : public ViewHeader
{
Q_OBJECT
@ -36,28 +32,8 @@ public:
explicit TrackHeader( TrackView* parent = 0 );
~TrackHeader();
int visibleSectionCount() const;
public slots:
void toggleVisibility( int index );
bool checkState();
protected:
void contextMenuEvent( QContextMenuEvent* e );
private slots:
void onSectionResized();
void onToggleResizeColumns();
private:
void addColumnToMenu( int index );
TrackView* m_parent;
QMenu* m_menu;
QSignalMapper* m_sigmap;
QList<QAction*> m_visActions;
bool m_init;
};
#endif

View File

@ -98,6 +98,7 @@ void
TrackView::setGuid( const QString& guid )
{
m_guid = guid;
m_header->setGuid( guid );
}

View File

@ -18,128 +18,21 @@
#include "treeheader.h"
#include <QContextMenuEvent>
#include <QMenu>
#include "tomahawksettings.h"
#include "playlist/treemodel.h"
#include "playlist/artistview.h"
#include "utils/logger.h"
TreeHeader::TreeHeader( ArtistView* parent )
: QHeaderView( Qt::Horizontal, parent )
: ViewHeader( parent )
, m_parent( parent )
, m_menu( new QMenu( this ) )
, m_sigmap( new QSignalMapper( this ) )
, m_init( false )
{
setResizeMode( QHeaderView::Interactive );
setMinimumSectionSize( 60 );
setDefaultAlignment( Qt::AlignLeft );
setMovable( true );
setStretchLastSection( true );
// setCascadingSectionResizes( true );
QList< double > columnWeights;
columnWeights << 0.50 << 0.07 << 0.07 << 0.07 << 0.07 << 0.07; // << 0.12;
// m_menu->addAction( tr( "Resize columns to fit window" ), this, SLOT( onToggleResizeColumns() ) );
// m_menu->addSeparator();
connect( this, SIGNAL( sectionResized( int, int, int ) ), SLOT( onSectionResized() ) );
connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( toggleVisibility( int ) ) );
setDefaultColumnWeights( columnWeights );
}
TreeHeader::~TreeHeader()
{
}
void
TreeHeader::onSectionResized()
{
if ( !m_init )
return;
TomahawkSettings::instance()->setPlaylistColumnSizes( m_parent->guid(), saveState() );
}
int
TreeHeader::visibleSectionCount() const
{
return count() - hiddenSectionCount();
}
void
TreeHeader::checkState()
{
if ( !count() || m_init )
return;
QByteArray state = TomahawkSettings::instance()->playlistColumnSizes( m_parent->guid() );
if ( !state.isEmpty() )
restoreState( state );
else
{
QList< double > m_columnWeights;
m_columnWeights << 0.50 << 0.07 << 0.07 << 0.07 << 0.07 << 0.07; // << 0.12;
for ( int i = 0; i < count() - 1; i++ )
{
if ( isSectionHidden( i ) )
continue;
double nw = (double)m_parent->width() * m_columnWeights.at( i );
qDebug() << "Setting default size:" << i << nw;
resizeSection( i, qMax( minimumSectionSize(), int( nw - 0.5 ) ) );
}
}
m_init = true;
}
void
TreeHeader::addColumnToMenu( int index )
{
QString title = m_parent->model()->headerData( index, Qt::Horizontal, Qt::DisplayRole ).toString();
QAction* action = m_menu->addAction( title, m_sigmap, SLOT( map() ) );
action->setCheckable( true );
action->setChecked( !isSectionHidden( index ) );
m_visActions << action;
m_sigmap->setMapping( action, index );
}
void
TreeHeader::contextMenuEvent( QContextMenuEvent* e )
{
qDeleteAll( m_visActions );
m_visActions.clear();
for ( int i = 0; i < count(); i++ )
addColumnToMenu( i );
m_menu->popup( e->globalPos() );
}
void
TreeHeader::onToggleResizeColumns()
{
}
void
TreeHeader::toggleVisibility( int index )
{
qDebug() << Q_FUNC_INFO << index;
if ( isSectionHidden( index ) )
showSection( index );
else
hideSection( index );
}

View File

@ -19,14 +19,12 @@
#ifndef TREEHEADER_H
#define TREEHEADER_H
#include <QHeaderView>
#include <QSignalMapper>
#include "ViewHeader.h"
#include "dllmacro.h"
class ArtistView;
class DLLEXPORT TreeHeader : public QHeaderView
class DLLEXPORT TreeHeader : public ViewHeader
{
Q_OBJECT
@ -34,28 +32,8 @@ public:
explicit TreeHeader( ArtistView* parent = 0 );
~TreeHeader();
int visibleSectionCount() const;
public slots:
void toggleVisibility( int index );
void checkState();
protected:
void contextMenuEvent( QContextMenuEvent* e );
private slots:
void onSectionResized();
void onToggleResizeColumns();
private:
void addColumnToMenu( int index );
ArtistView* m_parent;
QMenu* m_menu;
QSignalMapper* m_sigmap;
QList<QAction*> m_visActions;
bool m_init;
};
#endif

View File

@ -71,9 +71,7 @@ WelcomeWidget::WelcomeWidget( QWidget* parent )
ui->playlistWidget->setItemDelegate( new PlaylistDelegate() );
ui->playlistWidget->setModel( model );
ui->playlistWidget->overlay()->resize( 380, 86 );
#ifdef Q_OS_MAC
ui->playlistWidget->setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
#endif
connect( model, SIGNAL( emptinessChanged( bool) ), this, SLOT( updatePlaylists() ) );