libyui-ncurses  2.57.2
NCTablePadBase.cc
1 /*
2  Copyright (C) 2020 SUSE LLC
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: NCTablePadBase.cc
20 
21  Authors: Michael Andres <ma@suse.de>
22  Stefan Hundhammer <shundhammer@suse.de>
23 
24 /-*/
25 
26 #define YUILogComponent "ncurses"
27 #include <yui/YUILog.h>
28 #include "NCTablePadBase.h"
29 
30 using std::vector;
31 
32 
33 NCTablePadBase::NCTablePadBase( int lines, int cols, const NCWidget & p )
34  : NCPad( lines, cols, p )
35  , _items( 0 )
36  , _headpad( 1, 1 )
37  , _dirtyHead( false )
38  , _dirtyFormat( false )
39  , _itemStyle( p )
40  , _citem( 0 )
41 {
42 }
43 
44 
45 NCTablePadBase::~NCTablePadBase()
46 {
47  ClearTable();
48 }
49 
50 
52 {
53  for ( unsigned i = 0; i < Lines(); ++i )
54  delete _items[i];
55 
56  _items.clear();
57  _visibleItems.clear();
58  setFormatDirty();
59 }
60 
61 
62 NCTableLine * NCTablePadBase::getLineWithIndex( unsigned idx ) const
63 {
64  NCTableLine * line = 0;
65 
66  if ( idx < Lines() )
67  line = _items[ idx ];
68 
69  if ( (unsigned) line->index() == idx )
70  return line;
71 
72  int pos = findIndex( idx );
73 
74  if ( pos >= 0 )
75  {
76  yuiWarning() << "Found item with index " << idx << " at pos " << pos << endl;
77 
78  return _items[ pos ];
79  }
80 
81  yuiError() << "Can't find item with index " << idx << endl;
82 
83  return 0;
84 }
85 
86 
87 const NCTableLine * NCTablePadBase::GetLine( unsigned idx ) const
88 {
89  return getLineWithIndex( idx );
90 }
91 
92 
94 {
95  setFormatDirty();
96  return getLineWithIndex( idx );
97 }
98 
99 
100 int NCTablePadBase::findIndex( unsigned idx ) const
101 {
102  for ( unsigned i=0; i < Lines(); i++ )
103  {
104  if ( (unsigned) _items[ i ]->index() == idx )
105  return i;
106  }
107 
108  return -1;
109 }
110 
111 
112 void NCTablePadBase::SetLines( unsigned idx )
113 {
114  if ( idx == Lines() )
115  return;
116 
117  unsigned olines = Lines();
118 
119  if ( idx < Lines() )
120  {
121  for ( unsigned i = idx; i < Lines(); ++i )
122  {
123  delete _items[i];
124  }
125  }
126 
127  _items.resize( idx, 0 );
128 
129  for ( unsigned i = olines; i < Lines(); ++i )
130  {
131  if ( !_items[i] )
132  _items[i] = new NCTableLine( 0 );
133  }
134 
135  setFormatDirty();
136 }
137 
138 
139 void NCTablePadBase::SetLines( std::vector<NCTableLine*> & newItems )
140 {
141  SetLines( 0 );
142  _items = newItems;
143 
144  for ( unsigned i = 0; i < Lines(); ++i )
145  {
146  if ( !_items[i] )
147  _items[i] = new NCTableLine( 0 );
148  }
149 
150  setFormatDirty();
151 }
152 
153 
154 void NCTablePadBase::AddLine( unsigned idx, NCTableLine * item )
155 {
156  assertLine( idx );
157  delete _items[idx];
158  _items[idx] = item ? item : new NCTableLine( 0 );
159 
160  setFormatDirty();
161 }
162 
163 
164 void NCTablePadBase::assertLine( unsigned idx )
165 {
166  if ( idx >= Lines() )
167  SetLines( idx + 1 );
168 }
169 
170 
171 bool NCTablePadBase::SetHeadline( const vector<NCstring> & head )
172 {
173  bool hascontent = _itemStyle.SetStyleFrom( head );
174  setFormatDirty();
175  update();
176 
177  return hascontent;
178 }
179 
180 
181 void NCTablePadBase::wRecoded()
182 {
183  setFormatDirty();
184  update();
185 }
186 
187 
189 {
190  _citem.C = srect.Pos.C;
191  return _citem;
192 }
193 
194 
195 wsze NCTablePadBase::tableSize()
196 {
197  if ( _dirtyFormat )
198  UpdateFormat();
199 
200  return wsze( Lines(), _itemStyle.TableWidth() );
201 }
202 
203 
204 wsze NCTablePadBase::UpdateFormat()
205 {
206  dirty = true;
207  _itemStyle.ResetToMinCols();
208 
209  for ( unsigned i = 0; i < Lines(); ++i )
210  _items[i]->UpdateFormat( _itemStyle );
211 
212  _dirtyFormat = false;
214 
215  maxspos.L = visibleLines() > (unsigned) srect.Sze.H ? visibleLines() - srect.Sze.H : 0;
216 
217  wsze size( visibleLines(), _itemStyle.TableWidth() );
218  resize( size );
219 
220  return size;
221 }
222 
223 
224 // Update the internal _visibleItems() vector.
225 // This does NOT do a screen update of the visible items!
226 
228 {
229  _visibleItems.clear();
230 
231  for ( unsigned i = 0; i < Lines(); ++i )
232  {
233  if ( _items[ i ]->isVisible() )
234  _visibleItems.push_back( _items[ i ] );
235  }
236 }
237 
238 
240 {
241  // Notice that this is only a fallback implementation of this method.
242  // Derived classes usually overwrite this with subtle changes.
243  // See NCTreePad::DoRedraw() or NCTablePad::DoRedraw().
244 
245  if ( !Destwin() )
246  {
247  dirty = true;
248  return OK;
249  }
250 
251  prepareRedraw();
253  drawHeader();
254 
255  dirty = false;
256 
257  return update();
258 }
259 
260 
262 {
263  if ( _dirtyFormat )
264  UpdateFormat();
265 
266  bkgdset( _itemStyle.getBG() );
267  clear();
268 }
269 
270 
272 {
273  wsze lineSize( 1, width() );
274 
275  for ( unsigned lineNo = 0; lineNo < visibleLines(); ++lineNo )
276  {
277  _visibleItems[ lineNo ]->DrawAt( *this,
278  wrect( wpos( lineNo, 0 ), lineSize ),
279  _itemStyle,
280  ( lineNo == (unsigned) currentLineNo() ) );
281  }
282 }
283 
284 
286 {
287  wsze lineSize( 1, width() );
288 
289  if ( _headpad.width() != width() )
290  _headpad.resize( 1, width() );
291 
292  _headpad.clear();
293  _itemStyle.Headline().DrawAt( _headpad,
294  wrect( wpos( 0, 0 ), lineSize ),
295  _itemStyle,
296  false );
297  SendHead();
298 }
299 
300 
301 int NCTablePadBase::setpos( const wpos & newpos )
302 {
303  if ( !Lines() )
304  {
305  if ( dirty || _dirtyFormat )
306  return DoRedraw();
307 
308  return OK;
309  }
310 
311  if ( _dirtyFormat )
312  UpdateFormat();
313 
314  // Save old values
315  int oldLineNo = currentLineNo();
316  int oldPos = srect.Pos.C;
317 
318  // Calc new values
319  setCurrentLineNo( newpos.L < 0 ? 0 : newpos.L );
320 
321  // Prevent scrolling out of the visible lines
322  if ( (unsigned) currentLineNo() >= visibleLines() )
324 
325  srect.Pos = wpos( currentLineNo() - ( drect.Sze.H - 1 ) / 2, newpos.C ).between( 0, maxspos );
326 
327  if ( currentLineNo() != oldLineNo )
328  {
329  unsigned at = 0;
330  unsigned len = 0;
331 
332  if ( currentLineNo() >= 0 && _visibleItems[ currentLineNo() ] )
333  {
334  len = _visibleItems[ currentLineNo() ]->Hotspot( at );
335  }
336  else
337  {
338  return ERR;
339  }
340 
341  if ( len )
342  {
343  if ( (int) at < srect.Pos.C )
344  {
345  srect.Pos.C = at;
346  }
347  else if ( (int) ( at + len - srect.Pos.C ) > drect.Sze.W )
348  {
349  srect.Pos.C = (int) at < maxspos.C ? at : maxspos.C;
350  }
351  }
352  }
353 
354  if ( dirty )
355  return DoRedraw();
356 
357  if ( ! paging() )
358  {
359  // adjust only
360 
361  if ( currentLineNo() != oldLineNo )
362  {
363  _visibleItems[ oldLineNo ]->DrawAt( *this,
364  wrect( wpos( oldLineNo, 0 ),
365  wsze( 1, width() ) ),
366  _itemStyle,
367  false );
368  }
369 
370  _visibleItems[ currentLineNo() ]->DrawAt( *this,
371  wrect( wpos( currentLineNo(), 0 ),
372  wsze( 1, width() ) ),
373  _itemStyle,
374  true );
375  }
376  // else
377  // item drawing requested via directDraw()
378 
379  if ( srect.Pos.C != oldPos )
380  SendHead();
381 
382  return update();
383 }
384 
385 
386 bool NCTablePadBase::handleInput( wint_t key )
387 {
388  // First, give the current item (the item at the cursor position) a chance
389  // to handle item-specific keys. The item handles opening and closing
390  // branches and item selection.
391 
392  bool handled = currentItemHandleInput( key );
393 
394  if ( ! handled )
395  {
396  switch ( key )
397  {
398  // At this time, there are no more special keys to handle on this
399  // level. This switch is a stub for future extension if any more
400  // keys need to be handled.
401  //
402  // Add 'case KEY_XXX' branches here if there should be any
403  // and don't forget to set 'handled' to 'true'.
404 #if 0
405  case KEY_SOMETHING: // Sample
406  doSomething();
407  handled = true;
408  break;
409 #endif
410 
411  default: // Call parent class input handler
412 
413  // The NCPad handles scrolling with the cursor keys, PgDn,
414  // PgUp, Home, End.
415  handled = NCPad::handleInput( key );
416  break;
417  }
418  }
419 
420  return handled;
421 }
422 
423 
425 {
426  bool handled = false;
427  NCTableLine * currentLine = GetCurrentLine();
428 
429  if ( currentLine )
430  {
431  handled = currentLine->handleInput( key );
432 
433  if ( handled )
434  {
435  UpdateFormat();
436  setpos( wpos( currentLineNo(), srect.Pos.C ) );
437  }
438  }
439 
440  return handled;
441 }
442 
443 
445 {
446  if ( currentLineNo() >= 0 && (unsigned) currentLineNo() < visibleLines() )
447  return _visibleItems[ currentLineNo() ];
448 
449  return 0;
450 }
451 
452 
453 //----------------------------------------------------------------------
454 
455 
456 std::ostream & operator<<( std::ostream & str, const NCTablePadBase & obj )
457 {
458  str << "TablePadBase: lines " << obj.Lines() << std::endl;
459 
460  for ( unsigned idx = 0; idx < obj.Lines(); ++idx )
461  {
462  str << idx << " " << *obj.GetLine( idx );
463  }
464 
465  return str;
466 }
wsze
Screen dimension (screen size) in the order height, width: (H, W)
Definition: position.h:154
NCTablePadBase::ClearTable
void ClearTable()
Clear all content.
Definition: NCTablePadBase.cc:51
NCTableStyle::ResetToMinCols
void ResetToMinCols()
Forget sizing based on table content, resize according to headline only.
Definition: NCTableItem.h:552
NCTablePadBase::findIndex
int findIndex(unsigned idx) const
Find the item with index 'idx' in the items and return its position.
Definition: NCTablePadBase.cc:100
NCTablePadBase::GetCurrentLine
NCTableLine * GetCurrentLine() const
Return the current line (the line at the cursor position) or 0 if there is none.
Definition: NCTablePadBase.cc:444
NCTablePadBase::SetLines
void SetLines(unsigned count)
Expand or shrink to have exactly count logical lines.
Definition: NCTablePadBase.cc:112
NCTablePadBase::updateVisibleItems
void updateVisibleItems()
Update the internal _visibleItems vector with the items that are currently visible: Clear the old con...
Definition: NCTablePadBase.cc:227
wpair::between
wpair between(const wpair &Min, const wpair &Max) const
a copy of this clamped between Min and Max
Definition: position.h:87
NCTablePadBase::Lines
unsigned Lines() const
Return the number of table lines (logical, not screen)
Definition: NCTablePadBase.h:122
NCursesWindow::clear
int clear()
Clear the window.
Definition: ncursesw.h:1524
NCTablePadBase::CurPos
virtual wpos CurPos() const
CurPos().L is the index of the selected item.
Definition: NCTablePadBase.cc:188
NCTablePadBase::prepareRedraw
virtual void prepareRedraw()
Prepare a redraw: Update the format if needed, set the background, clear the old content.
Definition: NCTablePadBase.cc:261
NCWidget
Definition: NCWidget.h:46
NCTablePadBase::drawHeader
virtual void drawHeader()
Redraw the table header.
Definition: NCTablePadBase.cc:285
NCTablePadBase::_dirtyFormat
bool _dirtyFormat
does table format (size) need recalculating?
Definition: NCTablePadBase.h:293
NCTablePadBase::ModifyLine
NCTableLine * ModifyLine(unsigned idx)
Return line at idx for read-write operations and mark it as modified.
Definition: NCTablePadBase.cc:93
NCTablePadBase::visibleLines
unsigned visibleLines() const
Return the number of lines that are currently visible.
Definition: NCTablePadBase.h:89
NCTablePadBase::setpos
virtual int setpos(const wpos &newPos)
Base function for scrolling: Move the cursor position to 'newPos' and redraw the old and the new curr...
Definition: NCTablePadBase.cc:301
NCursesWindow::width
int width() const
Number of columns in this window.
Definition: ncursesw.h:1077
NCTablePadBase::assertLine
void assertLine(unsigned index)
Ensure that a line with the specified index exists.
Definition: NCTablePadBase.cc:164
NCTablePadBase::GetLine
const NCTableLine * GetLine(unsigned idx) const
Return the line at idx for read-only operations.
Definition: NCTablePadBase.cc:87
NCTablePadBase::currentLineNo
int currentLineNo() const
Return the current line number (the cursor position).
Definition: NCTablePadBase.h:261
NCTablePadBase::_citem
wpos _citem
current/cursor position
Definition: NCTablePadBase.h:295
NCTablePadBase::_visibleItems
std::vector< NCTableLine * > _visibleItems
not owned
Definition: NCTablePadBase.h:290
NCPad
A virtual window with a real viewport (which is NCursesWindow) and a scrolling mechanism.
Definition: NCPad.h:113
NCTableLine::DrawAt
virtual void DrawAt(NCursesWindow &w, const wrect at, NCTableStyle &tableStyle, bool active) const
Definition: NCTableItem.cc:319
NCTablePadBase::drawContentLines
virtual void drawContentLines()
Redraw the (visible) content lines one by one.
Definition: NCTablePadBase.cc:271
wpos
Screen position pair in the order line, column: (L, C)
Definition: position.h:110
NCTableStyle::SetStyleFrom
bool SetStyleFrom(const std::vector< NCstring > &head)
Reset columns, setting their alignment and optionally titles.
Definition: NCTableItem.cc:721
NCTablePadBase::currentItemHandleInput
virtual bool currentItemHandleInput(wint_t key)
Call the current item's handleInput() method and return 'true' if the event is now handled,...
Definition: NCTablePadBase.cc:424
NCTablePadBase::handleInput
virtual bool handleInput(wint_t key)
Handle a keyboard input event.
Definition: NCTablePadBase.cc:386
NCTablePadBase::_items
std::vector< NCTableLine * > _items
(owned)
Definition: NCTablePadBase.h:289
NCTableLine::index
int index() const
Return the unique index by which this line can be identified.
Definition: NCTableItem.h:137
NCPad::paging
bool paging() const
Whether the Pad is truncated (we're paging).
Definition: NCPad.h:149
NCTableStyle::TableWidth
unsigned TableWidth() const
Add up the widths of columns with the separators.
Definition: NCTableItem.h:612
NCTableLine
One line in a NCTable with multiple cells and an optional tree hierarchy.
Definition: NCTableItem.h:68
NCTablePadBase::DoRedraw
virtual int DoRedraw()
Redraw the pad.
Definition: NCTablePadBase.cc:239
wrect
A rectangle is defined by its position and size: wpos Pos, wsze Sze.
Definition: position.h:194
NCTablePadBase::NCTablePadBase
NCTablePadBase(int lines, int cols, const NCWidget &p)
Constructor.
Definition: NCTablePadBase.cc:33
NCTablePadBase
An NCPad for an NCTable or an NCTree.
Definition: NCTablePadBase.h:59
NCTableLine::handleInput
virtual bool handleInput(wint_t key)
Handle keyboard input.
Definition: NCTableItem.cc:472
NCursesWindow::bkgdset
void bkgdset(chtype ch)
Set the background property.
Definition: ncursesw.h:1450
NCTablePadBase::setCurrentLineNo
void setCurrentLineNo(int newVal)
Set the current line number (the cursor position).
Definition: NCTablePadBase.h:266
NCPad::srect
wrect srect
Source rectangle: the visible part of this pad.
Definition: NCPad.h:138
NCTablePadBase::AddLine
void AddLine(unsigned idx, NCTableLine *item)
Add item at position idx, expanding if needed.
Definition: NCTablePadBase.cc:154