libyui-ncurses  2.44.1
/usr/src/RPM/BUILD/libyui-ncurses-2.44.1/src/NCStyleDef.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:       NCStyleDef.cc
00020 
00021    Author:     Michael Andres <ma@suse.de>
00022 
00023 /-*/
00024 
00025 #include <iostream>
00026 #include <fstream>
00027 #include <vector>
00028 #include <list>
00029 
00030 
00031 #define  YUILogComponent "ncurses"
00032 #include <yui/YUILog.h>
00033 #include "NCurses.h"
00034 #include "NCstyle.h"
00035 
00036 
00037 class NCStyleDef
00038 {
00039 
00040 public:
00041 
00042     // Self reference
00043     static NCStyleDef * NCStyleDef_p;
00044 
00045     // Reference to class NCstyle
00046     NCstyle & NCstyle_C;
00047 
00048     // Master panel
00049     NCursesPanel p;
00050 
00051     // draw panel frame in move mode or plain
00052     void pbox( bool on = false );
00053 
00054     // move panel interactive or determined by key
00055     int  movePad( int key = -1 );
00056 
00057     static const NCursesPanel & pad()                   { return NCStyleDef_p->p; }
00058 
00059     static void                 refresh()               { NCStyleDef_p->p.refresh(); }
00060 
00061     static int                  movepad( int key = -1 ) { return NCStyleDef_p->movePad( key ); }
00062 
00063 
00064     // Example popup is somwhat special. It's handmade, so we habe to
00065     // keep it in sync when attributes change.
00066 
00067     enum ExMode { EX_OFF, EX_ON, EX_TOGGLE, EX_UPDATE };
00068 
00069     static void showex( ExMode mode );
00070 
00071     // Advise NCstyle to fake attributes, i.e. always return the set we currently process
00072     static void fakestyle( NCstyle::StyleSet style )
00073     {
00074         NCStyleDef_p->NCstyle_C.fakestyle( style );
00075 
00076         if ( style != NCstyle::MaxStyleSet )
00077         {
00078             NCStyleDef_p->doshowset( NCStyleDef_p->wSet.cset, true );
00079             showex( EX_UPDATE );
00080         }
00081         else
00082         {
00083             showex( EX_OFF );
00084         }
00085     }
00086 
00087     // to be called to reflect changed attributes on screen
00088     static void attrchanged()
00089     {
00090         NCurses::Redraw();
00091         showex( EX_UPDATE );
00092     }
00093 
00094     // SetTypes handled by struct Wset.
00095 
00096     enum SetType
00097     {
00098         Global = 0,
00099         DialogBorder,
00100         DialogBorderActive,
00101         DialogText,
00102         Widget,
00103         WidgetActive,
00104         FrameWidget,
00105         FrameWidgetActive,
00106         List,
00107         ListActive,
00108         RichText,
00109         ProgressBar,
00110         // last entry
00111         MaxSetType
00112     };
00113 
00114     static std::string dumpName( SetType a )
00115     {
00116 #define PRT(t) case t: return #t;
00117 
00118         switch ( a )
00119         {
00120             PRT( Global );
00121             PRT( DialogBorder );
00122             PRT( DialogBorderActive );
00123             PRT( DialogText );
00124             PRT( Widget );
00125             PRT( WidgetActive );
00126             PRT( FrameWidget );
00127             PRT( FrameWidgetActive );
00128             PRT( List );
00129             PRT( ListActive );
00130             PRT( RichText );
00131             PRT( ProgressBar );
00132 
00133             case MaxSetType:
00134                 break;
00135         }
00136 
00137         return "unknown";
00138 
00139 #undef PRT
00140     }
00141 
00142     // Aset serves as menu entry for struct Wchattr.
00143     // Any modification of the associated chtype is handled here.
00144 
00145     struct Aset
00146     {
00147 
00148 private:
00149         chtype * attr_p;
00150 
00151 public:
00152         std::string      label;
00153         Aset( chtype & ch, const std::string & l ) : attr_p( &ch ), label( l )
00154         {}
00155 
00156         chtype attr()     const { return *attr_p; }
00157 
00158         chtype textattr() const { return attr() &  ~NCattribute::char_mask; }
00159 
00160         void setBg( bool prev ) { NCattribute::setBg( *attr_p, NCattribute::getBg( *attr_p ) + ( prev ? -1 : 1 ) ); }
00161 
00162         void setFg( bool prev ) { NCattribute::setFg( *attr_p, NCattribute::getFg( *attr_p ) + ( prev ? -1 : 1 ) ); }
00163 
00164         void toggleStyle( chtype sty ) { NCattribute::toggleStyle( *attr_p, sty ); }
00165 
00166         void setStyle( chtype sty )    { NCattribute::setStyle( *attr_p, sty ); }
00167 
00168         void setChar( chtype sty )     { NCattribute::setChar( *attr_p, sty ); }
00169     };
00170 
00171     // Retrieve appropriate chtype from NCstyle
00172     const chtype & attr( NCstyle::STglobal a )
00173     {
00174         return NCstyle_C.getStyle( NCstyle_C.fakestyle_e ).attr( a );
00175     }
00176 
00177     const chtype & attr( NCstyle::STlocal a )
00178     {
00179         return NCstyle_C.getStyle( NCstyle_C.fakestyle_e ).attr( a );
00180     }
00181 
00182     // Build the Aset std::vector associated with a SetType and assing it to struct Wchattr.
00183     void doshowset( SetType a, bool reset = false );
00184 
00185     static void showset( SetType a )
00186     {
00187         NCStyleDef_p->doshowset( a );
00188     }
00189 
00190     // queryCharEnt serves as menu entry for the ACS char popoup in queryChar()
00191     // queryChar(). Used in struct Wchattr.
00192 
00193     struct queryCharEnt
00194     {
00195         std::string l;
00196         chtype c;
00197         queryCharEnt( std::string L, chtype C ) { l = L; c = C; }
00198     };
00199 
00200     static chtype queryChar( int column = 0, chtype selbg = A_REVERSE );
00201 
00202     // Show details of Wchattr's current item (fg/bg and attributes)
00203 
00204     void doshowstat( const Aset & a ) { wChstat.stat( a ); }
00205 
00206     static void showstat( const Aset & a )
00207     {
00208         NCStyleDef_p->doshowstat( a );
00209     }
00210 
00211     static const char * dumpColor( short c )
00212     {
00213         switch ( c )
00214         {
00215             case -1:
00216                 return "-1";
00217                 break;
00218 
00219             case COLOR_BLACK:
00220                 return "bk";
00221                 break;
00222 
00223             case COLOR_RED:
00224                 return "re";
00225                 break;
00226 
00227             case COLOR_GREEN:
00228                 return "gr";
00229                 break;
00230 
00231             case COLOR_YELLOW:
00232                 return "ye";
00233                 break;
00234 
00235             case COLOR_BLUE:
00236                 return "bl";
00237                 break;
00238 
00239             case COLOR_MAGENTA:
00240                 return "ma";
00241                 break;
00242 
00243             case COLOR_CYAN:
00244                 return "cy";
00245                 break;
00246 
00247             case COLOR_WHITE:
00248                 return "wh";
00249                 break;
00250         }
00251 
00252         return "??";
00253     }
00254 
00255 
00256     /**
00257      * SubWin: base class for the windows used
00258      **/
00259     struct SubWin
00260     {
00261         static const int taglen = 7;
00262         NCursesWindow w;
00263         std::string     tag;
00264         chtype          changestyle;
00265         SubWin( std::string T, NCursesWindow & P, int H, int W, int L, int C )
00266                 : w( P, H, W, L, C, 'r' )
00267                 , tag( std::string( "<" ) + T + ">" )
00268         {
00269             changestyle = A_NORMAL;
00270         }
00271 
00272         virtual ~SubWin() {}
00273 
00274         virtual void draw( bool immediate = false )
00275         {
00276             w.syncup();
00277 
00278             if ( immediate )
00279                 refresh();
00280         }
00281 
00282         virtual int dtag()
00283         {
00284             if ( tag.size() > 2 )
00285             {
00286                 w.printw( 0, 0, "%-*.*s", taglen, taglen, tag.c_str() );
00287                 return w.width() - taglen;
00288             }
00289 
00290             w.move( 0, 0 );
00291 
00292             return w.width();
00293         }
00294 
00295         virtual int change()
00296         {
00297             enterchange();
00298             bool continue_bi = true;
00299             int  in          = -1;
00300 
00301             do
00302             {
00303                 switch (( in = getch() ) )
00304                 {
00305                     case -1:
00306                     case KEY_ESC:
00307                     case KEY_TAB:
00308                     case KEY_RETURN:
00309                         in = -1; // no reconsume
00310 
00311                     case KEY_F( 1 ):
00312                     case KEY_F( 2 ):
00313                     case KEY_F( 3 ):
00314                     case KEY_F( 4 ):
00315                     case KEY_F( 5 ):
00316                     case KEY_F( 6 ):
00317                     case KEY_F( 7 ):
00318                     case KEY_F( 8 ):
00319                     case KEY_F( 9 ):
00320                     case KEY_F( 10 ):
00321                         continue_bi = false;
00322                         break;
00323 
00324                     default:
00325                         handle( in );
00326                         break;
00327                 }
00328             }
00329             while ( continue_bi );
00330 
00331             leavechange();
00332 
00333             return in;
00334         }
00335 
00336         virtual void enterchange()
00337         {
00338             changestyle = A_REVERSE;
00339             w.bkgd( changestyle );
00340             draw( true );
00341         }
00342 
00343         virtual void leavechange()
00344         {
00345             changestyle = A_NORMAL;
00346             w.bkgd( changestyle );
00347             draw( true );
00348         }
00349 
00350         virtual void handle( int in )
00351         {
00352         }
00353     };
00354 
00355 
00356     /**
00357      * Wstyle: Selection of the current NCstyle::StyleSet to process
00358      **/
00359     struct Wstyle : public SubWin
00360     {
00361         NCstyle::StyleSet cset;
00362         Wstyle( std::string T, NCursesWindow & P, int H, int W, int L, int C )
00363                 : SubWin( T, P, H, W, L, C )
00364         {
00365             cset = ( NCstyle::StyleSet )( 0 );
00366         }
00367 
00368         virtual void draw( bool immediate = false )
00369         {
00370             int len = dtag();
00371             w.printw( "%-*.*s", len, len, NCstyle::dumpName( cset ).c_str() );
00372 
00373             if ( cset == 0 )
00374                 w.addch( 0, 2, '-' );
00375 
00376             if ( cset ==  NCstyle::MaxStyleSet - 1 )
00377                 w.addch( 0, 4, '-' );
00378 
00379             SubWin::draw( immediate );
00380         }
00381 
00382         virtual void handle( int in )
00383         {
00384             switch ( in )
00385             {
00386                 case KEY_UP:
00387 
00388                     if ( cset > 0 )
00389                     {
00390                         cset = ( NCstyle::StyleSet )( cset - 1 );
00391                         draw( true );
00392                         fakestyle( cset );
00393                     }
00394                     break;
00395 
00396                 case KEY_DOWN:
00397 
00398                     if ( cset + 1 < NCstyle::MaxStyleSet )
00399                     {
00400                         cset = ( NCstyle::StyleSet )( cset + 1 );
00401                         draw( true );
00402                         fakestyle( cset );
00403                     }
00404                     break;
00405             }
00406         }
00407     };
00408 
00409 
00410     /**
00411      * Wset: Selection of the current attribute std::set to process
00412      **/
00413     struct Wset : public SubWin
00414     {
00415         SetType cset;
00416         Wset( std::string T, NCursesWindow & P, int H, int W, int L, int C )
00417                 : SubWin( T, P, H, W, L, C )
00418         {
00419             cset = ( SetType )( 0 );
00420         }
00421 
00422         virtual void draw( bool immediate = false )
00423         {
00424             int len = dtag();
00425             w.printw( "%-*.*s", len, len, dumpName( cset ).c_str() );
00426 
00427             if ( cset == 0 )
00428                 w.addch( 0, 2, '-' );
00429 
00430             if ( cset ==  MaxSetType - 1 )
00431                 w.addch( 0, 4, '-' );
00432 
00433             SubWin::draw( immediate );
00434         }
00435 
00436         virtual void handle( int in )
00437         {
00438             switch ( in )
00439             {
00440                 case KEY_UP:
00441 
00442                     if ( cset > 0 )
00443                     {
00444                         cset = ( SetType )( cset - 1 );
00445                         draw( true );
00446                         showset( cset );
00447                     }
00448 
00449                     break;
00450 
00451                 case KEY_DOWN:
00452 
00453                     if ( cset + 1 < MaxSetType )
00454                     {
00455                         cset = ( SetType )( cset + 1 );
00456                         draw( true );
00457                         showset( cset );
00458                     }
00459 
00460                     break;
00461             }
00462         }
00463     };
00464 
00465 
00466     /**
00467      * Wchattr: handle modification of the current attribute std::set.
00468      **/
00469     struct Wchattr : public SubWin
00470     {
00471         std::vector<Aset> aset;
00472         unsigned     fitem;
00473         unsigned     citem;
00474         Wchattr( std::string T, NCursesWindow & P, int H, int W, int L, int C )
00475                 : SubWin( T, P, H, W, L, C )
00476         {
00477             fitem = citem = 0;
00478         }
00479 
00480         virtual void draw( bool immediate = false )
00481         {
00482             w.box();
00483             dtag();
00484             drawTable( immediate );
00485         }
00486 
00487         virtual void handle( int in )
00488         {
00489             if ( !aset.size() )
00490                 return;
00491 
00492             bool redraw    = true;
00493 
00494             bool redrawall = true;
00495 
00496             switch ( in )
00497             {
00498                 case KEY_UP:
00499 
00500                     if ( citem )
00501                     {
00502                         --citem;
00503                         redrawall = false;
00504                     }
00505 
00506                     break;
00507 
00508                 case KEY_DOWN:
00509 
00510                     if ( citem + 1 < aset.size() )
00511                     {
00512                         ++citem;
00513                         redrawall = false;
00514                     }
00515 
00516                     break;
00517 
00518                 case KEY_LEFT:
00519                 case KEY_RIGHT:
00520                     movepad( in );
00521                     break;
00522 
00523                 case KEY_PPAGE:
00524                     aset[citem].setBg( true );
00525                     break;
00526 
00527                 case KEY_NPAGE:
00528                     aset[citem].setBg( false );
00529                     break;
00530 
00531                 case KEY_HOME:
00532                     aset[citem].setFg( true );
00533                     break;
00534 
00535                 case KEY_END:
00536                     aset[citem].setFg( false );
00537                     break;
00538 
00539                 case KEY_IC:
00540                 case 'b':
00541                     aset[citem].toggleStyle( A_BOLD );
00542                     break;
00543 
00544                 case KEY_DC:
00545                 case 'n':
00546                     aset[citem].setStyle( A_NORMAL );
00547                     break;
00548 
00549                 case 'l':
00550                     aset[citem].toggleStyle( A_BLINK );
00551                     break;
00552 
00553                 case 's':
00554                     aset[citem].toggleStyle( A_STANDOUT );
00555                     break;
00556 
00557                 case 'u':
00558                     aset[citem].toggleStyle( A_UNDERLINE );
00559                     break;
00560 
00561                 case 'r':
00562                     aset[citem].toggleStyle( A_REVERSE );
00563                     break;
00564 
00565                 case 'd':
00566                     aset[citem].toggleStyle( A_DIM );
00567                     break;
00568 
00569                 case 'i':
00570                     aset[citem].toggleStyle( A_INVIS );
00571                     break;
00572 
00573                 case 'a':
00574                     {
00575                         chtype ach = queryChar( pad().begx() + 5, aset[citem].textattr() );
00576 
00577                         if ( ach != ( chtype ) - 1 )
00578                             aset[citem].setChar( ach );
00579                     }
00580 
00581                     break;
00582 
00583                 default:
00584                     redraw = redrawall = false;
00585                     break;
00586             }
00587 
00588             if ( redraw )
00589                 drawTable( true );
00590 
00591             if ( redrawall )
00592                 attrchanged();
00593         }
00594 
00595         void set( std::vector<Aset> & nset, bool reset = false )
00596         {
00597             aset.swap( nset );
00598             draw( true );
00599         }
00600 
00601         void drawTable( bool immediate = false )
00602         {
00603             unsigned t    = w.height() - 1;
00604             unsigned high = ( t - 1 );
00605             unsigned spot = high / 2;
00606             unsigned l = 1;
00607 
00608             if ( !aset.size() )
00609                 citem = 0;
00610             else if ( citem >= aset.size() )
00611                 citem = aset.size() - 1;
00612 
00613             if ( high >= aset.size() || citem <= spot )
00614             {
00615                 fitem = 0;
00616             }
00617             else
00618             {
00619                 fitem = citem - spot;
00620 
00621                 if ( fitem + high >= aset.size() )
00622                     fitem = aset.size() - high;
00623             }
00624 
00625             for ( unsigned i = fitem; l < t; ++i, ++l )
00626             {
00627                 drawItemAt( l, i );
00628             }
00629 
00630             if ( !aset.size() )
00631             {
00632                 int len = w.width() - 2;
00633                 w.bkgdset( changestyle );
00634                 w.printw( 1, 1, "%-*.*s", len, len, "<empty>" );
00635             }
00636 
00637             w.bkgdset( changestyle );
00638 
00639             SubWin::draw( immediate );
00640         }
00641 
00642         void drawItemAt( unsigned line, unsigned num )
00643         {
00644             int len = w.width() - 4;
00645 
00646             if ( num < aset.size() )
00647             {
00648                 w.bkgdset( changestyle );
00649 
00650                 if ( num == citem )
00651                 {
00652                     w.addstr( line, 1, "->" );
00653                     showstat( aset[num] );
00654                 }
00655                 else
00656                 {
00657                     w.addstr( line, 1, "  " );
00658                 }
00659 
00660                 w.bkgdset( aset[num].attr() );
00661 
00662                 w.printw( line, 3, "%-*.*s", len, len, "" );
00663                 w.bkgdset( aset[num].textattr() );
00664                 w.addstr( line, 3, aset[num].label.c_str(), len );
00665             }
00666             else
00667             {
00668                 w.bkgdset( changestyle );
00669                 w.printw( line, 1, "%-*.*s", len + 2, len + 2, "" );
00670             }
00671         }
00672     };
00673 
00674 
00675     /**
00676      * Wchstat: show current attributes definition
00677      **/
00678     struct Wchstat : public SubWin
00679     {
00680         Wchstat( std::string T, NCursesWindow & P, int H, int W, int L, int C )
00681                 : SubWin( T, P, H, W, L, C )
00682         {
00683         }
00684 
00685         virtual int change() { return -1; }
00686 
00687         virtual void draw( bool immediate = false )
00688         {
00689             w.bkgdset( A_NORMAL );
00690             w.clear();
00691             SubWin::draw( immediate );
00692         }
00693 
00694         void stat( const Aset & a )
00695         {
00696             static char buf[1024];
00697             int len = w.width() - 2;
00698             chtype ch = a.attr();
00699             w.bkgdset( a.attr() );
00700             w.clear();
00701             w.bkgdset( a.textattr() );
00702             w.box();
00703             w.addstr( 0, 1, a.label.c_str(), len );
00704             sprintf( buf, "%s/%s %c%c%c%c%c%c%c %c%3u",
00705                      dumpColor( NCattribute::fg_color_of( ch ) ),
00706                      dumpColor( NCattribute::bg_color_of( ch ) ),
00707                      ( ch&A_INVIS ?      'i' : '.' ),
00708                      ( ch&A_BOLD ?       'b' : '.' ),
00709                      ( ch&A_DIM ?        'd' : '.' ),
00710                      ( ch&A_BLINK ?      'l' : '.' ),
00711                      ( ch&A_REVERSE ?    'r' : '.' ),
00712                      ( ch&A_UNDERLINE ?  'u' : '.' ),
00713                      ( ch&A_STANDOUT ?   's' : '.' ),
00714                      ( ch&A_ALTCHARSET ? 'A' : '.' ),
00715                      ( unsigned )( ch&A_CHARTEXT )
00716                    );
00717             w.addstr( 1, 1, buf, len );
00718             SubWin::draw( true );
00719         }
00720     };
00721 
00722 
00723     /**
00724      * Wex: popup and down the example Dialog
00725      **/
00726     struct Wex : public SubWin
00727     {
00728         SetType cset;
00729         Wex( std::string T, NCursesWindow & P, int H, int W, int L, int C )
00730                 : SubWin( T, P, H, W, L, C )
00731         {
00732             showex( EX_OFF );
00733         }
00734 
00735         virtual void draw( bool immediate = false )
00736         {
00737             int len = dtag();
00738             w.printw( "%-*.*s", len, len, "Example Dialog" );
00739             SubWin::draw( immediate );
00740         }
00741 
00742         virtual int change()
00743         {
00744             showex( EX_TOGGLE );
00745             return -1;
00746         }
00747     };
00748 
00749 
00750     //
00751     // Construct the panel and widgets
00752     //
00753 
00754     Wstyle  wStyle;
00755     Wset    wSet;
00756     Wchstat wChstat;
00757     Wchattr wChattr;
00758     Wex     wEx;
00759 
00760     NCStyleDef( NCstyle & style )
00761             : NCstyle_C( style )
00762             , p( 19, 30, NCurses::lines() - 19, 1 )
00763             , wStyle( "F1/2", p,  1, 28,  1, 1 )
00764             , wSet( "F3/4", p,  1, 28,  2, 1 )
00765             , wChstat( "",     p,  3, 28,  3, 1 )
00766             , wChattr( "",     p, 11, 28,  6, 1 )
00767             , wEx( "F6",   p,  1, 28, 17, 1 )
00768     {
00769         NCStyleDef_p = this;
00770         pbox();
00771         wStyle.draw();
00772         wSet.draw();
00773         wChstat.draw();
00774         wChattr.draw();
00775         wEx.draw();
00776     }
00777 
00778     ~NCStyleDef() { NCStyleDef_p = 0; }
00779 
00780     void changeStyle();
00781 
00782     void saveStyle();
00783 
00784     // that's the way the chtype is saved to file
00785     std::ostream & dumpChtype( std::ostream & str, const chtype & ch )
00786     {
00787         static chtype mask = A_STANDOUT | A_UNDERLINE | A_REVERSE | A_BLINK | A_DIM | A_BOLD | A_INVIS;
00788         chtype base  = ch & ~mask;
00789         chtype style = ch & mask;
00790 #define PRTIF(S) if ( style & S ) str << "|" << #S
00791         str << base;
00792         PRTIF( A_STANDOUT );
00793         PRTIF( A_UNDERLINE );
00794         PRTIF( A_REVERSE );
00795         PRTIF( A_BLINK );
00796         PRTIF( A_DIM );
00797         PRTIF( A_BOLD );
00798         PRTIF( A_INVIS );
00799 #undef PRTIF
00800         return str;
00801     }
00802 
00803     void restoreStyle();
00804 
00805 
00806     /**
00807      * helper struct to std::map strings to NCstyle enum values
00808      **/
00809     struct lookupIdx
00810     {
00811         NCstyle::STglobal glob;
00812         NCstyle::STlocal  loc;
00813         lookupIdx()                      { glob = NCstyle::MaxSTglobal; loc = NCstyle::MaxSTlocal; }
00814 
00815         lookupIdx( NCstyle::STglobal g ) { glob = g; loc = NCstyle::MaxSTlocal; }
00816 
00817         lookupIdx( NCstyle::STlocal  l ) { glob = NCstyle::MaxSTglobal; loc = l; }
00818 
00819         bool isLoc()     const { return glob == NCstyle::MaxSTglobal && loc != NCstyle::MaxSTlocal; }
00820 
00821         bool isGlob()    const { return glob != NCstyle::MaxSTglobal && loc == NCstyle::MaxSTlocal; }
00822 
00823         bool isUnknown() const { return glob == NCstyle::MaxSTglobal && loc == NCstyle::MaxSTlocal; }
00824 
00825         unsigned     uindex() const { if ( isLoc() ) return loc; return isGlob() ? glob : ( unsigned ) - 1; }
00826 
00827         const char * stat()   const { if ( isLoc() ) return "L"; return isGlob() ? "G"  : "?"; }
00828     };
00829 
00830     void showHelp();
00831 };
00832 
00833 
00834 NCStyleDef * NCStyleDef::NCStyleDef_p = 0;
00835 
00836 
00837 
00838 void NCStyleDef::doshowset( SetType a, bool reset )
00839 {
00840     std::vector<Aset> aset;
00841 
00842     switch ( a )
00843     {
00844 #define PRT(T) aset.push_back( Aset( const_cast<chtype&>( attr( NCstyle::T ) ), #T ) )
00845 
00846         case Global:
00847             PRT( AppTitle );
00848             PRT( AppText );
00849             break;
00850 
00851         case DialogBorder:
00852             PRT( DialogBorder );
00853             PRT( DialogTitle );
00854             break;
00855 
00856         case DialogBorderActive:
00857             PRT( DialogActiveBorder );
00858             PRT( DialogActiveTitle );
00859             break;
00860 
00861         case DialogText:
00862             PRT( DialogText );
00863             PRT( DialogHeadline );
00864             PRT( DialogDisabled );
00865             break;
00866 
00867         case Widget:
00868             PRT( DialogPlain );
00869             PRT( DialogLabel );
00870             PRT( DialogData );
00871             PRT( DialogHint );
00872             PRT( DialogScrl );
00873             break;
00874 
00875         case WidgetActive:
00876             PRT( DialogActivePlain );
00877             PRT( DialogActiveLabel );
00878             PRT( DialogActiveData );
00879             PRT( DialogActiveHint );
00880             PRT( DialogActiveScrl );
00881             break;
00882 
00883         case FrameWidget:
00884             PRT( DialogFramePlain );
00885             PRT( DialogFrameLabel );
00886             PRT( DialogFrameData );
00887             PRT( DialogFrameHint );
00888             PRT( DialogFrameScrl );
00889             break;
00890 
00891         case FrameWidgetActive:
00892             PRT( DialogActiveFramePlain );
00893             PRT( DialogActiveFrameLabel );
00894             PRT( DialogActiveFrameData );
00895             PRT( DialogActiveFrameHint );
00896             PRT( DialogActiveFrameScrl );
00897             break;
00898 
00899         case List:
00900             PRT( ListTitle );
00901             PRT( ListPlain );
00902             PRT( ListLabel );
00903             PRT( ListData );
00904             PRT( ListHint );
00905             PRT( ListSelPlain );
00906             PRT( ListSelLabel );
00907             PRT( ListSelData );
00908             PRT( ListSelHint );
00909             break;
00910 
00911         case ListActive:
00912             PRT( ListActiveTitle );
00913             PRT( ListActivePlain );
00914             PRT( ListActiveLabel );
00915             PRT( ListActiveData );
00916             PRT( ListActiveHint );
00917             PRT( ListActiveSelPlain );
00918             PRT( ListActiveSelLabel );
00919             PRT( ListActiveSelData );
00920             PRT( ListActiveSelHint );
00921             break;
00922 
00923         case RichText:
00924             PRT( RichTextPlain );
00925             PRT( RichTextTitle );
00926             PRT( RichTextLink );
00927             PRT( RichTextArmedlink );
00928             PRT( RichTextActiveArmedlink );
00929             PRT( RichTextVisitedLink );
00930             PRT( RichTextB );
00931             PRT( RichTextI );
00932             PRT( RichTextT );
00933             PRT( RichTextBI );
00934             PRT( RichTextBT );
00935             PRT( RichTextIT );
00936             PRT( RichTextBIT );
00937             break;
00938 
00939         case ProgressBar:
00940             PRT( ProgbarCh );
00941             PRT( ProgbarBgch );
00942             PRT( TextCursor );
00943             break;
00944 
00945         case MaxSetType:
00946             break;
00947 #undef PRT
00948     }
00949 
00950     wChattr.set( aset, reset );
00951 }
00952 
00953 
00954 
00955 void NCStyleDef::pbox( bool on )
00956 {
00957     p.bkgdset( A_NORMAL );
00958     p.box();
00959 
00960     if ( on )
00961     {
00962         p.bkgdset( A_REVERSE );
00963         p.addstr( 0, 1, "<ENTER> done " );
00964     }
00965     else
00966         p.addstr( 0, 1, "<F5> move pad " );
00967 
00968     p.bkgdset( A_NORMAL );
00969 }
00970 
00971 
00972 
00973 int NCStyleDef::movePad( int key )
00974 {
00975     pbox( true );
00976     p.show();
00977 
00978     bool continue_bi = true;
00979     int in = -1;
00980 
00981     do
00982     {
00983         refresh();
00984 
00985         if ( key == -1 )
00986             in = getch();
00987         else
00988             in = key;
00989 
00990         switch ( in )
00991         {
00992             case KEY_UP:
00993 
00994                 if ( p.begy() > 0 )
00995                 {
00996                     p.mvwin( p.begy() - 1, p.begx() );
00997                 }
00998                 break;
00999 
01000             case KEY_DOWN:
01001 
01002                 if ( p.begy() + p.height() < NCurses::lines() )
01003                 {
01004                     p.mvwin( p.begy() + 1, p.begx() );
01005                 }
01006                 break;
01007 
01008             case KEY_LEFT:
01009 
01010                 if ( p.begx() > 0 )
01011                 {
01012                     p.mvwin( p.begy(), p.begx() - 1 );
01013                 }
01014                 break;
01015 
01016             case KEY_RIGHT:
01017 
01018                 if ( p.begx() + p.width() < NCurses::cols() )
01019                 {
01020                     p.mvwin( p.begy(), p.begx() + 1 );
01021                 }
01022                 break;
01023 
01024             case -1:
01025             case KEY_ESC:
01026             case KEY_TAB:
01027             case KEY_RETURN:
01028             case KEY_F( 1 ):
01029             case KEY_F( 2 ):
01030             case KEY_F( 3 ):
01031             case KEY_F( 4 ):
01032             case KEY_F( 5 ):
01033             case KEY_F( 6 ):
01034             case KEY_F( 7 ):
01035             case KEY_F( 8 ):
01036             case KEY_F( 9 ):
01037             case KEY_F( 10 ):
01038                 continue_bi = false;
01039                 break;
01040         }
01041 
01042     }
01043     while ( continue_bi && key == -1 );
01044 
01045     pbox( false );
01046 
01047     if ( key != -1 )
01048         in = -1;
01049 
01050     return in;
01051 }
01052 
01053 
01054 
01055 void NCStyleDef::changeStyle()
01056 {
01057     fakestyle( wStyle.cset );
01058     p.show();
01059 
01060     bool continue_bi = true;
01061     int in   = -1;
01062     int rein =  1;
01063 
01064     do
01065     {
01066         refresh();
01067 
01068         if ( rein != -2 )
01069         {
01070             in = rein;
01071             rein = -1;
01072         }
01073         else
01074         {
01075             in = getch();
01076         }
01077 
01078         switch ( in )
01079         {
01080             case KEY_F( 1 ):
01081                 wStyle.handle( KEY_UP );
01082                 break;
01083 
01084             case KEY_F( 2 ):
01085                 wStyle.handle( KEY_DOWN );
01086                 break;
01087 
01088             case KEY_F( 3 ):
01089                 wSet.handle( KEY_UP );
01090                 break;
01091 
01092             case KEY_F( 4 ):
01093                 wSet.handle( KEY_DOWN );
01094                 break;
01095 
01096             case KEY_F( 5 ):
01097                 rein = movePad();
01098                 break;
01099 
01100             case KEY_F( 6 ):
01101                 rein = wEx.change();
01102                 break;
01103 
01104             case KEY_F( 8 ):
01105                 restoreStyle();
01106                 break;
01107 
01108             case KEY_F( 9 ):
01109                 saveStyle();
01110                 break;
01111 
01112             case KEY_ESC:
01113             case KEY_F( 10 ):
01114                 continue_bi = false;
01115                 break;
01116 
01117             default:
01118                 rein = wChattr.change();
01119                 break;
01120         }
01121     }
01122     while ( continue_bi );
01123 
01124     p.hide();
01125 
01126     p.refresh();
01127 
01128     fakestyle( NCstyle::MaxStyleSet );
01129 }
01130 
01131 
01132 
01133 // query popup for ACS chars
01134 chtype NCStyleDef::queryChar( int column, chtype selbg )
01135 {
01136     std::vector<queryCharEnt> men;
01137     men.push_back( queryCharEnt( "NO CHAR", ' ' ) );
01138     men.push_back( queryCharEnt( "BLANK", ' ' ) );
01139 #define PUT(a) men.push_back( queryCharEnt( #a, a ) );
01140     PUT( ACS_CKBOARD );
01141     PUT( ACS_BOARD );
01142     PUT( ACS_BLOCK );
01143     PUT( ACS_DIAMOND );
01144     PUT( ACS_BULLET );
01145     PUT( ACS_DEGREE );
01146     PUT( ACS_PLMINUS );
01147     PUT( ACS_LEQUAL );
01148     PUT( ACS_GEQUAL );
01149     PUT( ACS_NEQUAL );
01150     PUT( ACS_S1 );
01151     PUT( ACS_S3 );
01152     PUT( ACS_S7 );
01153     PUT( ACS_S9 );
01154     PUT( ACS_PI );
01155     PUT( ACS_LANTERN );
01156     PUT( ACS_STERLING );
01157     PUT( ACS_LARROW );
01158     PUT( ACS_RARROW );
01159     PUT( ACS_DARROW );
01160     PUT( ACS_UARROW );
01161     PUT( ACS_ULCORNER );
01162     PUT( ACS_URCORNER );
01163     PUT( ACS_LLCORNER );
01164     PUT( ACS_LRCORNER );
01165     PUT( ACS_VLINE );
01166     PUT( ACS_LTEE );
01167     PUT( ACS_RTEE );
01168     PUT( ACS_BTEE );
01169     PUT( ACS_TTEE );
01170     PUT( ACS_HLINE );
01171     PUT( ACS_PLUS );
01172 #undef PUT
01173 
01174     chtype defbg = A_NORMAL;
01175     unsigned lrow = men.size() - men.size() / 2;
01176 
01177     NCursesPanel popup( lrow + 2, 39, 1, 1 );
01178     popup.bkgd( defbg );
01179     popup.box();
01180 
01181     popup.show();
01182     chtype   ret = ( chtype ) - 1;
01183     unsigned idx = 0;
01184     int      in  = -1;
01185 
01186     do
01187     {
01188         int l = 1;
01189         int c = 1;
01190         int len = 13;
01191 
01192         for ( unsigned i = 0; i < men.size(); ++i, ++l )
01193         {
01194             if ( i == lrow )
01195             {
01196                 c += len + 6;
01197                 l = 1;
01198             }
01199 
01200             popup.bkgdset( defbg );
01201 
01202             popup.addstr( l, c, ( i == idx ? "->" : "  " ) );
01203             popup.bkgdset( i == idx ? selbg : defbg );
01204             popup.addch( ' ' );
01205             popup.addch( men[i].c );
01206             popup.printw( " %-*.*s", len, len, men[i].l.c_str() );
01207         }
01208 
01209         popup.refresh();
01210 
01211         switch ( ( in = getch() ) )
01212         {
01213 
01214             case KEY_UP:
01215 
01216                 if ( idx )
01217                     --idx;
01218                 break;
01219 
01220             case KEY_DOWN:
01221 
01222                 if ( idx + 1 < men.size() )
01223                     ++idx;
01224                 break;
01225 
01226             case KEY_RETURN:
01227                 ret = idx ? men[idx].c : 0;
01228 
01229             case KEY_ESC:
01230                 in = -1;
01231 
01232                 break;
01233         }
01234     }
01235     while ( in != -1 );
01236 
01237     popup.hide();
01238     popup.refresh();
01239 
01240     return ret;
01241 }
01242 
01243 
01244 #define BGSET(a) W.bkgdset( st.a )
01245 
01246 static int hi = 4;
01247 static int wi = 15;
01248 
01249 
01250 inline void frame( NCursesWindow & w, int l, int c, int H = 0, int W = 0 )
01251 {
01252     if ( !H )
01253         H = hi;
01254 
01255     if ( !W )
01256         W = wi;
01257 
01258     w.vline( l, c, H );
01259     w.vline( l, c + W, H );
01260     w.hline( l, c, W );
01261     w.hline( l + H, c, W );
01262 
01263     w.addch( l, c, ACS_ULCORNER );
01264     w.addch( l + H, c, ACS_LLCORNER );
01265     w.addch( l, c + W, ACS_URCORNER );
01266     w.addch( l + H, c + W, ACS_LRCORNER );
01267 }
01268 
01269 
01270 inline void laex( NCursesWindow & W, const char * T, NCstyle::StItem st )
01271 {
01272     BGSET( hint );
01273     W.addch( *T );
01274     BGSET( label );
01275     W.addstr( T + 1 );
01276 }
01277 
01278 
01279 inline void itex( NCursesWindow & W, const char * T, NCstyle::StItem st )
01280 {
01281     BGSET( plain );
01282     W.addstr( "(" );
01283     BGSET( data );
01284     W.addstr( "X" );
01285     BGSET( plain );
01286     W.addstr( ") " );
01287     laex( W, T, st );
01288 }
01289 
01290 
01291 inline void butex( NCursesWindow & W, int L, int C, const char * T, NCstyle::StWidget st )
01292 {
01293     W.move( L, C );
01294     itex( W, T, st );
01295     BGSET( scrl );
01296     W.addch( ACS_DARROW );
01297 }
01298 
01299 
01300 inline void frameex( NCursesWindow & W, int L, int C, const char * T, NCstyle::StWidget st )
01301 {
01302     BGSET( plain );
01303     frame( W, L, C );
01304     W.move( L, C + 1 );
01305     laex( W, T, st );
01306     BGSET( scrl );
01307     W.addch( L + hi, C + 1, ACS_LTEE );
01308     W.addch( ACS_HLINE );
01309     W.addch( ACS_RTEE );
01310     W.addch( L + 1, C + wi, ACS_TTEE );
01311     W.addch( L + 2, C + wi, ACS_BTEE );
01312 }
01313 
01314 
01315 inline void listex( NCursesWindow & W, int L, int C, NCstyle::StList st )
01316 {
01317     BGSET( title );
01318     W.printw( L, C, "%-*s", wi - 1, "Title" );
01319     ++L;
01320     BGSET( item.plain );
01321     W.printw( L, C, "%-*s", wi - 1, "" );
01322     W.move( L, C );
01323     itex( W, "Item", st.item );
01324     ++L;
01325     BGSET( selected.plain );
01326     W.printw( L, C, "%-*s", wi - 1, "" );
01327     W.move( L, C );
01328     itex( W, "Selected", st.selected );
01329 }
01330 
01331 
01332 inline void widex( NCursesWindow & W, int L, int C, const char * T,
01333                    NCstyle::StWidget w, NCstyle::StWidget f, NCstyle::StList l )
01334 {
01335     butex( W, L, C, T, w );
01336     L += 2;
01337     frameex( W, L, C, T, f );
01338     L += 1;
01339     listex( W, L, C + 1, l );
01340 }
01341 
01342 
01343 
01344 void NCStyleDef::showex( ExMode mode )
01345 {
01346     static NCursesPanel W( 14, NCurses::cols(), 0, 0 );
01347 
01348     if ( mode == EX_TOGGLE )
01349         mode = W.hidden() ? EX_ON : EX_OFF;
01350 
01351     if ( mode == EX_OFF )
01352     {
01353         if ( !W.hidden() )
01354         {
01355             W.hide();
01356             W.refresh();
01357         }
01358 
01359         return;
01360     }
01361 
01362     if ( mode == EX_ON && W.hidden() )
01363     {
01364         W.show();
01365     }
01366 
01367     if ( W.hidden() )
01368         return;
01369 
01370     const NCstyle::Style & st( NCStyleDef_p->NCstyle_C.getStyle( NCStyleDef_p->NCstyle_C.fakestyle_e ) );
01371 
01372     BGSET( dumb.text );
01373     W.clear();
01374     BGSET( border.text );
01375     W.box();
01376     BGSET( border.title );
01377     W.addstr( 0, 1, "normal dialog" );
01378     int l = 1;
01379     int c = 1;
01380     BGSET( activeBorder.text );
01381     frame( W, l, c, W.height() - 2, W.width() - 2 );
01382     BGSET( activeBorder.title );
01383     W.addstr( l, c + 1, "active dialog" );
01384     l = 3;
01385     c = 3;
01386     BGSET( dumb.title );
01387     W.addstr( l, c, "Heading" );
01388     BGSET( dumb.text );
01389     frame( W, l + 2, c );
01390     W.addstr( l + 2, c + 1, "Frame" );
01391     W.addstr( l + 4, c + 1, "Some text" );
01392     c += 20;
01393     widex( W, l, c, "Disabled", st.disabled, st.disabled, st.disabledList );
01394     c += 20;
01395     widex( W, l, c, "Normal", st.normal, st.frame, st.list );
01396     c += 20;
01397     widex( W, l, c, "Active", st.active, st.activeFrame, st.activeList );
01398     l += hi + 4;
01399     c = 3;
01400     BGSET( progbar.bar.chattr );
01401     W.addstr( l, c, "      " );
01402     BGSET( progbar.bar.getNonChar() );
01403     W.addstr( "50" );
01404     BGSET( progbar.nonbar.getNonChar() );
01405     W.addstr( "%" );
01406     BGSET( progbar.nonbar.chattr );
01407     W.addstr( "       " );
01408     W.refresh();
01409 }
01410 
01411 
01412 void NCStyleDef::saveStyle()
01413 {
01414     std::string fname( "NCstyle." + NCstyle_C.styleName + ".h" );
01415     std::string hname( "NCstyle_" + NCstyle_C.styleName + "_h" );
01416     std::string fpath( "/tmp/" );
01417     fpath += fname;
01418 
01419     std::ofstream out( fpath.c_str(), std::ios::out );
01420     NCursesPanel  p( 5, NCurses::cols() - 4, ( NCurses::lines() - 5 ) / 2, 2 );
01421     int pl = p.height() / 2;
01422     p.box();
01423 
01424     if ( !out.good() )
01425     {
01426         p.bkgd( NCattribute::color_pair( COLOR_WHITE, COLOR_RED ) );
01427         p.printw( pl, 2, "Can't open output file \"%s\"!", fpath.c_str() );
01428         p.show();
01429         p.refresh();
01430         getch();
01431         p.hide();
01432         p.refresh();
01433         return;
01434     }
01435 
01436     p.bkgd( NCattribute::color_pair( COLOR_CYAN, COLOR_BLACK ) );
01437 
01438     p.printw( pl, 2, "Saving style \"%s\" in \"%s\" ...", NCstyle_C.styleName.c_str(), fpath.c_str() );
01439     p.show();
01440     p.refresh();
01441 
01442     out << "/*" << std::endl;
01443     out << "  Copyright (C) 2000-2012 Novell, Inc" << std::endl;
01444     out << "  This library is free software; you can redistribute it and/or modify" << std::endl;
01445     out << "  it under the terms of the GNU Lesser General Public License as" << std::endl;
01446     out << "  published by the Free Software Foundation; either version 2.1 of the" << std::endl;
01447     out << "  License, or (at your option) version 3.0 of the License. This library" << std::endl;
01448     out << "  is distributed in the hope that it will be useful, but WITHOUT ANY" << std::endl;
01449     out << "  WARRANTY; without even the implied warranty of MERCHANTABILITY or" << std::endl;
01450     out << "  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public" << std::endl;
01451     out << "  License for more details. You should have received a copy of the GNU" << std::endl;
01452     out << "  Lesser General Public License along with this library; if not, write" << std::endl;
01453     out << "  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth" << std::endl;
01454     out << "  Floor, Boston, MA 02110-1301 USA" << std::endl;
01455     out << "*/" << std::endl;
01456     out << std::endl;
01457     out << std::endl;
01458     out << "/*-/" << std::endl;
01459     out << std::endl;
01460     out << "   File:       " << fname << std::endl;
01461     out << std::endl;
01462     out << "   Author:     Generated by class NCstyle" << std::endl;
01463     out << std::endl;
01464     out << "/-*/" << std::endl;
01465     out << "#ifndef " << hname << std::endl;
01466     out << "#define " << hname << std::endl;
01467     out << "" << std::endl;
01468     out << "#include \"NCstyle.h\"" << std::endl;
01469     out << "" << std::endl;
01470     out << "inline void NCstyleInit_" << NCstyle_C.styleName << "( std::vector<NCstyle::Style> & styleSet )" << std::endl;
01471     out << "{" << std::endl;
01472 
01473     out << "  //=================================================================" << std::endl;
01474     out << "  // init global attributes" << std::endl;
01475     out << "  //=================================================================" << std::endl;
01476     out << "  NCattrset * attrset( &styleSet[NCstyle::" << NCstyle::dumpName( NCstyle::DefaultStyle ) << "].getAttrGlobal() );" << std::endl;
01477 
01478     for ( NCstyle::STglobal a = ( NCstyle::STglobal )0; a < NCstyle::MaxSTglobal; a = ( NCstyle::STglobal )( a + 1 ) )
01479     {
01480         out << "  attrset->setAttr( NCstyle::"
01481         << NCstyle::dumpName( a )
01482         << ", ";
01483         dumpChtype( out, NCstyle_C( a ) )
01484         << " );" << std::endl;
01485     }
01486 
01487     out << "  //=================================================================" << std::endl;
01488     out << "  // init local attributes" << std::endl;
01489     out << "  //=================================================================" << std::endl;
01490 
01491     for ( NCstyle::StyleSet sts = ( NCstyle::StyleSet )0; sts < NCstyle::MaxStyleSet; sts = ( NCstyle::StyleSet )( sts + 1 ) )
01492     {
01493         out << "  // " << NCstyle::dumpName( sts ) << std::endl;
01494         out << "  attrset = &styleSet[NCstyle::" << NCstyle::dumpName( sts ) << "].getAttrLocal();"  << std::endl;
01495 
01496         for ( NCstyle::STlocal a = ( NCstyle::STlocal )0; a < NCstyle::MaxSTlocal; a = ( NCstyle::STlocal )( a + 1 ) )
01497         {
01498             out << "  attrset->setAttr( NCstyle::"
01499             << NCstyle::dumpName( a )
01500             << ", ";
01501             dumpChtype( out, NCstyle_C.styleSet[sts]( a ) )
01502             << " );" << std::endl;
01503         }
01504     }
01505 
01506     out << "}" << std::endl;
01507     out << "#endif // " << hname << std::endl;
01508     out.close();
01509 
01510     if ( ! out.good() )
01511     {
01512         p.bkgd( NCattribute::color_pair( COLOR_WHITE, COLOR_RED ) );
01513         p.printw( " FAILED!" );
01514     }
01515     else
01516     {
01517         p.printw( " DONE!" );
01518 
01519     }
01520 
01521     p.show();
01522 
01523     p.refresh();
01524     getch();
01525     p.hide();
01526     p.refresh();
01527 }
01528 
01529 
01530 void NCStyleDef::restoreStyle()
01531 {
01532     std::string fname( "NCstyle." + NCstyle_C.styleName + ".h" );
01533     std::string fpath( "/tmp/" );
01534     fpath += fname;
01535 
01536     std::ifstream inp( fpath.c_str(), std::ios::in );
01537     int ph = 5;
01538     NCursesPanel  p( ph, NCurses::cols() - 4, ( NCurses::lines() - ph ) / 2, 2 );
01539     int pl = 2;
01540     p.box();
01541 
01542     if ( !inp.good() )
01543     {
01544         p.bkgd( NCattribute::color_pair( COLOR_WHITE, COLOR_RED ) );
01545         p.printw( pl, 2, "Can't open input file \"%s\"!", fpath.c_str() );
01546         p.show();
01547         p.refresh();
01548         getch();
01549         p.hide();
01550         p.refresh();
01551         return;
01552     }
01553 
01554     p.bkgd( NCattribute::color_pair( COLOR_CYAN, COLOR_BLACK ) );
01555 
01556     p.printw( pl, 2, "Reding style \"%s\" from \"%s\" ...", NCstyle_C.styleName.c_str(), fpath.c_str() );
01557     p.show();
01558     p.refresh();
01559 
01560     std::list<std::string> data_vec[NCstyle::MaxStyleSet+1];
01561     NCstyle::StyleSet cvec = NCstyle::MaxStyleSet;
01562 
01563     std::string initfnc_ti( "inline void NCstyleInit_" );
01564     initfnc_ti += NCstyle_C.styleName + "(";
01565     std::string attrdef( "  attrset->setAttr( NCstyle::" );
01566     std::string stydef( "  attrset = &styleSet[NCstyle::" );
01567 
01568     enum STATE { PRE, ONFNC, IN, POST, ERROR };
01569     STATE psaw = PRE;
01570 
01571     std::string line( "" );
01572     unsigned    lineno = 0;
01573 
01574     while ( inp.good() && psaw != POST && psaw != ERROR )
01575     {
01576         char c;
01577         line = "";
01578 
01579         while ( inp.get( c ), inp.good() && c != '\n' )
01580             line += c;
01581 
01582         {
01583             ++lineno;
01584             // consume
01585 
01586             switch ( psaw )
01587             {
01588                 case PRE:
01589 
01590                     if ( line.find( initfnc_ti ) == 0 )
01591                         psaw = ONFNC;
01592 
01593                     break;
01594 
01595                 case ONFNC:
01596                     if ( line == "{" || line.find( "  //" ) == 0 )
01597                         break;
01598 
01599                     if ( line == "  NCattrset * attrset( &styleSet[NCstyle::DefaultStyle].getAttrGlobal() );" )
01600                     {
01601                         psaw = IN;
01602                         cvec = NCstyle::MaxStyleSet;
01603                         //p.printw( "[GLOBAL]" );
01604                         //p.show();
01605                         //p.refresh();
01606                     }
01607                     else
01608                         psaw = ERROR;
01609 
01610                     break;
01611 
01612                 case IN:
01613                     if ( line == "}" )
01614                     {
01615                         psaw = POST;
01616                         break;
01617                     }
01618 
01619                     if ( line.find( "  //" ) == 0 )
01620                         break;
01621 
01622                     if ( line.find( attrdef ) == 0 )
01623                     {
01624                         data_vec[cvec].push_back( line.substr( attrdef.size() ) );
01625                         //p.printw( "." );
01626                     }
01627                     else if ( line.find( stydef ) == 0 )
01628                     {
01629                         line.erase( 0, stydef.size() );
01630 
01631                         if ( line.find( "DefaultStyle]" ) == 0 )
01632                         {
01633                             cvec = NCstyle::DefaultStyle;
01634                             //p.printw( "[DefaultStyle]" );
01635                         }
01636                         else if ( line.find( "InfoStyle]" ) == 0 )
01637                         {
01638                             cvec = NCstyle::InfoStyle;
01639                             //p.printw( "[InfoStyle]" );
01640                         }
01641                         else if ( line.find( "WarnStyle]" ) == 0 )
01642                         {
01643                             cvec = NCstyle::WarnStyle;
01644                             //p.printw( "[WarnStyle]" );
01645                         }
01646                         else if ( line.find( "PopupStyle]" ) == 0 )
01647                         {
01648                             cvec = NCstyle::PopupStyle;
01649                             //p.printw( "[PopupStyle]" );
01650                         }
01651                         else
01652                         {
01653                             psaw = ERROR;
01654                         }
01655 
01656                         p.show();
01657 
01658                         p.refresh();
01659                     }
01660                     else
01661                     {
01662                         psaw = ERROR;
01663                     }
01664 
01665                     break;
01666 
01667                 case ERROR:
01668 
01669                 case POST:
01670                     break;
01671             }
01672         }
01673     }
01674 
01675     if ( psaw != POST )
01676     {
01677         p.bkgd( NCattribute::color_pair( COLOR_WHITE, COLOR_RED ) );
01678         p.printw( " FAILED stage %d!\n[%d]>>%s<<", psaw, lineno, line.c_str() );
01679         p.show();
01680         p.refresh();
01681         getch();
01682         p.hide();
01683         p.refresh();
01684         return;
01685     }
01686 
01687     inp.close();
01688 
01689     // parse data
01690 
01691     std::vector<NCattrset> attr_vec;
01692 
01693     for ( cvec = ( NCstyle::StyleSet )0; cvec <= NCstyle::MaxStyleSet; cvec = ( NCstyle::StyleSet )( cvec + 1 ) )
01694     {
01695         attr_vec.push_back( cvec == NCstyle::MaxStyleSet ? NCattrset( NCstyle::MaxSTglobal ) : NCattrset( NCstyle::MaxSTlocal ) );
01696     }
01697 
01698     std::map<std::string, lookupIdx> lookupmap;
01699 
01700     for ( NCstyle::STglobal a = ( NCstyle::STglobal )0; a < NCstyle::MaxSTglobal; a = ( NCstyle::STglobal )( a + 1 ) )
01701     {
01702         std::map<std::string, lookupIdx>::value_type v( NCstyle::dumpName( a ), lookupIdx( a ) );
01703         lookupmap.insert( v );
01704     }
01705 
01706     for ( NCstyle::STlocal a = ( NCstyle::STlocal )0; a < NCstyle::MaxSTlocal; a = ( NCstyle::STlocal )( a + 1 ) )
01707     {
01708         std::map<std::string, lookupIdx>::value_type v( NCstyle::dumpName( a ), lookupIdx( a ) );
01709         lookupmap.insert( v );
01710     }
01711 
01712     //p.printw( "\n[PARSE]" );
01713     //p.show();
01714     //p.refresh();
01715 
01716     // globals first
01717     for ( cvec = ( NCstyle::StyleSet )( NCstyle::MaxStyleSet + 1 ); cvec > 0; )
01718     {
01719         cvec = ( NCstyle::StyleSet )( cvec - 1 );
01720         //p.printw( "[%s]", NCstyle::dumpName( cvec ).c_str() );
01721         //p.show();
01722         //p.refresh();
01723 
01724         for ( std::list<std::string>::iterator i = data_vec[cvec].begin(); i != data_vec[cvec].end(); ++i )
01725         {
01726             std::string::size_type sep = i->find( ", " );
01727 
01728             if ( sep != std::string::npos )
01729             {
01730                 std::string id( i->substr( 0, sep ) );
01731                 std::string val( i->substr( sep + 2 ) );
01732                 sep = val.find( " " );
01733 
01734                 if ( sep != std::string::npos )
01735                 {
01736                     val.erase( sep );
01737                 }
01738 
01739                 std::map<std::string, lookupIdx>::const_iterator ldat = lookupmap.find( id );
01740 
01741                 if ( ldat == lookupmap.end() || ldat->second.isUnknown() )
01742                 {
01743                     p.printw( "{UNKNOWN:%s=%s}", id.c_str(), val.c_str() );
01744                     p.show();
01745                     p.refresh();
01746                 }
01747                 else
01748                 {
01749                     chtype ch = atoi( val.c_str() );
01750                     sep = val.find( "|" );
01751 
01752                     if ( sep != std::string::npos )
01753                     {
01754                         val.erase( 0, sep + 1 );
01755 
01756                         while ( val.size() )
01757                         {
01758                             sep = val.find( "|" );
01759                             std::string tt = val.substr( 0, sep );
01760 #define IFASSIGN(T) if ( tt == #T ) ch |= T
01761                             IFASSIGN( A_STANDOUT );
01762                             else IFASSIGN( A_UNDERLINE );
01763                             else IFASSIGN( A_REVERSE );
01764                             else IFASSIGN( A_BLINK );
01765                             else IFASSIGN( A_DIM );
01766                             else IFASSIGN( A_BOLD );
01767                             else IFASSIGN( A_INVIS );
01768 
01769 #undef IFASSIGN
01770                             val.erase( 0, ( sep != std::string::npos ) ? sep + 1 : sep );
01771                         }
01772                     }
01773 
01774                     // ready to assign
01775                     if ( ldat->second.isLoc() )
01776                     {
01777                         // actual value is local
01778                         if ( cvec == NCstyle::MaxStyleSet )
01779                         {
01780                             // global data parsed
01781                             for ( unsigned ii = 0; ii < NCstyle::MaxStyleSet; ++ii )
01782                             {
01783                                 attr_vec[ii].setAttr( ldat->second.uindex(), ch );
01784                             }
01785                         }
01786                         else
01787                         {
01788                             // local data parsed
01789                             attr_vec[cvec].setAttr( ldat->second.uindex(), ch );
01790                         }
01791 
01792                         attr_vec[cvec].setAttr( ldat->second.uindex(), ch );
01793                     }
01794                     else if ( ldat->second.isGlob() )
01795                     {
01796                         // actual value is global
01797                         attr_vec[NCstyle::MaxStyleSet].setAttr( ldat->second.uindex(), ch );
01798                     }
01799                 }
01800 
01801                 //p.printw( "." );
01802                 //p.show();
01803                 //p.refresh();
01804             }
01805             else
01806             {
01807                 p.printw( "{NOVAL:%s}", i->c_str() );
01808                 p.show();
01809                 p.refresh();
01810             }
01811         }
01812     }
01813 
01814     // apply
01815     cvec = ( NCstyle::StyleSet )0;
01816 
01817     NCstyle_C.getStyle( cvec ).getAttrGlobal() = attr_vec[NCstyle::MaxStyleSet];
01818 
01819     for ( ; cvec < NCstyle::MaxStyleSet; cvec = ( NCstyle::StyleSet )( cvec + 1 ) )
01820     {
01821         NCstyle_C.getStyle( cvec ).getAttrLocal() = attr_vec[cvec];
01822     }
01823 
01824     attrchanged();
01825 
01826     // finish
01827     p.printw( " DONE!" );
01828     p.show();
01829     p.refresh();
01830     getch();
01831     p.hide();
01832     p.refresh();
01833 }
01834 
01835 
01836 void NCDefineStyle( NCstyle & style )
01837 {
01838     static NCStyleDef cstyle( style );
01839     cstyle.changeStyle();
01840 }
 All Classes Functions Variables