1 
2 //
3 // "$Id: Fl_Text_Buffer_mod.H 8148 2010-12-31 22:38:03Z matt $"
4 //
5 // Header file for Fl_Text_Buffer_mod class.
6 //
7 // Copyright 2001-2010 by Bill Spitzak and others.
8 // Original code Copyright Mark Edel.  Permission to distribute under
9 // the LGPL for the FLTK library granted by Mark Edel.
10 //
11 // This library is free software; you can redistribute it and/or
12 // modify it under the terms of the GNU Library General Public
13 // License as published by the Free Software Foundation; either
14 // version 2 of the License, or (at your option) any later version.
15 //
16 // This library is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 // Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public
22 // License along with this library; if not, write to the
23 //
24 //  Free Software Foundation, Inc.
25 //  51 Franklin Street, Fifth Floor
26 //  Boston, MA  02110-1301 USA.
27 //
28 // Please report all bugs and problems on the following page:
29 //
30 //     http://www.fltk.org/str.php
31 //
32 
33 /* \file
34  Fl_Text_Buffer_mod, Fl_Text_Selection_mod widget . */
35 
36 #ifndef Fl_Text_Buffer_mod_H
37 #define Fl_Text_Buffer_mod_H
38 
39 #include <config.h>
40 
41 #undef ASSERT_UTF8
42 
43 #ifdef ASSERT_UTF8
44 # include <assert.h>
45 # define IS_UTF8_ALIGNED(a) if (a && *a) assert(fl_utf8len(*(a))>0);
46 # define IS_UTF8_ALIGNED2(a, b) if (b>=0 && b<a->length()) assert(fl_utf8len(a->byte_at(b))>0);
47 #else
48 # define IS_UTF8_ALIGNED(a)
49 # define IS_UTF8_ALIGNED2(a, b)
50 #endif
51 
52 
53 /*
54  "character size" is the size of a UTF-8 character in bytes
55  "character width" is the width of a Unicode character in pixels
56  "column" was orginally defined as a character offset from the left margin.
57  It was identical to the byte offset. In UTF-8, we have neither a byte offset
58  nor truly fixed width fonts (*). Column could be a pixel value multiplied with
59  an average character width (which is a bearable approximation).
60 
61  * in Unicode, there are no fixed width fonts! Even if the ASCII characters may
62  happen to be all the same width in pixels, chinese charcaters surely are not.
63  There are plenty of exceptions, like ligatures, that make special handling of
64  "fixed" character widths a nightmare. I decided to remove all references to
65  fixed fonts and see "columns" as a multiple of the average width of a
66  character in the main font.
67  - Matthias
68  */
69 
70 
71 /* Maximum length in characters of a tab or control character expansion
72  of a single buffer character */
73 #define FL_TEXT_MAX_EXP_CHAR_LEN 20
74 
75 #include <FL/Fl_Export.H>
76 
77 
78 /**
79  \class Fl_Text_Selection_mod
80  \brief This is an internal class for Fl_Text_Buffer_mod to manage text selections.
81  This class works correctly with utf-8 strings assuming that the parameters
82  for all calls are on character boundaries.
83  */
84 class FL_EXPORT Fl_Text_Selection_mod {
85 	friend class Fl_Text_Buffer_mod;
86 
87 public:
88 
89 	/**
90 	 \brief Set the selection range.
91 	 \param start byte offset to first selected character
92 	 \param end byte offset pointing after last selected character
93 	 */
94 	void set(int start, int end);
95 
96 	/**
97 	 \brief Updates a selection afer text was modified.
98 	 Updates an individual selection for changes in the corresponding text
99 	 \param pos byte offset into text buffer at which the change occured
100 	 \param nDeleted number of bytes deleted from the buffer
101 	 \param nInserted number of bytes inserted into the buffer
102 	 */
103 	void update(int pos, int nDeleted, int nInserted);
104 
105 	/**
106 	 \brief Return the byte offset to the first selected character.
107 	 \return byte offset
108 	 */
start()109 	int start() const { return mStart; }
110 
111 	/**
112 	 \brief Return the byte ofsset to the character after the last selected character.
113 	 \return byte offset
114 	 */
end()115 	int end() const { return mEnd; }
116 
117 	/**
118 	 \brief Returns true if any text is selected.
119 	 \return a non-zero number if any text has been selected, or 0
120 	 if no text is selected.
121 	 */
selected()122 	bool selected() const { return mSelected; }
123 
124 	/**
125 	 \brief Modify the 'selected' flag.
126 	 \param b new flag
127 	 */
selected(bool b)128 	void selected(bool b) { mSelected = b; }
129 
130 	/**
131 	 Return true if position \p pos with indentation \p dispIndex is in
132 	 the Fl_Text_Selection_mod.
133 	 */
134 	int includes(int pos) const;
135 
136 	/**
137 	 \brief Return the positions of this selection.
138 	 \param start retrun byte offset to first selected character
139 	 \param end retrun byte offset pointing after last selected character
140 	 \return true if selected
141 	 */
142 	int position(int* start, int* end) const;
143 
144 protected:
145 
146 	int mStart;         ///< byte offset to the first selected character
147 	int mEnd;           ///< byte offset to the character after the last selected character
148 	bool mSelected;     ///< this flag is set if any text is selected
149 };
150 
151 
152 typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted,
153 int nRestyled, const char* deletedText,
154 void* cbArg);
155 
156 
157 typedef void (*Fl_Text_Predelete_Cb)(int pos, int nDeleted, void* cbArg);
158 
159 
160 /**
161  \brief This class manages unicode displayed in one or more Fl_Text_Display_mod widgets.
162 
163  All text in Fl_Text_Buffer_modmust be encoded in UTF-8. All indices used in the
164  function calls must be aligned to the start of a UTF-8 sequence. All indices
165  and pointers returned will be aligned. All functions that return a single
166  character will return that in an unsiged int in UCS-4 encoding.
167 
168  The Fl_Text_Buffer_mod class is used by the Fl_Text_Display_mod
169  and Fl_Text_Editor_mod to manage complex text data and is based upon the
170  excellent NEdit text editor engine - see http://www.nedit.org/.
171  */
172 class FL_EXPORT Fl_Text_Buffer_mod {
173 public:
174 
175 	/**
176 	 Create an empty text buffer of a pre-determined size.
177 	 \param requestedSize use this to avoid unnecessary re-allocation
178 	 if you know exactly how much the buffer will need to hold
179 	 \param preferredGapSize Initial size for the buffer gap (empty space
180 	 in the buffer where text might be inserted
181 	 if the user is typing sequential chars)
182 	 */
183 	Fl_Text_Buffer_mod(int requestedSize = 0, int preferredGapSize = 1024);
184 
185 	/**
186 	 Frees a text buffer
187 	 */
188 	~Fl_Text_Buffer_mod();
189 
190 	/**
191 	 \brief Returns the number of bytes in the buffer.
192 	 \return size of text in bytes
193 	 */
length()194 	int length() const { return mLength; }
195 
196 	/**
197 	 \brief Get a copy of the entire contents of the text buffer.
198 	 Memory is allocated to contain the returned string, which the caller
199 	 must free.
200 	 \return newly allocated text buffer - must be free'd, text is utf8
201 	 */
202 	char* text() const;
203 
204 	/**
205 	 Replaces the entire contents of the text buffer.
206 	 \param text Text must be valid utf8.
207 	 */
208 	void text(const char* text);
209 
210 	/**
211 	 \brief Get a copy of a part of the text buffer.
212 	 Return a copy of the text between \p start and \p end character positions
213 	 from text buffer \p buf. Positions start at 0, and the range does not
214 	 include the character pointed to by \p end.
215 	 When you are done with the text, free it using the free() function.
216 	 \param start byte offset to first character
217 	 \param end byte offset after last character in range
218 	 \return newly allocated text buffer - must be free'd, text is utf8
219 	 */
220 	char* text_range(int start, int end) const;
221 
222 	/**
223 	 Returns the character at the specified position pos in the buffer.
224 	 Positions start at 0
225 	 \param pos byte offset into buffer, pos must be at acharacter boundary
226 	 \return Unicode UCS-4 encoded character
227 	 */
228 	unsigned int char_at(int pos) const;
229 
230 	/**
231 	 Returns the raw byte at the specified position pos in the buffer.
232 	 Positions start at 0
233 	 \param pos byte offset into buffer
234 	 \return unencoded raw byte
235 	 */
236 	char byte_at(int pos) const;
237 
238 	/**
239 	 Convert a byte offset in buffer into a memory address.
240 	 \param pos byte offset into buffer
241 	 \return byte offset converted to a memory address
242 	 */
address(int pos)243 	const char *address(int pos) const
244 	{ return (pos < mGapStart) ? mBuf+pos : mBuf+pos+mGapEnd-mGapStart; }
245 
246 	/**
247 	 Convert a byte offset in buffer into a memory address.
248 	 \param pos byte offset into buffer
249 	 \return byte offset converted to a memory address
250 	 */
address(int pos)251 	char *address(int pos)
252 	{ return (pos < mGapStart) ? mBuf+pos : mBuf+pos+mGapEnd-mGapStart; }
253 
254 	/**
255 	 Inserts null-terminated string \p text at position \p pos.
256 	 \param pos insertion position as byte offset (must be utf-8 character aligned)
257 	 \param text utf-8 encoded and nul terminated text
258 	 */
259 	void insert(int pos, const char* text);
260 
261 	/**
262 	 Appends the text string to the end of the buffer.
263 	 \param t utf-8 encoded and nul terminated text
264 	 */
append(const char * t)265 	void append(const char* t) { insert(length(), t); }
266 
267 	/**
268 	 Deletes a range of characters in the buffer.
269 	 \param start byte offset to first character to be removed
270 	 \param end byte offset to charcatre after last character to be removed
271 	 */
272 	void remove(int start, int end);
273 
274 	/**
275 	 Deletes the characters between \p start and \p end, and inserts the null-terminated string \p text in their place in the buffer.
276 	 \param start byte offset to first character to be removed and new insert position
277 	 \param end byte offset to charcatre after last character to be removed
278 	 \param text utf-8 encoded and nul terminated text
279 	 */
280 	void replace(int start, int end, const char *text);
281 
282 	/**
283 	 Copies text from one buffer to this one.
284 	 \param fromBuf source text buffer may be the same as this
285 	 \param fromStart byte offset into buffer
286 	 \param fromEnd byte offset into buffer
287 	 \param toPos destination byte offset into buffer
288 	 */
289 	void copy(Fl_Text_Buffer_mod* fromBuf, int fromStart, int fromEnd, int toPos);
290 
291 	/**
292 	 Undo text modification according to the undo variables or insert text
293 	 from the undo buffer
294 	 */
295 	int undo(int *cp=0);
296 
297 	/**
298 	 Lets the undo system know if we can undo changes
299 	 */
300 	void canUndo(char flag=1);
301 
302 	/**
303 	 Inserts a file at the specified position. Returns 0 on success,
304 	 non-zero on error (strerror() contains reason).  1 indicates open
305 	 for read failed (no data loaded). 2 indicates error occurred
306 	 while reading data (data was partially loaded).
307 	 File can be UTF-8 or CP1252-encoded.
308 	 If the input file is not UTF-8-encoded, the Fl_Text_Buffer_mod widget will contain
309 	 UTF-8-transcoded data. By default, the message Fl_Text_Buffer_mod::file_encoding_warning_message
310 	 will warn the user about this.
311 	 \see input_file_was_transcoded and transcoding_warning_action.
312 	 */
313 	int insertfile(const char *file, int pos, int buflen = 128*1024);
314 
315 	/**
316 	 Appends the named file to the end of the buffer. See also insertfile().
317 	 */
318 	int appendfile(const char *file, int buflen = 128*1024)
319 	{ return insertfile(file, length(), buflen); }
320 
321 	/**
322 	 Loads a text file into the buffer. See also insertfile().
323 	 */
324 	int loadfile(const char *file, int buflen = 128*1024)
325 	{ select(0, length()); remove_selection(); return appendfile(file, buflen); }
326 
327 	/**
328 	 Writes the specified portions of the file to a file. Returns 0 on success, non-zero
329 	 on error (strerror() contains reason).  1 indicates open for write failed
330 	 (no data saved). 2 indicates error occurred while writing data
331 	 (data was partially saved).
332 	 */
333 	int outputfile(const char *file, int start, int end, int buflen = 128*1024);
334 
335 	/**
336 	 Saves a text file from the current buffer
337 	 */
338 	int savefile(const char *file, int buflen = 128*1024)
339 	{ return outputfile(file, 0, length(), buflen); }
340 
341 	/**
342 	 Gets the tab width.
343 	 */
tab_distance()344 	int tab_distance() const { return mTabDist; }
345 
346 	/**
347 	 Set the hardware tab distance (width) used by all displays for this buffer,
348 	 and used in computing offsets for rectangular selection operations.
349 	 */
350 	void tab_distance(int tabDist);
351 
352 	/**
353 	 Selects a range of characters in the buffer.
354 	 */
355 	void select(int start, int end);
356 
357 	/**
358 	 Returns a non 0 value if text has been selected, 0 otherwise
359 	 */
selected()360 	int selected() const { return mPrimary.selected(); }
361 
362 	/**
363 	 Cancels any previous selection on the primary text selection object
364 	 */
365 	void unselect();
366 
367 	/**
368 	 Gets the selection position
369 	 */
370 	int selection_position(int* start, int* end);
371 
372 	/**
373 	 Returns the currently selected text. When you are done with
374 	 the text, free it using the free() function.
375 	 */
376 	char* selection_text();
377 
378 	/**
379 	 Removes the text in the primary selection.
380 	 */
381 	void remove_selection();
382 
383 	/**
384 	 Replaces the text in the primary selection.
385 	 */
386 	void replace_selection(const char* text);
387 
388 	/**
389 	 Selects a range of characters in the secondary selection.
390 	 */
391 	void secondary_select(int start, int end);
392 
393 	/**
394 	 Returns a non 0 value if text has been selected in the secondary
395 	 text selection, 0 otherwise
396 	 */
secondary_selected()397 	int secondary_selected() { return mSecondary.selected(); }
398 
399 	/**
400 	 Clears any selection in the secondary text selection object.
401 	 */
402 	void secondary_unselect();
403 
404 	/**
405 	 Returns the current selection in the secondary text selection object.
406 	 */
407 	int secondary_selection_position(int* start, int* end);
408 
409 	/**
410 	 Returns the text in the secondary selection. When you are
411 	 done with the text, free it using the free() function.
412 	 */
413 	char* secondary_selection_text();
414 
415 	/**
416 	 Removes the text from the buffer corresponding to the secondary text selection object.
417 	 */
418 	void remove_secondary_selection();
419 
420 	/**
421 	 Replaces the text from the buffer corresponding to the secondary
422 	 text selection object with the new string \p text.
423 	 */
424 	void replace_secondary_selection(const char* text);
425 
426 	/**
427 	 Highlights the specified text within the buffer.
428 	 */
429 	void highlight(int start, int end);
430 
431 	/**
432 	 Returns the highlighted text. When you are done with the
433 	 text, free it using the free() function.
434 	 */
highlight()435 	int highlight() { return mHighlight.selected(); }
436 
437 	/**
438 	 Unhighlights text in the buffer.
439 	 */
440 	void unhighlight();
441 
442 	/**
443 	 Highlights the specified text between \p start and \p end within the buffer.
444 	 */
445 	int highlight_position(int* start, int* end);
446 
447 	/**
448 	 Returns the highlighted text. When you are done with the
449 	 text, free it using the free() function.
450 	 */
451 	char* highlight_text();
452 
453 	/**
454 	 Adds a callback function that is called whenever the text buffer is
455 	 modified. The callback function is declared as follows:
456 
457 	 \code
458 	 typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted,
459 	 int nRestyled, const char* deletedText,
460 	 void* cbArg);
461 	 \endcode
462 	 */
463 	void add_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg);
464 
465 	/**
466 	 Removes a modify callback.
467 	 */
468 	void remove_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg);
469 
470 	/**
471 	 Calls all modify callbacks that have been registered using
472 	 the add_modify_callback()
473 	 method.
474 	 */
call_modify_callbacks()475 	void call_modify_callbacks() { call_modify_callbacks(0, 0, 0, 0, 0); }
476 
477 	/**
478 	 Adds a callback routine to be called before text is deleted from the buffer.
479 	 */
480 	void add_predelete_callback(Fl_Text_Predelete_Cb bufPredelCB, void* cbArg);
481 
482 	/**
483 	 Removes a callback routine \p bufPreDeleteCB associated with argument \p cbArg
484 	 to be called before text is deleted from the buffer.
485 	 */
486 	void remove_predelete_callback(Fl_Text_Predelete_Cb predelCB, void* cbArg);
487 
488 	/**
489 	 Calls the stored pre-delete callback procedure(s) for this buffer to update
490 	 the changed area(s) on the screen and any other listeners.
491 	 */
call_predelete_callbacks()492 	void call_predelete_callbacks() { call_predelete_callbacks(0, 0); }
493 
494 	/**
495 	 Returns the text from the entire line containing the specified
496 	 character position. When you are done with the text, free it
497 	 using the free() function.
498 	 \param pos byte index into buffer
499 	 \return copy of utf8 text, must be free'd
500 	 */
501 	char* line_text(int pos) const;
502 
503 	/**
504 	 Returns the position of the start of the line containing position \p pos.
505 	 \param pos byte index into buffer
506 	 \return byte offset to line start
507 	 */
508 	int line_start(int pos) const;
509 
510 	/**
511 	 Finds and returns the position of the end of the line containing position \p pos
512 	 (which is either a pointer to the newline character ending the line,
513 	 or a pointer to one character beyond the end of the buffer)
514 	 \param pos byte index into buffer
515 	 \return byte offset to line end
516 	 */
517 	int line_end(int pos) const;
518 
519 	/**
520 	 Returns the position corresponding to the start of the word
521 	 \param pos byte index into buffer
522 	 \return byte offset to word start
523 	 */
524 	int word_start(int pos) const;
525 
526 	/**
527 	 Returns the position corresponding to the end of the word.
528 	 \param pos byte index into buffer
529 	 \return byte offset to word end
530 	 */
531 	int word_end(int pos) const;
532 
533 	/**
534 	 Count the number of displayed characters between buffer position
535 	 \p lineStartPos and \p targetPos. (displayed characters are the characters
536 	 shown on the screen to represent characters in the buffer, where tabs and
537 	 control characters are expanded)
538 	 */
539 	int count_displayed_characters(int lineStartPos, int targetPos) const;
540 
541 	/**
542 	 Count forward from buffer position \p startPos in displayed characters
543 	 (displayed characters are the characters shown on the screen to represent
544 	 characters in the buffer, where tabs and control characters are expanded)
545 	 \param lineStartPos byte offset into buffer
546 	 \param nChars number of bytes that are sent to the display
547 	 \return byte offset in input after all output bytes are sent
548 	 */
549 	int skip_displayed_characters(int lineStartPos, int nChars);
550 
551 	/**
552 	 Counts the number of newlines between \p startPos and \p endPos in buffer.
553 	 The character at position \p endPos is not counted.
554 	 */
555 	int count_lines(int startPos, int endPos) const;
556 
557 	/**
558 	 Finds the first character of the line \p nLines forward from \p startPos
559 	 in the buffer and returns its position
560 	 */
561 	int skip_lines(int startPos, int nLines);
562 
563 	/**
564 	 Finds and returns the position of the first character of the line \p nLines backwards
565 	 from \p startPos (not counting the character pointed to by \p startpos if
566 	 that is a newline) in the buffer.  \p nLines == 0 means find the beginning of the line
567 	 */
568 	int rewind_lines(int startPos, int nLines);
569 
570 	/**
571 	 Finds the next occurrence of the specified character.
572 	 Search forwards in buffer for character \p searchChar, starting
573 	 with the character \p startPos, and returning the result in \p foundPos
574 	 returns 1 if found, 0 if not.  (The difference between this and
575 	 BufSearchForward is that it's optimized for single characters.  The
576 	 overall performance of the text widget is dependent on its ability to
577 	 count lines quickly, hence searching for a single character: newline)
578 	 \param startPos byte offset to start position
579 	 \param searchChar UCS-4 character that we want to find
580 	 \param foundPos byte offset where the character was found
581 	 \return 1 if found, 0 if not
582 	 */
583 	int findchar_forward(int startPos, unsigned searchChar, int* foundPos) const;
584 
585 	/**
586 	 Search backwards in buffer \p buf for character \p searchChar, starting
587 	 with the character BEFORE \p startPos, returning the result in \p foundPos
588 	 returns 1 if found, 0 if not.  (The difference between this and
589 	 BufSearchBackward is that it's optimized for single characters.  The
590 	 overall performance of the text widget is dependent on its ability to
591 	 count lines quickly, hence searching for a single character: newline)
592 	 \param startPos byte offset to start position
593 	 \param searchChar UCS-4 character that we want to find
594 	 \param foundPos byte offset where the character was found
595 	 \return 1 if found, 0 if not
596 	 */
597 	int findchar_backward(int startPos, unsigned int searchChar, int* foundPos) const;
598 
599 	/**
600 	 Search forwards in buffer for string \p searchString, starting with the
601 	 character \p startPos, and returning the result in \p foundPos
602 	 returns 1 if found, 0 if not.
603 	 \param startPos byte offset to start position
604 	 \param searchString utf8 string that we want to find
605 	 \param foundPos byte offset where the string was found
606 	 \param matchCase if set, match character case
607 	 \return 1 if found, 0 if not
608 	 */
609 	int search_forward(int startPos, const char* searchString, int* foundPos,
610 					   int matchCase = 0) const;
611 
612 	/**
613 	 Search backwards in buffer for string <i>searchCharssearchString</i>, starting with the
614 	 character BEFORE \p startPos, returning the result in \p foundPos
615 	 returns 1 if found, 0 if not.
616 	 \param startPos byte offset to start position
617 	 \param searchString utf8 string that we want to find
618 	 \param foundPos byte offset where the string was found
619 	 \param matchCase if set, match character case
620 	 \return 1 if found, 0 if not
621 	 */
622 	int search_backward(int startPos, const char* searchString, int* foundPos,
623 						int matchCase = 0) const;
624 
625 	int findchars_forward(int startPos, const char* searchChars, int* foundPos);
626 	int findchars_backward(int startPos, const char* searchChars, int* foundPos);
627 
628 	/**
629 	 Returns the primary selection.
630 	 */
primary_selection()631 	const Fl_Text_Selection_mod* primary_selection() const { return &mPrimary; }
632 
633 	/**
634 	 Returns the primary selection.
635 	 */
primary_selection()636 	Fl_Text_Selection_mod* primary_selection() { return &mPrimary; }
637 
638 	/**
639 	 Returns the secondary selection.
640 	 */
secondary_selection()641 	const Fl_Text_Selection_mod* secondary_selection() const { return &mSecondary; }
642 
643 	/**
644 	 Returns the current highlight selection.
645 	 */
highlight_selection()646 	const Fl_Text_Selection_mod* highlight_selection() const { return &mHighlight; }
647 
648 	/**
649 	 Returns the index of the previous character.
650 	 \param ix index to the current char
651 	 */
652 	int prev_char(int ix) const;
653 	int prev_char_clipped(int ix) const;
654 
655 	/**
656 	 Returns the index of the next character.
657 	 \param ix index to the current char
658 	 */
659 	int next_char(int ix) const;
660 	int next_char_clipped(int ix) const;
661 
662 	/**
663 	 Align an index into the buffer to the current or previous utf8 boundary.
664 	 */
665 	int utf8_align(int) const;
666 
667 	/**
668 	 \brief true iff the loaded file has been transcoded to UTF-8
669 	 */
670 	int input_file_was_transcoded;
671 
672 	/** This message may be displayed using the fl_alert() function when a file
673 	 which was not UTF-8 encoded is input.
674 	 */
675 	static const char* file_encoding_warning_message;
676 
677 	/**
678 	 \brief Pointer to a function called after reading a non UTF-8 encoded file.
679 
680 	 This function is called after reading a file if the file content
681 	 was transcoded to UTF-8. Its default implementation calls fl_alert()
682 	 with the text of \ref file_encoding_warning_message. No warning message is
683 	 displayed if this pointer is set to NULL. Use \ref input_file_was_transcoded
684 	 to be informed if file input required transcoding to UTF-8.
685 	 */
686 	void (*transcoding_warning_action)(Fl_Text_Buffer_mod*);
687 
688 protected:
689 
690 	/**
691 	 Calls the stored modify callback procedure(s) for this buffer to update the
692 	 changed area(s) on the screen and any other listeners.
693 	 */
694 	void call_modify_callbacks(int pos, int nDeleted, int nInserted,
695 							   int nRestyled, const char* deletedText) const;
696 
697 	/**
698 	 Calls the stored pre-delete callback procedure(s) for this buffer to update
699 	 the changed area(s) on the screen and any other listeners.
700 	 */
701 	void call_predelete_callbacks(int pos, int nDeleted) const;
702 
703 	/**
704 	 Internal (non-redisplaying) version of BufInsert. Returns the length of
705 	 text inserted (this is just strlen(\p text), however this calculation can be
706 	 expensive and the length will be required by any caller who will continue
707 	 on to call redisplay). \p pos must be contiguous with the existing text in
708 	 the buffer (i.e. not past the end).
709 	 \return the number of bytes inserted
710 	 */
711 	int insert_(int pos, const char* text);
712 
713 	/**
714 	 Internal (non-redisplaying) version of BufRemove.  Removes the contents
715 	 of the buffer between start and end (and moves the gap to the site of
716 	 the delete).
717 	 */
718 	void remove_(int start, int end);
719 
720 	/**
721 	 Calls the stored redisplay procedure(s) for this buffer to update the
722 	 screen for a change in a selection.
723 	 */
724 	void redisplay_selection(Fl_Text_Selection_mod* oldSelection,
725 							 Fl_Text_Selection_mod* newSelection) const;
726 
727 	/**
728 	 Move the gap to start at a new position.
729 	 */
730 	void move_gap(int pos);
731 
732 	/**
733 	 Reallocates the text storage in the buffer to have a gap starting at \p newGapStart
734 	 and a gap size of \p newGapLen, preserving the buffer's current contents.
735 	 */
736 	void reallocate_with_gap(int newGapStart, int newGapLen);
737 
738 	char* selection_text_(Fl_Text_Selection_mod* sel) const;
739 
740 	/**
741 	 Removes the text from the buffer corresponding to \p sel.
742 	 */
743 	void remove_selection_(Fl_Text_Selection_mod* sel);
744 
745 	/**
746 	 Replaces the \p text in selection \p sel.
747 	 */
748 	void replace_selection_(Fl_Text_Selection_mod* sel, const char* text);
749 
750 	/**
751 	 Updates all of the selections in the buffer for changes in the buffer's text
752 	 */
753 	void update_selections(int pos, int nDeleted, int nInserted);
754 
755 	Fl_Text_Selection_mod mPrimary;     /**< highlighted areas */
756 	Fl_Text_Selection_mod mSecondary;   /**< highlighted areas */
757 	Fl_Text_Selection_mod mHighlight;   /**< highlighted areas */
758 	int mLength;                    /**< length of the text in the buffer (the length
759 									 of the buffer itself must be calculated:
760 									 gapEnd - gapStart + length) */
761 	char* mBuf;                     /**< allocated memory where the text is stored */
762 	int mGapStart;                  /**< points to the first character of the gap */
763 	int mGapEnd;                    /**< points to the first char after the gap */
764 	// The hardware tab distance used by all displays for this buffer,
765 	// and used in computing offsets for rectangular selection operations.
766 	int mTabDist;                   /**< equiv. number of characters in a tab */
767 	int mNModifyProcs;              /**< number of modify-redisplay procs attached */
768 	Fl_Text_Modify_Cb *mModifyProcs;/**< procedures to call when buffer is
769 									 modified to redisplay contents */
770 	void** mCbArgs;                 /**< caller arguments for modifyProcs above */
771 	int mNPredeleteProcs;           /**< number of pre-delete procs attached */
772 	Fl_Text_Predelete_Cb *mPredeleteProcs; /**< procedure to call before text is deleted
773 											from the buffer; at most one is supported. */
774 	void **mPredeleteCbArgs;        /**< caller argument for pre-delete proc above */
775 	int mCursorPosHint;             /**< hint for reasonable cursor position after
776 									 a buffer modification operation */
777 	char mCanUndo;                  /**< if this buffer is used for attributes, it must
778 									 not do any undo calls */
779 	int mPreferredGapSize;          /**< the default allocation for the text gap is 1024
780 									 bytes and should only be increased if frequent
781 									 and large changes in buffer size are expected */
782 };
783 
784 #endif
785 
786 //
787 // End of "$Id: Fl_Text_Buffer_mod.H 8148 2010-12-31 22:38:03Z matt $".
788 //
789