merge the formfield patch from ooo-build
[ooovba.git] / fpicker / source / win32 / filepicker / WinFileOpenImpl.cxx
blob2ee2867d9572f624a3ec125e0eb702c1a82eda91
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: WinFileOpenImpl.cxx,v $
10 * $Revision: 1.30 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_fpicker.hxx"
34 //------------------------------------------------------------------------
35 // includes
36 //------------------------------------------------------------------------
38 #include "shared.hxx"
39 #include "WinFileOpenImpl.hxx"
40 #include <osl/diagnose.h>
41 #include <osl/file.hxx>
42 #include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
43 #include <com/sun/star/ui/dialogs/FilePickerEvent.hpp>
44 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
45 #include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
46 #include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
47 #include <com/sun/star/ui/dialogs/ListBoxControlActions.hpp>
48 #include "..\misc\WinImplHelper.hxx"
50 #ifndef _FILEPICKER_HXX_
51 #include "filepicker.hxx"
52 #endif
53 #include "controlaccess.hxx"
54 #include <rtl/ustrbuf.hxx>
55 #include <rtl/string.hxx>
56 #include <osl/thread.hxx>
57 #include "filepickerstate.hxx"
59 //------------------------------------------------------------------------
60 // namespace directives
61 //------------------------------------------------------------------------
63 using namespace com::sun::star;
65 using com::sun::star::ui::dialogs::FilePickerEvent;
66 using com::sun::star::lang::IllegalArgumentException;
67 using com::sun::star::ui::dialogs::XFilePicker2;
69 using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
70 using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
71 using namespace ::com::sun::star::ui::dialogs::ListboxControlActions;
73 //-------------------------------------------------------------------------
74 // to distinguish what to do in the enum child window callback function
75 //-------------------------------------------------------------------------
77 enum ECW_ACTION_T
79 INIT_CUSTOM_CONTROLS,
80 CACHE_CONTROL_VALUES
83 struct EnumParam
85 ECW_ACTION_T m_action;
86 CWinFileOpenImpl* m_instance;
88 EnumParam( ECW_ACTION_T action, CWinFileOpenImpl* instance ):
89 m_action( action ),
90 m_instance( instance )
94 //-------------------------------------------------------------------------
95 // ctor
96 //-------------------------------------------------------------------------
98 CWinFileOpenImpl::CWinFileOpenImpl(
99 CFilePicker* aFilePicker,
100 sal_Bool bFileOpenDialog,
101 sal_uInt32 dwFlags,
102 sal_uInt32 dwTemplateId,
103 HINSTANCE hInstance) :
104 CFileOpenDialog(bFileOpenDialog, dwFlags, dwTemplateId, hInstance),
105 m_filterContainer(new CFilterContainer()),
106 m_Preview(new CPreviewAdapter(hInstance)),
107 m_CustomControlFactory(new CCustomControlFactory()),
108 m_CustomControls(m_CustomControlFactory->CreateCustomControlContainer()),
109 m_FilePicker(aFilePicker),
110 m_bInitialSelChanged(sal_True),
111 m_HelpPopupWindow(hInstance, m_hwndFileOpenDlg),
112 m_ExecuteFilePickerState(new CExecuteFilePickerState()),
113 m_NonExecuteFilePickerState(new CNonExecuteFilePickerState())
115 m_FilePickerState = m_NonExecuteFilePickerState;
118 //------------------------------------------------------------------------
119 // dtor
120 //------------------------------------------------------------------------
122 CWinFileOpenImpl::~CWinFileOpenImpl()
124 delete m_ExecuteFilePickerState;
125 delete m_NonExecuteFilePickerState;
128 //------------------------------------------------------------------------
129 // we expect the directory in URL format
130 //------------------------------------------------------------------------
132 void CWinFileOpenImpl::setDisplayDirectory(const rtl::OUString& aDirectory)
133 throw( IllegalArgumentException, uno::RuntimeException )
135 rtl::OUString aSysDirectory;
136 if( aDirectory.getLength() > 0)
138 if ( ::osl::FileBase::E_None !=
139 ::osl::FileBase::getSystemPathFromFileURL(aDirectory,aSysDirectory))
140 throw IllegalArgumentException(
141 rtl::OUString::createFromAscii("Invalid directory"),
142 static_cast<XFilePicker2*>(m_FilePicker), 1);
144 // we ensure that there is a trailing '/' at the end of
145 // he given file url, because the windows functions only
146 // works correctly when providing "c:\" or an environment
147 // variable like "=c:=c:\.." etc. is set, else the
148 // FolderPicker would stand in the root of the shell
149 // hierarchie which is the desktop folder
150 if ( aSysDirectory.lastIndexOf(BACKSLASH) != (aSysDirectory.getLength() - 1))
151 aSysDirectory += BACKSLASH;
154 // call base class method
155 CFileOpenDialog::setDisplayDirectory(aSysDirectory);
158 //------------------------------------------------------------------------
159 // we return the directory in URL format
160 //------------------------------------------------------------------------
162 rtl::OUString CWinFileOpenImpl::getDisplayDirectory() throw(uno::RuntimeException)
164 return m_FilePickerState->getDisplayDirectory(this);
167 //-----------------------------------------------------------------------------------------
169 //-----------------------------------------------------------------------------------------
171 void SAL_CALL CWinFileOpenImpl::setDefaultName(const rtl::OUString& aName)
172 throw( IllegalArgumentException, uno::RuntimeException )
174 // we don't set the default name directly
175 // because this influences how the file open
176 // dialog sets the initial path when it is about
177 // to open (see MSDN: OPENFILENAME)
178 // so we save the default name which should
179 // appear in the file-name-box and set
180 // this name when processing onInitDone
181 m_defaultName = aName;
184 //-----------------------------------------------------------------------------------------
185 // return format: URL
186 // if multiselection is allowed there are two different cases
187 // 1. one file selected: the sequence contains one entry path\filename.ext
188 // 2. multiple files selected: the sequence contains multiple entries
189 // the first entry is the path url, all other entries are file names
190 //-----------------------------------------------------------------------------------------
192 uno::Sequence<rtl::OUString> SAL_CALL CWinFileOpenImpl::getFiles()
193 throw(uno::RuntimeException)
195 return m_FilePickerState->getFiles(this);
198 //-----------------------------------------------------------------------------------------
199 // shows the FileOpen/FileSave dialog
200 //-----------------------------------------------------------------------------------------
202 sal_Int16 SAL_CALL CWinFileOpenImpl::execute( ) throw(uno::RuntimeException)
204 sal_Int16 rc = CFileOpenDialog::doModal();
206 if (1 == rc)
207 rc = ::com::sun::star::ui::dialogs::ExecutableDialogResults::OK;
208 else if (0 == rc)
209 rc = ::com::sun::star::ui::dialogs::ExecutableDialogResults::CANCEL;
210 else
211 throw uno::RuntimeException(
212 rtl::OUString::createFromAscii("Error executing dialog"),
213 static_cast<XFilePicker2*>(m_FilePicker));
215 return rc;
218 //-----------------------------------------------------------------------------------------
219 // appends a new filter
220 // returns false if the title (aTitle) was already added or the title or the filter are
221 // empty
222 //-----------------------------------------------------------------------------------------
224 void SAL_CALL CWinFileOpenImpl::appendFilter(const rtl::OUString& aTitle, const rtl::OUString& aFilter)
225 throw(IllegalArgumentException, uno::RuntimeException)
227 sal_Bool bRet = m_filterContainer->addFilter(aTitle, aFilter);
229 if (!bRet)
230 throw IllegalArgumentException(
231 rtl::OUString::createFromAscii("filter already exists"),
232 static_cast<XFilePicker2*>(m_FilePicker), 1);
234 // #95345# see MSDN OPENFILENAME
235 // If nFilterIndex is zero and lpstrCustomFilter is NULL,
236 // the system uses the first filter in the lpstrFilter buffer.
237 // to reflect this we must set the filter index so that calls
238 // to getSelectedFilterIndex without explicitly calling
239 // setFilterIndex before does not return 0 which leads to a
240 // false state
241 if (0 == getSelectedFilterIndex())
242 CFileOpenDialog::setFilterIndex(1);
245 //-----------------------------------------------------------------------------------------
246 // sets a current filter
247 //-----------------------------------------------------------------------------------------
249 void SAL_CALL CWinFileOpenImpl::setCurrentFilter(const rtl::OUString& aTitle)
250 throw( IllegalArgumentException, uno::RuntimeException)
252 sal_Int32 filterPos = m_filterContainer->getFilterPos(aTitle);
254 if (filterPos < 0)
255 throw IllegalArgumentException(
256 rtl::OUString::createFromAscii("filter doesn't exist"),
257 static_cast<XFilePicker2*>(m_FilePicker), 1);
259 // filter index of the base class starts with 1
260 CFileOpenDialog::setFilterIndex(filterPos + 1);
263 //-----------------------------------------------------------------------------------------
264 // returns the currently selected filter
265 //-----------------------------------------------------------------------------------------
267 rtl::OUString SAL_CALL CWinFileOpenImpl::getCurrentFilter() throw(uno::RuntimeException)
269 sal_uInt32 nIndex = getSelectedFilterIndex();
271 rtl::OUString currentFilter;
272 if (nIndex > 0)
274 // filter index of the base class starts with 1
275 if (!m_filterContainer->getFilter(nIndex - 1, currentFilter)) {
276 OSL_ASSERT(false);
280 return currentFilter;
283 //-----------------------------------------------------------------------------------------
285 //-----------------------------------------------------------------------------------------
287 inline void SAL_CALL CWinFileOpenImpl::appendFilterGroupSeparator()
289 m_filterContainer->addFilter(FILTER_SEPARATOR, ALL_FILES_WILDCARD, ALLOW_DUPLICATES);
292 //-----------------------------------------------------------------------------------------
293 // XFilterGroupManager
294 //-----------------------------------------------------------------------------------------
296 void SAL_CALL CWinFileOpenImpl::appendFilterGroup(const rtl::OUString& sGroupTitle, const uno::Sequence<beans::StringPair>& aFilters)
297 throw (IllegalArgumentException, uno::RuntimeException)
299 (void) sGroupTitle; // avoid warning
300 OSL_ENSURE(0 == sGroupTitle.getLength(), "appendFilterGroup: Parameter 'GroupTitle' currently ignored");
302 sal_Int32 nFilters = aFilters.getLength();
304 OSL_PRECOND(nFilters > 0, "Empty filter list");
306 if (nFilters > 0)
308 // append a separator before the next group if
309 // there is already a group of filters
310 if (m_filterContainer->numFilter() > 0)
311 appendFilterGroupSeparator();
313 for (int i = 0; i < nFilters; i++)
314 appendFilter(aFilters[i].First, aFilters[i].Second);
318 //=================================================================================================================
319 // XExtendedFilePicker
320 //=================================================================================================================
322 void SAL_CALL CWinFileOpenImpl::setValue(sal_Int16 aControlId, sal_Int16 aControlAction, const uno::Any& aValue)
323 throw(uno::RuntimeException)
325 OSL_ASSERT(m_FilePickerState);
326 m_FilePickerState->setValue(aControlId, aControlAction, aValue);
329 //-----------------------------------------------------------------------------------------
330 // returns the value of an custom template element
331 // we assume that there are only checkboxes or comboboxes
332 //-----------------------------------------------------------------------------------------
334 uno::Any SAL_CALL CWinFileOpenImpl::getValue(sal_Int16 aControlId, sal_Int16 aControlAction)
335 throw(uno::RuntimeException)
337 OSL_ASSERT(m_FilePickerState);
338 return m_FilePickerState->getValue(aControlId, aControlAction);
341 //-----------------------------------------------------------------------------------------
342 // enables a custom template element
343 //-----------------------------------------------------------------------------------------
345 void SAL_CALL CWinFileOpenImpl::enableControl(sal_Int16 ControlID, sal_Bool bEnable)
346 throw(uno::RuntimeException)
348 OSL_ASSERT(m_FilePickerState);
349 m_FilePickerState->enableControl(ControlID, bEnable);
352 //-----------------------------------------------------------------------------------------
354 //-----------------------------------------------------------------------------------------
356 void SAL_CALL CWinFileOpenImpl::setLabel( sal_Int16 aControlId, const rtl::OUString& aLabel )
357 throw (uno::RuntimeException)
359 m_FilePickerState->setLabel(aControlId, aLabel);
362 //-----------------------------------------------------------------------------------------
364 //-----------------------------------------------------------------------------------------
366 rtl::OUString SAL_CALL CWinFileOpenImpl::getLabel( sal_Int16 aControlId )
367 throw (uno::RuntimeException)
369 return m_FilePickerState->getLabel(aControlId);
372 //-----------------------------------------------------------------------------------------
374 //-----------------------------------------------------------------------------------------
376 uno::Sequence<sal_Int16> SAL_CALL CWinFileOpenImpl::getSupportedImageFormats()
377 throw (uno::RuntimeException)
379 return m_Preview->getSupportedImageFormats();
382 //-----------------------------------------------------------------------------------------
384 //-----------------------------------------------------------------------------------------
386 sal_Int32 SAL_CALL CWinFileOpenImpl::getTargetColorDepth()
387 throw (uno::RuntimeException)
389 return m_Preview->getTargetColorDepth();
392 //-----------------------------------------------------------------------------------------
394 //-----------------------------------------------------------------------------------------
396 sal_Int32 SAL_CALL CWinFileOpenImpl::getAvailableWidth()
397 throw (uno::RuntimeException)
399 return m_Preview->getAvailableWidth();
402 //-----------------------------------------------------------------------------------------
404 //-----------------------------------------------------------------------------------------
406 sal_Int32 SAL_CALL CWinFileOpenImpl::getAvailableHeight()
407 throw (uno::RuntimeException)
409 return m_Preview->getAvailableHeight();
412 //-----------------------------------------------------------------------------------------
414 //-----------------------------------------------------------------------------------------
416 void SAL_CALL CWinFileOpenImpl::setImage(sal_Int16 aImageFormat, const uno::Any& aImage)
417 throw (IllegalArgumentException, uno::RuntimeException)
419 m_Preview->setImage(aImageFormat,aImage);
422 //-----------------------------------------------------------------------------------------
424 //-----------------------------------------------------------------------------------------
426 sal_Bool SAL_CALL CWinFileOpenImpl::setShowState(sal_Bool bShowState)
427 throw (uno::RuntimeException)
429 return m_Preview->setShowState(bShowState);
432 //-----------------------------------------------------------------------------------------
434 //-----------------------------------------------------------------------------------------
436 sal_Bool SAL_CALL CWinFileOpenImpl::getShowState()
437 throw (uno::RuntimeException)
439 return m_Preview->getShowState();
442 //-----------------------------------------------------------------------------------------
444 //-----------------------------------------------------------------------------------------
446 void SAL_CALL CWinFileOpenImpl::cancel()
448 if (IsWindow(m_hwndFileOpenDlg))
450 // simulate a mouse click to the
451 // cancel button
452 PostMessage(
453 m_hwndFileOpenDlg,
454 WM_COMMAND,
455 MAKEWPARAM(IDCANCEL,BN_CLICKED),
456 (LPARAM)GetDlgItem(m_hwndFileOpenDlg, IDCANCEL));
460 //-----------------------------------------------------------------------------------------
461 // returns the id of a custom template element
462 //-----------------------------------------------------------------------------------------
464 sal_Int16 SAL_CALL CWinFileOpenImpl::getFocused()
466 int nID = GetDlgCtrlID(GetFocus());
468 // we don't forward id's of standard file open
469 // dialog elements (ctlFirst is defined in dlgs.h
470 // in MS Platform SDK)
471 if (nID >= ctlFirst)
472 nID = 0;
474 return sal::static_int_cast< sal_Int16 >(nID);
477 //-----------------------------------------------------------------------------------------
479 //-----------------------------------------------------------------------------------------
481 inline sal_Bool SAL_CALL CWinFileOpenImpl::IsCustomControlHelpRequested(LPHELPINFO lphi) const
483 return ((lphi->iCtrlId != IDOK) && (lphi->iCtrlId != IDCANCEL) && (lphi->iCtrlId < ctlFirst));
486 //-----------------------------------------------------------------------------------------
487 // our own DlgProc because we do subclass the dialog
488 // we catch the WM_NCDESTROY message in order to erase an entry in our static map
489 // if one instance dies
490 //-----------------------------------------------------------------------------------------
492 LRESULT CALLBACK CWinFileOpenImpl::SubClassFunc(
493 HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam)
495 unsigned int lResult = 0;
497 CWinFileOpenImpl* pImpl = dynamic_cast<CWinFileOpenImpl*>(getCurrentInstance(hWnd));
499 switch(wMessage)
501 case WM_HELP:
503 LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
505 if (pImpl->IsCustomControlHelpRequested(lphi))
506 pImpl->onCustomControlHelpRequest(lphi);
507 else
508 lResult = CallWindowProc(
509 reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc),
510 hWnd,wMessage,wParam,lParam);
512 break;
514 case WM_SIZE:
515 lResult = CallWindowProc(
516 reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc),
517 hWnd,wMessage,wParam,lParam);
519 pImpl->onWMSize();
520 break;
522 case WM_WINDOWPOSCHANGED:
523 lResult = CallWindowProc(
524 reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc),
525 hWnd,wMessage,wParam,lParam);
527 pImpl->onWMWindowPosChanged();
528 break;
530 case WM_SHOWWINDOW:
531 lResult = CallWindowProc(
532 reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc),
533 hWnd,wMessage,wParam,lParam);
535 pImpl->onWMShow((BOOL)wParam);
536 break;
538 case WM_NCDESTROY:
539 // restore the old window proc
540 SetWindowLong(hWnd, GWL_WNDPROC,
541 reinterpret_cast<LONG>(pImpl->m_pfnOldDlgProc));
543 lResult = CallWindowProc(
544 reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc),
545 hWnd,wMessage,wParam,lParam);
546 break;
548 default:
549 lResult = CallWindowProc(
550 reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc),
551 hWnd,wMessage,wParam,lParam);
552 break;
554 } // switch
556 return lResult;
559 //-----------------------------------------------------------------
561 //-----------------------------------------------------------------
563 void SAL_CALL CWinFileOpenImpl::InitControlLabel(HWND hWnd)
565 //-----------------------------------------
566 // set the labels for all extendet controls
567 //-----------------------------------------
569 sal_Int16 aCtrlId = sal::static_int_cast< sal_Int16 >(GetDlgCtrlID(hWnd));
570 rtl::OUString aLabel = m_ResProvider.getResString(aCtrlId);
571 if (aLabel.getLength())
572 setLabel(aCtrlId, aLabel);
575 //-----------------------------------------------------------------
576 // There may be problems with the layout of our custom controls,
577 // so that they are not aligned with the standard controls of the
578 // FileOpen dialog.
579 // We use a simple algorithm to move the custom controls to their
580 // proper position and resize them.
581 // Our approach is to align all static text controls with the
582 // static text control "File name" of the FileOpen dialog,
583 // all checkboxes and all list/comboboxes will be left aligned with
584 // the standard combobox edt1 (defined in MS platform sdk dlgs.h)
585 // and all push buttons will be left aligned with the standard
586 // "OK" button
587 //-----------------------------------------------------------------
589 void SAL_CALL CWinFileOpenImpl::InitCustomControlContainer(HWND hCustomControl)
591 m_CustomControls->AddControl(
592 m_CustomControlFactory->CreateCustomControl(hCustomControl,m_hwndFileOpenDlg));
595 //-----------------------------------------------------------------
597 //-----------------------------------------------------------------
599 void SAL_CALL CWinFileOpenImpl::CacheControlState(HWND hWnd)
601 OSL_ASSERT(m_FilePickerState && m_NonExecuteFilePickerState);
602 m_ExecuteFilePickerState->cacheControlState(hWnd, m_NonExecuteFilePickerState);
605 //-----------------------------------------------------------------
607 //-----------------------------------------------------------------
609 BOOL CALLBACK CWinFileOpenImpl::EnumChildWndProc(HWND hWnd, LPARAM lParam)
611 EnumParam* enumParam = (EnumParam*)lParam;
612 CWinFileOpenImpl* pImpl = enumParam->m_instance;
614 OSL_ASSERT(pImpl);
616 BOOL bRet = TRUE;
618 switch(enumParam->m_action)
620 case INIT_CUSTOM_CONTROLS:
621 pImpl->InitControlLabel(hWnd);
622 pImpl->InitCustomControlContainer(hWnd);
623 break;
625 case CACHE_CONTROL_VALUES:
626 pImpl->CacheControlState(hWnd);
627 break;
629 default:
630 // should not end here
631 OSL_ASSERT(sal_False);
634 return bRet;
637 //-----------------------------------------------------------------
639 //-----------------------------------------------------------------
641 sal_uInt32 SAL_CALL CWinFileOpenImpl::onFileOk()
643 m_NonExecuteFilePickerState->reset();
645 EnumParam enumParam(CACHE_CONTROL_VALUES,this);
647 EnumChildWindows(
648 m_hwndFileOpenDlgChild,
649 CWinFileOpenImpl::EnumChildWndProc,
650 (LPARAM)&enumParam);
652 return 0;
655 //-----------------------------------------------------------------
657 //-----------------------------------------------------------------
659 void SAL_CALL CWinFileOpenImpl::onSelChanged(HWND)
661 // the windows file open dialog sends an initial
662 // SelChanged message after the InitDone message
663 // when the dialog is about to be opened
664 // if the lpstrFile buffer of the OPENFILENAME is
665 // empty (zero length string) the windows file open
666 // dialog sends a WM_SETTEXT message with an empty
667 // string to the file name edit line
668 // this would overwritte our text when we would set
669 // the default name in onInitDone, so we have to
670 // remeber that this is the first SelChanged message
671 // and set the default name here to overwrite the
672 // windows setting
673 InitialSetDefaultName();
675 FilePickerEvent evt;
676 m_FilePicker->fileSelectionChanged(evt);
679 // #i40865# The size of the standard labels 'File name'
680 // and 'File type' is to short in some cases when the
681 // label will be changed (e.g. in the Brazil version).
682 // We just make sure that the labels are using the maximum
683 // available space.
684 void CWinFileOpenImpl::EnlargeStdControlLabels() const
686 HWND hFilterBoxLabel = GetDlgItem(m_hwndFileOpenDlg, stc2);
687 HWND hFileNameBoxLabel = GetDlgItem(m_hwndFileOpenDlg, stc3);
688 HWND hFileNameBox = GetDlgItem(m_hwndFileOpenDlg, cmb13);
689 if (!hFileNameBox)
690 hFileNameBox = GetDlgItem(m_hwndFileOpenDlg, edt1); // under Win98 it is edt1 instead of cmb13
692 HWND hFilterBox = GetDlgItem(m_hwndFileOpenDlg, cmb1);
693 HWND hOkButton = GetDlgItem(m_hwndFileOpenDlg, IDOK);
695 // Move filter and file name box nearer to OK and Cancel button
696 RECT rcOkButton;
697 GetWindowRect(hOkButton, &rcOkButton);
699 const int MAX_GAP = IsWindows98() ? 5 : 10;
700 const int OFFSET = IsWindows98() ? 10 : 0;
702 RECT rcFileNameBox;
703 GetWindowRect(hFileNameBox, &rcFileNameBox);
704 int w = rcFileNameBox.right - rcFileNameBox.left;
705 int h = rcFileNameBox.bottom - rcFileNameBox.top;
707 int gap = rcOkButton.left - rcFileNameBox.right;
708 gap = (gap > MAX_GAP) ? gap - MAX_GAP : gap;
710 ScreenToClient(m_hwndFileOpenDlg, (LPPOINT)&rcFileNameBox);
711 MoveWindow(hFileNameBox, rcFileNameBox.left + gap + OFFSET, rcFileNameBox.top, w - OFFSET, h, true);
713 RECT rcFilterBox;
714 GetWindowRect(hFilterBox, &rcFilterBox);
715 w = rcFilterBox.right - rcFilterBox.left;
716 h = rcFilterBox.bottom - rcFilterBox.top;
717 ScreenToClient(m_hwndFileOpenDlg, (LPPOINT)&rcFilterBox);
718 MoveWindow(hFilterBox, rcFilterBox.left + gap + OFFSET, rcFilterBox.top, w - OFFSET, h, true);
720 // get the new window rect
721 GetWindowRect(hFileNameBox, &rcFileNameBox);
723 RECT rcFilterBoxLabel;
724 GetWindowRect(hFilterBoxLabel, &rcFilterBoxLabel);
725 int offset = rcFileNameBox.left - rcFilterBoxLabel.right - 1;
727 w = rcFilterBoxLabel.right - rcFilterBoxLabel.left + offset;
728 h = rcFilterBoxLabel.bottom - rcFilterBoxLabel.top;
729 ScreenToClient(m_hwndFileOpenDlg, (LPPOINT)&rcFilterBoxLabel);
730 MoveWindow(hFilterBoxLabel, rcFilterBoxLabel.left, rcFilterBoxLabel.top, w, h, true);
732 RECT rcFileNameBoxLabel;
733 GetWindowRect(hFileNameBoxLabel, &rcFileNameBoxLabel);
734 w = rcFileNameBoxLabel.right - rcFileNameBoxLabel.left + offset;
735 h = rcFileNameBoxLabel.bottom - rcFileNameBoxLabel.top;
736 ScreenToClient(m_hwndFileOpenDlg, (LPPOINT)&rcFileNameBoxLabel);
737 MoveWindow(hFileNameBoxLabel, rcFileNameBoxLabel.left, rcFileNameBoxLabel.top, w, h, true);
740 void SAL_CALL CWinFileOpenImpl::onInitDone()
742 m_Preview->setParent(m_hwndFileOpenDlg);
744 // but now we have a valid parent handle
745 m_HelpPopupWindow.setParent(m_hwndFileOpenDlg);
747 EnlargeStdControlLabels();
749 // #99826
750 // Set the online filepicker state before initializing
751 // the control labels from the resource else we are
752 // overriding the offline settings
753 m_ExecuteFilePickerState->setHwnd(m_hwndFileOpenDlgChild);
755 m_FilePickerState = m_ExecuteFilePickerState;
757 // initialize controls from cache
759 EnumParam enumParam(INIT_CUSTOM_CONTROLS,this);
761 EnumChildWindows(
762 m_hwndFileOpenDlgChild,
763 CWinFileOpenImpl::EnumChildWndProc,
764 (LPARAM)&enumParam);
766 m_ExecuteFilePickerState->initFilePickerControls(
767 m_NonExecuteFilePickerState->getControlCommand());
769 SetDefaultExtension();
771 m_CustomControls->Align();
773 m_CustomControls->SetFont(
774 reinterpret_cast<HFONT>(SendMessage(m_hwndFileOpenDlg, WM_GETFONT, 0, 0)));
776 // resume event notification that was
777 // defered in onInitDialog
778 m_FilePicker->resumeEventNotification();
780 //#105996 let vcl know that now a system window is active
781 PostMessage(
782 HWND_BROADCAST,
783 RegisterWindowMessage(TEXT("SYSTEM_WINDOW_ACTIVATED")),
787 // call the parent function to center the
788 // dialog to it's parent
789 CFileOpenDialog::onInitDone();
792 //-----------------------------------------------------------------
794 //-----------------------------------------------------------------
796 void SAL_CALL CWinFileOpenImpl::onFolderChanged()
798 FilePickerEvent evt;
799 m_FilePicker->directoryChanged(evt);
802 //-----------------------------------------------------------------
804 //-----------------------------------------------------------------
806 void SAL_CALL CWinFileOpenImpl::onTypeChanged(sal_uInt32)
808 SetDefaultExtension();
810 FilePickerEvent evt;
811 evt.ElementId = LISTBOX_FILTER;
812 m_FilePicker->controlStateChanged(evt);
815 //-----------------------------------------------------------------------------------------
816 // onMessageCommand handler
817 //-----------------------------------------------------------------------------------------
819 sal_uInt32 SAL_CALL CWinFileOpenImpl::onCtrlCommand(
820 HWND, sal_uInt16 ctrlId, sal_uInt16)
822 SetDefaultExtension();
824 if (ctrlId < ctlFirst)
826 FilePickerEvent evt;
827 evt.ElementId = ctrlId;
828 m_FilePicker->controlStateChanged(evt);
831 return 0;
834 //-----------------------------------------------------------------------------------------
836 //-----------------------------------------------------------------------------------------
838 void CWinFileOpenImpl::onWMSize()
840 m_Preview->notifyParentSizeChanged();
841 m_CustomControls->Align();
842 m_FilePicker->dialogSizeChanged();
845 //-----------------------------------------------------------------------------------------
847 //-----------------------------------------------------------------------------------------
849 void CWinFileOpenImpl::onWMShow(BOOL bShow)
851 m_Preview->notifyParentShow(bShow);
854 //-----------------------------------------------------------------------------------------
856 //-----------------------------------------------------------------------------------------
858 void CWinFileOpenImpl::onWMWindowPosChanged()
860 m_Preview->notifyParentWindowPosChanged();
863 //-----------------------------------------------------------------------------------------
865 //-----------------------------------------------------------------------------------------
867 void CWinFileOpenImpl::onCustomControlHelpRequest(LPHELPINFO lphi)
869 FilePickerEvent evt;
870 evt.ElementId = sal::static_int_cast< sal_Int16 >(lphi->iCtrlId);
872 rtl::OUString aPopupHelpText = m_FilePicker->helpRequested(evt);
874 if (aPopupHelpText.getLength())
876 m_HelpPopupWindow.setText(aPopupHelpText);
878 DWORD dwMsgPos = GetMessagePos();
879 m_HelpPopupWindow.show(LOWORD(dwMsgPos),HIWORD(dwMsgPos));
883 //-----------------------------------------------------------------------------------------
885 //-----------------------------------------------------------------------------------------
887 void SAL_CALL CWinFileOpenImpl::onInitDialog(HWND hwndDlg)
889 // subclass the dialog window
890 m_pfnOldDlgProc =
891 reinterpret_cast<WNDPROC>(
892 SetWindowLong( hwndDlg, GWL_WNDPROC,
893 reinterpret_cast<LONG>(SubClassFunc)));
896 //-----------------------------------------------------------------------------------------
897 // processing before showing the dialog
898 //-----------------------------------------------------------------------------------------
900 bool SAL_CALL CWinFileOpenImpl::preModal()
902 CFileOpenDialog::setFilter(
903 makeWinFilterBuffer(*m_filterContainer.get()));
905 return true;
908 //-----------------------------------------------------------------------------------------
909 // processing after showing the dialog
910 //-----------------------------------------------------------------------------------------
912 void CWinFileOpenImpl::postModal(sal_Int16 nDialogResult)
914 CFileOpenDialog::postModal(nDialogResult);
916 // empty the container in order to get rid off
917 // invalid controls in case someone calls execute
918 // twice in sequence with the same instance
919 m_CustomControls->RemoveAllControls();
921 m_FilePickerState = m_NonExecuteFilePickerState;
924 //-----------------------------------------------------------------------------------------
926 //-----------------------------------------------------------------------------------------
928 void SAL_CALL CWinFileOpenImpl::SetDefaultExtension()
930 HWND hwndChkSaveWithExt = GetDlgItem(m_hwndFileOpenDlgChild, 100);
932 if (hwndChkSaveWithExt)
934 uno::Any aAny = CheckboxGetState(hwndChkSaveWithExt);
935 sal_Bool bChecked = *reinterpret_cast<const sal_Bool*>(aAny.getValue());
937 if (bChecked)
939 sal_uInt32 nIndex = getSelectedFilterIndex();
941 rtl::OUString currentFilter;
942 if (nIndex > 0)
944 // filter index of the base class starts with 1
945 m_filterContainer->getFilter(nIndex - 1, currentFilter);
947 if (currentFilter.getLength())
949 rtl::OUString FilterExt;
950 m_filterContainer->getFilter(currentFilter, FilterExt);
952 sal_Int32 posOfPoint = FilterExt.indexOf(L'.');
953 const sal_Unicode* pFirstExtStart = FilterExt.getStr() + posOfPoint + 1;
955 sal_Int32 posOfSemiColon = FilterExt.indexOf(L';') - 1;
956 if (posOfSemiColon < 0)
957 posOfSemiColon = FilterExt.getLength() - 1;
959 FilterExt = rtl::OUString(pFirstExtStart, posOfSemiColon - posOfPoint);
961 SendMessage(m_hwndFileOpenDlg, CDM_SETDEFEXT, 0, reinterpret_cast<LPARAM>(FilterExt.getStr()));
965 else
967 SendMessage(m_hwndFileOpenDlg, CDM_SETDEFEXT, 0, reinterpret_cast<LPARAM>(TEXT("")));
971 // !!! HACK !!!
974 //-----------------------------------------------------------------------------------------
976 //-----------------------------------------------------------------------------------------
978 void SAL_CALL CWinFileOpenImpl::InitialSetDefaultName()
980 // manually setting the file name that appears
981 // initially in the file-name-box of the file
982 // open dialog (reason: see above setDefaultName)
983 if (m_bInitialSelChanged && m_defaultName.getLength())
985 sal_Int32 edt1Id = edt1;
987 // under W2k the there is a combobox instead
988 // of an edit field for the file name edit field
989 // the control id of this box is cmb13 and not
990 // edt1 as before so we must use this id
991 if (IsWindows2000Platform())
992 edt1Id = cmb13;
994 HWND hwndEdt1 = GetDlgItem(m_hwndFileOpenDlg, edt1Id);
995 SetWindowText(hwndEdt1, reinterpret_cast<LPCTSTR>(m_defaultName.getStr()));
998 m_bInitialSelChanged = sal_False;