select directories
This commit is contained in:
parent
3fe47f1982
commit
763e707139
|
@ -101,6 +101,9 @@ namespace
|
||||||
auto fileSelectionButton = new Button( "File selection", this );
|
auto fileSelectionButton = new Button( "File selection", this );
|
||||||
connect( fileSelectionButton, &Button::clicked, this, &ButtonBox::execFileSelection );
|
connect( fileSelectionButton, &Button::clicked, this, &ButtonBox::execFileSelection );
|
||||||
|
|
||||||
|
auto directorySelectionButton = new Button( "Directory selection", this );
|
||||||
|
connect( directorySelectionButton, &Button::clicked, this, &ButtonBox::execDirectorySelection );
|
||||||
|
|
||||||
setExtraSpacingAt( Qt::BottomEdge );
|
setExtraSpacingAt( Qt::BottomEdge );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,6 +172,15 @@ namespace
|
||||||
// not implemented for now (class is not public)
|
// not implemented for now (class is not public)
|
||||||
#else
|
#else
|
||||||
( void ) qskDialog->selectFile( "select file", QDir::currentPath() );
|
( void ) qskDialog->selectFile( "select file", QDir::currentPath() );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void execDirectorySelection()
|
||||||
|
{
|
||||||
|
#ifndef QSK_USE_EXEC
|
||||||
|
// not implemented for now (class is not public)
|
||||||
|
#else
|
||||||
|
( void ) qskDialog->selectDirectory( "select directory", QDir::currentPath() );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "QskSelectionSubWindow.h"
|
#include "QskSelectionSubWindow.h"
|
||||||
#include "QskSelectionWindow.h"
|
#include "QskSelectionWindow.h"
|
||||||
|
|
||||||
|
#include "QskEvent.h"
|
||||||
#include "QskFunctions.h"
|
#include "QskFunctions.h"
|
||||||
#include "QskListView.h"
|
#include "QskListView.h"
|
||||||
#include "QskPushButton.h"
|
#include "QskPushButton.h"
|
||||||
|
@ -157,25 +158,60 @@ namespace
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// copied from QskListView.cpp:
|
||||||
|
static inline int qskRowAt( const QskListView* listView, const QPointF& pos )
|
||||||
|
{
|
||||||
|
const auto rect = listView->viewContentsRect();
|
||||||
|
if ( rect.contains( pos ) )
|
||||||
|
{
|
||||||
|
const auto y = pos.y() - rect.top() + listView->scrollPos().y();
|
||||||
|
|
||||||
|
const int row = y / listView->rowHeight();
|
||||||
|
if ( row >= 0 && row < listView->rowCount() )
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copied from QskGestureRecognizer.cpp:
|
||||||
|
static QMouseEvent* qskClonedMouseEvent( const QMouseEvent* event )
|
||||||
|
{
|
||||||
|
QMouseEvent* clonedEvent;
|
||||||
|
|
||||||
|
#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
|
||||||
|
clonedEvent = QQuickWindowPrivate::cloneMouseEvent(
|
||||||
|
const_cast< QMouseEvent* >( event ), nullptr );
|
||||||
|
#else
|
||||||
|
clonedEvent = event->clone();
|
||||||
|
#endif
|
||||||
|
clonedEvent->setAccepted( false );
|
||||||
|
|
||||||
|
return clonedEvent;
|
||||||
|
}
|
||||||
|
|
||||||
class FileSystemView : public QskListView
|
class FileSystemView : public QskListView
|
||||||
{
|
{
|
||||||
|
using Inherited = QskListView;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FileSystemView( const QString& directory, QQuickItem* parent = nullptr )
|
FileSystemView( const QString& directory, QDir::Filters filter, QQuickItem* parent = nullptr )
|
||||||
: QskListView( parent )
|
: QskListView( parent )
|
||||||
, m_model( new QFileSystemModel( this ) )
|
, m_model( new QFileSystemModel( this ) )
|
||||||
{
|
{
|
||||||
connect( m_model, &QFileSystemModel::directoryLoaded, this, [this]()
|
connect( m_model, &QFileSystemModel::directoryLoaded, this, [this]()
|
||||||
{
|
{
|
||||||
columnWidths.fill( 0 );
|
m_columnWidths.fill( 0 );
|
||||||
updateScrollableSize();
|
updateScrollableSize();
|
||||||
setScrollPos( { 0, 0 } );
|
setScrollPos( { 0, 0 } );
|
||||||
setSelectedRow( -1 );
|
setSelectedRow( -1 );
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_model->setFilter( filter );
|
||||||
m_model->setRootPath( directory );
|
m_model->setRootPath( directory );
|
||||||
|
|
||||||
columnWidths.fill( 0, m_model->columnCount() );
|
m_columnWidths.fill( 0, m_model->columnCount() );
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual int rowCount() const override
|
virtual int rowCount() const override
|
||||||
|
@ -192,7 +228,7 @@ namespace
|
||||||
|
|
||||||
virtual qreal columnWidth( int col ) const override
|
virtual qreal columnWidth( int col ) const override
|
||||||
{
|
{
|
||||||
auto w = columnWidths.at( col );
|
auto w = m_columnWidths.at( col );
|
||||||
|
|
||||||
if( col == 0 )
|
if( col == 0 )
|
||||||
w = qMax( 250, w );
|
w = qMax( 250, w );
|
||||||
|
@ -220,9 +256,9 @@ namespace
|
||||||
|
|
||||||
const auto w = qskHorizontalAdvance( effectiveFont( Text ), v.toString() );
|
const auto w = qskHorizontalAdvance( effectiveFont( Text ), v.toString() );
|
||||||
|
|
||||||
if( w > columnWidths.at( col ) )
|
if( w > m_columnWidths.at( col ) )
|
||||||
{
|
{
|
||||||
columnWidths[ col ] = w;
|
m_columnWidths[ col ] = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
@ -233,9 +269,42 @@ namespace
|
||||||
return m_model;
|
return m_model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
void mousePressEvent( QMouseEvent* event ) override
|
||||||
|
{
|
||||||
|
if( m_doubleClickEvent && m_doubleClickEvent->timestamp() == event->timestamp() )
|
||||||
|
{
|
||||||
|
// do not select rows from double click mouse events
|
||||||
|
m_doubleClickEvent = nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Inherited::mousePressEvent( event );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouseDoubleClickEvent( QMouseEvent* event ) override
|
||||||
|
{
|
||||||
|
m_doubleClickEvent = qskClonedMouseEvent( event );
|
||||||
|
|
||||||
|
const int row = qskRowAt( this, qskMousePosition( event ) );
|
||||||
|
const auto path = valueAt( row, 0 ).toString();
|
||||||
|
|
||||||
|
QFileInfo fi( m_model->rootPath(), path );
|
||||||
|
|
||||||
|
if( fi.isDir() )
|
||||||
|
{
|
||||||
|
m_model->setRootPath( fi.absoluteFilePath() );
|
||||||
|
}
|
||||||
|
|
||||||
|
Inherited::mouseDoubleClickEvent( event );
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QFileSystemModel* const m_model;
|
QFileSystemModel* const m_model;
|
||||||
mutable QVector< int > columnWidths;
|
mutable QVector< int > m_columnWidths;
|
||||||
|
QMouseEvent* m_doubleClickEvent = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
template< typename W >
|
template< typename W >
|
||||||
|
@ -245,7 +314,8 @@ namespace
|
||||||
|
|
||||||
public:
|
public:
|
||||||
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, QDir::Filters filter )
|
||||||
: WindowOrSubWindow< W >( parent, title, actions, defaultAction )
|
: WindowOrSubWindow< W >( parent, title, actions, defaultAction )
|
||||||
{
|
{
|
||||||
auto* outerBox = new QskLinearBox( Qt::Vertical );
|
auto* outerBox = new QskLinearBox( Qt::Vertical );
|
||||||
|
@ -255,14 +325,14 @@ namespace
|
||||||
outerBox->setFixedSize( 700, 500 );
|
outerBox->setFixedSize( 700, 500 );
|
||||||
#endif
|
#endif
|
||||||
setupHeader( outerBox );
|
setupHeader( outerBox );
|
||||||
setupFileSystemView( directory, outerBox );
|
setupFileSystemView( directory, filter, outerBox );
|
||||||
|
|
||||||
updateHeader( directory );
|
updateHeader( directory );
|
||||||
|
|
||||||
Inherited::setContentItem( outerBox );
|
Inherited::setContentItem( outerBox );
|
||||||
}
|
}
|
||||||
|
|
||||||
QString selectedFile() const
|
QString selectedPath() const
|
||||||
{
|
{
|
||||||
if( m_fileView->selectedRow() != -1 )
|
if( m_fileView->selectedRow() != -1 )
|
||||||
{
|
{
|
||||||
|
@ -344,24 +414,12 @@ namespace
|
||||||
m_headerScrollArea->ensureItemVisible( m_breadcrumbsButtons.last() );
|
m_headerScrollArea->ensureItemVisible( m_breadcrumbsButtons.last() );
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupFileSystemView( const QString& directory, QQuickItem* parentItem )
|
void setupFileSystemView( const QString& directory, QDir::Filters filter, QQuickItem* parentItem )
|
||||||
{
|
{
|
||||||
m_fileView = new FileSystemView( directory, parentItem );
|
m_fileView = new FileSystemView( directory, filter, parentItem );
|
||||||
|
|
||||||
QObject::connect( m_fileView->model(), &QFileSystemModel::rootPathChanged,
|
QObject::connect( m_fileView->model(), &QFileSystemModel::rootPathChanged,
|
||||||
this, &FileSelectionWindow< W >::updateHeader );
|
this, &FileSelectionWindow< W >::updateHeader );
|
||||||
|
|
||||||
QObject::connect( m_fileView, &QskListView::selectedRowChanged,
|
|
||||||
this, [this]( int row )
|
|
||||||
{
|
|
||||||
const auto path = m_fileView->valueAt( row, 0 ).toString();
|
|
||||||
QFileInfo fi( m_fileView->model()->rootPath(), path );
|
|
||||||
|
|
||||||
if( fi.isDir() )
|
|
||||||
{
|
|
||||||
m_fileView->model()->setRootPath( fi.absoluteFilePath() );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QskScrollArea* m_headerScrollArea;
|
QskScrollArea* m_headerScrollArea;
|
||||||
|
@ -527,12 +585,12 @@ static QString qskSelectWindow(
|
||||||
}
|
}
|
||||||
|
|
||||||
template< typename W >
|
template< typename W >
|
||||||
static QString qskSelectFile( FileSelectionWindow< W >& window )
|
static QString qskSelectPath( FileSelectionWindow< W >& window )
|
||||||
{
|
{
|
||||||
QString selectedFile = window.selectedFile();
|
QString selectedFile = window.selectedPath();
|
||||||
|
|
||||||
if( window.exec() == QskDialog::Accepted )
|
if( window.exec() == QskDialog::Accepted )
|
||||||
selectedFile = window.selectedFile();
|
selectedFile = window.selectedPath();
|
||||||
|
|
||||||
return selectedFile;
|
return selectedFile;
|
||||||
}
|
}
|
||||||
|
@ -660,6 +718,8 @@ QString QskDialog::selectFile(
|
||||||
const auto defaultAction = QskDialog::Ok;
|
const auto defaultAction = QskDialog::Ok;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const auto flags = QDir::AllEntries | QDir::NoDotAndDotDot | QDir::AllDirs;
|
||||||
|
|
||||||
if ( m_data->policy == EmbeddedBox )
|
if ( m_data->policy == EmbeddedBox )
|
||||||
{
|
{
|
||||||
auto quickWindow = qobject_cast< QQuickWindow* >( m_data->transientParent );
|
auto quickWindow = qobject_cast< QQuickWindow* >( m_data->transientParent );
|
||||||
|
@ -669,13 +729,46 @@ QString QskDialog::selectFile(
|
||||||
|
|
||||||
if ( quickWindow )
|
if ( quickWindow )
|
||||||
{
|
{
|
||||||
FileSelectionWindow< QskDialogSubWindow > window( quickWindow, title, actions, defaultAction, directory );
|
FileSelectionWindow< QskDialogSubWindow > window( quickWindow, title,
|
||||||
return qskSelectFile< QskDialogSubWindow >( window );
|
actions, defaultAction, directory, flags );
|
||||||
|
return qskSelectPath< QskDialogSubWindow >( window );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSelectionWindow< QskDialogWindow > window( m_data->transientParent, title, actions, defaultAction, directory );
|
FileSelectionWindow< QskDialogWindow > window( m_data->transientParent, title,
|
||||||
return qskSelectFile< QskDialogWindow >( window );
|
actions, defaultAction, directory, flags );
|
||||||
|
return qskSelectPath< QskDialogWindow >( window );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QskDialog::selectDirectory(
|
||||||
|
const QString& title, const QString& directory ) const
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
// should be parameters
|
||||||
|
const auto actions = QskDialog::Ok | QskDialog::Cancel;
|
||||||
|
const auto defaultAction = QskDialog::Ok;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const auto flags = QDir::NoDotAndDotDot | QDir::AllDirs;
|
||||||
|
|
||||||
|
if ( m_data->policy == EmbeddedBox )
|
||||||
|
{
|
||||||
|
auto quickWindow = qobject_cast< QQuickWindow* >( m_data->transientParent );
|
||||||
|
|
||||||
|
if ( quickWindow == nullptr )
|
||||||
|
quickWindow = qskSomeQuickWindow();
|
||||||
|
|
||||||
|
if ( quickWindow )
|
||||||
|
{
|
||||||
|
FileSelectionWindow< QskDialogSubWindow > window( quickWindow, title,
|
||||||
|
actions, defaultAction, directory, flags );
|
||||||
|
return qskSelectPath< QskDialogSubWindow >( window );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSelectionWindow< QskDialogWindow > window( m_data->transientParent, title,
|
||||||
|
actions, defaultAction, directory, flags );
|
||||||
|
return qskSelectPath< QskDialogWindow >( window );
|
||||||
}
|
}
|
||||||
|
|
||||||
QskDialog::ActionRole QskDialog::actionRole( Action action )
|
QskDialog::ActionRole QskDialog::actionRole( Action action )
|
||||||
|
|
|
@ -133,6 +133,9 @@ class QSK_EXPORT QskDialog : public QObject
|
||||||
Q_INVOKABLE QString selectFile( const QString& title,
|
Q_INVOKABLE QString selectFile( const QString& title,
|
||||||
const QString& directory ) const;
|
const QString& directory ) const;
|
||||||
|
|
||||||
|
Q_INVOKABLE QString selectDirectory( const QString& title,
|
||||||
|
const QString& directory ) const;
|
||||||
|
|
||||||
static ActionRole actionRole( Action action );
|
static ActionRole actionRole( Action action );
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
|
Loading…
Reference in New Issue