1 /***************************************************************************
2 * Copyright (C) 2008-2010 by Andrzej Rybczak *
3 * electricityispower@gmail.com *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
32 /// Buffer template class that can store text along with its
33 /// format attributes. The content can be easily printed to
34 /// window or taken as raw string at any time.
36 template <typename C
> class basic_buffer
38 /// Struct used for storing information about
39 /// one color/format flag along with its position
46 bool operator<(const FormatPos
&f
)
48 return Position
< f
.Position
;
51 bool operator==(const FormatPos
&f
)
53 return Position
== f
.Position
&& Value
== f
.Value
;
57 /// Internal buffer for storing raw text
59 std::basic_ostringstream
<C
> itsString
;
61 /// List used for storing formatting informations
63 std::list
<FormatPos
> itsFormat
;
65 /// Pointer to temporary string
68 std::basic_string
<C
> *itsTempString
;
71 /// Constructs an empty buffer
73 basic_buffer() : itsTempString(0) { }
75 /// Constructs a buffer from the existed one
76 /// @param b copied buffer
78 basic_buffer(const basic_buffer
&b
);
80 /// @return raw content of the buffer without formatting informations
82 std::basic_string
<C
> Str() const;
84 /// Searches for given string in buffer and sets format/color at the
85 /// beginning and end of it using val_b and val_e flags accordingly
86 /// @param val_b flag set at the beginning of found occurence of string
87 /// @param s string that function seaches for
88 /// @param val_e flag set at the end of found occurence of string
89 /// @param case_sensitive indicates whether algorithm should care about case sensitivity
90 /// @param for_each indicates whether function searches through whole buffer and sets
91 /// the format for all occurences of given string or stops after the first one
92 /// @return true if at least one occurence of the string was found, false otherwise
94 bool SetFormatting(short val_b
, std::basic_string
<C
> s
, short val_e
,
95 bool case_sensitive
, bool for_each
= 1);
97 /// Searches for given string in buffer and removes given
98 /// format/color from the beginning and end of its occurence
99 /// @param val_b flag to be removed from the beginning of the string
100 /// @param s string that function seaches for
101 /// @param val_e flag to be removed from the end of the string
102 /// @param case_sensitive indicates whether algorithm should care about case sensitivity
103 /// @param for_each indicates whether function searches through whole buffer and removes
104 /// given format from all occurences of given string or stops after the first one
106 void RemoveFormatting(short val_b
, std::basic_string
<C
> pattern
, short val_e
,
107 bool case_sensitive
, bool for_each
= 1);
109 /// Removes all formating applied to string in buffer.
111 void RemoveFormatting();
113 /// Sets the pointer to string, that will be passed in operator<<() to window
114 /// object instead of the internal buffer. This is useful if you took the content
115 /// of the buffer, modified it somehow and want to print the modified version instead
116 /// of the original one, but with the original formatting informations. Note that after
117 /// you're done with the printing etc., this pointer has to be set to null.
118 /// @param tmp address of the temporary string
120 void SetTemp(std::basic_string
<C
> *tmp
);
122 /// Prints to window object given part of the string, loading all needed formatting info
123 /// and cleaning up after. The main goal of this function is to provide interface for
124 /// colorful scrollers.
125 /// @param w window object that we want to print to
126 /// @param start_pos reference to start position of the string. note that this variable is
127 /// incremented by one after each call or set to 0 if end of string is reached
128 /// @param width width of the string to be printed
129 /// @param separator additional text to be placed between the end and the beginning of
132 void Write(Window
&w
, size_t &start_pos
, size_t width
,
133 const std::basic_string
<C
> &separator
) const;
135 /// Clears the content of the buffer and its formatting informations
139 /// @param t any object that has defined ostream &operator<<()
140 /// @return reference to itself
142 template <typename T
> basic_buffer
<C
> &operator<<(const T
&t
)
149 /// @return reference to itself
151 basic_buffer
<C
> &operator<<(Color color
);
153 /// Handles format flags
154 /// @return reference to itself
156 basic_buffer
<C
> &operator<<(Format f
);
158 /// Handles copying one buffer to another using operator<<()
159 /// @param buf buffer to be copied
160 /// @return reference to itself
162 basic_buffer
<C
> &operator<<(const basic_buffer
<C
> &buf
);
164 /// Friend operator, that handles printing
165 /// the content of buffer to window object
166 friend Window
&operator<< <>(Window
&, const basic_buffer
<C
> &);
169 /// Loads an attribute to given window object
170 /// @param w window object we want to load attribute to
171 /// @param value value of attribute to be loaded
173 void LoadAttribute(Window
&w
, short value
) const;
176 /// Standard buffer that uses narrow characters
178 typedef basic_buffer
<char> Buffer
;
180 /// Standard buffer that uses wide characters
182 typedef basic_buffer
<wchar_t> WBuffer
;
185 template <typename C
> NCurses::basic_buffer
<C
>::basic_buffer(const basic_buffer
&b
) : itsFormat(b
.itsFormat
),
186 itsTempString(b
.itsTempString
)
188 itsString
<< b
.itsString
.str();
191 template <typename C
> std::basic_string
<C
> NCurses::basic_buffer
<C
>::Str() const
193 return itsString
.str();
196 template <typename C
> bool NCurses::basic_buffer
<C
>::SetFormatting( short val_b
,
197 std::basic_string
<C
> s
,
206 std::basic_string
<C
> base
= itsString
.str();
213 for (size_t i
= base
.find(s
); i
!= std::basic_string
<C
>::npos
; i
= base
.find(s
, i
))
218 itsFormat
.push_back(fp
);
222 itsFormat
.push_back(fp
);
230 template <typename C
> void NCurses::basic_buffer
<C
>::RemoveFormatting( short val_b
,
231 std::basic_string
<C
> pattern
,
239 std::basic_string
<C
> base
= itsString
.str();
246 for (size_t i
= base
.find(pattern
); i
!= std::basic_string
<C
>::npos
; i
= base
.find(pattern
, i
))
250 itsFormat
.remove(fp
);
251 i
+= pattern
.length();
254 itsFormat
.remove(fp
);
260 template <typename C
> void NCurses::basic_buffer
<C
>::RemoveFormatting()
265 template <typename C
> void NCurses::basic_buffer
<C
>::SetTemp(std::basic_string
<C
> *tmp
)
270 template <typename C
> void NCurses::basic_buffer
<C
>::Write( Window
&w
,
273 const std::basic_string
<C
> &separator
276 std::basic_string
<C
> s
= itsString
.str();
277 size_t len
= Window::Length(s
);
284 typename
std::list
<typename
NCurses::basic_buffer
<C
>::FormatPos
>::const_iterator lb
= itsFormat
.begin();
285 if (itsFormat
.back().Position
> start_pos
) // if there is no attributes from current position, don't load them
287 // load all attributes that are before start position
288 for (; lb
->Position
< start_pos
; ++lb
)
289 LoadAttribute(w
, lb
->Value
);
292 for (size_t i
= start_pos
; i
< s
.length() && len
< width
; ++i
)
294 while (i
== lb
->Position
&& lb
!= itsFormat
.end())
296 LoadAttribute(w
, lb
->Value
);
299 if ((len
+= wcwidth(s
[i
])) > width
)
303 if (++start_pos
>= s
.length())
307 lb
= itsFormat
.begin();
308 for (size_t i
= 0; len
< width
; ++i
)
310 while (i
== lb
->Position
&& lb
!= itsFormat
.end())
312 LoadAttribute(w
, lb
->Value
);
315 if ((len
+= wcwidth(s
[i
])) > width
)
319 // load all remained attributes to clean up
320 for (; lb
!= itsFormat
.end(); ++lb
)
321 LoadAttribute(w
, lb
->Value
);
327 template <typename C
> void NCurses::basic_buffer
<C
>::Clear()
329 itsString
.str(std::basic_string
<C
>());
333 template <typename C
> void NCurses::basic_buffer
<C
>::LoadAttribute(Window
&w
, short value
) const
335 if (value
< NCurses::fmtNone
)
336 w
<< NCurses::Color(value
);
338 w
<< NCurses::Format(value
);
341 template <typename C
> NCurses::basic_buffer
<C
> &NCurses::basic_buffer
<C
>::operator<<(Color color
)
344 f
.Position
= itsString
.str().length();
346 itsFormat
.push_back(f
);
350 template <typename C
> NCurses::basic_buffer
<C
> &NCurses::basic_buffer
<C
>::operator<<(Format f
)
352 return operator<<(Color(f
));
355 template <typename C
> NCurses::basic_buffer
<C
> &NCurses::basic_buffer
<C
>::operator<<(const NCurses::basic_buffer
<C
> &buf
)
357 size_t len
= itsString
.str().length();
358 itsString
<< buf
.itsString
.str();
359 std::list
<FormatPos
> tmp
= buf
.itsFormat
;
361 for (typename
std::list
<typename
NCurses::basic_buffer
<C
>::FormatPos
>::iterator it
= tmp
.begin(); it
!= tmp
.end(); ++it
)
363 itsFormat
.merge(tmp
);
367 template <typename C
> NCurses::Window
&operator<<(NCurses::Window
&w
, const NCurses::basic_buffer
<C
> &buf
)
369 const std::basic_string
<C
> &s
= buf
.itsTempString
? *buf
.itsTempString
: buf
.itsString
.str();
370 if (buf
.itsFormat
.empty())
376 std::basic_string
<C
> tmp
;
377 typename
std::list
<typename
NCurses::basic_buffer
<C
>::FormatPos
>::const_iterator b
= buf
.itsFormat
.begin();
378 typename
std::list
<typename
NCurses::basic_buffer
<C
>::FormatPos
>::const_iterator e
= buf
.itsFormat
.end();
379 for (size_t i
= 0; i
< s
.length() || b
!= e
; ++i
)
381 while (b
!= e
&& i
== b
->Position
)
388 buf
.LoadAttribute(w
, b
->Value
);