1 /****************************************************************************
2 **
3 ** This file is part of the LibreCAD project, a 2D CAD program
4 **
5 ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl)
6 ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved.
7 **
8 **
9 ** This file may be distributed and/or modified under the terms of the
10 ** GNU General Public License version 2 as published by the Free Software
11 ** Foundation and appearing in the file gpl-2.0.txt included in the
12 ** packaging of this file.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ** GNU General Public License for more details.
18 **
19 ** You should have received a copy of the GNU General Public License
20 ** along with this program; if not, write to the Free Software
21 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 **
23 ** This copyright notice MUST APPEAR in all copies of the script!
24 **
25 **********************************************************************/
26 
27 #include <QKeyEvent>
28 #include "rs_actioninterface.h"
29 #include "rs_graphicview.h"
30 #include "rs_commands.h"
31 #include "rs_dialogfactory.h"
32 #include "rs_coordinateevent.h"
33 #include "rs_debug.h"
34 
35 /**
36  * Constructor.
37  *
38  * Sets the entity container on which the action class inherited
39  * from this interface operates.
40  *
41  * @param name Action name. This can be used internally for
42  *             debugging mainly.
43  * @param container Entity container this action operates on.
44  * @param graphicView Graphic view instance this action operates on.
45  *                    Please note that an action belongs to this
46  *                    view.
47  * @param cursor Default mouse cursor for this action. If the action
48  *               is suspended and resumed again the cursor will always
49  *               be reset to the one given here.
50  */
RS_ActionInterface(const char * name,RS_EntityContainer & container,RS_GraphicView & graphicView)51 RS_ActionInterface::RS_ActionInterface(const char* name,
52                                        RS_EntityContainer& container,
53                                        RS_GraphicView& graphicView) :
54 RS_Snapper(container, graphicView) {
55 
56     RS_DEBUG->print("RS_ActionInterface::RS_ActionInterface: Setting up action: \"%s\"", name);
57 
58     this->name = name;
59     status = 0;
60     finished = false;
61     //triggerOnResume = false;
62 
63     // graphic provides a pointer to the graphic if the
64     // entity container is a graphic (i.e. can also hold
65     // layers).
66     graphic = container.getGraphic();
67 
68     // document pointer will be used for undo / redo
69     document = container.getDocument();
70 
71     //this->cursor = cursor;
72     //setSnapMode(graphicView.getDefaultSnapMode());
73     actionType=RS2::ActionNone;
74 
75     RS_DEBUG->print("RS_ActionInterface::RS_ActionInterface: Setting up action: \"%s\": OK", name);
76 
77 }
78 
79 /**
80  * Must be implemented to return the ID of this action.
81 *
82 * @todo no default implementation
83  */
rtti() const84 RS2::ActionType RS_ActionInterface::rtti() const{
85 	return actionType;
86 }
87 
88 /**
89  * @return name of this action
90  */
getName()91 QString RS_ActionInterface::getName() {
92     return name;
93 }
94 
setName(const char * _name)95 void RS_ActionInterface::setName(const char* _name) {
96     this->name=_name;
97 }
98 
99 /**
100  * Called to initiate an action. This funtcion is often
101  * overwritten by the implementing action.
102  *
103  * @param status The status on which to initiate this action.
104  * default is 0 to begin the action.
105  */
init(int status)106 void RS_ActionInterface::init(int status)
107 {
108     setStatus(status);
109     if (status>=0) {
110         RS_Snapper::init();
111         updateMouseButtonHints();
112         updateMouseCursor();
113     }else{
114         //delete snapper when finished, bug#3416878
115         deleteSnapper();
116 
117     }
118 }
119 
120 
121 
122 /**
123  * Called when the mouse moves and this is the current action.
124  * This function can be overwritten by the implementing action.
125  * The default implementation keeps track of the mouse position.
126  */
mouseMoveEvent(QMouseEvent *)127 void RS_ActionInterface::mouseMoveEvent(QMouseEvent*) {}
128 
129 /**
130  * Called when the left mouse button is pressed and this is the
131  * current action.
132  * This function can be overwritten by the implementing action.
133  * The default implementation does nothing.
134  */
mousePressEvent(QMouseEvent *)135 void RS_ActionInterface::mousePressEvent(QMouseEvent*) {}
136 
137 /**
138  * Called when the left mouse button is released and this is
139  * the current action.
140  * This function can be overwritten by the implementing action.
141  * The default implementation does nothing.
142  */
mouseReleaseEvent(QMouseEvent *)143 void RS_ActionInterface::mouseReleaseEvent(QMouseEvent*) {}
144 
145 /**
146  * Called when a key is pressed and this is the current action.
147  * This function can be overwritten by the implementing action.
148  * The default implementation does nothing.
149  */
keyPressEvent(QKeyEvent * e)150 void RS_ActionInterface::keyPressEvent(QKeyEvent* e) {
151     e->ignore();
152 }
153 
154 /**
155  * Called when a key is released and this is the current action.
156  * This function can be overwritten by the implementing action.
157  * The default implementation does nothing.
158  */
keyReleaseEvent(QKeyEvent * e)159 void RS_ActionInterface::keyReleaseEvent(QKeyEvent* e) {
160     e->ignore();
161 }
162 
163 /**
164  * Coordinate event. Triggered usually from a command line.
165  * This function can be overwritten by the implementing action.
166  * The default implementation does nothing.
167  */
coordinateEvent(RS_CoordinateEvent *)168 void RS_ActionInterface::coordinateEvent(RS_CoordinateEvent*) {}
169 
170 /**
171  * Called when a command from the command line is launched.
172  * and this is the current action.
173  * This function can be overwritten by the implementing action.
174  * The default implementation does nothing.
175  */
commandEvent(RS_CommandEvent *)176 void RS_ActionInterface::commandEvent(RS_CommandEvent*) {
177 }
178 
179 /**
180  * Must be implemented to return the currently available commands
181  *  for the command line.
182  */
getAvailableCommands()183 QStringList RS_ActionInterface::getAvailableCommands() {
184 	return QStringList{};
185 }
186 
187 /**
188  * Sets the current status (progress) of this action.
189  * The default implementation sets the class variable 'status' to the
190  * given value and finishes the action if 'status' is negative.
191  *
192  * @param status Status number. It's up to the action implementor
193  *               what the action uses the status for. However, a
194  *               negative status number finishes the action. Usually
195  *               the status of an action increases for every step
196  *               of progress and decreases when the user goes one
197  *               step back (i.e. presses the right mouse button).
198  */
setStatus(int status)199 void RS_ActionInterface::setStatus(int status) {
200     this->status = status;
201     updateMouseButtonHints();
202     updateMouseCursor();
203     if(status<0) finish();
204 }
205 
206 /**
207  * @return Current status of this action.
208  */
getStatus()209 int RS_ActionInterface::getStatus() {
210     return status;
211 }
212 
213 /**
214  * Triggers this action. This should be called after all
215  * data needed for this action was collected / set.
216  * The default implementation does nothing.
217  */
trigger()218 void RS_ActionInterface::trigger() {}
219 
220 /**
221  * Should be overwritten to update the mouse button hints
222  * wherever they might needed.
223  */
updateMouseButtonHints()224 void RS_ActionInterface::updateMouseButtonHints() {}
225 
226 /**
227  * Should be overwritten to set the mouse cursor for this action.
228  */
updateMouseCursor()229 void RS_ActionInterface::updateMouseCursor() {}
230 
231 /**
232  * @return true, if the action is finished and can be deleted.
233  */
isFinished()234 bool RS_ActionInterface::isFinished() {
235     return finished;
236 }
237 
238 
239 /**
240  * Forces a termination of the action without any cleanup.
241  */
setFinished()242 void RS_ActionInterface::setFinished() {
243         status = -1;
244 }
245 
246 
247 /**
248  * Finishes this action.
249  */
finish(bool)250 void RS_ActionInterface::finish(bool /*updateTB*/)
251 {
252 	RS_DEBUG->print("RS_ActionInterface::finish");
253 	//refuse to quit the default action
254 	if(rtti() != RS2::ActionDefault) {
255 		status = -1;
256 		finished = true;
257 		hideOptions();
258 		RS_Snapper::finish();
259 	}
260 	RS_DEBUG->print("RS_ActionInterface::finish: OK");
261 }
262 
263 /**
264  * Called by the event handler to give this action a chance to
265  * communicate with its predecessor.
266  */
setPredecessor(RS_ActionInterface * pre)267 void RS_ActionInterface::setPredecessor(RS_ActionInterface* pre) {
268     predecessor = pre;
269 }
270 
271 /**
272  * Suspends this action while another action takes place.
273  */
suspend()274 void RS_ActionInterface::suspend() {
275     RS_Snapper::suspend();
276 }
277 
278 /**
279  * Resumes an action after it was suspended.
280  */
resume()281 void RS_ActionInterface::resume() {
282     updateMouseCursor();
283     updateMouseButtonHints();
284     RS_Snapper::resume();
285 }
286 
287 /**
288  * Hides the tool options. Default implementation does nothing.
289  */
hideOptions()290 void RS_ActionInterface::hideOptions() {
291     RS_Snapper::hideOptions();
292 }
293 
294 /**
295  * Shows the tool options. Default implementation does nothing.
296  */
showOptions()297 void RS_ActionInterface::showOptions() {
298     RS_Snapper::showOptions();
299 }
300 
setActionType(RS2::ActionType actionType)301 void RS_ActionInterface::setActionType(RS2::ActionType actionType){
302 	this->actionType=actionType;
303 }
304 
305 /**
306  * Calls checkCommand() from the RS_COMMANDS module.
307  */
checkCommand(const QString & cmd,const QString & str,RS2::ActionType action)308 bool RS_ActionInterface::checkCommand(const QString& cmd, const QString& str,
309                                       RS2::ActionType action) {
310     return RS_COMMANDS->checkCommand(cmd, str, action);
311 }
312 
313 /**
314  * Calls command() from the RS_COMMANDS module.
315  */
command(const QString & cmd)316 QString RS_ActionInterface::command(const QString& cmd) {
317     return RS_COMMANDS->command(cmd);
318 }
319 
320 /**
321  * Calls msgAvailableCommands() from the RS_COMMANDS module.
322  */
msgAvailableCommands()323 QString RS_ActionInterface::msgAvailableCommands() {
324     return RS_COMMANDS->msgAvailableCommands();
325 }
326 
327