FLTK 1.3.0
Fl_Text_Buffer.H
1 //
2 // "$Id: Fl_Text_Buffer.H 8148 2010-12-31 22:38:03Z matt $"
3 //
4 // Header file for Fl_Text_Buffer class.
5 //
6 // Copyright 2001-2010 by Bill Spitzak and others.
7 // Original code Copyright Mark Edel. Permission to distribute under
8 // the LGPL for the FLTK library granted by Mark Edel.
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Library General Public
12 // License as published by the Free Software Foundation; either
13 // version 2 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Library General Public License for more details.
19 //
20 // You should have received a copy of the GNU Library General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 // USA.
24 //
25 // Please report all bugs and problems on the following page:
26 //
27 // http://www.fltk.org/str.php
28 //
29 
30 /* \file
31  Fl_Text_Buffer, Fl_Text_Selection widget . */
32 
33 #ifndef FL_TEXT_BUFFER_H
34 #define FL_TEXT_BUFFER_H
35 
36 
37 #undef ASSERT_UTF8
38 
39 #ifdef ASSERT_UTF8
40 # include <assert.h>
41 # define IS_UTF8_ALIGNED(a) if (a && *a) assert(fl_utf8len(*(a))>0);
42 # define IS_UTF8_ALIGNED2(a, b) if (b>=0 && b<a->length()) assert(fl_utf8len(a->byte_at(b))>0);
43 #else
44 # define IS_UTF8_ALIGNED(a)
45 # define IS_UTF8_ALIGNED2(a, b)
46 #endif
47 
48 
49 /*
50  "character size" is the size of a UTF-8 character in bytes
51  "character width" is the width of a Unicode character in pixels
52  "column" was orginally defined as a character offset from the left margin.
53  It was identical to the byte offset. In UTF-8, we have neither a byte offset
54  nor truly fixed width fonts (*). Column could be a pixel value multiplied with
55  an average character width (which is a bearable approximation).
56 
57  * in Unicode, there are no fixed width fonts! Even if the ASCII characters may
58  happen to be all the same width in pixels, chinese charcaters surely are not.
59  There are plenty of exceptions, like ligatures, that make special handling of
60  "fixed" character widths a nightmare. I decided to remove all references to
61  fixed fonts and see "columns" as a multiple of the average width of a
62  character in the main font.
63  - Matthias
64  */
65 
66 
67 /* Maximum length in characters of a tab or control character expansion
68  of a single buffer character */
69 #define FL_TEXT_MAX_EXP_CHAR_LEN 20
70 
71 #include "Fl_Export.H"
72 
73 
80 class FL_EXPORT Fl_Text_Selection {
81  friend class Fl_Text_Buffer;
82 
83 public:
84 
90  void set(int start, int end);
91 
99  void update(int pos, int nDeleted, int nInserted);
100 
105  int start() const { return mStart; }
106 
111  int end() const { return mEnd; }
112 
118  bool selected() const { return mSelected; }
119 
124  void selected(bool b) { mSelected = b; }
125 
130  int includes(int pos) const;
131 
138  int position(int* start, int* end) const;
139 
140 protected:
141 
142  int mStart;
143  int mEnd;
144  bool mSelected;
145 };
146 
147 
148 typedef void (*Fl_Text_Modify_Cb)(int pos, int nInserted, int nDeleted,
149  int nRestyled, const char* deletedText,
150  void* cbArg);
151 
152 
153 typedef void (*Fl_Text_Predelete_Cb)(int pos, int nDeleted, void* cbArg);
154 
155 
168 class FL_EXPORT Fl_Text_Buffer {
169 public:
170 
179  Fl_Text_Buffer(int requestedSize = 0, int preferredGapSize = 1024);
180 
184  ~Fl_Text_Buffer();
185 
190  int length() const { return mLength; }
191 
198  char* text() const;
199 
204  void text(const char* text);
205 
216  char* text_range(int start, int end) const;
217 
224  unsigned int char_at(int pos) const;
225 
232  char byte_at(int pos) const;
233 
239  const char *address(int pos) const
240  { return (pos < mGapStart) ? mBuf+pos : mBuf+pos+mGapEnd-mGapStart; }
241 
247  char *address(int pos)
248  { return (pos < mGapStart) ? mBuf+pos : mBuf+pos+mGapEnd-mGapStart; }
249 
255  void insert(int pos, const char* text);
256 
261  void append(const char* t) { insert(length(), t); }
262 
268  void remove(int start, int end);
269 
276  void replace(int start, int end, const char *text);
277 
285  void copy(Fl_Text_Buffer* fromBuf, int fromStart, int fromEnd, int toPos);
286 
291  int undo(int *cp=0);
292 
296  void canUndo(char flag=1);
297 
309  int insertfile(const char *file, int pos, int buflen = 128*1024);
310 
314  int appendfile(const char *file, int buflen = 128*1024)
315  { return insertfile(file, length(), buflen); }
316 
320  int loadfile(const char *file, int buflen = 128*1024)
321  { select(0, length()); remove_selection(); return appendfile(file, buflen); }
322 
329  int outputfile(const char *file, int start, int end, int buflen = 128*1024);
330 
334  int savefile(const char *file, int buflen = 128*1024)
335  { return outputfile(file, 0, length(), buflen); }
336 
340  int tab_distance() const { return mTabDist; }
341 
346  void tab_distance(int tabDist);
347 
351  void select(int start, int end);
352 
356  int selected() const { return mPrimary.selected(); }
357 
361  void unselect();
362 
366  int selection_position(int* start, int* end);
367 
372  char* selection_text();
373 
377  void remove_selection();
378 
382  void replace_selection(const char* text);
383 
387  void secondary_select(int start, int end);
388 
393  int secondary_selected() { return mSecondary.selected(); }
394 
398  void secondary_unselect();
399 
403  int secondary_selection_position(int* start, int* end);
404 
409  char* secondary_selection_text();
410 
414  void remove_secondary_selection();
415 
420  void replace_secondary_selection(const char* text);
421 
425  void highlight(int start, int end);
426 
431  int highlight() { return mHighlight.selected(); }
432 
436  void unhighlight();
437 
441  int highlight_position(int* start, int* end);
442 
447  char* highlight_text();
448 
459  void add_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg);
460 
464  void remove_modify_callback(Fl_Text_Modify_Cb bufModifiedCB, void* cbArg);
465 
471  void call_modify_callbacks() { call_modify_callbacks(0, 0, 0, 0, 0); }
472 
476  void add_predelete_callback(Fl_Text_Predelete_Cb bufPredelCB, void* cbArg);
477 
482  void remove_predelete_callback(Fl_Text_Predelete_Cb predelCB, void* cbArg);
483 
489 
497  char* line_text(int pos) const;
498 
504  int line_start(int pos) const;
505 
513  int line_end(int pos) const;
514 
520  int word_start(int pos) const;
521 
527  int word_end(int pos) const;
528 
535  int count_displayed_characters(int lineStartPos, int targetPos) const;
536 
545  int skip_displayed_characters(int lineStartPos, int nChars);
546 
551  int count_lines(int startPos, int endPos) const;
552 
557  int skip_lines(int startPos, int nLines);
558 
564  int rewind_lines(int startPos, int nLines);
565 
579  int findchar_forward(int startPos, unsigned searchChar, int* foundPos) const;
580 
593  int findchar_backward(int startPos, unsigned int searchChar, int* foundPos) const;
594 
605  int search_forward(int startPos, const char* searchString, int* foundPos,
606  int matchCase = 0) const;
607 
618  int search_backward(int startPos, const char* searchString, int* foundPos,
619  int matchCase = 0) const;
620 
624  const Fl_Text_Selection* primary_selection() const { return &mPrimary; }
625 
629  Fl_Text_Selection* primary_selection() { return &mPrimary; }
630 
634  const Fl_Text_Selection* secondary_selection() const { return &mSecondary; }
635 
639  const Fl_Text_Selection* highlight_selection() const { return &mHighlight; }
640 
645  int prev_char(int ix) const;
646  int prev_char_clipped(int ix) const;
647 
652  int next_char(int ix) const;
653  int next_char_clipped(int ix) const;
654 
658  int utf8_align(int) const;
659 
664 
668  static const char* file_encoding_warning_message;
669 
679  void (*transcoding_warning_action)(Fl_Text_Buffer*);
680 
681 protected:
682 
687  void call_modify_callbacks(int pos, int nDeleted, int nInserted,
688  int nRestyled, const char* deletedText) const;
689 
694  void call_predelete_callbacks(int pos, int nDeleted) const;
695 
704  int insert_(int pos, const char* text);
705 
711  void remove_(int start, int end);
712 
717  void redisplay_selection(Fl_Text_Selection* oldSelection,
718  Fl_Text_Selection* newSelection) const;
719 
723  void move_gap(int pos);
724 
729  void reallocate_with_gap(int newGapStart, int newGapLen);
730 
731  char* selection_text_(Fl_Text_Selection* sel) const;
732 
736  void remove_selection_(Fl_Text_Selection* sel);
737 
741  void replace_selection_(Fl_Text_Selection* sel, const char* text);
742 
746  void update_selections(int pos, int nDeleted, int nInserted);
747 
751  int mLength;
754  char* mBuf;
755  int mGapStart;
756  int mGapEnd;
757  // The hardware tab distance used by all displays for this buffer,
758  // and used in computing offsets for rectangular selection operations.
759  int mTabDist;
761  Fl_Text_Modify_Cb *mModifyProcs;
763  void** mCbArgs;
765  Fl_Text_Predelete_Cb *mPredeleteProcs;
770  char mCanUndo;
775 };
776 
777 #endif
778 
779 //
780 // End of "$Id: Fl_Text_Buffer.H 8148 2010-12-31 22:38:03Z matt $".
781 //