system dialogs: Implement file dialog
This commit is contained in:
parent
4462815617
commit
2d70a6ae42
|
@ -9,6 +9,8 @@
|
||||||
#include <QskLinearBox.h>
|
#include <QskLinearBox.h>
|
||||||
#include <QskPushButton.h>
|
#include <QskPushButton.h>
|
||||||
|
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
#if QT_CONFIG(thread)
|
#if QT_CONFIG(thread)
|
||||||
/*
|
/*
|
||||||
WebAssembly without asyncify support does not allow recursive
|
WebAssembly without asyncify support does not allow recursive
|
||||||
|
@ -96,6 +98,9 @@ namespace
|
||||||
auto selectButton = new Button( "Selection", this );
|
auto selectButton = new Button( "Selection", this );
|
||||||
connect( selectButton, &Button::clicked, this, &ButtonBox::execSelection );
|
connect( selectButton, &Button::clicked, this, &ButtonBox::execSelection );
|
||||||
|
|
||||||
|
auto fileSelectionButton = new Button( "File selection", this );
|
||||||
|
connect( fileSelectionButton, &Button::clicked, this, &ButtonBox::execFileSelection );
|
||||||
|
|
||||||
setExtraSpacingAt( Qt::BottomEdge );
|
setExtraSpacingAt( Qt::BottomEdge );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,6 +160,15 @@ namespace
|
||||||
QskDialog::Ok | QskDialog::Cancel, QskDialog::Ok, entries, 7 );
|
QskDialog::Ok | QskDialog::Cancel, QskDialog::Ok, entries, 7 );
|
||||||
#else
|
#else
|
||||||
(void )qskDialog->select( title, entries, 7 );
|
(void )qskDialog->select( title, entries, 7 );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void execFileSelection()
|
||||||
|
{
|
||||||
|
#ifndef QSK_USE_EXEC
|
||||||
|
// not implemented for now (class is not public)
|
||||||
|
#else
|
||||||
|
( void ) qskDialog->selectFile( "select file", QDir::currentPath() );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <QskCheckBox.h>
|
#include <QskCheckBox.h>
|
||||||
#include <QskLinearBox.h>
|
#include <QskLinearBox.h>
|
||||||
#include <QskMainView.h>
|
#include <QskMainView.h>
|
||||||
|
#include <QskDialog.h>
|
||||||
|
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
|
|
||||||
|
@ -108,10 +109,29 @@ namespace
|
||||||
|
|
||||||
if ( qGuiApp->testAttribute( Qt::AA_DontUseNativeDialogs ) )
|
if ( qGuiApp->testAttribute( Qt::AA_DontUseNativeDialogs ) )
|
||||||
{
|
{
|
||||||
const auto metaEnum = QMetaEnum::fromType<DialogType>();
|
switch( dialogType )
|
||||||
m_dialog = createQml( metaEnum.key( dialogType ) );
|
{
|
||||||
if ( m_dialog )
|
case FileDialog:
|
||||||
m_dialog->setParentWindow( window() );
|
{
|
||||||
|
auto file = qskDialog->selectFile( "select file", "." );
|
||||||
|
qDebug() << "selected file" << file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MessageDialog:
|
||||||
|
{
|
||||||
|
auto action = qskDialog->message( "message", "The quick brown fox jumps over the lazy dog" );
|
||||||
|
qDebug() << "got message action" << action;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
const auto metaEnum = QMetaEnum::fromType<DialogType>();
|
||||||
|
m_dialog = createQml( metaEnum.key( dialogType ) );
|
||||||
|
|
||||||
|
if ( m_dialog )
|
||||||
|
m_dialog->setParentWindow( window() );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,12 +6,17 @@
|
||||||
#include "QskDialog.h"
|
#include "QskDialog.h"
|
||||||
#include "QskDialogButtonBox.h"
|
#include "QskDialogButtonBox.h"
|
||||||
|
|
||||||
|
#include "QskLinearBox.h"
|
||||||
|
|
||||||
#include "QskMessageSubWindow.h"
|
#include "QskMessageSubWindow.h"
|
||||||
#include "QskMessageWindow.h"
|
#include "QskMessageWindow.h"
|
||||||
|
|
||||||
#include "QskSelectionSubWindow.h"
|
#include "QskSelectionSubWindow.h"
|
||||||
#include "QskSelectionWindow.h"
|
#include "QskSelectionWindow.h"
|
||||||
|
|
||||||
|
#include "QskSimpleListBox.h"
|
||||||
|
#include "QskTextLabel.h"
|
||||||
|
|
||||||
#include "QskFocusIndicator.h"
|
#include "QskFocusIndicator.h"
|
||||||
|
|
||||||
#include <qguiapplication.h>
|
#include <qguiapplication.h>
|
||||||
|
@ -43,6 +48,192 @@ static QskDialog::Action qskActionCandidate( const QskDialogButtonBox* buttonBox
|
||||||
return QskDialog::NoAction;
|
return QskDialog::NoAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template< typename W, typename T, typename... Args >
|
||||||
|
class WindowOrSubWindow : public W, public T
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WindowOrSubWindow( QObject* parent, const QString& title,
|
||||||
|
QskDialog::Actions actions, QskDialog::Action defaultAction, Args... args )
|
||||||
|
: W( parent, title, actions, defaultAction )
|
||||||
|
, T( parent, args... )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void setContentItem()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T, typename... Args >
|
||||||
|
class WindowOrSubWindow< QskDialogWindow, T, Args... > : public QskDialogWindow, public T
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WindowOrSubWindow( QObject* parent, const QString& title,
|
||||||
|
QskDialog::Actions actions, QskDialog::Action defaultAction, Args... args )
|
||||||
|
: QskDialogWindow( static_cast< QWindow* >( parent ) )
|
||||||
|
, T( parent, args... )
|
||||||
|
{
|
||||||
|
auto* transientParent = static_cast< QWindow* >( parent );
|
||||||
|
setTransientParent( transientParent );
|
||||||
|
|
||||||
|
setTitle( title );
|
||||||
|
setDialogActions( actions );
|
||||||
|
|
||||||
|
if ( actions != QskDialog::NoAction && defaultAction == QskDialog::NoAction )
|
||||||
|
defaultAction = qskActionCandidate( buttonBox() );
|
||||||
|
|
||||||
|
setDefaultDialogAction( defaultAction );
|
||||||
|
|
||||||
|
setModality( transientParent ? Qt::WindowModal : Qt::ApplicationModal );
|
||||||
|
|
||||||
|
const QSize size = sizeConstraint();
|
||||||
|
|
||||||
|
if ( this->parent() )
|
||||||
|
{
|
||||||
|
QRect r( QPoint(), size );
|
||||||
|
r.moveCenter( QRect( QPoint(), this->parent()->size() ).center() );
|
||||||
|
|
||||||
|
setGeometry( r );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( size.isValid() )
|
||||||
|
{
|
||||||
|
setFlags( flags() | Qt::MSWindowsFixedSizeDialogHint );
|
||||||
|
setFixedSize( size );
|
||||||
|
}
|
||||||
|
|
||||||
|
setModality( Qt::ApplicationModal );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskDialog::DialogCode exec()
|
||||||
|
{
|
||||||
|
return qskExec( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void setContentItem( QQuickItem* item )
|
||||||
|
{
|
||||||
|
QskDialogWindow::setDialogContentItem( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
QQuickItem* rootItem()
|
||||||
|
{
|
||||||
|
return contentItem();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename T, typename... Args >
|
||||||
|
class WindowOrSubWindow< QskDialogSubWindow, T, Args... > : public QskDialogSubWindow, public T
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WindowOrSubWindow( QObject* parent, const QString& title,
|
||||||
|
QskDialog::Actions actions, QskDialog::Action defaultAction, Args... args )
|
||||||
|
: QskDialogSubWindow( static_cast< QQuickWindow* >( parent )->contentItem() )
|
||||||
|
, T( parent, args... )
|
||||||
|
{
|
||||||
|
setPopupFlag( QskPopup::DeleteOnClose );
|
||||||
|
setModal( true );
|
||||||
|
setTitle( title );
|
||||||
|
setDialogActions( actions );
|
||||||
|
|
||||||
|
if ( actions != QskDialog::NoAction && defaultAction == QskDialog::NoAction )
|
||||||
|
defaultAction = qskActionCandidate( buttonBox() );
|
||||||
|
|
||||||
|
setDefaultDialogAction( defaultAction );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskDialog::DialogCode exec()
|
||||||
|
{
|
||||||
|
return QskDialogSubWindow::exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setContentItem( QQuickItem* item )
|
||||||
|
{
|
||||||
|
QskDialogSubWindow::setContentItem( item );
|
||||||
|
}
|
||||||
|
|
||||||
|
QQuickItem* rootItem()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class FileSelection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FileSelection( QObject* parent, const QString& directory )
|
||||||
|
: m_dir( directory )
|
||||||
|
{
|
||||||
|
Q_UNUSED( parent )
|
||||||
|
|
||||||
|
m_dir.setFilter( QDir::Files | QDir::NoDotAndDotDot );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString selectedFile() const
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir currentDir()
|
||||||
|
{
|
||||||
|
return m_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QDir m_dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
template< typename W >
|
||||||
|
class FileSelectionWindow : public WindowOrSubWindow< W, FileSelection, QString >
|
||||||
|
{
|
||||||
|
using Inherited = WindowOrSubWindow< W, FileSelection, QString >;
|
||||||
|
|
||||||
|
public:
|
||||||
|
FileSelectionWindow( QObject* parent, const QString& title,
|
||||||
|
QskDialog::Actions actions, QskDialog::Action defaultAction,const QString& directory )
|
||||||
|
: WindowOrSubWindow< W, FileSelection, QString >( parent, title, actions, defaultAction, directory )
|
||||||
|
{
|
||||||
|
auto* outerBox = new QskLinearBox( Qt::Vertical );
|
||||||
|
#if 1
|
||||||
|
outerBox->setPreferredSize( 500, 500 );
|
||||||
|
#endif
|
||||||
|
setupHeader( outerBox );
|
||||||
|
setupListBox( outerBox );
|
||||||
|
|
||||||
|
Inherited::setContentItem( outerBox );
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setupHeader( QQuickItem* parentItem )
|
||||||
|
{
|
||||||
|
m_header = new QskTextLabel( parentItem );
|
||||||
|
const auto path = FileSelection::currentDir().absolutePath();
|
||||||
|
updateHeader( path );
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateHeader( const QString& path )
|
||||||
|
{
|
||||||
|
// m_header->setText( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupListBox( QQuickItem* parentItem )
|
||||||
|
{
|
||||||
|
m_listBox = new QskSimpleListBox( parentItem );
|
||||||
|
loadContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadContents()
|
||||||
|
{
|
||||||
|
m_listBox->removeBulk( 0 );
|
||||||
|
m_listBox->setEntries( FileSelection::currentDir().entryList() );
|
||||||
|
}
|
||||||
|
|
||||||
|
QskSimpleListBox* m_listBox;
|
||||||
|
QskTextLabel* m_header;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
static QskDialog::DialogCode qskExec( QskDialogWindow* dialogWindow )
|
static QskDialog::DialogCode qskExec( QskDialogWindow* dialogWindow )
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
|
@ -108,6 +299,7 @@ static void qskSetupWindow(
|
||||||
window->setModality( transientParent ? Qt::WindowModal : Qt::ApplicationModal );
|
window->setModality( transientParent ? Qt::WindowModal : Qt::ApplicationModal );
|
||||||
|
|
||||||
const QSize size = window->sizeConstraint();
|
const QSize size = window->sizeConstraint();
|
||||||
|
qDebug() << "sc:" << size;
|
||||||
|
|
||||||
if ( window->parent() )
|
if ( window->parent() )
|
||||||
{
|
{
|
||||||
|
@ -207,6 +399,17 @@ static QString qskSelectWindow(
|
||||||
return selectedEntry;
|
return selectedEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template< typename W >
|
||||||
|
static QString qskSelectFile( FileSelectionWindow< W >& window )
|
||||||
|
{
|
||||||
|
QString selectedFile = window.selectedFile();
|
||||||
|
|
||||||
|
if( window.exec() == QskDialog::Accepted )
|
||||||
|
selectedFile = window.selectedFile();
|
||||||
|
|
||||||
|
return selectedFile;
|
||||||
|
}
|
||||||
|
|
||||||
class QskDialog::PrivateData
|
class QskDialog::PrivateData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -321,6 +524,33 @@ QString QskDialog::select( const QString& title,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString QskDialog::selectFile(
|
||||||
|
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
|
||||||
|
|
||||||
|
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 );
|
||||||
|
return qskSelectFile< QskDialogSubWindow >( window );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FileSelectionWindow< QskDialogWindow > window( m_data->transientParent, title, actions, defaultAction, directory );
|
||||||
|
return qskSelectFile< QskDialogWindow >( window );
|
||||||
|
}
|
||||||
|
|
||||||
QskDialog::ActionRole QskDialog::actionRole( Action action )
|
QskDialog::ActionRole QskDialog::actionRole( Action action )
|
||||||
{
|
{
|
||||||
using Q = QPlatformDialogHelper;
|
using Q = QPlatformDialogHelper;
|
||||||
|
|
|
@ -130,6 +130,9 @@ class QSK_EXPORT QskDialog : public QObject
|
||||||
Q_INVOKABLE QString select( const QString& title,
|
Q_INVOKABLE QString select( const QString& title,
|
||||||
const QStringList& entries, int selectedRow = 0 ) const;
|
const QStringList& entries, int selectedRow = 0 ) const;
|
||||||
|
|
||||||
|
Q_INVOKABLE QString selectFile( 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