1///////////////////////////////////////////////////////////////////////////// 2// Name: src/cocoa/filedlg.mm 3// Purpose: wxFileDialog for wxCocoa 4// Author: Ryan Norton 5// Modified by: 6// Created: 2004-10-02 7// Copyright: (c) Ryan Norton 8// Licence: wxWindows licence 9///////////////////////////////////////////////////////////////////////////// 10 11// ============================================================================ 12// declarations 13// ============================================================================ 14 15// ---------------------------------------------------------------------------- 16// headers 17// ---------------------------------------------------------------------------- 18 19// For compilers that support precompilation, includes "wx.h". 20#include "wx/wxprec.h" 21 22#if wxUSE_FILEDLG 23 24#include "wx/filedlg.h" 25 26#ifndef WX_PRECOMP 27 #include "wx/msgdlg.h" 28 #include "wx/app.h" 29#endif 30 31#include "wx/filename.h" 32 33#include "wx/cocoa/autorelease.h" 34#include "wx/cocoa/string.h" 35#include "wx/modalhook.h" 36 37#import <AppKit/NSOpenPanel.h> 38#import <AppKit/NSSavePanel.h> 39 40#import <Foundation/NSArray.h> 41// ============================================================================ 42// implementation 43// ============================================================================ 44 45IMPLEMENT_CLASS(wxCocoaFileDialog, wxFileDialogBase) 46 47// ---------------------------------------------------------------------------- 48// wxFileDialog 49// ---------------------------------------------------------------------------- 50 51wxFileDialog::wxFileDialog(wxWindow *parent, 52 const wxString& message, 53 const wxString& defaultDir, 54 const wxString& defaultFileName, 55 const wxString& wildCard, 56 long style, 57 const wxPoint& pos, 58 const wxSize& sz, 59 const wxString& name) 60 : wxFileDialogBase(parent, message, defaultDir, defaultFileName, 61 wildCard, style, pos, sz, name) 62{ 63 wxTopLevelWindows.Append(this); 64 65 wxASSERT(CreateBase(parent,wxID_ANY,pos,wxDefaultSize,style,wxDefaultValidator,wxDialogNameStr)); 66 67 if ( parent ) 68 parent->AddChild(this); 69 70 m_cocoaNSWindow = nil; 71 m_cocoaNSView = nil; 72 73 //Init the wildcard array 74 m_wildcards = [[NSMutableArray alloc] initWithCapacity:0]; 75 76 //If the user requests to save - use a NSSavePanel 77 //else use a NSOpenPanel 78 if (HasFlag(wxFD_SAVE)) 79 { 80 SetNSPanel([NSSavePanel savePanel]); 81 82 [GetNSSavePanel() setTitle:wxNSStringWithWxString(message)]; 83 84 [GetNSSavePanel() setPrompt:@"Save"]; 85 [GetNSSavePanel() setTreatsFilePackagesAsDirectories:YES]; 86 [GetNSSavePanel() setCanSelectHiddenExtension:YES]; 87 88// Cached as per-app in obj-c 89// [GetNSSavePanel() setExtensionHidden:YES]; 90 91 // 92 // NB: Note that only Panther supports wildcards 93 // with save dialogs - not that wildcards in save 94 // dialogs are all that useful, anyway :) 95 // 96 } 97 else //m_dialogStyle & wxFD_OPEN 98 { 99 SetNSPanel([NSOpenPanel openPanel]); 100 [m_cocoaNSWindow setTitle:wxNSStringWithWxString(message)]; 101 102 [(NSOpenPanel*)m_cocoaNSWindow setAllowsMultipleSelection:(HasFlag(wxFD_MULTIPLE))]; 103 [(NSOpenPanel*)m_cocoaNSWindow setResolvesAliases:YES]; 104 [(NSOpenPanel*)m_cocoaNSWindow setCanChooseFiles:YES]; 105 [(NSOpenPanel*)m_cocoaNSWindow setCanChooseDirectories:NO]; 106 [GetNSSavePanel() setPrompt:@"Open"]; 107 108 //convert wildcards - open panel only takes file extensions - 109 //no actual wildcards here :) 110 size_t lastwcpos = 0; 111 bool bDescription = true; 112 size_t i; 113 for(i = wildCard.find('|'); 114 i != wxString::npos; 115 i = wildCard.find('|', lastwcpos+1)) 116 { 117 size_t oldi = i; 118 119 if(!bDescription) 120 { 121 bDescription = !bDescription; 122 123 //work backwards looking for a period 124 while(i != lastwcpos && wildCard[--i] != '.') {} 125 126 if(i == lastwcpos) 127 { 128 //no extension - can't use this wildcard 129 lastwcpos = oldi; 130 continue; 131 } 132 133 [m_wildcards addObject:wxNSStringWithWxString(wildCard.substr(i+1, oldi-i-1))]; 134 } 135 else 136 bDescription = !bDescription; 137 lastwcpos = oldi; 138 } 139 140 if (!bDescription) 141 { 142 //get last wildcard 143 size_t oldi = wildCard.length(); 144 i = oldi; 145 146 //work backwards looking for a period 147 while(i != lastwcpos && wildCard[--i] != '.') {} 148 149 if(i != lastwcpos) 150 [m_wildcards addObject:wxNSStringWithWxString(wildCard.substr(i+1, oldi-i-1))]; 151 } 152 153 if ([m_wildcards count] == 0) 154 { 155 [m_wildcards release]; 156 m_wildcards = nil; 157 } 158 } 159} 160 161wxFileDialog::~wxFileDialog() 162{ 163 [m_wildcards release]; 164} 165 166void wxFileDialog::GetPaths(wxArrayString& paths) const 167{ 168 paths.Empty(); 169 170 wxString dir(m_dir); 171 if ( m_dir.Last() != wxT('\\') ) 172 dir += wxT('\\'); 173 174 size_t count = m_fileNames.GetCount(); 175 for ( size_t n = 0; n < count; n++ ) 176 { 177 if (wxFileName(m_fileNames[n]).IsAbsolute()) 178 paths.Add(m_fileNames[n]); 179 else 180 paths.Add(dir + m_fileNames[n]); 181 } 182} 183 184void wxFileDialog::GetFilenames(wxArrayString& files) const 185{ 186 files = m_fileNames; 187} 188 189void wxFileDialog::SetPath(const wxString& path) 190{ 191 wxString ext; 192 wxFileName::SplitPath(path, &m_dir, &m_fileName, &ext); 193 if ( !ext.empty() ) 194 m_fileName << wxT('.') << ext; 195} 196 197int wxFileDialog::ShowModal() 198{ 199 WX_HOOK_MODAL_DIALOG(); 200 201 wxAutoNSAutoreleasePool thePool; 202 203 m_fileNames.Empty(); 204 205 int nResult; 206 207 if (HasFlag(wxFD_SAVE)) 208 { 209 nResult = [GetNSSavePanel() 210 runModalForDirectory:wxNSStringWithWxString(m_dir) 211 file:wxNSStringWithWxString(m_fileName)]; 212 213 if (nResult == NSOKButton) 214 { 215 m_fileNames.Add(wxStringWithNSString([GetNSSavePanel() filename])); 216 m_path = m_fileNames[0]; 217 } 218 } 219 else //m_dialogStyle & wxFD_OPEN 220 { 221 nResult = [(NSOpenPanel*)m_cocoaNSWindow 222 runModalForDirectory:wxNSStringWithWxString(m_dir) 223 file:wxNSStringWithWxString(m_fileName) 224 types:m_wildcards]; 225 226 if (nResult == NSOKButton) 227 { 228 for(unsigned i = 0; i < [[(NSOpenPanel*)m_cocoaNSWindow filenames] count]; ++i) 229 { 230 m_fileNames.Add(wxStringWithNSString([[(NSOpenPanel*)m_cocoaNSWindow filenames] objectAtIndex:(i)])); 231 } 232 233 m_path = m_fileNames[0]; 234 } 235 } 236 237 return nResult == NSOKButton ? wxID_OK : wxID_CANCEL; 238} 239 240#endif // wxUSE_FILEDLG 241