File indexing completed on 2024-04-28 05:49:09

0001 /*  This file is part of the Kate project.
0002  *
0003  *  SPDX-FileCopyrightText: 2012 Christoph Cullmann <cullmann@kde.org>
0004  *
0005  *  SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "kateprojectview.h"
0009 #include "branchcheckoutdialog.h"
0010 #include "gitprocess.h"
0011 #include "gitwidget.h"
0012 #include "kateprojectfiltermodel.h"
0013 #include "kateprojectplugin.h"
0014 #include "kateprojectpluginview.h"
0015 
0016 #include <KTextEditor/Document>
0017 #include <KTextEditor/Editor>
0018 #include <KTextEditor/MainWindow>
0019 #include <KTextEditor/View>
0020 
0021 #include <KAcceleratorManager>
0022 #include <KActionCollection>
0023 #include <KLineEdit>
0024 #include <KLocalizedString>
0025 
0026 #include <QPushButton>
0027 #include <QVBoxLayout>
0028 
0029 KateProjectView::KateProjectView(KateProjectPluginView *pluginView, KateProject *project)
0030     : m_pluginView(pluginView)
0031     , m_project(project)
0032     , m_treeView(new KateProjectViewTree(pluginView, project))
0033     , m_filter(new KLineEdit())
0034 {
0035     /**
0036      * layout tree view and co.
0037      */
0038     QVBoxLayout *layout = new QVBoxLayout();
0039     layout->setSpacing(0);
0040     layout->setContentsMargins(0, 0, 0, 0);
0041     layout->addWidget(m_treeView);
0042     layout->addWidget(m_filter);
0043     setLayout(layout);
0044 
0045     /**
0046      * Setup checkout stuff, git branch button in statusbar
0047      */
0048 
0049     // let tree get focus for keyboard selection of file to open
0050     setFocusProxy(m_treeView);
0051 
0052     m_filterStartTimer.setSingleShot(true);
0053     m_filterStartTimer.setInterval(400);
0054     m_filterStartTimer.callOnTimeout(this, &KateProjectView::filterTextChanged);
0055 
0056     /**
0057      * setup filter line edit
0058      */
0059     m_filter->setPlaceholderText(i18n("Filter..."));
0060     m_filter->setClearButtonEnabled(true);
0061     m_filter->setProperty("_breeze_borders_sides", QVariant::fromValue(Qt::TopEdge | Qt::TopEdge));
0062     connect(m_filter, &KLineEdit::textChanged, this, [this] {
0063         m_filterStartTimer.start();
0064     });
0065 
0066     // pluginView is not fully initialized at this point so delay it.
0067     QMetaObject::invokeMethod(this, &KateProjectView::checkAndRefreshGit, Qt::QueuedConnection);
0068 
0069     connect(m_project, &KateProject::modelChanged, this, &KateProjectView::checkAndRefreshGit);
0070     connect(&m_pluginView->plugin()->fileWatcher(), &QFileSystemWatcher::fileChanged, this, [this](const QString &path) {
0071         if (m_branchChangedWatcherFile == path) {
0072             m_project->reload(true);
0073         }
0074     });
0075 }
0076 
0077 KateProjectView::~KateProjectView()
0078 {
0079     if (!m_branchChangedWatcherFile.isEmpty()) {
0080         m_pluginView->plugin()->fileWatcher().removePath(m_branchChangedWatcherFile);
0081     }
0082 }
0083 
0084 void KateProjectView::selectFile(const QString &file)
0085 {
0086     m_treeView->selectFile(file);
0087 }
0088 
0089 void KateProjectView::openSelectedDocument()
0090 {
0091     m_treeView->openSelectedDocument();
0092 }
0093 
0094 void KateProjectView::filterTextChanged()
0095 {
0096     const auto filterText = m_filter->text();
0097     /**
0098      * filter
0099      */
0100     static_cast<KateProjectFilterProxyModel *>(m_treeView->model())->setFilterString(filterText);
0101 
0102     /**
0103      * expand
0104      */
0105     if (!filterText.isEmpty()) {
0106         QTimer::singleShot(100, m_treeView, &QTreeView::expandAll);
0107     }
0108 }
0109 
0110 void KateProjectView::checkAndRefreshGit()
0111 {
0112     const auto dotGitPath = getRepoBasePath(m_project->baseDir());
0113     /**
0114      * Not in a git repo or git was removed
0115      */
0116     if (!dotGitPath.has_value()) {
0117         if (!m_branchChangedWatcherFile.isEmpty()) {
0118             m_pluginView->plugin()->fileWatcher().removePath(m_branchChangedWatcherFile);
0119             m_branchChangedWatcherFile.clear();
0120         }
0121     } else {
0122         const QString fileToWatch = dotGitPath.value() + QStringLiteral(".git/HEAD");
0123         // fileToWatch == m_branchChangedWatcherFile can be true, but doesn't matter. We MUST always
0124         // re add the file otherwise it will not work.
0125 
0126         if (!m_branchChangedWatcherFile.isEmpty()) {
0127             m_pluginView->plugin()->fileWatcher().removePath(m_branchChangedWatcherFile);
0128             m_branchChangedWatcherFile.clear();
0129         }
0130         if (QFileInfo::exists(fileToWatch)) {
0131             m_branchChangedWatcherFile = fileToWatch;
0132             m_pluginView->plugin()->fileWatcher().addPath(m_branchChangedWatcherFile);
0133         }
0134     }
0135     m_pluginView->updateGitBranchButton(m_project);
0136 }
0137 
0138 #include "moc_kateprojectview.cpp"