1 /*
2  * LibrePCB - Professional EDA for everyone!
3  * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4  * https://librepcb.org/
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef LIBREPCB_LIBRARY_EDITOR_PACKAGEEDITORFSM_H
21 #define LIBREPCB_LIBRARY_EDITOR_PACKAGEEDITORFSM_H
22 
23 /*******************************************************************************
24  *  Includes
25  ******************************************************************************/
26 #include "../../common/editorwidgetbase.h"
27 
28 #include <QtCore>
29 
30 #include <memory>
31 
32 /*******************************************************************************
33  *  Namespace / Forward Declarations
34  ******************************************************************************/
35 namespace librepcb {
36 
37 class UndoStack;
38 class GraphicsScene;
39 class GraphicsView;
40 class GridProperties;
41 class IF_GraphicsLayerProvider;
42 class PrimitiveTextGraphicsItem;
43 
44 namespace library {
45 
46 class Package;
47 class Footprint;
48 class FootprintGraphicsItem;
49 
50 namespace editor {
51 
52 class PackageEditorState;
53 class PackageEditorWidget;
54 
55 /*******************************************************************************
56  *  Class PackageEditorFsm
57  ******************************************************************************/
58 
59 /**
60  * @brief The PackageEditorFsm class is the finit state machine (FSM) of the
61  * package editor
62  */
63 class PackageEditorFsm final : public QObject {
64   Q_OBJECT
65 
66 private:  // Types
67   enum class State {
68     IDLE,
69     SELECT,
70     ADD_THT_PADS,
71     ADD_SMT_PADS,
72     ADD_NAMES,
73     ADD_VALUES,
74     DRAW_LINE,
75     DRAW_RECT,
76     DRAW_POLYGON,
77     DRAW_CIRCLE,
78     DRAW_TEXT,
79     ADD_HOLES,
80   };
81 
82 public:  // Types
83   struct Context {
84     workspace::Workspace& workspace;
85     PackageEditorWidget& editorWidget;
86     UndoStack& undoStack;
87     bool readOnly;
88     GraphicsScene& graphicsScene;
89     GraphicsView& graphicsView;
90     const IF_GraphicsLayerProvider& layerProvider;
91     Package& package;
92     std::shared_ptr<Footprint> currentFootprint;
93     std::shared_ptr<FootprintGraphicsItem> currentGraphicsItem;
94     ToolBarProxy& commandToolBar;
95   };
96 
97 public:
98   // Constructors / Destructor
99   PackageEditorFsm() = delete;
100   PackageEditorFsm(const PackageEditorFsm& other) = delete;
101   explicit PackageEditorFsm(const Context& context) noexcept;
102   virtual ~PackageEditorFsm() noexcept;
103 
104   // Getters
105   EditorWidgetBase::Tool getCurrentTool() const noexcept;
106 
107   // Event Handlers
108   bool processChangeCurrentFootprint(
109       const std::shared_ptr<Footprint>& fpt) noexcept;
110   bool processGraphicsSceneMouseMoved(QGraphicsSceneMouseEvent& e) noexcept;
111   bool processGraphicsSceneLeftMouseButtonPressed(
112       QGraphicsSceneMouseEvent& e) noexcept;
113   bool processGraphicsSceneLeftMouseButtonReleased(
114       QGraphicsSceneMouseEvent& e) noexcept;
115   bool processGraphicsSceneLeftMouseButtonDoubleClicked(
116       QGraphicsSceneMouseEvent& e) noexcept;
117   bool processGraphicsSceneRightMouseButtonReleased(
118       QGraphicsSceneMouseEvent& e) noexcept;
119   bool processSelectAll() noexcept;
120   bool processCut() noexcept;
121   bool processCopy() noexcept;
122   bool processPaste() noexcept;
123   bool processRotateCw() noexcept;
124   bool processRotateCcw() noexcept;
125   bool processMirror() noexcept;
126   bool processFlip() noexcept;
127   bool processRemove() noexcept;
128   bool processAbortCommand() noexcept;
129   bool processStartSelecting() noexcept;
130   bool processStartAddingFootprintThtPads() noexcept;
131   bool processStartAddingFootprintSmtPads() noexcept;
132   bool processStartAddingNames() noexcept;
133   bool processStartAddingValues() noexcept;
134   bool processStartDrawLines() noexcept;
135   bool processStartDrawRects() noexcept;
136   bool processStartDrawPolygons() noexcept;
137   bool processStartDrawCircles() noexcept;
138   bool processStartDrawTexts() noexcept;
139   bool processStartAddingHoles() noexcept;
140   bool processStartDxfImport() noexcept;
141 
142   // Operator Overloadings
143   PackageEditorFsm& operator=(const PackageEditorFsm& rhs) = delete;
144 
145 signals:
146   void toolChanged(EditorWidgetBase::Tool newTool);
147 
148 private:  // Methods
149   PackageEditorState* getCurrentState() const noexcept;
150   bool setNextState(State state) noexcept;
151   bool leaveCurrentState() noexcept;
152   bool enterNextState(State state) noexcept;
153 
154 private:  // Data
155   Context mContext;
156   QMap<State, PackageEditorState*> mStates;
157   State mCurrentState;
158   QScopedPointer<PrimitiveTextGraphicsItem> mSelectFootprintGraphicsItem;
159 };
160 
161 /*******************************************************************************
162  *  End of File
163  ******************************************************************************/
164 
165 }  // namespace editor
166 }  // namespace library
167 }  // namespace librepcb
168 
169 #endif  // LIBREPCB_LIBRARY_EDITOR_PACKAGEEDITORFSM_H
170