25 #include <QAbstractListModel> 28 #include <QFileDialog> 29 #include <QModelIndex> 30 #include <QPixmapCache> 38 QgsSvgSelectorLoader::QgsSvgSelectorLoader(
QObject* parent )
41 , mTimerThreshold( 0 )
45 QgsSvgSelectorLoader::~QgsSvgSelectorLoader()
50 void QgsSvgSelectorLoader::run()
54 mTraversedPaths.clear();
62 if ( !mQueuedSvgs.isEmpty() )
65 emit foundSvgs( mQueuedSvgs );
70 void QgsSvgSelectorLoader::stop()
73 while ( isRunning() ) {}
76 void QgsSvgSelectorLoader::loadPath(
const QString& path )
86 Q_FOREACH (
const QString& svgPath, svgPaths )
102 QString canonicalPath = dir.canonicalPath();
103 if ( mTraversedPaths.contains( canonicalPath ) )
106 mTraversedPaths.
insert( canonicalPath );
110 Q_FOREACH (
const QString& item, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
115 QString newPath = dir.path() +
'/' + item;
122 void QgsSvgSelectorLoader::loadImages(
const QString& path )
125 Q_FOREACH (
const QString& item, dir.entryList(
QStringList(
"*.svg" ), QDir::Files ) )
131 QString svgPath = dir.path() +
'/' + item;
135 mQueuedSvgs << svgPath;
139 if ( mTimer.elapsed() > mTimerThreshold && !mQueuedSvgs.isEmpty() )
141 emit foundSvgs( mQueuedSvgs );
147 if ( mTimerThreshold < 1000 )
148 mTimerThreshold *= 2;
161 , mCancelled( false )
166 QgsSvgGroupLoader::~QgsSvgGroupLoader()
171 void QgsSvgGroupLoader::run()
174 mTraversedPaths.clear();
176 while ( !mCancelled && !mParentPaths.isEmpty() )
178 QString parentPath = mParentPaths.takeFirst();
179 loadGroup( parentPath );
183 void QgsSvgGroupLoader::stop()
186 while ( isRunning() ) {}
189 void QgsSvgGroupLoader::loadGroup(
const QString& parentPath )
191 QDir parentDir( parentPath );
194 QString canonicalPath = parentDir.canonicalPath();
195 if ( mTraversedPaths.contains( canonicalPath ) )
198 mTraversedPaths.
insert( canonicalPath );
200 Q_FOREACH (
const QString& item, parentDir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
205 emit foundPath( parentPath, item );
206 mParentPaths.append( parentDir.path() +
'/' + item );
218 , mSvgLoader( new QgsSvgSelectorLoader( this ) )
220 mSvgLoader->setPath(
QString() );
227 , mSvgLoader( new QgsSvgSelectorLoader( this ) )
229 mSvgLoader->setPath( path );
240 QPixmap QgsSvgSelectorListModel::createPreview(
const QString& entry )
const 244 double outlineWidth, fillOpacity, outlineOpacity;
245 bool fillParam, fillOpacityParam, outlineParam, outlineWidthParam, outlineOpacityParam;
246 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultOutlineColor =
false,
247 hasDefaultOutlineWidth =
false, hasDefaultOutlineOpacity =
false;
249 fillOpacityParam, hasDefaultFillOpacity, fillOpacity,
250 outlineParam, hasDefaultOutlineColor, outline,
251 outlineWidthParam, hasDefaultOutlineWidth, outlineWidth,
252 outlineOpacityParam, hasDefaultOutlineOpacity, outlineOpacity );
255 if ( !hasDefaultFillColor )
256 fill =
QColor( 200, 200, 200 );
257 fill.
setAlphaF( hasDefaultFillOpacity ? fillOpacity : 1.0 );
258 if ( !hasDefaultOutlineColor )
260 outline.
setAlphaF( hasDefaultOutlineOpacity ? outlineOpacity : 1.0 );
261 if ( !hasDefaultOutlineWidth )
273 if ( role == Qt::DecorationRole )
278 pixmap = createPreview( entry );
284 else if ( role == Qt::UserRole || role == Qt::ToolTipRole )
292 void QgsSvgSelectorListModel::addSvgs(
const QStringList& svgs )
307 , mLoader( new QgsSvgGroupLoader( this ) )
313 for (
int i = 0; i < svgPaths.
size(); i++ )
315 QDir dir( svgPaths.
at( i ) );
331 baseGroup->setEditable(
false );
332 baseGroup->setCheckable(
false );
334 baseGroup->setToolTip( dir.path() );
336 parentPaths << svgPaths.
at( i );
337 mPathItemHash.
insert( svgPaths.
at( i ), baseGroup );
338 QgsDebugMsg(
QString(
"SVG base path %1: %2" ).arg( i ).arg( baseGroup->data().toString() ) );
340 mLoader->setParentPaths( parentPaths );
350 void QgsSvgSelectorGroupsModel::addPath(
const QString& parentPath,
const QString& item )
364 mPathItemHash.
insert( fullPath, group );
376 mGroupsTreeView->setHeaderHidden(
true );
380 this, SLOT( svgSelectionChanged(
const QModelIndex& ) ) );
382 this, SLOT( populateIcons(
const QModelIndex& ) ) );
386 || settings.value(
"/Windows/SvgSelectorWidget/RelativePath" ).toBool() );
387 mRelativePathChkBx->setChecked( useRelativePath );
393 settings.
setValue(
"/Windows/SvgSelectorWidget/RelativePath", mRelativePathChkBx->isChecked() );
401 if ( !svgPath.
contains(
"://" ) || ( svgPath.
contains(
"file://", Qt::CaseInsensitive ) ) )
404 if ( !resolvedPath.
isNull() )
406 updatedPath = resolvedPath;
410 mCurrentSvgPath = updatedPath;
412 mFileLineEdit->blockSignals(
true );
413 mFileLineEdit->setText( updatedPath );
414 mFileLineEdit->blockSignals(
false );
416 mImagesListView->selectionModel()->blockSignals(
true );
419 for (
int i = 0; i < m->
rowCount(); i++ )
424 selModel->
select( idx, QItemSelectionModel::SelectCurrent );
426 mImagesListView->scrollTo( idx );
430 mImagesListView->selectionModel()->blockSignals(
false );
435 if ( mRelativePathChkBx->isChecked() )
438 return mCurrentSvgPath;
446 void QgsSvgSelectorWidget::updateCurrentSvgPath(
const QString& svgPath )
448 mCurrentSvgPath = svgPath;
452 void QgsSvgSelectorWidget::svgSelectionChanged(
const QModelIndex& idx )
455 mFileLineEdit->setText( filePath );
456 updateCurrentSvgPath( filePath );
459 void QgsSvgSelectorWidget::populateIcons(
const QModelIndex& idx )
465 mImagesListView->setModel( m );
469 this, SLOT( svgSelectionChanged(
const QModelIndex& ) ) );
473 void QgsSvgSelectorWidget::on_mFilePushButton_clicked()
478 QString lineEditText = mFileLineEdit->text();
481 QFileInfo openDirFileInfo( lineEditText );
482 openDir = openDirFileInfo.
path();
486 tr(
"Select SVG file" ),
488 tr(
"SVG files" ) +
" (*.svg *.SVG)" );
498 updateCurrentSvgPath(
QString() );
499 updateLineEditFeedback(
false );
503 mFileLineEdit->setText( file );
504 updateCurrentSvgPath( file );
507 void QgsSvgSelectorWidget::updateLineEditFeedback(
bool ok,
const QString& tip )
510 mFileLineEdit->setStyleSheet(
QString( !ok ?
"QLineEdit{ color: rgb(225, 0, 0); }" :
"" ) );
511 mFileLineEdit->setToolTip( !ok ?
tr(
"File not found" ) : tip );
514 void QgsSvgSelectorWidget::on_mFileLineEdit_textChanged(
const QString& text )
517 bool validSVG = !resolvedPath.
isNull();
519 updateLineEditFeedback( validSVG, resolvedPath );
520 updateCurrentSvgPath( validSVG ? resolvedPath :
QString() );
526 mGroupsTreeView->setModel( g );
529 for (
int i = 0; i < rows; i++ )
537 mImagesListView->setModel( m );
545 Qt::Orientation orientation )
549 Q_UNUSED( orientation );
QgsSvgSelectorWidget * mSvgSelector
QByteArray toByteArray() const
virtual int rowCount(const QModelIndex &parent) const=0
iterator insert(const Key &key, const T &value)
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const=0
void setIcon(const QIcon &icon)
static QString qgisSettingsDirPath()
Returns the path to the settings directory in user's home dir.
bool readBoolEntry(const QString &scope, const QString &key, bool def=false, bool *ok=nullptr) const
A model for displaying SVG files with a preview icon.
QStandardItem * invisibleRootItem() const
const T & at(int i) const
QgsSvgSelectorGroupsModel(QObject *parent)
QPixmap fromImage(const QImage &image, QFlags< Qt::ImageConversionFlag > flags)
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasOutlineParam, QColor &defaultOutlineColor, bool &hasOutlineWidthParam, double &defaultOutlineWidth) const
Tests if an svg file contains parameters for fill, outline color, outline width.
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
QString tr(const char *sourceText, const char *disambiguation, int n)
virtual void setData(const QVariant &value, int role)
static QgsSvgCache * instance()
void setValue(const QString &key, const QVariant &value)
int rowCount(const QModelIndex &parent=QModelIndex()) const override
const QImage & svgAsImage(const QString &file, double size, const QColor &fill, const QColor &outline, double outlineWidth, double widthScaleFactor, double rasterScaleFactor, bool &fitsInCache)
Get SVG as QImage.
static QString symbolPathToName(QString path)
Get symbols's name from its path.
int count(const T &value) const
void append(const T &value)
QString & insert(int position, QChar ch)
QModelIndex indexFromItem(const QStandardItem *item) const
QDialogButtonBox * mButtonBox
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const
void appendRow(const QList< QStandardItem * > &items)
virtual void select(const QModelIndex &index, QFlags< QItemSelectionModel::SelectionFlag > command)
static QString symbolNameToPath(QString name)
Get symbol's path from its name.
virtual QVariant data(const QModelIndex &index, int role) const=0
~QgsSvgSelectorGroupsModel()
QgsSvgSelectorDialog(QWidget *parent=nullptr, const Qt::WindowFlags &fl=QgisGui::ModalDialogFlags, const QDialogButtonBox::StandardButtons &buttons=QDialogButtonBox::Close|QDialogButtonBox::Ok, Qt::Orientation orientation=Qt::Horizontal)
const T value(const Key &key) const
QStandardItem * item(int row, int column) const
static QString pkgDataPath()
Returns the common root path of all application data directories.
bool contains(QChar ch, Qt::CaseSensitivity cs) const
QgsSvgSelectorListModel(QObject *parent)
Constructor for QgsSvgSelectorListModel.
void beginInsertRows(const QModelIndex &parent, int first, int last)
A model for displaying SVG search paths.
QVariant value(const QString &key, const QVariant &defaultValue) const
QVariant data(int role) const
static QgsProject * instance()
Returns the QgsProject singleton instance.
QPixmap * find(const QString &key)
virtual int rowCount(const QModelIndex &parent) const
static QStringList svgPaths()
Returns the pathes to svg directories.
void setAlphaF(qreal alpha)
void setCurrentIndex(const QModelIndex &index, QFlags< QItemSelectionModel::SelectionFlag > command)
QString getOpenFileName(QWidget *parent, const QString &caption, const QString &dir, const QString &filter, QString *selectedFilter, QFlags< QFileDialog::Option > options)
bool insert(const QString &key, const QPixmap &pixmap)
QString absolutePath() const
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setCheckable(bool checkable)
void setEditable(bool editable)