00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <fcntl.h>
00021 #include <sys/types.h>
00022 #include <sys/stat.h>
00023 #include <errno.h>
00024 #include <string.h>
00025 #include <stdlib.h>
00026 #include <unistd.h>
00027 #include <dirent.h>
00028
00029 #ifndef HAVE_PATHCONF
00030 #if HAVE_LIMITS_H
00031 # include <limits.h>
00032 #elif HAVE_SYS_PARAM_H
00033 # include <sys/param.h>
00034 #endif
00035 #ifndef PATH_MAX
00036 # if defined(_POSIX_PATH_MAX)
00037 # define PATH_MAX _POSIX_PATH_MAX
00038 # elif defined(MAXPATHLEN)
00039 # define PATH_MAX MAXPATHLEN
00040 # else
00041 # define PATH_MAX 255
00042 # endif
00043 #endif
00044 #endif // HAVE_PATHCONF
00045
00046 #ifdef HAVE_ALGORITHM
00047 # include <algorithm>
00048 #endif
00049
00050 #include <messagebox.h>
00051 #include <colors.h>
00052 #include "fileopen.h"
00053
00054 void
00055 FileOpen::createWindows() throw (YAPETUI::UIException) {
00056 if (window != NULL) return;
00057
00058 window = newwin (windowHeight(), windowWidth(), startY(), startX());
00059 if (window == NULL)
00060 throw YAPETUI::UIException ("Error creating file open window");
00061
00062 std::list<YAPETUI::secstring> dir_list;
00063 std::list<YAPETUI::secstring> file_list;
00064 getEntries(dir_list, file_list);
00065 dir = new YAPETUI::ListWidget<YAPETUI::secstring>(dir_list,
00066 startX()+1,
00067 startY()+2,
00068 windowWidth()/2-1,
00069 windowHeight()-6);
00070
00071 files = new YAPETUI::ListWidget<YAPETUI::secstring>(file_list,
00072 startX() + windowWidth()/2 ,
00073 startY() + 2,
00074 windowWidth()/2-1,
00075 windowHeight()-6);
00076
00077 input = new YAPETUI::InputWidget(startX()+1,
00078 startY()+windowHeight()-3,
00079 windowWidth()-2);
00080
00081 okbutton = new YAPETUI::Button("OK",
00082 startX()+1,
00083 startY()+windowHeight()-2);
00084
00085 cancelbutton = new YAPETUI::Button("Cancel",
00086 startX()+8,
00087 startY()+windowHeight()-2);
00088
00089 }
00090
00091 void
00092 FileOpen::getEntries(std::list<YAPETUI::secstring>& d,
00093 std::list<YAPETUI::secstring>& f)
00094 throw(YAPETUI::UIException) {
00095
00096 DIR* dir_ptr = opendir(directory.c_str());
00097 if (dir_ptr == NULL)
00098 throw YAPETUI::UIException(strerror(errno));
00099
00100 struct dirent* de;
00101 struct stat st;
00102
00103 while ( (de = readdir(dir_ptr)) != NULL) {
00104 int retval = stat( YAPETUI::secstring(directory +"/"+de->d_name).c_str(), &st);
00105 if (retval != 0) {
00106 continue;
00107 }
00108
00109 if (S_ISDIR(st.st_mode)) {
00110 d.push_back(de->d_name);
00111 } else if (S_ISREG(st.st_mode)) {
00112 std::string tmp(de->d_name);
00113 if (endswith(tmp, ".pet") )
00114 f.push_back(de->d_name);
00115 }
00116 }
00117 closedir(dir_ptr);
00118
00119 d.sort();
00120 f.sort();
00121 }
00122
00123 void
00124 FileOpen::printTitle() throw(YAPETUI::UIException) {
00125 int retval = mymvwaddstr(window, 0, 2, title.c_str());
00126 if (retval == ERR)
00127 throw YAPETUI::UIException("Error printing title");
00128 }
00129
00130 void
00131 FileOpen::printCWD() throw(YAPETUI::UIException) {
00132 char format[50];
00133 snprintf(format, 50, "%%-%ds", (windowWidth()-2));
00134
00135 int retval = mvwprintw(window, 1, 1, format, " ");
00136 if (retval == ERR)
00137 throw YAPETUI::UIException("Error clearing line");
00138
00139 retval = mymvwaddstr(window, 1, 1, directory.c_str());
00140 if (retval == ERR)
00141 throw YAPETUI::UIException("Error printing cwd");
00142
00143 retval = wrefresh(window);
00144 if (retval == ERR)
00145 throw YAPETUI::UIException("Error refreshing cwd");
00146 }
00147
00148 void
00149 FileOpen::getcwd() throw (YAPETUI::UIException) {
00150 long size = 0;
00151 #ifdef HAVE_PATHCONF
00152 size = pathconf (".", _PC_PATH_MAX);
00153 size = size < 1 ? FALLBACK_PATH_MAX : size;
00154 #else
00155 size = MAX_PATH;
00156 #endif
00157 char* buf = (char *) malloc ( (size_t) size);
00158 if (buf == NULL)
00159 throw YAPETUI::UIException ("Error allocating memory");
00160
00161 char* ptr = ::getcwd (buf, (size_t) size);
00162 if (ptr == NULL) {
00163 free (buf);
00164 throw YAPETUI::UIException (strerror (errno));
00165 }
00166
00167 directory = ptr;
00168 free (ptr);
00169 }
00170
00171 void
00172 FileOpen::cd (const YAPETUI::secstring d) throw (YAPETUI::UIException) {
00173 int retval = chdir (d.c_str());
00174 if (retval != 0)
00175 throw YAPETUI::UIException (strerror (errno));
00176
00177 getcwd();
00178 }
00179
00180 FileOpen::FileOpen(std::string t) throw(YAPETUI::UIException) : BaseWindow(),
00181 title(t),
00182 window (NULL),
00183 dir (NULL),
00184 files (NULL),
00185 input(NULL),
00186 okbutton(NULL),
00187 cancelbutton(NULL),
00188 canceled(true) {
00189 getcwd();
00190 createWindows();
00191
00192 }
00193
00194 FileOpen::~FileOpen() {
00195 wclear(window);
00196 delwin (window);
00197 delete dir;
00198 delete files;
00199 delete input;
00200 delete okbutton;
00201 delete cancelbutton;
00202 }
00203
00204 void
00205 FileOpen::run() throw (YAPETUI::UIException) {
00206 std::list<YAPETUI::secstring> file_list;
00207 std::list<YAPETUI::secstring> dir_list;
00208
00209 refresh();
00210
00211 int ch;
00212
00213 while(true){
00214
00215
00216 while ( (ch= dir->focus()) != '\t') {
00217 switch (ch) {
00218 #ifdef HAVE_WRESIZE
00219 case KEY_RESIZE:
00220 YAPETUI::BaseWindow::resizeAll();
00221 break;
00222 #endif // HAVE_WRESIZE
00223 case KEY_ENTER:
00224 case '\n': {
00225 try {
00226 file_list.clear();
00227 dir_list.clear();
00228 cd(dir->getSelectedItem());
00229 getEntries(dir_list, file_list);
00230 files->setList(file_list);
00231 dir->setList(dir_list);
00232 printCWD();
00233 } catch (YAPETUI::UIException& ex) {
00234 YAPETUI::MessageBox* tmp =
00235 new YAPETUI::MessageBox("Error", ex.what());
00236 tmp->run();
00237 delete tmp;
00238 this->refresh();
00239 }
00240 }
00241 break;
00242 }
00243 }
00244
00245
00246 while ( (ch = files->focus()) != '\t') {
00247 switch (ch) {
00248 #ifdef HAVE_WRESIZE
00249 case KEY_RESIZE:
00250 YAPETUI::BaseWindow::resizeAll();
00251 break;
00252 #endif // HAVE_WRESIZE
00253 case KEY_ENTER:
00254 case '\n':
00255 filename = files->getSelectedItem();
00256 input->setText(filename);
00257 break;
00258 }
00259 }
00260
00261 #ifdef HAVE_WRESIZE
00262 while ( (ch = input->focus()) == KEY_RESIZE)
00263 YAPETUI::BaseWindow::resizeAll();
00264 #else // HAVE_WRESIZE
00265 ch = input->focus();
00266 #endif // HAVE_WRESIZE
00267 filename = input->getText();
00268
00269
00270
00271 #ifdef HAVE_WRESIZE
00272 while ( (ch = okbutton->focus()) == KEY_RESIZE)
00273 YAPETUI::BaseWindow::resizeAll();
00274 #else // HAVE_WRESIZE
00275 ch = okbutton->focus();
00276 #endif // HAVE_WRESIZE
00277 if (ch == '\n' || ch == KEY_ENTER) {
00278 canceled = false;
00279 return;
00280 }
00281
00282
00283 #ifdef HAVE_WRESIZE
00284 while ( (ch = cancelbutton->focus()) == KEY_RESIZE)
00285 YAPETUI::BaseWindow::resizeAll();
00286 #else // HAVE_WRESIZE
00287 ch = cancelbutton->focus();
00288 #endif // HAVE_WRESIZE
00289 if (ch == '\n' || ch == KEY_ENTER) {
00290 canceled = true;
00291 return;
00292 }
00293 }
00294 }
00295
00296 void
00297 FileOpen::refresh() throw (YAPETUI::UIException) {
00298 YAPETUI::Colors::setcolor(window, YAPETUI::MESSAGEBOX);
00299
00300
00301
00302 int retval = box(window, 0, 0);
00303 if (retval == ERR)
00304 throw YAPETUI::UIException("Error drawing box");
00305
00306 printTitle();
00307 printCWD();
00308
00309 retval = wrefresh (window);
00310 if (retval == ERR)
00311 throw YAPETUI::UIException ("Error refreshing window");
00312
00313 dir->refresh();
00314 files->refresh();
00315 input->refresh();
00316 okbutton->refresh();
00317 cancelbutton->refresh();
00318 }
00319
00320 void
00321 FileOpen::resize() throw (YAPETUI::UIException) {
00322 delete dir;
00323 delete files;
00324 delete input;
00325 delete okbutton;
00326 delete cancelbutton;
00327
00328 int retval = delwin(window);
00329 if (retval == ERR)
00330 throw YAPETUI::UIException("Error deleting window");
00331
00332 window = NULL;
00333 dir = NULL;
00334 files = NULL;
00335 input = NULL;
00336 okbutton = NULL;
00337 cancelbutton = NULL;
00338
00339 createWindows();
00340 }
00341
00342 std::string
00343 FileOpen::getFilepath() {
00344 if (!endswith(filename, ".pet"))
00345 filename+=".pet";
00346
00347 std::string tmp_filename(filename.c_str());
00348 std::string tmp_directory(directory.c_str());
00349 if (tmp_directory == "/")
00350 return tmp_directory + tmp_filename;
00351
00352 return tmp_directory + "/" + tmp_filename;
00353 }