diff --git a/mozilla/widget/src/os2/nsFileWidget.cpp b/mozilla/widget/src/os2/nsFileWidget.cpp new file mode 100644 index 00000000000..022d185b724 --- /dev/null +++ b/mozilla/widget/src/os2/nsFileWidget.cpp @@ -0,0 +1,404 @@ +/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * Pierre Phaneuf + */ + +// Define so header files for openfilename are included +#ifdef WIN32_LEAN_AND_MEAN +#undef WIN32_LEAN_AND_MEAN +#endif + +#include "nsCOMPtr.h" +#include "nsIServiceManager.h" +#define NS_IMPL_IDS +#include "nsIPlatformCharset.h" +#undef NS_IMPL_IDS +#include "nsWidgetDefs.h" +#include "nsDirPicker.h" +#include "nsFileWidget.h" +#include "nsFileSpec.h" + + +static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); + +NS_IMPL_ADDREF(nsFileWidget) +NS_IMPL_RELEASE(nsFileWidget) + + +//------------------------------------------------------------------------- +// +// nsFileWidget constructor +// +//------------------------------------------------------------------------- +nsFileWidget::nsFileWidget() : nsIFileWidget() +{ + NS_INIT_REFCNT(); + mWnd = NULL; + mNumberOfFilters = 0; + mUnicodeEncoder = nsnull; + mUnicodeDecoder = nsnull; +} + +//------------------------------------------------------------------------- +// +// nsFileWidget destructor +// +//------------------------------------------------------------------------- +nsFileWidget::~nsFileWidget() +{ + NS_IF_RELEASE(mUnicodeEncoder); + NS_IF_RELEASE(mUnicodeDecoder); +} + +/** + * @param aIID The name of the class implementing the method + * @param _classiiddef The name of the #define symbol that defines the IID + * for the class (e.g. NS_ISUPPORTS_IID) + * +*/ +nsresult nsFileWidget::QueryInterface(const nsIID& aIID, void** aInstancePtr) +{ + + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + + nsresult rv = NS_NOINTERFACE; + + if (aIID.Equals(NS_GET_IID(nsIFileWidget))) { + *aInstancePtr = (void*) ((nsIFileWidget*)this); + NS_ADDREF_THIS(); + return NS_OK; + } + + return rv; +} + + +//------------------------------------------------------------------------- +// +// Show - Display the file dialog +// +//------------------------------------------------------------------------- + +PRBool nsFileWidget::Show() +{ + char fileBuffer[MAX_PATH+1] = ""; + char *converted = ConvertToFileSystemCharset(mDefault.GetUnicode()); + if (nsnull == converted) { + mDefault.ToCString(fileBuffer,MAX_PATH); + } + else { + PL_strcpy(fileBuffer, converted); + delete [] converted; + } + + OPENFILENAME ofn; + memset(&ofn, 0, sizeof(ofn)); + + ofn.lStructSize = sizeof(ofn); + + nsString filterList; + GetFilterListArray(filterList); + char *filterBuffer = ConvertToFileSystemCharset(filterList.GetUnicode(), filterList.Length()); + char *title = ConvertToFileSystemCharset(mTitle.GetUnicode()); + if (nsnull == title) + title = mTitle.ToNewCString(); + const char *initialDir = mDisplayDirectory.GetNativePathCString(); + if (initialDir && *initialDir) { + ofn.lpstrInitialDir = initialDir; + } + + ofn.lpstrTitle = title; + ofn.lpstrFilter = filterBuffer; + ofn.nFilterIndex = 1; + ofn.hwndOwner = mWnd; + ofn.lpstrFile = fileBuffer; + ofn.nMaxFile = MAX_PATH; + + // XXX use OFN_NOCHANGEDIR for M5 + ofn.Flags = OFN_SHAREAWARE | OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY; + + PRBool result = PR_TRUE; + LONG retval; + + if (mMode == eMode_load) { + // FILE MUST EXIST! + ofn.Flags |= OFN_FILEMUSTEXIST; + } + if( !DaxOpenSave( (mMode == eMode_save), &retval, &ofn, NULL) ) + result = PR_FALSE; + + // Remember what filter type the user selected + mSelectedType = (PRInt16)ofn.nFilterIndex; + + // Store the current directory in mDisplayDirectory + char* newCurrentDirectory = new char[MAX_PATH+1]; + VERIFY(gModuleData.GetCurrentDirectory(MAX_PATH, newCurrentDirectory) > 0); + mDisplayDirectory = newCurrentDirectory; + delete[] newCurrentDirectory; + + // Clean up filter buffers + if (filterBuffer) + delete[] filterBuffer; + if (title) + delete[] title; + + // Set user-selected location of file or directory + mFile.SetLength(0); + if (result == PR_TRUE) { + // I think it also needs a conversion here (to unicode since appending to nsString) + // but doing that generates garbage file name, weird. + mFile.AppendWithConversion(fileBuffer); + } + + return((PRBool)result); +} + +//------------------------------------------------------------------------- +// +// Convert filter titles + filters into a Windows filter string +// +//------------------------------------------------------------------------- + +void nsFileWidget::GetFilterListArray(nsString& aFilterList) +{ + aFilterList.SetLength(0); + for (PRUint32 i = 0; i < mNumberOfFilters; i++) { + const nsString& title = mTitles[i]; + const nsString& filter = mFilters[i]; + + aFilterList.Append(title); + aFilterList.AppendWithConversion('\0'); + aFilterList.Append(filter); + aFilterList.AppendWithConversion('\0'); + } + aFilterList.AppendWithConversion('\0'); +} + +//------------------------------------------------------------------------- +// +// Set the list of filters +// +//------------------------------------------------------------------------- + +NS_IMETHODIMP nsFileWidget::SetFilterList(PRUint32 aNumberOfFilters,const nsString aTitles[],const nsString aFilters[]) +{ + mNumberOfFilters = aNumberOfFilters; + mTitles = aTitles; + mFilters = aFilters; + return NS_OK; +} + +//------------------------------------------------------------------------- +//------------------------------------------------------------------------- +NS_IMETHODIMP nsFileWidget::GetSelectedType(PRInt16& theType) +{ + theType = mSelectedType; + return NS_OK; +} + +//------------------------------------------------------------------------- +// +//------------------------------------------------------------------------- +NS_IMETHODIMP nsFileWidget::GetFile(nsFileSpec& aFile) +{ + nsFilePath filePath(mFile); + nsFileSpec fileSpec(filePath); + + aFile = filePath; + return NS_OK; +} + + +//------------------------------------------------------------------------- +// +// Get the file + path +// +//------------------------------------------------------------------------- +NS_IMETHODIMP nsFileWidget::SetDefaultString(const nsString& aString) +{ + mDefault = aString; + return NS_OK; +} + + +//------------------------------------------------------------------------- +// +// Set the display directory +// +//------------------------------------------------------------------------- +NS_IMETHODIMP nsFileWidget::SetDisplayDirectory(const nsFileSpec& aDirectory) +{ + mDisplayDirectory = aDirectory; + return NS_OK; +} + + +//------------------------------------------------------------------------- +// +// Get the display directory +// +//------------------------------------------------------------------------- +NS_IMETHODIMP nsFileWidget::GetDisplayDirectory(nsFileSpec& aDirectory) +{ + aDirectory = mDisplayDirectory; + return NS_OK; +} + + +//------------------------------------------------------------------------- +NS_IMETHODIMP nsFileWidget::Create(nsIWidget *aParent, + const nsString& aTitle, + nsFileDlgMode aMode, + nsIDeviceContext *aContext, + nsIAppShell *aAppShell, + nsIToolkit *aToolkit, + void *aInitData) +{ + mWnd = (HWND) ((aParent) ? aParent->GetNativeData(NS_NATIVE_WINDOW) : 0); + mTitle.SetLength(0); + mTitle.Append(aTitle); + mMode = aMode; + return NS_OK; +} + +//------------------------------------------------------------------------- +nsFileDlgResults nsFileWidget::GetFile(nsIWidget * aParent, + const nsString & promptString, + nsFileSpec & theFileSpec) +{ + Create(aParent, promptString, eMode_load, nsnull, nsnull); + PRBool result = Show(); + nsFileDlgResults status = nsFileDlgResults_Cancel; + if (result && mFile.Length() > 0) { + nsFilePath filePath(mFile); + nsFileSpec fileSpec(filePath); + theFileSpec = fileSpec; + status = nsFileDlgResults_OK; + } + return status; +} + +//------------------------------------------------------------------------- +nsFileDlgResults nsFileWidget::GetFolder(nsIWidget * aParent, + const nsString & promptString, + nsFileSpec & theFileSpec) +{ + + nsFileDlgResults status = nsFileDlgResults_Cancel; + + HWND hwndOwner = HWND_DESKTOP; + if( aParent) + hwndOwner = (HWND) aParent->GetNativeData( NS_NATIVE_WIDGET); + + DIRPICKER dp = { { 0 }, 0, TRUE, 0 }; // modal dialog + + gModuleData.ConvertFromUcs( promptString, dp.szFullFile, CCHMAXPATH); + + HWND ret = FS_PickDirectory( HWND_DESKTOP, hwndOwner, + gModuleData.hModResources, &dp); + + if( ret && dp.lReturn == DID_OK) + { + theFileSpec = dp.szFullFile; + status = nsFileDlgResults_OK; + } + + return status; +} + +//------------------------------------------------------------------------- +nsFileDlgResults nsFileWidget::PutFile(nsIWidget * aParent, + const nsString & promptString, + nsFileSpec & theFileSpec) +{ + Create(aParent, promptString, eMode_save, nsnull, nsnull); + PRBool result = Show(); + nsFileDlgResults status = nsFileDlgResults_Cancel; + if (result && mFile.Length() > 0) { + nsFilePath filePath(mFile); + nsFileSpec fileSpec(filePath); + theFileSpec = fileSpec; + + if (result) { + status = (theFileSpec.Exists()?nsFileDlgResults_Replace:nsFileDlgResults_OK); + } + } + return status; +} + +//------------------------------------------------------------------------- +void nsFileWidget::GetFileSystemCharset(nsString & fileSystemCharset) +{ + static nsAutoString aCharset; + nsresult rv; + + if (aCharset.Length() < 1) { + nsCOMPtr platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv); + if (NS_SUCCEEDED(rv)) + rv = platformCharset->GetCharset(kPlatformCharsetSel_FileName, aCharset); + + NS_ASSERTION(NS_SUCCEEDED(rv), "error getting platform charset"); + if (NS_FAILED(rv)) + aCharset.AssignWithConversion("windows-1252"); + } + fileSystemCharset = aCharset; +} + +//------------------------------------------------------------------------- +char * nsFileWidget::ConvertToFileSystemCharset(const PRUnichar *inString, PRInt32 inLength) +{ + char *outString = nsnull; + nsresult rv = NS_OK; + + // get file system charset and create a unicode encoder + if (nsnull == mUnicodeEncoder) { + nsAutoString fileSystemCharset; + GetFileSystemCharset(fileSystemCharset); + + NS_WITH_SERVICE(nsICharsetConverterManager, ccm, kCharsetConverterManagerCID, &rv); + if (NS_SUCCEEDED(rv)) { + rv = ccm->GetUnicodeEncoder(&fileSystemCharset, &mUnicodeEncoder); + } + } + + // converts from unicode to the file system charset + if (NS_SUCCEEDED(rv)) { + if(inLength < 0) + inLength = nsCRT::strlen(inString); + PRInt32 outLength; + rv = mUnicodeEncoder->GetMaxLength(inString, inLength, &outLength); + if (NS_SUCCEEDED(rv)) { + outString = new char[outLength+1]; + if (nsnull == outString) { + return nsnull; + } + rv = mUnicodeEncoder->Convert(inString, &inLength, outString, &outLength); + if (NS_SUCCEEDED(rv)) { + outString[outLength] = '\0'; + } + } + } + + return NS_SUCCEEDED(rv) ? outString : nsnull; +} + diff --git a/mozilla/widget/src/os2/nsFileWidget.h b/mozilla/widget/src/os2/nsFileWidget.h new file mode 100644 index 00000000000..792d12ff4d0 --- /dev/null +++ b/mozilla/widget/src/os2/nsFileWidget.h @@ -0,0 +1,105 @@ +/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; -*- */ +/* + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + */ + +#ifndef nsFileWidget_h__ +#define nsFileWidget_h__ + +#define NS_IMPL_IDS +#include "nsICharsetConverterManager.h" +#undef NS_IMPL_IDS +#include "nsToolkit.h" +#include "nsIWidget.h" +#include "nsIFileWidget.h" + +/** + * Native Win32 FileSelector wrapper + */ + +class nsFileWidget : public nsIFileWidget +{ + public: + nsFileWidget(); + virtual ~nsFileWidget(); + + NS_DECL_ISUPPORTS + + PRBool OnPaint(); + + // nsIWidget interface + + NS_IMETHOD Create( nsIWidget *aParent, + const nsString& aTitle, + nsFileDlgMode aMode, + nsIDeviceContext *aContext = nsnull, + nsIAppShell *aAppShell = nsnull, + nsIToolkit *aToolkit = nsnull, + void *aInitData = nsnull); + + // nsIFileWidget part + virtual PRBool Show(); + NS_IMETHOD GetFile(nsFileSpec& aFile); + NS_IMETHOD SetDefaultString(const nsString& aFile); + NS_IMETHOD SetFilterList(PRUint32 aNumberOfFilters,const nsString aTitles[],const nsString aFilters[]); + NS_IMETHOD GetDisplayDirectory(nsFileSpec& aDirectory); + NS_IMETHOD SetDisplayDirectory(const nsFileSpec& aDirectory); + + virtual nsFileDlgResults GetFile( + nsIWidget * aParent, + const nsString & promptString, // Window title for the dialog + nsFileSpec & theFileSpec); // Populate with initial path for file dialog + + virtual nsFileDlgResults GetFolder( + nsIWidget * aParent, + const nsString & promptString, // Window title for the dialog + nsFileSpec & theFileSpec); // Populate with initial path for file dialog + + virtual nsFileDlgResults PutFile( + nsIWidget * aParent, + const nsString & promptString, // Window title for the dialog + nsFileSpec & theFileSpec); // Populate with initial path for file dialog + + NS_IMETHOD GetSelectedType(PRInt16& theType); + + protected: + + static void GetFileSystemCharset(nsString & fileSystemCharset); + char * ConvertToFileSystemCharset(const PRUnichar *inString, PRInt32 inLength=-1); + PRUnichar * ConvertFromFileSystemCharset(const char *inString); + + HWND mWnd; + nsString mTitle; + nsFileDlgMode mMode; + nsString mFile; + PRUint32 mNumberOfFilters; + const nsString* mTitles; + const nsString* mFilters; + nsString mDefault; + nsIUnicodeEncoder* mUnicodeEncoder; + nsIUnicodeDecoder* mUnicodeDecoder; + nsFileSpec mDisplayDirectory; + + + void GetFilterListArray(nsString& aFilterList); + PRInt16 mSelectedType; +}; + +#endif // nsFileWidget_h__