1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
|
/* This file is part of the KDE project
*
* Copyright (C) 2005 Leo Savernik <l.savernik@aon.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef domtreecommands_H
#define domtreecommands_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <dom/dom_element.h>
#include <dom/dom_exception.h>
#include <dom/dom_string.h>
#include <dom/dom_text.h>
#include <kcommand.h>
#include <qobject.h>
#include <qptrlist.h>
class DOMTreeView;
class KPrinter;
class KURL;
namespace domtreeviewer {
class ManipulationCommandSignalEmitter;
class ChangedNodeSet;
/** returns a localized string for the given dom exception code */
QString domErrorMessage(int exception_code);
/**
* Internal class for emitting signals.
* @internal
*/
class ManipulationCommandSignalEmitter : public QObject
{
Q_OBJECT
ManipulationCommandSignalEmitter();
virtual ~ManipulationCommandSignalEmitter();
#undef signals
#define signals public
signals:
#undef signals
#define signals protected
/** emitted if the DOM structure has been changed */
void structureChanged();
/** emitted if a DOM node has been changed */
void nodeChanged(const DOM::Node &changedNode);
/** emitted if an error occurred
* @param err_id DOM error id
* @param msg error message
*/
void error(int err_id, const QString &msg);
private: // make moc not complain
friend class ManipulationCommand;
};
/**
* Base class of all dom tree manipulation commands.
* @author Leo Savernik
*/
class ManipulationCommand : public KCommand
{
public:
ManipulationCommand();
virtual ~ManipulationCommand();
/** returns whether this command is still valid and can be executed */
bool isValid() const { return !_exception.code; }
/** returns the last occurred DOM exception */
DOM::DOMException exception() const { return _exception; }
/** returns true when the next issue of execute will reapply the command */
bool shouldReapply() const { return _reapplied; }
/** returns true if the command may emit signals */
bool allowSignals() const { return allow_signals; }
/** connects the given signal to a slot */
static void connect(const char *signal, QObject *recv, const char *slot);
/** does grunt work and calls apply()/reapply() */
virtual void execute();
/** does grunt work and calls unapply() */
virtual void unexecute();
protected:
virtual void apply() = 0;
virtual void reapply();
virtual void unapply() = 0;
void handleException(DOM::DOMException &);
void checkAndEmitSignals();
void addChangedNode(const DOM::Node &);
static ManipulationCommandSignalEmitter *mcse();
protected:
DOM::DOMException _exception;
ChangedNodeSet *changedNodes;
bool _reapplied:1;
bool struc_changed:1;
private:
bool allow_signals:1;
friend class MultiCommand;
};
/**
* Combines multiple commands into a single command.
*
* Does basically the same as KMacroCommand, but inherits from
* ManipulationCommand, and supports rollback.
*/
class MultiCommand : public ManipulationCommand
{
public:
MultiCommand(const QString &name);
virtual ~MultiCommand();
/** Adds a new command. Will take ownership of \c cmd */
void addCommand(ManipulationCommand *cmd);
virtual QString name() const;
protected:
virtual void apply();
virtual void unapply();
void mergeChangedNodesFrom(ManipulationCommand *cmd);
protected:
QPtrList<ManipulationCommand> cmds;
QString _name;
};
/**
* Adds an attribute to a node.
* @author Leo Savernik
*/
class AddAttributeCommand : public ManipulationCommand
{
public:
AddAttributeCommand(const DOM::Element &element, const QString &attrName, const QString &attrValue);
virtual ~AddAttributeCommand();
virtual QString name() const;
protected:
virtual void apply();
virtual void unapply();
protected:
DOM::Element _element;
DOM::DOMString attrName;
DOM::DOMString attrValue;
};
/**
* Manipulates an attribute's value.
* @author Leo Savernik
*/
class ChangeAttributeValueCommand : public ManipulationCommand
{
public:
ChangeAttributeValueCommand(const DOM::Element &element, const QString &attr, const QString &value);
virtual ~ChangeAttributeValueCommand();
virtual QString name() const;
protected:
virtual void apply();
virtual void unapply();
protected:
DOM::Element _element;
DOM::DOMString _attr;
DOM::DOMString old_value;
DOM::DOMString new_value;
};
/**
* Removes an attribute from a node.
* @author Leo Savernik
*/
class RemoveAttributeCommand : public ManipulationCommand
{
public:
RemoveAttributeCommand(const DOM::Element &element, const QString &attrName);
virtual ~RemoveAttributeCommand();
virtual QString name() const;
protected:
virtual void apply();
virtual void unapply();
protected:
DOM::Element _element;
DOM::DOMString attrName;
DOM::DOMString oldAttrValue;
};
/**
* Renames an attribute.
* @author Leo Savernik
*/
class RenameAttributeCommand : public ManipulationCommand
{
public:
RenameAttributeCommand(const DOM::Element &element, const QString &attrOldName, const QString &attrNewName);
virtual ~RenameAttributeCommand();
virtual QString name() const;
protected:
virtual void apply();
virtual void unapply();
protected:
DOM::Element _element;
DOM::DOMString attrOldName;
DOM::DOMString attrNewName;
DOM::DOMString attrValue;
};
/**
* Changes the value of a CData-node.
* @author Leo Savernik
*/
class ChangeCDataCommand : public ManipulationCommand
{
public:
ChangeCDataCommand(const DOM::CharacterData &, const QString &value);
virtual ~ChangeCDataCommand();
virtual QString name() const;
protected:
virtual void apply();
virtual void unapply();
protected:
DOM::CharacterData cdata;
DOM::DOMString value;
DOM::DOMString oldValue;
bool has_newlines;
};
/**
* Handles insertion and deletion primitives of nodes.
* @author Leo Savernik
*/
class ManipulateNodeCommand : public ManipulationCommand
{
public:
/**
* Prepare command, where \c node is to be contained in \c parent, just
* before \c after. If \c after is 0, it is appended at the end.
*/
ManipulateNodeCommand(const DOM::Node &node, const DOM::Node &parent, const DOM::Node &after);
virtual ~ManipulateNodeCommand();
protected:
void insert();
void remove();
protected:
DOM::Node _node;
DOM::Node _parent;
DOM::Node _after;
};
/**
* Inserts a node into the tree.
*
* The handed in node may be a full tree, even a document fragment.
*
* @author Leo Savernik
*/
class InsertNodeCommand : public ManipulateNodeCommand
{
public:
/**
* Prepare insertion command, inserting \c node into \c parent, just
* before \c after. If \c after is 0, append it to the list of children.
*/
InsertNodeCommand(const DOM::Node &node, const DOM::Node &parent, const DOM::Node &after);
virtual ~InsertNodeCommand();
virtual QString name() const;
protected:
virtual void apply();
virtual void unapply();
protected:
};
/**
* Removes a node from the tree.
*
* The handed in node may be a full tree, even a document fragment.
*
* @author Leo Savernik
*/
class RemoveNodeCommand : public ManipulateNodeCommand
{
public:
/**
* Prepare insertion command, inserting \c node into \c parent, just
* before \c after. If \c after is 0, append it to the list of children.
*/
RemoveNodeCommand(const DOM::Node &node, const DOM::Node &parent, const DOM::Node &after);
virtual ~RemoveNodeCommand();
virtual QString name() const;
protected:
virtual void apply();
virtual void unapply();
protected:
};
/**
* Moves a node.
* @author Leo Savernik
*/
class MoveNodeCommand : public ManipulationCommand
{
public:
/**
* Move \c node from current position into \c parent, just before \c after.
* Appends if \c after is 0.
*/
MoveNodeCommand(const DOM::Node &node, const DOM::Node &parent, const DOM::Node &after);
virtual ~MoveNodeCommand();
virtual QString name() const;
protected:
virtual void apply();
virtual void unapply();
protected:
DOM::Node _node;
DOM::Node old_parent, old_after;
DOM::Node new_parent, new_after;
};
} // namespace domtreeviewer
#endif // domtreewindow_H
|