From 10968aeb2501282afc953c6877b4646c935ae323 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 6 Aug 2017 05:07:59 +1000 Subject: [PATCH 1/3] Improve appearance of QgsFileWidget Fix vertical alignment of widgets so that they are always in line --- src/gui/qgsfilewidget.cpp | 21 +++++++++++++++------ src/gui/qgsfilewidget.h | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/gui/qgsfilewidget.cpp b/src/gui/qgsfilewidget.cpp index ed1464cabe4..019c8041b1e 100644 --- a/src/gui/qgsfilewidget.cpp +++ b/src/gui/qgsfilewidget.cpp @@ -44,8 +44,8 @@ QgsFileWidget::QgsFileWidget( QWidget *parent ) setBackgroundRole( QPalette::Window ); setAutoFillBackground( true ); - QGridLayout *layout = new QGridLayout(); - layout->setMargin( 0 ); + mLayout = new QHBoxLayout(); + mLayout->setMargin( 0 ); // If displaying a hyperlink, use a QLabel mLinkLabel = new QLabel( this ); @@ -56,20 +56,19 @@ QgsFileWidget::QgsFileWidget( QWidget *parent ) mLinkLabel->setEnabled( true ); mLinkLabel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ); mLinkLabel->setTextFormat( Qt::RichText ); - layout->addWidget( mLinkLabel, 0, 0 ); mLinkLabel->hide(); // do not show by default // otherwise, use the traditional QLineEdit mLineEdit = new QgsFilterLineEdit( this ); connect( mLineEdit, &QLineEdit::textChanged, this, &QgsFileWidget::textEdited ); - layout->addWidget( mLineEdit, 1, 0 ); + mLayout->addWidget( mLineEdit ); mFileWidgetButton = new QToolButton( this ); mFileWidgetButton->setText( QStringLiteral( "…" ) ); connect( mFileWidgetButton, &QAbstractButton::clicked, this, &QgsFileWidget::openFileDialog ); - layout->addWidget( mFileWidgetButton, 0, 1, 2, 1 ); + mLayout->addWidget( mFileWidgetButton ); - setLayout( layout ); + setLayout( mLayout ); } QString QgsFileWidget::filePath() @@ -142,6 +141,16 @@ void QgsFileWidget::setUseLink( bool useLink ) mUseLink = useLink; mLinkLabel->setVisible( mUseLink ); mLineEdit->setVisible( !mUseLink ); + if ( mUseLink ) + { + mLayout->removeWidget( mLineEdit ); + mLayout->insertWidget( 0, mLinkLabel ); + } + else + { + mLayout->removeWidget( mLinkLabel ); + mLayout->insertWidget( 0, mLineEdit ); + } } bool QgsFileWidget::fullUrl() const diff --git a/src/gui/qgsfilewidget.h b/src/gui/qgsfilewidget.h index 9df007118cb..8445a01ec83 100644 --- a/src/gui/qgsfilewidget.h +++ b/src/gui/qgsfilewidget.h @@ -159,6 +159,7 @@ class GUI_EXPORT QgsFileWidget : public QWidget QLabel *mLinkLabel = nullptr; QgsFilterLineEdit *mLineEdit = nullptr; QToolButton *mFileWidgetButton = nullptr; + QHBoxLayout *mLayout = nullptr; //! returns a HTML code with a link to the given file path QString toUrl( const QString &path ) const; From b1a6c790cfa51d8db5e3308da7f72ea68adb880c Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sun, 6 Aug 2017 16:32:10 +1000 Subject: [PATCH 2/3] Remove QgsFileDropEdit widget and integrate functionality into QgsFileWidget It makes no sense to have two classes covering this use case, with partial functionality in each. Smash the two together so we can safely use QgsFileWidget for all use cases in future. --- doc/api_break.dox | 1 + python/gui/gui_auto.sip | 1 - python/gui/qgsfilewidget.sip | 14 +- src/gui/CMakeLists.txt | 3 - src/gui/qgsfiledropedit.cpp | 121 ------------------ src/gui/qgsfiledropedit.h | 78 ----------- src/gui/qgsfilewidget.cpp | 110 +++++++++++++++- src/gui/qgsfilewidget.h | 63 ++++++++- src/plugins/gps_importer/qgsgpsplugingui.cpp | 10 +- .../gps_importer/qgsgpspluginguibase.ui | 38 ++---- tests/src/gui/testqgsfilewidget.cpp | 57 +++++++++ 11 files changed, 254 insertions(+), 242 deletions(-) delete mode 100644 src/gui/qgsfiledropedit.cpp delete mode 100644 src/gui/qgsfiledropedit.h diff --git a/doc/api_break.dox b/doc/api_break.dox index 6276530daa5..1ff0c69d92e 100644 --- a/doc/api_break.dox +++ b/doc/api_break.dox @@ -267,6 +267,7 @@ should now call QgsCoordinateReferenceSystem::invalidateCache() and QgsCoordinat - QgsDataDefinedSymbolDialog was removed. Code using this dialog should be reworked to use QgsPropertyOverrideButton - QgsDefaultPluginLayerLegend was removed. Use QgsMapLayer::setLegend() to provide legend nodes for plugin layers. - QgsFileNameWidgetWrapper was removed. Use QgsExternalResourceWidgetWrapper instead. +- QgsFileDropEdit was removed. Use QgsFileWidget instead. - QgsFormAnnotationItem. Use QgsFormAnnotation instead. - QgsHtmlAnnotationItem. Use QgsHtmlAnnotation instead. - QgsHttpTransaction. This class was outdated and code should be ported to native Qt or Python implementations. diff --git a/python/gui/gui_auto.sip b/python/gui/gui_auto.sip index 34005f05870..071eb2153b1 100644 --- a/python/gui/gui_auto.sip +++ b/python/gui/gui_auto.sip @@ -4,7 +4,6 @@ %Include qgscustomdrophandler.sip %Include qgsdetaileditemdata.sip %Include qgsexpressionbuilderdialog.sip -%Include qgsfiledropedit.sip %Include qgsgeometryrubberband.sip %Include qgsgui.sip %Include qgshelp.sip diff --git a/python/gui/qgsfilewidget.sip b/python/gui/qgsfilewidget.sip index c774afad72f..616ebae4ec9 100644 --- a/python/gui/qgsfilewidget.sip +++ b/python/gui/qgsfilewidget.sip @@ -9,8 +9,6 @@ - - class QgsFileWidget : QWidget { %Docstring @@ -149,6 +147,14 @@ returns if the relative path is with respect to the project path or the default determines if the relative path is with respect to the project path or the default path %End + QLineEdit *lineEdit(); +%Docstring + Returns a pointer to the widget's line edit, which can be used to customise + the appearance and behavior of the line edit portion of the widget. +.. versionadded:: 3.0 + :rtype: QLineEdit +%End + signals: void fileChanged( const QString & ); %Docstring @@ -157,6 +163,10 @@ emitted as soon as the current file or directory is changed }; + + + + /************************************************************************ * This file has been generated automatically from * * * diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index ea71eb41d2d..8b98c620211 100755 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -243,7 +243,6 @@ SET(QGIS_GUI_SRCS qgsfieldexpressionwidget.cpp qgsfieldvalidator.cpp qgsfieldvalueslineedit.cpp - qgsfiledropedit.cpp qgsfilewidget.cpp qgsfilterlineedit.cpp qgsfloatingwidget.cpp @@ -408,7 +407,6 @@ SET(QGIS_GUI_MOC_HDRS qgsfieldexpressionwidget.h qgsfieldvalidator.h qgsfieldvalueslineedit.h - qgsfiledropedit.h qgsfilewidget.h qgsfilterlineedit.h qgsfloatingwidget.h @@ -691,7 +689,6 @@ SET(QGIS_GUI_HDRS qgscustomdrophandler.h qgsdetaileditemdata.h qgsexpressionbuilderdialog.h - qgsfiledropedit.h qgsgeometryrubberband.h qgsgui.h qgsguiutils.h diff --git a/src/gui/qgsfiledropedit.cpp b/src/gui/qgsfiledropedit.cpp deleted file mode 100644 index 2d36b8c7a9f..00000000000 --- a/src/gui/qgsfiledropedit.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/*************************************************************************** - qgsfiledropedit.cpp - File Dropable LineEdit - -------------------------------------- - Date : 31-Jan-2007 - Copyright : (C) 2007 by Tom Elwertowski - Email : telwertowski at users dot sourceforge dot net - *************************************************************************** - * * - * This program 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 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "qgsfiledropedit.h" -#include -#include -#include -#include -#include - -QgsFileDropEdit::QgsFileDropEdit( QWidget *parent ) - : QLineEdit( parent ) -{ - mDirOnly = false; - mFileOnly = true; - mDragActive = false; - setAcceptDrops( true ); -} - -void QgsFileDropEdit::setDirOnly( bool isDirOnly ) -{ - mDirOnly = isDirOnly; - if ( mDirOnly ) - { - mFileOnly = false; - } -} - -void QgsFileDropEdit::setFileOnly( bool isFileOnly ) -{ - mFileOnly = isFileOnly; - if ( mFileOnly ) - { - mDirOnly = false; - } -} - -void QgsFileDropEdit::setSuffixFilter( const QString &suffix ) -{ - mSuffix = suffix; -} - -QString QgsFileDropEdit::acceptableFilePath( QDropEvent *event ) const -{ - QString path; - if ( event->mimeData()->hasUrls() ) - { - QFileInfo file( event->mimeData()->urls().first().toLocalFile() ); - if ( !( ( mFileOnly && !file.isFile() ) || - ( mDirOnly && !file.isDir() ) || - ( !mSuffix.isEmpty() && mSuffix.compare( file.suffix(), Qt::CaseInsensitive ) ) ) ) - path = file.filePath(); - } - return path; -} - -void QgsFileDropEdit::dragEnterEvent( QDragEnterEvent *event ) -{ - QString filePath = acceptableFilePath( event ); - if ( !filePath.isEmpty() ) - { - event->acceptProposedAction(); - mDragActive = true; - update(); - } - else - { - QLineEdit::dragEnterEvent( event ); - } -} - -void QgsFileDropEdit::dragLeaveEvent( QDragLeaveEvent *event ) -{ - QLineEdit::dragLeaveEvent( event ); - event->accept(); - mDragActive = false; - update(); -} - -void QgsFileDropEdit::dropEvent( QDropEvent *event ) -{ - QString filePath = acceptableFilePath( event ); - if ( !filePath.isEmpty() ) - { - setText( filePath ); - selectAll(); - setFocus( Qt::MouseFocusReason ); - event->acceptProposedAction(); - mDragActive = false; - update(); - } - else - { - QLineEdit::dropEvent( event ); - } -} - -void QgsFileDropEdit::paintEvent( QPaintEvent *e ) -{ - QLineEdit::paintEvent( e ); - if ( mDragActive ) - { - QPainter p( this ); - int width = 2; // width of highlight rectangle inside frame - p.setPen( QPen( palette().highlight(), width ) ); - QRect r = rect().adjusted( width, width, -width, -width ); - p.drawRect( r ); - } -} diff --git a/src/gui/qgsfiledropedit.h b/src/gui/qgsfiledropedit.h deleted file mode 100644 index b274a934d57..00000000000 --- a/src/gui/qgsfiledropedit.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************** - qgsfiledropedit.h - File Dropable LineEdit - -------------------------------------- - Date : 31-Jan-2007 - Copyright : (C) 2007 by Tom Elwertowski - Email : telwertowski at users dot sourceforge dot net - *************************************************************************** - * * - * This program 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 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ -#ifndef QGSFILEDROPEDIT_H -#define QGSFILEDROPEDIT_H - -#include -#include "qgis.h" -#include "qgis_gui.h" - - -/** \ingroup gui - * A line edit for capturing file names that can have files dropped onto - * it via drag & drop. - * - * Dropping can be limited to files only, files with a specific extension - or directories only. By default, dropping is limited to files only. - */ -class GUI_EXPORT QgsFileDropEdit: public QLineEdit -{ - Q_OBJECT - - public: - QgsFileDropEdit( QWidget *parent SIP_TRANSFERTHIS = 0 ); - - bool isDirOnly() const { return mDirOnly; } - - /** - Limit drops to directories. - */ - void setDirOnly( bool isDirOnly ); - - bool isFileOnly() const { return mFileOnly; } - - /** - Limit drops to files. - */ - void setFileOnly( bool isFileOnly ); - - QString suffixFilter() const { return mSuffix; } - - /** - Limit drops to files with specified extension. - */ - void setSuffixFilter( const QString &suffix ); - - protected: - - virtual void dragEnterEvent( QDragEnterEvent *event ) override; - virtual void dragLeaveEvent( QDragLeaveEvent *event ) override; - virtual void dropEvent( QDropEvent *event ) override; - virtual void paintEvent( QPaintEvent *e ) override; - - private: - - /** - Return file name if object meets drop criteria. - */ - QString acceptableFilePath( QDropEvent *event ) const; - - QString mSuffix; - bool mDirOnly; - bool mFileOnly; - bool mDragActive; -}; - -#endif diff --git a/src/gui/qgsfilewidget.cpp b/src/gui/qgsfilewidget.cpp index 019c8041b1e..3af620fe7ec 100644 --- a/src/gui/qgsfilewidget.cpp +++ b/src/gui/qgsfilewidget.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include "qgssettings.h" #include "qgsfilterlineedit.h" @@ -58,8 +59,8 @@ QgsFileWidget::QgsFileWidget( QWidget *parent ) mLinkLabel->setTextFormat( Qt::RichText ); mLinkLabel->hide(); // do not show by default - // otherwise, use the traditional QLineEdit - mLineEdit = new QgsFilterLineEdit( this ); + // otherwise, use the traditional QLineEdit subclass + mLineEdit = new QgsFileDropEdit( this ); connect( mLineEdit, &QLineEdit::textChanged, this, &QgsFileWidget::textEdited ); mLayout->addWidget( mLineEdit ); @@ -111,6 +112,7 @@ QString QgsFileWidget::filter() const void QgsFileWidget::setFilter( const QString &filters ) { mFilter = filters; + mLineEdit->setFilters( filters ); } bool QgsFileWidget::fileWidgetButtonVisible() const @@ -181,6 +183,7 @@ QgsFileWidget::StorageMode QgsFileWidget::storageMode() const void QgsFileWidget::setStorageMode( QgsFileWidget::StorageMode storageMode ) { mStorageMode = storageMode; + mLineEdit->setStorageMode( storageMode ); } QgsFileWidget::RelativeStorage QgsFileWidget::relativeStorage() const @@ -193,6 +196,11 @@ void QgsFileWidget::setRelativeStorage( QgsFileWidget::RelativeStorage relativeS mRelativeStorage = relativeStorage; } +QLineEdit *QgsFileWidget::lineEdit() +{ + return mLineEdit; +} + void QgsFileWidget::openFileDialog() { QgsSettings settings; @@ -316,3 +324,101 @@ QString QgsFileWidget::toUrl( const QString &path ) const return rep; } + + + + +///@cond PRIVATE + + +QgsFileDropEdit::QgsFileDropEdit( QWidget *parent ) + : QgsFilterLineEdit( parent ) +{ + mDragActive = false; + setAcceptDrops( true ); +} + +void QgsFileDropEdit::setFilters( const QString &filters ) +{ + mAcceptableExtensions.clear(); + + if ( filters.contains( QStringLiteral( "*.*" ) ) ) + return; // everything is allowed! + + QRegularExpression rx( "\\*\\.(\\w+)" ); + QRegularExpressionMatchIterator i = rx.globalMatch( filters ); + while ( i.hasNext() ) + { + QRegularExpressionMatch match = i.next(); + if ( match.hasMatch() ) + { + mAcceptableExtensions << match.captured( 1 ).toLower(); + } + } +} + +QString QgsFileDropEdit::acceptableFilePath( QDropEvent *event ) const +{ + QString path; + if ( event->mimeData()->hasUrls() ) + { + QFileInfo file( event->mimeData()->urls().first().toLocalFile() ); + if ( ( mStorageMode == QgsFileWidget::GetFile && file.isFile() && + ( mAcceptableExtensions.isEmpty() || mAcceptableExtensions.contains( file.suffix(), Qt::CaseInsensitive ) ) ) + || ( mStorageMode == QgsFileWidget::GetDirectory && file.isDir() ) ) + path = file.filePath(); + } + return path; +} + +void QgsFileDropEdit::dragEnterEvent( QDragEnterEvent *event ) +{ + QString filePath = acceptableFilePath( event ); + if ( !filePath.isEmpty() ) + { + event->acceptProposedAction(); + mDragActive = true; + update(); + } + else + { + event->ignore(); + } +} + +void QgsFileDropEdit::dragLeaveEvent( QDragLeaveEvent *event ) +{ + QgsFilterLineEdit::dragLeaveEvent( event ); + event->accept(); + mDragActive = false; + update(); +} + +void QgsFileDropEdit::dropEvent( QDropEvent *event ) +{ + QString filePath = acceptableFilePath( event ); + if ( !filePath.isEmpty() ) + { + setText( filePath ); + selectAll(); + setFocus( Qt::MouseFocusReason ); + event->acceptProposedAction(); + mDragActive = false; + update(); + } +} + +void QgsFileDropEdit::paintEvent( QPaintEvent *e ) +{ + QgsFilterLineEdit::paintEvent( e ); + if ( mDragActive ) + { + QPainter p( this ); + int width = 2; // width of highlight rectangle inside frame + p.setPen( QPen( palette().highlight(), width ) ); + QRect r = rect().adjusted( width, width, -width, -width ); + p.drawRect( r ); + } +} + +///@endcond diff --git a/src/gui/qgsfilewidget.h b/src/gui/qgsfilewidget.h index 8445a01ec83..f4492e33721 100644 --- a/src/gui/qgsfilewidget.h +++ b/src/gui/qgsfilewidget.h @@ -20,13 +20,13 @@ class QLabel; class QToolButton; class QVariant; - -class QgsFilterLineEdit; - +class QgsFileDropEdit; +class QHBoxLayout; #include #include "qgis_gui.h" #include "qgis.h" +#include "qgsfilterlineedit.h" /** \ingroup gui * \brief The QgsFileWidget class creates a widget for selecting a file or a folder. @@ -137,6 +137,13 @@ class GUI_EXPORT QgsFileWidget : public QWidget //! determines if the relative path is with respect to the project path or the default path void setRelativeStorage( QgsFileWidget::RelativeStorage relativeStorage ); + /** + * Returns a pointer to the widget's line edit, which can be used to customise + * the appearance and behavior of the line edit portion of the widget. + * \since QGIS 3.0 + */ + QLineEdit *lineEdit(); + signals: //! emitted as soon as the current file or directory is changed void fileChanged( const QString & ); @@ -157,7 +164,7 @@ class GUI_EXPORT QgsFileWidget : public QWidget RelativeStorage mRelativeStorage; QLabel *mLinkLabel = nullptr; - QgsFilterLineEdit *mLineEdit = nullptr; + QgsFileDropEdit *mLineEdit = nullptr; QToolButton *mFileWidgetButton = nullptr; QHBoxLayout *mLayout = nullptr; @@ -170,4 +177,52 @@ class GUI_EXPORT QgsFileWidget : public QWidget friend class TestQgsFileWidget; }; + + +///@cond PRIVATE + +#ifndef SIP_RUN + +/** \ingroup gui + * A line edit for capturing file names that can have files dropped onto + * it via drag & drop. + * + * Dropping can be limited to files only, files with a specific extension + * or directories only. By default, dropping is limited to files only. + * \note not available in Python bindings + */ +class GUI_EXPORT QgsFileDropEdit: public QgsFilterLineEdit +{ + Q_OBJECT + + public: + QgsFileDropEdit( QWidget *parent SIP_TRANSFERTHIS = 0 ); + + void setStorageMode( QgsFileWidget::StorageMode storageMode ) { mStorageMode = storageMode; } + + void setFilters( const QString &filters ); + + protected: + + virtual void dragEnterEvent( QDragEnterEvent *event ) override; + virtual void dragLeaveEvent( QDragLeaveEvent *event ) override; + virtual void dropEvent( QDropEvent *event ) override; + virtual void paintEvent( QPaintEvent *e ) override; + + private: + + /** + Return file name if object meets drop criteria. + */ + QString acceptableFilePath( QDropEvent *event ) const; + + QStringList mAcceptableExtensions; + QgsFileWidget::StorageMode mStorageMode = QgsFileWidget::GetFile; + bool mDragActive; + friend class TestQgsFileWidget; +}; + +#endif +///@endcond + #endif // QGSFILEWIDGET_H diff --git a/src/plugins/gps_importer/qgsgpsplugingui.cpp b/src/plugins/gps_importer/qgsgpsplugingui.cpp index 3408d566f8f..1ff157abd5e 100644 --- a/src/plugins/gps_importer/qgsgpsplugingui.cpp +++ b/src/plugins/gps_importer/qgsgpsplugingui.cpp @@ -51,7 +51,7 @@ QgsGPSPluginGui::QgsGPSPluginGui( const BabelMap &importers, // click it pbnOK = buttonBox->button( QDialogButtonBox::Ok ); pbnOK->setEnabled( false ); - connect( leGPXFile, &QLineEdit::textChanged, + connect( mFileWidget, &QgsFileWidget::fileChanged, this, &QgsGPSPluginGui::enableRelevantControls ); connect( leIMPInput, &QLineEdit::textChanged, this, &QgsGPSPluginGui::enableRelevantControls ); @@ -75,7 +75,7 @@ QgsGPSPluginGui::QgsGPSPluginGui( const BabelMap &importers, this, &QgsGPSPluginGui::enableRelevantControls ); // drag and drop filter - leGPXFile->setSuffixFilter( QStringLiteral( "gpx" ) ); + mFileWidget->setFilter( tr( "GPX files (*.gpx)" ) ); } QgsGPSPluginGui::~QgsGPSPluginGui() @@ -92,7 +92,7 @@ void QgsGPSPluginGui::on_buttonBox_accepted() { case 0: // add a GPX layer? - emit loadGPXFile( leGPXFile->text(), cbGPXWaypoints->isChecked(), + emit loadGPXFile( mFileWidget->filePath(), cbGPXWaypoints->isChecked(), cbGPXRoutes->isChecked(), cbGPXTracks->isChecked() ); break; @@ -180,7 +180,7 @@ void QgsGPSPluginGui::enableRelevantControls() // load GPX if ( tabWidget->currentIndex() == 0 ) { - if ( ( leGPXFile->text() == QLatin1String( "" ) ) ) + if ( !mFileWidget->filePath().isEmpty() ) { pbnOK->setEnabled( false ); cbGPXWaypoints->setEnabled( false ); @@ -259,7 +259,7 @@ void QgsGPSPluginGui::on_pbnGPXSelectFile_clicked() tr( "GPS eXchange format" ) + " (*.gpx)" ); if ( !myFileNameQString.isEmpty() ) { - leGPXFile->setText( myFileNameQString ); + mFileWidget->setFilePath( myFileNameQString ); settings.setValue( QStringLiteral( "Plugin-GPS/gpxdirectory" ), QFileInfo( myFileNameQString ).absolutePath() ); } } diff --git a/src/plugins/gps_importer/qgsgpspluginguibase.ui b/src/plugins/gps_importer/qgsgpspluginguibase.ui index f8a8fe6be57..c36432689a1 100644 --- a/src/plugins/gps_importer/qgsgpspluginguibase.ui +++ b/src/plugins/gps_importer/qgsgpspluginguibase.ui @@ -6,8 +6,8 @@ 0 0 - 647 - 277 + 1217 + 504 @@ -15,8 +15,7 @@ - - + .. @@ -30,25 +29,15 @@ - + + + + File - - pbnGPXSelectFile - - - - - - - - - - Browse... - @@ -655,15 +644,14 @@ - QgsFileDropEdit - QLineEdit -
qgsfiledropedit.h
+ QgsFileWidget + QWidget +
qgsfilewidget.h
+ 1
tabWidget - leGPXFile - pbnGPXSelectFile cbGPXWaypoints cbGPXRoutes cbGPXTracks @@ -693,8 +681,6 @@ leCONVLayer buttonBox - - - + diff --git a/tests/src/gui/testqgsfilewidget.cpp b/tests/src/gui/testqgsfilewidget.cpp index aab256d2fc2..4cea165c495 100644 --- a/tests/src/gui/testqgsfilewidget.cpp +++ b/tests/src/gui/testqgsfilewidget.cpp @@ -17,6 +17,7 @@ #include "qgstest.h" #include "qgsfilewidget.h" +#include class TestQgsFileWidget: public QObject { @@ -29,6 +30,7 @@ class TestQgsFileWidget: public QObject void relativePath(); void toUrl(); + void testDroppedFiles(); }; @@ -81,7 +83,62 @@ void TestQgsFileWidget::toUrl() QCOMPARE( w->toUrl( "../test2/file6.ext" ), QString( "file6.ext" ) ); } +void TestQgsFileWidget::testDroppedFiles() +{ + QgsFileWidget *w = new QgsFileWidget(); + w->setStorageMode( QgsFileWidget::GetFile ); + // should not accept dropped folders + std::unique_ptr< QMimeData > mime( new QMimeData() ); + mime->setUrls( QList() << QUrl::fromLocalFile( TEST_DATA_DIR ) ); + std::unique_ptr< QDropEvent > event( new QDropEvent( QPointF( 1, 1 ), Qt::CopyAction, mime.get(), Qt::LeftButton, Qt::NoModifier ) ); + + qobject_cast< QgsFileDropEdit * >( w->lineEdit() )->dropEvent( event.get() ); + QVERIFY( w->lineEdit()->text().isEmpty() ); + + // but dropped files should be fine + mime->setUrls( QList() << QUrl::fromLocalFile( TEST_DATA_DIR + QStringLiteral( "/bug5598.shp" ) ) ); + event.reset( new QDropEvent( QPointF( 1, 1 ), Qt::CopyAction, mime.get(), Qt::LeftButton, Qt::NoModifier ) ); + qobject_cast< QgsFileDropEdit * >( w->lineEdit() )->dropEvent( event.get() ); + QCOMPARE( w->lineEdit()->text(), TEST_DATA_DIR + QStringLiteral( "/bug5598.shp" ) ); + + // with file filter + w->setFilter( QStringLiteral( "Data (*.shp)" ) ); + w->setFilePath( QString() ); + qobject_cast< QgsFileDropEdit * >( w->lineEdit() )->dropEvent( event.get() ); + QCOMPARE( w->lineEdit()->text(), TEST_DATA_DIR + QStringLiteral( "/bug5598.shp" ) ); + w->setFilePath( QString() ); + // should be rejected, not compatible with filter + mime->setUrls( QList() << QUrl::fromLocalFile( TEST_DATA_DIR + QStringLiteral( "/encoded_html.html" ) ) ); + event.reset( new QDropEvent( QPointF( 1, 1 ), Qt::CopyAction, mime.get(), Qt::LeftButton, Qt::NoModifier ) ); + qobject_cast< QgsFileDropEdit * >( w->lineEdit() )->dropEvent( event.get() ); + QVERIFY( w->lineEdit()->text().isEmpty() ); + // new filter, should be allowed now + w->setFilter( QStringLiteral( "Data (*.shp);;HTML (*.HTML)" ) ); + qobject_cast< QgsFileDropEdit * >( w->lineEdit() )->dropEvent( event.get() ); + QCOMPARE( w->lineEdit()->text(), TEST_DATA_DIR + QStringLiteral( "/encoded_html.html" ) ); + + //try with wildcard filter + w->setFilter( QStringLiteral( "All files (*.*);;Data (*.shp);;HTML (*.HTML)" ) ); + mime->setUrls( QList() << QUrl::fromLocalFile( TEST_DATA_DIR + QStringLiteral( "/bug5598.prj" ) ) ); + event.reset( new QDropEvent( QPointF( 1, 1 ), Qt::CopyAction, mime.get(), Qt::LeftButton, Qt::NoModifier ) ); + qobject_cast< QgsFileDropEdit * >( w->lineEdit() )->dropEvent( event.get() ); + QCOMPARE( w->lineEdit()->text(), TEST_DATA_DIR + QStringLiteral( "/bug5598.prj" ) ); + + // try with folders + w->setStorageMode( QgsFileWidget::GetDirectory ); + w->setFilePath( QString() ); + // should be rejected + qobject_cast< QgsFileDropEdit * >( w->lineEdit() )->dropEvent( event.get() ); + QVERIFY( w->lineEdit()->text().isEmpty() ); + + // but dropping a folder should work + mime->setUrls( QList() << QUrl::fromLocalFile( TEST_DATA_DIR ) ); + event.reset( new QDropEvent( QPointF( 1, 1 ), Qt::CopyAction, mime.get(), Qt::LeftButton, Qt::NoModifier ) ); + qobject_cast< QgsFileDropEdit * >( w->lineEdit() )->dropEvent( event.get() ); + QCOMPARE( w->lineEdit()->text(), QString( TEST_DATA_DIR ) ); + +} QGSTEST_MAIN( TestQgsFileWidget ) #include "testqgsfilewidget.moc" From c3b62ad4ca9bf0532b3227dcde36bdf49fe7fa1b Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Mon, 7 Aug 2017 01:37:19 +1000 Subject: [PATCH 3/3] Customise->Customize --- python/gui/qgsfilewidget.sip | 2 +- src/gui/qgsfilewidget.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python/gui/qgsfilewidget.sip b/python/gui/qgsfilewidget.sip index 616ebae4ec9..45f1904f272 100644 --- a/python/gui/qgsfilewidget.sip +++ b/python/gui/qgsfilewidget.sip @@ -149,7 +149,7 @@ determines if the relative path is with respect to the project path or the defau QLineEdit *lineEdit(); %Docstring - Returns a pointer to the widget's line edit, which can be used to customise + Returns a pointer to the widget's line edit, which can be used to customize the appearance and behavior of the line edit portion of the widget. .. versionadded:: 3.0 :rtype: QLineEdit diff --git a/src/gui/qgsfilewidget.h b/src/gui/qgsfilewidget.h index f4492e33721..74666d5ddfe 100644 --- a/src/gui/qgsfilewidget.h +++ b/src/gui/qgsfilewidget.h @@ -138,7 +138,7 @@ class GUI_EXPORT QgsFileWidget : public QWidget void setRelativeStorage( QgsFileWidget::RelativeStorage relativeStorage ); /** - * Returns a pointer to the widget's line edit, which can be used to customise + * Returns a pointer to the widget's line edit, which can be used to customize * the appearance and behavior of the line edit portion of the widget. * \since QGIS 3.0 */