summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/coreplugin/fileiconprovider.cpp185
-rw-r--r--src/plugins/coreplugin/fileiconprovider.h40
-rw-r--r--src/plugins/cppeditor/cppplugin.cpp4
-rw-r--r--src/plugins/projectexplorer/foldernavigationwidget.cpp17
-rw-r--r--src/plugins/projectexplorer/foldernavigationwidget.h6
5 files changed, 164 insertions, 88 deletions
diff --git a/src/plugins/coreplugin/fileiconprovider.cpp b/src/plugins/coreplugin/fileiconprovider.cpp
index 5615fb81d9..03bfb56cf4 100644
--- a/src/plugins/coreplugin/fileiconprovider.cpp
+++ b/src/plugins/coreplugin/fileiconprovider.cpp
@@ -30,68 +30,138 @@
#include "fileiconprovider.h"
#include "mimedatabase.h"
+#include <utils/qtcassert.h>
+
#include <QtGui/QApplication>
#include <QtGui/QStyle>
#include <QtGui/QPainter>
+#include <QtCore/QFileInfo>
+#include <QtCore/QPair>
+#include <QtCore/QDebug>
-using namespace Core;
+#include <QtGui/QFileIconProvider>
+#include <QtGui/QIcon>
+#include <QtGui/QStyle>
/*!
\class FileIconProvider
- Provides icons based on file suffixes.
+ Provides icons based on file suffixes with the ability to overwrite system
+ icons for specific subtypes. Implements the QFileIconProvider interface
+ and can therefore be used for QFileSystemModel.
+
+ Note: Registering overlay icons currently completely replaces the system
+ icon and is therefore not recommended on platforms that have their
+ own overlay icon handling (Mac/Windows).
The class is a singleton: It's instance can be accessed via the static instance() method.
Plugins can register custom icons via registerIconSuffix(), and retrieve icons via the icon()
method.
+ The instance is explicitly deleted by the core plugin for destruction order reasons.
*/
-FileIconProvider *FileIconProvider::m_instance = 0;
+// Cache icons in a list of pairs suffix/icon which should be faster than
+// hashes for small lists.
+
+enum { debug = 0 };
+
+typedef QPair<QString, QIcon> StringIconPair;
+typedef QList<StringIconPair> StringIconPairList;
+
+// Helper to find an icon by suffix in a list of pairs for const/non-const-iterators.
+
+template <class StringIconPairListIterator>
+inline StringIconPairListIterator
+findBySuffix(const QString &suffix,
+ StringIconPairListIterator iter,
+ const StringIconPairListIterator &end)
+{
+ for (; iter != end; ++iter)
+ if ((*iter).first == suffix)
+ return iter;
+ return end;
+}
+
+namespace Core {
+
+struct FileIconProviderPrivate {
+ FileIconProviderPrivate();
+
+ // Mapping of file suffix to icon.
+ StringIconPairList m_cache;
-FileIconProvider::FileIconProvider()
- : m_unknownFileIcon(qApp->style()->standardIcon(QStyle::SP_FileIcon))
+ QFileIconProvider m_systemIconProvider;
+ QIcon m_unknownFileIcon;
+
+ // singleton pattern
+ static FileIconProvider *m_instance;
+};
+
+FileIconProviderPrivate::FileIconProviderPrivate() :
+ m_unknownFileIcon(qApp->style()->standardIcon(QStyle::SP_FileIcon))
+{
+}
+
+FileIconProvider *FileIconProviderPrivate::m_instance = 0;
+
+// FileIconProvider
+
+FileIconProvider::FileIconProvider() :
+ d(new FileIconProviderPrivate)
{
+ FileIconProviderPrivate::m_instance = this;
}
FileIconProvider::~FileIconProvider()
{
- m_instance = 0;
+ FileIconProviderPrivate::m_instance = 0;
+ delete d;
}
/*!
Returns the icon associated with the file suffix in fileInfo. If there is none,
the default icon of the operating system is returned.
*/
-QIcon FileIconProvider::icon(const QFileInfo &fileInfo)
-{
- const QString suffix = fileInfo.suffix();
- QIcon icon = iconForSuffix(suffix);
-
- if (icon.isNull()) {
- // Get icon from OS and store it in the cache
- // Disabled since for now we'll make sure that all icons fit with our
- // own custom icons by returning an empty one if we don't know it.
+QIcon FileIconProvider::icon(const QFileInfo &fileInfo) const
+{
+ typedef StringIconPairList::const_iterator CacheConstIterator;
+
+ if (debug)
+ qDebug() << "FileIconProvider::icon" << fileInfo.absoluteFilePath();
+ // Check for cached overlay icons by file suffix.
+ if (!d->m_cache.isEmpty() && !fileInfo.isDir()) {
+ const QString suffix = fileInfo.suffix();
+ if (!suffix.isEmpty()) {
+ const CacheConstIterator it = findBySuffix(suffix, d->m_cache.constBegin(), d->m_cache.constEnd());
+ if (it != d->m_cache.constEnd())
+ return (*it).second;
+ }
+ }
+ // Get icon from OS.
#if defined(Q_WS_WIN) || defined(Q_WS_MAC)
- // This is incorrect if the OS does not always return the same icon for the
- // same suffix (Mac OS X), but should speed up the retrieval a lot ...
- icon = m_systemIconProvider.icon(fileInfo);
- if (!suffix.isEmpty())
- registerIconOverlayForSuffix(icon, suffix);
+ return d->m_systemIconProvider.icon(fileInfo);
#else
- if (fileInfo.isDir()) {
- icon = m_systemIconProvider.icon(fileInfo);
- } else {
- icon = m_unknownFileIcon;
- }
+ // File icons are unknown on linux systems.
+ return (fileInfo.isDir()) ?
+ d->m_systemIconProvider.icon(fileInfo) :
+ d->m_unknownFileIcon;
#endif
- }
+}
+
+QIcon FileIconProvider::icon(IconType type) const
+{
+ return d->m_systemIconProvider.icon(type);
+}
- return icon;
+QString FileIconProvider::type(const QFileInfo &info) const
+{
+ return d->m_systemIconProvider.type(info);
}
/*!
Creates a pixmap with baseicon at size and overlays overlayIcon over it.
+ See platform note in class documentation about recommended usage.
*/
QPixmap FileIconProvider::overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlayIcon, const QSize &size) const
{
@@ -104,21 +174,26 @@ QPixmap FileIconProvider::overlayIcon(QStyle::StandardPixmap baseIcon, const QIc
/*!
Registers an icon for a given suffix, overlaying the system file icon.
+ See platform note in class documentation about recommended usage.
*/
-void FileIconProvider::registerIconOverlayForSuffix(const QIcon &icon, const QString &suffix)
+void FileIconProvider::registerIconOverlayForSuffix(const QIcon &icon,
+ const QString &suffix)
{
- QPixmap fileIconPixmap = overlayIcon(QStyle::SP_FileIcon, icon, QSize(16, 16));
- // delete old icon, if it exists
- QList<QPair<QString,QIcon> >::iterator iter = m_cache.begin();
- for (; iter != m_cache.end(); ++iter) {
- if ((*iter).first == suffix) {
- iter = m_cache.erase(iter);
- break;
- }
- }
+ typedef StringIconPairList::iterator CacheIterator;
- QPair<QString,QIcon> newEntry(suffix, fileIconPixmap);
- m_cache.append(newEntry);
+ if (debug)
+ qDebug() << "FileIconProvider::registerIconOverlayForSuffix" << suffix;
+
+ QTC_ASSERT(!icon.isNull() && !suffix.isEmpty(), return)
+
+ const QPixmap fileIconPixmap = overlayIcon(QStyle::SP_FileIcon, icon, QSize(16, 16));
+ // replace old icon, if it exists
+ const CacheIterator it = findBySuffix(suffix, d->m_cache.begin(), d->m_cache.end());
+ if (it == d->m_cache.end()) {
+ d->m_cache.append(StringIconPair(suffix, fileIconPixmap));
+ } else {
+ (*it).second = fileIconPixmap;
+ }
}
/*!
@@ -131,34 +206,14 @@ void FileIconProvider::registerIconOverlayForMimeType(const QIcon &icon, const M
}
/*!
- Returns an icon for the given suffix, or an empty one if none registered.
- */
-QIcon FileIconProvider::iconForSuffix(const QString &suffix) const
-{
- QIcon icon;
-#if defined(Q_WS_WIN) || defined(Q_WS_MAC) // On Windows and Mac we use the file system icons
- Q_UNUSED(suffix)
-#else
- if (suffix.isEmpty())
- return icon;
-
- QList<QPair<QString,QIcon> >::const_iterator iter = m_cache.constBegin();
- for (; iter != m_cache.constEnd(); ++iter) {
- if ((*iter).first == suffix) {
- icon = (*iter).second;
- break;
- }
- }
-#endif
- return icon;
-}
-
-/*!
Returns the sole instance of FileIconProvider.
*/
+
FileIconProvider *FileIconProvider::instance()
{
- if (!m_instance)
- m_instance = new FileIconProvider;
- return m_instance;
+ if (!FileIconProviderPrivate::m_instance)
+ FileIconProviderPrivate::m_instance = new FileIconProvider;
+ return FileIconProviderPrivate::m_instance;
}
+
+} // namespace core
diff --git a/src/plugins/coreplugin/fileiconprovider.h b/src/plugins/coreplugin/fileiconprovider.h
index a4973399c1..a86f895a8f 100644
--- a/src/plugins/coreplugin/fileiconprovider.h
+++ b/src/plugins/coreplugin/fileiconprovider.h
@@ -32,22 +32,35 @@
#include <coreplugin/core_global.h>
-#include <QtCore/QFileInfo>
-#include <QtCore/QPair>
-#include <QtGui/QFileIconProvider>
-#include <QtGui/QIcon>
#include <QtGui/QStyle>
+#include <QtGui/QFileIconProvider>
+
+QT_BEGIN_NAMESPACE
+class QFileInfo;
+class QIcon;
+class QPixmap;
+class QString;
+QT_END_NAMESPACE
namespace Core {
class MimeType;
+struct FileIconProviderPrivate;
-class CORE_EXPORT FileIconProvider
+class CORE_EXPORT FileIconProvider : public QFileIconProvider
{
+ Q_DISABLE_COPY(FileIconProvider)
+ FileIconProvider();
+
public:
- ~FileIconProvider(); // used to clear the cache
- QIcon icon(const QFileInfo &fileInfo);
+ virtual ~FileIconProvider();
+ // Implement QFileIconProvider
+ virtual QIcon icon(IconType type) const;
+ virtual QIcon icon(const QFileInfo &info) const;
+ virtual QString type(const QFileInfo &info) const;
+
+ // Register additional overlay icons
QPixmap overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlayIcon, const QSize &size) const;
void registerIconOverlayForSuffix(const QIcon &icon, const QString &suffix);
void registerIconOverlayForMimeType(const QIcon &icon, const MimeType &mimeType);
@@ -55,18 +68,7 @@ public:
static FileIconProvider *instance();
private:
- QIcon iconForSuffix(const QString &suffix) const;
-
- // mapping of file ending to icon
- // TODO: Check if this is really faster than a QHash
- mutable QList<QPair<QString, QIcon> > m_cache;
-
- QFileIconProvider m_systemIconProvider;
- QIcon m_unknownFileIcon;
-
- // singleton pattern
- FileIconProvider();
- static FileIconProvider *m_instance;
+ FileIconProviderPrivate *d;
};
} // namespace Core
diff --git a/src/plugins/cppeditor/cppplugin.cpp b/src/plugins/cppeditor/cppplugin.cpp
index d3f5b2a3e4..ace3b776d8 100644
--- a/src/plugins/cppeditor/cppplugin.cpp
+++ b/src/plugins/cppeditor/cppplugin.cpp
@@ -75,7 +75,7 @@ CppEditorFactory::CppEditorFactory(CppPlugin *owner) :
<< QLatin1String(CppEditor::Constants::CPP_SOURCE_MIMETYPE)
<< QLatin1String(CppEditor::Constants::CPP_HEADER_MIMETYPE);
-#ifndef Q_WS_MAC
+#if !defined(Q_WS_MAC) && !defined(Q_WS_WIN)
Core::FileIconProvider *iconProvider = Core::FileIconProvider::instance();
Core::MimeDatabase *mimeDatabase = Core::ICore::instance()->mimeDatabase();
iconProvider->registerIconOverlayForMimeType(QIcon(":/cppeditor/images/qt_cpp.png"),
@@ -89,7 +89,7 @@ CppEditorFactory::CppEditorFactory(CppPlugin *owner) :
QString CppEditorFactory::id() const
{
- return QLatin1String(QLatin1String(CppEditor::Constants::CPPEDITOR_ID));
+ return QLatin1String(CppEditor::Constants::CPPEDITOR_ID);
}
QString CppEditorFactory::displayName() const
diff --git a/src/plugins/projectexplorer/foldernavigationwidget.cpp b/src/plugins/projectexplorer/foldernavigationwidget.cpp
index eb30b850bb..0e6bed1c4f 100644
--- a/src/plugins/projectexplorer/foldernavigationwidget.cpp
+++ b/src/plugins/projectexplorer/foldernavigationwidget.cpp
@@ -33,6 +33,7 @@
#include "environment.h"
#include <coreplugin/icore.h>
+#include <coreplugin/fileiconprovider.h>
#include <coreplugin/filemanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/coreconstants.h>
@@ -100,9 +101,11 @@ FolderNavigationWidget::FolderNavigationWidget(QWidget *parent)
m_fileSystemModel(new QFileSystemModel(this)),
m_filterModel(new DotRemovalFilter(this)),
m_title(new QLabel(this)),
- m_autoSync(false)
+ m_autoSync(false),
+ m_autoSyncAction(0)
{
m_fileSystemModel->setResolveSymlinks(false);
+ m_fileSystemModel->setIconProvider(Core::FileIconProvider::instance());
QDir::Filters filters = QDir::AllDirs | QDir::Files | QDir::Drives
| QDir::Readable| QDir::Writable
| QDir::Executable | QDir::Hidden;
@@ -158,6 +161,9 @@ void FolderNavigationWidget::setAutoSynchronization(bool sync)
disconnect(fileManager, SIGNAL(currentFileChanged(QString)),
this, SLOT(setCurrentFile(QString)));
}
+
+ if (m_autoSyncAction && m_autoSyncAction->isChecked() != m_autoSync)
+ m_autoSyncAction->setChecked(m_autoSync);
}
void FolderNavigationWidget::setCurrentFile(const QString &filePath)
@@ -280,6 +286,15 @@ void FolderNavigationWidget::contextMenuEvent(QContextMenuEvent *ev)
actionTerminal->setEnabled(hasCurrentItem);
// Open file dialog to choose a path starting from current
QAction *actionChooseFolder = menu.addAction(tr("Choose folder..."));
+ // Sync checkable action
+ if (!m_autoSyncAction) {
+ m_autoSyncAction = new QAction(tr("Synchronize"), this);
+ m_autoSyncAction->setCheckable(true);
+ m_autoSyncAction->setChecked(autoSynchronization());
+ connect(m_autoSyncAction, SIGNAL(toggled(bool)), this, SLOT(setAutoSynchronization(bool)));
+ }
+ menu.addSeparator();
+ menu.addAction(m_autoSyncAction);
QAction *action = menu.exec(ev->globalPos());
if (!action)
diff --git a/src/plugins/projectexplorer/foldernavigationwidget.h b/src/plugins/projectexplorer/foldernavigationwidget.h
index cfb4f8870f..f63524105d 100644
--- a/src/plugins/projectexplorer/foldernavigationwidget.h
+++ b/src/plugins/projectexplorer/foldernavigationwidget.h
@@ -41,6 +41,7 @@ class QSortFilterProxyModel;
class QModelIndex;
class QFileSystemModel;
class QDir;
+class QAction;
QT_END_NAMESPACE
namespace ProjectExplorer {
@@ -54,11 +55,12 @@ namespace Internal {
class FolderNavigationWidget : public QWidget
{
Q_OBJECT
+ Q_PROPERTY(bool autoSynchronization READ autoSynchronization WRITE setAutoSynchronization)
public:
FolderNavigationWidget(QWidget *parent = 0);
bool autoSynchronization() const;
- void setAutoSynchronization(bool sync);
+
// Helpers for common directory browser options.
static void showInGraphicalShell(QWidget *parent, const QString &path);
@@ -68,6 +70,7 @@ public:
static QString msgTerminalAction();
public slots:
+ void setAutoSynchronization(bool sync);
void toggleAutoSynchronization();
private slots:
@@ -90,6 +93,7 @@ private:
QSortFilterProxyModel *m_filterModel;
QLabel *m_title;
bool m_autoSync;
+ QAction *m_autoSyncAction;
};
class FolderNavigationWidgetFactory : public Core::INavigationWidgetFactory