Fixed Fl_Input_::maximum_size() documentation and Fl_Input::replace()

to honor maximum_size() as number of allowed characters (STR #2747).
This was a hangover from FLTK 1.1, where the number of bytes was equal
to the number of characters.


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@9196 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Albrecht Schlosser 2011-12-06 16:55:51 +00:00
parent 3edb5e5aba
commit d250e21542
3 changed files with 70 additions and 24 deletions

View File

@ -1,6 +1,8 @@
CHANGES IN FLTK 1.3.1
- Fixed Fl_Input_::maximum_size() documentation and replace() method
to honor maximum_size() as number of allowed characters (STR #2747).
- Fixed a potential crash if Fl_Double_Window::flush() was called
before show()
- Fixed regression (in FLTK 1.3.0) that could clear a radio

View File

@ -3,7 +3,7 @@
//
// Input base class header file for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2010 by Bill Spitzak and others.
// Copyright 1998-2011 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@ -69,9 +69,10 @@
\endcode
All variables that represent an index into a text buffer are byte-oriented,
not character oriented. Since UTF-8 characters can be up to six bytes long,
simply incrementing such an index will not reliably advance to the next character
in the text buffer.
not character oriented, counting from 0 (at or before the first character)
to size() (at the end of the buffer, after the last byte). Since UTF-8
characters can be up to six bytes long, simply incrementing such an index
will not reliably advance to the next character in the text buffer.
Indices and pointers into the text buffer should always point at a 7 bit ASCII
character or the beginning of a UTF-8 character sequence. Behavior for false
@ -123,7 +124,7 @@ class FL_EXPORT Fl_Input_ : public Fl_Widget {
of the buffer. */
int mu_p;
/** \internal Maximum size of buffer. \todo Is this really needed? */
/** \internal Maximum number of characters. */
int maximum_size_;
/** \internal Shortcut key that will fetch focus for this widget. */
@ -260,16 +261,21 @@ public:
\see Fl_Widget::size(int, int) */
void size(int W, int H) { Fl_Widget::size(W, H); }
/** Gets the maximum length of the input field.
\todo It is not clear if this function is actually required */
/** Gets the maximum length of the input field in characters.
\see maximum_size(int). */
int maximum_size() const {return maximum_size_;}
/** Sets the maximum length of the input field.
\todo It is not clear if this function is actually required */
/** Sets the maximum length of the input field in characters.
This limits the number of <b>characters</b> that can be inserted
in the widget.
\since FLTK 1.3 this is different than the buffer size, since one
character can be more than one byte in UTF-8 encoding. In FLTK 1.1
this was the same (one byte = one character).
*/
void maximum_size(int m) {maximum_size_ = m;}
/** Gets the position of the text cursor.
\return the cursor position as an index
\return the cursor position as an index in the range 0..size()
\see position(int, int)
*/
int position() const {return position_;}
@ -281,7 +287,7 @@ public:
/* Sets the index for the cursor and mark. */
int position(int p, int m);
/** Set the cursor position and mark.
/** Sets the cursor position and mark.
position(n) is the same as <tt>position(n, n)</tt>.
\param p new index for cursor and mark
\return 0 if no positions changed
@ -296,8 +302,8 @@ public:
\see position(), position(int, int) */
int mark(int m) {return position(position(), m);}
/* Deletes text from b to e and inserts the new string text. */
int replace(int, int, const char*, int=0);
/* Deletes text from \p b to \p e and inserts the new string \p text. */
int replace(int b, int e, const char *text, int ilen=0);
/**
Deletes the current selection.

View File

@ -3,7 +3,7 @@
//
// Common input widget routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2010 by Bill Spitzak and others.
// Copyright 1998-2011 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@ -719,9 +719,9 @@ static void undobuffersize(int n) {
Deletes text from \p b to \p e and inserts the new string \p text.
All changes to the text buffer go through this function.
It deletes the region between \p a and \p b (either one may be less or
It deletes the region between \p b and \p e (either one may be less or
equal to the other), and then inserts the string \p text
at that point and moves the mark() and
at that point and moves the mark() and
position() to the end of the insertion. Does the callback if
<tt>when() & FL_WHEN_CHANGED</tt> and there is a change.
@ -731,11 +731,23 @@ static void undobuffersize(int n) {
\p ilen can be zero or <tt>strlen(text)</tt>, which
saves a tiny bit of time if you happen to already know the
length of the insertion, or can be used to insert a portion of a
string.
\p b and \p e are clamped to the
<tt>0..size()</tt> range, so it is safe to pass any values.
string. If \p ilen is zero, <tt>strlen(text)</tt> is used instead.
\p b and \p e are clamped to the <tt>0..size()</tt> range, so it is
safe to pass any values. \p b, \p e, and \p ilen are used as numbers
of bytes (not characters), where \p b and \p e count from 0 to
size() (end of buffer).
If \p b and/or \p e don't point to a valid UTF-8 character boundary,
they are adjusted to the previous (\p b) or the next (\p e) valid
UTF-8 character boundary, resp..
If the current number of characters in the buffer minus deleted
characters plus inserted characters in \p text would overflow the
number of allowed characters (maximum_size()), then only the first
characters of the string are inserted, so that maximum_size()
is not exceeded.
cut() and insert() are just inline functions that call replace().
\param [in] b beginning index of text to be deleted
@ -743,6 +755,10 @@ static void undobuffersize(int n) {
\param [in] text string that will be inserted
\param [in] ilen length of \p text or 0 for \c nul terminated strings
\return 0 if nothing changed
\note If \p text does not point to a valid UTF-8 character or includes
invalid UTF-8 sequences, the text is inserted nevertheless (counting
invalid UTF-8 bytes as one character each).
*/
int Fl_Input_::replace(int b, int e, const char* text, int ilen) {
int ul, om, op;
@ -762,10 +778,32 @@ int Fl_Input_::replace(int b, int e, const char* text, int ilen) {
}
if (text && !ilen) ilen = strlen(text);
if (e<=b && !ilen) return 0; // don't clobber undo for a null operation
if (size_+ilen-(e-b) > maximum_size_) {
ilen = maximum_size_-size_+(e-b);
if (ilen < 0) ilen = 0;
// we must count UTF-8 *characters* to determine whether we can insert
// the full text or only a part of it (and how much this would be)
int nchars = 0; // characters in value() - deleted + inserted
const char *p = value_;
while (p < (char *)(value_+size_)) {
if (p == (char *)(value_+b)) { // skip removed part
p = (char *)(value_+e);
if (p >= (char *)(value_+size_)) break;
}
int ulen = fl_utf8len(*p);
if (ulen < 1) ulen = 1; // invalid UTF-8 character: count as 1
nchars++;
p += ulen;
}
int nlen = 0; // length (in bytes) to be inserted
p = text;
while (p < (char *)(text+ilen) && nchars < maximum_size()) {
int ulen = fl_utf8len(*p);
if (ulen < 1) ulen = 1; // invalid UTF-8 character: count as 1
nchars++;
p += ulen;
nlen += ulen;
}
ilen = nlen;
put_in_buffer(size_+ilen);