1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : #include "DeleteTextTxn.h"
39 : #include "nsIDOMCharacterData.h"
40 : #include "nsISelection.h"
41 : #include "nsSelectionState.h"
42 :
43 : #ifdef NS_DEBUG
44 : static bool gNoisy = false;
45 : #endif
46 :
47 0 : DeleteTextTxn::DeleteTextTxn()
48 : : EditTxn()
49 : ,mEditor(nsnull)
50 : ,mElement()
51 : ,mOffset(0)
52 : ,mNumCharsToDelete(0)
53 0 : ,mRangeUpdater(nsnull)
54 : {
55 0 : }
56 :
57 1464 : NS_IMPL_CYCLE_COLLECTION_CLASS(DeleteTextTxn)
58 :
59 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(DeleteTextTxn, EditTxn)
60 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mElement)
61 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
62 :
63 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DeleteTextTxn, EditTxn)
64 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mElement)
65 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
66 :
67 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DeleteTextTxn)
68 0 : NS_INTERFACE_MAP_END_INHERITING(EditTxn)
69 :
70 0 : NS_IMETHODIMP DeleteTextTxn::Init(nsIEditor *aEditor,
71 : nsIDOMCharacterData *aElement,
72 : PRUint32 aOffset,
73 : PRUint32 aNumCharsToDelete,
74 : nsRangeUpdater *aRangeUpdater)
75 : {
76 0 : NS_ASSERTION(aEditor&&aElement, "bad arg");
77 0 : if (!aEditor || !aElement) { return NS_ERROR_NULL_POINTER; }
78 :
79 0 : mEditor = aEditor;
80 0 : mElement = do_QueryInterface(aElement);
81 : // do nothing if the node is read-only
82 0 : if (!mEditor->IsModifiableNode(mElement)) {
83 0 : return NS_ERROR_FAILURE;
84 : }
85 :
86 0 : mOffset = aOffset;
87 0 : mNumCharsToDelete = aNumCharsToDelete;
88 0 : NS_ASSERTION(0!=aNumCharsToDelete, "bad arg, numCharsToDelete");
89 : PRUint32 count;
90 0 : aElement->GetLength(&count);
91 0 : NS_ASSERTION(count>=aNumCharsToDelete, "bad arg, numCharsToDelete. Not enough characters in node");
92 0 : NS_ASSERTION(count>=aOffset+aNumCharsToDelete, "bad arg, numCharsToDelete. Not enough characters in node");
93 0 : mDeletedText.Truncate();
94 0 : mRangeUpdater = aRangeUpdater;
95 0 : return NS_OK;
96 : }
97 :
98 0 : NS_IMETHODIMP DeleteTextTxn::DoTransaction(void)
99 : {
100 : #ifdef NS_DEBUG
101 0 : if (gNoisy) { printf("Do Delete Text\n"); }
102 : #endif
103 :
104 0 : NS_ASSERTION(mEditor && mElement, "bad state");
105 0 : if (!mEditor || !mElement) { return NS_ERROR_NOT_INITIALIZED; }
106 : // get the text that we're about to delete
107 0 : nsresult result = mElement->SubstringData(mOffset, mNumCharsToDelete, mDeletedText);
108 0 : NS_ASSERTION(NS_SUCCEEDED(result), "could not get text to delete.");
109 0 : result = mElement->DeleteData(mOffset, mNumCharsToDelete);
110 0 : NS_ENSURE_SUCCESS(result, result);
111 :
112 0 : if (mRangeUpdater)
113 0 : mRangeUpdater->SelAdjDeleteText(mElement, mOffset, mNumCharsToDelete);
114 :
115 : // only set selection to deletion point if editor gives permission
116 : bool bAdjustSelection;
117 0 : mEditor->ShouldTxnSetSelection(&bAdjustSelection);
118 0 : if (bAdjustSelection)
119 : {
120 0 : nsCOMPtr<nsISelection> selection;
121 0 : result = mEditor->GetSelection(getter_AddRefs(selection));
122 0 : NS_ENSURE_SUCCESS(result, result);
123 0 : NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
124 0 : result = selection->Collapse(mElement, mOffset);
125 0 : NS_ASSERTION((NS_SUCCEEDED(result)), "selection could not be collapsed after undo of deletetext.");
126 : }
127 : else
128 : {
129 : // do nothing - dom range gravity will adjust selection
130 : }
131 0 : return result;
132 : }
133 :
134 : //XXX: we may want to store the selection state and restore it properly
135 : // was it an insertion point or an extended selection?
136 0 : NS_IMETHODIMP DeleteTextTxn::UndoTransaction(void)
137 : {
138 : #ifdef NS_DEBUG
139 0 : if (gNoisy) { printf("Undo Delete Text\n"); }
140 : #endif
141 :
142 0 : NS_ASSERTION(mEditor && mElement, "bad state");
143 0 : if (!mEditor || !mElement) { return NS_ERROR_NOT_INITIALIZED; }
144 :
145 0 : return mElement->InsertData(mOffset, mDeletedText);
146 : }
147 :
148 0 : NS_IMETHODIMP DeleteTextTxn::GetTxnDescription(nsAString& aString)
149 : {
150 0 : aString.AssignLiteral("DeleteTextTxn: ");
151 0 : aString += mDeletedText;
152 0 : return NS_OK;
153 4392 : }
|