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

0001 /*  This file is part of the Kate project.
0002  *
0003  *  SPDX-FileCopyrightText: 2010 Christoph Cullmann <cullmann@kde.org>
0004  *
0005  *  SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #pragma once
0009 
0010 #include <QComboBox>
0011 #include <QMenu>
0012 #include <QPointer>
0013 #include <QStackedWidget>
0014 #include <QToolButton>
0015 
0016 #include <KTextEditor/View>
0017 #include <KXMLGUIClient>
0018 
0019 #include <memory>
0020 
0021 #include <kateprojectview.h>
0022 
0023 class QAction;
0024 class QDir;
0025 class KateProject;
0026 class KateProjectPlugin;
0027 class KateProjectInfoView;
0028 
0029 typedef QMap<QString, QString> QStringMap;
0030 Q_DECLARE_METATYPE(QStringMap)
0031 
0032 class KateProjectPluginView : public QObject, public KXMLGUIClient
0033 {
0034     Q_OBJECT
0035 
0036     Q_PROPERTY(QString projectFileName READ projectFileName NOTIFY projectFileNameChanged)
0037     Q_PROPERTY(QString projectName READ projectName)
0038     Q_PROPERTY(QString projectBaseDir READ projectBaseDir)
0039     Q_PROPERTY(QVariantMap projectMap READ projectMap NOTIFY projectMapChanged)
0040     Q_PROPERTY(QStringList projectFiles READ projectFiles)
0041 
0042     Q_PROPERTY(QString allProjectsCommonBaseDir READ allProjectsCommonBaseDir)
0043     Q_PROPERTY(QStringList allProjectsFiles READ allProjectsFiles)
0044     Q_PROPERTY(QStringMap allProjects READ allProjects)
0045 
0046 public:
0047     KateProjectPluginView(KateProjectPlugin *plugin, KTextEditor::MainWindow *mainWindow);
0048     ~KateProjectPluginView() override;
0049 
0050     /**
0051      * content of current active project, as variant map
0052      * @return empty map if no project active, else content of project JSON
0053      */
0054     QVariantMap projectMap() const;
0055 
0056     /**
0057      * which project file is currently active?
0058      * @return empty string if none, else project file name
0059      */
0060     QString projectFileName() const;
0061 
0062     /**
0063      * Returns the name of the project
0064      */
0065     QString projectName() const;
0066 
0067     /**
0068      * Returns the base directory of the project
0069      */
0070     QString projectBaseDir() const;
0071 
0072     /**
0073      * files for the current active project?
0074      * @return empty list if none, else project files as stringlist
0075      */
0076     QStringList projectFiles() const;
0077 
0078     /**
0079      * Example: Two projects are loaded with baseDir1="/home/dev/project1" and
0080      * baseDir2="/home/dev/project2". Then "/home/dev/" is returned.
0081      * @see projectBaseDir().
0082      * Used for the Search&Replace plugin for option "Search in all open projects".
0083      */
0084     QString allProjectsCommonBaseDir() const;
0085 
0086     /**
0087      * @returns a flat list of files for all open projects (@see also projectFiles())
0088      */
0089     QStringList allProjectsFiles() const;
0090 
0091     /**
0092      * @returns a map of all open projects which maps base directory to name
0093      */
0094     QMap<QString, QString> allProjects() const;
0095 
0096     /**
0097      * the main window we belong to
0098      * @return our main window
0099      */
0100     KTextEditor::MainWindow *mainWindow() const
0101     {
0102         return m_mainWindow;
0103     }
0104 
0105     /**
0106      * the plugin we belong to
0107      * @return our plugin
0108      */
0109     KateProjectPlugin *plugin() const
0110     {
0111         return m_plugin;
0112     }
0113 
0114     /**
0115      * Open terminal view at \p dirPath location for project \p project
0116      */
0117     void openTerminal(const QString &dirPath, KateProject *project);
0118 
0119     /**
0120      * Open a project
0121      */
0122     void openProject(KateProject *project);
0123 
0124 public Q_SLOTS:
0125     /**
0126      * Create views for given project.
0127      * Either gives existing ones or creates new one
0128      * @param project project we want view for
0129      * @return views (normal + info view)
0130      */
0131     QPair<KateProjectView *, KateProjectInfoView *> viewForProject(KateProject *project);
0132 
0133     /**
0134      * Switch to project for given dir, if any there!
0135      * @param dir dir with the project
0136      */
0137     void switchToProject(const QDir &dir);
0138 
0139     void runCmdInTerminal(const QString &workingDir, const QString &cmd);
0140 
0141     void updateGitBranchButton(KateProject *project);
0142 
0143 private Q_SLOTS:
0144     /**
0145      * Plugin config updated
0146      */
0147     void slotConfigUpdated();
0148 
0149     /**
0150      * New view got created, we need to update our connections
0151      * @param view new created view
0152      */
0153     void slotViewCreated(KTextEditor::View *view);
0154 
0155     /**
0156      * View got destroyed.
0157      * @param view deleted view
0158      */
0159     void slotViewDestroyed(QObject *view);
0160 
0161     /**
0162      * Activate the previous project.
0163      */
0164     void slotProjectPrev();
0165 
0166     /**
0167      * Activate the next project.
0168      */
0169     void slotProjectNext();
0170 
0171     /**
0172      * Reload current project, if any.
0173      * This will trigger a reload with force.
0174      */
0175     void slotProjectReload();
0176 
0177     /**
0178      * Close currently active project.
0179      */
0180     void slotCloseProject();
0181 
0182     /**
0183      * Close all projects.
0184      */
0185     void slotCloseAllProjects();
0186 
0187     /**
0188      * Close all projects without open documents.
0189      */
0190     void slotCloseAllProjectsWithoutDocuments();
0191 
0192     /**
0193      * Handle closing of a project.
0194      */
0195     void slotHandleProjectClosing(KateProject *project);
0196 
0197     /**
0198      * Lookup current word
0199      */
0200     void slotProjectIndex();
0201 
0202     /**
0203      * Goto current word
0204      */
0205     void slotGotoSymbol();
0206 
0207     /**
0208      * activate the given project inside the project tool view
0209      * will NOT show the project toolview
0210      * @param project project to activate
0211      */
0212     void slotActivateProject(KateProject *project);
0213 
0214 Q_SIGNALS:
0215 
0216     /**
0217      * Emitted if project is about to close.
0218      */
0219     void pluginProjectRemoved(QString baseDir, QString name);
0220 
0221     /**
0222      * Emitted if project is added.
0223      */
0224     void pluginProjectAdded(QString baseDir, QString name);
0225 
0226     /**
0227      * Emitted if project is about to close.
0228      */
0229     void pluginProjectClose(KateProject *project);
0230 
0231     /**
0232      * Emitted if projectFileName changed.
0233      */
0234     void projectFileNameChanged();
0235 
0236     /**
0237      * Emitted if projectMap changed.
0238      */
0239     void projectMapChanged();
0240 
0241     /**
0242      * Emitted when a ctags lookup in requested
0243      * @param word lookup word
0244      */
0245     void projectLookupWord(const QString &word);
0246 
0247     /**
0248      * Emitted when a ctags goto sysmbol is requested
0249      * @param word lookup word
0250      */
0251     void gotoSymbol(const QString &word, int &results);
0252 
0253 private Q_SLOTS:
0254     /**
0255      * This slot is called whenever the active view changes in our main window.
0256      */
0257     void slotViewChanged();
0258 
0259     /**
0260      * Current project changed.
0261      * @param index index in toolbox
0262      */
0263     void slotCurrentChanged(int index);
0264 
0265     /**
0266      * Url changed, to auto-load projects
0267      */
0268     void slotDocumentUrlChanged(KTextEditor::Document *document);
0269 
0270     /**
0271      * A helper to trigger an update of the git-widget.
0272      */
0273     void slotDocumentSaved();
0274 
0275     /**
0276      * Show context menu
0277      */
0278     void slotContextMenuAboutToShow();
0279 
0280     /**
0281      * Handle esc key and hide the toolview
0282      */
0283     void handleEsc(QEvent *e);
0284 
0285     /**
0286      * Update git status on toolview shown
0287      */
0288     void slotUpdateStatus(bool visible);
0289 
0290     /**
0291      * Open a folder / project
0292      */
0293     void openDirectoryOrProject();
0294     void openDirectoryOrProject(const QDir &dir);
0295 
0296     /**
0297      * Show projects To-Dos and Fix-mes
0298      */
0299     static void showProjectTodos();
0300 
0301     /**
0302      * Enable/disable project actions
0303      */
0304     void updateActions();
0305 
0306 private:
0307     /**
0308      * find current selected or under cursor word
0309      */
0310     QString currentWord() const;
0311 
0312 private:
0313     /**
0314      * Watches for changes to .git/index
0315      * If this is non-empty, we registered that file in the project watcher
0316      */
0317     QString m_gitChangedWatcherFile;
0318 
0319     /**
0320      * our plugin
0321      */
0322     KateProjectPlugin *m_plugin;
0323 
0324     /**
0325      * the main window we belong to
0326      */
0327     KTextEditor::MainWindow *m_mainWindow;
0328 
0329     /**
0330      * our projects toolview
0331      */
0332     QWidget *m_toolView;
0333 
0334     /**
0335      * our projects info toolview
0336      */
0337     QWidget *m_toolInfoView;
0338 
0339     /**
0340      * our projects info toolview
0341      */
0342     std::unique_ptr<QWidget> m_gitToolView;
0343 
0344     /**
0345      * our cross-projects toolview
0346      */
0347     QWidget *m_toolMultiView;
0348 
0349     /**
0350      * combo box with all loaded projects inside
0351      */
0352     QComboBox *m_projectsCombo;
0353 
0354     /**
0355      * combo box with all loaded projects inside
0356      */
0357     QComboBox *m_projectsComboGit;
0358 
0359     /**
0360      * Reload button
0361      */
0362     QToolButton *m_reloadButton;
0363 
0364     /**
0365      * Closing button for current project
0366      */
0367     QToolButton *m_closeProjectButton;
0368 
0369     /**
0370      * Git status refresh button
0371      */
0372     QToolButton *m_gitStatusRefreshButton;
0373 
0374     /**
0375      * stacked widget will all currently created project views
0376      */
0377     QStackedWidget *m_stackedProjectViews;
0378 
0379     /**
0380      * stacked widget will all currently created project info views
0381      */
0382     QStackedWidget *m_stackedProjectInfoViews;
0383 
0384     /**
0385      * stacked widget will all currently created git views
0386      */
0387     QStackedWidget *m_stackedGitViews;
0388 
0389     /**
0390      * project => view
0391      */
0392     QMap<KateProject *, QPair<KateProjectView *, KateProjectInfoView *>> m_project2View;
0393 
0394     /**
0395      * remember current active view text editor view
0396      * might be 0
0397      */
0398     QPointer<KTextEditor::View> m_activeTextEditorView;
0399 
0400     /**
0401      * remember for which text views we might need to cleanup stuff
0402      */
0403     QSet<QObject *> m_textViews;
0404 
0405     /**
0406      * project related actions
0407      */
0408     QAction *m_lookupAction;
0409     QAction *m_gotoSymbolAction;
0410     QAction *m_gotoSymbolActionAppMenu;
0411     QAction *m_projectTodosAction;
0412     QAction *m_projectPrevAction;
0413     QAction *m_projectNextAction;
0414     QAction *m_projectGotoIndexAction;
0415     QAction *m_projectCloseAction;
0416     QAction *m_projectCloseAllAction;
0417     QAction *m_projectCloseWithoutDocumentsAction;
0418     QAction *m_projectReloadAction;
0419 
0420     /**
0421       checkout branch button in the statusbar
0422      */
0423     std::unique_ptr<QToolButton> m_branchBtn = nullptr;
0424 };