libyui-ncurses  2.44.1
/usr/src/RPM/BUILD/libyui-ncurses-2.44.1/src/NCTreePad.cc
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:       NCTreePad.cc
00020 
00021    Author:     Michael Andres <ma@suse.de>
00022 
00023 /-*/
00024 
00025 #define  YUILogComponent "ncurses"
00026 #include <yui/YUILog.h>
00027 #include "NCTreePad.h"
00028 
00029 
00030 
00031 NCTreePad::NCTreePad( int lines, int cols, const NCWidget & p )
00032         : NCPad( lines, cols, p )
00033         , Headpad( 1, 1 )
00034         , dirtyHead( false )
00035         , dirtyFormat( false )
00036         , ItemStyle( p )
00037         , Headline( 0 )
00038         , Items( 0 )
00039         , visItems( 0 )
00040         , citem( 0 )
00041 {
00042 }
00043 
00044 
00045 
00046 NCTreePad::~NCTreePad()
00047 {
00048     ClearTable();
00049 }
00050 
00051 
00052 
00053 void NCTreePad::assertLine( unsigned idx )
00054 {
00055     if ( idx >= Lines() )
00056         SetLines( idx + 1 );
00057 }
00058 
00059 
00060 
00061 void NCTreePad::SetLines( unsigned idx )
00062 {
00063     if ( idx == Lines() )
00064         return;
00065 
00066     unsigned olines = Lines();
00067 
00068     if ( idx < Lines() )
00069     {
00070         for ( unsigned i = idx; i < Lines(); ++i )
00071         {
00072             delete Items[i];
00073         }
00074     }
00075 
00076     Items.resize( idx, 0 );
00077 
00078     for ( unsigned i = olines; i < Lines(); ++i )
00079     {
00080         if ( !Items[i] )
00081             Items[i] = new NCTableLine( 0 );
00082     }
00083 
00084     DirtyFormat();
00085 }
00086 
00087 
00088 
00089 void NCTreePad::SetLines( std::vector<NCTableLine*> & nItems )
00090 {
00091     SetLines( 0 );
00092     Items = nItems;
00093 
00094     for ( unsigned i = 0; i < Lines(); ++i )
00095     {
00096         if ( !Items[i] )
00097             Items[i] = new NCTableLine( 0 );
00098     }
00099 
00100     DirtyFormat();
00101 }
00102 
00103 
00104 
00105 void NCTreePad::AddLine( unsigned idx, NCTableLine * item )
00106 {
00107     assertLine( idx );
00108     delete Items[idx];
00109     Items[idx] = item ? item : new NCTableLine( 0 );
00110 
00111     DirtyFormat();
00112 }
00113 
00114 
00115 
00116 void NCTreePad::DelLine( unsigned idx )
00117 {
00118     if ( idx < Lines() )
00119     {
00120         Items[idx]->ClearLine();
00121         DirtyFormat();
00122     }
00123 }
00124 
00125 
00126 
00127 const NCTableLine * NCTreePad::GetCurrentLine() const
00128 {
00129     if ( citem.L >= 0 && ( unsigned )citem.L < visLines() )
00130         return visItems[citem.L];
00131 
00132     return 0;
00133 }
00134 
00135 
00136 
00137 NCTableLine * NCTreePad::ModifyLine( unsigned idx )
00138 {
00139     if ( idx < Lines() )
00140     {
00141         DirtyFormat();
00142         return Items[idx];
00143     }
00144 
00145     return 0;
00146 }
00147 
00148 
00149 
00150 const NCTableLine * NCTreePad::GetLine( unsigned idx ) const
00151 {
00152     if ( idx < Lines() )
00153         return Items[idx];
00154 
00155     return 0;
00156 }
00157 
00158 
00159 
00160 bool NCTreePad::SetHeadline( const std::vector<NCstring> & head )
00161 {
00162     bool hascontent = ItemStyle.SetStyleFrom( head );
00163     DirtyFormat();
00164     update();
00165     return hascontent;
00166 }
00167 
00168 
00169 
00170 void NCTreePad::Destwin( NCursesWindow * dwin )
00171 {
00172     NCPad::Destwin( dwin );
00173 
00174     if ( destwin )
00175     {
00176         maxspos.L = visLines() > ( unsigned )srect.Sze.H ? visLines() - srect.Sze.H : 0;
00177     }
00178 }
00179 
00180 
00181 
00182 void NCTreePad::wRecoded()
00183 {
00184     DirtyFormat();
00185     update();
00186 }
00187 
00188 
00189 
00190 wpos NCTreePad::CurPos() const
00191 {
00192     citem.C = srect.Pos.C;
00193     return citem;
00194 }
00195 
00196 
00197 
00198 void NCTreePad::ShowItem( const NCTableLine * item )
00199 {
00200     if ( !item )
00201         return;
00202 
00203     if ( const_cast<NCTableLine *>( item )->ChangeToVisible() || dirtyFormat )
00204         UpdateFormat();
00205 
00206     for ( unsigned l = 0; l < visLines(); ++l )
00207     {
00208         if ( visItems[l] == item )
00209         {
00210             setpos( wpos( l, srect.Pos.C ) );
00211             break;
00212         }
00213     }
00214 }
00215 
00216 
00217 
00218 wsze NCTreePad::UpdateFormat()
00219 {
00220     dirty = true;
00221     dirtyFormat = false;
00222     visItems.clear();
00223     ItemStyle.ResetToMinCols();
00224 
00225     for ( unsigned l = 0; l < Lines(); ++l )
00226     {
00227         Items[l]->UpdateFormat( ItemStyle );
00228 
00229         if ( Items[l]->isVisible() )
00230             visItems.push_back( Items[l] );
00231     }
00232 
00233     maxspos.L = visLines() > ( unsigned )srect.Sze.H ? visLines() - srect.Sze.H : 0;
00234 
00235     resize( wsze( visLines(), ItemStyle.TableWidth() ) );
00236     return wsze( visLines(), ItemStyle.TableWidth() );
00237 }
00238 
00239 
00240 
00241 int NCTreePad::DoRedraw()
00242 {
00243     if ( !Destwin() )
00244     {
00245         dirty = true;
00246         return OK;
00247     }
00248 
00249     if ( dirtyFormat )
00250         UpdateFormat();
00251 
00252     bkgdset( ItemStyle.getBG() );
00253 
00254     clear();
00255 
00256     wsze lSze( 1, width() );
00257 
00258     for ( unsigned l = 0; l < visLines(); ++l )
00259     {
00260         visItems[l]->DrawAt( *this, wrect( wpos( l, 0 ), lSze ),
00261                              ItemStyle, ( l == ( unsigned )citem.L ) );
00262     }
00263 
00264     if ( Headpad.width() != width() )
00265         Headpad.resize( 1, width() );
00266 
00267     Headpad.clear();
00268 
00269     ItemStyle.Headline().DrawAt( Headpad, wrect( wpos( 0, 0 ), lSze ),
00270                                  ItemStyle, false );
00271 
00272     SendHead();
00273 
00274     dirty = false;
00275 
00276     return update();
00277 }
00278 
00279 
00280 
00281 int NCTreePad::setpos( const wpos & newpos )
00282 {
00283     if ( !visLines() )
00284     {
00285         if ( dirty )
00286             return DoRedraw();
00287 
00288         return OK;
00289     }
00290 
00291     if ( dirtyFormat )
00292         UpdateFormat();
00293 
00294     // save old values
00295     int oitem = citem.L;
00296 
00297     int opos  = srect.Pos.C;
00298 
00299     // calc new values
00300     citem.L = newpos.L < 0 ? 0 : newpos.L;
00301 
00302     if (( unsigned )citem.L >= visLines() )
00303         citem.L = visLines() - 1;
00304 
00305     srect.Pos = wpos( citem.L - ( drect.Sze.H - 1 ) / 2, newpos.C ).between( 0, maxspos );
00306 
00307     if ( citem.L != oitem )
00308     {
00309         unsigned at  = 0;
00310         unsigned len = 0;
00311 
00312         if ( citem.L >= 0 && visItems[citem.L] )
00313             len = visItems[citem.L]->Hotspot( at );
00314         else
00315             return ERR;
00316 
00317         if ( len )
00318         {
00319             if (( int )at < srect.Pos.C )
00320             {
00321                 srect.Pos.C = at;
00322             }
00323             else if (( int )( at + len - srect.Pos.C ) > drect.Sze.W )
00324             {
00325                 srect.Pos.C = ( int )at < maxspos.C ? at : maxspos.C;
00326             }
00327         }
00328     }
00329 
00330     if ( dirty )
00331     {
00332         return DoRedraw();
00333     }
00334 
00335     // adjust only
00336     if ( citem.L != oitem )
00337     {
00338         visItems[oitem]->DrawAt( *this, wrect( wpos( oitem, 0 ), wsze( 1, width() ) ),
00339                                  ItemStyle, false );
00340     }
00341 
00342     visItems[citem.L]->DrawAt( *this, wrect( wpos( citem.L, 0 ), wsze( 1, width() ) ),
00343 
00344                                ItemStyle, true );
00345 
00346     if ( srect.Pos.C != opos )
00347         SendHead();
00348 
00349     return update();
00350 }
00351 
00352 
00353 
00354 void NCTreePad::updateScrollHint()
00355 {
00356     NCPad::updateScrollHint();
00357 }
00358 
00359 
00360 
00361 bool NCTreePad::handleInput( wint_t key )
00362 {
00363     bool handled = true;
00364 
00365     if ( !GetCurrentLine() )
00366         return false;
00367 
00368     switch ( key )
00369     {
00370         case KEY_UP:
00371         case KEY_PPAGE:
00372         case KEY_DOWN:
00373         case KEY_NPAGE:
00374             //handle these in compatible way with other widgets (#251180)
00375             //jump to the first/last item
00376 
00377         case KEY_HOME:
00378         case KEY_END:
00379             //scroll horizontally
00380 
00381         case KEY_RIGHT:
00382         case KEY_LEFT:
00383             handled = NCPad::handleInput( key );
00384             break;
00385 
00386             //use these for toggling pack/unpack the tree
00387 
00388         case '+':
00389         case '-':
00390         case KEY_IC:
00391         case KEY_DC:
00392         case KEY_SPACE:
00393         //  case KEY_RETURN: - see bug 67350
00394 
00395             if ( visItems[citem.L]->handleInput( key ) )
00396             {
00397                 UpdateFormat();
00398                 setpos( wpos( citem.L, srect.Pos.C ) );
00399             }
00400 
00401             break;
00402 
00403         default:
00404             handled = false;
00405     }
00406 
00407     return handled;
00408 }
00409 
00410 
00411 std::ostream & operator<<( std::ostream & STREAM, const NCTreePad & OBJ )
00412 {
00413     STREAM << "TreePad: lines " << OBJ.Lines() << std::endl;
00414 
00415     for ( unsigned idx = 0; idx < OBJ.Lines(); ++idx )
00416     {
00417         STREAM << idx << " " << *OBJ.GetLine( idx );
00418     }
00419 
00420     return STREAM;
00421 }
00422 
 All Classes Functions Variables