/* ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 1, or (at your option) ** any later version. ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Author : Alexandre Parenteau --- December 1997 */ /* * PromptFiles.cpp --- class to pick set of files and folder */ #include "stdafx.h" #ifdef macintosh # include "GUSIInternal.h" # include "GUSIFileSpec.h" # include # include # include # include "stdfolder.h" # include "stdmfiles.h" # include "VolsPaths.h" #endif /* macintosh */ #if qMacPP # include # include #endif #include "PromptFiles.h" #include "MultiFiles.h" #include "AppConsole.h" #ifdef qQT # include "qcvsapp.h" # include "CPStr.h" # include "TextBinary.h" # include # include # include #endif /* qQT */ #ifdef qGTK # include # include # include "TextBinary.h" #endif /* qGTK */ #ifdef WIN32 # ifdef _DEBUG # define new DEBUG_NEW # undef THIS_FILE static char THIS_FILE[] = __FILE__; # endif #endif /* WIN32 */ #ifdef macintosh //{ Mac - Part const char * BrowserGetDirectory(const char *prompt) { # if qMacPP # if !qCarbon if(UConditionalDialogs::UseNavServices()) # else if(1) # endif { UNavServicesDialogs::LFileChooser chooser; FSSpec folderReply; SInt32 outFolderDirID; if(!chooser.AskChooseFolder(folderReply, outFolderDirID)) return 0L; static char cres[256]; GUSIFileSpec dirSpec(folderReply); strcpy(cres, dirSpec.FullPath()); return cres; } # endif # if !qCarbon FSSpec folderReply; Point apt = {-1, -1}; Str255 pprompt; strcpy((char *)pprompt, prompt); c2pstr((char *)pprompt); if(!SF_PromptForFolder(apt, pprompt, &folderReply)) return NULL; GUSIFileSpec spec = folderReply; static char aPath[512]; strcpy(aPath, spec.FullPath()); if(spec.Error() != noErr) { cvs_err("MacCvs: Unable to convert path name\n"); return NULL; } return aPath; # else return 0L; # endif } // enumerate the multiple files extern "C" { static void MacEnumFiles_hook(UFSSpec *newFile, MultiFiles *mf) { #if TARGET_RT_MAC_CFM char cname[64]; p2cstrcpy(cname, newFile->name); mf->newfile(cname, newFile); #else UInt8 utf8path[PATH_MAX]; if(FSRefMakePath(newFile, utf8path, sizeof(utf8path)) == noErr) { UStr uppath, cname; SplitPath(utf8_to_posix(utf8path), uppath, cname); mf->newfile(cname, newFile); } #endif } } // prompt for multiple files bool BrowserGetMultiFiles(const char *prompt, MultiFiles & mf) { Point apt = {-1, -1}; Str255 pprompt; c2pstrcpy(pprompt, prompt); if(!SF_PromptForMFiles(apt, pprompt)) return false; SF_PFMF_INFO info; UFSSpec dirSpec; SF_PFMF_BeginTraversal(&info); while(1) { if(!SF_PFMF_GetCurrentDir(&info, &dirSpec)) break; char aPath[255]; GUSIFileSpec spec = dirSpec; strcpy(aPath, spec.FullPath()); if(spec.Error() != noErr) { cvs_err("MacCvs: Unable to convert path name\n"); return false; } mf.newdir(aPath); if(!SF_PFMF_DoTraversal(&info, true, (SF_PFMF_HOOK)MacEnumFiles_hook, &mf)) return false; } SF_PFMF_EndTraversal(&info); return true; } #endif //{ macintosh #ifdef WIN32 //{ Win32 - Part # if oldWay static BOOL CALLBACK APIENTRY MyDirOpen(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: { LPOPENFILENAME pofn = (LPOPENFILENAME)lParam; if(pofn && pofn->lpstrTitle) { SetDlgItemText (hDlg, 1090, pofn->lpstrTitle); } return TRUE; } case WM_COMMAND: { if (LOWORD(wParam) == IDOK) { EndDialog(hDlg, wParam); return TRUE; } } } return FALSE; } bool BrowserGetDirectory(const char * prompt, char* fileName, int size) { OPENFILENAME ofn; // set default informations memset(&ofn, 0, sizeof(OPENFILENAME)); ofn.lStructSize = sizeof(OPENFILENAME); ofn.hwndOwner = *AfxGetMainWnd(); ofn.lpstrFilter = NULL; ofn.nFilterIndex = 0; ofn.lpstrFile = fileName; ofn.nMaxFile = size; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = (fileName[0]) ? fileName : NULL; ofn.lpstrTitle = prompt; ofn.lpTemplateName = "MYFOLDEROPENORD"; ofn.hInstance = AfxGetResourceHandle(); ofn.lpfnHook = (LPOFNHOOKPROC)MyDirOpen; ofn.Flags = OFN_ENABLEHOOK | OFN_ENABLETEMPLATE; if (GetOpenFileName( &ofn )) { GetCurrentDirectory(size, fileName); return true; } else { // LM TRACE("Retrun error of GetOpenFileName() = %0x\n", CommDlgExtendedError()); // CDERR_DIALOGFAILURE } return false; } # else // !oldWay bool BrowserGetDirectory(const char* prompt, char* fileName, int size, CWnd* pParentWnd) { CCJShell m_shell; m_shell.m_strTitle = (prompt) ? prompt : ""; if (fileName[0]) { m_shell.m_strSelDir = fileName; } if( m_shell.BrowseForFolder(pParentWnd != 0L ? pParentWnd : AfxGetMainWnd()) ) { lstrcpyn(fileName, m_shell.m_strPath, size); return true; } return false; } # endif // !oldWay static char sDefaultPath[MAX_PATH]; const char * BrowserGetDirectory(const char *prompt, CWnd* pParentWnd) { BOOL selected = BrowserGetDirectory(prompt, sDefaultPath, MAX_PATH, pParentWnd); return (selected) ? sDefaultPath : NULL; } bool BrowserGetMultiFiles(const char *prompt, MultiFiles & mf, const char* lpszFilter) { bool result = false; CFileDialog fd(true, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT | OFN_FILEMUSTEXIST, lpszFilter ); fd.m_ofn.nMaxFile = 38000 * sizeof(char); fd.m_ofn.lpstrFile = (char *)malloc(fd.m_ofn.nMaxFile * sizeof(char)); fd.m_ofn.lpstrTitle = prompt; fd.m_ofn.lpstrInitialDir = sDefaultPath[0] != '\0' ? sDefaultPath : NULL; fd.m_ofn.nMaxFileTitle = 38000; fd.m_ofn.lpstrFileTitle = (char *)malloc(fd.m_ofn.nMaxFileTitle * sizeof(char)); if(fd.m_ofn.lpstrFile == NULL || fd.m_ofn.lpstrFileTitle == NULL) { cvs_err("Impossible to allocate %d bytes !\n", 38000 * sizeof(char)); exit(1); } // add the directory and the files fd.m_ofn.lpstrFile[0] = '\0'; fd.m_ofn.lpstrFileTitle[0] = '\0'; if(fd.DoModal() == IDOK) { GetCurrentDirectory(sizeof(sDefaultPath), sDefaultPath); const char *tmp = fd.m_ofn.lpstrFile; if(fd.m_ofn.lpstrFileTitle[0] == '\0') { mf.newdir(tmp); tmp += strlen(tmp) + 1; while(tmp[0] != '\0') { mf.newfile(tmp); tmp += strlen(tmp) + 1; } } else { mf.newdir(sDefaultPath); mf.newfile(tmp + fd.m_ofn.nFileOffset); } result = true; } free(fd.m_ofn.lpstrFile); free(fd.m_ofn.lpstrFileTitle); return result; } #endif //{ WIN32 #ifdef qQT //{ QT - Part const char * BrowserGetDirectory(const char *prompt) { QFileDialog::Mode mode = QFileDialog::Directory; QString start(QDir::currentDirPath()); QString filter("*"); QString caption(prompt); QFileDialog fd(start, filter, 0, 0L, TRUE ); fd.setMode(mode); fd.setCaption(caption); fd.setSelection(start); if (fd.exec() == QDialog::Accepted) { static CStr result; result = fd.dirPath(); return result; } return 0L; } extern "C" { static int compareCStr(const CStr *s1, const CStr *s2) { return strcmp(*s1, *s2); } } bool BrowserGetMultiFiles(const char *prompt, MultiFiles & mf) { QStringList s = QFileDialog::getOpenFileNames(); vector allpaths; QStringList::Iterator f; for (f = s.begin(); f != s.end(); f++) { allpaths.push_back(CStr(*f)); } if(allpaths.size() == 0) return false; qsort(&allpaths[0], allpaths.size(), sizeof(CStr), (int (*)(const void *, const void *))compareCStr); vector::const_iterator i; CStr uppath, file, oldpath; for(i = allpaths.begin(); i != allpaths.end(); ++i) { SplitPath(*i, uppath, file); if(strcmp(uppath, oldpath) != 0) mf.newdir(uppath); oldpath = uppath; mf.newfile(file); } return true; } #endif //} qQT #ifdef qGTK //{ GTK - Part static CStr gtksel; static bool gtkModalLoop; static gint gtkcancel(GtkWidget *widget, gpointer data) { gtkModalLoop = false; return TRUE; } static void file_ok_sel (GtkWidget *w, gpointer data) { gtkModalLoop = false; gtksel = gtk_file_selection_get_filename(GTK_FILE_SELECTION (data)); } static void file_cancel_sel (GtkWidget *w, gpointer data) { gtkModalLoop = false; } static void fileop_c_dir_sel (GtkWidget *w, gpointer data) { GtkWidget *dialog = GTK_FILE_SELECTION (GTK_WIDGET (data))->fileop_dialog; gtk_grab_add (dialog); // remove grab from fileselection dialog gtk_grab_remove (GTK_WIDGET (data)); fprintf(stderr, "fileop_c_dir open\n"); } const char * BrowserGetDirectory(const char *prompt) { /* Create a new file selection widget */ GtkWidget *filew = gtk_file_selection_new (prompt); gtk_signal_connect(GTK_OBJECT(filew), "delete_event", GTK_SIGNAL_FUNC(gtkcancel), 0L); /* Connect the ok_button to file_ok_sel function */ gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button), "clicked", (GtkSignalFunc) file_ok_sel, filew); gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->cancel_button), "clicked", (GtkSignalFunc) file_cancel_sel, filew); //{ WORKAROUND Bug #440874 // call 'fileop_c_dir_sel' when file options selected gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->fileop_c_dir), "clicked", (GtkSignalFunc) fileop_c_dir_sel, filew); //} WORKAROUND Bug #440874 gtkModalLoop = true; gtksel = ""; gtk_widget_show(filew); //{ WORKAROUND Bug 440874: blocks keyboard in create dialog if uncommented gtk_grab_add (filew); //} WORKAROUND Bug 440874 while (gtkModalLoop) { gtk_main_iteration_do(TRUE); } //{ WORKAROUND Bug 440874: blocks keyboard in create dialog if uncommented gtk_grab_remove (filew); //} BWORKAROUND ug 440874 gtk_widget_destroy(filew); if(!gtksel.empty()) { static CStr fname; fname = gtksel; if(fname.empty()) return 0L; struct stat sb; if (stat(fname, &sb) != -1 && S_ISREG(sb.st_mode)) { CStr uppath, file; SplitPath(fname, uppath, file); fname = uppath; } if(fname.endsWith(kPathDelimiter)) fname[fname.length() - 1] = '\0'; return fname; } return 0L; } bool BrowserGetMultiFiles(const char *prompt, MultiFiles & mf) { /* Create a new file selection widget */ GtkWidget *filew = gtk_file_selection_new (prompt); gtk_signal_connect(GTK_OBJECT(filew), "delete_event", GTK_SIGNAL_FUNC(gtkcancel), 0L); /* Connect the ok_button to file_ok_sel function */ gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->ok_button), "clicked", (GtkSignalFunc) file_ok_sel, filew); gtk_signal_connect (GTK_OBJECT (GTK_FILE_SELECTION (filew)->cancel_button), "clicked", (GtkSignalFunc) file_cancel_sel, filew); gtkModalLoop = true; gtksel = ""; gtk_widget_show(filew); //{ WORKAROUND Bug 440874: Directory creation is not necessary in this file selection box gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(filew)); //{ WORKAROUND Bug 440874 gtk_grab_add (filew); while (gtkModalLoop) { gtk_main_iteration_do(TRUE); } gtk_grab_remove (filew); gtk_widget_destroy(filew); if(!gtksel.empty()) { CStr fname = gtksel; if(fname.empty()) return false; CStr uppath, file; SplitPath(fname, uppath, file); mf.newdir(uppath); mf.newfile(file); return true; } return false; } #endif //} qGTK