Files
libreoffice/fpicker/source/win32/filepicker/WinFileOpenImpl.cxx

849 lines
26 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 .
*/
#include "shared.hxx"
#include "WinFileOpenImpl.hxx"
#include <osl/diagnose.h>
#include <osl/file.hxx>
#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/FilePickerEvent.hpp>
#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp>
#include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp>
#include <com/sun/star/ui/dialogs/ListboxControlActions.hpp>
#include "../misc/WinImplHelper.hxx"
#include "FilePicker.hxx"
#include "controlaccess.hxx"
#include "customcontrolfactory.hxx"
#include <rtl/ustrbuf.hxx>
2001-07-09 11:58:25 +00:00
#include <rtl/string.hxx>
#include <osl/thread.hxx>
#include "filepickerstate.hxx"
2002-03-28 07:57:33 +00:00
using namespace com::sun::star;
2002-03-28 07:57:33 +00:00
using com::sun::star::ui::dialogs::FilePickerEvent;
using com::sun::star::lang::IllegalArgumentException;
using com::sun::star::ui::dialogs::XFilePicker2;
using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds;
using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds;
using namespace ::com::sun::star::ui::dialogs::ListboxControlActions;
// to distinguish what to do in the enum child window callback function
enum ECW_ACTION_T
{
2002-03-21 06:37:13 +00:00
INIT_CUSTOM_CONTROLS,
CACHE_CONTROL_VALUES
};
2001-07-09 11:58:25 +00:00
struct EnumParam
{
ECW_ACTION_T m_action;
CWinFileOpenImpl* m_instance;
EnumParam( ECW_ACTION_T action, CWinFileOpenImpl* instance ):
m_action( action ),
m_instance( instance )
{}
};
CWinFileOpenImpl::CWinFileOpenImpl(
CFilePicker* aFilePicker,
bool bFileOpenDialog,
sal_uInt32 dwFlags,
sal_uInt32 dwTemplateId,
2002-03-21 06:37:13 +00:00
HINSTANCE hInstance) :
CFileOpenDialog(bFileOpenDialog, dwFlags, dwTemplateId, hInstance),
m_filterContainer(new CFilterContainer()),
2002-03-21 06:37:13 +00:00
m_Preview(new CPreviewAdapter(hInstance)),
m_CustomControls(CCustomControlFactory::CreateCustomControlContainer()),
2002-03-21 06:37:13 +00:00
m_FilePicker(aFilePicker),
m_bInitialSelChanged(true),
2002-03-21 06:37:13 +00:00
m_HelpPopupWindow(hInstance, m_hwndFileOpenDlg),
m_ExecuteFilePickerState(new CExecuteFilePickerState()),
m_NonExecuteFilePickerState(new CNonExecuteFilePickerState())
{
m_FilePickerState = m_NonExecuteFilePickerState;
}
2002-03-21 06:37:13 +00:00
CWinFileOpenImpl::~CWinFileOpenImpl()
{
delete m_ExecuteFilePickerState;
delete m_NonExecuteFilePickerState;
}
// we expect the directory in URL format
void CWinFileOpenImpl::setDisplayDirectory(const OUString& aDirectory)
2002-03-28 07:57:33 +00:00
throw( IllegalArgumentException, uno::RuntimeException )
{
OUString aSysDirectory;
2002-03-28 07:57:33 +00:00
if( aDirectory.getLength() > 0)
{
if ( ::osl::FileBase::E_None !=
2002-03-21 06:37:13 +00:00
::osl::FileBase::getSystemPathFromFileURL(aDirectory,aSysDirectory))
throw IllegalArgumentException(
"Invalid directory",
static_cast<XFilePicker2*>(m_FilePicker), 1);
// we ensure that there is a trailing '/' at the end of
// he given file url, because the windows functions only
// works correctly when providing "c:\" or an environment
// variable like "=c:=c:\.." etc. is set, else the
// FolderPicker would stand in the root of the shell
2014-04-10 09:35:15 +02:00
// hierarchy which is the desktop folder
2002-03-21 06:37:13 +00:00
if ( aSysDirectory.lastIndexOf(BACKSLASH) != (aSysDirectory.getLength() - 1))
aSysDirectory += BACKSLASH;
}
// call base class method
2002-03-21 06:37:13 +00:00
CFileOpenDialog::setDisplayDirectory(aSysDirectory);
}
// we return the directory in URL format
OUString CWinFileOpenImpl::getDisplayDirectory() throw(uno::RuntimeException)
{
2002-03-28 07:57:33 +00:00
return m_FilePickerState->getDisplayDirectory(this);
}
void SAL_CALL CWinFileOpenImpl::setDefaultName(const OUString& aName)
2002-03-28 07:57:33 +00:00
throw( IllegalArgumentException, uno::RuntimeException )
{
// we don't set the default name directly
// because this influences how the file open
// dialog sets the initial path when it is about
// to open (see MSDN: OPENFILENAME)
// so we save the default name which should
// appear in the file-name-box and set
// this name when processing onInitDone
m_defaultName = aName;
}
// return format: URL
// if multiselection is allowed there are two different cases
// 1. one file selected: the sequence contains one entry path\filename.ext
// 2. multiple files selected: the sequence contains multiple entries
// the first entry is the path url, all other entries are file names
uno::Sequence<OUString> SAL_CALL CWinFileOpenImpl::getFiles()
2002-03-28 07:57:33 +00:00
throw(uno::RuntimeException)
{
2002-03-28 07:57:33 +00:00
return m_FilePickerState->getFiles(this);
}
// shows the FileOpen/FileSave dialog
2002-03-28 07:57:33 +00:00
sal_Int16 SAL_CALL CWinFileOpenImpl::execute( ) throw(uno::RuntimeException)
{
2002-03-21 06:37:13 +00:00
sal_Int16 rc = CFileOpenDialog::doModal();
2002-03-28 07:57:33 +00:00
if (1 == rc)
rc = css::ui::dialogs::ExecutableDialogResults::OK;
2002-03-28 07:57:33 +00:00
else if (0 == rc)
rc = css::ui::dialogs::ExecutableDialogResults::CANCEL;
else
2002-03-28 07:57:33 +00:00
throw uno::RuntimeException(
"Error executing dialog",
static_cast<XFilePicker2*>(m_FilePicker));
return rc;
}
// appends a new filter
// returns false if the title (aTitle) was already added or the title or the filter are
// empty
void SAL_CALL CWinFileOpenImpl::appendFilter(const OUString& aTitle, const OUString& aFilter)
2002-03-28 07:57:33 +00:00
throw(IllegalArgumentException, uno::RuntimeException)
{
bool bRet = m_filterContainer->addFilter(aTitle, aFilter);
2002-03-28 07:57:33 +00:00
if (!bRet)
throw IllegalArgumentException(
"filter already exists",
static_cast<XFilePicker2*>(m_FilePicker), 1);
// #95345# see MSDN OPENFILENAME
// If nFilterIndex is zero and lpstrCustomFilter is NULL,
// the system uses the first filter in the lpstrFilter buffer.
// to reflect this we must set the filter index so that calls
// to getSelectedFilterIndex without explicitly calling
// setFilterIndex before does not return 0 which leads to a
// false state
2002-03-28 07:57:33 +00:00
if (0 == getSelectedFilterIndex())
CFileOpenDialog::setFilterIndex(1);
}
// sets a current filter
void SAL_CALL CWinFileOpenImpl::setCurrentFilter(const OUString& aTitle)
2002-03-28 07:57:33 +00:00
throw( IllegalArgumentException, uno::RuntimeException)
{
2002-03-28 07:57:33 +00:00
sal_Int32 filterPos = m_filterContainer->getFilterPos(aTitle);
2002-03-28 07:57:33 +00:00
if (filterPos < 0)
throw IllegalArgumentException(
"filter doesn't exist",
static_cast<XFilePicker2*>(m_FilePicker), 1);
// filter index of the base class starts with 1
2002-03-28 07:57:33 +00:00
CFileOpenDialog::setFilterIndex(filterPos + 1);
}
// returns the currently selected filter
OUString SAL_CALL CWinFileOpenImpl::getCurrentFilter() throw(uno::RuntimeException)
{
2002-03-28 07:57:33 +00:00
sal_uInt32 nIndex = getSelectedFilterIndex();
OUString currentFilter;
2002-03-28 07:57:33 +00:00
if (nIndex > 0)
{
// filter index of the base class starts with 1
if (!m_filterContainer->getFilter(nIndex - 1, currentFilter)) {
OSL_ASSERT(false);
}
}
return currentFilter;
}
2002-03-28 07:57:33 +00:00
inline void SAL_CALL CWinFileOpenImpl::appendFilterGroupSeparator()
{
2002-03-28 07:57:33 +00:00
m_filterContainer->addFilter(FILTER_SEPARATOR, ALL_FILES_WILDCARD, ALLOW_DUPLICATES);
}
// XFilterGroupManager
void SAL_CALL CWinFileOpenImpl::appendFilterGroup(const OUString& sGroupTitle, const uno::Sequence<beans::StringPair>& aFilters)
2002-03-28 07:57:33 +00:00
throw (IllegalArgumentException, uno::RuntimeException)
{
(void) sGroupTitle; // avoid warning
2002-03-28 07:57:33 +00:00
OSL_ENSURE(0 == sGroupTitle.getLength(), "appendFilterGroup: Parameter 'GroupTitle' currently ignored");
2002-03-28 07:57:33 +00:00
sal_Int32 nFilters = aFilters.getLength();
2002-03-28 07:57:33 +00:00
OSL_PRECOND(nFilters > 0, "Empty filter list");
2002-03-28 07:57:33 +00:00
if (nFilters > 0)
{
// append a separator before the next group if
// there is already a group of filters
2002-03-28 07:57:33 +00:00
if (m_filterContainer->numFilter() > 0)
appendFilterGroupSeparator();
2002-03-28 07:57:33 +00:00
for (int i = 0; i < nFilters; i++)
appendFilter(aFilters[i].First, aFilters[i].Second);
}
}
// XExtendedFilePicker
// #i90917: Due to a different feature set for the system-dependent file pickers
// it's possible that generic code (e.g. sfx2) provides control ids
// (see ExtendedFilePickerElementIds::LISTBOX_FILTER_SELECTOR) which are NOT
// available on all platforms. This filter function should filter out control ids
// which are only available on KDE/GTK file pickers.
static bool filterControlCommand( sal_Int16 nControlId )
{
if ( nControlId == LISTBOX_FILTER_SELECTOR )
return true;
return false;
}
2002-03-28 07:57:33 +00:00
void SAL_CALL CWinFileOpenImpl::setValue(sal_Int16 aControlId, sal_Int16 aControlAction, const uno::Any& aValue)
throw(uno::RuntimeException)
{
2002-03-28 07:57:33 +00:00
OSL_ASSERT(m_FilePickerState);
if ( !filterControlCommand( aControlId ))
m_FilePickerState->setValue(aControlId, aControlAction, aValue);
}
// returns the value of an custom template element
// we assume that there are only checkboxes or comboboxes
2002-03-28 07:57:33 +00:00
uno::Any SAL_CALL CWinFileOpenImpl::getValue(sal_Int16 aControlId, sal_Int16 aControlAction)
throw(uno::RuntimeException)
{
2002-03-28 07:57:33 +00:00
OSL_ASSERT(m_FilePickerState);
if ( !filterControlCommand( aControlId ))
return m_FilePickerState->getValue(aControlId, aControlAction);
else
return uno::Any();
}
// enables a custom template element
void SAL_CALL CWinFileOpenImpl::enableControl(sal_Int16 ControlID, bool bEnable)
2002-03-28 07:57:33 +00:00
throw(uno::RuntimeException)
{
2002-03-28 07:57:33 +00:00
OSL_ASSERT(m_FilePickerState);
if ( !filterControlCommand( ControlID ))
m_FilePickerState->enableControl(ControlID, bEnable);
}
void SAL_CALL CWinFileOpenImpl::setLabel( sal_Int16 aControlId, const OUString& aLabel )
2002-03-28 07:57:33 +00:00
throw (uno::RuntimeException)
{
OSL_ASSERT(m_FilePickerState);
if ( !filterControlCommand( aControlId ))
m_FilePickerState->setLabel(aControlId, aLabel);
}
OUString SAL_CALL CWinFileOpenImpl::getLabel( sal_Int16 aControlId )
2002-03-28 07:57:33 +00:00
throw (uno::RuntimeException)
{
OSL_ASSERT(m_FilePickerState);
if ( !filterControlCommand( aControlId ))
return m_FilePickerState->getLabel(aControlId);
else
return OUString();
}
2002-03-28 07:57:33 +00:00
uno::Sequence<sal_Int16> SAL_CALL CWinFileOpenImpl::getSupportedImageFormats()
throw (uno::RuntimeException)
{
return CPreviewAdapter::getSupportedImageFormats();
}
2002-03-21 06:37:13 +00:00
sal_Int32 SAL_CALL CWinFileOpenImpl::getTargetColorDepth()
2002-03-28 07:57:33 +00:00
throw (uno::RuntimeException)
{
2002-03-21 06:37:13 +00:00
return m_Preview->getTargetColorDepth();
}
2002-03-21 06:37:13 +00:00
sal_Int32 SAL_CALL CWinFileOpenImpl::getAvailableWidth()
2002-03-28 07:57:33 +00:00
throw (uno::RuntimeException)
{
2002-03-21 06:37:13 +00:00
return m_Preview->getAvailableWidth();
}
2002-03-21 06:37:13 +00:00
sal_Int32 SAL_CALL CWinFileOpenImpl::getAvailableHeight()
2002-03-28 07:57:33 +00:00
throw (uno::RuntimeException)
{
2002-03-21 06:37:13 +00:00
return m_Preview->getAvailableHeight();
}
2002-03-28 07:57:33 +00:00
void SAL_CALL CWinFileOpenImpl::setImage(sal_Int16 aImageFormat, const uno::Any& aImage)
throw (IllegalArgumentException, uno::RuntimeException)
{
2002-03-21 06:37:13 +00:00
m_Preview->setImage(aImageFormat,aImage);
}
bool SAL_CALL CWinFileOpenImpl::setShowState(bool bShowState)
2002-03-28 07:57:33 +00:00
throw (uno::RuntimeException)
{
2002-03-21 06:37:13 +00:00
return m_Preview->setShowState(bShowState);
}
bool SAL_CALL CWinFileOpenImpl::getShowState()
2002-03-28 07:57:33 +00:00
throw (uno::RuntimeException)
{
2002-03-21 06:37:13 +00:00
return m_Preview->getShowState();
}
2002-03-21 06:37:13 +00:00
void SAL_CALL CWinFileOpenImpl::cancel()
{
2002-03-21 06:37:13 +00:00
if (IsWindow(m_hwndFileOpenDlg))
{
// simulate a mouse click to the
// cancel button
BOOL const ret = PostMessage(
m_hwndFileOpenDlg,
WM_COMMAND,
2002-03-21 06:37:13 +00:00
MAKEWPARAM(IDCANCEL,BN_CLICKED),
reinterpret_cast<LPARAM>(GetDlgItem(m_hwndFileOpenDlg, IDCANCEL)));
SAL_WARN_IF(0 == ret, "fpicker", "ERROR: PostMessage() failed!");
}
}
// returns the id of a custom template element
2002-03-21 06:37:13 +00:00
sal_Int16 SAL_CALL CWinFileOpenImpl::getFocused()
{
int nID = GetDlgCtrlID(GetFocus());
// we don't forward id's of standard file open
// dialog elements (ctlFirst is defined in dlgs.h
// in MS Platform SDK)
2002-03-21 06:37:13 +00:00
if (nID >= ctlFirst)
nID = 0;
return sal::static_int_cast< sal_Int16 >(nID);
}
inline bool SAL_CALL CWinFileOpenImpl::IsCustomControlHelpRequested(LPHELPINFO lphi)
2002-03-21 06:37:13 +00:00
{
return ((lphi->iCtrlId != IDOK) && (lphi->iCtrlId != IDCANCEL) && (lphi->iCtrlId < ctlFirst));
}
// our own DlgProc because we do subclass the dialog
// we catch the WM_NCDESTROY message in order to erase an entry in our static map
// if one instance dies
LRESULT CALLBACK CWinFileOpenImpl::SubClassFunc(
HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam)
{
2001-07-09 11:58:25 +00:00
unsigned int lResult = 0;
2002-03-21 06:37:13 +00:00
CWinFileOpenImpl* pImpl = dynamic_cast<CWinFileOpenImpl*>(getCurrentInstance(hWnd));
2002-03-21 06:37:13 +00:00
switch(wMessage)
{
case WM_HELP:
{
2002-03-21 06:37:13 +00:00
LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam);
if (CWinFileOpenImpl::IsCustomControlHelpRequested(lphi))
2002-03-21 06:37:13 +00:00
pImpl->onCustomControlHelpRequest(lphi);
else
lResult = CallWindowProc(
2002-03-21 06:37:13 +00:00
reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc),
hWnd,wMessage,wParam,lParam);
}
break;
2002-03-21 06:37:13 +00:00
case WM_SIZE:
lResult = CallWindowProc(
2002-03-21 06:37:13 +00:00
reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc),
hWnd,wMessage,wParam,lParam);
pImpl->onWMSize();
2002-03-21 06:37:13 +00:00
break;
case WM_WINDOWPOSCHANGED:
lResult = CallWindowProc(
2002-03-21 06:37:13 +00:00
reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc),
hWnd,wMessage,wParam,lParam);
pImpl->onWMWindowPosChanged();
2002-03-21 06:37:13 +00:00
break;
case WM_SHOWWINDOW:
lResult = CallWindowProc(
2002-03-21 06:37:13 +00:00
reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc),
hWnd,wMessage,wParam,lParam);
pImpl->onWMShow(bool(wParam));
2002-03-21 06:37:13 +00:00
break;
2002-03-28 07:57:33 +00:00
case WM_NCDESTROY:
// restore the old window proc
SetWindowLongPtr(hWnd, GWLP_WNDPROC,
reinterpret_cast<LONG_PTR>(pImpl->m_pfnOldDlgProc));
2002-03-28 07:57:33 +00:00
lResult = CallWindowProc(
2002-03-28 07:57:33 +00:00
reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc),
hWnd,wMessage,wParam,lParam);
break;
default:
lResult = CallWindowProc(
2002-03-21 06:37:13 +00:00
reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc),
hWnd,wMessage,wParam,lParam);
break;
} // switch
return lResult;
}
2002-03-28 07:57:33 +00:00
void SAL_CALL CWinFileOpenImpl::InitControlLabel(HWND hWnd)
{
// set the labels for all extended controls
sal_Int16 aCtrlId = sal::static_int_cast< sal_Int16 >(GetDlgCtrlID(hWnd));
OUString aLabel = m_ResProvider.getResString(aCtrlId);
2002-03-28 07:57:33 +00:00
if (aLabel.getLength())
setLabel(aCtrlId, aLabel);
}
2002-03-21 06:37:13 +00:00
// There may be problems with the layout of our custom controls,
// so that they are not aligned with the standard controls of the
// FileOpen dialog.
// We use a simple algorithm to move the custom controls to their
// proper position and resize them.
// Our approach is to align all static text controls with the
// static text control "File name" of the FileOpen dialog,
// all checkboxes and all list/comboboxes will be left aligned with
// the standard combobox edt1/cmb13 (defined in MS platform sdk dlgs.h)
2002-03-21 06:37:13 +00:00
// and all push buttons will be left aligned with the standard
// "OK" button
2002-03-21 06:37:13 +00:00
void SAL_CALL CWinFileOpenImpl::InitCustomControlContainer(HWND hCustomControl)
{
2002-03-21 06:37:13 +00:00
m_CustomControls->AddControl(
CCustomControlFactory::CreateCustomControl(hCustomControl,m_hwndFileOpenDlg));
}
2002-03-21 06:37:13 +00:00
void SAL_CALL CWinFileOpenImpl::CacheControlState(HWND hWnd)
{
2002-03-21 06:37:13 +00:00
OSL_ASSERT(m_FilePickerState && m_NonExecuteFilePickerState);
m_ExecuteFilePickerState->cacheControlState(hWnd, m_NonExecuteFilePickerState);
}
2002-03-21 06:37:13 +00:00
BOOL CALLBACK CWinFileOpenImpl::EnumChildWndProc(HWND hWnd, LPARAM lParam)
{
EnumParam* enumParam = reinterpret_cast<EnumParam*>(lParam);
2001-07-09 11:58:25 +00:00
CWinFileOpenImpl* pImpl = enumParam->m_instance;
2002-03-21 06:37:13 +00:00
OSL_ASSERT(pImpl);
bool bRet = true;
2002-03-21 06:37:13 +00:00
switch(enumParam->m_action)
{
2002-03-21 06:37:13 +00:00
case INIT_CUSTOM_CONTROLS:
pImpl->InitControlLabel(hWnd);
pImpl->InitCustomControlContainer(hWnd);
break;
case CACHE_CONTROL_VALUES:
2002-03-21 06:37:13 +00:00
pImpl->CacheControlState(hWnd);
break;
2001-07-09 11:58:25 +00:00
default:
// should not end here
OSL_ASSERT(false);
}
return bRet;
}
sal_uInt32 SAL_CALL CWinFileOpenImpl::onFileOk()
{
2002-03-21 06:37:13 +00:00
m_NonExecuteFilePickerState->reset();
2001-07-09 11:58:25 +00:00
2002-03-21 06:37:13 +00:00
EnumParam enumParam(CACHE_CONTROL_VALUES,this);
2001-07-09 11:58:25 +00:00
EnumChildWindows(
m_hwndFileOpenDlgChild,
CWinFileOpenImpl::EnumChildWndProc,
reinterpret_cast<LPARAM>(&enumParam));
return 0;
}
void SAL_CALL CWinFileOpenImpl::onSelChanged(HWND)
{
// the windows file open dialog sends an initial
// SelChanged message after the InitDone message
// when the dialog is about to be opened
// if the lpstrFile buffer of the OPENFILENAME is
// empty (zero length string) the windows file open
// dialog sends a WM_SETTEXT message with an empty
// string to the file name edit line
// this would overwritte our text when we would set
// the default name in onInitDone, so we have to
// remember that this is the first SelChanged message
// and set the default name here to overwrite the
// windows setting
2002-03-21 06:37:13 +00:00
InitialSetDefaultName();
FilePickerEvent evt;
2002-03-21 06:37:13 +00:00
m_FilePicker->fileSelectionChanged(evt);
}
// #i40865# The size of the standard labels 'File name'
// and 'File type' is to short in some cases when the
// label will be changed (e.g. in the Brazil version).
// We just make sure that the labels are using the maximum
// available space.
void CWinFileOpenImpl::EnlargeStdControlLabels() const
{
HWND hFilterBoxLabel = GetDlgItem(m_hwndFileOpenDlg, stc2);
HWND hFileNameBoxLabel = GetDlgItem(m_hwndFileOpenDlg, stc3);
HWND hFileNameBox = GetDlgItem(m_hwndFileOpenDlg, cmb13);
if (!hFileNameBox)
hFileNameBox = GetDlgItem(m_hwndFileOpenDlg, edt1); // since Win2k it is cmb13 or edt1
HWND hFilterBox = GetDlgItem(m_hwndFileOpenDlg, cmb1);
HWND hOkButton = GetDlgItem(m_hwndFileOpenDlg, IDOK);
// Move filter and file name box nearer to OK and Cancel button
RECT rcOkButton;
GetWindowRect(hOkButton, &rcOkButton);
2011-07-20 21:51:04 +03:00
const int MAX_GAP = 10;
const int OFFSET = 0;
RECT rcFileNameBox;
GetWindowRect(hFileNameBox, &rcFileNameBox);
int w = rcFileNameBox.right - rcFileNameBox.left;
int h = rcFileNameBox.bottom - rcFileNameBox.top;
int gap = rcOkButton.left - rcFileNameBox.right;
gap = (gap > MAX_GAP) ? gap - MAX_GAP : gap;
ScreenToClient(m_hwndFileOpenDlg, reinterpret_cast<LPPOINT>(&rcFileNameBox));
MoveWindow(hFileNameBox, rcFileNameBox.left + gap + OFFSET, rcFileNameBox.top, w - OFFSET, h, true);
RECT rcFilterBox;
GetWindowRect(hFilterBox, &rcFilterBox);
w = rcFilterBox.right - rcFilterBox.left;
CWS-TOOLING: integrate CWS vcl100 2009-03-26 21:27:56 +0100 pl r270106 : #i10000# fix an include path missing when using configure 2009-03-16 12:18:24 +0100 pl r269518 : #i98963# revert change 2009-03-13 14:56:47 +0100 pl r269483 : #i98980# work around a mysterious crash 2009-03-12 20:02:48 +0100 pl r269440 : resolve some warnings 2009-03-12 19:30:32 +0100 pl r269439 : resolve some warnings 2009-03-12 18:07:47 +0100 pl r269432 : solve some warnings 2009-03-12 09:07:33 +0100 hdu r269358 : #i100134# remove obsolete RCS/CVS keywords from source 2009-03-11 21:18:28 +0100 pl r269355 : #i100134# change sft.h and ttcr.h to c++ headers 2009-03-11 20:19:15 +0100 pl r269353 : #i100134# remove some ugly C style lists 2009-03-11 18:19:35 +0100 hdu r269347 : #i100134# make psprint.fontsubset source C++ and make it compile 2009-03-11 14:44:35 +0100 hdu r269334 : #i99862# fix justification of vocalized hebrew (thanks hennerdrewes) 2009-03-11 13:40:35 +0100 pl r269327 : CWS-TOOLING: rebase CWS vcl100 to trunk@269297 (milestone: DEV300:m43) 2009-03-10 16:49:34 +0100 hdu r269284 : #i1000020# add style-matching heuristics for single-char stylenames 2009-03-10 15:42:53 +0100 hdu r269278 : use fast ASCII-matching for extracting attributes from PSName 2009-03-09 16:29:08 +0100 pl r269200 : #i98980# skip bundles that are not NP plugins 2009-03-09 13:26:14 +0100 hdu r269083 : #i99868# fix text breaking for large nCharExtra 2009-03-09 12:20:01 +0100 hdu r269078 : #i99868# fix text breaking for large nCharExtra 2009-03-06 17:35:27 +0100 pl r269032 : #i98980# mouse events 2009-03-06 17:10:14 +0100 pl r269024 : #i98980# flash animations, initial paint problem 2009-03-05 20:00:21 +0100 pl r268939 : #i98980# more plugin support 2009-03-05 15:35:06 +0100 pl r268914 : #i98980# first twitches of a live plugin 2009-03-05 15:34:10 +0100 pl r268913 : #i98980# access to carbon headers 2009-03-04 15:46:29 +0100 pl r268839 : #i98980# generalize vcl SystemChildWindow from QTMovieView to NSView 2009-03-04 15:40:20 +0100 pl r268838 : #i98980# generalize vcl SystemChildWindow from QTMovieView to NSView 2009-03-04 11:30:49 +0100 hdu r268801 : #i99722# for OSX any anisotropy reported for the display resolution is best ignored 2009-03-02 15:52:21 +0100 pl r268655 : #i99770# fix ambiguous looking if statements (thanks cmc) 2009-03-02 13:28:17 +0100 pl r268649 : #i99770# fix ambiguous looking if statements (thanks cmc) 2009-02-27 15:39:30 +0100 pl r268603 : #i97512# omit degenrate current matrix 2009-02-27 12:37:29 +0100 pl r268579 : #i99716# remove unused code (thanks cmc) 2009-02-27 11:21:18 +0100 pl r268569 : #i99705 remove unused code (thanks cmc) 2009-02-23 10:42:00 +0100 pl r268345 : #i99492# remove a typo (thanks tono) 2009-02-19 12:46:21 +0100 pl r268274 : #i99411# add new mimetype 2009-02-10 12:57:59 +0100 pl r267548 : #i98980# more aqua plugin changes 2009-02-06 16:50:34 +0100 pl r267475 : #i98980# plugin detection 2009-02-06 16:46:48 +0100 pl r267474 : #i98980# make debug compilation work 2009-02-06 12:16:37 +0100 pl r267449 : #98963# add missing wrapper 2009-02-04 20:06:59 +0100 pl r267402 : #i97135# work around a gcc x64 optimizer bug 2009-02-04 13:45:36 +0100 pl r267380 : #159153# do not emit empty glyph vector 2009-02-03 17:47:16 +0100 pl r267338 : #i98533# recent gtk versions do not support GTK_MODULES for accessibility anymore 2009-02-03 10:39:46 +0100 pl r267305 : #i97146# check if the idle formatted view is still valid 2009-01-28 11:23:23 +0100 pl r267045 : #i42227# #i48965# refinement of check markings images 2009-01-27 19:40:01 +0100 pl r267016 : #i42227# #i48965# change menus wrt checkmarks and images
2009-04-01 11:54:14 +00:00
h = rcFilterBox.bottom - rcFilterBox.top;
ScreenToClient(m_hwndFileOpenDlg, reinterpret_cast<LPPOINT>(&rcFilterBox));
MoveWindow(hFilterBox, rcFilterBox.left + gap + OFFSET, rcFilterBox.top, w - OFFSET, h, true);
// get the new window rect
GetWindowRect(hFileNameBox, &rcFileNameBox);
RECT rcFilterBoxLabel;
GetWindowRect(hFilterBoxLabel, &rcFilterBoxLabel);
int offset = rcFileNameBox.left - rcFilterBoxLabel.right - 1;
w = rcFilterBoxLabel.right - rcFilterBoxLabel.left + offset;
h = rcFilterBoxLabel.bottom - rcFilterBoxLabel.top;
ScreenToClient(m_hwndFileOpenDlg, reinterpret_cast<LPPOINT>(&rcFilterBoxLabel));
MoveWindow(hFilterBoxLabel, rcFilterBoxLabel.left, rcFilterBoxLabel.top, w, h, true);
RECT rcFileNameBoxLabel;
GetWindowRect(hFileNameBoxLabel, &rcFileNameBoxLabel);
w = rcFileNameBoxLabel.right - rcFileNameBoxLabel.left + offset;
h = rcFileNameBoxLabel.bottom - rcFileNameBoxLabel.top;
ScreenToClient(m_hwndFileOpenDlg, reinterpret_cast<LPPOINT>(&rcFileNameBoxLabel));
MoveWindow(hFileNameBoxLabel, rcFileNameBoxLabel.left, rcFileNameBoxLabel.top, w, h, true);
}
void SAL_CALL CWinFileOpenImpl::onInitDone()
{
2002-03-21 06:37:13 +00:00
m_Preview->setParent(m_hwndFileOpenDlg);
2001-07-09 11:58:25 +00:00
2002-03-21 06:37:13 +00:00
// but now we have a valid parent handle
m_HelpPopupWindow.setParent(m_hwndFileOpenDlg);
EnlargeStdControlLabels();
// #99826
// Set the online filepicker state before initializing
// the control labels from the resource else we are
// overriding the offline settings
m_ExecuteFilePickerState->setHwnd(m_hwndFileOpenDlgChild);
m_FilePickerState = m_ExecuteFilePickerState;
// initialize controls from cache
2002-03-21 06:37:13 +00:00
EnumParam enumParam(INIT_CUSTOM_CONTROLS,this);
2001-07-09 11:58:25 +00:00
EnumChildWindows(
m_hwndFileOpenDlgChild,
CWinFileOpenImpl::EnumChildWndProc,
reinterpret_cast<LPARAM>(&enumParam));
2001-07-09 11:58:25 +00:00
m_ExecuteFilePickerState->initFilePickerControls(
2002-03-21 06:37:13 +00:00
m_NonExecuteFilePickerState->getControlCommand());
2002-03-21 06:37:13 +00:00
SetDefaultExtension();
2002-03-21 06:37:13 +00:00
m_CustomControls->Align();
m_CustomControls->SetFont(
reinterpret_cast<HFONT>(SendMessageW(m_hwndFileOpenDlg, WM_GETFONT, 0, 0)));
// resume event notification that was
// defered in onInitDialog
m_FilePicker->resumeEventNotification();
//#105996 let vcl know that now a system window is active
BOOL const ret = PostMessage(
HWND_BROADCAST,
RegisterWindowMessageW(L"SYSTEM_WINDOW_ACTIVATED"),
0,
0);
SAL_WARN_IF(0 == ret, "fpicker", "ERROR: PostMessage() failed!");
// call the parent function to center the
// dialog to its parent
CFileOpenDialog::onInitDone();
}
void SAL_CALL CWinFileOpenImpl::onFolderChanged()
{
FilePickerEvent evt;
2002-03-21 06:37:13 +00:00
m_FilePicker->directoryChanged(evt);
}
void SAL_CALL CWinFileOpenImpl::onTypeChanged(sal_uInt32)
{
2002-03-21 06:37:13 +00:00
SetDefaultExtension();
2001-07-09 11:58:25 +00:00
FilePickerEvent evt;
evt.ElementId = LISTBOX_FILTER;
2002-03-21 06:37:13 +00:00
m_FilePicker->controlStateChanged(evt);
}
// onMessageCommand handler
sal_uInt32 SAL_CALL CWinFileOpenImpl::onCtrlCommand(
HWND, sal_uInt16 ctrlId, sal_uInt16)
{
2002-03-21 06:37:13 +00:00
SetDefaultExtension();
2001-07-09 11:58:25 +00:00
2002-03-21 06:37:13 +00:00
if (ctrlId < ctlFirst)
{
FilePickerEvent evt;
evt.ElementId = ctrlId;
2002-03-21 06:37:13 +00:00
m_FilePicker->controlStateChanged(evt);
}
return 0;
}
void CWinFileOpenImpl::onWMSize()
2002-03-21 06:37:13 +00:00
{
m_Preview->notifyParentSizeChanged();
m_CustomControls->Align();
m_FilePicker->dialogSizeChanged();
}
void CWinFileOpenImpl::onWMShow(bool bShow)
2002-03-21 06:37:13 +00:00
{
m_Preview->notifyParentShow(bShow);
}
void CWinFileOpenImpl::onWMWindowPosChanged()
2002-03-21 06:37:13 +00:00
{
m_Preview->notifyParentWindowPosChanged();
2002-03-21 06:37:13 +00:00
}
void CWinFileOpenImpl::onCustomControlHelpRequest(LPHELPINFO lphi)
2002-03-21 06:37:13 +00:00
{
FilePickerEvent evt;
evt.ElementId = sal::static_int_cast< sal_Int16 >(lphi->iCtrlId);
2002-03-21 06:37:13 +00:00
OUString aPopupHelpText = m_FilePicker->helpRequested(evt);
2002-03-21 06:37:13 +00:00
if (aPopupHelpText.getLength())
{
m_HelpPopupWindow.setText(aPopupHelpText);
DWORD dwMsgPos = GetMessagePos();
m_HelpPopupWindow.show(LOWORD(dwMsgPos),HIWORD(dwMsgPos));
}
}
void SAL_CALL CWinFileOpenImpl::onInitDialog(HWND hwndDlg)
{
// subclass the dialog window
m_pfnOldDlgProc =
reinterpret_cast<WNDPROC>(
SetWindowLongPtr( hwndDlg, GWLP_WNDPROC,
reinterpret_cast<LONG_PTR>(SubClassFunc)));
}
// processing before showing the dialog
2002-03-28 07:57:33 +00:00
bool SAL_CALL CWinFileOpenImpl::preModal()
{
CFileOpenDialog::setFilter(
2002-03-21 06:37:13 +00:00
makeWinFilterBuffer(*m_filterContainer.get()));
2002-03-28 07:57:33 +00:00
return true;
}
// processing after showing the dialog
2002-03-21 06:37:13 +00:00
void CWinFileOpenImpl::postModal(sal_Int16 nDialogResult)
{
2002-03-21 06:37:13 +00:00
CFileOpenDialog::postModal(nDialogResult);
2002-03-28 07:57:33 +00:00
// empty the container in order to get rid off
// invalid controls in case someone calls execute
// twice in sequence with the same instance
m_CustomControls->RemoveAllControls();
m_FilePickerState = m_NonExecuteFilePickerState;
2001-07-09 11:58:25 +00:00
}
2002-03-21 06:37:13 +00:00
void SAL_CALL CWinFileOpenImpl::SetDefaultExtension()
2001-07-09 11:58:25 +00:00
{
HWND hwndChkSaveWithExt = GetDlgItem(m_hwndFileOpenDlgChild, 100);
2001-07-09 11:58:25 +00:00
if (hwndChkSaveWithExt)
2001-07-09 11:58:25 +00:00
{
uno::Any aAny = CheckboxGetState(hwndChkSaveWithExt);
bool bChecked = *static_cast<const sal_Bool*>(aAny.getValue());
2001-07-09 11:58:25 +00:00
if (bChecked)
2001-07-09 11:58:25 +00:00
{
sal_uInt32 nIndex = getSelectedFilterIndex();
2001-07-09 11:58:25 +00:00
OUString currentFilter;
if (nIndex > 0)
2001-07-09 11:58:25 +00:00
{
// filter index of the base class starts with 1
m_filterContainer->getFilter(nIndex - 1, currentFilter);
2001-07-09 11:58:25 +00:00
if (currentFilter.getLength())
2001-07-09 11:58:25 +00:00
{
OUString FilterExt;
m_filterContainer->getFilter(currentFilter, FilterExt);
2001-07-09 11:58:25 +00:00
sal_Int32 posOfPoint = FilterExt.indexOf(L'.');
const sal_Unicode* pFirstExtStart = FilterExt.getStr() + posOfPoint + 1;
2001-07-09 11:58:25 +00:00
sal_Int32 posOfSemiColon = FilterExt.indexOf(L';') - 1;
if (posOfSemiColon < 0)
posOfSemiColon = FilterExt.getLength() - 1;
2001-07-09 11:58:25 +00:00
FilterExt = OUString(pFirstExtStart, posOfSemiColon - posOfPoint);
2001-07-09 11:58:25 +00:00
SendMessageW(m_hwndFileOpenDlg, CDM_SETDEFEXT, 0, reinterpret_cast<LPARAM>(FilterExt.getStr()));
}
2001-07-09 11:58:25 +00:00
}
}
else
{
SendMessageW(m_hwndFileOpenDlg, CDM_SETDEFEXT, 0, reinterpret_cast<LPARAM>(L""));
2001-07-09 11:58:25 +00:00
}
}
// !!! HACK !!!
}
2002-03-21 06:37:13 +00:00
void SAL_CALL CWinFileOpenImpl::InitialSetDefaultName()
{
// manually setting the file name that appears
// initially in the file-name-box of the file
// open dialog (reason: see above setDefaultName)
2002-03-21 06:37:13 +00:00
if (m_bInitialSelChanged && m_defaultName.getLength())
{
// under W2k by default there is a combobox instead
// of an edit field for the file name edit field
// the control id of this box is cmb13 and not
// edt1 as before.
// However, edt1 is still possible. See fdo#74295
HWND hFileNameBox = GetDlgItem(m_hwndFileOpenDlg, cmb13);
if (!hFileNameBox)
hFileNameBox = GetDlgItem(m_hwndFileOpenDlg, edt1);
SetWindowTextW(hFileNameBox, reinterpret_cast<PCWSTR>(m_defaultName.getStr()));
}
m_bInitialSelChanged = false;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */