File indexing completed on 2024-05-19 05:42:18

0001 // ct_lvtqtw_graphicsview.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 INCLUDED_LVTQTC_GRAPHICSVIEW
0021 #define INCLUDED_LVTQTC_GRAPHICSVIEW
0022 
0023 #include <lvtqtc_export.h>
0024 
0025 #include <ct_lvtqtc_undo_manager.h>
0026 
0027 #include <ct_lvtplg_pluginmanager.h>
0028 #include <ct_lvtqtc_itool.h>
0029 #include <ct_lvtshr_graphenums.h>
0030 
0031 #include <ct_lvtldr_lakosiannode.h>
0032 
0033 #include <QGraphicsView>
0034 #include <QUndoCommand>
0035 
0036 #include <memory>
0037 #include <qevent.h>
0038 
0039 class CodeVisApplicationTestFixture;
0040 namespace Codethink::lvtclr {
0041 class ColorManagement;
0042 }
0043 namespace Codethink::lvtldr {
0044 class NodeStorage;
0045 }
0046 namespace Codethink::lvtprj {
0047 class ProjectFile;
0048 }
0049 
0050 namespace Codethink::lvtqtc {
0051 
0052 class LakosianEntity;
0053 
0054 class LVTQTC_EXPORT GraphicsView : public QGraphicsView
0055 // Visualizes a Tree model and reacts to changes
0056 {
0057     Q_OBJECT
0058   public:
0059     friend class ::CodeVisApplicationTestFixture;
0060 
0061     // CREATORS
0062     explicit GraphicsView(Codethink::lvtldr::NodeStorage& nodeStorage,
0063                           lvtprj::ProjectFile const& projectFile,
0064                           QWidget *parent = nullptr);
0065     // Constructor
0066 
0067     ~GraphicsView() noexcept override;
0068     // Destructor
0069 
0070     // METHODS
0071     void setColorManagement(const std::shared_ptr<lvtclr::ColorManagement>& colorManagement);
0072 
0073     void setUndoManager(UndoManager *undoManager);
0074 
0075     Q_SIGNAL void zoomFactorChanged(int zoomFactor);
0076     // The current zoom factor, emitted when the internal value changes
0077 
0078     Q_SIGNAL void visibleAreaChanged(QRectF rect);
0079     // we moved or zoomed in, the area changed.
0080 
0081     [[nodiscard]] int zoomFactor() const;
0082 
0083     void setZoomFactor(int zoomFactorInPercent);
0084     // set's the zoom factor in percents
0085 
0086     void calculateCurrentZoomFactor();
0087     // when we load a graph, we zoom out or zoom in, to fit the entire graph on screen
0088     // so we need to calculate how much this affected the zoom.
0089 
0090     void zoomIntoRect(const QPoint& topLeft, const QPoint& bottomRight);
0091 
0092     void fitAllInView();
0093     // Adjust zoom so that the whole scene is visible
0094 
0095     void fitItemInView(QGraphicsItem *entity);
0096     // Adjust zoom so that the main entity is visible
0097 
0098     void setPluginManager(Codethink::lvtplg::PluginManager& pm);
0099 
0100     Q_SLOT void toggleMinimap(bool toggle);
0101     // Shows / Hides the minimap widget
0102 
0103     Q_SLOT void toggleLegend(bool toggle);
0104     // shows / hides the legend widget
0105 
0106     Q_SLOT void undoCommandReceived(QUndoCommand *command);
0107 
0108     Q_SIGNAL void packageNavigateRequested(const QString& qualifiedName);
0109     Q_SIGNAL void componentNavigateRequested(const QString& qualifiedName);
0110     Q_SIGNAL void classNavigateRequested(const QString& qualifiedName);
0111 
0112     Q_SIGNAL void graphLoadStarted();
0113     Q_SIGNAL void graphLoadFinished();
0114 
0115     Q_SIGNAL void requestNext();
0116     Q_SIGNAL void requestPrevious();
0117 
0118     Q_SIGNAL void onUndoCommandReceived(Codethink::lvtqtc::GraphicsView *, QUndoCommand *);
0119 
0120     Q_SIGNAL void errorMessage(const QString& message);
0121 
0122     Q_SIGNAL void newSelectionMade(std::deque<Codethink::lvtldr::LakosianNode *> selectedNodes);
0123 
0124     void debugVisibleScreen();
0125 
0126     void setCurrentTool(ITool *tool);
0127     // sets the tool that's controlling the view.
0128     // currently this is used just for the drawForeground
0129     // as the rest I can easily handle via eventFilter.
0130     // a better approach is to use the event filter for the drawForeground,
0131     // but there's no event for that, just a paintEvent.
0132 
0133     ITool *currentTool() const;
0134 
0135     // Called by the Search Box.
0136     Q_SLOT void setSearchMode(lvtshr::SearchMode mode);
0137     Q_SLOT void setSearchString(const QString& search);
0138     Q_SLOT void highlightedNextSearchElement();
0139     Q_SLOT void highlightedPreviousSearchElement();
0140     Q_SIGNAL void searchTotal(int nr);
0141     Q_SIGNAL void currentSearchItemHighlighted(int idx);
0142     void doSearch();
0143 
0144     /* Return all of the items of type T */
0145     template<typename T>
0146     QList<T *> allItemsByType() const
0147     {
0148         return commonItemsByType<T>(items());
0149     }
0150 
0151     /* Return all of the items of type T in the specific area */
0152     template<typename T>
0153     QList<T *> itemsByType(const QPoint& point) const
0154     {
0155         return commonItemsByType<T>(items(point));
0156     }
0157 
0158     /* Return all of the items of type T */
0159     template<typename T>
0160     QList<T *> itemsByType(QRect area, Qt::ItemSelectionMode mode) const
0161     {
0162         return commonItemsByType<T>(items(area, mode));
0163     }
0164 
0165     /* Return the first item of the type T at a specific position */
0166     template<typename T>
0167     T *itemByTypeAt(const QPoint& pos) const
0168     {
0169         const auto qItems = itemsByType<T>(pos);
0170         if (qItems.empty()) {
0171             return nullptr;
0172         }
0173         return qItems[0];
0174     }
0175 
0176   protected:
0177     void fitRectInView(QRectF const& r);
0178 
0179     void keyPressEvent(QKeyEvent *event) override;
0180     void keyReleaseEvent(QKeyEvent *event) override;
0181     void mouseMoveEvent(QMouseEvent *event) override;
0182     void mousePressEvent(QMouseEvent *event) override;
0183     void mouseReleaseEvent(QMouseEvent *event) override;
0184     void showEvent(QShowEvent *event) override;
0185     void wheelEvent(QWheelEvent *event) override;
0186     void contextMenuEvent(QContextMenuEvent *event) override;
0187     void dragEnterEvent(QDragEnterEvent *event) override;
0188     void dragMoveEvent(QDragMoveEvent *event) override;
0189     void dropEvent(QDropEvent *event) override;
0190     void drawForeground(QPainter *painter, const QRectF& rect) override;
0191     [[nodiscard]] GraphicsScene *graphicsScene() const;
0192 
0193     template<typename T>
0194     QList<T *> commonItemsByType(const QList<QGraphicsItem *>& items) const
0195     {
0196         QList<T *> byType;
0197         for (auto *item : items) {
0198             if (auto itemCast = dynamic_cast<T *>(item)) {
0199                 byType.push_back(itemCast);
0200             }
0201         }
0202         return byType;
0203     }
0204 
0205   private:
0206     // DATA TYPES
0207     struct Private;
0208     std::unique_ptr<Private> d;
0209 };
0210 
0211 } // end namespace Codethink::lvtqtc
0212 
0213 #endif