Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
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, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #pragma once
24 :
25 : #include "elementeditdata.h"
26 : #include "transaction/undoablecommand.h"
27 :
28 : #include "../dom/textbase.h"
29 :
30 : namespace mu::engraving {
31 : //---------------------------------------------------------
32 : // TextEditData
33 : //---------------------------------------------------------
34 :
35 : struct TextEditData : public ElementEditData {
36 0 : OBJECT_ALLOCATOR(engraving, TextEditData)
37 : public:
38 :
39 : String oldXmlText;
40 : size_t startUndoIdx = 0;
41 :
42 : bool deleteText = false;
43 :
44 : String selectedText;
45 : String selectedPlainText;
46 : static constexpr const char* mimeRichTextFormat = "application/musescore/richtext";
47 :
48 4 : TextEditData(TextBase* t)
49 4 : : m_textBase(t) {}
50 : TextEditData(const TextEditData&) = delete;
51 : TextEditData& operator=(const TextEditData&) = delete;
52 : ~TextEditData();
53 :
54 0 : virtual EditDataType type() override { return EditDataType::TextEditData; }
55 :
56 : void setDeleteText(bool val) { deleteText = val; }
57 :
58 : private:
59 : TextBase* m_textBase = nullptr;
60 : };
61 :
62 : //---------------------------------------------------------
63 : // TextEditUndoableCommand
64 : //---------------------------------------------------------
65 :
66 : class TextEditUndoableCommand : public UndoableCommand
67 : {
68 0 : OBJECT_ALLOCATOR(engraving, TextEditUndoableCommand)
69 :
70 : public:
71 9 : UNDO_TYPE(CommandType::TextEdit)
72 0 : UNDO_NAME("TextEdit")
73 27 : UNDO_CHANGED_OBJECTS({ m_cursor.text() })
74 :
75 11 : TextEditUndoableCommand(const TextCursor& tc)
76 11 : : m_cursor(tc) {}
77 :
78 3 : bool matchesFilter(UndoableCommandFilter f, const EngravingItem* target) const override
79 : {
80 3 : return f == UndoableCommandFilter::TextEdit && m_cursor.text() == target;
81 : }
82 :
83 47 : TextCursor& cursor() { return m_cursor; }
84 9 : const TextCursor& cursor() const { return m_cursor; }
85 :
86 : protected:
87 : TextCursor m_cursor;
88 : };
89 :
90 : //---------------------------------------------------------
91 : // ChangeText
92 : //---------------------------------------------------------
93 :
94 : class ChangeTextProperties : public TextEditUndoableCommand
95 : {
96 6 : OBJECT_ALLOCATOR(engraving, ChangeTextProperties)
97 :
98 : public:
99 : ChangeTextProperties(const TextCursor* tc, Pid propId, const PropertyValue& propVal, PropertyFlags flags);
100 : void undo() override;
101 : void redo() override;
102 :
103 : private:
104 :
105 : void restoreSelection();
106 :
107 : String m_xmlText;
108 : Pid m_propertyId;
109 : PropertyValue m_propertyVal;
110 : FontStyle m_existingStyle;
111 : PropertyFlags m_flags;
112 : };
113 :
114 : //---------------------------------------------------------
115 : // ChangeText
116 : //---------------------------------------------------------
117 :
118 : class ChangeText : public TextEditUndoableCommand
119 : {
120 0 : OBJECT_ALLOCATOR(engraving, ChangeText)
121 :
122 : public:
123 5 : ChangeText(const TextCursor* tc, const String& t)
124 5 : : TextEditUndoableCommand(*tc), m_s(t), m_format(*tc->format()) {}
125 : virtual void undo() override = 0;
126 : virtual void redo() override = 0;
127 : const String& string() const { return m_s; }
128 :
129 : protected:
130 : void insertText();
131 : void removeText();
132 :
133 : private:
134 :
135 : String m_s;
136 : CharFormat m_format;
137 : };
138 :
139 : //---------------------------------------------------------
140 : // InsertText
141 : //---------------------------------------------------------
142 :
143 : class InsertText : public ChangeText
144 : {
145 10 : OBJECT_ALLOCATOR(engraving, InsertText)
146 : public:
147 5 : InsertText(const TextCursor* tc, const String& t)
148 5 : : ChangeText(tc, t) {}
149 5 : virtual void redo() override { insertText(); }
150 0 : virtual void undo() override { removeText(); }
151 0 : UNDO_NAME("InsertText")
152 : };
153 :
154 : //---------------------------------------------------------
155 : // RemoveText
156 : //---------------------------------------------------------
157 :
158 : class RemoveText : public ChangeText
159 : {
160 0 : OBJECT_ALLOCATOR(engraving, RemoveText)
161 : public:
162 0 : RemoveText(const TextCursor* tc, const String& t)
163 0 : : ChangeText(tc, t) {}
164 0 : virtual void redo() override { removeText(); }
165 0 : virtual void undo() override { insertText(); }
166 0 : UNDO_NAME("RemoveText")
167 : };
168 :
169 : //---------------------------------------------------------
170 : // SplitJoinText
171 : //---------------------------------------------------------
172 :
173 : class SplitJoinText : public TextEditUndoableCommand
174 : {
175 0 : OBJECT_ALLOCATOR(engraving, SplitJoinText)
176 : protected:
177 : virtual void split();
178 : virtual void join();
179 :
180 : public:
181 0 : SplitJoinText(const TextCursor* tc)
182 0 : : TextEditUndoableCommand(*tc) {}
183 : };
184 :
185 : //---------------------------------------------------------
186 : // SplitText
187 : //---------------------------------------------------------
188 :
189 : class SplitText : public SplitJoinText
190 : {
191 0 : OBJECT_ALLOCATOR(engraving, SplitText)
192 :
193 0 : virtual void undo() override { join(); }
194 0 : virtual void redo() override { split(); }
195 :
196 : public:
197 0 : SplitText(const TextCursor* tc)
198 0 : : SplitJoinText(tc) {}
199 0 : UNDO_NAME("SplitText")
200 : };
201 :
202 : //---------------------------------------------------------
203 : // JoinText
204 : //---------------------------------------------------------
205 :
206 : class JoinText : public SplitJoinText
207 : {
208 0 : OBJECT_ALLOCATOR(engraving, JoinText)
209 :
210 0 : virtual void undo() override { split(); }
211 0 : virtual void redo() override { join(); }
212 :
213 : public:
214 0 : JoinText(const TextCursor* tc)
215 0 : : SplitJoinText(tc) {}
216 0 : UNDO_NAME("JoinText")
217 : };
218 : } // namespace mu::engraving
|