1 /* 2 * Copyright 2012, 2013 Thomas Schöps 3 * Copyright 2015-2017 Kai Pastor 4 * 5 * This file is part of OpenOrienteering. 6 * 7 * OpenOrienteering is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * OpenOrienteering is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with OpenOrienteering. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #ifndef OPENORIENTEERING_EDIT_TOOL_H 22 #define OPENORIENTEERING_EDIT_TOOL_H 23 24 #include <utility> 25 #include <vector> 26 27 #include <Qt> 28 #include <QFlags> 29 #include <QObject> 30 #include <QPointF> 31 #include <QRectF> 32 #include <QRgb> 33 #include <QScopedPointer> 34 #include <QString> 35 36 #include "core/map_coord.h" 37 #include "tools/tool.h" 38 #include "tools/tool_base.h" 39 40 class QAction; 41 class QPainter; 42 class QPointF; 43 class QRectF; 44 45 namespace OpenOrienteering { 46 47 class MapEditorController; 48 class MapWidget; 49 class Object; 50 class ObjectSelector; 51 52 using SelectionInfoVector = std::vector<std::pair<int, Object*>>; 53 54 55 /** 56 * Base class for object editing tools. 57 */ 58 class EditTool : public MapEditorToolBase 59 { 60 public: 61 /** 62 * @brief A type for general information on what is hovered over. 63 */ 64 enum HoverFlag 65 { 66 OverNothing = 0, 67 OverFrame = 1, 68 OverObjectNode = 2, 69 OverPathEdge = 4, 70 }; 71 Q_DECLARE_FLAGS(HoverState, HoverFlag) 72 73 Q_OBJECT 74 public: 75 EditTool(MapEditorController* editor, MapEditorTool::Type type, QAction* tool_action); 76 77 ~EditTool() override; 78 79 /** 80 * The platform's key for deleting selected objects. 81 * 82 * OS X use the backspace key for deleting selected objects, 83 * while other platforms use the delete key. 84 * 85 * This causes translation issues and inconsistent behaviour on OS X: 86 * - In Finder, moving an object to trash is Cmd+Backspace. 87 * - Other programs are reported to use [forward] delete. 88 * - Some programs are reported to support multiple keys, 89 * e.g. Delete and Backspace. 90 * - A major source of irritation is the absence of a delete key on some 91 * Macbooks. On these keyboards, delete is entered as Fn+Backspace. 92 * - Some programs use another key for delete, e.g. "x". 93 * (Note that Cmd-x (aka Cut) will have a similar effect.) 94 * 95 * \todo Either use a function for testing whether a key means 96 * "delete object", or switch to a QAction based implementation 97 * since QAction supports alternative QKeySequences. 98 */ 99 #ifdef Q_OS_MACOS 100 static constexpr Qt::Key DeleteObjectKey = Qt::Key_Backspace; 101 #else 102 static constexpr Qt::Key DeleteObjectKey = Qt::Key_Delete; 103 #endif 104 105 protected: 106 /** 107 * Deletes all selected objects and updates the status text. 108 */ 109 void deleteSelectedObjects(); 110 111 /** 112 * Creates a replace object undo step for the given object. 113 */ 114 void createReplaceUndoStep(Object* object); 115 116 /** 117 * Returns if the point is inside the click_tolerance from the rect's border. 118 */ 119 bool pointOverRectangle(const QPointF& point, const QRectF& rect) const; 120 121 /** 122 * Returns the point on the rect which is closest to the given point. 123 */ 124 static MapCoordF closestPointOnRect(MapCoordF point, const QRectF& rect); 125 126 /** 127 * Configures the angle helper from the primary directions of the edited objects. 128 * 129 * If no primary directions are found, the default directions are set. 130 */ 131 void setupAngleHelperFromEditedObjects(); 132 133 /** 134 * Draws a bounding box with a dashed line of the given color. 135 * 136 * @param bounding_box the box extent in map coordinates 137 */ 138 void drawBoundingBox(QPainter* painter, MapWidget* widget, const QRectF& bounding_box, const QRgb& color); 139 140 /** 141 * Draws a bounding path with a dashed line of the given color. 142 * 143 * @param bounding_box the box extent in map coordinates 144 */ 145 void drawBoundingPath(QPainter* painter, MapWidget* widget, const std::vector<QPointF>& bounding_path, const QRgb& color); 146 147 /** 148 * An utility implementing object selection logic. 149 */ 150 QScopedPointer<ObjectSelector> object_selector; 151 }; 152 153 154 } // namespace OpenOrienteering 155 156 157 Q_DECLARE_OPERATORS_FOR_FLAGS(OpenOrienteering::EditTool::HoverState) 158 159 160 #endif 161