From a08cb7d52ef48e9c2ef45d0b81903cdf6b1ed90c Mon Sep 17 00:00:00 2001
From: Tobias Hunger <tobias.hunger@theqtcompany.com>
Date: Mon, 2 Nov 2015 17:00:46 +0100
Subject: [PATCH] FolderNodes: Specify filter for Add Existing Directory

Allow foldernodes to specify which files they care for when doing
"Add Existing Directory". Before we used a fixed list with C++ header
and source files, which does make no sense for e.g. adding to resources.

Task-number: QTCREATORBUG-15278
Change-Id: I15dad133391485c2bcebd2d864623304b31b5f8f
Reviewed-by: Niels Weber <niels.weber@theqtcompany.com>
---
 .../projectexplorer/projectexplorer.cpp       |  1 +
 src/plugins/projectexplorer/projectnodes.cpp  | 10 ++++
 src/plugins/projectexplorer/projectnodes.h    |  4 ++
 .../projectexplorer/selectablefilesmodel.cpp  |  5 ++
 .../projectexplorer/selectablefilesmodel.h    |  2 +
 .../pythoneditor/pythoneditorplugin.cpp       |  7 +++
 .../qmakeprojectmanager/qmakenodes.cpp        | 53 +++++++++++++------
 src/plugins/qmakeprojectmanager/qmakenodes.h  |  9 +++-
 src/plugins/resourceeditor/resourcenode.cpp   |  5 ++
 src/plugins/resourceeditor/resourcenode.h     |  2 +
 10 files changed, 79 insertions(+), 19 deletions(-)

diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index dc213d05e4c..69cad4e8242 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -3151,6 +3151,7 @@ void ProjectExplorerPluginPrivate::addExistingDirectory()
     QTC_ASSERT(folderNode, return);
 
     SelectableFilesDialogAddDirectory dialog(directoryFor(ProjectTree::currentNode()), QStringList(), ICore::mainWindow());
+    dialog.setAddFileFilter(folderNode->addFileFilter());
 
     if (dialog.exec() == QDialog::Accepted)
         ProjectExplorerPlugin::addExistingFiles(folderNode, dialog.selectedFiles());
diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp
index 96b39f1312f..83869e5d12e 100644
--- a/src/plugins/projectexplorer/projectnodes.cpp
+++ b/src/plugins/projectexplorer/projectnodes.cpp
@@ -309,6 +309,11 @@ void FolderNode::setIcon(const QIcon &icon)
     m_icon = icon;
 }
 
+QString FolderNode::addFileFilter() const
+{
+    return parentFolderNode()->addFileFilter();
+}
+
 bool FolderNode::addFiles(const QStringList &filePaths, QStringList *notAdded)
 {
     if (projectNode())
@@ -764,6 +769,11 @@ QList<ProjectNode*> SessionNode::projectNodes() const
     return m_projectNodes;
 }
 
+QString SessionNode::addFileFilter() const
+{
+    return QLatin1String("*.c; *.cc; *.cpp; *.cp; *.cxx; *.c++; *.h; *.hh; *.hpp; *.hxx;");
+}
+
 void SessionNode::addProjectNodes(const QList<ProjectNode*> &projectNodes)
 {
     if (!projectNodes.isEmpty()) {
diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h
index ce92457af97..cf6d93dccee 100644
--- a/src/plugins/projectexplorer/projectnodes.h
+++ b/src/plugins/projectexplorer/projectnodes.h
@@ -184,6 +184,8 @@ public:
     void setDisplayName(const QString &name);
     void setIcon(const QIcon &icon);
 
+    virtual QString addFileFilter() const;
+
     virtual bool addFiles(const QStringList &filePaths, QStringList *notAdded = 0);
     virtual bool removeFiles(const QStringList &filePaths, QStringList *notRemoved = 0);
     virtual bool deleteFiles(const QStringList &filePaths);
@@ -294,6 +296,8 @@ public:
 
     QList<ProjectNode*> projectNodes() const;
 
+    QString addFileFilter() const override;
+
     void accept(NodesVisitor *visitor) override;
 
     bool isEnabled() const override { return true; }
diff --git a/src/plugins/projectexplorer/selectablefilesmodel.cpp b/src/plugins/projectexplorer/selectablefilesmodel.cpp
index 7fc1494caa0..ae8b916ba7c 100644
--- a/src/plugins/projectexplorer/selectablefilesmodel.cpp
+++ b/src/plugins/projectexplorer/selectablefilesmodel.cpp
@@ -663,6 +663,11 @@ QStringList SelectableFilesDialogEditFiles::selectedFiles() const
     return m_selectableFilesModel->selectedFiles();
 }
 
+void SelectableFilesDialogEditFiles::setAddFileFilter(const QString &filter)
+{
+    m_showFilesfilterLineEdit->setText(filter);
+}
+
 void SelectableFilesDialogEditFiles::applyFilter()
 {
     const QString showFilesFilter = m_showFilesfilterLineEdit->text();
diff --git a/src/plugins/projectexplorer/selectablefilesmodel.h b/src/plugins/projectexplorer/selectablefilesmodel.h
index dad1d536d33..f267399d562 100644
--- a/src/plugins/projectexplorer/selectablefilesmodel.h
+++ b/src/plugins/projectexplorer/selectablefilesmodel.h
@@ -155,6 +155,8 @@ public:
     ~SelectableFilesDialogEditFiles();
     QStringList selectedFiles() const;
 
+    void setAddFileFilter(const QString &filter);
+
 private slots:
     void applyFilter();
     void parsingProgress(const QString &fileName);
diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp
index 8d147920f18..400f05ba93e 100644
--- a/src/plugins/pythoneditor/pythoneditorplugin.cpp
+++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp
@@ -337,6 +337,8 @@ public:
 
     QList<ProjectAction> supportedActions(Node *node) const override;
 
+    QString addFileFilter() const override;
+
     bool renameFile(const QString &filePath, const QString &newFilePath) override;
     void refresh(QSet<QString> oldFileList = QSet<QString>());
 
@@ -1057,6 +1059,11 @@ QList<ProjectAction> PythonProjectNode::supportedActions(Node *node) const
     return {};
 }
 
+QString PythonProjectNode::addFileFilter() const
+{
+    return QLatin1String("*.py");
+}
+
 bool PythonProjectNode::renameFile(const QString &filePath, const QString &newFilePath)
 {
     return m_project->renameFile(filePath, newFilePath);
diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp
index 3ed821073c5..daa03fe04de 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp
@@ -88,24 +88,25 @@ using namespace Utils;
 
 struct FileTypeDataStorage {
     FileType type;
+    Theme::ImageFile themeImage;
     const char *typeName;
     const char *icon;
-    Theme::ImageFile themeImage;
+    const char *addFileFilter;
 };
 
 static const FileTypeDataStorage fileTypeDataStorage[] = {
-    { HeaderType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Headers"),
-      ":/qmakeprojectmanager/images/headers.png", Theme::ProjectExplorerHeader },
-    { SourceType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Sources"),
-      ":/qmakeprojectmanager/images/sources.png", Theme::ProjectExplorerSource },
-    { FormType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Forms"),
-      ":/qtsupport/images/forms.png", Theme::ProjectExplorerForm },
-    { ResourceType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Resources"),
-      ":/qtsupport/images/qt_qrc.png", Theme::ProjectExplorerResource },
-    { QMLType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "QML"),
-      ":/qtsupport/images/qml.png", Theme::ProjectExplorerQML },
-    { UnknownFileType, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Other files"),
-      ":/qmakeprojectmanager/images/unknown.png", Theme::ProjectExplorerOtherFiles }
+    { HeaderType, Theme::ProjectExplorerHeader, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Headers"),
+      ":/qmakeprojectmanager/images/headers.png", "*.h; *.hh; *.hpp; *.hxx;"},
+    { SourceType, Theme::ProjectExplorerSource, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Sources"),
+      ":/qmakeprojectmanager/images/sources.png", "*.c; *.cc; *.cpp; *.cp; *.cxx; *.c++;" },
+    { FormType, Theme::ProjectExplorerForm, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Forms"),
+      ":/qtsupport/images/forms.png", "*.ui;" },
+    { ResourceType, Theme::ProjectExplorerResource, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Resources"),
+      ":/qtsupport/images/qt_qrc.png", "*.qrc;" },
+    { QMLType, Theme::ProjectExplorerQML, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "QML"),
+      ":/qtsupport/images/qml.png", "*.qml; *.qml.ui" },
+    { UnknownFileType, Theme::ProjectExplorerOtherFiles, QT_TRANSLATE_NOOP("QmakeProjectManager::QmakePriFileNode", "Other files"),
+      ":/qmakeprojectmanager/images/unknown.png", "*;" }
 };
 
 class SortByPath
@@ -128,11 +129,13 @@ public:
     public:
         FileTypeData(FileType t = UnknownFileType,
                      const QString &tN = QString(),
+                     const QString &aff = QString(),
                      const QIcon &i = QIcon()) :
-        type(t), typeName(tN), icon(i) { }
+        type(t), typeName(tN), addFileFilter(aff), icon(i) { }
 
         FileType type;
         QString typeName;
+        QString addFileFilter;
         QIcon icon;
     };
 
@@ -164,8 +167,9 @@ QmakeNodeStaticData::QmakeNodeStaticData()
         QIcon folderIcon;
         folderIcon.addPixmap(folderPixmap);
         const QString desc = QCoreApplication::translate("QmakeProjectManager::QmakePriFileNode", fileTypeDataStorage[i].typeName);
+        const QString filter = QString::fromUtf8(fileTypeDataStorage[i].addFileFilter);
         fileTypeData.push_back(QmakeNodeStaticData::FileTypeData(fileTypeDataStorage[i].type,
-                                                               desc, folderIcon));
+                                                                 desc, filter, folderIcon));
     }
     // Project icon
     const QString fileName = creatorTheme()->imageFile(Theme::ProjectFileIcon,
@@ -246,9 +250,20 @@ public:
     bool isDeployable;
     QStringList errors;
 };
+
+QString ProVirtualFolderNode::displayName() const
+{
+    return m_typeName;
 }
+
+QString ProVirtualFolderNode::addFileFilter() const
+{
+    return m_addFileFilter;
 }
 
+} // namespace Internal
+} // namespace QMakeProjectManager
+
 QmakePriFile::QmakePriFile(QmakeProjectManager::QmakePriFileNode *qmakePriFile)
     : IDocument(0), m_priFile(qmakePriFile)
 {
@@ -347,6 +362,7 @@ struct InternalNode
     int priority = 0;
     QString displayName;
     QString typeName;
+    QString addFileFilter;
     QString fullPath;
     QIcon icon;
 
@@ -446,8 +462,10 @@ struct InternalNode
         if (node->typeName.isEmpty()) {
             newNode = new FolderNode(FileName::fromString(node->fullPath));
         } else {
-            newNode = new ProVirtualFolderNode(FileName::fromString(node->fullPath),
-                                               node->priority, node->typeName);
+            auto n = new ProVirtualFolderNode(FileName::fromString(node->fullPath),
+                                                 node->priority, node->typeName);
+            n->setAddFileFilter(node->addFileFilter);
+            newNode = n;
         }
 
         newNode->setDisplayName(node->displayName);
@@ -770,6 +788,7 @@ void QmakePriFileNode::update(const Internal::PriFileEvalResult &result)
             subfolder->icon = fileTypes.at(i).icon;
             subfolder->fullPath = m_projectDir;
             subfolder->typeName = fileTypes.at(i).typeName;
+            subfolder->addFileFilter = fileTypes.at(i).addFileFilter;
             subfolder->priority = -i;
             subfolder->displayName = fileTypes.at(i).typeName;
             contents.virtualfolders.append(subfolder);
diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h
index c1bc710e938..96bc1110b3e 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodes.h
+++ b/src/plugins/qmakeprojectmanager/qmakenodes.h
@@ -267,9 +267,13 @@ public:
         : VirtualFolderNode(folderPath, priority), m_typeName(typeName)
     { }
 
-    QString displayName() const override
+    QString displayName() const override;
+
+    QString addFileFilter() const override;
+
+    void setAddFileFilter(const QString &filter)
     {
-        return m_typeName;
+        m_addFileFilter = filter;
     }
 
     QString tooltip() const override
@@ -279,6 +283,7 @@ public:
 
 private:
     QString m_typeName;
+    QString m_addFileFilter;
 };
 
 } // namespace Internal
diff --git a/src/plugins/resourceeditor/resourcenode.cpp b/src/plugins/resourceeditor/resourcenode.cpp
index 6302dfba693..78d9aceb9bb 100644
--- a/src/plugins/resourceeditor/resourcenode.cpp
+++ b/src/plugins/resourceeditor/resourcenode.cpp
@@ -201,6 +201,11 @@ void ResourceTopLevelNode::update()
     }
 }
 
+QString ResourceTopLevelNode::addFileFilter() const
+{
+    return QLatin1String("*.png; *.jpg; *.gif; *.svg; *.ico; *.qml; *.qml.ui");
+}
+
 QList<ProjectExplorer::ProjectAction> ResourceTopLevelNode::supportedActions(ProjectExplorer::Node *node) const
 {
     if (node != this)
diff --git a/src/plugins/resourceeditor/resourcenode.h b/src/plugins/resourceeditor/resourcenode.h
index 05666d20a60..f503d5e4aef 100644
--- a/src/plugins/resourceeditor/resourcenode.h
+++ b/src/plugins/resourceeditor/resourcenode.h
@@ -49,6 +49,8 @@ public:
     ~ResourceTopLevelNode() override;
     void update();
 
+    QString addFileFilter() const override;
+
     QList<ProjectExplorer::ProjectAction> supportedActions(Node *node) const override;
     bool addFiles(const QStringList &filePaths, QStringList *notAdded) override;
     bool removeFiles(const QStringList &filePaths, QStringList *notRemoved) override;
-- 
GitLab