1
1
//
2
- // RichEditorState+UndoRedoManager .swift
2
+ // RichEditorState+UndoManager .swift
3
3
// RichEditorSwiftUI
4
4
//
5
5
// Created by Divyesh Vekariya on 06/01/25.
6
6
//
7
7
8
8
import Foundation
9
+ import SwiftUI
9
10
10
11
extension RichEditorState {
11
12
func updateUndoRedoState( ) {
@@ -24,7 +25,7 @@ extension RichEditorState {
24
25
// if let operation {
25
26
// self.undoManager.registerUndoOperation(operation)
26
27
// }
27
- // self.isOperationIsFromUser = false
28
+ self . isOperationIsFromUser = false
28
29
// self.operationRawText = self.attributedString.string
29
30
updateUndoRedoState ( )
30
31
}
@@ -46,7 +47,7 @@ extension RichEditorState {
46
47
private func restoreState( for operation: RichTextOperation , isRedo: Bool ) {
47
48
setSelectedRange ( range: operation. range)
48
49
if isRedo {
49
- setCurrentAttributes ( attributes: operation. attributes)
50
+ // setCurrentAttributes(attributes: operation.attributes)
50
51
}
51
52
52
53
switch operation. operationType {
@@ -78,7 +79,7 @@ extension RichEditorState {
78
79
}
79
80
80
81
if !isRedo {
81
- setCurrentAttributes ( attributes: undoManager . getPreviousAttributes ( ) )
82
+ setCurrentAttributes ( attributes: operation . previousAttributes )
82
83
}
83
84
84
85
updateUndoRedoState ( )
@@ -89,16 +90,23 @@ extension RichEditorState {
89
90
selectedRange = range
90
91
}
91
92
private func setCurrentAttributes( attributes: OperationAttributes ) {
92
- activeStyles = attributes. activeStyles
93
- headerType = attributes. headerType
94
- textAlignment = attributes. textAlignment
95
- fontName = attributes. fontName
96
- fontSize = attributes. fontSize
97
- colors = attributes. colors
98
- lineSpacing = attributes. lineSpacing
99
- paragraphStyle = attributes. paragraphStyle
100
- // styles = attributes.styles
101
- link = attributes. link
93
+ // let attributedStringCopy = NSMutableAttributedString(attributedString: attributes.attributedString)
94
+ // attributedString = attributedStringCopy
95
+ selectedRange = attributes. selectedRange
96
+ headerType = attributes. headerType
97
+ textAlignment = attributes. textAlignment
98
+ fontName = attributes. fontName
99
+ fontSize = attributes. fontSize
100
+ lineSpacing = attributes. lineSpacing
101
+ colors = attributes. colors
102
+ highlightingStyle = attributes. highlightingStyle
103
+ paragraphStyle = attributes. paragraphStyle
104
+ styles = attributes. styles
105
+ link = attributes. link
106
+ highlightedRange = attributes. highlightedRange
107
+ activeStyles = attributes. activeStyles
108
+ activeAttributes = attributes. activeAttributes
109
+ // rawText = attributes.rawText
102
110
}
103
111
104
112
func getAttributedStringBy( adding: Bool , chars: String , at index: Int )
@@ -126,15 +134,17 @@ extension RichEditorState {
126
134
return RichTextOperation (
127
135
operationType: . addOrRemoveText( newText: newText, rawText: rawText, isAdded: isAdded) ,
128
136
range: range,
129
- attributes: getCurrentAttributes ( )
137
+ attributes: getCurrentAttributes ( ) ,
138
+ previousAttributes: getPreviousAttributes ( )
130
139
)
131
140
}
132
141
133
142
func getOperationFor( style: RichTextSpanStyle , isAdded: Bool ) -> RichTextOperation {
134
143
return RichTextOperation (
135
144
operationType: . addOrRemoveStyle( style: style, isAdded: isAdded) ,
136
145
range: selectedRange,
137
- attributes: getCurrentAttributes ( )
146
+ attributes: getCurrentAttributes ( ) ,
147
+ previousAttributes: getPreviousAttributes ( )
138
148
)
139
149
}
140
150
@@ -152,7 +162,8 @@ extension RichEditorState {
152
162
return RichTextOperation (
153
163
operationType: . setStyleStyle( previousStyle: previousStyle, newStyle: newStyle, isSet: isSet) ,
154
164
range: selectedRange,
155
- attributes: getCurrentAttributes ( )
165
+ attributes: getCurrentAttributes ( ) ,
166
+ previousAttributes: getPreviousAttributes ( )
156
167
)
157
168
}
158
169
@@ -176,25 +187,88 @@ extension RichEditorState {
176
187
updateUndoRedoState ( )
177
188
}
178
189
179
- func registerUndoForSetStyle( previousStyle: RichTextSpanStyle ? , newStyle: RichTextSpanStyle ) {
190
+ func registerUndoForSetStyle( newStyle: RichTextSpanStyle ) {
191
+ let previousStyle = getPreviousStyleFor ( style: newStyle)
180
192
let operation = getOperationForSetStyle (
181
193
previousStyle: previousStyle, newStyle: newStyle, isSet: true )
182
194
undoManager. registerUndoOperation ( operation)
183
195
updateUndoRedoState ( )
184
196
}
185
197
186
- private func getCurrentAttributes( ) -> OperationAttributes {
187
- return OperationAttributes (
188
- activeStyles: activeStyles,
189
- headerType: headerType,
190
- textAlignment: textAlignment,
191
- fontName: fontName,
192
- fontSize: fontSize,
193
- colors: colors,
194
- lineSpacing: lineSpacing,
195
- paragraphStyle: paragraphStyle,
196
- styles: styles,
197
- link: link
198
- )
199
- }
198
+ private func getPreviousStyleFor( style: RichTextSpanStyle ) -> RichTextSpanStyle ? {
199
+ var previousStyle : RichTextSpanStyle ? = nil
200
+ switch style {
201
+ case . h1, . h2, . h3, . h4, . h5, . h6:
202
+ previousStyle = previousHeaderType. getTextSpanStyle ( )
203
+ case . size( _) :
204
+ previousStyle = . size( Int ( previousFontSize) )
205
+ case . font( _) :
206
+ let fontName : String = previousFontName. isEmpty ? RichTextFont . PickerFont. standardSystemFontDisplayName : previousFontName
207
+ previousStyle = . font( fontName)
208
+ case . color( _) :
209
+ if let color = previousColors [ . foreground] {
210
+ previousStyle = . color( Color ( color) )
211
+ } else {
212
+ previousStyle = . color( )
213
+ }
214
+ case . background( _) :
215
+ if let color = previousColors [ . background] {
216
+ previousStyle = . background( Color ( color) )
217
+ } else {
218
+ previousStyle = . background( )
219
+ }
220
+ case . align( _) :
221
+ previousStyle = . align( previousTextAlignment)
222
+ case . link( _) :
223
+ previousStyle = . link( previousLink)
224
+ default :
225
+ previousStyle = nil
226
+ }
227
+ return previousStyle
228
+ }
229
+
230
+ private func getCurrentAttributes( ) -> OperationAttributes {
231
+ let attributedString = NSMutableAttributedString ( attributedString: attributedString)
232
+
233
+ return OperationAttributes (
234
+ attributedString: attributedString,
235
+ selectedRange: selectedRange,
236
+ headerType: headerType,
237
+ textAlignment: textAlignment,
238
+ fontName: fontName,
239
+ fontSize: fontSize,
240
+ lineSpacing: lineSpacing,
241
+ colors: colors,
242
+ highlightingStyle: highlightingStyle,
243
+ paragraphStyle: paragraphStyle,
244
+ styles: styles,
245
+ link: link,
246
+ highlightedRange: highlightedRange,
247
+ activeStyles: activeStyles,
248
+ activeAttributes: activeAttributes,
249
+ rawText: rawText
250
+ )
251
+ }
252
+
253
+ private func getPreviousAttributes( ) -> OperationAttributes {
254
+ let previousAttributedString = NSMutableAttributedString ( attributedString: previousAttributedString)
255
+ return OperationAttributes (
256
+ attributedString: previousAttributedString,
257
+ selectedRange: previousSelectedRange,
258
+ headerType: previousHeaderType,
259
+ textAlignment: previousTextAlignment,
260
+ fontName: previousFontName,
261
+ fontSize: previousFontSize,
262
+ lineSpacing: previousLineSpacing,
263
+ colors: previousColors,
264
+ highlightingStyle: previousHighlightingStyle,
265
+ paragraphStyle: previousParagraphStyle,
266
+ styles: previousStyles,
267
+ link: previousLink,
268
+ highlightedRange: previousHighlightedRange,
269
+ activeStyles: previousActiveStyles,
270
+ activeAttributes: previousActiveAttributes,
271
+ rawText: previousRawText
272
+ )
273
+ }
200
274
}
0 commit comments