File indexing completed on 2024-05-19 05:41:56

0001 // mainwindow.h                                                      -*-C++-*-
0002 
0003 /*
0004 // Copyright 2023 Codethink Ltd <codethink@codethink.co.uk>
0005 // SPDX-License-Identifier: Apache-2.0
0006 //
0007 // Licensed under the Apache License, Version 2.0 (the "License");
0008 // you may not use this file except in compliance with the License.
0009 // You may obtain a copy of the License at
0010 //
0011 //     http://www.apache.org/licenses/LICENSE-2.0
0012 //
0013 // Unless required by applicable law or agreed to in writing, software
0014 // distributed under the License is distributed on an "AS IS" BASIS,
0015 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0016 // See the License for the specific language governing permissions and
0017 // limitations under the License.
0018 */
0019 
0020 #ifndef MAINWINDOW_H
0021 #define MAINWINDOW_H
0022 
0023 #include <ct_lvtshr_graphenums.h>
0024 
0025 #include <ct_lvtmdl_debugmodel.h>
0026 #include <ct_lvtmdl_modelhelpers.h>
0027 
0028 #include <ct_lvtldr_lakosiannode.h>
0029 #include <ct_lvtplg_pluginmanager.h>
0030 #include <ct_lvtqtc_graphicsscene.h>
0031 #include <ct_lvtqtw_splitterview.h>
0032 #include <ct_lvtqtw_statusbar.h>
0033 
0034 #include <ct_lvtmdl_fieldstreemodel.h>
0035 
0036 #include <ct_lvtprj_projectfile.h>
0037 
0038 #include <ui_mainwindow.h>
0039 
0040 #include <KXmlGuiWindow>
0041 
0042 #include <QElapsedTimer>
0043 #include <QFileDialog>
0044 #include <QSplitter>
0045 #include <optional>
0046 
0047 class QModelIndex;
0048 class QLabel;
0049 
0050 class CodeVisApplicationTestFixture;
0051 
0052 namespace Codethink::lvtmdl {
0053 class ErrorsModel;
0054 class NamespaceTreeModel;
0055 class PackageTreeModel;
0056 class TreeFilterModel;
0057 class BaseTableModel;
0058 } // namespace Codethink::lvtmdl
0059 
0060 namespace Codethink::lvtqtc {
0061 class GraphicsView;
0062 class UndoManager;
0063 } // namespace Codethink::lvtqtc
0064 
0065 namespace Codethink::lvtqtw {
0066 class TabWidget;
0067 class ParseCodebaseDialog;
0068 class ConfigurationDialog;
0069 } // namespace Codethink::lvtqtw
0070 
0071 class WrappedUiMainWindow : public Ui::MainWindow {
0072   public:
0073     WrappedUiMainWindow(Codethink::lvtldr::NodeStorage& sharedNodeStorage,
0074                         Codethink::lvtprj::ProjectFile& projectFile,
0075                         Codethink::lvtplg::PluginManager *pluginManager = nullptr);
0076     void setupUi(QMainWindow *mw);
0077 
0078     Codethink::lvtqtw::SplitterView *mainSplitter = nullptr;
0079     Codethink::lvtldr::NodeStorage& sharedNodeStorage;
0080     Codethink::lvtprj::ProjectFile& projectFile;
0081     Codethink::lvtplg::PluginManager *pluginManager = nullptr;
0082 };
0083 
0084 class MainWindow : public KXmlGuiWindow {
0085     Q_OBJECT
0086   public:
0087     friend class ::CodeVisApplicationTestFixture;
0088 
0089     // initializes the qrc file, should be called before the mainwindow is build.
0090     static void initializeResource();
0091     explicit MainWindow(Codethink::lvtldr::NodeStorage& sharedNodeStorage,
0092                         Codethink::lvtplg::PluginManager *pluginManager = nullptr,
0093                         Codethink::lvtqtc::UndoManager *undoManager = nullptr,
0094                         Codethink::lvtmdl::DebugModel *debugModel = nullptr);
0095     ~MainWindow() noexcept;
0096 
0097     [[nodiscard]] bool openProjectFromPath(const QString& path);
0098     void openProjectSettings();
0099 
0100     void newTab();
0101     // Creates a new tab on the focused tabwidget.
0102 
0103     void closeCurrentTab();
0104     // closes the current tab on the focused tabwidget.
0105 
0106     void toggleSplitView() const;
0107 
0108     void selectLeftSplitView() const;
0109     void selectRightSplitView() const;
0110 
0111     void setCurrentGraphFromString(Codethink::lvtmdl::NodeType::Enum type, const QString& qualifiedName);
0112     // searches for an QModelIndex that matches the str, and calls setCurrentGraph
0113 
0114     Codethink::lvtprj::ProjectFile& projectFile();
0115 
0116     [[nodiscard]] QString currentMessage() const;
0117 
0118     void setupActions();
0119     void dragEnterEvent(QDragEnterEvent *e) override;
0120     void dropEvent(QDropEvent *e) override;
0121 
0122   protected:
0123     virtual QString requestProjectName();
0124 
0125   private:
0126     void saveTabsOnProject();
0127     void loadTabsFromProject();
0128 
0129     void openGenerateDatabase();
0130 
0131     void openCodeGenerationWindow();
0132 
0133     void exportSvg();
0134 
0135     void currentGraphSplitChanged(Codethink::lvtqtw::TabWidget *tabWidget);
0136 
0137     void closeProject();
0138     bool newProject();
0139     void newProjectFromSource();
0140 
0141     void openProjectAction();
0142 
0143     [[nodiscard]] bool askCloseCurrentProject();
0144     [[nodiscard]] bool tryCreateEmptyProjectFile();
0145 
0146     void setProjectWidgetsEnabled(bool enabled);
0147     void createStatusBar();
0148 
0149     void updateSessionPtr();
0150     // when a database changes, we need to update the session
0151     // pointer to all objects that can query the db.
0152 
0153     void showWelcomeScreen();
0154     void showProjectView();
0155 
0156     void mousePressEvent(QMouseEvent *ev) override;
0157     void mouseReleaseEvent(QMouseEvent *ev) override;
0158     void closeEvent(QCloseEvent *ev) override;
0159     bool eventFilter(QObject *obj, QEvent *event) override;
0160 
0161     void configurePluginDocks();
0162 
0163     Q_SLOT void focusedGraphChanged(const QString& qualifiedName);
0164     Q_SLOT void graphLoadStarted();
0165     Q_SLOT void graphLoadFinished();
0166     Q_SLOT void triggerUndo();
0167     Q_SLOT void triggerRedo();
0168     Q_SLOT void bookmarkCurrentTab();
0169     Q_SLOT void bookmarksChanged();
0170 
0171     Q_SLOT void generateDatabaseReadyForUpdate();
0172     // database generation is ready to replace our database when it is next
0173     // idle
0174 
0175     Q_SLOT void prepareForCodeDatabaseUpdate();
0176     // To be called once the database is idle
0177 
0178     Q_SLOT void generateCodeDatabaseFinished(Codethink::lvtqtw::ParseCodebaseDialog::State state);
0179     // database generation is finished. Load new database.
0180 
0181     Q_SLOT void setCurrentGraph(const QModelIndex& idx);
0182     // callback when something is selected in the tree view
0183 
0184     Q_SLOT void newTabRequested(const QModelIndex& idx);
0185     Q_SLOT void newTabRequested(const QModelIndexList& idxList);
0186     // callback when a new tab is requested from the tree view
0187     Q_SLOT void newTabRequested(const QSet<QString> qualifiedNames);
0188 
0189     Q_SLOT void changeCurrentGraphWidget(int graphTabIdx);
0190     // callback for when the tab we update the title.
0191 
0192     Q_SLOT void openPreferences();
0193     // callback for openPreferences action
0194 
0195     Q_SLOT void openPreferencesAt(std::optional<QString> preferredPage = std::nullopt);
0196 
0197     Q_SLOT void saveProject();
0198     // saves the current project
0199 
0200     Q_SLOT void saveProjectAs();
0201     // saves the current project on the specified folder.
0202 
0203     Q_SLOT void showWarningMessage(const QString& message);
0204     Q_SLOT void showErrorMessage(const QString& message);
0205     Q_SLOT void showSuccessMessage(const QString& message);
0206     Q_SLOT void showMessage(const QString& message, KMessageWidget::MessageType type);
0207 
0208     Q_SLOT void requestSearch();
0209     // Show / Hide the search box on the selected widget, if the widget is searchable.
0210 
0211     Q_SLOT void disableWindow();
0212 
0213     Q_SLOT void enableWindow();
0214 
0215     Q_SIGNAL void databaseIdle();
0216 
0217     Q_SLOT void
0218     requestMenuPackageView(const QModelIndexList& multiSelection, const QModelIndex& clickedOn, const QPoint& pos);
0219     Q_SLOT void requestMenuNamespaceView([[maybe_unused]] const QModelIndexList& multiSelection,
0220                                          const QModelIndex& clickedOn,
0221                                          const QPoint& pos);
0222     Q_SLOT void updatePluginData();
0223 
0224     Q_SLOT void updateTableModels(std::deque<Codethink::lvtldr::LakosianNode *> selectedNodes);
0225 
0226     void createReport(std::string const& title, std::string const& htmlContents);
0227 
0228     WrappedUiMainWindow ui;
0229 
0230     Codethink::lvtldr::NodeStorage& sharedNodeStorage;
0231 
0232     std::unique_ptr<Codethink::lvtqtw::ParseCodebaseDialog> d_parseCodebaseDialog_p;
0233 
0234     // Data Models
0235     Codethink::lvtmdl::NamespaceTreeModel *namespaceModel = nullptr;
0236     Codethink::lvtmdl::PackageTreeModel *packageModel = nullptr;
0237     Codethink::lvtmdl::ErrorsModel *d_errorModel_p = nullptr;
0238 
0239     QList<Codethink::lvtmdl::BaseTableModel *> tableModels;
0240     Codethink::lvtmdl::FieldsTreeModel *fieldsModel;
0241 
0242     // TODO: Maybe we should move these variables to a GraphWidgetManager of sorts.
0243     Codethink::lvtqtc::GraphicsView *currentGraphWidget = nullptr;
0244     Codethink::lvtqtw::TabWidget *currentGraphTab = nullptr;
0245 
0246     Codethink::lvtqtw::CodeVisStatusBar *d_status_bar;
0247     QString m_currentQualifiedName;
0248 
0249     QList<QWidget *> d_disabledWidgets;
0250     // Widgets we disabled during the last graph load
0251 
0252     bool d_graphLoadRunning = false;
0253 
0254     QElapsedTimer d_graphProgressPartialTimer;
0255     QElapsedTimer d_graphProgressTimer;
0256 
0257     Codethink::lvtprj::ProjectFile d_projectFile;
0258 
0259     Codethink::lvtplg::PluginManager *d_pluginManager_p = nullptr;
0260     Codethink::lvtqtc::UndoManager *d_undoManager_p = nullptr;
0261     Codethink::lvtmdl::DebugModel *debugModel = nullptr;
0262 
0263     QDockWidget *d_dockReports = nullptr;
0264     QTabWidget *d_reportsTabWidget = nullptr;
0265 };
0266 
0267 #endif