Skip to content
Permalink
Browse files
[feature] Users can set a custom icon color for different folders
in the browser

Effectively allows users to "tag" folders, aiding in rapid
browser navigation of complex folder structures.
  • Loading branch information
nyalldawson committed May 17, 2021
1 parent 2aa7040 commit be803e935dbdbb10bbdf3c4a0871679e2616fc1c
@@ -859,6 +859,41 @@ Returns the full path to the directory the item represents.

virtual QIcon icon();


QColor iconColor() const;
%Docstring
Returns the directory's icon color.

An invalid color will be returned if the default icon color is used.

.. seealso:: :py:func:`setIconColor`

.. versionadded:: 3.20
%End

void setIconColor( const QColor &color );
%Docstring
Sets the directory's icon ``color``.

Setting an invalid color will cause the default icon color to be used.

This is a transient property, and will not permanently alter the directory's colors
in future QGIS sessions. Use :py:func:`~QgsDirectoryItem.setCustomColor` to permanently set the directory's color.

.. seealso:: :py:func:`iconColor`

.. versionadded:: 3.20
%End

static void setCustomColor( const QString &directory, const QColor &color );
%Docstring
Sets a custom icon ``color`` to use for the items for the corresponding ``directory`` path.

If ``color`` is an invalid color then the default icon color will be used.

.. versionadded:: 3.20
%End

virtual QWidget *paramWidget() /Factory,Deprecated/;

virtual bool hasDragEnabled() const;
@@ -42,6 +42,7 @@
#include "qgsprovidermetadata.h"
#include "qgsnewvectortabledialog.h"
#include "qgsdataitemproviderregistry.h"
#include "qgscolordialog.h"

#include <QFileInfo>
#include <QMenu>
@@ -159,6 +160,7 @@ void QgsAppDirectoryItemGuiProvider::populateContextMenu( QgsDataItem *item, QMe
renameFavorite( favoriteItem );
} );
menu->addAction( actionRename );

QAction *removeFavoriteAction = new QAction( tr( "Remove Favorite" ), menu );
connect( removeFavoriteAction, &QAction::triggered, this, [ = ]
{
@@ -226,6 +228,18 @@ void QgsAppDirectoryItemGuiProvider::populateContextMenu( QgsDataItem *item, QMe
menu->addMenu( hiddenMenu );
}

QAction *actionSetIconColor = new QAction( tr( "Set Color…" ), menu );
if ( directoryItem->iconColor().isValid() )
{
const QPixmap icon = QgsColorButton::createMenuIcon( directoryItem->iconColor(), true );
actionSetIconColor->setIcon( icon );
}
connect( actionSetIconColor, &QAction::triggered, this, [ = ]
{
changeDirectoryColor( directoryItem );
} );
menu->addAction( actionSetIconColor );

QAction *fastScanAction = new QAction( tr( "Fast Scan this Directory" ), menu );
connect( fastScanAction, &QAction::triggered, this, [ = ]
{
@@ -299,6 +313,20 @@ void QgsAppDirectoryItemGuiProvider::renameFavorite( QgsFavoriteItem *favorite )
favorite->rename( dlg.name() );
}

void QgsAppDirectoryItemGuiProvider::changeDirectoryColor( QgsDirectoryItem *item )
{
const QColor oldColor = item->iconColor();

const QColor color = QgsColorDialog::getColor( oldColor, QgisApp::instance(), tr( "Set Color" ), true );
if ( !color.isValid() )
return;

// store new color for directory
item->setCustomColor( item->dirPath(), color );
// and update item's color immediately
item->setIconColor( color );
}

void QgsAppDirectoryItemGuiProvider::hideDirectory( QgsDirectoryItem *item )
{
if ( ! item )
@@ -46,6 +46,7 @@ class QgsAppDirectoryItemGuiProvider : public QObject, public QgsDataItemGuiProv
void addFavorite( QgsDirectoryItem *item );
void removeFavorite( QgsFavoriteItem *favorite );
void renameFavorite( QgsFavoriteItem *favorite );
void changeDirectoryColor( QgsDirectoryItem *favorite );
void hideDirectory( QgsDirectoryItem *item );
void toggleFastScan( QgsDirectoryItem *item );
void showProperties( QgsDirectoryItem *item, QgsDataItemGuiContext context );
@@ -1122,6 +1122,17 @@ QgsDirectoryItem::QgsDirectoryItem( QgsDataItem *parent, const QString &name,
, mDirPath( dirPath )
, mRefreshLater( false )
{
QgsSettings settings;
settings.beginGroup( QStringLiteral( "qgis/browserPathColors" ) );
QString settingKey = mDirPath;
settingKey.replace( '/', QStringLiteral( "|||" ) );
if ( settings.childKeys().contains( settingKey ) )
{
const QString colorString = settings.value( settingKey ).toString();
mIconColor = QColor( colorString );
}
settings.endGroup();

mType = Directory;
init();
}
@@ -1131,6 +1142,33 @@ void QgsDirectoryItem::init()
setToolTip( QDir::toNativeSeparators( mDirPath ) );
}

QColor QgsDirectoryItem::iconColor() const
{
return mIconColor;
}

void QgsDirectoryItem::setIconColor( const QColor &color )
{
if ( color == mIconColor )
return;

mIconColor = color;
emit dataChanged( this );
}

void QgsDirectoryItem::setCustomColor( const QString &directory, const QColor &color )
{
QgsSettings settings;
settings.beginGroup( QStringLiteral( "qgis/browserPathColors" ) );
QString settingKey = directory;
settingKey.replace( '/', QStringLiteral( "|||" ) );
if ( color.isValid() )
settings.setValue( settingKey, color.name( QColor::HexArgb ) );
else
settings.remove( settingKey );
settings.endGroup();
}

QIcon QgsDirectoryItem::icon()
{
if ( mDirPath == QDir::homePath() )
@@ -1149,10 +1187,10 @@ QIcon QgsDirectoryItem::icon()

// loaded? show the open dir icon
if ( state() == Populated )
return openDirIcon();
return openDirIcon( mIconColor, mIconColor.darker() );

// show the closed dir icon
return iconDir();
return iconDir( mIconColor, mIconColor.darker() );
}


@@ -1632,7 +1670,8 @@ void QgsFavoritesItem::renameFavorite( const QString &path, const QString &name
const QString dir = parts.at( 0 );
if ( dir == path )
{
favDirs[i] = QStringLiteral( "%1|||%2" ).arg( path, name );
QStringList newParts { path, name };
favDirs[i] = newParts.join( QStringLiteral( "|||" ) );
break;
}
}
@@ -858,6 +858,39 @@ class CORE_EXPORT QgsDirectoryItem : public QgsDataCollectionItem

bool equal( const QgsDataItem *other ) override;
QIcon icon() override;

/**
* Returns the directory's icon color.
*
* An invalid color will be returned if the default icon color is used.
*
* \see setIconColor()
* \since QGIS 3.20
*/
QColor iconColor() const;

/**
* Sets the directory's icon \a color.
*
* Setting an invalid color will cause the default icon color to be used.
*
* This is a transient property, and will not permanently alter the directory's colors
* in future QGIS sessions. Use setCustomColor() to permanently set the directory's color.
*
* \see iconColor()
* \since QGIS 3.20
*/
void setIconColor( const QColor &color );

/**
* Sets a custom icon \a color to use for the items for the corresponding \a directory path.
*
* If \a color is an invalid color then the default icon color will be used.
*
* \since QGIS 3.20
*/
static void setCustomColor( const QString &directory, const QColor &color );

Q_DECL_DEPRECATED QWidget *paramWidget() override SIP_FACTORY SIP_DEPRECATED;
bool hasDragEnabled() const override { return true; }
QgsMimeDataUtils::UriList mimeUris() const override;
@@ -877,6 +910,7 @@ class CORE_EXPORT QgsDirectoryItem : public QgsDataCollectionItem
QFileSystemWatcher *mFileSystemWatcher = nullptr;
bool mRefreshLater;
QDateTime mLastScan;
QColor mIconColor;
};

/**
@@ -1195,6 +1229,7 @@ class CORE_EXPORT QgsFavoriteItem : public QgsDirectoryItem
private:

QgsFavoritesItem *mFavorites = nullptr;

};
Q_NOWARN_DEPRECATED_POP

@@ -105,7 +105,7 @@ void TestQgsApplication::themeIcon()
QImage im( icon.pixmap( 16, 16 ).toImage() );
QVERIFY( renderCheck( QStringLiteral( "theme_icon" ), im, 0 ) );

// parameterized
// with colors
icon = QgsApplication::getThemeIcon( QStringLiteral( "/mIconFolderParams.svg" ), QColor( 255, 100, 100 ), QColor( 255, 0, 0 ) );
QVERIFY( !icon.isNull() );
im = QImage( icon.pixmap( 16, 16 ).toImage() );

0 comments on commit be803e9

Please sign in to comment.