mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 661991 - add support for new file pickers. r=ehsan
This commit is contained in:
parent
6540425368
commit
218e530c99
@ -450,8 +450,7 @@ nsFilePicker::ShowFolderPicker(const nsString& aInitialDir)
|
||||
dialog->Advise(this, &mFDECookie);
|
||||
|
||||
// options
|
||||
FILEOPENDIALOGOPTIONS fos = 0;
|
||||
fos |= FOS_PICKFOLDERS;
|
||||
FILEOPENDIALOGOPTIONS fos = FOS_PICKFOLDERS;
|
||||
dialog->SetOptions(fos);
|
||||
|
||||
// initial strings
|
||||
@ -521,7 +520,7 @@ nsFilePicker::ShowXPFilePicker(const nsString& aInitialDir)
|
||||
nsString filterBuffer = mFilterList;
|
||||
|
||||
nsAutoArrayPtr<PRUnichar> fileBuffer(new PRUnichar[FILE_BUFFER_SIZE]);
|
||||
wcsncpy(fileBuffer, mDefault.get(), FILE_BUFFER_SIZE);
|
||||
wcsncpy(fileBuffer, mDefaultFilePath.get(), FILE_BUFFER_SIZE);
|
||||
fileBuffer[FILE_BUFFER_SIZE-1] = '\0'; // null terminate in case copy truncated
|
||||
|
||||
if (!aInitialDir.IsEmpty()) {
|
||||
@ -638,7 +637,7 @@ nsFilePicker::ShowXPFilePicker(const nsString& aInitialDir)
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_ERROR("unsupported file picker mode");
|
||||
NS_NOTREACHED("unsupported file picker mode");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -711,7 +710,148 @@ nsFilePicker::ShowXPFilePicker(const nsString& aInitialDir)
|
||||
bool
|
||||
nsFilePicker::ShowFilePicker(const nsString& aInitialDir)
|
||||
{
|
||||
return false;
|
||||
nsRefPtr<IFileDialog> dialog;
|
||||
if (mMode != modeSave) {
|
||||
if (FAILED(CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC,
|
||||
IID_IFileOpenDialog,
|
||||
getter_AddRefs(dialog))))
|
||||
return false;
|
||||
} else {
|
||||
if (FAILED(CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_INPROC,
|
||||
IID_IFileSaveDialog,
|
||||
getter_AddRefs(dialog))))
|
||||
return false;
|
||||
}
|
||||
|
||||
// hook up event callbacks
|
||||
dialog->Advise(this, &mFDECookie);
|
||||
|
||||
// options
|
||||
|
||||
FILEOPENDIALOGOPTIONS fos = 0;
|
||||
fos |= FOS_SHAREAWARE | FOS_OVERWRITEPROMPT | FOS_NOREADONLYRETURN;
|
||||
|
||||
// Handle add to recent docs settings
|
||||
if (IsPrivacyModeEnabled() || !mAddToRecentDocs) {
|
||||
fos |= FOS_DONTADDTORECENT;
|
||||
}
|
||||
|
||||
// Msdn claims FOS_NOCHANGEDIR is not needed. We'll add this
|
||||
// just in case.
|
||||
AutoRestoreWorkingPath arw;
|
||||
|
||||
// mode specific
|
||||
switch(mMode) {
|
||||
case modeOpen:
|
||||
fos |= FOS_FILEMUSTEXIST;
|
||||
break;
|
||||
|
||||
case modeOpenMultiple:
|
||||
fos |= FOS_FILEMUSTEXIST | FOS_ALLOWMULTISELECT;
|
||||
break;
|
||||
|
||||
case modeSave:
|
||||
// Don't follow shortcuts when saving a shortcut, this can be used
|
||||
// to trick users (bug 271732)
|
||||
if (IsDefaultPathLink())
|
||||
fos |= FOS_NODEREFERENCELINKS;
|
||||
break;
|
||||
}
|
||||
|
||||
dialog->SetOptions(fos);
|
||||
|
||||
// initial strings
|
||||
|
||||
// title
|
||||
dialog->SetTitle(mTitle.get());
|
||||
|
||||
// default filename
|
||||
if (!mDefaultFilename.IsEmpty()) {
|
||||
dialog->SetFileName(mDefaultFilename.get());
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_STRING(htmExt, "html");
|
||||
|
||||
// default extension to append to new files
|
||||
if (!mDefaultExtension.IsEmpty()) {
|
||||
dialog->SetDefaultExtension(mDefaultExtension.get());
|
||||
} else if (IsDefaultPathHtml()) {
|
||||
dialog->SetDefaultExtension(htmExt.get());
|
||||
}
|
||||
|
||||
// initial location
|
||||
if (!aInitialDir.IsEmpty()) {
|
||||
nsRefPtr<IShellItem> folder;
|
||||
if (SUCCEEDED(SHCreateItemFromParsingName(aInitialDir.get(), NULL,
|
||||
IID_IShellItem,
|
||||
getter_AddRefs(folder)))) {
|
||||
dialog->SetFolder(folder);
|
||||
}
|
||||
}
|
||||
|
||||
// filter types and the default index
|
||||
if (!mComFilterList.IsEmpty()) {
|
||||
dialog->SetFileTypes(mComFilterList.Length(), mComFilterList.get());
|
||||
dialog->SetFileTypeIndex(mSelectedType);
|
||||
}
|
||||
|
||||
// display
|
||||
|
||||
AutoDestroyTmpWindow adtw((HWND)(mParentWidget.get() ?
|
||||
mParentWidget->GetNativeData(NS_NATIVE_TMP_WINDOW) : NULL));
|
||||
|
||||
AutoWidgetPickerState awps(mParentWidget);
|
||||
if (FAILED(dialog->Show(adtw.get()))) {
|
||||
dialog->Unadvise(mFDECookie);
|
||||
return false;
|
||||
}
|
||||
dialog->Unadvise(mFDECookie);
|
||||
|
||||
// results
|
||||
|
||||
// single selection
|
||||
if (mMode != modeOpenMultiple) {
|
||||
nsRefPtr<IShellItem> item;
|
||||
if (FAILED(dialog->GetResult(getter_AddRefs(item))) || !item) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LPWSTR str = NULL;
|
||||
if (FAILED(item->GetDisplayName(SIGDN_FILESYSPATH, &str)))
|
||||
return false;
|
||||
mUnicodeFile.Assign(str);
|
||||
CoTaskMemFree(str);
|
||||
return true;
|
||||
}
|
||||
|
||||
// multiple selection
|
||||
nsRefPtr<IFileOpenDialog> openDlg;
|
||||
dialog->QueryInterface(IID_IFileOpenDialog, getter_AddRefs(openDlg));
|
||||
if (!openDlg) {
|
||||
// should not happen
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<IShellItemArray> items;
|
||||
if (FAILED(openDlg->GetResults(getter_AddRefs(items))) || !items) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD count = 0;
|
||||
items->GetCount(&count);
|
||||
for (unsigned int idx = 0; idx < count; idx++) {
|
||||
nsRefPtr<IShellItem> item;
|
||||
if (SUCCEEDED(items->GetItemAt(idx, getter_AddRefs(item)))) {
|
||||
LPWSTR str = NULL;
|
||||
if (FAILED(item->GetDisplayName(SIGDN_FILESYSPATH, &str)))
|
||||
continue;
|
||||
nsCOMPtr<nsILocalFile> file = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
if (file && NS_SUCCEEDED(file->InitWithPath(nsDependentString(str))))
|
||||
mFiles.AppendObject(file);
|
||||
CoTaskMemFree(str);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -830,32 +970,33 @@ nsFilePicker::GetFiles(nsISimpleEnumerator **aFiles)
|
||||
NS_IMETHODIMP
|
||||
nsFilePicker::SetDefaultString(const nsAString& aString)
|
||||
{
|
||||
mDefault = aString;
|
||||
mDefaultFilePath = aString;
|
||||
|
||||
//First, make sure the file name is not too long!
|
||||
// First, make sure the file name is not too long.
|
||||
PRInt32 nameLength;
|
||||
PRInt32 nameIndex = mDefault.RFind("\\");
|
||||
PRInt32 nameIndex = mDefaultFilePath.RFind("\\");
|
||||
if (nameIndex == kNotFound)
|
||||
nameIndex = 0;
|
||||
else
|
||||
nameIndex ++;
|
||||
nameLength = mDefault.Length() - nameIndex;
|
||||
nameLength = mDefaultFilePath.Length() - nameIndex;
|
||||
mDefaultFilename.Assign(Substring(mDefaultFilePath, nameIndex));
|
||||
|
||||
if (nameLength > MAX_PATH) {
|
||||
PRInt32 extIndex = mDefault.RFind(".");
|
||||
PRInt32 extIndex = mDefaultFilePath.RFind(".");
|
||||
if (extIndex == kNotFound)
|
||||
extIndex = mDefault.Length();
|
||||
extIndex = mDefaultFilePath.Length();
|
||||
|
||||
//Let's try to shave the needed characters from the name part
|
||||
// Let's try to shave the needed characters from the name part.
|
||||
PRInt32 charsToRemove = nameLength - MAX_PATH;
|
||||
if (extIndex - nameIndex >= charsToRemove) {
|
||||
mDefault.Cut(extIndex - charsToRemove, charsToRemove);
|
||||
mDefaultFilePath.Cut(extIndex - charsToRemove, charsToRemove);
|
||||
}
|
||||
}
|
||||
|
||||
//Then, we need to replace illegal characters.
|
||||
//At this stage, we cannot replace the backslash as the string might represent a file path.
|
||||
mDefault.ReplaceChar(FILE_ILLEGAL_CHARACTERS, '-');
|
||||
// Then, we need to replace illegal characters. At this stage, we cannot
|
||||
// replace the backslash as the string might represent a file path.
|
||||
mDefaultFilePath.ReplaceChar(FILE_ILLEGAL_CHARACTERS, '-');
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -922,8 +1063,8 @@ nsFilePicker::GetQualifiedPath(const PRUnichar *aInPath, nsString &aOutPath)
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter)
|
||||
void
|
||||
nsFilePicker::AppendXPFilter(const nsAString& aTitle, const nsAString& aFilter)
|
||||
{
|
||||
mFilterList.Append(aTitle);
|
||||
mFilterList.Append(PRUnichar('\0'));
|
||||
@ -940,7 +1081,20 @@ nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter)
|
||||
}
|
||||
|
||||
mFilterList.Append(PRUnichar('\0'));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter)
|
||||
{
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
if (nsWindow::GetWindowsVersion() >= VISTA_VERSION) {
|
||||
mComFilterList.Append(aTitle, aFilter);
|
||||
} else {
|
||||
AppendXPFilter(aTitle, aFilter);
|
||||
}
|
||||
#else
|
||||
AppendXPFilter(aTitle, aFilter);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -986,7 +1140,7 @@ nsFilePicker::IsPrivacyModeEnabled()
|
||||
bool
|
||||
nsFilePicker::IsDefaultPathLink()
|
||||
{
|
||||
NS_ConvertUTF16toUTF8 ext(mDefault);
|
||||
NS_ConvertUTF16toUTF8 ext(mDefaultFilePath);
|
||||
ext.Trim(" .", false, true); // watch out for trailing space and dots
|
||||
ToLowerCase(ext);
|
||||
if (StringEndsWith(ext, NS_LITERAL_CSTRING(".lnk")) ||
|
||||
@ -999,10 +1153,10 @@ nsFilePicker::IsDefaultPathLink()
|
||||
bool
|
||||
nsFilePicker::IsDefaultPathHtml()
|
||||
{
|
||||
PRInt32 extIndex = mDefault.RFind(".");
|
||||
PRInt32 extIndex = mDefaultFilePath.RFind(".");
|
||||
if (extIndex >= 0) {
|
||||
nsAutoString ext;
|
||||
mDefault.Right(ext, mDefault.Length() - extIndex);
|
||||
mDefaultFilePath.Right(ext, mDefaultFilePath.Length() - extIndex);
|
||||
if (ext.LowerCaseEqualsLiteral(".htm") ||
|
||||
ext.LowerCaseEqualsLiteral(".html") ||
|
||||
ext.LowerCaseEqualsLiteral(".shtml"))
|
||||
@ -1010,3 +1164,30 @@ nsFilePicker::IsDefaultPathHtml()
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
nsFilePicker::ComDlgFilterSpec::Append(const nsAString& aTitle, const nsAString& aFilter)
|
||||
{
|
||||
PRUint32 size = sizeof(COMDLG_FILTERSPEC);
|
||||
PRUint32 hdrLen = size * (mLength + 1);
|
||||
mSpecList = (COMDLG_FILTERSPEC*)realloc(mSpecList, hdrLen);
|
||||
if (!mSpecList) {
|
||||
NS_WARNING("mSpecList realloc failed.");
|
||||
return;
|
||||
}
|
||||
COMDLG_FILTERSPEC* pSpecForward = (COMDLG_FILTERSPEC*)(mSpecList + mLength);
|
||||
memset(pSpecForward, 0, size);
|
||||
nsString* pStr = mStrings.AppendElement(aTitle);
|
||||
if (!pStr) {
|
||||
NS_WARNING("mStrings.AppendElement failed.");
|
||||
return;
|
||||
}
|
||||
pSpecForward->pszName = pStr->get();
|
||||
pStr = mStrings.AppendElement(aFilter);
|
||||
if (!pStr) {
|
||||
NS_WARNING("mStrings.AppendElement failed.");
|
||||
return;
|
||||
}
|
||||
pSpecForward->pszSpec = pStr->get();
|
||||
mLength++;
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ protected:
|
||||
bool ShowXPFolderPicker(const nsString& aInitialDir);
|
||||
bool ShowFilePicker(const nsString& aInitialDir);
|
||||
bool ShowXPFilePicker(const nsString& aInitialDir);
|
||||
void AppendXPFilter(const nsAString& aTitle, const nsAString& aFilter);
|
||||
void RememberLastUsedDirectory();
|
||||
bool IsPrivacyModeEnabled();
|
||||
bool IsDefaultPathLink();
|
||||
@ -138,7 +139,8 @@ protected:
|
||||
nsString mTitle;
|
||||
PRInt16 mMode;
|
||||
nsCString mFile;
|
||||
nsString mDefault;
|
||||
nsString mDefaultFilePath;
|
||||
nsString mDefaultFilename;
|
||||
nsString mDefaultExtension;
|
||||
nsString mFilterList;
|
||||
PRInt16 mSelectedType;
|
||||
@ -147,6 +149,39 @@ protected:
|
||||
nsString mUnicodeFile;
|
||||
static PRUnichar *mLastUsedUnicodeDirectory;
|
||||
DWORD mFDECookie;
|
||||
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
class ComDlgFilterSpec
|
||||
{
|
||||
public:
|
||||
ComDlgFilterSpec() :
|
||||
mSpecList(nsnull),
|
||||
mLength(0) {}
|
||||
~ComDlgFilterSpec() {
|
||||
free(mSpecList);
|
||||
}
|
||||
|
||||
PRUint32 Length() {
|
||||
return mLength;
|
||||
}
|
||||
|
||||
bool IsEmpty() {
|
||||
return (mLength == 0);
|
||||
}
|
||||
|
||||
const COMDLG_FILTERSPEC* get() {
|
||||
return mSpecList;
|
||||
}
|
||||
|
||||
void Append(const nsAString& aTitle, const nsAString& aFilter);
|
||||
private:
|
||||
COMDLG_FILTERSPEC* mSpecList;
|
||||
nsAutoTArray<nsString, 2> mStrings;
|
||||
PRUint32 mLength;
|
||||
};
|
||||
|
||||
ComDlgFilterSpec mComFilterList;
|
||||
#endif
|
||||
};
|
||||
|
||||
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
|
||||
|
Loading…
Reference in New Issue
Block a user