implement own file system view

This commit is contained in:
Peter Hartmann 2025-01-23 11:57:42 +01:00
parent 736a5034de
commit 3fe47f1982
1 changed files with 114 additions and 50 deletions

View File

@ -14,12 +14,14 @@
#include "QskSelectionSubWindow.h" #include "QskSelectionSubWindow.h"
#include "QskSelectionWindow.h" #include "QskSelectionWindow.h"
#include "QskFunctions.h"
#include "QskListView.h"
#include "QskPushButton.h" #include "QskPushButton.h"
#include "QskScrollArea.h" #include "QskScrollArea.h"
#include "QskSimpleListBox.h"
#include "QskFocusIndicator.h" #include "QskFocusIndicator.h"
#include <qfontmetrics.h>
#include <qfilesystemmodel.h> #include <qfilesystemmodel.h>
#include <qguiapplication.h> #include <qguiapplication.h>
#include <qpointer.h> #include <qpointer.h>
@ -123,11 +125,6 @@ namespace
{ {
QskDialogWindow::setDialogContentItem( item ); QskDialogWindow::setDialogContentItem( item );
} }
QQuickItem* rootItem()
{
return contentItem();
}
}; };
template<> template<>
@ -158,11 +155,87 @@ namespace
{ {
QskDialogSubWindow::setContentItem( item ); QskDialogSubWindow::setContentItem( item );
} }
};
QQuickItem* rootItem() class FileSystemView : public QskListView
{
public:
FileSystemView( const QString& directory, QQuickItem* parent = nullptr )
: QskListView( parent )
, m_model( new QFileSystemModel( this ) )
{ {
return this; connect( m_model, &QFileSystemModel::directoryLoaded, this, [this]()
{
columnWidths.fill( 0 );
updateScrollableSize();
setScrollPos( { 0, 0 } );
setSelectedRow( -1 );
update();
});
m_model->setRootPath( directory );
columnWidths.fill( 0, m_model->columnCount() );
} }
virtual int rowCount() const override
{
const auto index = m_model->index( m_model->rootPath() );
return m_model->rowCount( index );
}
virtual int columnCount() const override
{
const auto index = m_model->index( m_model->rootPath() );
return m_model->columnCount( index );
}
virtual qreal columnWidth( int col ) const override
{
auto w = columnWidths.at( col );
if( col == 0 )
w = qMax( 250, w );
return w + 15; // spacing
}
virtual qreal rowHeight() const override
{
const auto hint = strutSizeHint( Cell );
const auto padding = paddingHint( Cell );
qreal h = effectiveFontHeight( Text );
h += padding.top() + padding.bottom();
return qMax( h, hint.height() );
}
virtual QVariant valueAt( int row, int col ) const override
{
const auto rootIndex = m_model->index( m_model->rootPath() );
const auto index = m_model->index( row, col, rootIndex );
const auto v = m_model->data( index );
const auto w = qskHorizontalAdvance( effectiveFont( Text ), v.toString() );
if( w > columnWidths.at( col ) )
{
columnWidths[ col ] = w;
}
return v;
}
QFileSystemModel* model()
{
return m_model;
}
private:
QFileSystemModel* const m_model;
mutable QVector< int > columnWidths;
}; };
template< typename W > template< typename W >
@ -174,37 +247,42 @@ namespace
FileSelectionWindow( QObject* parent, const QString& title, FileSelectionWindow( QObject* parent, const QString& title,
QskDialog::Actions actions, QskDialog::Action defaultAction,const QString& directory ) QskDialog::Actions actions, QskDialog::Action defaultAction,const QString& directory )
: WindowOrSubWindow< W >( parent, title, actions, defaultAction ) : WindowOrSubWindow< W >( parent, title, actions, defaultAction )
, m_model( new QFileSystemModel( parent ) )
{ {
m_model->setRootPath( directory );
auto* outerBox = new QskLinearBox( Qt::Vertical ); auto* outerBox = new QskLinearBox( Qt::Vertical );
outerBox->setMargins( 20 ); outerBox->setMargins( 20 );
outerBox->setSpacing( 20 ); outerBox->setSpacing( 20 );
#if 1 #if 1
outerBox->setFixedSize( 500, 500 ); outerBox->setFixedSize( 700, 500 );
#endif #endif
setupHeader( outerBox ); setupHeader( outerBox );
setupListBox( outerBox ); setupFileSystemView( directory, outerBox );
updateHeader( directory );
Inherited::setContentItem( outerBox ); Inherited::setContentItem( outerBox );
} }
QString selectedFile() const QString selectedFile() const
{ {
const auto index = m_model->index( m_model->rootPath() ); if( m_fileView->selectedRow() != -1 )
return m_model->filePath( index ); {
const auto path = m_fileView->valueAt( m_fileView->selectedRow(), 0 ).toString();
QFileInfo fi( m_fileView->model()->rootPath(), path );
return fi.absoluteFilePath();
}
return {};
} }
private: private:
void setupHeader( QQuickItem* parentItem ) void setupHeader( QQuickItem* parentItem )
{ {
m_scrollArea = new QskScrollArea( parentItem ); m_headerScrollArea = new QskScrollArea( parentItem );
m_scrollArea->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed ); m_headerScrollArea->setSizePolicy( Qt::Vertical, QskSizePolicy::Fixed );
m_scrollArea->setFlickableOrientations( Qt::Horizontal ); m_headerScrollArea->setFlickableOrientations( Qt::Horizontal );
m_headerBox = new QskLinearBox( Qt::Horizontal, m_scrollArea ); m_headerBox = new QskLinearBox( Qt::Horizontal, m_headerScrollArea );
m_scrollArea->setScrolledItem( m_headerBox ); m_headerScrollArea->setScrolledItem( m_headerBox );
} }
static QStringList splitPath( const QString& path ) static QStringList splitPath( const QString& path )
@ -252,59 +330,45 @@ namespace
QObject::connect( b, &QskPushButton::clicked, this, [this, fi]() QObject::connect( b, &QskPushButton::clicked, this, [this, fi]()
{ {
m_model->setRootPath( fi.filePath() ); m_fileView->model()->setRootPath( fi.filePath() );
}); });
} }
for( int i = dirPaths.count(); i < m_breadcrumbsButtons.count(); i++ ) for( int i = dirPaths.count(); i < m_breadcrumbsButtons.count(); i++ )
{ {
m_breadcrumbsButtons.at( i )->deleteLater(); m_breadcrumbsButtons.at( i )->deleteLater();
m_breadcrumbsButtons.removeAt( i );
} }
m_scrollArea->ensureItemVisible( m_breadcrumbsButtons.last() ); m_breadcrumbsButtons.remove( dirPaths.count(), m_breadcrumbsButtons.count() - dirPaths.count() );
m_headerScrollArea->ensureItemVisible( m_breadcrumbsButtons.last() );
} }
void setupListBox( QQuickItem* parentItem ) void setupFileSystemView( const QString& directory, QQuickItem* parentItem )
{ {
m_listBox = new QskSimpleListBox( parentItem ); m_fileView = new FileSystemView( directory, parentItem );
QObject::connect( m_model, &QFileSystemModel::directoryLoaded, QObject::connect( m_fileView->model(), &QFileSystemModel::rootPathChanged,
this, &FileSelectionWindow< W >::loadContents ); this, &FileSelectionWindow< W >::updateHeader );
QObject::connect( m_listBox, &QskSimpleListBox::selectedEntryChanged, QObject::connect( m_fileView, &QskListView::selectedRowChanged,
this, [this]( const QString& path ) this, [this]( int row )
{ {
QFileInfo fi( m_model->rootPath(), path ); const auto path = m_fileView->valueAt( row, 0 ).toString();
QFileInfo fi( m_fileView->model()->rootPath(), path );
if( fi.isDir() ) if( fi.isDir() )
{ {
m_model->setRootPath( fi.absoluteFilePath() ); m_fileView->model()->setRootPath( fi.absoluteFilePath() );
} }
}); });
} }
void loadContents() QskScrollArea* m_headerScrollArea;
{
m_listBox->removeBulk( 0 );
const auto index = m_model->index( m_model->rootPath() );
for ( int row = 0; row < m_model->rowCount( index ); row++ )
{
auto idx = m_model->index( row, 0, index );
m_listBox->append( m_model->fileName( idx ) );
}
updateHeader( QDir( selectedFile() ).path() );
}
QFileSystemModel* const m_model;
QskSimpleListBox* m_listBox;
QskLinearBox* m_headerBox; QskLinearBox* m_headerBox;
QskScrollArea* m_scrollArea;
QVector< QskPushButton* > m_breadcrumbsButtons; QVector< QskPushButton* > m_breadcrumbsButtons;
FileSystemView* m_fileView;
}; };
} }