PLearn 0.1
viewVMat.cc
Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 // vmatmain.cc
00004 // Copyright (C) 2002 Pascal Vincent, Julien Keable, Xavier Saint-Mleux, Rejean Ducharme
00005 //
00006 // Redistribution and use in source and binary forms, with or without
00007 // modification, are permitted provided that the following conditions are met:
00008 //
00009 //  1. Redistributions of source code must retain the above copyright
00010 //     notice, this list of conditions and the following disclaimer.
00011 //
00012 //  2. Redistributions in binary form must reproduce the above copyright
00013 //     notice, this list of conditions and the following disclaimer in the
00014 //     documentation and/or other materials provided with the distribution.
00015 //
00016 //  3. The name of the authors may not be used to endorse or promote
00017 //     products derived from this software without specific prior written
00018 //     permission.
00019 //
00020 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
00021 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00022 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
00023 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00024 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
00025 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00026 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00027 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00028 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00029 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00030 //
00031 // This file is part of the PLearn library. For more information on the PLearn
00032 // library, go to the PLearn Web site at www.plearn.org
00033 
00034 /* *******************************************************
00035  * $Id: vmatmain.cc 6316 2006-10-16 23:22:54Z lamblin $
00036  ******************************************************* */
00037 
00038 #include "viewVMat.h"
00039 #include <algorithm>                         // for max
00040 #include <plearn/base/general.h>
00041 #include <plearn/base/stringutils.h>
00042 #include <plearn/vmat/ConcatColumnsVMatrix.h>
00043 #include <plearn/vmat/SortRowsVMatrix.h>
00044 #include <plearn/vmat/SubVMatrix.h>
00045 #include <plearn/db/getDataSet.h>
00046 
00047 #if defined(WIN32) && !defined(__CYGWIN__)
00048 // There does not seem to be a Windows implementation of 'ncurses', thus we
00049 // use 'pdcurses' instead.
00050 #include <pdcurses/curses.h>
00051 #else
00052 #include "curses.h"
00053 #endif
00054 
00055 // Some of the above 'curses.h' includes may define those annoying macros,
00056 // which would conflict with the code that follows.
00057 #ifdef min
00058 #undef min
00059 #endif
00060 #ifdef max
00061 #undef max
00062 #endif
00063 #ifdef clear
00064 #undef clear
00065 #endif
00066 
00067 namespace PLearn {
00068 using namespace std;
00069 
00070 
00071 // returns false if the input is invalid and write in strReason the reason
00072 bool getList(char* str, int curj, const VMat& vm, Vec& outList,
00073              char* strReason)
00074 {
00075     vector<string>columnList;
00076     if (str[0] == '\0')
00077     {
00078         // nothing was inserted, then gets the current column
00079         char strj[10];
00080         sprintf(strj, "%d", curj);
00081         columnList.push_back(strj);
00082     }
00083     else
00084     {
00085         columnList = split(str, " -,", true);
00086     }
00087 
00088     vector<string>::iterator vsIt;
00089 
00090     // checks for errors
00091     bool invalidInput = false;
00092     int colVal = 0;
00093     char separator = 0;
00094 
00095     for (vsIt = columnList.begin(); vsIt != columnList.end(); vsIt++)
00096     {
00097         if (pl_isnumber(*vsIt))
00098         {
00099             if (colVal > toint(*vsIt) && separator == '-')
00100             {
00101                 invalidInput = true;
00102                 strcpy(strReason,
00103                        "Second element in range smaller than the first");
00104                 break;
00105             }
00106             colVal = toint(*vsIt);
00107             if (colVal < 0 || colVal >= vm->width())
00108             {
00109                 invalidInput = true;
00110                 strcpy(strReason, "Invalid column number");
00111                 break;
00112             }
00113         }
00114         else
00115         {
00116             // there was already a separator!
00117             if (separator == '-')
00118             {
00119                 invalidInput = true;
00120                 strcpy(strReason, "Too many '-' separators");
00121                 break;
00122             }
00123 
00124             separator = (*vsIt)[0];
00125             if (separator != '-' &&
00126                 separator != ',')
00127             {
00128                 invalidInput = true;
00129                 strcpy(strReason, "Invalid column separator");
00130                 break;
00131             }
00132         }
00133     }
00134 
00135     outList.clear();
00136     if (separator == '-')
00137     {
00138         int start = toint(columnList.front());
00139         int end = toint(columnList.back());
00140         for (int colIdx = start; colIdx <= end; ++colIdx)
00141             outList.push_back(colIdx);
00142     }
00143     else if (separator == ',')
00144     {
00145         for (vsIt = columnList.begin(); vsIt != columnList.end(); ++vsIt)
00146         {
00147             if (pl_isnumber(*vsIt))
00148                 outList.push_back(toint(*vsIt));
00149         }
00150     }
00151     else if (separator == 0)
00152     {
00153         outList.push_back(toint(columnList.front()));
00154     }
00155 
00156     return invalidInput;
00157 }
00158 
00159 void viewVMat(const VMat& vm, PPath filename)
00160 {
00161     initscr();
00162     cbreak();
00163     noecho();
00164     keypad(stdscr,TRUE);
00165 
00166     VMat vm_showed = vm;
00167 
00168     int key = 0;
00169     bool view_strings = true;
00170     // If 'indent_strings_left' is set to false, then strings will be indented
00171     // to the right.
00172     bool indent_strings_left = true;
00179     int hide_sameval = 0;
00180     bool transposed = false;
00181 
00184     bool display_filename = false;
00185     int namewidth = 0;
00186     for(int j=0; j<vm->width(); j++)
00187         namewidth = max(namewidth, (int) vm->fieldName(j).size());
00188     int namewidth_ = namewidth;
00189 
00190     int valwidth = 15;
00191     int valstrwidth = valwidth-1;
00192 
00193     const char* valstrformat = "%14s";
00194 
00195     int curi = 0;
00196     int curj = 0;
00197     int starti = 0;
00198     int startj = 0;
00199 
00200     int vStartHelp = 0;
00201 
00202     bool onError=false;
00203 
00204     map<int,Vec> cached_columns;
00205 
00206     try {
00207 
00208         while(key != 'q' && key != 'Q')
00209         {
00210             erase();
00211 
00212             int leftcolwidth = transposed ?1+namewidth :10;
00213 
00214             int nj = transposed ? LINES-3 : (COLS-leftcolwidth)/valwidth;
00215             int ni = transposed ? (COLS-leftcolwidth)/valwidth : LINES-4;
00216             if(display_filename && filename.length()>(size_t)COLS)
00217                 ni -= filename.length()/COLS;
00218 
00219             int endj = min(vm_showed->width(), startj+nj);
00220             int endi = min(vm_showed->length(), starti+ni);
00221 
00222             int x=0, y=0; // (curses coordinates are (y,x) )
00223 
00224             // print field names
00225             for(int j=startj; j<endj; j++)
00226             {
00227                 string s = vm_showed->fieldName(j);
00228                 if ( int(s.size()) > namewidth)
00229                     s = s.substr(0, namewidth);
00230 
00231                 // if(j==curj)
00232                 //  attron(A_REVERSE);
00233                 if(transposed)
00234                     mvprintw(1+(j-startj),0,"%s", s.c_str());
00235                 else
00236                 {
00237                     x = 1+leftcolwidth+(j-startj)*valwidth;
00238                     mvprintw(0, x, valstrformat,
00239                              s.substr(0,valstrwidth).c_str() );
00240                     if((int)s.length() > valstrwidth)
00241                         mvprintw(1, x, valstrformat,
00242                                  s.substr(valstrwidth,valstrwidth).c_str() );
00243                 }
00244                 // attroff(A_REVERSE);
00245             }
00246 
00247             Vec v(vm_showed.width());
00248             Vec oldv(vm_showed.width());
00249 
00250             for(int i=starti; i<endi; i++)
00251             {
00252                 if(transposed)
00253                 {
00254                     y = 0;
00255                     x = 1+leftcolwidth+(i-starti)*valwidth;
00256                     mvprintw(y,x,"%14d",i);
00257                 }
00258                 else
00259                 {
00260                     y = i-starti+2;
00261                     x = 0;
00262                     mvprintw(y,x,"%d",i);
00263                 }
00264 
00265                 vm_showed->getRow(i,v);
00266 
00267                 for(int j=startj; j<endj; j++)
00268                 {
00269                     real val = v[j];
00270                     string s = vm_showed->getValString(j,val);
00271                     if (!view_strings || s == "")
00272                     {
00273                         // We only have 14 characters, and have to display
00274                         // correctly numbers like "18270326".
00275                         // Best compromise found is "%14.8g".
00276                         char tmp[1000];
00277                         sprintf(tmp, "%14.8g", val);
00278                         s = tmp;
00279                     }
00280                     else {
00281                         // This is a string. Maybe we want to indent it to the
00282                         // right.
00283                         // In this case we truncate it to its last characters.
00284                         if (!indent_strings_left) {
00285                             if (s.size() >= (size_t) valstrwidth) {
00286                                 s = s.substr(s.size() - valstrwidth,
00287                                              valstrwidth);
00288                             } else {
00289                                 string added_spaces((size_t) (valstrwidth - s.size()), ' ');
00290                                 s = added_spaces + s;
00291                             }
00292                         }
00293                     }
00294 
00295                     if(transposed)
00296                         y = 1+(j-startj);
00297                     else
00298                         x = 1+leftcolwidth+(j-startj)*valwidth;
00299 
00300                     if( i == curi || (vm_showed.width() > 1 && j == curj) )
00301                         attron(A_REVERSE);
00302                     //else if ()
00303                     //  attron(A_REVERSE);
00304 
00305                     if(hide_sameval== 2 && i>starti && (is_equal(val,oldv[j])) )
00306                         mvprintw(y, x, valstrformat, "...");
00307                     else if(fast_exact_is_equal(hide_sameval, 1) && i>starti &&
00308                             (fast_exact_is_equal(val, oldv[j]) ||
00309                              (is_missing(val) && is_missing(oldv[j]))))
00310                         mvprintw(y, x, valstrformat, "...");
00311                     else
00312                         mvprintw(y, x, valstrformat,
00313                                  s.substr(0,valstrwidth).c_str());
00314 
00315                     attroff(A_REVERSE);
00316                 }
00317                 oldv << v;
00318             }
00319 
00320             string strval = vm_showed->getString(curi, curj);
00321             mvprintw(0,0,"Cols[%d-%d]", 0, vm_showed.width()-1);
00322             if(display_filename){
00323                 mvprintw(LINES-filename.length()/COLS-1,0,"%s",filename.c_str());
00324             }else
00325                 mvprintw(LINES-1,0,
00326                          " %dx%d   line= %d   col= %d     %s = %s (%f)",
00327                          vm_showed->length(), vm_showed->width(),
00328                          curi, curj, vm_showed->fieldName(curj).c_str(),
00329                          strval.c_str(), vm_showed(curi,curj));
00330 
00331             refresh();
00332             if (!onError)
00333                 key = getch();
00334             else
00335                 onError = false;
00336 
00338             switch(key)
00339             {
00340             case KEY_LEFT:
00341                 if(transposed)
00342                 {
00343                     if(curi>0)
00344                         --curi;
00345                     if(curi<starti)
00346                         starti = curi;
00347                 }
00348                 else
00349                 {
00350                     if(curj>0)
00351                         --curj;
00352                     if(curj<startj)
00353                         startj=curj;
00354                 }
00355                 break;
00357             case KEY_RIGHT:
00358                 if(transposed)
00359                 {
00360                     if(curi<vm_showed->length()-1)
00361                         ++curi;
00362                     if(curi>=starti+ni)
00363                         ++starti;
00364                 }
00365                 else
00366                 {
00367                     if(curj<vm_showed->width()-1)
00368                         ++curj;
00369                     if(curj>=startj+nj)
00370                         ++startj;
00371                 }
00372                 break;
00374             case KEY_UP:
00375                 if(transposed)
00376                 {
00377                     if(curj>0)
00378                         --curj;
00379                     if(curj<startj)
00380                         startj=curj;
00381                 }
00382                 else
00383                 {
00384                     if(curi>0)
00385                         --curi;
00386                     if(curi<starti)
00387                         starti = curi;
00388                 }
00389                 break;
00391             case KEY_DOWN:
00392                 if(transposed)
00393                 {
00394                     if(curj<vm_showed->width()-1)
00395                         ++curj;
00396                     if(curj>=startj+nj)
00397                         ++startj;
00398                 }
00399                 else
00400                 {
00401                     if(curi<vm_showed->length()-1)
00402                         ++curi;
00403                     if(curi>=starti+ni)
00404                         ++starti;
00405                 }
00406                 break;
00408             case KEY_PPAGE:
00409                 if(transposed)
00410                 {
00411                     curj -= nj;
00412                     startj -= nj;
00413                     if(startj<0)
00414                         startj = 0;
00415                     if(curj<0)
00416                         curj = 0;
00417                 }
00418                 else
00419                 {
00420                     curi -= ni;
00421                     starti -= ni;
00422                     if(starti<0)
00423                         starti = 0;
00424                     if(curi<0)
00425                         curi = 0;
00426                 }
00427                 break;
00429             case KEY_NPAGE:
00430                 if(transposed)
00431                 {
00432                     curj += nj;
00433                     startj += nj;
00434                     if(curj>=vm_showed->width())
00435                         curj = vm_showed->width()-1;
00436                     if(startj>vm_showed->width()-nj)
00437                         startj = max(0,vm_showed->width()-nj);
00438                 }
00439                 else
00440                 {
00441                     curi += ni;
00442                     starti += ni;
00443                     if(curi>=vm_showed->length())
00444                         curi = vm_showed->length()-1;
00445                     if(starti>vm_showed->length()-ni)
00446                         starti = max(0,vm_showed->length()-ni);
00447                 }
00448                 break;
00450             case KEY_HOME:
00451                 // not working on unix for the moment: see
00452                 // http://dickey.his.com/xterm/xterm.faq.html#xterm_pc_style
00453                 if(transposed)
00454                 {
00455                     curi = 0;
00456                     starti = 0;
00457                 }
00458                 else
00459                 {
00460                     curj = 0;
00461                     startj = 0;
00462                 }
00463                 break;
00465             case KEY_END:
00466                 // not working on unix for the moment: see
00467                 // http://dickey.his.com/xterm/xterm.faq.html#xterm_pc_style
00468                 if(transposed)
00469                 {
00470                     curi = vm_showed->length()-1;
00471                     starti = max(curi-ni + 1, 0);
00472                 }
00473                 else
00474                 {
00475                     curj = vm_showed->width()-1;
00476                     startj = max(curj-nj + 1, 0);
00477                 }
00478                 break;
00480             case '.':
00481                 if (hide_sameval == 1)
00482                     hide_sameval = 0;
00483                 else
00484                     hide_sameval = 1;
00485                 break;
00487             case ',':
00488                 if (hide_sameval == 2)
00489                     hide_sameval = 0;
00490                 else
00491                     hide_sameval = 2;
00492                 break;
00494             case 't': case 'T':
00495                 transposed = !transposed;
00496                 nj = transposed ? LINES-3 : (COLS-leftcolwidth)/valwidth;
00497                 ni = transposed ? (COLS-leftcolwidth)/valwidth : LINES-4;
00498                 starti = max(0,curi-ni/2);
00499                 startj = max(0,curj-nj/2);
00500                 //endj = min(vm_showed->width(), startj+nj);
00501                 //endi = min(vm_showed->length(), starti+ni);
00502                 break;
00504             case '/':  // search for value
00505             {
00506                 echo();
00507                 char strmsg[] = {"Search for value or string: "};
00508                 mvprintw(LINES-1,0,strmsg);
00509                 // clear the rest of the line
00510                 clrtoeol();
00511                 move(LINES-1, (int)strlen(strmsg));
00512                 char l[20];
00513                 getnstr(l, 20);
00514                 string searchme = removeblanks(l);
00515                 real searchval = vm_showed(curi,curj);
00516                 if(searchme!="")
00517                 {
00518                     searchval = vm_showed->getStringVal(curj, searchme);
00519                     if(is_missing(searchval))
00520                     {
00521                         searchval = toreal(searchme);
00522                         // This one gives a very bad error: to be changed
00523                         if(is_missing(searchval))
00524                             PLERROR("Search item is neither a string with a valid mapping, nor convertible to a real");
00525                     }
00526                 }
00527 
00528                 Vec cached;
00529                 if(cached_columns.find(curj)!=cached_columns.end())
00530                     cached = cached_columns[curj];
00531                 else
00532                 {
00533                     mvprintw(LINES-1,0,"Building cache...");
00534                     // clear the rest of the line
00535                     clrtoeol();
00536                     refresh();
00537                     cached.resize(vm_showed->length());
00538                     vm_showed->getColumn(curj,cached);
00539                     cached_columns[curj] = cached;
00540                 }
00541 
00542                 mvprintw(LINES-1,0,"Searching for value %f ...",searchval);
00543                 clrtoeol();
00544                 refresh();
00545                 int curi_backup = curi;
00546                 ++curi; // start searching from next row
00547                 while(curi<vm_showed->length() &&
00548                       !fast_exact_is_equal(cached[curi], searchval))
00549                     ++curi;
00550                 bool found = (curi < vm_showed->length());
00551                 if (!found) {
00552                     // Try approximate match.
00553                     curi = curi_backup + 1;
00554                     while(curi<vm_showed->length() &&
00555                             !is_equal(cached[curi], searchval))
00556                         ++curi;
00557                 }
00558                 if(curi>=vm_showed->length())
00559                     curi = 0;
00560                 ni = transposed ? (COLS-leftcolwidth)/valwidth : LINES-4;
00561                 starti = max(0,curi-ni/2);
00562             }
00563             break;
00565             case (int)'l': case (int)'L':
00566             {
00567                 echo();
00568                 char strmsg[] = {"Goto line: "};
00569                 mvprintw(LINES-1,0,strmsg);
00570                 clrtoeol();
00571                 move(LINES-1, (int)strlen(strmsg));
00572                 char l[10];
00573                 getnstr(l, 10);
00574                 if(l[0] == '\0' || !pl_isnumber(l) || toint(l) < 0 || toint(l)>=vm_showed->length())
00575                 {
00576                     mvprintw(LINES-1,0,"*** Invalid line number ***");
00577                     clrtoeol();
00578                     refresh();
00579                     // wait until the user types something
00580                     key = getch();
00581                     onError = true;
00582                 }
00583                 else
00584                 {
00585                     curi= toint(l);
00586                     starti = max(curi-ni + 1, 0);
00587                     //starti = curi;
00588                 }
00589                 noecho();
00590             }
00591             break;
00593             case (int)'c': case (int)'C':
00594             {
00595                 echo();
00596                 char strmsg[] = {"Goto column: "};
00597                 mvprintw(LINES-1,0,strmsg);
00598                 clrtoeol();
00599                 move(LINES-1, (int)strlen(strmsg));
00600                 char c[200];
00601                 getnstr(c, 10);
00602                 string the_col = c;
00603                 int col_num = -1;
00604                 try {
00605                     col_num = vm_showed->getFieldIndex(the_col);
00606                 } catch (...) {}
00607                 if(col_num < 0)
00608                 {
00609                     mvprintw(LINES-1,0,"*** Invalid column number ***");
00610                     clrtoeol();
00611                     refresh();
00612                     // wait until the user types something
00613                     key = getch();
00614                     onError = true;
00615                 }
00616                 else
00617                 {
00618                     curj = col_num;
00619                     startj = max(curj-nj + 1, 0);
00620                 }
00621                 noecho();
00622             }
00623             break;
00625             case (int)'v': case (int)'V':
00626             {
00627                 echo();
00628                 char strmsg[] = {"View dataset ('Enter' = reload last dataset): "};
00629                 mvprintw(LINES-1,0,strmsg);
00630                 clrtoeol();
00631                 move(LINES-1, (int) strlen(strmsg));
00632                 char c[200];
00633                 getnstr(c, 200);
00634                 if (!string(c).empty())
00635                     filename = string(c);
00636                 VMat new_vm;
00637                 bool error = false;
00638                 try {
00639                     new_vm = getDataSet(filename);
00640                 } catch(const PLearnError&) {
00641                     error = true;
00642                 }
00643                 if (error) {
00644                     mvprintw(LINES-1,0,"*** Invalid dataset ***");
00645                     clrtoeol();
00646                     refresh();
00647                     // Wait until the user types something.
00648                     key = getch();
00649                     onError = true;
00650                 } else {
00651                     // Display the new dataset.
00652                     // First close the current display.
00653                     mvprintw(LINES-1,0,"");
00654                     clrtoeol();
00655                     refresh();
00656                     endwin();
00657                     // And launch the new one.
00658                     viewVMat(new_vm, filename);
00659                     if(string(c).empty())
00660                         //if we reload, we should forget the last one
00661                         key='q';
00662                 }
00663             }
00664             break;
00666             case (int)'i': case (int)'I':
00667             {
00668                 echo();
00669                 char strmsg[] = {"Insert before column ('Enter' = current, '-1' = insert at the end): "};
00670                 mvprintw(LINES-1,0,strmsg);
00671                 clrtoeol();
00672                 move(LINES-1, (int)strlen(strmsg));
00673                 char l[10];
00674                 getnstr(l, 10);
00675                 int ins_col = curj;
00676                 if (l[0] != '\0') {
00677                     if (!pl_isnumber(l) || toint(l) < -1 || toint(l)>=vm_showed->width()) {
00678                         mvprintw(LINES-1,0,"*** Invalid column number ***");
00679                         clrtoeol();
00680                         refresh();
00681                         // wait until the user types something
00682                         key = getch();
00683                         onError = true;
00684                         noecho();
00685                         break;
00686                     } else {
00687                         ins_col = toint(l);
00688                     }
00689                 }
00690                 if (ins_col == -1)
00691                     ins_col = vm_showed->width();
00692                 char strmsg2[] = {"Name of the column to insert ('Enter' = column number): "};
00693                 mvprintw(LINES-1,0,strmsg2);
00694                 clrtoeol();
00695                 move(LINES-1, (int)strlen(strmsg2));
00696                 char l2[100];
00697                 getnstr(l2, 100);
00698                 string ins_name = tostring(ins_col);
00699                 if (l2[0] != '\0') {
00700                     ins_name = l2;
00701                 }
00702                 char strmsg3[] = {"Default value ('Enter' = 0): "};
00703                 mvprintw(LINES-1,0,strmsg3);
00704                 clrtoeol();
00705                 move(LINES-1, (int)strlen(strmsg3));
00706                 char l3[100];
00707                 getnstr(l3, 100);
00708                 string default_val = tostring(0);
00709                 if (l3[0] != '\0') {
00710                     default_val = l3;
00711                 }
00712                 TVec<VMat> vmats;
00713                 if (ins_col > 0)
00714                     vmats.append(new SubVMatrix(vm_showed, 0, 0,
00715                                                 vm_showed->length(), ins_col));
00716                 Mat col_mat(vm_showed->length(), 1);
00717                 VMat col_vmat(col_mat);
00718                 col_vmat->declareFieldNames(TVec<string>(1, ins_name));
00719                 real val;
00720                 if (pl_isnumber(default_val, &val))
00721                     col_mat.fill(val);
00722                 else {
00723                     col_mat.fill(-1000);
00724                     col_vmat->addStringMapping(0, default_val, -1000);
00725                 }
00726                 vmats.append(col_vmat);
00727                 if (ins_col < vm_showed->width())
00728                     vmats.append(new SubVMatrix(vm_showed, 0, ins_col,
00729                                                 vm_showed->length(),
00730                                                 vm_showed->width() - ins_col));
00731                 vm_showed = new ConcatColumnsVMatrix(vmats);
00732                 mvprintw(LINES-1,0,"*** Inserted column '%s' at position %d with default value %s ***",
00733                          ins_name.c_str(), ins_col, default_val.c_str());
00734                 clrtoeol();
00735                 refresh();
00736                 // Wait for a key to be pressed.
00737                 key = getch();
00738                 noecho();
00739             }
00740             break;
00742             case (int)'e': case (int)'E':
00743             {
00744                 echo();
00745                 char strmsg[100];
00746                 sprintf(strmsg, "Enter column(s) or range (ex: 7;1-20;7,8,12) to export (enter=%d): ", curj);
00747                 mvprintw(LINES-1,0,strmsg);
00748                 clrtoeol();
00749 
00750                 move(LINES-1, (int)strlen(strmsg));
00751                 char strRange[50];
00752                 getnstr(strRange, 50);
00753 
00754                 Vec indexs;
00755                 char strReason[100] = {"\0"};
00756                 bool invalidInput = getList(strRange, curj, vm_showed, indexs,
00757                                             strReason);
00758 
00759                 if (invalidInput)
00760                 {
00761                     mvprintw(LINES-1,0,"*** Invalid input: %s ***", strReason);
00762                     clrtoeol();
00763                     refresh();
00764                     // wait until the user types something
00765                     key = getch();
00766                     onError = true;
00767                 }
00768                 else
00769                 {
00770 
00771                     char filemsg[] = {"Enter file name (enter=outCol.txt): "};
00772                     mvprintw(LINES-1,0,filemsg);
00773                     clrtoeol();
00774 
00775                     move(LINES-1, (int)strlen(filemsg));
00776                     char fname[200];
00777                     getnstr(fname, 200);
00778 
00779                     if (fname[0] == '\0')
00780                         strcpy(fname, "outCol.txt");
00781                     string fname_str = fname;
00782 
00783                     mvprintw(LINES-1,0,"Writing file '%s'...", fname);
00784                     clrtoeol();
00785                     refresh();
00786 
00787                     // Save the selected columns to the desired file, keeping
00788                     // the string values if 'view_strings' is currently true
00789                     // (can be toggled with 's'/'S' keys).
00790                     vm_showed.columns(indexs)->saveAMAT(fname_str, false,
00791                                                         false, view_strings);
00792 
00793                     mvprintw(LINES-1,0,"*** Output written on: %s ***", fname);
00794                     clrtoeol();
00795                     refresh();
00796                     // wait until the user types something
00797                     key = getch();
00798 
00799                 }
00800 
00801                 noecho();
00802             }
00803             break;
00805             case (int)'r': case (int)'R':
00806             {
00807                 echo();
00808                 char strmsg[100];
00809                 sprintf(strmsg, "Enter column(s) or range (ex: 7;1-20;7,8,12) to view (enter=%d): ", curj);
00810                 mvprintw(LINES-1,0,strmsg);
00811                 clrtoeol();
00812 
00813                 move(LINES-1, (int)strlen(strmsg));
00814                 char c[50];
00815                 getnstr(c, 50);
00816 
00817                 Vec indexs;
00818                 char strReason[100] = {"\0"};
00819                 bool invalidInput = getList(c, curj, vm_showed, indexs,
00820                                             strReason);
00821 
00822                 if (invalidInput)
00823                 {
00824                     mvprintw(LINES-1,0,"*** Invalid input: %s ***", strReason);
00825                     clrtoeol();
00826                     refresh();
00827                     // wait until the user types something
00828                     key = getch();
00829                     onError = true;
00830                 }
00831                 else
00832                 {
00833                     vm_showed = vm_showed.columns(indexs);
00834                     if (curj>=vm_showed.width())
00835                     {
00836                         curj = vm_showed.width()-1;
00837                         startj = max(curj-nj + 1, 0);
00838                     }
00839                 }
00840 
00841                 noecho();
00842             }
00843             break;
00845             case (int)'x': case (int)'X':
00846                 // Hide the currently selected row.
00847             {
00848                 //echo();
00849                 Vec index(vm_showed.width() - 1);
00850                 for (int i = 0; i < curj; i++) {
00851                     index[i] = i;
00852                 }
00853                 for (int i = curj + 1; i < vm_showed.width(); i++) {
00854                     index[i - 1] = i;
00855                 }
00856                 vm_showed = vm_showed.columns(index);
00857                 if (curj>=vm_showed.width()) {
00858                     curj = vm_showed.width()-1;
00859                     startj = max(curj-nj + 1, 0);
00860                 }
00861 
00862                 //          noecho();
00863             }
00864             break;
00866             case (int)'<': case (int)'>':
00867                 // Sort by increasing or decreasing order.
00868             {
00869                 PP<SortRowsVMatrix> new_vm;
00870                 if(vm_showed->classname()!="SortRowsVMatrix" 
00871                    || ((PP<SortRowsVMatrix>)vm_showed)->sort_columns[0]!=curj){
00872                 //if it is a SortRowsVMatrix and we sort on a new column
00873                 // we can't reuse the last SortRowsVMatrix as it don't suport 
00874                 // different order on each row.
00875                     new_vm = new SortRowsVMatrix();
00876                     new_vm->source = vm_showed;
00877                     vm_showed = get_pointer(new_vm);
00878                 } else 
00879                     //in the case where we sort multiple time on the same column
00880                     //we reuse the last VMatrix.
00881                     new_vm= (PP<SortRowsVMatrix>)vm_showed;
00882                 new_vm->sort_columns = TVec<int>(1, curj);
00883                 if (key == (int)'>')
00884                     new_vm->increasing_order = false;
00885                 else                    
00886                     new_vm->increasing_order = true;
00887                 new_vm->build();
00888             }
00889             break;
00891             case (int)'a': case (int)'A':
00892                 vm_showed = vm;
00893                 break;
00895             case (int)'n': case (int)'N':
00896                 if ( namewidth != namewidth_ )
00897                     namewidth = namewidth_;
00898                 else
00899                 {
00900                     int def = (namewidth < 80) ? namewidth : 80;
00901 
00902                     echo();
00903                     char strmsg[100];
00904                     sprintf(strmsg, "Enter namewidth to use (between 10 and %d -- enter=%d): ",
00905                             namewidth, def);
00906                     mvprintw(LINES-1,0,strmsg);
00907                     clrtoeol();
00908 
00909                     move(LINES-1, (int)strlen(strmsg));
00910                     char l[10];
00911                     getnstr(l, 10);
00912                     if(l[0] == '\0')
00913                     {
00914                         namewidth = def;
00915                     }
00916                     else if( !pl_isnumber(l) || toint(l) < 0 || toint(l)>namewidth )
00917                     {
00918                         mvprintw(LINES-1,0,"*** Invalid line number ***");
00919                         clrtoeol();
00920                         refresh();
00921                         // wait until the user types something
00922                         key = getch();
00923                         onError = true;
00924                     }
00925                     else
00926                     {
00927                         namewidth = toint(l);
00928                     }
00929                     noecho();
00930                 }
00931                 break;
00933             case (int)'s':
00934                 if (indent_strings_left)
00935                     // Toggle display.
00936                     view_strings = !view_strings;
00937                 else {
00938                     // Do not remove display if we only asked to change
00939                     // indentation.
00940                     indent_strings_left = true;
00941                     if (!view_strings)
00942                         view_strings = true;
00943                 }
00944                 break;
00945             case (int)'S':
00946                 // Same as above, except we indent to the right.
00947                 if (!indent_strings_left)
00948                     view_strings = !view_strings;
00949                 else {
00950                     indent_strings_left = false;
00951                     if (!view_strings)
00952                         view_strings = true;
00953                 }
00954                 break;
00956             case (int)'h': case (int)'H':
00957                 erase();
00958 
00959                 vStartHelp = 2;
00960 
00961                 mvprintw(0,COLS/2-6,"*** HELP ***");
00962 
00963                 mvprintw(vStartHelp++,10,"KEYS:");
00964                 mvprintw(vStartHelp++,10," - up: move up one line");
00965                 mvprintw(vStartHelp++,10," - down: move down one line");
00966                 mvprintw(vStartHelp++,10," - right: move right one column");
00967                 mvprintw(vStartHelp++,10," - left: move left one column");
00968                 mvprintw(vStartHelp++,10," - page up: move up one screen");
00969                 mvprintw(vStartHelp++,10," - page down: move down one screen");
00970                 mvprintw(vStartHelp++,10," - home: move to the first column");
00971                 mvprintw(vStartHelp++,10," - end: move to the last column");
00972                 mvprintw(vStartHelp++,10," - 'r' or 'R': show only a range or a set of columns");
00973                 mvprintw(vStartHelp++,10," - 'x' or 'X': hide the currently selected column");
00974                 mvprintw(vStartHelp++,10," - 'a' or 'A': show the original VMat");
00975                 mvprintw(vStartHelp++,10," - 'f' or 'F': toggle the display of the filename");
00976                 mvprintw(vStartHelp++,10," - 'i' or 'I': insert a new column with default value");
00977                 mvprintw(vStartHelp++,10," - 'l' or 'L': prompt for a line number and go to that line");
00978                 mvprintw(vStartHelp++,10," - 'c' or 'C': prompt for a column number and go to that column");
00979                 mvprintw(vStartHelp++,10," - 's' or 'S': toggle display string fields as strings or numbers ('S' = right indentation)");
00980                 mvprintw(vStartHelp++,10," - 't' or 'T': toggle transposed display mode");
00981                 mvprintw(vStartHelp++,10," - 'n' or 'N': toggle truncated field name display mode (under transposed display mode)");
00982                 mvprintw(vStartHelp++,10," - 'e' or 'E': export a range or a set of columns to file");
00983                 mvprintw(vStartHelp++,10," - 'v' or 'V': prompt for another dataset to view");
00984                 mvprintw(vStartHelp++,10," - '.'       : toggle displaying of ... for values that do not change (exact match)");
00985                 mvprintw(vStartHelp++,10," - ','       : toggle displaying of ... for values that do not change (approximate match)");
00986                 mvprintw(vStartHelp++,10," - '/'       : search for a value of the current field");
00987                 mvprintw(vStartHelp++,10," - '<' or '>': sort column by increasing or decreasing order");
00988                 mvprintw(vStartHelp++,10," - 'h' or 'H': display this screen");
00989                 mvprintw(vStartHelp++,10," - 'q' or 'Q': quit program");
00990                 mvprintw(vStartHelp++,COLS/2-13,"(press any key to continue)");
00991 
00992                 refresh();
00993                 getch();
00994 
00995                 break;
00996 
00997             case (int)'f': case (int)'F':
00998                 display_filename = !display_filename;
00999 
01000             case (int)'q': case (int)'Q':
01001                 break;
01002 
01004             default:
01005                 mvprintw(LINES-1,0,"*** Invalid command (type 'h' for help) ***");
01006                 // clear the rest of the line
01007                 clrtoeol();
01008 
01009                 refresh();
01010 
01011                 // wait until the user types something
01012                 key = getch();
01013                 onError = true;
01014 
01015                 //sleep(1);
01016                 break;
01017             }
01018         }
01019     } // end try
01020     catch(const PLearnError& e)
01021     {
01022         endwin();
01023         throw(e);
01024     }
01025 
01026     // make sure it is clean
01027     mvprintw(LINES-1,0,"");
01028     clrtoeol();
01029     refresh();
01030 
01031     endwin();
01032 }
01033 
01034 
01035 BEGIN_DECLARE_REMOTE_FUNCTIONS
01036 
01037     declareFunction("viewVMat", &viewVMat,
01038                     (BodyDoc("Displays a VMat's contents using curses.\n"),
01039                      ArgDoc("vm",
01040                             "the VMat to display"),
01041                      ArgDoc("filename",
01042                             "optional filename of the dataset, that may be used to reload it (\"\" works just fine)")));
01043 
01044 END_DECLARE_REMOTE_FUNCTIONS
01045 
01046 
01047 } // end of namespace PLearn
01048 
01049 
01050 /*
01051   Local Variables:
01052   mode:c++
01053   c-basic-offset:4
01054   c-file-style:"stroustrup"
01055   c-file-offsets:((innamespace . 0)(inline-open . 0))
01056   indent-tabs-mode:nil
01057   fill-column:79
01058   End:
01059 */
01060 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines