libyui-ncurses
2.44.1
|
00001 /* 00002 Copyright (C) 2000-2012 Novell, Inc 00003 This library is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU Lesser General Public License as 00005 published by the Free Software Foundation; either version 2.1 of the 00006 License, or (at your option) version 3.0 of the License. This library 00007 is distributed in the hope that it will be useful, but WITHOUT ANY 00008 WARRANTY; without even the implied warranty of MERCHANTABILITY or 00009 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 00010 License for more details. You should have received a copy of the GNU 00011 Lesser General Public License along with this library; if not, write 00012 to the Free Software Foundation, Inc., 51 Franklin Street, Fifth 00013 Floor, Boston, MA 02110-1301 USA 00014 */ 00015 00016 00017 /*-/ 00018 00019 File: NCTablePad.cc 00020 00021 Author: Michael Andres <ma@suse.de> 00022 00023 /-*/ 00024 00025 #define YUILogComponent "ncurses" 00026 #include <yui/YUILog.h> 00027 #include "NCTablePad.h" 00028 #include "NCPopupMenu.h" 00029 00030 #include <limits.h> 00031 00032 00033 NCTablePad::NCTablePad( int lines, int cols, const NCWidget & p ) 00034 : NCPad( lines, cols, p ) 00035 , Headpad( 1, 1 ) 00036 , dirtyHead( false ) 00037 , dirtyFormat( false ) 00038 , ItemStyle( p ) 00039 , Headline( 0 ) 00040 , Items( 0 ) 00041 , citem( 0 ) 00042 , sortStrategy ( new NCTableSortDefault ) 00043 { 00044 } 00045 00046 00047 00048 NCTablePad::~NCTablePad() 00049 { 00050 ClearTable(); 00051 } 00052 00053 00054 00055 void NCTablePad::assertLine( unsigned idx ) 00056 { 00057 if ( idx >= Lines() ) 00058 SetLines( idx + 1 ); 00059 } 00060 00061 00062 00063 void NCTablePad::SetLines( unsigned idx ) 00064 { 00065 if ( idx == Lines() ) 00066 return; 00067 00068 unsigned olines = Lines(); 00069 00070 if ( idx < Lines() ) 00071 { 00072 for ( unsigned i = idx; i < Lines(); ++i ) 00073 { 00074 delete Items[i]; 00075 } 00076 } 00077 00078 Items.resize( idx, 0 ); 00079 00080 for ( unsigned i = olines; i < Lines(); ++i ) 00081 { 00082 if ( !Items[i] ) 00083 Items[i] = new NCTableLine( 0 ); 00084 } 00085 00086 DirtyFormat(); 00087 } 00088 00089 00090 00091 void NCTablePad::SetLines( std::vector<NCTableLine*> & nItems ) 00092 { 00093 SetLines( 0 ); 00094 Items = nItems; 00095 00096 for ( unsigned i = 0; i < Lines(); ++i ) 00097 { 00098 if ( !Items[i] ) 00099 Items[i] = new NCTableLine( 0 ); 00100 } 00101 00102 DirtyFormat(); 00103 } 00104 00105 00106 00107 void NCTablePad::AddLine( unsigned idx, NCTableLine * item ) 00108 { 00109 assertLine( idx ); 00110 delete Items[idx]; 00111 Items[idx] = item ? item : new NCTableLine( 0 ); 00112 00113 DirtyFormat(); 00114 } 00115 00116 00117 00118 void NCTablePad::DelLine( unsigned idx ) 00119 { 00120 if ( idx < Lines() ) 00121 { 00122 Items[idx]->ClearLine(); 00123 DirtyFormat(); 00124 } 00125 } 00126 00127 00128 00129 const NCTableLine * NCTablePad::GetLine( unsigned idx ) const 00130 { 00131 if ( idx < Lines() ) 00132 return Items[idx]; 00133 00134 return 0; 00135 } 00136 00137 00138 00139 NCTableLine * NCTablePad::ModifyLine( unsigned idx ) 00140 { 00141 if ( idx < Lines() ) 00142 { 00143 DirtyFormat(); 00144 return Items[idx]; 00145 } 00146 00147 return 0; 00148 } 00149 00150 00151 00152 bool NCTablePad::SetHeadline( const std::vector<NCstring> & head ) 00153 { 00154 bool hascontent = ItemStyle.SetStyleFrom( head ); 00155 DirtyFormat(); 00156 update(); 00157 return hascontent; 00158 } 00159 00160 00161 00162 void NCTablePad::wRecoded() 00163 { 00164 DirtyFormat(); 00165 update(); 00166 } 00167 00168 00169 00170 wpos NCTablePad::CurPos() const 00171 { 00172 citem.C = srect.Pos.C; 00173 return citem; 00174 } 00175 00176 00177 00178 wsze NCTablePad::UpdateFormat() 00179 { 00180 yuiDebug() << std::endl; 00181 dirty = true; 00182 dirtyFormat = false; 00183 ItemStyle.ResetToMinCols(); 00184 00185 for ( unsigned l = 0; l < Lines(); ++l ) 00186 { 00187 Items[l]->UpdateFormat( ItemStyle ); 00188 } 00189 00190 resize( wsze( Lines(), ItemStyle.TableWidth() ) ); 00191 00192 return wsze( Lines(), ItemStyle.TableWidth() ); 00193 } 00194 00195 00196 00197 int NCTablePad::DoRedraw() 00198 { 00199 if ( !Destwin() ) 00200 { 00201 dirty = true; 00202 return OK; 00203 } 00204 00205 yuiDebug() << "dirtyFormat " << dirtyFormat << std::endl; 00206 00207 if ( dirtyFormat ) 00208 UpdateFormat(); 00209 00210 bkgdset( ItemStyle.getBG() ); 00211 00212 clear(); 00213 00214 wsze lSze( 1, width() ); 00215 00216 if ( ! pageing() ) 00217 { 00218 for ( unsigned l = 0; l < Lines(); ++l ) 00219 { 00220 Items[l]->DrawAt( *this, wrect( wpos( l, 0 ), lSze ), 00221 ItemStyle, (( unsigned )citem.L == l ) ); 00222 } 00223 } 00224 // else: item drawing requested via directDraw 00225 00226 if ( Headpad.width() != width() ) 00227 Headpad.resize( 1, width() ); 00228 00229 Headpad.clear(); 00230 00231 ItemStyle.Headline().DrawAt( Headpad, wrect( wpos( 0, 0 ), lSze ), 00232 ItemStyle, false ); 00233 00234 SendHead(); 00235 00236 dirty = false; 00237 00238 return update(); 00239 } 00240 00241 00242 00243 void NCTablePad::directDraw( NCursesWindow & w, const wrect at, unsigned lineno ) 00244 { 00245 if ( lineno < Lines() ) 00246 Items[lineno]->DrawAt( w, at, ItemStyle, ((unsigned)citem.L == lineno) ); 00247 else 00248 yuiWarning() << "Illegal Lineno " << lineno << " (" << Lines() << ")" << std::endl; 00249 } 00250 00251 00252 00253 int NCTablePad::setpos( const wpos & newpos ) 00254 { 00255 if ( !Lines() ) 00256 { 00257 if ( dirty || dirtyFormat ) 00258 return DoRedraw(); 00259 00260 return OK; 00261 } 00262 00263 yuiDebug() << newpos << " : l " << Lines() << " : cl " << citem.L 00264 00265 << " : d " << dirty << " : df " << dirtyFormat << std::endl; 00266 00267 if ( dirtyFormat ) 00268 UpdateFormat(); 00269 00270 // save old values 00271 int oitem = citem.L; 00272 00273 int opos = srect.Pos.C; 00274 00275 // calc new values 00276 citem.L = newpos.L < 0 ? 0 : newpos.L; 00277 00278 if (( unsigned )citem.L >= Lines() ) 00279 citem.L = Lines() - 1; 00280 00281 srect.Pos = wpos( citem.L - ( drect.Sze.H - 1 ) / 2, newpos.C ).between( 0, maxspos ); 00282 00283 if ( dirty ) 00284 { 00285 return DoRedraw(); 00286 } 00287 00288 if ( ! pageing() ) 00289 { 00290 // adjust only 00291 if ( citem.L != oitem ) 00292 { 00293 Items[oitem]->DrawAt( *this, wrect( wpos( oitem, 0 ), wsze( 1, width() ) ), 00294 ItemStyle, false ); 00295 } 00296 00297 Items[citem.L]->DrawAt( *this, wrect( wpos( citem.L, 0 ), wsze( 1, width() ) ), 00298 00299 ItemStyle, true ); 00300 } 00301 // else: item drawing requested via directDraw 00302 00303 if ( srect.Pos.C != opos ) 00304 SendHead(); 00305 00306 return update(); 00307 } 00308 00309 00310 00311 void NCTablePad::updateScrollHint() 00312 { 00313 NCPad::updateScrollHint(); 00314 } 00315 00316 00317 00318 bool NCTablePad::setItemByKey( int key ) 00319 { 00320 if ( HotCol() >= Cols() ) 00321 return false; 00322 00323 if ( key < 0 || UCHAR_MAX < key ) 00324 return false; 00325 00326 unsigned hcol = HotCol(); 00327 00328 unsigned hkey = tolower( key ); 00329 00330 for ( unsigned l = 0; l < Lines(); ++l ) 00331 { 00332 if ( Items[l]->GetCol( hcol )->hasHotkey() 00333 && 00334 ( unsigned )tolower( Items[l]->GetCol( hcol )->hotkey() ) == hkey ) 00335 { 00336 ScrlLine( l ); 00337 return true; 00338 } 00339 } 00340 00341 return false; 00342 } 00343 00344 // 00345 // setOrder() sorts the table according to given column by calling 00346 // the sort startegy. Sorting in reverse order is only done 00347 // if 'do_reverse' is set to 'true'. 00348 // 00349 void NCTablePad::setOrder( int col, bool do_reverse ) 00350 { 00351 if ( col < 0 ) 00352 return; 00353 00354 if ( sortStrategy->getColumn() == col && do_reverse ) 00355 { 00356 std::reverse( Items.begin(), Items.end() ); 00357 } 00358 else 00359 { 00360 sortStrategy->setColumn( col ); 00361 sortStrategy->sort( Items.begin(), Items.end(), col ); 00362 } 00363 00364 dirty = true; 00365 update(); 00366 } 00367 00368 00369 00370 bool NCTablePad::handleInput( wint_t key ) 00371 { 00372 return NCPad::handleInput( key ); 00373 } 00374 00375 void NCTablePad::stripHotkeys() 00376 { 00377 for ( unsigned i = 0; i < Lines(); ++i ) 00378 { 00379 if ( Items[i] ) 00380 { 00381 Items[i]->stripHotkeys(); 00382 } 00383 } 00384 } 00385 00386 00387 std::ostream & operator<<( std::ostream & STREAM, const NCTablePad & OBJ ) 00388 { 00389 STREAM << "TablePad: lines " << OBJ.Lines() << std::endl; 00390 00391 for ( unsigned idx = 0; idx < OBJ.Lines(); ++idx ) 00392 { 00393 STREAM << idx << " " << *OBJ.GetLine( idx ); 00394 } 00395 00396 return STREAM; 00397 } 00398