libyui-ncurses
2.44.1
|
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 }