20 #include <QToolButton>    22 #include <QFileDialog>    23 #include <QGridLayout>    38   setBackgroundRole( QPalette::Window );
    39   setAutoFillBackground( 
true );
    41   mLayout = 
new QHBoxLayout();
    42   mLayout->setMargin( 0 );
    45   mLinkLabel = 
new QLabel( 
this );
    47   mLinkLabel->setOpenExternalLinks( 
true );
    50   mLinkLabel->setEnabled( 
true );
    51   mLinkLabel->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
    52   mLinkLabel->setTextFormat( Qt::RichText );
    56   mLineEdit = 
new QgsFileDropEdit( 
this );
    57   mLineEdit->setDragEnabled( 
true );
    58   mLineEdit->setToolTip( tr( 
"Full path to the file(s), including name and extension" ) );
    59   connect( mLineEdit, &QLineEdit::textChanged, 
this, &QgsFileWidget::textEdited );
    60   mLayout->addWidget( mLineEdit );
    62   mFileWidgetButton = 
new QToolButton( 
this );
    63   mFileWidgetButton->setText( QChar( 0x2026 ) );
    64   mFileWidgetButton->setToolTip( tr( 
"Browse" ) );
    65   connect( mFileWidgetButton, &QAbstractButton::clicked, 
this, &QgsFileWidget::openFileDialog );
    66   mLayout->addWidget( mFileWidgetButton );
    79   const QStringList pathParts = path.split( QRegExp( 
"\"\\s+\"" ), QString::SkipEmptyParts );
    80   for ( 
const auto &pathsPart : pathParts )
    82     QString cleaned = pathsPart;
    83     cleaned.remove( QRegExp( 
"(^\\s*\")|(\"\\s*)" ) );
    84     paths.append( cleaned );
    97   mLineEdit->setValue( path );
   103   mFileWidgetButton->setEnabled( !readOnly );
   104   mLineEdit->setEnabled( !readOnly );
   114   mDialogTitle = title;
   125   mLineEdit->setFilters( filters );
   130   return mButtonVisible;
   135   mButtonVisible = visible;
   136   mFileWidgetButton->setVisible( visible );
   139 void QgsFileWidget::textEdited( 
const QString &path )
   142   mLinkLabel->setText( toUrl( path ) );
   144   if ( path.contains( QStringLiteral( 
"\" \"" ) ) )
   146     mLineEdit->setToolTip( tr( 
"Selected files:<br><ul><li>%1</li></ul><br>" ).arg( 
splitFilePaths( path ).join( QStringLiteral( 
"</li><li>" ) ) ) );
   150     mLineEdit->setToolTip( QString() );
   163   mLinkLabel->setVisible( mUseLink );
   164   mLineEdit->setVisible( !mUseLink );
   167     mLayout->removeWidget( mLineEdit );
   168     mLayout->insertWidget( 0, mLinkLabel );
   172     mLayout->removeWidget( mLinkLabel );
   173     mLayout->insertWidget( 0, mLineEdit );
   205   mLineEdit->setStorageMode( storageMode );
   210   return mRelativeStorage;
   223 void QgsFileWidget::openFileDialog()
   230   if ( !mFilePath.isEmpty() )
   232     oldPath = relativePath( mFilePath, 
false );
   236   else if ( !mDefaultRoot.isEmpty() )
   238     oldPath = QDir::cleanPath( mDefaultRoot );
   242   QUrl url = QUrl::fromUserInput( oldPath );
   243   if ( !url.isValid() )
   245     QString defPath = QDir::cleanPath( QFileInfo( 
QgsProject::instance()->absoluteFilePath() ).path() );
   246     if ( defPath.isEmpty() )
   248       defPath = QDir::homePath();
   250     oldPath = settings.
value( QStringLiteral( 
"UI/lastFileNameWidgetDir" ), defPath ).toString();
   255   QStringList fileNames;
   259   switch ( mStorageMode )
   262       title = !mDialogTitle.isEmpty() ? mDialogTitle : tr( 
"Select a file" );
   263       fileName = QFileDialog::getOpenFileName( 
this, title, QFileInfo( oldPath ).absoluteFilePath(), mFilter, &mSelectedFilter );
   266       title = !mDialogTitle.isEmpty() ? mDialogTitle : tr( 
"Select one or more files" );
   267       fileNames = QFileDialog::getOpenFileNames( 
this, title, QFileInfo( oldPath ).absoluteFilePath(), mFilter, &mSelectedFilter );
   270       title = !mDialogTitle.isEmpty() ? mDialogTitle : tr( 
"Select a directory" );
   271       fileName = QFileDialog::getExistingDirectory( 
this, title, QFileInfo( oldPath ).absoluteFilePath(),  QFileDialog::ShowDirsOnly );
   275       title = !mDialogTitle.isEmpty() ? mDialogTitle : tr( 
"Create or select a file" );
   278         fileName = QFileDialog::getSaveFileName( 
this, title, QFileInfo( oldPath ).absoluteFilePath(), mFilter, &mSelectedFilter, QFileDialog::DontConfirmOverwrite );
   282         fileName = QFileDialog::getSaveFileName( 
this, title, QFileInfo( oldPath ).absoluteFilePath(), mFilter, &mSelectedFilter );
   293   if ( fileName.isEmpty() && fileNames.isEmpty( ) )
   298     fileName = QDir::toNativeSeparators( QDir::cleanPath( QFileInfo( fileName ).absoluteFilePath() ) );
   302     for ( 
int i = 0; i < fileNames.length(); i++ )
   304       fileNames.replace( i, QDir::toNativeSeparators( QDir::cleanPath( QFileInfo( fileNames.at( i ) ).absoluteFilePath() ) ) );
   309   switch ( mStorageMode )
   313       settings.
setValue( QStringLiteral( 
"UI/lastFileNameWidgetDir" ), QFileInfo( fileName ).absolutePath() );
   316       settings.
setValue( QStringLiteral( 
"UI/lastFileNameWidgetDir" ), fileName );
   319       settings.
setValue( QStringLiteral( 
"UI/lastFileNameWidgetDir" ), QFileInfo( fileNames.first( ) ).absolutePath() );
   326     fileName = relativePath( fileName, 
true );
   331     for ( 
int i = 0; i < fileNames.length(); i++ )
   333       fileNames.replace( i, relativePath( fileNames.at( i ), true ) );
   335     if ( fileNames.length() > 1 )
   337       setFilePath( QStringLiteral( 
"\"%1\"" ).arg( fileNames.join( QStringLiteral( 
"\" \"" ) ) ) );
   347 QString QgsFileWidget::relativePath( 
const QString &
filePath, 
bool removeRelative )
 const   349   QString RelativePath;
   352     RelativePath = QDir::toNativeSeparators( QDir::cleanPath( QFileInfo( 
QgsProject::instance()->absoluteFilePath() ).path() ) );
   356     RelativePath = QDir::toNativeSeparators( QDir::cleanPath( mDefaultRoot ) );
   359   if ( !RelativePath.isEmpty() )
   361     if ( removeRelative )
   363       return QDir::cleanPath( QDir( RelativePath ).relativeFilePath( 
filePath ) );
   375 QString QgsFileWidget::toUrl( 
const QString &path )
 const   378   if ( path.isEmpty() )
   383   QString urlStr = relativePath( path, 
false );
   384   QUrl url = QUrl::fromUserInput( urlStr );
   385   if ( !url.isValid() || !url.isLocalFile() )
   387     QgsDebugMsg( QStringLiteral( 
"URL: %1 is not valid or not a local file!" ).arg( path ) );
   391   QString pathStr = url.toString();
   394     rep = QStringLiteral( 
"<a href=\"%1\">%2</a>" ).arg( pathStr, path );
   398     QString fileName = QFileInfo( urlStr ).fileName();
   399     rep = QStringLiteral( 
"<a href=\"%1\">%2</a>" ).arg( pathStr, fileName );
   410 QgsFileDropEdit::QgsFileDropEdit( QWidget *parent )
   414   setAcceptDrops( 
true );
   417 void QgsFileDropEdit::setFilters( 
const QString &filters )
   419   mAcceptableExtensions.clear();
   421   if ( filters.contains( QStringLiteral( 
"*.*" ) ) )
   424   QRegularExpression rx( QStringLiteral( 
"\\*\\.(\\w+)" ) );
   425   QRegularExpressionMatchIterator i = rx.globalMatch( filters );
   426   while ( i.hasNext() )
   428     QRegularExpressionMatch match = i.next();
   429     if ( match.hasMatch() )
   431       mAcceptableExtensions << match.captured( 1 ).toLower();
   436 QString QgsFileDropEdit::acceptableFilePath( QDropEvent *event )
 const   438   QStringList rawPaths;
   440   if ( event->mimeData()->hasUrls() )
   442     const QList< QUrl > urls = 
event->mimeData()->urls();
   443     rawPaths.reserve( urls.count() );
   444     for ( 
const QUrl &url : urls )
   446       const QString local =  url.toLocalFile();
   447       if ( !rawPaths.contains( local ) )
   448         rawPaths.append( local );
   455     if ( !rawPaths.contains( u.uri ) )
   456       rawPaths.append( u.uri );
   459   if ( !event->mimeData()->text().isEmpty() && !rawPaths.contains( event->mimeData()->text() ) )
   460     rawPaths.append( event->mimeData()->text() );
   462   paths.reserve( rawPaths.count() );
   463   for ( 
const QString &path : qgis::as_const( rawPaths ) )
   465     QFileInfo file( path );
   466     switch ( mStorageMode )
   472         if ( file.isFile() && ( mAcceptableExtensions.isEmpty() || mAcceptableExtensions.contains( file.suffix(), Qt::CaseInsensitive ) ) )
   473           paths.append( file.filePath() );
   481           paths.append( file.filePath() );
   482         else if ( file.isFile() )
   485           paths.append( file.absolutePath() );
   493   if ( paths.size() > 1 )
   495     return QStringLiteral( 
"\"%1\"" ).arg( paths.join( QStringLiteral( 
"\" \"" ) ) );
   497   else if ( paths.size() == 1 )
   499     return paths.first();
   507 void QgsFileDropEdit::dragEnterEvent( QDragEnterEvent *event )
   509   QString 
filePath = acceptableFilePath( event );
   510   if ( !filePath.isEmpty() )
   512     event->acceptProposedAction();
   522 void QgsFileDropEdit::dragLeaveEvent( QDragLeaveEvent *event )
   524   QgsFilterLineEdit::dragLeaveEvent( event );
   530 void QgsFileDropEdit::dropEvent( QDropEvent *event )
   532   QString 
filePath = acceptableFilePath( event );
   533   if ( !filePath.isEmpty() )
   537     setFocus( Qt::MouseFocusReason );
   538     event->acceptProposedAction();
   544 void QgsFileDropEdit::paintEvent( QPaintEvent *e )
   546   QgsFilterLineEdit::paintEvent( e );
   551     p.setPen( QPen( palette().highlight(), width ) );
   552     QRect r = rect().adjusted( width, width, -width, -width );
 
This class is a composition of two QSettings instances: 
 
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key. 
 
static UriList decodeUriList(const QMimeData *data)
 
QLineEdit subclass with built in support for clearing the widget's value and handling custom null val...
 
static QString nullRepresentation()
This string is used to represent the value NULL throughout QGIS. 
 
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value. 
 
static QgsProject * instance()
Returns the QgsProject singleton instance. 
 
QList< QgsMimeDataUtils::Uri > UriList
 
static QString addExtensionFromFilter(const QString &fileName, const QString &filter)
Ensures that a fileName ends with an extension from the specified filter string.