Commit c8513df2 authored by Pawel Faron's avatar Pawel Faron Committed by Daniel Teske

Implemented "Add Existing Directory..." feature.

This feature lets add files from selected directory and its
subdirectories to project. Files to add are selected based on filter
supplied by a user.

Task-number: QTCREATORBUG-9081
Change-Id: I978e87c24c5aeffc4eb74160cd6f4f20096de017
Reviewed-by: default avatarDaniel Teske <daniel.teske@digia.com>
parent 0ddb6cac
......@@ -31,10 +31,10 @@
#include "genericprojectwizard.h"
#include "genericprojectconstants.h"
#include "selectablefilesmodel.h"
#include <coreplugin/mimedatabase.h>
#include <coreplugin/icore.h>
#include <projectexplorer/selectablefilesmodel.h>
#include <QVBoxLayout>
#include <QLineEdit>
......@@ -117,12 +117,12 @@ void FilesSelectionWizardPage::initializePage()
{
m_view->setModel(0);
delete m_model;
m_model = new SelectableFilesModel(m_genericProjectWizardDialog->path(), this);
m_model = new ProjectExplorer::SelectableFilesModel(this);
connect(m_model, SIGNAL(parsingProgress(QString)),
this, SLOT(parsingProgress(QString)));
connect(m_model, SIGNAL(parsingFinished()),
this, SLOT(parsingFinished()));
m_model->startParsing();
m_model->startParsing(m_genericProjectWizardDialog->path());
m_hideFilesFilterLabel->setVisible(false);
m_hideFilesfilterLineEdit->setVisible(false);
......@@ -139,7 +139,6 @@ void FilesSelectionWizardPage::initializePage()
void FilesSelectionWizardPage::cleanupPage()
{
m_model->cancel();
m_model->waitForFinished();
}
void FilesSelectionWizardPage::parsingProgress(const QString &text)
......
......@@ -39,11 +39,14 @@ class QTreeView;
class QLineEdit;
QT_END_NAMESPACE
namespace ProjectExplorer {
class SelectableFilesModel;
}
namespace GenericProjectManager {
namespace Internal {
class GenericProjectWizardDialog;
class SelectableFilesModel;
class FilesSelectionWizardPage : public QWizardPage
{
......@@ -68,7 +71,7 @@ private:
void createApplyButton(QVBoxLayout *layout);
GenericProjectWizardDialog *m_genericProjectWizardDialog;
SelectableFilesModel *m_model;
ProjectExplorer::SelectableFilesModel *m_model;
QLabel *m_hideFilesFilterLabel;
QLineEdit *m_hideFilesfilterLineEdit;
......
......@@ -10,7 +10,6 @@ HEADERS = genericproject.h \
pkgconfigtool.h \
genericmakestep.h \
genericbuildconfiguration.h \
selectablefilesmodel.h \
filesselectionwizardpage.h
SOURCES = genericproject.cpp \
genericprojectplugin.cpp \
......@@ -21,7 +20,6 @@ SOURCES = genericproject.cpp \
pkgconfigtool.cpp \
genericmakestep.cpp \
genericbuildconfiguration.cpp \
selectablefilesmodel.cpp \
filesselectionwizardpage.cpp
RESOURCES += genericproject.qrc
FORMS += genericmakestep.ui
......@@ -39,7 +39,5 @@ QtcPlugin {
"genericprojectwizard.h",
"pkgconfigtool.cpp",
"pkgconfigtool.h",
"selectablefilesmodel.cpp",
"selectablefilesmodel.h",
]
}
......@@ -237,6 +237,7 @@ QList<ProjectNode::ProjectAction> GenericProjectNode::supportedActions(Node *nod
return QList<ProjectAction>()
<< AddNewFile
<< AddExistingFile
<< AddExistingDirectory
<< RemoveFile
<< Rename;
}
......
......@@ -36,7 +36,6 @@
#include "genericprojectfileseditor.h"
#include "genericmakestep.h"
#include "genericproject.h"
#include "selectablefilesmodel.h"
#include <coreplugin/icore.h>
#include <coreplugin/mimedatabase.h>
......@@ -45,7 +44,7 @@
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/selectablefilesmodel.h>
#include <texteditor/texteditoractionhandler.h>
......@@ -115,7 +114,7 @@ void GenericProjectPlugin::updateContextMenu(ProjectExplorer::Project *project,
void GenericProjectPlugin::editFiles()
{
GenericProject *genericProject = static_cast<GenericProject *>(m_contextMenuProject);
SelectableFilesDialog sfd(QFileInfo(genericProject->projectFilePath()).path(), genericProject->files(),
ProjectExplorer::SelectableFilesDialogEditFiles sfd(QFileInfo(genericProject->projectFilePath()).path(), genericProject->files(),
Core::ICore::mainWindow());
if (sfd.exec() == QDialog::Accepted)
genericProject->setFiles(sfd.selectedFiles());
......
......@@ -76,6 +76,7 @@
#include "miniprojecttargetselector.h"
#include "taskhub.h"
#include "customtoolchain.h"
#include <selectablefilesmodel.h>
#include <projectexplorer/customwizard/customwizard.h>
#include "devicesupport/desktopdevice.h"
#include "devicesupport/desktopdevicefactory.h"
......@@ -198,6 +199,7 @@ struct ProjectExplorerPluginPrivate {
QAction *m_cancelBuildAction;
QAction *m_addNewFileAction;
QAction *m_addExistingFilesAction;
QAction *m_addExistingDirectoryAction;
QAction *m_addNewSubprojectAction;
QAction *m_removeFileAction;
QAction *m_removeProjectAction;
......@@ -795,6 +797,15 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
// add existing directory action
d->m_addExistingDirectoryAction = new QAction(tr("Add Existing Directory..."), this);
cmd = Core::ActionManager::registerAction(d->m_addExistingDirectoryAction,
ProjectExplorer::Constants::ADDEXISTINGDIRECTORY,
projecTreeContext);
mprojectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
msubProjectContextMenu->addAction(cmd, Constants::G_PROJECT_FILES);
mfolderContextMenu->addAction(cmd, Constants::G_FOLDER_FILES);
// new subproject action
d->m_addNewSubprojectAction = new QAction(tr("New Subproject..."), this);
cmd = ActionManager::registerAction(d->m_addNewSubprojectAction, ProjectExplorer::Constants::ADDNEWSUBPROJECT,
......@@ -962,6 +973,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
connect(d->m_closeAllProjects, SIGNAL(triggered()), this, SLOT(closeAllProjects()));
connect(d->m_addNewFileAction, SIGNAL(triggered()), this, SLOT(addNewFile()));
connect(d->m_addExistingFilesAction, SIGNAL(triggered()), this, SLOT(addExistingFiles()));
connect(d->m_addExistingDirectoryAction, SIGNAL(triggered()), this, SLOT(addExistingDirectory()));
connect(d->m_addNewSubprojectAction, SIGNAL(triggered()), this, SLOT(addNewSubproject()));
connect(d->m_removeProjectAction, SIGNAL(triggered()), this, SLOT(removeProject()));
connect(d->m_openFileAction, SIGNAL(triggered()), this, SLOT(openFile()));
......@@ -2619,6 +2631,7 @@ void ProjectExplorerPlugin::invalidateProject(Project *project)
void ProjectExplorerPlugin::updateContextMenuActions()
{
d->m_addExistingFilesAction->setEnabled(false);
d->m_addExistingDirectoryAction->setEnabled(false);
d->m_addNewFileAction->setEnabled(false);
d->m_addNewSubprojectAction->setEnabled(false);
d->m_removeFileAction->setEnabled(false);
......@@ -2626,6 +2639,7 @@ void ProjectExplorerPlugin::updateContextMenuActions()
d->m_renameFileAction->setEnabled(false);
d->m_addExistingFilesAction->setVisible(true);
d->m_addExistingDirectoryAction->setVisible(true);
d->m_removeFileAction->setVisible(true);
d->m_deleteFileAction->setVisible(true);
d->m_runActionContextMenu->setVisible(false);
......@@ -2663,6 +2677,7 @@ void ProjectExplorerPlugin::updateContextMenuActions()
d->m_addNewSubprojectAction->setEnabled(d->m_currentNode->nodeType() == ProjectNodeType
&& actions.contains(ProjectNode::AddSubProject));
d->m_addExistingFilesAction->setEnabled(actions.contains(ProjectNode::AddExistingFile));
d->m_addExistingDirectoryAction->setEnabled(actions.contains(ProjectNode::AddExistingDirectory));
d->m_renameFileAction->setEnabled(actions.contains(ProjectNode::Rename));
} else if (qobject_cast<FileNode*>(d->m_currentNode)) {
// Enable and show remove / delete in magic ways:
......@@ -2772,6 +2787,17 @@ void ProjectExplorerPlugin::addExistingFiles()
addExistingFiles(fileNames);
}
void ProjectExplorerPlugin::addExistingDirectory()
{
QTC_ASSERT(d->m_currentNode, return);
const QString path = QFileInfo(d->m_currentNode->path()).absolutePath();
SelectableFilesDialogAddDirectory dialog(path, QStringList(), Core::ICore::mainWindow());
if (dialog.exec() == QDialog::Accepted)
addExistingFiles(dialog.selectedFiles());
}
void ProjectExplorerPlugin::addExistingFiles(const QStringList &filePaths)
{
ProjectNode *projectNode = qobject_cast<ProjectNode*>(d->m_currentNode->projectNode());
......
......@@ -186,6 +186,7 @@ private slots:
void addNewFile();
void addExistingFiles();
void addExistingDirectory();
void addNewSubproject();
void removeProject();
void openFile();
......
......@@ -141,7 +141,8 @@ HEADERS += projectexplorer.h \
projectmacroexpander.h \
customparser.h \
customparserconfigdialog.h \
ipotentialkit.h
ipotentialkit.h \
selectablefilesmodel.h
SOURCES += projectexplorer.cpp \
abi.cpp \
......@@ -269,7 +270,8 @@ SOURCES += projectexplorer.cpp \
projectmacroexpander.cpp \
customparser.cpp \
customparserconfigdialog.cpp \
ipotentialkit.cpp
ipotentialkit.cpp \
selectablefilesmodel.cpp
FORMS += processstep.ui \
editorsettingspropertiespage.ui \
......
......@@ -121,6 +121,7 @@ QtcPlugin {
"runconfiguration.cpp", "runconfiguration.h",
"runconfigurationmodel.cpp", "runconfigurationmodel.h",
"runsettingspropertiespage.cpp", "runsettingspropertiespage.h",
"selectablefilesmodel.cpp", "selectablefilesmodel.h"
"session.cpp", "session.h",
"sessiondialog.cpp", "sessiondialog.h", "sessiondialog.ui",
"settingsaccessor.cpp", "settingsaccessor.h",
......@@ -141,7 +142,7 @@ QtcPlugin {
"toolchainmanager.cpp", "toolchainmanager.h",
"toolchainoptionspage.cpp", "toolchainoptionspage.h",
"unconfiguredprojectpanel.cpp", "unconfiguredprojectpanel.h",
"vcsannotatetaskhandler.cpp", "vcsannotatetaskhandler.h",
"vcsannotatetaskhandler.cpp", "vcsannotatetaskhandler.h"
]
}
......
......@@ -69,6 +69,7 @@ const char RUNCONTEXTMENU[] = "ProjectExplorer.RunContextMenu";
const char STOP[] = "ProjectExplorer.Stop";
const char ADDNEWFILE[] = "ProjectExplorer.AddNewFile";
const char ADDEXISTINGFILES[] = "ProjectExplorer.AddExistingFiles";
const char ADDEXISTINGDIRECTORY[] = "ProjectExplorer.AddExistingDirectory";
const char ADDNEWSUBPROJECT[] = "ProjectExplorer.AddNewSubproject";
const char REMOVEPROJECT[] = "ProjectExplorer.RemoveProject";
const char OPENFILE[] = "ProjectExplorer.OpenFile";
......@@ -246,6 +247,12 @@ const char VAR_CURRENTKIT_ID[] = "CurrentKit:Id";
const char VAR_CURRENTBUILD_NAME[] = "CurrentBuild:Name";
const char VAR_CURRENTBUILD_TYPE[] = "CurrentBuild:Type";
const char HIDE_FILE_FILTER_SETTING[] = "GenericProject/FileFilter";
const char HIDE_FILE_FILTER_DEFAULT[] = "Makefile*; *.o; *.obj; *~; *.files; *.config; *.creator; *.user; *.includes; *.autosave";
const char SHOW_FILE_FILTER_SETTING[] = "GenericProject/ShowFileFilter";
const char SHOW_FILE_FILTER_DEFAULT[] = "*.c; *.cc; *.cpp; *.cp; *.cxx; *.c++; *.h; *.hh; *.hpp; *.hxx;";
// Unconfigured Panel
const char UNCONFIGURED_PANEL_PAGE_ID[] = "UnconfiguredPanel";
......
......@@ -184,6 +184,9 @@ public:
// the file is added
AddNewFile,
AddExistingFile,
// Add files, which match user defined filters,
// from an existing directory and its subdirectories
AddExistingDirectory,
// Removes a file from the project, optionally also
// delete it on disc
RemoveFile,
......
......@@ -28,7 +28,7 @@
****************************************************************************/
#include "selectablefilesmodel.h"
#include "genericprojectconstants.h"
#include <projectexplorerconstants.h>
#include <coreplugin/fileiconprovider.h>
#include <coreplugin/icore.h>
......@@ -41,19 +41,14 @@
#include <QPushButton>
#include <QTreeView>
#include <QDir>
#include <utils/pathchooser.h>
namespace GenericProjectManager {
namespace Internal {
namespace ProjectExplorer {
SelectableFilesModel::SelectableFilesModel(const QString &baseDir, QObject *parent)
: QAbstractItemModel(parent), m_root(0), m_baseDir(baseDir), m_allFiles(true)
SelectableFilesModel::SelectableFilesModel(QObject *parent)
: QAbstractItemModel(parent), m_root(0), m_allFiles(true)
{
// Dummy tree
m_root = new Tree;
m_root->name = QLatin1String("/");
m_root->parent = 0;
m_root->fullPath = m_baseDir;
m_root->isDir = true;
connect(&m_watcher, SIGNAL(finished()), this, SLOT(buildTreeFinished()));
}
void SelectableFilesModel::setInitialMarkedFiles(const QStringList &files)
......@@ -68,20 +63,19 @@ void SelectableFilesModel::setInitialMarkedFiles(const QStringList &files)
m_allFiles = false;
}
void SelectableFilesModel::init()
void SelectableFilesModel::startParsing(const QString &baseDir)
{
}
m_watcher.cancel();
m_watcher.waitForFinished();
void SelectableFilesModel::startParsing()
{
m_baseDir = baseDir;
// Build a tree in a future
m_rootForFuture = new Tree;
m_rootForFuture->name = QLatin1String("/");
m_rootForFuture->parent = 0;
m_rootForFuture->fullPath = m_baseDir;
m_rootForFuture->fullPath = baseDir;
m_rootForFuture->isDir = true;
connect(&m_watcher, SIGNAL(finished()), this, SLOT(buildTreeFinished()));
m_watcher.setFuture(QtConcurrent::run(&SelectableFilesModel::run, this));
}
......@@ -101,14 +95,10 @@ void SelectableFilesModel::buildTreeFinished()
emit parsingFinished();
}
void SelectableFilesModel::waitForFinished()
{
m_watcher.waitForFinished();
}
void SelectableFilesModel::cancel()
{
m_watcher.cancel();
m_watcher.waitForFinished();
}
bool SelectableFilesModel::filter(Tree *t)
......@@ -193,11 +183,15 @@ void SelectableFilesModel::buildTree(const QString &baseDir, Tree *tree, QFuture
SelectableFilesModel::~SelectableFilesModel()
{
m_watcher.cancel();
m_watcher.waitForFinished();
deleteTree(m_root);
}
void SelectableFilesModel::deleteTree(Tree *tree)
{
if (!tree)
return;
foreach (Tree *t, tree->childDirectories)
deleteTree(t);
foreach (Tree *t, tree->files)
......@@ -234,6 +228,8 @@ QModelIndex SelectableFilesModel::parent(const QModelIndex &child) const
{
if (!child.isValid())
return QModelIndex();
if (!child.internalPointer())
return QModelIndex();
Tree *parent = static_cast<Tree *>(child.internalPointer())->parent;
if (!parent)
return QModelIndex();
......@@ -398,6 +394,22 @@ void SelectableFilesModel::applyFilter(const QString &showFilesfilter, const QSt
applyFilter(createIndex(0, 0, m_root));
}
void SelectableFilesModel::selectAllFiles()
{
selectAllFiles(m_root);
}
void SelectableFilesModel::selectAllFiles(Tree *root)
{
root->checked = Qt::Checked;
foreach (Tree *t, root->childDirectories)
selectAllFiles(t);
foreach (Tree *t, root->visibleFiles)
t->checked = Qt::Checked;
}
Qt::CheckState SelectableFilesModel::applyFilter(const QModelIndex &index)
{
bool allChecked = true;
......@@ -511,10 +523,10 @@ Qt::CheckState SelectableFilesModel::applyFilter(const QModelIndex &index)
}
//////////
// SelectableFilesDialog
// SelectableFilesDialogs
//////////
SelectableFilesDialog::SelectableFilesDialog(const QString &path, const QStringList files, QWidget *parent)
SelectableFilesDialogEditFiles::SelectableFilesDialogEditFiles(const QString &path, const QStringList files, QWidget *parent)
: QDialog(parent)
{
QVBoxLayout *layout = new QVBoxLayout();
......@@ -527,7 +539,7 @@ SelectableFilesDialog::SelectableFilesDialog(const QString &path, const QStringL
createHideFileFilterControls(layout);
createApplyButton(layout);
m_selectableFilesModel = new SelectableFilesModel(path, this);
m_selectableFilesModel = new SelectableFilesModel(this);
m_selectableFilesModel->setInitialMarkedFiles(files);
m_view->setModel(m_selectableFilesModel);
m_view->setMinimumSize(500, 400);
......@@ -556,10 +568,10 @@ SelectableFilesDialog::SelectableFilesDialog(const QString &path, const QStringL
connect(m_selectableFilesModel, SIGNAL(parsingFinished()),
this, SLOT(parsingFinished()));
m_selectableFilesModel->startParsing();
m_selectableFilesModel->startParsing(path);
}
void SelectableFilesDialog::createHideFileFilterControls(QVBoxLayout *layout)
void SelectableFilesDialogEditFiles::createHideFileFilterControls(QVBoxLayout *layout)
{
QHBoxLayout *hbox = new QHBoxLayout;
m_hideFilesFilterLabel = new QLabel;
......@@ -576,7 +588,7 @@ void SelectableFilesDialog::createHideFileFilterControls(QVBoxLayout *layout)
layout->addLayout(hbox);
}
void SelectableFilesDialog::createShowFileFilterControls(QVBoxLayout *layout)
void SelectableFilesDialogEditFiles::createShowFileFilterControls(QVBoxLayout *layout)
{
QHBoxLayout *hbox = new QHBoxLayout;
m_showFilesFilterLabel = new QLabel;
......@@ -593,7 +605,7 @@ void SelectableFilesDialog::createShowFileFilterControls(QVBoxLayout *layout)
layout->addLayout(hbox);
}
void SelectableFilesDialog::createApplyButton(QVBoxLayout *layout)
void SelectableFilesDialogEditFiles::createApplyButton(QVBoxLayout *layout)
{
QHBoxLayout *hbox = new QHBoxLayout;
......@@ -608,18 +620,17 @@ void SelectableFilesDialog::createApplyButton(QVBoxLayout *layout)
connect(m_applyFilterButton, SIGNAL(clicked()), this, SLOT(applyFilter()));
}
SelectableFilesDialog::~SelectableFilesDialog()
SelectableFilesDialogEditFiles::~SelectableFilesDialogEditFiles()
{
m_selectableFilesModel->cancel();
m_selectableFilesModel->waitForFinished();
}
void SelectableFilesDialog::parsingProgress(const QString &fileName)
void SelectableFilesDialogEditFiles::parsingProgress(const QString &fileName)
{
m_progressLabel->setText(tr("Generating file list...\n\n%1").arg(fileName));
}
void SelectableFilesDialog::parsingFinished()
void SelectableFilesDialogEditFiles::parsingFinished()
{
m_hideFilesFilterLabel->show();
m_hideFilesfilterLineEdit->show();
......@@ -642,7 +653,7 @@ void SelectableFilesDialog::parsingFinished()
}
}
void SelectableFilesDialog::smartExpand(const QModelIndex &index)
void SelectableFilesDialogEditFiles::smartExpand(const QModelIndex &index)
{
if (m_view->model()->data(index, Qt::CheckStateRole) == Qt::PartiallyChecked) {
m_view->expand(index);
......@@ -652,12 +663,12 @@ void SelectableFilesDialog::smartExpand(const QModelIndex &index)
}
}
QStringList SelectableFilesDialog::selectedFiles() const
QStringList SelectableFilesDialogEditFiles::selectedFiles() const
{
return m_selectableFilesModel->selectedFiles();
}
void SelectableFilesDialog::applyFilter()
void SelectableFilesDialogEditFiles::applyFilter()
{
const QString showFilesFilter = m_showFilesfilterLineEdit->text();
Core::ICore::settings()->setValue(QLatin1String(Constants::SHOW_FILE_FILTER_SETTING), showFilesFilter);
......@@ -668,7 +679,70 @@ void SelectableFilesDialog::applyFilter()
m_selectableFilesModel->applyFilter(showFilesFilter, hideFilesFilter);
}
} // namespace Internal
} // namespace GenericProjectManager
SelectableFilesDialogAddDirectory::SelectableFilesDialogAddDirectory(const QString &path,
const QStringList files, QWidget *parent) :
SelectableFilesDialogEditFiles(path, files, parent)
{
setWindowTitle(tr("Add Existing Directory"));
connect(m_selectableFilesModel, SIGNAL(parsingFinished()), this, SLOT(parsingFinished()));
createPathChooser(static_cast<QVBoxLayout*>(layout()), path);
}
void SelectableFilesDialogAddDirectory::createPathChooser(QVBoxLayout *layout, const QString &path)
{
QHBoxLayout *hbox = new QHBoxLayout;
m_pathChooser = new Utils::PathChooser;
m_pathChooser->setPath(path);
m_sourceDirectoryLabel = new QLabel(tr("Source directory:"));
hbox->addWidget(m_sourceDirectoryLabel);
hbox->addWidget(m_pathChooser);
layout->insertLayout(0, hbox);
m_startParsingButton = new QPushButton(tr("Start Parsing"));
hbox->addWidget(m_startParsingButton);
connect(m_pathChooser, SIGNAL(validChanged(bool)), this, SLOT(validityOfDirectoryChanged(bool)));
connect(m_startParsingButton, SIGNAL(clicked()), this, SLOT(startParsing()));
}
void SelectableFilesDialogAddDirectory::validityOfDirectoryChanged(bool validState)
{
m_startParsingButton->setEnabled(validState);
}
void SelectableFilesDialogAddDirectory::parsingFinished()
{
m_selectableFilesModel->selectAllFiles();
m_selectableFilesModel->applyFilter(m_showFilesfilterLineEdit->text(),
m_hideFilesfilterLineEdit->text());
setWidgetsEnabled(true);
}
void SelectableFilesDialogAddDirectory::startParsing()
{
setWidgetsEnabled(false);
m_selectableFilesModel->startParsing(m_pathChooser->path());
}
void SelectableFilesDialogAddDirectory::setWidgetsEnabled(bool enabled)
{
m_hideFilesfilterLineEdit->setEnabled(enabled);
m_showFilesfilterLineEdit->setEnabled(enabled);
m_applyFilterButton->setEnabled(enabled);
m_view->setEnabled(enabled);
m_pathChooser->setEnabled(enabled);
m_startParsingButton->setVisible(enabled);
m_progressLabel->setVisible(!enabled);
}
} // namespace ProjectExplorer
......@@ -37,13 +37,15 @@
#include <QDialog>
#include <QTreeView>
#include <QLabel>
#include "projectexplorer_export.h"
namespace Utils { class PathChooser; }
QT_BEGIN_NAMESPACE
class QVBoxLayout;
QT_END_NAMESPACE
namespace GenericProjectManager {
namespace Internal {
namespace ProjectExplorer {
struct Tree
{
......@@ -81,12 +83,12 @@ struct Glob
}
};
class SelectableFilesModel : public QAbstractItemModel
class PROJECTEXPLORER_EXPORT SelectableFilesModel : public QAbstractItemModel
{
Q_OBJECT
public:
SelectableFilesModel(const QString &baseDir, QObject *parent);
SelectableFilesModel(QObject *parent);
~SelectableFilesModel();
void setInitialMarkedFiles(const QStringList &files);
......@@ -104,12 +106,12 @@ public:
QStringList selectedPaths() const;
QStringList preservedFiles() const;
// only call this once
void startParsing();
void waitForFinished();
void startParsing(const QString &baseDir);
void cancel();
void applyFilter(const QString &selectFilesfilter, const QString &hideFilesfilter);
void selectAllFiles();
signals:
void parsingFinished();
void parsingProgress(const QString &filename);
......@@ -121,7 +123,6 @@ private:
QList<Glob> parseFilter(const QString &filter);
Qt::CheckState applyFilter(const QModelIndex &index);
bool filter(Tree *t);
void init();
void run(QFutureInterface<void> &fi);
void collectFiles(Tree *root, QStringList *result) const;
void collectPaths(Tree *root, QStringList *result) const;
......@@ -129,6 +130,7 @@ private:
void deleteTree(Tree *tree);
void propagateUp(const QModelIndex &index);
void propagateDown(const QModelIndex &index);
void selectAllFiles(Tree *root);
Tree *m_root;
// Used in the future thread need to all not used after calling startParsing
QString m_baseDir;
......@@ -143,13 +145,13 @@ private:
QList<Glob> m_showFilesFilter;
};
class SelectableFilesDialog : public QDialog
class PROJECTEXPLORER_EXPORT SelectableFilesDialogEditFiles : public QDialog
{
Q_OBJECT
public:
SelectableFilesDialog(const QString &path, const QStringList files, QWidget *parent);
~SelectableFilesDialog();
SelectableFilesDialogEditFiles(const QString &path, const QStringList files, QWidget *parent);
~SelectableFilesDialogEditFiles();
QStringList selectedFiles() const;
private slots:
......@@ -157,11 +159,12 @@ private slots:
void parsingProgress(const QString &fileName);
void parsingFinished();
private:
protected:
void smartExpand(const QModelIndex &index);
void createShowFileFilterControls(QVBoxLayout *layout);
void createHideFileFilterControls(QVBoxLayout *layout);
void createApplyButton(QVBoxLayout *layout);
SelectableFilesModel *m_selectableFilesModel;
QLabel *m_hideFilesFilterLabel;
......@@ -177,8 +180,28 @@ private:
QLabel *m_progressLabel;
};
} // namespace Internal
} // namespace GenericProjectManager
class SelectableFilesDialogAddDirectory : public SelectableFilesDialogEditFiles
{
Q_OBJECT
public:
SelectableFilesDialogAddDirectory(const QString &path, const QStringList files, QWidget *parent);
private slots:
void validityOfDirectoryChanged(bool validState);
void parsingFinished();
void startParsing();
private:
Utils::PathChooser *m_pathChooser;
QLabel *m_sourceDirectoryLabel;
QPushButton *m_startParsingButton;
void setWidgetsEnabled(bool enabled);
void createPathChooser(QVBoxLayout *layout, const QString &path);
};
} // namespace ProjectExplorer
#endif // SELECTABLEFILESMODEL_H
......@@ -865,7 +865,7 @@ QList<ProjectNode::ProjectAction> QmakePriFileNode::supportedActions(Node *node)
addExistingFiles = addExistingFiles && !deploysFolder(node->path());
if (addExistingFiles)
actions << AddExistingFile;
actions << AddExistingFile << AddExistingDirectory;