libyui-ncurses  2.44.1
 All Classes Functions Variables
NCTreePad.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: NCTreePad.cc
20 
21  Author: Michael Andres <ma@suse.de>
22 
23 /-*/
24 
25 #define YUILogComponent "ncurses"
26 #include <yui/YUILog.h>
27 #include "NCTreePad.h"
28 
29 
30 
31 NCTreePad::NCTreePad( int lines, int cols, const NCWidget & p )
32  : NCPad( lines, cols, p )
33  , Headpad( 1, 1 )
34  , dirtyHead( false )
35  , dirtyFormat( false )
36  , ItemStyle( p )
37  , Headline( 0 )
38  , Items( 0 )
39  , visItems( 0 )
40  , citem( 0 )
41 {
42 }
43 
44 
45 
46 NCTreePad::~NCTreePad()
47 {
48  ClearTable();
49 }
50 
51 
52 
53 void NCTreePad::assertLine( unsigned idx )
54 {
55  if ( idx >= Lines() )
56  SetLines( idx + 1 );
57 }
58 
59 
60 
61 void NCTreePad::SetLines( unsigned idx )
62 {
63  if ( idx == Lines() )
64  return;
65 
66  unsigned olines = Lines();
67 
68  if ( idx < Lines() )
69  {
70  for ( unsigned i = idx; i < Lines(); ++i )
71  {
72  delete Items[i];
73  }
74  }
75 
76  Items.resize( idx, 0 );
77 
78  for ( unsigned i = olines; i < Lines(); ++i )
79  {
80  if ( !Items[i] )
81  Items[i] = new NCTableLine( 0 );
82  }
83 
84  DirtyFormat();
85 }
86 
87 
88 
89 void NCTreePad::SetLines( std::vector<NCTableLine*> & nItems )
90 {
91  SetLines( 0 );
92  Items = nItems;
93 
94  for ( unsigned i = 0; i < Lines(); ++i )
95  {
96  if ( !Items[i] )
97  Items[i] = new NCTableLine( 0 );
98  }
99 
100  DirtyFormat();
101 }
102 
103 
104 
105 void NCTreePad::AddLine( unsigned idx, NCTableLine * item )
106 {
107  assertLine( idx );
108  delete Items[idx];
109  Items[idx] = item ? item : new NCTableLine( 0 );
110 
111  DirtyFormat();
112 }
113 
114 
115 
116 void NCTreePad::DelLine( unsigned idx )
117 {
118  if ( idx < Lines() )
119  {
120  Items[idx]->ClearLine();
121  DirtyFormat();
122  }
123 }
124 
125 
126 
127 const NCTableLine * NCTreePad::GetCurrentLine() const
128 {
129  if ( citem.L >= 0 && ( unsigned )citem.L < visLines() )
130  return visItems[citem.L];
131 
132  return 0;
133 }
134 
135 
136 
137 NCTableLine * NCTreePad::ModifyLine( unsigned idx )
138 {
139  if ( idx < Lines() )
140  {
141  DirtyFormat();
142  return Items[idx];
143  }
144 
145  return 0;
146 }
147 
148 
149 
150 const NCTableLine * NCTreePad::GetLine( unsigned idx ) const
151 {
152  if ( idx < Lines() )
153  return Items[idx];
154 
155  return 0;
156 }
157 
158 
159 
160 bool NCTreePad::SetHeadline( const std::vector<NCstring> & head )
161 {
162  bool hascontent = ItemStyle.SetStyleFrom( head );
163  DirtyFormat();
164  update();
165  return hascontent;
166 }
167 
168 
169 
170 void NCTreePad::Destwin( NCursesWindow * dwin )
171 {
172  NCPad::Destwin( dwin );
173 
174  if ( destwin )
175  {
176  maxspos.L = visLines() > ( unsigned )srect.Sze.H ? visLines() - srect.Sze.H : 0;
177  }
178 }
179 
180 
181 
182 void NCTreePad::wRecoded()
183 {
184  DirtyFormat();
185  update();
186 }
187 
188 
189 
190 wpos NCTreePad::CurPos() const
191 {
192  citem.C = srect.Pos.C;
193  return citem;
194 }
195 
196 
197 
198 void NCTreePad::ShowItem( const NCTableLine * item )
199 {
200  if ( !item )
201  return;
202 
203  if ( const_cast<NCTableLine *>( item )->ChangeToVisible() || dirtyFormat )
204  UpdateFormat();
205 
206  for ( unsigned l = 0; l < visLines(); ++l )
207  {
208  if ( visItems[l] == item )
209  {
210  setpos( wpos( l, srect.Pos.C ) );
211  break;
212  }
213  }
214 }
215 
216 
217 
218 wsze NCTreePad::UpdateFormat()
219 {
220  dirty = true;
221  dirtyFormat = false;
222  visItems.clear();
223  ItemStyle.ResetToMinCols();
224 
225  for ( unsigned l = 0; l < Lines(); ++l )
226  {
227  Items[l]->UpdateFormat( ItemStyle );
228 
229  if ( Items[l]->isVisible() )
230  visItems.push_back( Items[l] );
231  }
232 
233  maxspos.L = visLines() > ( unsigned )srect.Sze.H ? visLines() - srect.Sze.H : 0;
234 
235  resize( wsze( visLines(), ItemStyle.TableWidth() ) );
236  return wsze( visLines(), ItemStyle.TableWidth() );
237 }
238 
239 
240 
241 int NCTreePad::DoRedraw()
242 {
243  if ( !Destwin() )
244  {
245  dirty = true;
246  return OK;
247  }
248 
249  if ( dirtyFormat )
250  UpdateFormat();
251 
252  bkgdset( ItemStyle.getBG() );
253 
254  clear();
255 
256  wsze lSze( 1, width() );
257 
258  for ( unsigned l = 0; l < visLines(); ++l )
259  {
260  visItems[l]->DrawAt( *this, wrect( wpos( l, 0 ), lSze ),
261  ItemStyle, ( l == ( unsigned )citem.L ) );
262  }
263 
264  if ( Headpad.width() != width() )
265  Headpad.resize( 1, width() );
266 
267  Headpad.clear();
268 
269  ItemStyle.Headline().DrawAt( Headpad, wrect( wpos( 0, 0 ), lSze ),
270  ItemStyle, false );
271 
272  SendHead();
273 
274  dirty = false;
275 
276  return update();
277 }
278 
279 
280 
281 int NCTreePad::setpos( const wpos & newpos )
282 {
283  if ( !visLines() )
284  {
285  if ( dirty )
286  return DoRedraw();
287 
288  return OK;
289  }
290 
291  if ( dirtyFormat )
292  UpdateFormat();
293 
294  // save old values
295  int oitem = citem.L;
296 
297  int opos = srect.Pos.C;
298 
299  // calc new values
300  citem.L = newpos.L < 0 ? 0 : newpos.L;
301 
302  if (( unsigned )citem.L >= visLines() )
303  citem.L = visLines() - 1;
304 
305  srect.Pos = wpos( citem.L - ( drect.Sze.H - 1 ) / 2, newpos.C ).between( 0, maxspos );
306 
307  if ( citem.L != oitem )
308  {
309  unsigned at = 0;
310  unsigned len = 0;
311 
312  if ( citem.L >= 0 && visItems[citem.L] )
313  len = visItems[citem.L]->Hotspot( at );
314  else
315  return ERR;
316 
317  if ( len )
318  {
319  if (( int )at < srect.Pos.C )
320  {
321  srect.Pos.C = at;
322  }
323  else if (( int )( at + len - srect.Pos.C ) > drect.Sze.W )
324  {
325  srect.Pos.C = ( int )at < maxspos.C ? at : maxspos.C;
326  }
327  }
328  }
329 
330  if ( dirty )
331  {
332  return DoRedraw();
333  }
334 
335  // adjust only
336  if ( citem.L != oitem )
337  {
338  visItems[oitem]->DrawAt( *this, wrect( wpos( oitem, 0 ), wsze( 1, width() ) ),
339  ItemStyle, false );
340  }
341 
342  visItems[citem.L]->DrawAt( *this, wrect( wpos( citem.L, 0 ), wsze( 1, width() ) ),
343 
344  ItemStyle, true );
345 
346  if ( srect.Pos.C != opos )
347  SendHead();
348 
349  return update();
350 }
351 
352 
353 
354 void NCTreePad::updateScrollHint()
355 {
356  NCPad::updateScrollHint();
357 }
358 
359 
360 
361 bool NCTreePad::handleInput( wint_t key )
362 {
363  bool handled = true;
364 
365  if ( !GetCurrentLine() )
366  return false;
367 
368  switch ( key )
369  {
370  case KEY_UP:
371  case KEY_PPAGE:
372  case KEY_DOWN:
373  case KEY_NPAGE:
374  //handle these in compatible way with other widgets (#251180)
375  //jump to the first/last item
376 
377  case KEY_HOME:
378  case KEY_END:
379  //scroll horizontally
380 
381  case KEY_RIGHT:
382  case KEY_LEFT:
383  handled = NCPad::handleInput( key );
384  break;
385 
386  //use these for toggling pack/unpack the tree
387 
388  case '+':
389  case '-':
390  case KEY_IC:
391  case KEY_DC:
392  case KEY_SPACE:
393  // case KEY_RETURN: - see bug 67350
394 
395  if ( visItems[citem.L]->handleInput( key ) )
396  {
397  UpdateFormat();
398  setpos( wpos( citem.L, srect.Pos.C ) );
399  }
400 
401  break;
402 
403  default:
404  handled = false;
405  }
406 
407  return handled;
408 }
409 
410 
411 std::ostream & operator<<( std::ostream & STREAM, const NCTreePad & OBJ )
412 {
413  STREAM << "TreePad: lines " << OBJ.Lines() << std::endl;
414 
415  for ( unsigned idx = 0; idx < OBJ.Lines(); ++idx )
416  {
417  STREAM << idx << " " << *OBJ.GetLine( idx );
418  }
419 
420  return STREAM;
421 }
422 
C++ class for windows.
Definition: ncursesw.h:904
void bkgdset(chtype ch)
Definition: ncursesw.h:1448
Definition: NCPad.h:93
Definition: position.h:109
Definition: position.h:154
int width() const
Definition: ncursesw.h:1075