Skip to content

Commit

Permalink
QgsFilePicker and QgsExternalResource: new file picker widget and edi…
Browse files Browse the repository at this point in the history
…tor widget for improved file name widget

* QgsFilePicker is intended to be used across whole QGIS application for file picking
  * right now it supports only single file/folder selection
  * it has advanced support of relative path

* QgsExternalRessourceWidget is the pending editor widget which integrates a photo/web viewer
  * it can be properly accessible from the API and custom widgets
  * new class to avoid duplicating code for legacy support
  * old widgets will be removed from QGIS 3 (users will be invited to use the new widget in the config dialog)
  • Loading branch information
3nids committed Jan 13, 2016
1 parent 0034108 commit 29752a3
Show file tree
Hide file tree
Showing 19 changed files with 1,703 additions and 653 deletions.
12 changes: 10 additions & 2 deletions src/gui/CMakeLists.txt
Expand Up @@ -103,7 +103,9 @@ SET(QGIS_GUI_SRCS
editorwidgets/qgsdummyconfigdlg.cpp
editorwidgets/qgsenumerationwidgetwrapper.cpp
editorwidgets/qgsenumerationwidgetfactory.cpp
editorwidgets/qgsfilenameconfigdlg.cpp
editorwidgets/qgsexternalresourceconfigdlg.cpp
editorwidgets/qgsexternalresourcewidgetwrapper.cpp
editorwidgets/qgsexternalresourcewidgetfactory.cpp
editorwidgets/qgsfilenamewidgetwrapper.cpp
editorwidgets/qgsfilenamewidgetfactory.cpp
editorwidgets/qgshiddenwidgetwrapper.cpp
Expand Down Expand Up @@ -190,13 +192,15 @@ SET(QGIS_GUI_SRCS
qgsexpressionhighlighter.cpp
qgsexpressionselectiondialog.cpp
qgsextentgroupbox.cpp
qgsexternalresourcewidget.cpp
qgsfeatureselectiondlg.cpp
qgsfieldcombobox.cpp
qgsfieldexpressionwidget.cpp
qgsfieldmodel.cpp
qgsfieldvalidator.cpp
qgsfieldproxymodel.cpp
qgsfiledropedit.cpp
qgsfilepickerwidget.cpp
qgsfilterlineedit.cpp
qgsformannotationitem.cpp
qgsgenericprojectionselector.cpp
Expand Down Expand Up @@ -326,13 +330,15 @@ SET(QGIS_GUI_MOC_HDRS
qgsexpressionhighlighter.h
qgsexpressionselectiondialog.h
qgsextentgroupbox.h
qgsexternalresourcewidget.h
qgsfeatureselectiondlg.h
qgsfieldcombobox.h
qgsfieldexpressionwidget.h
qgsfieldmodel.h
qgsfieldproxymodel.h
qgsfieldvalidator.h
qgsfiledropedit.h
qgsfilepickerwidget.h
qgsfilterlineedit.h
qgsformannotationitem.h
qgsgenericprojectionselector.h
Expand Down Expand Up @@ -496,7 +502,8 @@ SET(QGIS_GUI_MOC_HDRS
editorwidgets/qgsdoublespinbox.h
editorwidgets/qgsdummyconfigdlg.h
editorwidgets/qgsenumerationwidgetwrapper.h
editorwidgets/qgsfilenameconfigdlg.h
editorwidgets/qgsexternalresourceconfigdlg.h
editorwidgets/qgsexternalresourcewidgetwrapper.h
editorwidgets/qgsfilenamewidgetwrapper.h
editorwidgets/qgshiddenwidgetwrapper.h
editorwidgets/qgsphotoconfigdlg.h
Expand Down Expand Up @@ -599,6 +606,7 @@ SET(QGIS_GUI_HDRS
editorwidgets/qgscolorwidgetfactory.h
editorwidgets/qgsdatetimeeditfactory.h
editorwidgets/qgsenumerationwidgetfactory.h
editorwidgets/qgsexternalresourcewidgetfactory.h
editorwidgets/qgsfilenamewidgetfactory.h
editorwidgets/qgshiddenwidgetfactory.h
editorwidgets/qgsphotowidgetfactory.h
Expand Down
23 changes: 13 additions & 10 deletions src/gui/editorwidgets/core/qgseditorwidgetregistry.cpp
Expand Up @@ -24,23 +24,25 @@

// Editors
#include "qgsclassificationwidgetwrapperfactory.h"
#include "qgsrangewidgetfactory.h"
#include "qgsuniquevaluewidgetfactory.h"
#include "qgsfilenamewidgetfactory.h"
#include "qgsvaluemapwidgetfactory.h"
#include "qgscheckboxwidgetfactory.h"
#include "qgscolorwidgetfactory.h"
#include "qgsdatetimeeditfactory.h"
#include "qgsenumerationwidgetfactory.h"
#include "qgsexternalresourcewidgetfactory.h"
#include "qgsfilenamewidgetfactory.h"
#include "qgshiddenwidgetfactory.h"
#include "qgscheckboxwidgetfactory.h"
#include "qgsphotowidgetfactory.h"
#include "qgsrangewidgetfactory.h"
#include "qgsrelationreferencefactory.h"
#include "qgstexteditwidgetfactory.h"
#include "qgsvaluerelationwidgetfactory.h"
#include "qgsuniquevaluewidgetfactory.h"
#include "qgsuuidwidgetfactory.h"
#include "qgsphotowidgetfactory.h"
#include "qgsvaluemapwidgetfactory.h"
#include "qgsvaluerelationwidgetfactory.h"
#ifdef WITH_QTWEBKIT
#include "qgswebviewwidgetfactory.h"
#endif
#include "qgscolorwidgetfactory.h"
#include "qgsrelationreferencefactory.h"
#include "qgsdatetimeeditfactory.h"


QgsEditorWidgetRegistry* QgsEditorWidgetRegistry::instance()
{
Expand Down Expand Up @@ -69,6 +71,7 @@ void QgsEditorWidgetRegistry::initEditors( QgsMapCanvas *mapCanvas, QgsMessageBa
reg->registerWidget( "Color", new QgsColorWidgetFactory( tr( "Color" ) ) );
reg->registerWidget( "RelationReference", new QgsRelationReferenceFactory( tr( "Relation Reference" ), mapCanvas, messageBar ) );
reg->registerWidget( "DateTime", new QgsDateTimeEditFactory( tr( "Date/Time" ) ) );
reg->registerWidget( "ExternalResource", new QgsExternalResourceWidgetFactory( tr( "External Resource" ) ) );
}

QgsEditorWidgetRegistry::QgsEditorWidgetRegistry()
Expand Down
211 changes: 211 additions & 0 deletions src/gui/editorwidgets/qgsexternalresourceconfigdlg.cpp
@@ -0,0 +1,211 @@
/***************************************************************************
qgsexternalresourceconfigdlg.cpp
--------------------------------------
Date : 2015-11-26
Copyright : (C) 2015 Médéric Ribreux
Email : mederic.ribreux at medspx dot fr
***************************************************************************
* *
* 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 "qgsexternalresourceconfigdlg.h"
#include "qgsexternalresourcewidget.h"
#include "qgsproject.h"

#include <QFileDialog>
#include <QSettings>

class QgsExternalResourceWidgetWrapper;

QgsExternalResourceConfigDlg::QgsExternalResourceConfigDlg( QgsVectorLayer* vl, int fieldIdx, QWidget* parent )
: QgsEditorConfigWidget( vl, fieldIdx, parent )
{
setupUi( this );

// By default, uncheck some options
mUseLink->setChecked( false );
mFullUrl->setChecked( false );
mDocumentViewerGroupBox->setChecked( false );
mRootPath->setPlaceholderText( QSettings().value( "/UI/lastExternalResourceWidgetDir", QDir::toNativeSeparators( QDir::cleanPath( QgsProject::instance()->fileInfo().absolutePath() ) ) ).toString() );

// Add connection to button for choosing default path
connect( mRootPathButton, SIGNAL( clicked() ), this, SLOT( chooseDefaultPath() ) );

// Activate Relative Default Path option only if Default Path is set
connect( mRootPath, SIGNAL( textChanged( const QString & ) ), this, SLOT( enableRelativeDefault() ) );

// Dynamic GroupBox for relative paths option
connect( mRelativeGroupBox, SIGNAL( toggled( bool ) ), this, SLOT( enableRelative( bool ) ) );

// set ids for StorageTypeButtons
mStorageButtonGroup->setId( mStoreFilesButton, QgsFilePickerWidget::File );
mStorageButtonGroup->setId( mStoreDirsButton, QgsFilePickerWidget::Directory );
mStoreFilesButton->setChecked( true );

// set ids for RelativeButtons
mRelativeButtonGroup->setId( mRelativeProject, QgsFilePickerWidget::RelativeProject );
mRelativeButtonGroup->setId( mRelativeDefault, QgsFilePickerWidget::RelativeDefaultPath );
mRelativeProject->setChecked( true );

mDocumentViewerContentComboBox->addItem( tr( "Image" ), QgsExternalResourceWidget::Image );
mDocumentViewerContentComboBox->addItem( tr( "Web view" ), QgsExternalResourceWidget::Web );
}

void QgsExternalResourceConfigDlg::chooseDefaultPath()
{
QString dir;
if ( !mRootPath->text().isEmpty() )
dir = mRootPath->text();
else
dir = QSettings().value( "/UI/lastExternalResourceWidgetDir", QDir::toNativeSeparators( QDir::cleanPath( QgsProject::instance()->fileInfo().absolutePath() ) ) ).toString();

QString rootName = QFileDialog::getExistingDirectory( this, tr( "Select a directory" ), dir, QFileDialog::ShowDirsOnly );

if ( rootName.isNull() )
return;

mRootPath->setText( rootName );
}

void QgsExternalResourceConfigDlg::enableRelativeDefault()
{
// Activate (or not) the RelativeDefault button if default path
if ( mRelativeGroupBox->isChecked() )
mRelativeDefault->setEnabled( !mRootPath->text().isEmpty() );

// If no default path, RelativeProj button enabled by default
if ( mRootPath->text().isEmpty() )
mRelativeProject->toggle();
}

void QgsExternalResourceConfigDlg::enableRelative( bool state )
{
if ( state )
{
mRelativeProject->setEnabled( true );
if ( mRootPath->text().isEmpty() )
mRelativeDefault->setEnabled( false );
else
mRelativeDefault->setEnabled( true );
}
else
{
mRelativeProject->setEnabled( false );
mRelativeDefault->setEnabled( false );
}
}


QgsEditorWidgetConfig QgsExternalResourceConfigDlg::config()
{
QgsEditorWidgetConfig cfg;

cfg.insert( "FilePicker", mFilePickerGroupBox->isChecked() );
cfg.insert( "FilePickerButton", mFilePickerButton->isChecked() );

if ( mUseLink->isChecked() )
{
cfg.insert( "UseLink", mUseLink->isChecked() );
if ( mFullUrl->isChecked() )
cfg.insert( "FullUrl", mFullUrl->isChecked() );
}

if ( !mRootPath->text().isEmpty() )
{
cfg.insert( "DefaultRoot", mRootPath->text() );
}

// Save Storage Mode
cfg.insert( "StorageMode", mStorageButtonGroup->checkedId() );

// Save Relative Paths option
if ( mRelativeGroupBox->isChecked() )
{
cfg.insert( "RelativeStorage", mRelativeButtonGroup->checkedId() );
}
else
{
cfg.insert( "RelativeStorage", ( int )QgsFilePickerWidget::Absolute );
}

if ( mDocumentViewerGroupBox->isChecked() )
{
cfg.insert( "DocumentViewer", mDocumentViewerContentComboBox->itemData( mDocumentViewerContentComboBox->currentIndex() ).toInt() );
cfg.insert( "DocumentViewerHeight", mDocumentViewerHeight->value() );
cfg.insert( "DocumentViewerWidth", mDocumentViewerWidth->value() );
}
else
{
cfg.insert( "DocumentViewer", ( int )QgsExternalResourceWidget::NoContent );
}

return cfg;
}


void QgsExternalResourceConfigDlg::setConfig( const QgsEditorWidgetConfig& config )
{
if ( config.contains( "FilePicker" ) )
{
mFilePickerGroupBox->setChecked( config.value( "FilePicker" ).toBool() );
}
if ( config.contains( "FilePicker" ) )
{
mFilePickerButton->setChecked( config.value( "FilePickerButton" ).toBool() );
}

if ( config.contains( "UseLink" ) )
{
mUseLink->setChecked( config.value( "UseLink" ).toBool() );
if ( config.contains( "FullUrl" ) )
mFullUrl->setChecked( true );
}

if ( config.contains( "DefaultRoot" ) )
{
mRootPath->setText( config.value( "DefaultRoot" ).toString() );
}

// relative storage
if ( config.contains( "RelativeStorage" ) )
{
int relative = config.value( "RelativeStorage" ).toInt();
if (( QgsFilePickerWidget::RelativeStorage )relative == QgsFilePickerWidget::Absolute )
{
mRelativeGroupBox->setChecked( false );
}
else
{
mRelativeGroupBox->setChecked( true );
mRelativeButtonGroup->button( relative )->setChecked( true );
}
}

// set storage mode
if ( config.contains( "StorageMode" ) )
{
int mode = config.value( "StorageMode" ).toInt();
mStorageButtonGroup->button( mode )->setChecked( true );
}

// Document viewer
if ( config.contains( "DocumentViewer" ) )
{
QgsExternalResourceWidget::DocumentViewerContent content = ( QgsExternalResourceWidget::DocumentViewerContent )config.value( "DocumentViewer" ).toInt();
mDocumentViewerGroupBox->setChecked( content != QgsExternalResourceWidget::NoContent );
mDocumentViewerContentComboBox->setCurrentIndex( mDocumentViewerContentComboBox->findData( content ) );
if ( config.contains( "DocumentViewerHeight" ) )
{
mDocumentViewerHeight->setValue( config.value( "DocumentViewerHeight" ).toInt() );
}
if ( config.contains( "DocumentViewerWidth" ) )
{
mDocumentViewerWidth->setValue( config.value( "DocumentViewerWidth" ).toInt() );
}
}
}
@@ -1,5 +1,5 @@
/***************************************************************************
qgsfilenameconfigdlg.h
qgsexternalresourceconfigdlg.h
--------------------------------------
Date : 2015-11-26
Copyright : (C) 2015 Médéric Ribreux
Expand All @@ -13,34 +13,38 @@
* *
***************************************************************************/

#ifndef QGSFILENAMECONFIGDLG_H
#define QGSFILENAMECONFIGDLG_H
#ifndef QGSEXTERNALRESOURCECONFIGDLG_H
#define QGSEXTERNALRESOURCECONFIGDLG_H

#include "ui_qgsfilenameconfigdlg.h"
#include "ui_qgsexternalresourceconfigdlg.h"

#include "qgseditorconfigwidget.h"
//#include "qgsfilenamewidgetwrapper.h"

/** \class QgsFileNameConfigDlg
/** \class QgsExternalResourceConfigDlg
* \note not available in Python bindings
*/

class GUI_EXPORT QgsFileNameConfigDlg : public QgsEditorConfigWidget, private Ui::QgsFileNameConfigDlg
class GUI_EXPORT QgsExternalResourceConfigDlg : public QgsEditorConfigWidget, private Ui::QgsExternalResourceConfigDlg
{
Q_OBJECT

public:
explicit QgsFileNameConfigDlg( QgsVectorLayer* vl, int fieldIdx, QWidget *parent = 0 );
explicit QgsExternalResourceConfigDlg( QgsVectorLayer* vl, int fieldIdx, QWidget *parent = 0 );

// QgsEditorConfigWidget interface
public:
QgsEditorWidgetConfig config() override;
void setConfig( const QgsEditorWidgetConfig& config ) override;

private slots:
//! Choose a base directory for rootPath
void chooseDefaultPath();

//! Modify RelativeDefault according to mRootPath content
void enableRelativeDefault();

//! Dynamic activation of RelativeGroupBox
void enableRelative( bool state );
};

#endif // QGSFILENAMECONFIGDLG_H
#endif // QGSEXTERNALRESOURCECONFIGDLG_H

0 comments on commit 29752a3

Please sign in to comment.