libyui-ncurses  2.44.1
 All Classes Functions Variables
NCtext.cc
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: NCtext.cc
20 
21  Author: Michael Andres <ma@suse.de>
22 
23 /-*/
24 
25 #define YUILogComponent "ncurses"
26 #include <yui/YUILog.h>
27 #include "NCtext.h"
28 #include "stringutil.h"
29 
30 #include <wchar.h> // wcwidth
31 #include <langinfo.h>
32 
33 #include <boost/algorithm/string.hpp>
34 
35 const NCstring NCtext::emptyStr;
36 
37 
38 
39 
40 NCtext::NCtext( const NCstring & nstr )
41 {
42  lset( nstr );
43 }
44 
45 
46 
47 NCtext::NCtext( const NCstring & nstr, size_t columns )
48 {
49  lbrset( nstr, columns );
50 }
51 
52 
53 
54 NCtext::~NCtext()
55 {}
56 
57 
58 
59 void NCtext::lset( const NCstring & ntext )
60 {
61  // FIXME: rewrite this function so one understands it
62 
63  mtext.clear();
64  mtext.push_back( "" );
65 
66  if ( ntext.str().empty() )
67  return;
68 
69  std::wstring text( ntext.str() );
70 
71  std::wstring::size_type spos = 0;
72 
73  std::wstring::size_type cpos = std::wstring::npos;
74 
75  bool sawnl = false; // saw new line
76 
77  // handle DOS text
78  boost::erase_all( text, L"\r" );
79 
80  while (( cpos = text.find( L'\n', spos ) ) != std::wstring::npos )
81  {
82  if ( sawnl )
83  mtext.push_back( "" );
84 
85  mtext.back() = NCstring( mtext.back().str() + text.substr( spos, cpos - spos ) );
86 
87  sawnl = true;
88 
89  spos = cpos + 1;
90  }
91 
92  if ( spos < text.size() )
93  {
94  if ( sawnl )
95  mtext.push_back( "" );
96 
97  mtext.back() = NCstring( mtext.back().str() + text.substr( spos ) );
98  }
99 }
100 
101 
102 
103 void NCtext::lbrset( const NCstring & ntext, size_t columns )
104 {
105  mtext.clear();
106 
107  if ( ntext.str().empty() )
108  return;
109 
110  std::wstring text( ntext.str() );
111 
112  // handle DOS text
113  boost::erase_all( text, L"\r" );
114 
115  std::wstring::size_type spos = 0;
116 
117  std::wstring::size_type cpos = std::wstring::npos;
118 
119  cpos = text.find( L'\n', spos );
120 
121  while ( cpos != std::wstring::npos )
122  {
123  std::wstring line = text.substr( spos, cpos - spos );
124 
125  if ( line.size() <= columns )
126  {
127  mtext.push_back( NCstring( line ) );
128  }
129  else
130  {
131  size_t start = columns;
132  mtext.push_back( NCstring( line.substr( 0, columns ) ) );
133 
134  while ( start < line.size() )
135  {
136  yuiDebug() << "Add: " << line.substr( start, columns ) << std::endl;
137  mtext.push_back( NCstring( L'~' + line.substr( start, columns - 1 ) ) );
138  start += columns - 1;
139  }
140  }
141 
142  spos = cpos + 1;
143 
144  cpos = text.find( L'\n', spos );
145  }
146 
147  if ( spos < text.size() )
148  {
149  mtext.push_back( NCstring( text.substr( spos ) ) );
150  }
151 }
152 
153 
154 
155 unsigned NCtext::Lines() const
156 {
157  if ( mtext.size() == 1 && mtext.front().Str() == "" )
158  {
159  return 0;
160  }
161  else
162  return mtext.size();
163 }
164 
165 
166 
167 void NCtext::append( const NCstring &line )
168 {
169  mtext.push_back( line );
170 }
171 
172 
173 
174 size_t NCtext::Columns() const
175 {
176  size_t llen = 0; // longest line
177  size_t tmp_len = 0; // width of current line
178 
179  const_iterator line; // iterator for list <NCstring> mtext
180  std::wstring::const_iterator wstr_it; // iterator for std::wstring
181 
182  for ( line = mtext.begin(); line != mtext.end(); ++line )
183  {
184  tmp_len = 0;
185 
186  for ( wstr_it = ( *line ).str().begin(); wstr_it != ( *line ).str().end() ; ++wstr_it )
187  {
188  if ( iswprint( *wstr_it ) )
189  tmp_len += wcwidth( *wstr_it );
190  else if ( *wstr_it == L'\t' )
191  tmp_len += NCurses::tabsize();
192  }
193 
194  if ( tmp_len > llen )
195  llen = tmp_len;
196  }
197 
198  return llen;
199 }
200 
201 
202 
203 const NCstring & NCtext::operator[]( std::wstring::size_type idx ) const
204 {
205  if ( idx >= Lines() )
206  return emptyStr;
207 
208  const_iterator line = mtext.begin();
209 
210  for ( ; idx; --idx, ++line )
211  ;
212 
213  return *line;
214 }
215 
216 
217 std::ostream & operator<<( std::ostream & STREAM, const NCtext & OBJ )
218 {
219  return STREAM << "[Text:" << OBJ.Lines() << ',' << OBJ.Columns() << ']';
220 }
221 
222 
223 
224 
225 
226 void NClabel::stripHotkey()
227 {
228  hotline = std::wstring::npos;
229  unsigned lineno = 0;
230 
231  for ( iterator line = mtext.begin(); line != mtext.end(); ++line, ++lineno )
232  {
233  line->getHotkey();
234 
235  if ( line->hotpos() != std::wstring::npos )
236  {
237  hotline = lineno;
238  break;
239  }
240  }
241 }
242 
243 
244 
245 void NClabel::drawAt( NCursesWindow & w, chtype style, chtype hotstyle,
246  const wrect & dim,
247  const NC::ADJUST adjust,
248  bool fillup ) const
249 {
250  wrect area( dim.intersectRelTo( w.area() ) );
251 
252  if ( area.Sze > 0 )
253  {
254  unsigned maxlen = area.Sze.W;
255  unsigned len = ( width() < maxlen ) ? width() : maxlen;
256  unsigned pre = 0;
257  unsigned post = 0;
258 
259  if ( len < maxlen )
260  {
261  unsigned dist = maxlen - len;
262 
263  if ( adjust & NC::LEFT )
264  pre = 0;
265  else if ( adjust & NC::RIGHT )
266  pre = dist;
267  else
268  pre = dist / 2;
269 
270  post = dist - pre;
271  }
272 
273  int l = area.Pos.L;
274 
275  int maxl = area.Pos.L + area.Sze.H;
276  unsigned lineno = 0;
277 
278  chtype obg = w.getbkgd();
279  w.bkgdset( style );
280 
281  for ( NCtext::const_iterator line = begin();
282  line != end() && l < maxl;
283  ++line, ++l, ++lineno )
284  {
285  if ( pre && fillup )
286  {
287  w.move( l, area.Pos.C );
288  w.addwstr( std::wstring( pre, L' ' ).c_str() );
289  }
290  else
291  {
292  w.move( l, area.Pos.C + pre );
293  }
294 
295  // yuiDebug() << "TERMINAL: " << NCstring::terminalEncoding() << " CODESET: " << nl_langinfo( CODESET) << std::endl;
296  if ( len )
297  {
298  if ( NCstring::terminalEncoding() != "UTF-8" )
299  {
300  std::string out;
301  bool ok = NCstring::RecodeFromWchar(( *line ).str(), NCstring::terminalEncoding(), &out );
302 
303  if ( ok )
304  {
305  w.printw( "%-*.*s", len, ( int )len, out.c_str() );
306  }
307  }
308  else
309  {
310  w.printw( "%ls", ( *line ).str().substr( 0, len ).c_str() );
311  }
312  }
313 
314  if ( post && fillup )
315  {
316  w.addwstr( std::wstring( post, L' ' ).c_str() );
317  }
318 
319  if ( lineno == hotline && hotstyle && pre + hotpos() < maxlen )
320  {
321  w.bkgdset( hotstyle );
322 
323  w.add_attr_char( l, area.Pos.C + pre + hotpos() );
324 
325  w.bkgdset( style );
326  }
327 
328  }
329 
330  if ( fillup )
331  {
332  for ( ; l < maxl; ++l )
333  {
334  w.printw( l, area.Pos.C, "%-*.*s", area.Sze.W, area.Sze.W, "" );
335  }
336  }
337 
338  w.bkgdset( obg );
339  }
340 }
341 
342 
343 std::ostream & operator<<( std::ostream & STREAM, const NClabel & OBJ )
344 {
345  STREAM << "[label" << OBJ.size() << ':' << OBJ[0].str();
346 
347  if ( OBJ.hasHotkey() )
348  STREAM << ':' << OBJ.hotkey() << " at " << OBJ.hotpos();
349 
350  return STREAM << ']';
351 }
352 
C++ class for windows.
Definition: ncursesw.h:904
int printw(const char *fmt,...)
Definition: ncursesw.cc:75
Definition: NCtext.h:37
void bkgdset(chtype ch)
Definition: ncursesw.h:1448
int addwstr(const wchar_t *str, int n=-1)
Definition: ncursesw.cc:123
int add_attr_char(int y, int x)
Definition: ncursesw.cc:166
chtype getbkgd() const
Definition: ncursesw.h:1438
int move(int y, int x)
Definition: ncursesw.h:1155
Definition: NCtext.h:81