libyui-ncurses  2.44.1
/usr/src/RPM/BUILD/libyui-ncurses-2.44.1/src/NCAskForFile.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:       NCAskForFile.cc
00020 
00021    Author:     Gabriele Strattner <gs@suse.de>
00022 
00023 /-*/
00024 
00025 #define  YUILogComponent "ncurses"
00026 #include <yui/YUILog.h>
00027 
00028 #include "NCAskForFile.h"
00029 
00030 #include <yui/YDialog.h>
00031 
00032 #include "NCWidgetFactory.h"
00033 #include "NCLayoutBox.h"
00034 #include "NCSpacing.h"
00035 #include "NCFrame.h"
00036 #include "NCi18n.h"
00037 
00038 #include <sys/types.h>
00039 #include <sys/stat.h>
00040 #include <unistd.h>
00041 #include <dirent.h>
00042 #include <sys/errno.h>
00043 
00044 /*
00045   Textdomain "ncurses"
00046 */
00047 
00048 
00049 NCAskForFile::NCAskForFile( const wpos at,
00050                             const std::string & iniDir,
00051                             const std::string & filter,
00052                             const std::string & headline )
00053     : NCPopup( at, true )
00054     , okButton( 0 )
00055     , cancelButton( 0 )
00056     , dirName( 0 )
00057     , dirList( 0 )
00058     , detailed( 0 )
00059     , fileList( 0 )
00060     , fileName( 0 )
00061 {
00062 
00063 }
00064 
00065 
00066 NCAskForFile::~NCAskForFile( )
00067 {
00068 
00069 }
00070 
00071 
00072 std::string NCAskForFile::checkIniDir( std::string iniDir )
00073 {
00074     std::string dname = "";
00075 
00076     struct stat64 statInfo;
00077     stat64( iniDir.c_str(), &statInfo );
00078 
00079     if ( S_ISDIR( statInfo.st_mode ) )
00080     {
00081         dname = iniDir;
00082     }
00083     else
00084     {
00085         std::string::size_type pos;
00086 
00087         pos = iniDir.find_last_of( "/" );
00088 
00089         if ( pos != std::string::npos
00090              && pos != 0 )
00091         {
00092             std::string dir = iniDir.substr( 0, pos );
00093             stat64( dir.c_str(), &statInfo );
00094 
00095             if ( S_ISDIR( statInfo.st_mode ) )
00096             {
00097                 dname = dir;
00098                 iniFileName  = iniDir.substr( pos + 1 );
00099             }
00100         }
00101     }
00102 
00103     return dname;
00104 }
00105 
00106 
00107 void NCAskForFile::createLayout( const std::string & iniDir,
00108                                  const std::string & filter,
00109                                  const std::string & headline,
00110                                  bool edit )
00111 {
00112     std::string startDir;
00113     std::string old_textdomain = textdomain( NULL );
00114     setTextdomain( "ncurses" );
00115 
00116     startDir = checkIniDir( iniDir );
00117 
00118     // the vertical split is the (only) child of the dialog
00119     YLayoutBox * split = YUI::widgetFactory()->createVBox( this );
00120 
00121     new NCLabel( split, headline, true, false ); // isHeading = true
00122 
00123     YFrame * frame = YUI::widgetFactory()->createFrame( split, "" );
00124 
00125     // label for text field showing the selected dir
00126     dirName = new NCComboBox( frame, _( "Selected Directory:" ), false );  // editable = false;
00127     dirName->setNotify( true );
00128     dirName->setStretchable( YD_HORIZ, true );
00129 
00130     // add the checkBox detailed
00131     YLayoutBox * hSplit = YUI::widgetFactory()->createHBox( split );
00132 
00133     // label for checkbox
00134     detailed = new NCCheckBox( hSplit, _( "&Detailed View" ), false );
00135     detailed->setNotify( true );
00136 
00137     // HBox for the lists
00138     YLayoutBox * hSplit1 = YUI::widgetFactory()->createHBox( split );
00139 
00140     // create table header for table type T_Overview
00141     YTableHeader * dirHeader = new YTableHeader();
00142     dirHeader->addColumn( " " );
00143     dirHeader->addColumn( _( "Directory name" ) );
00144 
00145     // add the list of directories
00146     dirList = new NCDirectoryTable( hSplit1,
00147                                     dirHeader,
00148                                     NCFileSelection::T_Overview,
00149                                     startDir );
00150     dirList->setSendKeyEvents( true );
00151 
00152     // create table header for table type T_Overview
00153     YTableHeader * fileHeader = new YTableHeader();
00154     fileHeader->addColumn( " " );
00155     fileHeader->addColumn( _( "File name" ) );
00156 
00157     // add the list of files
00158     fileList = new NCFileTable( hSplit1,
00159                                 fileHeader,
00160                                 NCFileSelection::T_Overview,
00161                                 filter,
00162                                 startDir );
00163 
00164     fileList->setSendKeyEvents( true );
00165 
00166     YLayoutBox * hSplit2 = YUI::widgetFactory()->createHBox( split );
00167 
00168     // opt.isEditable.setValue( edit );
00169     // NCInputField doesn't support mode 'not editable' any longer
00170     // -> an InputField IS editable
00171 
00172     // add the text entry for the file name
00173     fileName = new NCInputField( hSplit2,
00174                                  // label for text field showing the filename
00175                                  _( "&File name:" ),
00176                                  false,         // passWordMode = false
00177                                  100,
00178                                  50 );
00179     fileName->setValue( iniFileName );
00180 
00181     // label for text field showing the filter (e.g. *.bak)
00182     NCComboBox * extension = new NCComboBox( hSplit2, _( "Filter:" ), false );  // editable = false
00183     extension->setStretchable( YD_HORIZ, true );
00184     extension->addItem( filter,
00185                         true );  // selected
00186 
00187     YUI::widgetFactory()->createSpacing( split, YD_VERT, false, 1.0 );
00188 
00189     // HBox for the buttons
00190     YLayoutBox * hSplit3 = YUI::widgetFactory()->createHBox( split );
00191 
00192     YUI::widgetFactory()->createSpacing( hSplit3, YD_HORIZ, true, 0.2 );  // stretchable = true
00193 
00194     // add the OK button
00195     okButton = new NCPushButton( hSplit3, _( "&OK" ) );
00196     okButton->setFunctionKey( 10 );
00197     okButton->setStretchable( YD_HORIZ, true );
00198 
00199     YUI::widgetFactory()->createSpacing( hSplit3, YD_HORIZ, true, 0.4 );
00200 
00201     // add the Cancel button
00202     cancelButton = new NCPushButton( hSplit3, _( "&Cancel" ) );
00203     cancelButton->setFunctionKey( 9 );
00204     cancelButton->setStretchable( YD_HORIZ, true );
00205 
00206     YUI::widgetFactory()->createSpacing( hSplit3, YD_HORIZ, true, 0.2 );
00207     // restore former text domain
00208     setTextdomain( old_textdomain.c_str() );
00209 }
00210 
00211 
00212 NCursesEvent & NCAskForFile::showDirPopup( )
00213 {
00214     postevent = NCursesEvent();
00215 
00216     if ( !dirList || !fileList || !dirName )
00217         return postevent;
00218 
00219     dirList->fillList();
00220     fileList->fillList();
00221     dirList->setKeyboardFocus();
00222     dirName->addItem( dirList->getCurrentDir(),
00223                       true );            // selected
00224 
00225     if ( iniFileName == "" )
00226         // show the currently selected file
00227         fileName->setValue( fileList->getCurrentFile() );
00228 
00229     // event loop
00230     do
00231     {
00232         popupDialog();
00233     }
00234     while ( postAgain() );
00235 
00236     popdownDialog();
00237 
00238     return postevent;
00239 }
00240 
00241 
00242 int NCAskForFile::preferredWidth()
00243 {
00244     return  NCurses::cols() - 10;
00245 }
00246 
00247 
00248 int NCAskForFile::preferredHeight()
00249 {
00250     return NCurses::lines() - 4;
00251 }
00252 
00253 
00254 NCursesEvent NCAskForFile::wHandleInput( wint_t ch )
00255 {
00256     if ( ch == 27 ) // ESC
00257         return NCursesEvent::cancel;
00258 
00259     return NCDialog::wHandleInput( ch );
00260 }
00261 
00262 
00263 void NCAskForFile::updateFileList()
00264 {
00265     // set new start dir and show the file list
00266     fileList->setStartDir( dirList->getCurrentDir() );
00267     fileList->fillList( );
00268 
00269     if ( iniFileName == "" )
00270         // show the currently selected file
00271         fileName->setValue( fileList->getCurrentFile() );
00272 }
00273 
00274 
00275 bool NCAskForFile::postAgain( )
00276 {
00277     if ( !postevent.widget )
00278         return false;
00279 
00280     postevent.detail = NCursesEvent::NODETAIL;
00281 
00282     if ( postevent.keySymbol == "CursorLeft" )
00283     {
00284         dirList->setKeyboardFocus();
00285         return true;
00286     }
00287     else if ( postevent.keySymbol == "CursorRight" )
00288     {
00289         fileList->setKeyboardFocus();
00290         fileName->setValue( fileList->getCurrentFile() );
00291         return true;
00292     }
00293 
00294     if ( postevent.widget == okButton )
00295     {
00296         postevent.result = dirList->getCurrentDir() + "/" + getFileName();
00297         // return false means: close the popup
00298         return false;
00299     }
00300     else if (( postevent.widget == dirList ) &&
00301              ( postevent.result != "" ) )
00302     {
00303         // show the currently selected directory
00304         dirName->addItem( postevent.result,
00305                           true );
00306         updateFileList();
00307 
00308         if ( postevent.reason == YEvent::Activated )
00309         {
00310             // fill directory and file list
00311             dirList->fillList();
00312             updateFileList();
00313         }
00314     }
00315     else if ( postevent.widget == dirName )
00316     {
00317         dirList->setStartDir( dirName->text() );
00318         dirList->fillList();
00319 
00320         updateFileList();
00321     }
00322     else if ( postevent.widget == detailed )
00323     {
00324         bool details = getCheckBoxValue( detailed );
00325 
00326         if ( details )
00327         {
00328             fileList->setTableType( NCFileTable::T_Detailed );
00329             dirList->setTableType( NCFileTable::T_Detailed );
00330         }
00331         else
00332         {
00333             fileList->setTableType( NCFileTable::T_Overview );
00334             dirList->setTableType( NCFileTable::T_Overview );
00335         }
00336 
00337         fileList->fillList();
00338 
00339         dirList->fillList();
00340     }
00341     else if ( postevent.widget == fileList )
00342     {
00343         if ( postevent.result != "" )
00344         {
00345             fileName->setValue( postevent.result );
00346         }
00347     }
00348     else
00349     {
00350         postevent.result = "";
00351         return false;
00352     }
00353 
00354     if ( postevent.widget == cancelButton ||
00355          postevent == NCursesEvent::cancel )
00356     {
00357         postevent.result = "";
00358         return false;
00359     }
00360 
00361     return true;
00362 }
00363 
00364 
00365 bool NCAskForFile::getCheckBoxValue( NCCheckBox * checkBox )
00366 {
00367     if ( checkBox )
00368     {
00369         // return whether the option is selected or not
00370         return ( checkBox->isChecked() );
00371     }
00372 
00373     return false;
00374 }
00375 
00376 
00377 NCAskForExistingFile::NCAskForExistingFile( const wpos at,
00378                                             const std::string & iniDir,
00379                                             const std::string & filter,
00380                                             const std::string & headline )
00381     : NCAskForFile( at, iniDir, filter, headline )
00382 {
00383     createLayout( iniDir,
00384                   filter,
00385                   headline,
00386                   false );      // file name is not editable
00387 }
00388 
00389 
00390 std::string NCAskForExistingFile::getFileName()
00391 {
00392     if ( fileName->value() == "" )
00393         return fileList->getCurrentFile();
00394     else
00395         return fileName->value();
00396 }
00397 
00398 
00399 NCAskForSaveFileName::NCAskForSaveFileName( const wpos at,
00400                                             const std::string & iniDir,
00401                                             const std::string & filter,
00402                                             const std::string & headline )
00403     : NCAskForFile( at, iniDir, filter, headline )
00404 {
00405     createLayout( iniDir,
00406                   filter,
00407                   headline,
00408                   true );       // file name is editable
00409 }
00410 
00411 
00412 std::string NCAskForSaveFileName::getFileName()
00413 {
00414     return fileName->value();
00415 }
 All Classes Functions Variables