Commit b3a3011b authored by Christoph Cullmann's avatar Christoph Cullmann 🐮
Browse files

implement close all projects

parent 216372af
......@@ -235,34 +235,52 @@ KateProject *KateProjectPlugin::projectForDir(QDir dir, bool userSpecified)
return nullptr;
}
bool KateProjectPlugin::closeProject(KateProject *project)
void KateProjectPlugin::closeProjects(QList<KateProject *> projects)
{
QVector<KTextEditor::Document *> projectDocuments;
const auto docs = KTextEditor::Editor::instance()->application()->documents();
for (auto doc : docs)
if (QUrl(project->baseDir()).isParentOf(doc->url().adjusted(QUrl::RemoveScheme)))
projectDocuments.push_back(doc);
if (projects.empty()) {
return;
}
// collect all documents we have mapped to the projects we want to close
// we can not delete projects that still have some mapping
QList<KTextEditor::Document *> projectDocuments;
for (const auto &it : m_document2Project) {
if (projects.contains(it.second)) {
projectDocuments.append(it.first);
printf("close %s\n", qPrintable(it.first->url().toString()));
}
}
// if we have some documents open for this project, ask if we want to close, else just do it
if (!projectDocuments.isEmpty()) {
// only tell the name if we close a singular project
QString title = i18n("Confirm closing of %1 projects", projects.size());
QString text = i18n("Do you want to close %1 projects and the related %2 open documents?", projects.size(), projectDocuments.size());
if (projects.size() == 1) {
title = i18n("Confirm project closing: %1", projects.first()->name());
text = i18n("Do you want to close the project %1 and the related %2 open documents?", projects.first()->name(), projectDocuments.size());
}
QWidget *window = KTextEditor::Editor::instance()->application()->activeMainWindow()->window();
const QString title = i18n("Confirm project closing: %1", project->name());
const QString text = i18n("Do you want to close the project %1 and the related %2 open documents?", project->name(), projectDocuments.size());
if (QMessageBox::Yes != QMessageBox::question(window, title, text, QMessageBox::No | QMessageBox::Yes, QMessageBox::Yes)) {
return false;
return;
}
for (auto doc : projectDocuments)
KTextEditor::Editor::instance()->application()->closeDocument(doc);
// best effort document closing, some might survive
KTextEditor::Editor::instance()->application()->closeDocuments(projectDocuments);
}
Q_EMIT pluginViewProjectClosing(project);
if (m_projects.removeOne(project)) {
// now: close all projects we have no longer any open documents for, we just filter the list
for (const auto &it : m_document2Project) {
if (projects.contains(it.second)) {
projects.removeOne(it.second);
}
}
for (auto project : projects) {
Q_EMIT pluginViewProjectClosing(project);
m_projects.removeOne(project);
delete project;
return true;
}
return false;
}
KateProject *KateProjectPlugin::projectForUrl(const QUrl &url)
......@@ -286,28 +304,23 @@ void KateProjectPlugin::slotDocumentCreated(KTextEditor::Document *document)
void KateProjectPlugin::slotDocumentDestroyed(QObject *document)
{
if (KateProject *project = m_document2Project.value(document)) {
project->unregisterDocument(static_cast<KTextEditor::Document *>(document));
const auto it = m_document2Project.find(static_cast<KTextEditor::Document *>(document));
if (it == m_document2Project.end()) {
return;
}
m_document2Project.remove(document);
it->second->unregisterDocument(static_cast<KTextEditor::Document *>(document));
m_document2Project.erase(it);
}
void KateProjectPlugin::slotDocumentUrlChanged(KTextEditor::Document *document)
{
KateProject *project = projectForUrl(document->url());
if (KateProject *project = m_document2Project.value(document)) {
project->unregisterDocument(document);
}
if (!project) {
m_document2Project.remove(document);
} else {
m_document2Project[document] = project;
}
// unregister from old mapping
slotDocumentDestroyed(document);
if (KateProject *project = m_document2Project.value(document)) {
// register for new project, if any
if (KateProject *project = projectForUrl(document->url())) {
m_document2Project.emplace(document, project);
project->registerDocument(document);
}
}
......
......@@ -63,11 +63,11 @@ public:
KateProject *projectForDir(QDir dir, bool userSpecified = false);
/**
* Search and close project for given project, if possible.
* @param project to search matching project for closing
* @return true if successful
* Try to close given list of projects.
* Will ask if the files belonging to them shall be closed, if not this will just do nothing.
* @param projects projects that shall be closed
*/
bool closeProject(KateProject *project);
void closeProjects(QList<KateProject *> projects);
/**
* Search and open project that contains given url, if possible.
......@@ -103,7 +103,8 @@ public:
*/
KateProject *projectForDocument(KTextEditor::Document *document)
{
return m_document2Project.value(document);
const auto it = m_document2Project.find(document);
return (it != m_document2Project.end()) ? it->second : nullptr;
}
void setAutoRepository(bool onGit, bool onSubversion, bool onMercurial, bool onFossil);
......@@ -233,7 +234,7 @@ private:
/**
* Mapping document => project
*/
QHash<QObject *, KateProject *> m_document2Project;
std::unordered_map<KTextEditor::Document *, KateProject *> m_document2Project;
/**
* Project completion
......
......@@ -194,9 +194,15 @@ KateProjectPluginView::KateProjectPluginView(KateProjectPlugin *plugin, KTextEdi
m_projectGotoIndexAction = a = actionCollection()->addAction(QStringLiteral("projects_goto_index"), this, SLOT(slotProjectIndex()));
a->setText(i18n("Lookup"));
actionCollection()->setDefaultShortcut(a, QKeySequence(Qt::ALT | Qt::Key_1));
m_projectCloseAction = a = actionCollection()->addAction(QStringLiteral("projects_close"), this, SLOT(slotProjectAboutToClose()));
a->setText(i18n("Close Project"));
a->setIcon(QIcon::fromTheme(QStringLiteral(PROJECTCLOSEICON)));
m_projectCloseAllAction = a = actionCollection()->addAction(QStringLiteral("projects_close_all"), this, SLOT(slotAllProjectsAboutToClose()));
a->setText(i18n("Close All Projects"));
a->setIcon(QIcon::fromTheme(QStringLiteral(PROJECTCLOSEICON)));
m_gotoSymbolActionAppMenu = a = actionCollection()->addAction(KStandardAction::Goto, QStringLiteral("projects_goto_symbol"), this, SLOT(slotGotoSymbol()));
// popup menu
......@@ -638,10 +644,15 @@ void KateProjectPluginView::slotProjectReload()
void KateProjectPluginView::slotProjectAboutToClose()
{
if (QWidget *current = m_stackedProjectViews->currentWidget()) {
m_plugin->closeProject(static_cast<KateProjectView *>(current)->project());
m_plugin->closeProjects({static_cast<KateProjectView *>(current)->project()});
}
}
void KateProjectPluginView::slotAllProjectsAboutToClose()
{
m_plugin->closeProjects(m_plugin->projects());
}
void KateProjectPluginView::slotProjectClose(KateProject *project)
{
const int index = m_plugin->projects().indexOf(project);
......@@ -830,6 +841,7 @@ void KateProjectPluginView::updateActions()
m_projectNextAction->setEnabled(projectActive);
m_projectGotoIndexAction->setEnabled(projectActive);
m_projectCloseAction->setEnabled(projectActive);
m_projectCloseAllAction->setEnabled(!m_plugin->projects().empty());
}
void KateProjectPluginView::slotActivateProject(KateProject *project)
......
......@@ -198,6 +198,12 @@ private Q_SLOTS:
*/
void slotProjectAboutToClose();
/**
* Getting project for others windows
* and closing project documents.
*/
void slotAllProjectsAboutToClose();
/**
* Close current project.
*/
......@@ -383,7 +389,7 @@ private:
QToolButton *m_reloadButton;
/**
* Closeing button
* Closing button for current project
*/
QToolButton *m_closeProjectButton;
......@@ -434,6 +440,7 @@ private:
QAction *m_projectNextAction;
QAction *m_projectGotoIndexAction;
QAction *m_projectCloseAction;
QAction *m_projectCloseAllAction;
class FixedView
{
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE gui SYSTEM "kpartgui.dtd">
<gui name="kateprojectplugin" library="kateprojectplugin" version="12" translationDomain="kateproject">
<gui name="kateprojectplugin" library="kateprojectplugin" version="13" translationDomain="kateproject">
<MenuBar>
<Menu name="file">
<Action name="projects_open_project" group="open_merge"/>
</Menu>
<Menu name="projects">
<text>&amp;Projects</text>
<Action name="projects_todos"/>
<Action name="projects_prev_project"/>
<Action name="projects_next_project"/>
<Separator/>
<Action name="projects_goto_index" />
<Action name="projects_goto_symbol" />
<Separator/>
<Action name="projects_close" />
<Action name="projects_close_all" />
<Separator/>
<Action name="projects_todos"/>
</Menu>
</MenuBar>
<Menu name="ktexteditor_popup" noMerge="1">
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment