1 /*
2    NSTextStorage.h
3 
4    Copyright (C) 1996,1999 Free Software Foundation, Inc.
5 
6    Author:  Daniel Böhringer <boehring@biomed.ruhr-uni-bochum.de>
7    Date: August 1998
8    Source by Daniel Böhringer integrated into GNUstep gui
9    by Felipe A. Rodriguez <far@ix.netcom.com>
10    Update: Richard Frith-Macdonald <richard@brainstorm.co.uk>
11 
12    Documentation written from scratch by: Nicola Pero
13    <nicola@brainstorm.co.uk>
14 
15    This file is part of the GNUstep GUI Library.
16 
17    This library is free software; you can redistribute it and/or
18    modify it under the terms of the GNU Lesser General Public
19    License as published by the Free Software Foundation; either
20    version 2 of the License, or (at your option) any later version.
21 
22    This library is distributed in the hope that it will be useful,
23    but WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
25    Lesser General Public License for more details.
26 
27    You should have received a copy of the GNU Lesser General Public
28    License along with this library; see the file COPYING.LIB.
29    If not, see <http://www.gnu.org/licenses/> or write to the
30    Free Software Foundation, 51 Franklin Street, Fifth Floor,
31    Boston, MA 02110-1301, USA.
32 */
33 
34 #ifndef _GNUstep_H_NSTextStorage
35 #define _GNUstep_H_NSTextStorage
36 
37 #import <Foundation/NSAttributedString.h>
38 #import <Foundation/NSGeometry.h>
39 #import <Foundation/NSObject.h>
40 #import <AppKit/AppKitDefines.h>
41 
42 @class NSNotification;
43 @class NSString;
44 @class GSLayoutManager;
45 @class NSFont;
46 @class NSColor;
47 
48 /*
49  * When edit:range:changeInLength: is called, it takes a mask saying
50  * what has been edited.  The mask is NSTextStorageEditedAttributes
51  * if the attributes have been changed, NSTextStorageEditedCharacters
52  * if the characters have been changed, and
53  * NSTextStorageEditedAttributes | NSTextStorageEditedCharacters if both
54  * characters and attributes were edited.
55  */
56 enum
57 {
58   NSTextStorageEditedAttributes = 1,
59   NSTextStorageEditedCharacters = 2
60 };
61 
62 /*
63  * The NSTextStorage
64  */
65 @interface NSTextStorage : NSMutableAttributedString
66 {
67   NSRange		_editedRange;
68   int			_editedDelta;
69   NSMutableArray	*_layoutManagers;
70   id			_delegate;
71   unsigned		_editedMask;
72   unsigned		_editCount;
73 }
74 
75 - (void) addLayoutManager: (GSLayoutManager*)obj;
76 - (void) removeLayoutManager: (GSLayoutManager*)obj;
77 - (NSArray*) layoutManagers;
78 
79 /*
80  * This method is normally called between a beginEditing and an
81  * endEditing message to record any changes which were made to the
82  * receiver.  It is automatically called by the NSTextStorage
83  * primitives, so in other words, NSTextStorage calls it for you, and
84  * you don't normally need to call this method.  You might (a more
85  * theoretical than practical option) need to subclass it and override
86  * this method to take into account changes done.
87  *
88  * If the method is called outside a beginEditing/endEditing calls, it
89  * calls processEditing immediately.  As far as I understand, that would
90  * happen if you modify the NSTextStorage without enclosing your changes
91  * inside a beginEditing/endEditing calls.
92  *
93  * maks can be NSTextStorageEditedAttributes or
94  * NSTextStorageEditedCharacters, or and | of the two.
95  *
96  * the old range is the range affected by the change in the string ... in the
97  * original string.
98  *
99  * the changeInLength is, well, positive if you added characters, negative
100  * if you removed characters.  */
101 - (void) edited: (unsigned)mask range: (NSRange)old changeInLength: (int)delta;
102 
103 /*
104  * This method is called to process the editing once it's finished.
105  * Normally it is called by endEditing; but if you modify the NSTextStorage
106  * without enclosing the modifications into a beginEditing/endEditing pair,
107  * this method will be called directly by edited:range:changeInLength:.
108  *
109  * But in practice, what does this method do ?  Well, it posts the
110  * NSTextStorageWillProcessEditing notification.  Then, it calls
111  * fixAttributesAfterEditingRange:.  Then, it posts the
112  * NSTextStorageDidProcessEditing notification.  Finally, it tells the
113  * layout manager(s) about this change in the text storage by calling
114  * textStorage:edited:range:changeInLength:invalidatedRange:.  */
115 - (void) processEditing;
116 
117 /*
118  * Start a set of changes to the text storage.  All the changes are
119  * recorded and merged - without any layout to be done.  When you call
120  * endEditing, the layout will be done in one single operation.
121  *
122  * In practice, you should call beginEditing before starting to modify
123  * the NSTextStorage.  When you are finished modifying it and you want
124  * your changes to be propagated to the layout manager(s), you call
125  * endEditing.
126  *
127  * If you don't enclose your changes into a beginEditing/endEditing pair,
128  * it still works, but it's less efficient.
129  */
130 - (void) beginEditing;
131 
132 /*
133  * End a set of changes, and calls processEditing.
134  */
135 - (void) endEditing;
136 
137 /*
138  * The delegate can use the following methods when it receives a
139  * notification that a change was made.  The methods tell him what
140  * kind of change was made.  */
141 - (unsigned) editedMask;
142 - (NSRange) editedRange;
143 - (int) changeInLength;
144 
145 - (void) setDelegate: (id)delegate;
146 - (id) delegate;
147 
148 #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
149 - (void) ensureAttributesAreFixedInRange: (NSRange)range;
150 - (BOOL) fixesAttributesLazily;
151 - (void) invalidateAttributesInRange: (NSRange)range;
152 #endif
153 
154 /** Returns the string data stored by the receiver.<br />
155  * For performance reasons (and OSX compatibility) this is actually
156  * a proxy to the internal representation of the string.<br />
157  * This proxy provides an immutable string interface,
158  * but you must be aware that the underlying information may be modified
159  * by the receiver at any point, so if you need a consistent/fixed
160  * snapshot of the data (or if you are going to pass the string to other
161  * code which expects to be working with a constant string), you should
162  * copy the object returned by this method rather than simply retaining it.
163  */
164 - (NSString*) string;
165 @end
166 
167 
168 /****  NSTextStorage delegate methods ****/
169 
170 @interface NSObject (NSTextStorageDelegate)
171 
172 /*
173  * The delegate is automatically registered to receive the
174  * NSTextStorageWillProcessEditingNotification, and the
175  * NSTextStorageDidProcessEditingNotification via these methods, so
176  * once the notifications are sent, these methods of the delegate will
177  * be invokes.  In these methods the delegate can use editedMask,
178  * editedRange, changeInLength to figure out what the actual change
179  * is.
180  */
181 - (void) textStorageWillProcessEditing: (NSNotification*)notification;
182 - (void) textStorageDidProcessEditing: (NSNotification*)notification;
183 
184 @end
185 
186 @interface NSTextStorage (Scripting)
187 /*
188  * Attributes for string...
189 */
190 - (NSFont*) font;
191 - (void) setFont: (NSFont*)font;
192 
193 /*
194  * The text storage contents as an array of attribute runs.
195  */
196 - (NSArray *)attributeRuns;
197 
198 /*
199  * The text storage contents as an array of paragraphs.
200  */
201 - (NSArray *)paragraphs;
202 
203 /*
204  * The text storage contents as an array of words.
205  */
206 - (NSArray *)words;
207 
208 /*
209  * The text storage contents as an array of characters.
210  */
211 - (NSArray *)characters;
212 
213 /*
214  * The font color used when drawing text.
215  */
216 - (NSColor *)foregroundColor;
217 @end
218 
219 /**** Notifications ****/
220 
221 /* The object of the notification is the NSTextStorage itself.  */
222 APPKIT_EXPORT NSString *NSTextStorageWillProcessEditingNotification;
223 APPKIT_EXPORT NSString *NSTextStorageDidProcessEditingNotification;
224 
225 #endif
226