csvviewer.cxx

Go to the documentation of this file.
00001 //
00002 // Copyright 2010, Lowell Boggs Jr.
00003 //
00004 // This file or directory, containing source code for a computer program,
00005 // is Copyrighted by Lowell Boggs, Jr.  987 Regency Drive, Lewisville
00006 // TX (USA), 75067.  You may use, copy, modify, and distribute this
00007 // source file without charge or obligation so long as you agree to
00008 // the following:
00009 //
00010 //  1.  You must indemnify Lowell Boggs against any and all financial
00011 //      obligations caused by its use, misuse, function, or malfunction.
00012 //      Further, you acknowledge that there is no warranty of any kind,
00013 //      whatsoever.
00014 //
00015 //  2.  You agree not to attempt to patent any portion of this original
00016 //      work -- though you may attempt to patent your own extensions to
00017 //      it if you so choose.
00018 //
00019 //  3.  You keep this copyright notice with the file and all copies
00020 //      of the file and do not change it anyway except language translation.
00021 //
00022 // You are responsible for enforcing your own compliance with these
00023 // conditions and may not use this source file if you cannot agree to the
00024 // above terms and conditions.
00025 //
00026 // Warning:  not all files in this directory structure are covered by the
00027 // same copyright.  Some of them are part of the GNU source distribution
00028 // and you must obey the GPL copyright for those files.
00029 
00030 #include <cxxtls/csvviewer.h>
00031 #include <cxxtls/viewermanager.h>
00032 #include <iostream>
00033 #include <fstream>
00034 #include <cxxtls/strtool.h>
00035 #include <cxxtls/file.h>
00036 
00037 using namespace std;
00038 
00039 namespace cxxtls
00040 {
00041 
00044 CsvViewer::~CsvViewer()
00045 {
00046 }
00049 CsvViewer::CsvViewer(ViewerManager *vm, string const &filename, int delimiter)
00050 : TableEditor(vm, delimiter)
00051 , filename_(filename)
00052 {
00053     ifstream input(filename.c_str());
00054 
00055     if(!input.good())
00056     {
00057        fileError_="Can not open file ";
00058        fileError_+= filename;
00059        return;
00060     }
00061 
00062     string line;
00063 
00064     bool firstLine=true;
00065 
00066     size_t rowCount=0, colCount=0;
00067 
00068     while(getline(input, line))
00069     {
00070         StrTool::stringlist_t fields;
00071 
00072         StrTool::parse_words(line, 
00073                              &fields, 
00074                              StrTool::all, 
00075                              StrTool::Is_Delim(delimiter_)
00076                             );
00077 
00078         if(firstLine)
00079         {
00080             // if this is the first line, set up the column headers
00081 
00082             firstLine = false;
00083 
00084             StrTool::stringlist_t::const_iterator first = fields.begin(),
00085                                                   last  = fields.end();
00086 
00087             while(first != last)
00088             {
00089                string const &cur = *first++;
00090 
00091                addColumnHeader(cur, cur.size(), true);
00092 
00093                ++colCount;
00094             }
00095 
00096         }
00097         else
00098         {
00099             char buffer[40];
00100 
00101             sprintf(buffer, "%lu", (unsigned long)rows()+1);
00102 
00103             addRow(buffer,1,false);
00104 
00105             ++rowCount;
00106 
00107             StrTool::stringlist_t::const_iterator first = fields.begin(),
00108                                                   last  = fields.end();
00109 
00110             while(first != last)
00111             {
00112                string const &cur = *first++;
00113 
00114                addColumnData(cur);
00115             }
00116 
00117 
00118 
00119         }
00120 
00121     }
00122 
00123 
00124 
00125 }
00128 bool CsvViewer::okToQuit(CursorWindow::viewport *vp)
00129 {
00130     if(is_dirty())
00131     {
00132       vp->beep();
00133       
00134       CursorWindow::Dialog d("Unsaved edit changes exist");
00135       d += new CursorWindow::Dialog::String("ok",
00136                                             "Quit Anyway (Yes or No)",
00137                                             "No",
00138                                             4
00139                                            );
00140       
00141       if(d.popup( manager_->window() ))
00142       {
00143         return false;
00144       }
00145       
00146       std::string ok_value = d.element_value("ok");
00147       
00148       if(ok_value.size() > 2)
00149       {
00150         ok_value.erase(2, ok_value.size());
00151       }
00152       
00153       if(ok_value != "Ye" && ok_value != "ye" )
00154       {
00155         vp->beep();
00156         return false;
00157       }
00158       
00159     }
00160     return true;
00161 }
00164 bool CsvViewer::handle_event( CursorWindow::input_event const * e,
00165                               CursorWindow::viewport          * vp
00166                             )
00167 {
00168     if(    e->type_ == CursorWindow::input_event::DataKey
00169        ||  e->type_ == CursorWindow::input_event::FunctionKey 
00170       )
00171     {
00172         if(keyKludge_)
00173         {
00174             keyKludge_ = false;
00175 
00176             switch(e->value_)
00177             {
00178                 case 0x03: // ^C quit editing
00179                    return true;
00180 
00181                 case 0x13: // ^S         // save current file
00182                    saveTo(filename_);
00183                    return false;
00184                    
00185 
00186                 case 0x0b: // ^K quit editing
00187                     if(okToQuit(vp))
00188                         return true;
00189                     return false;
00190                 
00191 
00192                 default: vp->beep(); break;
00193             }
00194 
00195             return false;
00196         }
00197 
00198     }
00199 
00200    // by default, act like a table viewer -- which has different arrow key behavior
00201    // than is inforced here
00202 
00203    bool quitNow = TableEditor::handle_event(e,vp);
00204 
00205    if(quitNow)
00206    {
00207       if(!okToQuit(vp))
00208         return false; 
00209    }
00210 
00211    return quitNow;
00212 }
00213 
00214 
00217 void CsvViewer::setCursorInfo(CursorWindow::viewport *vp,
00218                               size_t worldRow, 
00219                               size_t worldCol, 
00220                               bool displayed
00221                              )
00222 {
00223     terminateInput();
00224 
00225     TableViewer::setCursorInfo(vp, worldRow, worldCol, displayed);
00226 }
00227 
00230 
00231 void CsvViewer::saveTo(std::string const &filename)
00232     {
00233        set_data_dirty(false);
00234 
00235        string delimString;  delimString += (char)delimiter_;
00236 
00237        fstream output(filename.c_str());
00238 
00239        fileError_.resize(0);
00240 
00241        if(!output.good())
00242        {
00243           CursorWindow::Message d("Error opening file for write ");
00244         
00245           d += "";
00246           d += string("File name: ") + filename;
00247           d += "";
00248           d += "Press Enter to continue";
00249         
00250           d.popup(manager_->window());
00251    
00252           fileError_ = string("Error openining input file: ") + filename;
00253 
00254           return;
00255           
00256        }
00257 
00258        {
00259           // output the header row
00260 
00261           vector<ColumnInfo>::const_iterator first = cols_.begin(),
00262                                              last  = cols_.end();
00263 
00264           while(first != last)
00265           {
00266              ColumnInfo const &cur = *first++;
00267 
00268              output << cur.title_;
00269 
00270              if(first != last)
00271                output << delimString;
00272 
00273           }
00274 
00275           output << '\n';
00276 
00277        }
00278 
00279 
00280        for(size_t row = 0; row < layout_.size(); ++row)
00281        {
00282           vector<CellInfo> const &curRow = layout_[row];
00283 
00284           vector<CellInfo>::const_iterator first = curRow.begin(),
00285                                            last  = curRow.end();
00286 
00287           while(first != last)
00288           {
00289               CellInfo const &curCell = *first++;
00290               
00291               if(!curCell.text_.empty())
00292                   output << curCell.text_[0];
00293 
00294               if(first != last)
00295                   output << delimString;
00296 
00297           }
00298 
00299           output << '\n';
00300 
00301        }
00302 
00303        if(!output.good())
00304        {
00305           fileError_ = string("Error writing to: ") + filename;
00306        }
00307 
00308 
00309     }
00310 
00313 std::string const &CsvViewer::application_name() const
00314 {
00315    static string rv("CsvViewer");
00316 
00317    return rv;
00318 }
00321 std::string CsvViewer::description() const
00322 {
00323    return "csv and tsv file editor";
00324 }
00327 Viewer* CsvViewer::app(ViewerManager*vm, std::string &fullname)
00328 {
00329   if(fullname.size() == 0)
00330   {
00331     // do not use the viewer selector from here because it can not repaint the screen
00332     // in this context
00333 
00334     CursorWindow::Dialog d("File name");
00335 
00336     d += new CursorWindow::Dialog::String("name",
00337                                           "path",
00338                                           "*",
00339                                           40
00340                                          );
00341                                 
00342     if(d.popup(vm->window()))
00343       return 0;
00344 
00345     fullname = d.element_value("name");
00346 
00347     if(fullname == "")
00348       return 0;
00349 
00350 
00351     FileName tmp(fullname);
00352     tmp.convert_to_absolute_path();
00353 
00354     fullname = tmp;
00355 
00356   }
00357 
00358   int delimiter=',';
00359 
00360   size_t dotPos = fullname.find_last_of('.');
00361 
00362   if(dotPos < fullname.size())
00363   {
00364     ++dotPos;  // get to 't' or 'c'
00365 
00366     if( dotPos < fullname.size())
00367     {
00368         if(fullname[dotPos] == 't' || fullname[dotPos] == 'T')
00369            delimiter=0x09; // tab  
00370     }
00371   }
00372 
00373   return new CsvViewer(vm,fullname, delimiter);
00374 }
00375 
00376 void
00377 CsvViewer::
00378 help()
00379 {
00380 
00381   std::auto_ptr< std::list< std::string > >
00382     viewer_help( new std::list< std::string > );
00383 
00384   viewer_help->push_back("Help for the Comma Separated Values Viewer");
00385   viewer_help->push_back("");
00386   viewer_help->push_back("  Movement keys");
00387   viewer_help->push_back("    up arrow    -- move up one cell");
00388   viewer_help->push_back("    down arrow  -- move down one cell");
00389   viewer_help->push_back("    left arrow  -- move left 1 character or cell");
00390   viewer_help->push_back("                   if at the beginning of the cell");
00391   viewer_help->push_back("    right arrow -- move right 1 character or cell");
00392   viewer_help->push_back("                   if at the end of text in the cell");
00393   viewer_help->push_back("    tab         -- move right one cell");
00394   viewer_help->push_back("    shift-tab   -- move left one cell");
00395   viewer_help->push_back("    ^A          -- move to left of the text in the cell");
00396   viewer_help->push_back("    ^E          -- move to the right of the text in the cell");
00397   viewer_help->push_back("    ^Q          -- move left 1 whole page");
00398   viewer_help->push_back("    ^P          -- move right 1 whole page");
00399   viewer_help->push_back("");
00400   viewer_help->push_back("  Editing keys");
00401   viewer_help->push_back("    Delete      -- deletes the current character");
00402   viewer_help->push_back("    Backspace   -- deletes the previous character");
00403   viewer_help->push_back("    F8          -- deletes the current row");
00404   viewer_help->push_back("    F9          -- inserts a new row above");
00405   viewer_help->push_back("    F11         -- inserts a new row below");
00406   viewer_help->push_back("");
00407   viewer_help->push_back("  Other keys");
00408   viewer_help->push_back("");
00409   viewer_help->push_back("    printable characters get inserted into the cell");
00410   viewer_help->push_back("");
00411   viewer_help->push_back("    non-printable characters are treated as exit commands");
00412 
00413   manager_->help_helper(*viewer_help);
00414 }
00415 
00416 } // namespace cxxtls
Generated on Wed Feb 29 22:50:04 2012 for CXXUtilities by  doxygen 1.6.3