Bug 959171 - Fix how to bind EGLImage in GrallocTextureHostOGL. r=nical
[gecko.git] / widget / os2 / nsFilePicker.cpp
blobf224face16a2a4d6616cb175623ac12e09d12a1e
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsCOMPtr.h"
8 #include "nsReadableUtils.h"
9 #include "nsNetUtil.h"
10 #include "nsIServiceManager.h"
11 #include "nsIPlatformCharset.h"
12 #include "nsIFile.h"
13 #include "nsIURL.h"
14 #include "nsIStringBundle.h"
15 #include "nsEnumeratorUtils.h"
16 #include "nsCRT.h"
17 #include "nsIWidget.h"
18 #include "nsOS2Uni.h"
19 #include "nsFilePicker.h"
21 #ifndef MAX_PATH
22 #define MAX_PATH CCHMAXPATH
23 #endif
25 /* Item structure */
26 typedef struct _MyData
28 PAPSZ papszIFilterList;
29 ULONG ulCurExt;
30 ULONG ulNumFilters;
31 }MYDATA, *PMYDATA;
33 NS_IMPL_ISUPPORTS1(nsFilePicker, nsIFilePicker)
35 char nsFilePicker::mLastUsedDirectory[MAX_PATH+1] = { 0 };
38 static char* gpszFDSaveCaption = 0;
39 static char* gpszFDFileExists = 0;
40 static char* gpszFDFileReadOnly = 0;
42 MRESULT EXPENTRY DirDialogProc( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2);
43 MRESULT EXPENTRY FileDialogProc( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2);
45 //-------------------------------------------------------------------------
47 // nsFilePicker constructor
49 //-------------------------------------------------------------------------
50 nsFilePicker::nsFilePicker()
52 mWnd = nullptr;
53 mUnicodeEncoder = nullptr;
54 mUnicodeDecoder = nullptr;
55 mSelectedType = 0;
58 //-------------------------------------------------------------------------
60 // nsFilePicker destructor
62 //-------------------------------------------------------------------------
63 nsFilePicker::~nsFilePicker()
65 mFilters.Clear();
66 mTitles.Clear();
68 NS_IF_RELEASE(mUnicodeEncoder);
69 NS_IF_RELEASE(mUnicodeDecoder);
72 /* static */ void
73 nsFilePicker::ReleaseGlobals()
75 if (gpszFDSaveCaption) {
76 free(gpszFDSaveCaption);
77 free(gpszFDFileExists);
78 free(gpszFDFileReadOnly);
82 //-------------------------------------------------------------------------
84 // Show - Display the file dialog
86 //-------------------------------------------------------------------------
87 NS_IMETHODIMP nsFilePicker::Show(int16_t *retval)
89 NS_ENSURE_ARG_POINTER(retval);
91 bool result = false;
92 nsAutoCString fileBuffer;
93 char *converted = ConvertToFileSystemCharset(mDefault);
94 if (nullptr == converted) {
95 LossyCopyUTF16toASCII(mDefault, fileBuffer);
97 else {
98 fileBuffer.Assign(converted);
99 nsMemory::Free( converted );
102 char *title = ConvertToFileSystemCharset(mTitle);
103 if (nullptr == title)
104 title = ToNewCString(mTitle);
105 nsAutoCString initialDir;
106 if (mDisplayDirectory)
107 mDisplayDirectory->GetNativePath(initialDir);
108 // If no display directory, re-use the last one.
109 if(initialDir.IsEmpty())
110 initialDir = mLastUsedDirectory;
112 mFile.Truncate();
114 FILEDLG filedlg;
115 memset(&filedlg, 0, sizeof(FILEDLG));
116 filedlg.cbSize = sizeof(FILEDLG);
117 filedlg.pszTitle = title;
119 if (mMode == modeGetFolder) {
120 PL_strncat(filedlg.szFullFile, initialDir.get(), MAX_PATH);
121 if (filedlg.szFullFile[0] &&
122 filedlg.szFullFile[strlen(filedlg.szFullFile) - 1] != '\\')
123 PL_strncat(filedlg.szFullFile, "\\", 1);
124 PL_strncat(filedlg.szFullFile, "^", 1);
125 filedlg.fl = FDS_OPEN_DIALOG | FDS_CENTER;
126 filedlg.pfnDlgProc = DirDialogProc;
127 DosError(FERR_DISABLEHARDERR);
128 WinFileDlg(HWND_DESKTOP, mWnd, &filedlg);
129 DosError(FERR_ENABLEHARDERR);
130 char* tempptr = strchr(filedlg.szFullFile, '^');
131 if (tempptr)
132 *tempptr = '\0';
133 if (filedlg.lReturn == DID_OK) {
134 result = true;
135 if (!mDisplayDirectory)
136 mDisplayDirectory = do_CreateInstance("@mozilla.org/file/local;1");
137 if (mDisplayDirectory)
138 mDisplayDirectory->InitWithNativePath(nsDependentCString(filedlg.szFullFile));
139 mFile.Assign(filedlg.szFullFile);
142 else {
143 PL_strncpy(filedlg.szFullFile, initialDir.get(), MAX_PATH);
144 if (filedlg.szFullFile[0] &&
145 filedlg.szFullFile[strlen(filedlg.szFullFile) - 1] != '\\')
146 PL_strncat(filedlg.szFullFile, "\\", 1);
147 PL_strncat(filedlg.szFullFile, fileBuffer.get(), MAX_PATH);
148 filedlg.fl = FDS_CENTER;
149 if (mMode == modeSave) {
150 filedlg.fl |= FDS_SAVEAS_DIALOG | FDS_ENABLEFILELB;
151 } else if (mMode == modeOpenMultiple) {
152 filedlg.fl |= FDS_MULTIPLESEL | FDS_OPEN_DIALOG;
153 } else {
154 filedlg.fl |= FDS_OPEN_DIALOG;
156 PMYDATA pmydata;
157 pmydata = (PMYDATA)calloc(1, sizeof(MYDATA));
158 filedlg.ulUser = (ULONG)pmydata;
159 filedlg.pfnDlgProc = FileDialogProc;
161 uint32_t i;
163 PSZ *apszTypeList;
164 apszTypeList = (PSZ *)malloc(mTitles.Length()*sizeof(PSZ)+1);
165 for (i = 0; i < mTitles.Length(); i++)
167 const nsString& typeWide = mTitles[i];
168 nsAutoCharBuffer buffer;
169 int32_t bufLength;
170 WideCharToMultiByte(0, typeWide.get(), typeWide.Length(),
171 buffer, bufLength);
172 apszTypeList[i] = ToNewCString(nsDependentCString(buffer.Elements()));
174 apszTypeList[i] = 0;
175 filedlg.papszITypeList = (PAPSZ)apszTypeList;
177 PSZ *apszFilterList;
178 apszFilterList = (PSZ *)malloc(mFilters.Length()*sizeof(PSZ)+1);
179 for (i = 0; i < mFilters.Length(); i++)
181 const nsString& filterWide = mFilters[i];
182 apszFilterList[i] = ToNewCString(filterWide);
184 apszFilterList[i] = 0;
185 pmydata->papszIFilterList = (PAPSZ)apszFilterList;
187 pmydata->ulCurExt = mSelectedType;
189 bool fileExists = true;
190 do {
191 DosError(FERR_DISABLEHARDERR);
192 WinFileDlg(HWND_DESKTOP, mWnd, &filedlg);
193 DosError(FERR_ENABLEHARDERR);
194 if ((filedlg.lReturn == DID_OK) && (mMode == modeSave)) {
195 PRFileInfo64 fileinfo64;
196 PRStatus status = PR_GetFileInfo64(filedlg.szFullFile, &fileinfo64);
197 if (status == PR_SUCCESS) {
198 fileExists = true;
199 } else {
200 fileExists = false;
202 if (fileExists) {
203 if (!gpszFDSaveCaption) {
204 HMODULE hmod;
205 char LoadError[CCHMAXPATH];
206 char loadedString[256];
207 int length;
208 DosLoadModule(LoadError, CCHMAXPATH, "PMSDMRI", &hmod);
209 length = WinLoadString((HAB)0, hmod, 1110, 256, loadedString);
210 gpszFDSaveCaption = (char*)malloc(length+1);
211 strcpy(gpszFDSaveCaption, loadedString);
212 length = WinLoadString((HAB)0, hmod, 1135, 256, loadedString);
213 gpszFDFileExists = (char*)malloc(length+1);
214 strcpy(gpszFDFileExists, loadedString);
215 length = WinLoadString((HAB)0, hmod, 1136, 256, loadedString);
216 gpszFDFileReadOnly = (char*)malloc(length+1);
217 strcpy(gpszFDFileReadOnly, loadedString);
218 int i;
219 for (i=0;i<256 && gpszFDFileExists[i];i++ ) {
220 if (gpszFDFileExists[i] == '%') {
221 gpszFDFileExists[i+1] = 's';
222 break;
225 for (i=0;i<256 && gpszFDFileReadOnly[i];i++ ) {
226 if (gpszFDFileReadOnly[i] == '%') {
227 gpszFDFileReadOnly[i+1] = 's';
228 break;
231 DosFreeModule(hmod);
234 char pszFullText[256+CCHMAXPATH];
235 FILESTATUS3 fsts3;
236 ULONG ulResponse;
237 DosQueryPathInfo( filedlg.szFullFile, FIL_STANDARD, &fsts3, sizeof(FILESTATUS3));
238 if (fsts3.attrFile & FILE_READONLY) {
239 sprintf(pszFullText, gpszFDFileReadOnly, filedlg.szFullFile);
240 ulResponse = WinMessageBox(HWND_DESKTOP, mWnd, pszFullText,
241 gpszFDSaveCaption, 0,
242 MB_OK | MB_MOVEABLE | MB_WARNING);
243 } else {
244 sprintf(pszFullText, gpszFDFileExists, filedlg.szFullFile);
245 ulResponse = WinMessageBox(HWND_DESKTOP, mWnd, pszFullText,
246 gpszFDSaveCaption, 0,
247 MB_YESNO | MB_MOVEABLE | MB_WARNING);
250 if (ulResponse == MBID_YES) {
251 fileExists = false;
255 } while (mMode == modeSave && fileExists && filedlg.lReturn == DID_OK);
257 if (filedlg.lReturn == DID_OK) {
258 result = true;
259 if (mMode == modeOpenMultiple) {
260 nsresult rv;
262 if (filedlg.papszFQFilename) {
263 for (ULONG i=0;i<filedlg.ulFQFCount;i++) {
264 nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1", &rv);
265 NS_ENSURE_SUCCESS(rv,rv);
267 rv = file->InitWithNativePath(nsDependentCString(*(filedlg.papszFQFilename)[i]));
268 NS_ENSURE_SUCCESS(rv,rv);
270 rv = mFiles.AppendObject(file);
271 NS_ENSURE_SUCCESS(rv,rv);
273 WinFreeFileDlgList(filedlg.papszFQFilename);
274 } else {
275 nsCOMPtr<nsIFile> file = do_CreateInstance("@mozilla.org/file/local;1", &rv);
276 NS_ENSURE_SUCCESS(rv,rv);
278 rv = file->InitWithNativePath(nsDependentCString(filedlg.szFullFile));
279 NS_ENSURE_SUCCESS(rv,rv);
281 rv = mFiles.AppendObject(file);
282 NS_ENSURE_SUCCESS(rv,rv);
284 } else {
285 mFile.Assign(filedlg.szFullFile);
287 mSelectedType = (int16_t)pmydata->ulCurExt;
290 for (i = 0; i < mTitles.Length(); i++)
292 nsMemory::Free(*(filedlg.papszITypeList[i]));
294 free(filedlg.papszITypeList);
296 for (i = 0; i < mFilters.Length(); i++)
298 nsMemory::Free(*(pmydata->papszIFilterList[i]));
300 free(pmydata->papszIFilterList);
301 free(pmydata);
304 if (title)
305 nsMemory::Free( title );
307 if (result) {
308 int16_t returnOKorReplace = returnOK;
310 nsresult rv;
311 // Remember last used directory.
312 nsCOMPtr<nsIFile> file(do_CreateInstance("@mozilla.org/file/local;1", &rv));
313 NS_ENSURE_SUCCESS(rv, rv);
315 file->InitWithNativePath(mFile);
316 nsCOMPtr<nsIFile> dir;
317 if (NS_SUCCEEDED(file->GetParent(getter_AddRefs(dir)))) {
318 nsAutoCString newDir;
319 dir->GetNativePath(newDir);
320 if(!newDir.IsEmpty())
321 PL_strncpyz(mLastUsedDirectory, newDir.get(), MAX_PATH+1);
322 // Update mDisplayDirectory with this directory, also.
323 // Some callers rely on this.
324 if (!mDisplayDirectory)
325 mDisplayDirectory = do_CreateInstance("@mozilla.org/file/local;1");
326 if (mDisplayDirectory)
327 mDisplayDirectory->InitWithNativePath( nsDependentCString(mLastUsedDirectory) );
330 if (mMode == modeSave) {
331 // Windows does not return resultReplace,
332 // we must check if file already exists
333 bool exists = false;
334 file->Exists(&exists);
335 if (exists)
336 returnOKorReplace = returnReplace;
338 *retval = returnOKorReplace;
340 else {
341 *retval = returnCancel;
343 return NS_OK;
348 NS_IMETHODIMP nsFilePicker::GetFile(nsIFile **aFile)
350 NS_ENSURE_ARG_POINTER(aFile);
352 if (mFile.IsEmpty())
353 return NS_OK;
355 nsCOMPtr<nsIFile> file(do_CreateInstance("@mozilla.org/file/local;1"));
357 NS_ENSURE_TRUE(file, NS_ERROR_FAILURE);
359 file->InitWithNativePath(mFile);
361 NS_ADDREF(*aFile = file);
363 return NS_OK;
366 //-------------------------------------------------------------------------
367 NS_IMETHODIMP nsFilePicker::GetFileURL(nsIURI **aFileURL)
369 *aFileURL = nullptr;
370 nsCOMPtr<nsIFile> file;
371 nsresult rv = GetFile(getter_AddRefs(file));
372 if (!file)
373 return rv;
375 return NS_NewFileURI(aFileURL, file);
378 NS_IMETHODIMP nsFilePicker::GetFiles(nsISimpleEnumerator **aFiles)
380 NS_ENSURE_ARG_POINTER(aFiles);
381 return NS_NewArrayEnumerator(aFiles, mFiles);
384 //-------------------------------------------------------------------------
386 // Get the file + path
388 //-------------------------------------------------------------------------
389 NS_IMETHODIMP nsFilePicker::SetDefaultString(const nsAString& aString)
391 mDefault = aString;
393 //First, make sure the file name is not too long!
394 int32_t nameLength;
395 int32_t nameIndex = mDefault.RFind("\\");
396 if (nameIndex == kNotFound)
397 nameIndex = 0;
398 else
399 nameIndex ++;
400 nameLength = mDefault.Length() - nameIndex;
402 if (nameLength > CCHMAXPATH) {
403 int32_t extIndex = mDefault.RFind(".");
404 if (extIndex == kNotFound)
405 extIndex = mDefault.Length();
407 //Let's try to shave the needed characters from the name part
408 int32_t charsToRemove = nameLength - CCHMAXPATH;
409 if (extIndex - nameIndex >= charsToRemove) {
410 mDefault.Cut(extIndex - charsToRemove, charsToRemove);
414 //Then, we need to replace illegal characters.
415 //Windows has the following statement:
416 //At this stage, we cannot replace the backslash as the string might represent a file path.
417 //But it is not correct - Windows assumes this is not a path as well,
418 //as one of the FILE_ILLEGAL_CHARACTERS is a colon (:)
420 mDefault.ReplaceChar("\"", '\'');
421 mDefault.ReplaceChar("<", '(');
422 mDefault.ReplaceChar(">", ')');
424 mDefault.ReplaceChar(FILE_ILLEGAL_CHARACTERS, '_');
426 return NS_OK;
429 NS_IMETHODIMP nsFilePicker::GetDefaultString(nsAString& aString)
431 return NS_ERROR_FAILURE;
434 //-------------------------------------------------------------------------
436 // The default extension to use for files
438 //-------------------------------------------------------------------------
439 NS_IMETHODIMP nsFilePicker::GetDefaultExtension(nsAString& aExtension)
441 aExtension = mDefaultExtension;
442 return NS_OK;
445 NS_IMETHODIMP nsFilePicker::SetDefaultExtension(const nsAString& aExtension)
447 mDefaultExtension = aExtension;
448 return NS_OK;
451 //-------------------------------------------------------------------------
453 // Set the filter index
455 //-------------------------------------------------------------------------
456 NS_IMETHODIMP nsFilePicker::GetFilterIndex(int32_t *aFilterIndex)
458 *aFilterIndex = mSelectedType;
459 return NS_OK;
462 NS_IMETHODIMP nsFilePicker::SetFilterIndex(int32_t aFilterIndex)
464 mSelectedType = aFilterIndex;
465 return NS_OK;
468 //-------------------------------------------------------------------------
469 void nsFilePicker::InitNative(nsIWidget *aParent,
470 const nsAString& aTitle)
472 mWnd = (HWND) ((aParent) ? aParent->GetNativeData(NS_NATIVE_WINDOW) : 0);
473 mTitle.Assign(aTitle);
477 //-------------------------------------------------------------------------
478 void nsFilePicker::GetFileSystemCharset(nsCString & fileSystemCharset)
480 static nsAutoCString aCharset;
481 nsresult rv;
483 if (aCharset.Length() < 1) {
484 nsCOMPtr <nsIPlatformCharset> platformCharset = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
485 if (NS_SUCCEEDED(rv))
486 rv = platformCharset->GetCharset(kPlatformCharsetSel_FileName, aCharset);
488 NS_ASSERTION(NS_SUCCEEDED(rv), "error getting platform charset");
489 if (NS_FAILED(rv))
490 aCharset.AssignLiteral("IBM850");
492 fileSystemCharset = aCharset;
495 //-------------------------------------------------------------------------
496 char * nsFilePicker::ConvertToFileSystemCharset(const nsAString& inString)
498 char *outString = nullptr;
499 nsresult rv = NS_OK;
501 // get file system charset and create a unicode encoder
502 if (nullptr == mUnicodeEncoder) {
503 nsAutoCString fileSystemCharset;
504 GetFileSystemCharset(fileSystemCharset);
506 nsCOMPtr<nsICharsetConverterManager> ccm =
507 do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
508 if (NS_SUCCEEDED(rv)) {
509 rv = ccm->GetUnicodeEncoderRaw(fileSystemCharset.get(), &mUnicodeEncoder);
513 // converts from unicode to the file system charset
514 if (NS_SUCCEEDED(rv)) {
515 int32_t inLength = inString.Length();
517 const nsAFlatString& flatInString = PromiseFlatString(inString);
519 int32_t outLength;
520 rv = mUnicodeEncoder->GetMaxLength(flatInString.get(), inLength,
521 &outLength);
522 if (NS_SUCCEEDED(rv)) {
523 outString = static_cast<char*>(nsMemory::Alloc( outLength+1 ));
524 if (nullptr == outString) {
525 return nullptr;
527 rv = mUnicodeEncoder->Convert(flatInString.get(), &inLength, outString,
528 &outLength);
529 if (NS_SUCCEEDED(rv)) {
530 outString[outLength] = '\0';
535 return NS_SUCCEEDED(rv) ? outString : nullptr;
538 //-------------------------------------------------------------------------
539 char16_t * nsFilePicker::ConvertFromFileSystemCharset(const char *inString)
541 char16_t *outString = nullptr;
542 nsresult rv = NS_OK;
544 // get file system charset and create a unicode encoder
545 if (nullptr == mUnicodeDecoder) {
546 nsAutoCString fileSystemCharset;
547 GetFileSystemCharset(fileSystemCharset);
549 nsCOMPtr<nsICharsetConverterManager> ccm =
550 do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
551 if (NS_SUCCEEDED(rv)) {
552 rv = ccm->GetUnicodeDecoderRaw(fileSystemCharset.get(), &mUnicodeDecoder);
556 // converts from the file system charset to unicode
557 if (NS_SUCCEEDED(rv)) {
558 int32_t inLength = strlen(inString);
559 int32_t outLength;
560 rv = mUnicodeDecoder->GetMaxLength(inString, inLength, &outLength);
561 if (NS_SUCCEEDED(rv)) {
562 outString = static_cast<char16_t*>(nsMemory::Alloc( (outLength+1) * sizeof( char16_t ) ));
563 if (nullptr == outString) {
564 return nullptr;
566 rv = mUnicodeDecoder->Convert(inString, &inLength, outString, &outLength);
567 if (NS_SUCCEEDED(rv)) {
568 outString[outLength] = 0;
573 NS_ASSERTION(NS_SUCCEEDED(rv), "error charset conversion");
574 return NS_SUCCEEDED(rv) ? outString : nullptr;
578 NS_IMETHODIMP
579 nsFilePicker::AppendFilter(const nsAString& aTitle, const nsAString& aFilter)
581 if (aFilter.EqualsLiteral("..apps"))
582 mFilters.AppendElement(NS_LITERAL_STRING("*.exe;*.cmd;*.com;*.bat"));
583 else
584 mFilters.AppendElement(aFilter);
585 mTitles.AppendElement(aTitle);
587 return NS_OK;
590 MRESULT EXPENTRY DirDialogProc( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
592 switch ( msg ) {
593 case WM_INITDLG:
595 SWP swpFileST;
596 SWP swpDirST;
597 SWP swpDirLB;
598 SWP swpDriveST;
599 SWP swpDriveCB;
600 SWP swpDriveCBEF;
601 SWP swpOK;
602 SWP swpCancel;
603 HWND hwndFileST;
604 HWND hwndDirST;
605 HWND hwndDirLB;
606 HWND hwndDriveST;
607 HWND hwndDriveCB;
608 HWND hwndOK;
609 HWND hwndCancel;
610 HENUM henum;
611 HWND hwndNext;
612 ULONG ulCurY, ulCurX;
613 LONG lScreenX, lScreenY, lDlgFrameX, lDlgFrameY, lTitleBarY;
615 lScreenX = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
616 lScreenY = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
617 lDlgFrameX = WinQuerySysValue(HWND_DESKTOP, SV_CXDLGFRAME);
618 lDlgFrameY = WinQuerySysValue(HWND_DESKTOP, SV_CYDLGFRAME);
619 lTitleBarY = WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
621 hwndFileST = WinWindowFromID(hwndDlg, DID_FILENAME_TXT);
622 hwndDirST = WinWindowFromID(hwndDlg, DID_DIRECTORY_TXT);
623 hwndDirLB = WinWindowFromID(hwndDlg, DID_DIRECTORY_LB);
624 hwndDriveST = WinWindowFromID(hwndDlg, DID_DRIVE_TXT);
625 hwndDriveCB = WinWindowFromID(hwndDlg, DID_DRIVE_CB);
626 hwndOK = WinWindowFromID(hwndDlg, DID_OK);
627 hwndCancel = WinWindowFromID(hwndDlg, DID_CANCEL);
629 #define SPACING 10
630 // Reposition drives combobox
631 ulCurY = SPACING;
632 ulCurX = SPACING + lDlgFrameX;
633 WinQueryWindowPos(hwndOK, &swpOK);
634 WinSetWindowPos(hwndOK, 0, ulCurX, ulCurY, 0, 0, SWP_MOVE);
635 ulCurY += swpOK.cy + SPACING;
636 WinQueryWindowPos(hwndCancel, &swpCancel);
637 WinSetWindowPos(hwndCancel, 0, ulCurX+swpOK.cx+10, SPACING, 0, 0, SWP_MOVE);
638 WinQueryWindowPos(hwndDirLB, &swpDirLB);
639 WinSetWindowPos(hwndDirLB, 0, ulCurX, ulCurY, swpDirLB.cx, swpDirLB.cy, SWP_MOVE | SWP_SIZE);
640 ulCurY += swpDirLB.cy + SPACING;
641 WinQueryWindowPos(hwndDirST, &swpDirST);
642 WinSetWindowPos(hwndDirST, 0, ulCurX, ulCurY, swpDirST.cx, swpDirST.cy, SWP_MOVE | SWP_SIZE);
643 ulCurY += swpDirST.cy + SPACING;
644 WinQueryWindowPos(hwndDriveCB, &swpDriveCB);
645 WinQueryWindowPos(WinWindowFromID(hwndDriveCB, CBID_EDIT), &swpDriveCBEF);
646 WinSetWindowPos(hwndDriveCB, 0, ulCurX, ulCurY-(swpDriveCB.cy-swpDriveCBEF.cy)+5,
647 swpDirLB.cx,
648 swpDriveCB.cy,
649 SWP_SIZE | SWP_MOVE);
650 ulCurY += swpDriveCBEF.cy + SPACING;
651 WinQueryWindowPos(hwndDriveST, &swpDriveST);
652 WinSetWindowPos(hwndDriveST, 0, ulCurX, ulCurY, swpDriveST.cx, swpDriveST.cy, SWP_MOVE | SWP_SIZE);
653 ulCurY += swpDriveST.cy + SPACING;
654 WinQueryWindowPos(hwndFileST, &swpFileST);
655 WinSetWindowPos(hwndFileST, 0, ulCurX, ulCurY, swpFileST.cx, swpFileST.cy, SWP_MOVE | SWP_SIZE);
656 ulCurY += swpFileST.cy + SPACING;
658 // Hide unused stuff
659 henum = WinBeginEnumWindows(hwndDlg);
660 while ((hwndNext = WinGetNextWindow(henum)) != NULLHANDLE)
662 USHORT usID = WinQueryWindowUShort(hwndNext, QWS_ID);
663 if (usID != DID_FILENAME_TXT &&
664 usID != DID_DIRECTORY_TXT &&
665 usID != DID_DIRECTORY_LB &&
666 usID != DID_DRIVE_TXT &&
667 usID != DID_DRIVE_CB &&
668 usID != DID_OK &&
669 usID != DID_CANCEL &&
670 usID != FID_TITLEBAR &&
671 usID != FID_SYSMENU &&
672 usID != FID_MINMAX)
674 WinShowWindow(hwndNext, FALSE);
678 WinSetWindowPos(hwndDlg,
679 HWND_TOP,
680 (lScreenX/2)-((swpDirLB.cx+2*SPACING+2*lDlgFrameX)/2),
681 (lScreenY/2)-((ulCurY+2*lDlgFrameY+lTitleBarY)/2),
682 swpDirLB.cx+2*SPACING+2*lDlgFrameX,
683 ulCurY+2*lDlgFrameY+lTitleBarY,
684 SWP_MOVE | SWP_SIZE);
686 break;
687 case WM_CONTROL:
689 PFILEDLG pfiledlg;
690 pfiledlg = (PFILEDLG)WinQueryWindowPtr(hwndDlg, QWL_USER);
692 HPS hps;
693 SWP swp;
694 HWND hwndST;
695 RECTL rectlString = {0,0,1000,1000};
696 char *ptr = nullptr;
697 int iHalfLen;
698 int iLength;
699 CHAR szString[CCHMAXPATH];
701 hwndST = WinWindowFromID(hwndDlg, DID_FILENAME_TXT);
703 strcpy(szString, pfiledlg->szFullFile);
704 iLength = strlen(pfiledlg->szFullFile);
705 /* If we are not just a drive */
706 if (iLength > 3) {
707 if (szString[iLength-1] == '\\') {
708 szString[iLength-1] = '\0';
709 iLength--;
713 hps = WinGetPS(hwndST);
714 WinQueryWindowPos(hwndST, &swp);
716 WinDrawText(hps, iLength, szString,
717 &rectlString, 0, 0,
718 DT_BOTTOM | DT_QUERYEXTENT | DT_TEXTATTRS);
719 while(rectlString.xRight > swp.cx)
721 iHalfLen = iLength / 2;
722 if(iHalfLen == 2)
723 break;
725 ptr = szString + iHalfLen;
726 memmove(ptr - 1, ptr, strlen(ptr) + 1);
727 szString[iHalfLen - 2] = '.';
728 szString[iHalfLen - 1] = '.';
729 szString[iHalfLen] = '.';
730 iLength = strlen(szString);
731 rectlString.xLeft = rectlString.yBottom = 0;
732 rectlString.xRight = rectlString.yTop = 1000;
733 WinDrawText(hps, iLength, szString,
734 &rectlString, 0, 0,
735 DT_BOTTOM | DT_QUERYEXTENT | DT_TEXTATTRS);
738 WinReleasePS(hps);
739 WinSetWindowText(hwndST, szString);
741 break;
743 return WinDefFileDlgProc(hwndDlg, msg, mp1, mp2);
746 MRESULT EXPENTRY FileDialogProc( HWND hwndDlg, ULONG msg, MPARAM mp1, MPARAM mp2)
748 MRESULT mr;
749 PFILEDLG pfiledlg;
750 HWND hwndTypeCombo;
751 INT i;
752 SWP swp;
753 PMYDATA pmydata;
755 switch ( msg ) {
756 case WM_INITDLG:
757 /* Create another dropdown that we manage */
758 mr = WinDefFileDlgProc(hwndDlg, msg, mp1, mp2);
759 hwndTypeCombo = WinWindowFromID(hwndDlg, DID_FILTER_CB);
760 WinQueryWindowPos(hwndTypeCombo, &swp);
761 WinSetWindowPos(hwndTypeCombo, NULLHANDLE, 0, 0, 0, 0, SWP_HIDE);
762 hwndTypeCombo = WinCreateWindow( hwndDlg, WC_COMBOBOX, "",
763 WS_VISIBLE | WS_PARENTCLIP | WS_SYNCPAINT | WS_TABSTOP | CBS_DROPDOWNLIST,
764 swp.x, swp.y,
765 swp.cx, swp.cy, hwndDlg, swp.hwndInsertBehind, 290,
766 nullptr, nullptr );
767 WinSendMsg( hwndTypeCombo, LM_DELETEALL, (MPARAM)0, (MPARAM)0 );
768 pfiledlg = (PFILEDLG)WinQueryWindowULong( hwndDlg, QWL_USER );
769 pmydata = (PMYDATA)pfiledlg->ulUser;
770 i = 0;
771 while (*(pfiledlg->papszITypeList[i]) != nullptr) {
772 WinSendMsg( hwndTypeCombo, LM_INSERTITEM, (MPARAM)LIT_END, (MPARAM)*(pfiledlg->papszITypeList[i]) );
773 i++;
775 WinSendMsg( hwndTypeCombo, LM_SELECTITEM, (MPARAM)pmydata->ulCurExt, (MPARAM)TRUE );
777 return mr;
778 case WM_CONTROL:
780 if ((SHORT1FROMMP(mp1) == 290) &&
781 (SHORT2FROMMP(mp1) == CBN_LBSELECT)) {
782 hwndTypeCombo = WinWindowFromID(hwndDlg, 290);
783 pfiledlg = (PFILEDLG)WinQueryWindowULong( hwndDlg, QWL_USER );
784 pmydata = (PMYDATA)pfiledlg->ulUser;
785 pmydata->ulCurExt = (ULONG)WinSendMsg( hwndTypeCombo, LM_QUERYSELECTION, (MPARAM)LIT_FIRST, (MPARAM)0 );
786 if (pfiledlg->fl & FDS_OPEN_DIALOG) {
787 WinSetWindowText(WinWindowFromID(hwndDlg,DID_FILENAME_ED), *(pmydata->papszIFilterList[pmydata->ulCurExt]));
788 WinSendMsg(WinWindowFromID(hwndDlg,DID_FILENAME_ED), EM_SETSEL, MPFROM2SHORT(0, 32000), (MPARAM)0 );
789 WinSendMsg(hwndDlg, WM_CONTROL, MPFROM2SHORT(DID_FILTER_CB, CBN_LBSELECT), (MPARAM)0 );
791 return (MRESULT)TRUE;
794 break;
796 return WinDefFileDlgProc(hwndDlg, msg, mp1, mp2);