PageRenderTime 66ms CodeModel.GetById 2ms app.highlight 58ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/lldirpicker.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 381 lines | 244 code | 84 blank | 53 comment | 43 complexity | abeee8146bd8f7f695b9d469be8ab16e MD5 | raw file
  1/** 
  2 * @file lldirpicker.cpp
  3 * @brief OS-specific file picker
  4 *
  5 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "lldirpicker.h"
 30//#include "llviewermessage.h"
 31#include "llworld.h"
 32#include "llviewerwindow.h"
 33#include "llkeyboard.h"
 34#include "lldir.h"
 35#include "llframetimer.h"
 36#include "lltrans.h"
 37#include "llwindow.h"	// beforeDialog()
 38#include "llviewercontrol.h"
 39
 40#if LL_LINUX || LL_SOLARIS
 41# include "llfilepicker.h"
 42#endif
 43
 44//
 45// Globals
 46//
 47
 48LLDirPicker LLDirPicker::sInstance;
 49
 50#if LL_WINDOWS
 51#include <shlobj.h>
 52#endif
 53
 54//
 55// Implementation
 56//
 57
 58// utility function to check if access to local file system via file browser 
 59// is enabled and if not, tidy up and indicate we're not allowed to do this.
 60bool LLDirPicker::check_local_file_access_enabled()
 61{
 62	// if local file browsing is turned off, return without opening dialog
 63	bool local_file_system_browsing_enabled = gSavedSettings.getBOOL("LocalFileSystemBrowsingEnabled");
 64	if ( ! local_file_system_browsing_enabled )
 65	{
 66		mDir.clear();	// Windows
 67		mFileName = NULL; // Mac/Linux
 68		return false;
 69	}
 70
 71	return true;
 72}
 73
 74#if LL_WINDOWS
 75
 76LLDirPicker::LLDirPicker() :
 77	mFileName(NULL),
 78	mLocked(false)
 79{
 80}
 81
 82LLDirPicker::~LLDirPicker()
 83{
 84	// nothing
 85}
 86
 87BOOL LLDirPicker::getDir(std::string* filename)
 88{
 89	if( mLocked )
 90	{
 91		return FALSE;
 92	}
 93
 94	// if local file browsing is turned off, return without opening dialog
 95	if ( check_local_file_access_enabled() == false )
 96	{
 97		return FALSE;
 98	}
 99
100	BOOL success = FALSE;
101
102	// Modal, so pause agent
103	send_agent_pause();
104
105   BROWSEINFO bi;
106   memset(&bi, 0, sizeof(bi));
107
108   bi.ulFlags   = BIF_USENEWUI;
109   bi.hwndOwner = (HWND)gViewerWindow->getPlatformWindow();
110   bi.lpszTitle = NULL;
111
112   ::OleInitialize(NULL);
113
114   LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);
115
116   if(pIDL != NULL)
117   {
118      WCHAR buffer[_MAX_PATH] = {'\0'};
119
120      if(::SHGetPathFromIDList(pIDL, buffer) != 0)
121      {
122		  	// Set the string value.
123
124   			mDir = utf16str_to_utf8str(llutf16string(buffer));
125	         success = TRUE;
126      }
127
128      // free the item id list
129      CoTaskMemFree(pIDL);
130   }
131
132   ::OleUninitialize();
133
134	send_agent_resume();
135
136	// Account for the fact that the app has been stalled.
137	LLFrameTimer::updateFrameTime();
138	return success;
139}
140
141std::string LLDirPicker::getDirName()
142{
143	return mDir;
144}
145
146/////////////////////////////////////////////DARWIN
147#elif LL_DARWIN
148
149LLDirPicker::LLDirPicker() :
150	mFileName(NULL),
151	mLocked(false)
152{
153	reset();
154
155	memset(&mNavOptions, 0, sizeof(mNavOptions));
156	OSStatus	error = NavGetDefaultDialogCreationOptions(&mNavOptions);
157	if (error == noErr)
158	{
159		mNavOptions.modality = kWindowModalityAppModal;
160	}
161}
162
163LLDirPicker::~LLDirPicker()
164{
165	// nothing
166}
167
168//static
169pascal void LLDirPicker::doNavCallbackEvent(NavEventCallbackMessage callBackSelector,
170										 NavCBRecPtr callBackParms, void* callBackUD)
171{
172	switch(callBackSelector)
173	{
174		case kNavCBStart:
175		{
176			if (!sInstance.mFileName) break;
177 
178			OSStatus error = noErr; 
179			AEDesc theLocation = {typeNull, NULL};
180			FSSpec outFSSpec;
181			
182			//Convert string to a FSSpec
183			FSRef myFSRef;
184			
185			const char* filename=sInstance.mFileName->c_str();
186			
187			error = FSPathMakeRef ((UInt8*)filename,	&myFSRef, 	NULL); 
188			
189			if (error != noErr) break;
190
191			error = FSGetCatalogInfo (&myFSRef, kFSCatInfoNone, NULL, NULL, &outFSSpec, NULL);
192
193			if (error != noErr) break;
194	
195			error = AECreateDesc(typeFSS, &outFSSpec, sizeof(FSSpec), &theLocation);
196
197			if (error != noErr) break;
198
199			error = NavCustomControl(callBackParms->context,
200							kNavCtlSetLocation, (void*)&theLocation);
201
202		}
203	}
204}
205
206OSStatus	LLDirPicker::doNavChooseDialog()
207{
208	OSStatus		error = noErr;
209	NavDialogRef	navRef = NULL;
210	NavReplyRecord	navReply;
211
212	memset(&navReply, 0, sizeof(navReply));
213	
214	// NOTE: we are passing the address of a local variable here.  
215	//   This is fine, because the object this call creates will exist for less than the lifetime of this function.
216	//   (It is destroyed by NavDialogDispose() below.)
217
218	error = NavCreateChooseFolderDialog(&mNavOptions, &doNavCallbackEvent, NULL, NULL, &navRef);
219
220	gViewerWindow->getWindow()->beforeDialog();
221
222	if (error == noErr)
223		error = NavDialogRun(navRef);
224
225	gViewerWindow->getWindow()->afterDialog();
226
227	if (error == noErr)
228		error = NavDialogGetReply(navRef, &navReply);
229
230	if (navRef)
231		NavDialogDispose(navRef);
232
233	if (error == noErr && navReply.validRecord)
234	{	
235		FSRef		fsRef;
236		AEKeyword	theAEKeyword;
237		DescType	typeCode;
238		Size		actualSize = 0;
239		char		path[LL_MAX_PATH];		 /*Flawfinder: ignore*/
240		
241		memset(&fsRef, 0, sizeof(fsRef));
242		error = AEGetNthPtr(&navReply.selection, 1, typeFSRef, &theAEKeyword, &typeCode, &fsRef, sizeof(fsRef), &actualSize);
243		
244		if (error == noErr)
245			error = FSRefMakePath(&fsRef, (UInt8*) path, sizeof(path));
246		
247		if (error == noErr)
248			mDir = path;
249	}
250	
251	return error;
252}
253
254BOOL LLDirPicker::getDir(std::string* filename)
255{
256	if( mLocked ) return FALSE;
257	BOOL success = FALSE;
258	OSStatus	error = noErr;
259
260	// if local file browsing is turned off, return without opening dialog
261	if ( check_local_file_access_enabled() == false )
262	{
263		return FALSE;
264	}
265
266	mFileName = filename;
267	
268//	mNavOptions.saveFileName 
269
270	// Modal, so pause agent
271	send_agent_pause();
272	{
273		error = doNavChooseDialog();
274	}
275	send_agent_resume();
276	if (error == noErr)
277	{
278		if (mDir.length() >  0)
279			success = true;
280	}
281
282	// Account for the fact that the app has been stalled.
283	LLFrameTimer::updateFrameTime();
284	return success;
285}
286
287std::string LLDirPicker::getDirName()
288{
289	return mDir;
290}
291
292void LLDirPicker::reset()
293{
294	mLocked = false;
295	mDir.clear();
296}
297
298#elif LL_LINUX || LL_SOLARIS
299
300LLDirPicker::LLDirPicker() :
301	mFileName(NULL),
302	mLocked(false)
303{
304	mFilePicker = new LLFilePicker();
305	reset();
306}
307
308LLDirPicker::~LLDirPicker()
309{
310	delete mFilePicker;
311}
312
313
314void LLDirPicker::reset()
315{
316	if (mFilePicker)
317		mFilePicker->reset();
318}
319
320BOOL LLDirPicker::getDir(std::string* filename)
321{
322	reset();
323
324	// if local file browsing is turned off, return without opening dialog
325	if ( check_local_file_access_enabled() == false )
326	{
327		return FALSE;
328	}
329
330	if (mFilePicker)
331	{
332		GtkWindow* picker = mFilePicker->buildFilePicker(false, true,
333								 "dirpicker");
334
335		if (picker)
336		{		   
337		   gtk_window_set_title(GTK_WINDOW(picker), LLTrans::getString("choose_the_directory").c_str());
338		   gtk_widget_show_all(GTK_WIDGET(picker));
339		   gtk_main();
340		   return (!mFilePicker->getFirstFile().empty());
341		}
342	}
343	return FALSE;
344}
345
346std::string LLDirPicker::getDirName()
347{
348	if (mFilePicker)
349	{
350		return mFilePicker->getFirstFile();
351	}
352	return "";
353}
354
355#else // not implemented
356
357LLDirPicker::LLDirPicker() 
358{
359	reset();
360}
361
362LLDirPicker::~LLDirPicker()
363{
364}
365
366
367void LLDirPicker::reset()
368{
369}
370
371BOOL LLDirPicker::getDir(std::string* filename)
372{
373	return FALSE;
374}
375
376std::string LLDirPicker::getDirName()
377{
378	return "";
379}
380
381#endif