diff options
Diffstat (limited to 'fpicker/source/win32')
87 files changed, 19893 insertions, 0 deletions
diff --git a/fpicker/source/win32/filepicker/FPServiceInfo.hxx b/fpicker/source/win32/filepicker/FPServiceInfo.hxx new file mode 100644 index 000000000000..046d2298fe13 --- /dev/null +++ b/fpicker/source/win32/filepicker/FPServiceInfo.hxx @@ -0,0 +1,77 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _FPSERVICEINFO_HXX_ +#define _FPSERVICEINFO_HXX_ + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +// the service name is a description of a set of +// interfaces (is the same as component categories in COM) + +#define TMPL95_FILEOPEN_READONLY_VERSION_BOX_ID 1000 +#define TMPL2000_FILEOPEN_READONLY_VERSION_BOX_ID 1001 + +#define TMPL95_FILEOPEN_LINK_PREVIEW_BOX_ID 2000 +#define TMPL2000_FILEOPEN_LINK_PREVIEW_BOX_ID 2001 + +#define TMPL95_FILEOPEN_AUTOEXT_TEMPLATE_BOX_ID 3000 +#define TMPL2000_FILEOPEN_AUTOEXT_TEMPLATE_BOX_ID 3001 + +#define TMPL95_FILESAVE_AUTOEXT_PASSWORD_BOX_ID 4000 +#define TMPL2000_FILESAVE_AUTOEXT_PASSWORD_BOX_ID 4001 + +#define TMPL95_AUTOEXT_PASSWORD_FILTEROPTION_BOX 5000 +#define TMPL2000_AUTOEXT_PASSWORD_FILTEROPTION_BOX 5001 + +#define TMPL95_PLAY_PUSHBUTTON 6000 +#define TMPL2000_PLAY_PUSHBUTTON 6001 + +#define TMPL95_AUTOEXT_SELECTION_BOX 7000 +#define TMPL2000_AUTOEXT_SELECTION_BOX 7001 + +#define TMPL95_FILEOPEN_LINK_PREVIEW_BOX_SIMPLE_ID 8000 +#define TMPL2000_FILEOPEN_LINK_PREVIEW_BOX_SIMPLE_ID 8001 + +#define TMPL95_FILESAVE_AUTOEXT 9000 +#define TMPL2000_FILESAVE_AUTOEXT 9001 + +// the service names +#define FILE_PICKER_SERVICE_NAME "com.sun.star.ui.dialogs.SystemFilePicker" + +// the implementation names +#define FILE_PICKER_IMPL_NAME "com.sun.star.ui.dialogs.Win32FilePicker" + +// the registry key names +// a key under which this service will be registered, Format: -> "/ImplName/UNO/SERVICES/ServiceName" +// < Implementation-Name ></UNO/SERVICES/>< Service-Name > +#define FILE_PICKER_REGKEY_NAME "/com.sun.star.ui.dialogs.Win32FilePicker/UNO/SERVICES/com.sun.star.ui.dialogs.SystemFilePicker" + +#endif diff --git a/fpicker/source/win32/filepicker/FPentry.cxx b/fpicker/source/win32/filepicker/FPentry.cxx new file mode 100644 index 000000000000..79a2cf3b2865 --- /dev/null +++ b/fpicker/source/win32/filepicker/FPentry.cxx @@ -0,0 +1,132 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//---------------------------------------------- +// includes of other projects +//---------------------------------------------- +#include <cppuhelper/factory.hxx> +#include <com/sun/star/container/XSet.hpp> +#include <osl/diagnose.h> +#include "FilePicker.hxx" +#include "FPServiceInfo.hxx" + +#pragma warning (disable:4917) +#include "VistaFilePicker.hxx" +#include "..\misc\WinImplHelper.hxx" +#include <stdio.h> + +//----------------------------------------------- +// namespace directives +//----------------------------------------------- + +using namespace ::rtl ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::container ; +using namespace ::com::sun::star::lang ; +using namespace ::com::sun::star::registry ; +using namespace ::cppu ; +using ::com::sun::star::ui::dialogs::XFilePicker; +using ::com::sun::star::ui::dialogs::XFilePicker2; + +//------------------------------------------------ +// +//------------------------------------------------ + +static Reference< XInterface > SAL_CALL createInstance( + const Reference< XMultiServiceFactory >& rServiceManager ) +{ + Reference< XInterface > xDlg; + bool bVistaOrNewer = IsWindowsVistaOrNewer(); + + if (bVistaOrNewer) + { + OSL_TRACE("use special (vista) system file picker ..."); + xDlg.set( + static_cast< XFilePicker2* >( + new ::fpicker::win32::vista::VistaFilePicker( rServiceManager ) ) ); + } + else + { + OSL_TRACE("use normal system file picker ..."); + xDlg.set( + static_cast< XFilePicker2* >( + new CFilePicker( rServiceManager ) ) ); + } + + return xDlg; +} + +//------------------------------------------------ +// the three uno functions that will be exported +//------------------------------------------------ + +extern "C" +{ + +//------------------------------------------------ +// component_getImplementationEnvironment +//------------------------------------------------ + +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//------------------------------------------------ +// +//------------------------------------------------ + +void* SAL_CALL component_getFactory( + const sal_Char* pImplName, uno_Interface* pSrvManager, uno_Interface* ) +{ + void* pRet = 0; + + if ( pSrvManager && ( 0 == rtl_str_compare( pImplName, FILE_PICKER_IMPL_NAME ) ) ) + { + Sequence< OUString > aSNS( 1 ); + aSNS.getArray( )[0] = OUString::createFromAscii( FILE_PICKER_SERVICE_NAME ); + + Reference< XSingleServiceFactory > xFactory ( createSingleFactory( + reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ), + OUString::createFromAscii( pImplName ), + createInstance, + aSNS ) ); + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} + +} // extern "C" diff --git a/fpicker/source/win32/filepicker/FileOpenDlg.cxx b/fpicker/source/win32/filepicker/FileOpenDlg.cxx new file mode 100644 index 000000000000..73a757058e28 --- /dev/null +++ b/fpicker/source/win32/filepicker/FileOpenDlg.cxx @@ -0,0 +1,695 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <tchar.h> +#include <osl/diagnose.h> +#include "../misc/WinImplHelper.hxx" +#include "FileOpenDlg.hxx" + +//------------------------------------------------------------------------ +// constants +//------------------------------------------------------------------------ + +namespace /* private */ +{ + // we choose such large buffers because the size of + // an single line edit field can be up to 32k; if + // a user has a multi selection FilePicker and selects + // a lot of files in a large directory we may reach this + // limit and don't want to get out of memory; + // another much more elegant way would be to subclass the + // FileOpen dialog and overload the BM_CLICK event of the + // OK button so that we determine the size of the text + // currently in the edit field and resize our buffer + // appropriately - in the future we will do this + const size_t MAX_FILENAME_BUFF_SIZE = 32000; + const size_t MAX_FILETITLE_BUFF_SIZE = 32000; + const size_t MAX_FILTER_BUFF_SIZE = 4096; + + const LPTSTR CURRENT_INSTANCE = TEXT("CurrInst"); + + //------------------------------------------ + // find an appropriate parent window + //------------------------------------------ + + inline bool is_current_process_window(HWND hwnd) + { + DWORD pid; + GetWindowThreadProcessId(hwnd, &pid); + return (pid == GetCurrentProcessId()); + } + + HWND choose_parent_window() + { + HWND hwnd_parent = GetForegroundWindow(); + if (!is_current_process_window(hwnd_parent)) + hwnd_parent = GetDesktopWindow(); + + return hwnd_parent; + } +}; + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFileOpenDialog::CFileOpenDialog( + bool bFileOpenDialog, + sal_uInt32 dwFlags, + sal_uInt32 dwTemplateId, + HINSTANCE hInstance) : + m_hwndFileOpenDlg(0), + m_hwndFileOpenDlgChild(0), + m_bFileOpenDialog(bFileOpenDialog), + m_filterBuffer(MAX_FILTER_BUFF_SIZE), + m_fileTitleBuffer(MAX_FILETITLE_BUFF_SIZE), + m_helperBuffer(MAX_FILENAME_BUFF_SIZE), + m_fileNameBuffer(MAX_FILENAME_BUFF_SIZE), + m_pfnBaseDlgProc(0) +{ + // initialize the OPENFILENAME struct + if (IsWindows2000Platform() || IsWindowsME()) + { + ZeroMemory(&m_ofn, sizeof(m_ofn)); + m_ofn.lStructSize = sizeof(m_ofn); + } + else // OSVER < Win2000 + { + // the size of the OPENFILENAME structure is different + // under windows < win2000 + ZeroMemory(&m_ofn, _OPENFILENAME_SIZE_VERSION_400); + m_ofn.lStructSize = _OPENFILENAME_SIZE_VERSION_400; + } + + // 0x02000000 for #97681, sfx will make the entry into + // the recent document list + m_ofn.Flags |= dwFlags | + OFN_EXPLORER | + OFN_ENABLEHOOK | + OFN_HIDEREADONLY | + OFN_PATHMUSTEXIST | + OFN_FILEMUSTEXIST | + OFN_OVERWRITEPROMPT | + OFN_ENABLESIZING | + OFN_DONTADDTORECENT; // 0x02000000 -> OFN_DONTADDTORECENT only available with new platform sdk + + // it is a little hack but how else could + // we get a parent window (using a vcl window?) + m_ofn.hwndOwner = choose_parent_window(); + + m_ofn.lpstrFile = reinterpret_cast<LPTSTR>(const_cast<sal_Unicode*>(m_fileNameBuffer.getStr())); + m_ofn.nMaxFile = m_fileNameBuffer.getCapacity(); + + m_ofn.lpstrFileTitle = reinterpret_cast<LPTSTR>(const_cast<sal_Unicode*>(m_fileTitleBuffer.getStr())); + m_ofn.nMaxFileTitle = m_fileTitleBuffer.getCapacity(); + + m_ofn.lpfnHook = CFileOpenDialog::ofnHookProc; + + // set a custom template + + if (dwTemplateId) + { + OSL_ASSERT(hInstance); + + m_ofn.Flags |= OFN_ENABLETEMPLATE; + m_ofn.lpTemplateName = MAKEINTRESOURCE(dwTemplateId); + m_ofn.hInstance = hInstance; + } + + // set a pointer to myself as ofn parameter + m_ofn.lCustData = reinterpret_cast<long>(this); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFileOpenDialog::~CFileOpenDialog() +{ +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFileOpenDialog::setTitle(const rtl::OUString& aTitle) +{ + m_dialogTitle = aTitle; + m_ofn.lpstrTitle = reinterpret_cast<LPCTSTR>(m_dialogTitle.getStr()); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void CFileOpenDialog::setFilter(const rtl::OUString& aFilter) +{ + // Format is like + // "*.TXT" or multiple separate by ';' like "*.TXT;*.DOC;*.SXW" + // Do not include spaces in the pattern string + m_filterBuffer.ensureCapacity(aFilter.getLength()); + m_filterBuffer.setLength(0); + m_filterBuffer.append(aFilter); + m_ofn.lpstrFilter = reinterpret_cast<LPCTSTR>(m_filterBuffer.getStr()); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +bool CFileOpenDialog::setFilterIndex(sal_uInt32 aIndex) +{ + OSL_ASSERT(aIndex > 0); + m_ofn.nFilterIndex = aIndex; + return sal_True; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_uInt32 CFileOpenDialog::getSelectedFilterIndex() const +{ + return m_ofn.nFilterIndex; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFileOpenDialog::setDefaultName(const rtl::OUString& aName) +{ + m_fileNameBuffer.setLength(0); + m_fileNameBuffer.append(aName); + m_ofn.lpstrFile = reinterpret_cast<LPTSTR>(const_cast<sal_Unicode*>(m_fileNameBuffer.getStr())); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFileOpenDialog::setDisplayDirectory(const rtl::OUString& aDirectory) +{ + m_displayDirectory = aDirectory; + m_ofn.lpstrInitialDir = reinterpret_cast<LPCTSTR>(m_displayDirectory.getStr()); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +rtl::OUString SAL_CALL CFileOpenDialog::getLastDisplayDirectory() const +{ + return m_displayDirectory; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +rtl::OUString SAL_CALL CFileOpenDialog::getFullFileName() const +{ + return rtl::OUString(m_fileNameBuffer.getStr(), + _wcslenex(m_fileNameBuffer.getStr())); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +rtl::OUString SAL_CALL CFileOpenDialog::getFileName() const +{ + return rtl::OUString(m_fileTitleBuffer); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +rtl::OUString CFileOpenDialog::getFileExtension() +{ + if (m_ofn.nFileExtension) + return rtl::OUString(m_fileNameBuffer.getStr() + m_ofn.nFileExtension, + rtl_ustr_getLength(m_fileNameBuffer.getStr() + m_ofn.nFileExtension)); + + return rtl::OUString(); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void CFileOpenDialog::setDefaultFileExtension(const rtl::OUString& aExtension) +{ + m_defaultExtension = aExtension; + m_ofn.lpstrDefExt = reinterpret_cast<LPCTSTR>(m_defaultExtension.getStr()); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFileOpenDialog::setMultiSelectionMode(bool bMode) +{ + if (bMode) + m_ofn.Flags |= OFN_ALLOWMULTISELECT; + else + m_ofn.Flags &= ~OFN_ALLOWMULTISELECT; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +bool SAL_CALL CFileOpenDialog::getMultiSelectionMode() const +{ + return ((m_ofn.Flags & OFN_ALLOWMULTISELECT) > 0); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Int16 SAL_CALL CFileOpenDialog::doModal() +{ + sal_Int16 nRC = -1; + + // pre-processing + if (preModal()) + { + bool bRet; + + if (m_bFileOpenDialog) + bRet = m_GetFileNameWrapper.getOpenFileName( + reinterpret_cast<LPOPENFILENAME>(&m_ofn)); + else + bRet = m_GetFileNameWrapper.getSaveFileName( + reinterpret_cast<LPOPENFILENAME>(&m_ofn)); + + nRC = 1; + + if (!bRet) + nRC = (0 == m_GetFileNameWrapper.commDlgExtendedError()) ? 0 : -1; + + // post-processing + postModal(nRC); + } + + return nRC; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_uInt32 SAL_CALL CFileOpenDialog::getLastDialogError() const +{ + return CommDlgExtendedError(); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +bool SAL_CALL CFileOpenDialog::preModal() +{ + return sal_True; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFileOpenDialog::postModal(sal_Int16 nDialogResult) +{ + OSL_ASSERT((-1 <= nDialogResult) && (nDialogResult <= 1)); + + if (1 == nDialogResult) + { + // Attention: assuming that nFileOffset is always greater 0 because under + // Windows there is always a drive letter or a server in a complete path + // the OPENFILENAME docu never says that nFileOffset can be 0 + m_displayDirectory = rtl::OUString(reinterpret_cast<const sal_Unicode*>(m_ofn.lpstrFile),m_ofn.nFileOffset); + } +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +rtl::OUString SAL_CALL CFileOpenDialog::getCurrentFilePath() const +{ + OSL_ASSERT(IsWindow(m_hwndFileOpenDlg)); + + LPARAM nLen = SendMessage( + m_hwndFileOpenDlg, + CDM_GETFILEPATH, + m_helperBuffer.getCapacity(), + reinterpret_cast<LPARAM>(m_helperBuffer.getStr())); + + if (nLen > 0) + { + m_helperBuffer.setLength((nLen * sizeof(sal_Unicode)) - 1); + return rtl::OUString(m_helperBuffer); + } + return rtl::OUString(); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +rtl::OUString SAL_CALL CFileOpenDialog::getCurrentFolderPath() const +{ + OSL_ASSERT(IsWindow(m_hwndFileOpenDlg)); + + LPARAM nLen = SendMessage( + m_hwndFileOpenDlg, + CDM_GETFOLDERPATH, + m_helperBuffer.getCapacity(), + reinterpret_cast<LPARAM>(m_helperBuffer.getStr())); + + if (nLen > 0) + { + m_helperBuffer.setLength((nLen * sizeof(sal_Unicode)) - 1); + return rtl::OUString(m_helperBuffer); + } + return rtl::OUString(); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +rtl::OUString SAL_CALL CFileOpenDialog::getCurrentFileName() const +{ + OSL_ASSERT(IsWindow(m_hwndFileOpenDlg)); + + LPARAM nLen = SendMessage( + m_hwndFileOpenDlg, + CDM_GETSPEC, + m_helperBuffer.getCapacity(), + reinterpret_cast<LPARAM>(m_helperBuffer.getStr())); + + if (nLen > 0) + { + m_helperBuffer.setLength((nLen * sizeof(sal_Unicode)) - 1); + return rtl::OUString(m_helperBuffer); + } + return rtl::OUString(); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_uInt32 SAL_CALL CFileOpenDialog::onShareViolation(const rtl::OUString&) +{ + return 0; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_uInt32 SAL_CALL CFileOpenDialog::onFileOk() +{ + return 0; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFileOpenDialog::onSelChanged(HWND) +{ +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFileOpenDialog::onHelp() +{ +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFileOpenDialog::onInitDone() +{ + centerPositionToParent(); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFileOpenDialog::onFolderChanged() +{ +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFileOpenDialog::onTypeChanged(sal_uInt32) +{ +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_uInt32 SAL_CALL CFileOpenDialog::onCtrlCommand(HWND, sal_uInt16, sal_uInt16) +{ + return 0; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_uInt32 SAL_CALL CFileOpenDialog::onWMNotify( HWND, LPOFNOTIFY lpOfNotify ) +{ + switch(lpOfNotify->hdr.code) + { + case CDN_SHAREVIOLATION: + return onShareViolation(reinterpret_cast<const sal_Unicode*>(lpOfNotify->pszFile)); + + case CDN_FILEOK: + return onFileOk(); + + case CDN_SELCHANGE: + onSelChanged(lpOfNotify->hdr.hwndFrom); + break; + + case CDN_HELP: + onHelp(); + break; + + case CDN_INITDONE: + onInitDone(); + break; + + case CDN_FOLDERCHANGE: + onFolderChanged(); + break; + + case CDN_TYPECHANGE: + m_ofn.nFilterIndex = lpOfNotify->lpOFN->nFilterIndex; + onTypeChanged(lpOfNotify->lpOFN->nFilterIndex); + break; + } + + return 0; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFileOpenDialog::handleInitDialog(HWND hwndDlg, HWND hwndChild) +{ + m_hwndFileOpenDlg = hwndDlg; + m_hwndFileOpenDlgChild = hwndChild; + + OSL_ASSERT(GetParent(hwndChild) == hwndDlg); + + // calling virtual function which the + // client can overload + onInitDialog(hwndDlg); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +unsigned int CALLBACK CFileOpenDialog::ofnHookProc( + HWND hChildDlg, unsigned int uiMsg, WPARAM wParam, LPARAM lParam) +{ + HWND hwndDlg = GetParent(hChildDlg); + CFileOpenDialog* pImpl = NULL; + + switch( uiMsg ) + { + case WM_INITDIALOG: + { + _LPOPENFILENAME lpofn = reinterpret_cast<_LPOPENFILENAME>(lParam); + pImpl = reinterpret_cast<CFileOpenDialog*>(lpofn->lCustData); + OSL_ASSERT(pImpl); + + // subclass the base dialog for WM_NCDESTROY processing + pImpl->m_pfnBaseDlgProc = + reinterpret_cast<WNDPROC>( + SetWindowLong( + hwndDlg, + GWL_WNDPROC, + reinterpret_cast<LONG>(CFileOpenDialog::BaseDlgProc))); + // connect the instance handle to the window + SetProp(hwndDlg, CURRENT_INSTANCE, pImpl); + pImpl->handleInitDialog(hwndDlg, hChildDlg); + } + return 0; + + case WM_NOTIFY: + { + pImpl = getCurrentInstance(hwndDlg); + return pImpl->onWMNotify( + hChildDlg, reinterpret_cast<LPOFNOTIFY>(lParam)); + } + + case WM_COMMAND: + { + pImpl = getCurrentInstance(hwndDlg); + OSL_ASSERT(pImpl); + + return pImpl->onCtrlCommand( + hChildDlg, LOWORD(wParam), HIWORD(lParam)); + } + } + + return 0; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +LRESULT CALLBACK CFileOpenDialog::BaseDlgProc( + HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam) +{ + CFileOpenDialog* pImpl = 0; + + if (WM_NCDESTROY == wMessage) + { + pImpl = reinterpret_cast<CFileOpenDialog*>( + RemoveProp(hWnd,CURRENT_INSTANCE)); + + SetWindowLong(hWnd, GWL_WNDPROC, + reinterpret_cast<LONG>(pImpl->m_pfnBaseDlgProc)); + } + else + { + pImpl = getCurrentInstance(hWnd); + } + + OSL_ASSERT(pImpl); + + return CallWindowProc( + reinterpret_cast<WNDPROC>(pImpl->m_pfnBaseDlgProc), + hWnd,wMessage,wParam,lParam); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CFileOpenDialog* SAL_CALL CFileOpenDialog::getCurrentInstance(HWND hwnd) +{ + OSL_ASSERT(IsWindow( hwnd)); + return reinterpret_cast<CFileOpenDialog*>( + GetProp(hwnd, CURRENT_INSTANCE)); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CFileOpenDialog::centerPositionToParent() const +{ + OSL_PRECOND(IsWindow(m_hwndFileOpenDlg), "no dialog window, call method only after or in onInitDone"); + + HWND hwndParent = m_ofn.hwndOwner; + + if (!IsWindow(hwndParent)) + hwndParent = GetDesktopWindow(); + + OSL_ASSERT(IsWindow(hwndParent)); + + RECT rcPar; + GetWindowRect(hwndParent, &rcPar); + + RECT rcDlg; + GetWindowRect(m_hwndFileOpenDlg, &rcDlg); + + int lDlgW = rcDlg.right - rcDlg.left; + int lDlgH = rcDlg.bottom - rcDlg.top; + + int x = (rcPar.left + rcPar.right - lDlgW) / 2; + int y = (rcPar.top + rcPar.bottom - lDlgH) / 2; + + HDC hdc = GetDC(m_hwndFileOpenDlg); + + int hResol = GetDeviceCaps(hdc, HORZRES); + int vResol = GetDeviceCaps(hdc, VERTRES); + + ReleaseDC(m_hwndFileOpenDlg, hdc); + + if (x < 0) + x = 0; + else if ((x + lDlgW) > hResol) + x = hResol - lDlgW; + + if (y < 0) + y = 0; + else if ((y + lDlgH) > vResol) + y = vResol - lDlgH; + + SetWindowPos( + m_hwndFileOpenDlg, + NULL, x, y, 0, 0, + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE ); +} diff --git a/fpicker/source/win32/filepicker/FileOpenDlg.hxx b/fpicker/source/win32/filepicker/FileOpenDlg.hxx new file mode 100644 index 000000000000..f1d8753dcf43 --- /dev/null +++ b/fpicker/source/win32/filepicker/FileOpenDlg.hxx @@ -0,0 +1,327 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _FILEOPENDLG_HXX_ +#define _FILEOPENDLG_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> + +#ifndef _RTL_USTRING_HXX_ +#include <rtl/ustring> +#endif +#include <rtl/ustrbuf.hxx> + +#include "platform_xp.h" +#include "getfilenamewrapper.hxx" + +// because we don't want to import the new W2k platform skd +// into our build environment if have stolen the definition +// for the new OPENFILENAME structure from the new headers + +#ifndef _CDSIZEOF_STRUCT +#define _CDSIZEOF_STRUCT(structname, member) (((int)((LPBYTE)(&((structname*)0)->member) - ((LPBYTE)((structname*)0)))) + sizeof(((structname*)0)->member)) +#endif + +typedef struct _tagOFNA { + DWORD lStructSize; + HWND hwndOwner; + HINSTANCE hInstance; + LPCSTR lpstrFilter; + LPSTR lpstrCustomFilter; + DWORD nMaxCustFilter; + DWORD nFilterIndex; + LPSTR lpstrFile; + DWORD nMaxFile; + LPSTR lpstrFileTitle; + DWORD nMaxFileTitle; + LPCSTR lpstrInitialDir; + LPCSTR lpstrTitle; + DWORD Flags; + WORD nFileOffset; + WORD nFileExtension; + LPCSTR lpstrDefExt; + LPARAM lCustData; + LPOFNHOOKPROC lpfnHook; + LPCSTR lpTemplateName; +#ifdef _MAC + LPEDITMENU lpEditInfo; + LPCSTR lpstrPrompt; +#endif +#if (_WIN32_WINNT >= 0x0500) + void * pvReserved; + DWORD dwReserved; + DWORD FlagsEx; +#endif // (_WIN32_WINNT >= 0x0500) +} _OPENFILENAMEA, *_LPOPENFILENAMEA; + +typedef struct _tagOFNW { + DWORD lStructSize; + HWND hwndOwner; + HINSTANCE hInstance; + LPCWSTR lpstrFilter; + LPWSTR lpstrCustomFilter; + DWORD nMaxCustFilter; + DWORD nFilterIndex; + LPWSTR lpstrFile; + DWORD nMaxFile; + LPWSTR lpstrFileTitle; + DWORD nMaxFileTitle; + LPCWSTR lpstrInitialDir; + LPCWSTR lpstrTitle; + DWORD Flags; + WORD nFileOffset; + WORD nFileExtension; + LPCWSTR lpstrDefExt; + LPARAM lCustData; + LPOFNHOOKPROC lpfnHook; + LPCWSTR lpTemplateName; +#if (_WIN32_WINNT >= 0x0500) + void * pvReserved; + DWORD dwReserved; + DWORD FlagsEx; +#endif // (_WIN32_WINNT >= 0x0500) +} _OPENFILENAMEW, *_LPOPENFILENAMEW; + +#ifdef UNICODE +typedef _OPENFILENAMEW _OPENFILENAME; +typedef _LPOPENFILENAMEW _LPOPENFILENAME; +#else +typedef _OPENFILENAMEA _OPENFILENAME; +typedef _LPOPENFILENAMEA _LPOPENFILENAME; +#endif // UNICODE + +#if (_WIN32_WINNT >= 0x0500) + #define _OPENFILENAME_SIZE_VERSION_400A _CDSIZEOF_STRUCT(_OPENFILENAMEA,lpTemplateName) + #define _OPENFILENAME_SIZE_VERSION_400W _CDSIZEOF_STRUCT(_OPENFILENAMEW,lpTemplateName) + #ifdef UNICODE + #define _OPENFILENAME_SIZE_VERSION_400 _OPENFILENAME_SIZE_VERSION_400W + #else + #define _OPENFILENAME_SIZE_VERSION_400 _OPENFILENAME_SIZE_VERSION_400A + #endif // !UNICODE +#else + #error _WIN32_WINNT seams not to be valid. +#endif // (_WIN32_WINNT >= 0x0500) + + +//------------------------------------------------------------- +// A simple wrapper class around the Win32 GetOpenFileName API. +// This class is not thread-safe and only one instance at a +// time is allowed +//------------------------------------------------------------- + +class CFileOpenDialog +{ +public: + // ctor + // bFileOpenDialog idicates if we want a FileOpen or FileSave + // dialog + // dwFlags see OPENFILENAME + // dwTemplateId - an ID for custom templates + // hInstance - an instance handle for the module + // which provides the custom template, unused if dwTemplateId + // is 0 + CFileOpenDialog( + bool bFileOpenDialog = sal_True, + sal_uInt32 dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, + sal_uInt32 dwTemplateId = 0, + HINSTANCE hInstance = 0); + + virtual ~CFileOpenDialog(); + + virtual void SAL_CALL setTitle(const rtl::OUString& aTitle); + + // to set a filter string using the M$ format + // e.g. FltName\0*.txt;*.rtf\0...\0\0 + void SAL_CALL setFilter(const rtl::OUString& aFilter); + + // set the index of the current filter when the + // dialog is about to shown, the index starts with 1 + // the function succeeded if the given filter index + // is greater than zero and is a valid position + // within filter string that was previously set + bool SAL_CALL setFilterIndex(sal_uInt32 aIndex); + + // get the index of the currently selected filter + // the index of the returned filter starts with 1 + sal_uInt32 SAL_CALL getSelectedFilterIndex() const; + + // set the name and optional the path of the + // file that will be initially be shown when + // the dialog will be displayed + virtual void SAL_CALL setDefaultName(const rtl::OUString& aName); + + // set the initial directory + virtual void SAL_CALL setDisplayDirectory(const rtl::OUString& aDirectory); + + // returns only the path of the selected file + virtual rtl::OUString SAL_CALL getLastDisplayDirectory() const; + + // returns the full file name including drive letter, path + // file name and file extension + virtual rtl::OUString SAL_CALL getFullFileName() const; + + // returns the file name and the file extension without + // drive letter and path + rtl::OUString SAL_CALL getFileName() const; + + // returns the file extension of the selected file + rtl::OUString SAL_CALL getFileExtension(); + + // set a default extension, only the first three letters of + // the given extension will be used; the given extension + // should not contain a '.' + void SAL_CALL setDefaultFileExtension(const rtl::OUString& aExtension); + + // enables or disables the multiselection mode for + // the FileOpen/FileSave dialog + void SAL_CALL setMultiSelectionMode(bool bMode); + + // returns whether multi-selection mode is enabled or not + bool SAL_CALL getMultiSelectionMode() const; + + // shows the dialog, calls preModal before + // showing the dialog and postModal after + // showing the dialog + // the method returns: + // 0 - when the dialog was canceled by the user + // 1 - when the dialog was closed with ok + // -1 - when an error occured + sal_Int16 SAL_CALL doModal(); + + // returns the last dialog error that occured + sal_uInt32 SAL_CALL getLastDialogError() const; + + // retrievs the currently selected file + // including path and drive information + // can be called only if the dialog is + // already displayed + rtl::OUString SAL_CALL getCurrentFilePath() const; + + // retrievs the currently selected folder + rtl::OUString SAL_CALL getCurrentFolderPath() const; + + // retrievs the currently selected file name + // without drive and path + rtl::OUString SAL_CALL getCurrentFileName() const; + +protected: + // have to be overwritten when subclasses + // want to do special pre- and post-modal + // processing + + // if preModal return true processing will + // continue else doModal exit without showing + // a dialog and returns -1 + virtual bool SAL_CALL preModal(); + + // post modal processing + // the function should accept only values returned from + // doModal and act appropriately + virtual void SAL_CALL postModal(sal_Int16 nDialogResult); + + // message handler, to be overwritten by subclasses + virtual sal_uInt32 SAL_CALL onShareViolation(const rtl::OUString& aPathName); + virtual sal_uInt32 SAL_CALL onFileOk(); + virtual void SAL_CALL onSelChanged(HWND hwndListBox); + virtual void SAL_CALL onHelp(); + + // only called back if OFN_EXPLORER is set + virtual void SAL_CALL onInitDone(); + virtual void SAL_CALL onFolderChanged(); + virtual void SAL_CALL onTypeChanged(sal_uInt32 nFilterIndex); + + virtual void SAL_CALL onInitDialog(HWND hwndDlg) = 0; + + virtual sal_uInt32 SAL_CALL onCtrlCommand(HWND hwndDlg, sal_uInt16 ctrlId, sal_uInt16 notifyCode); + + sal_uInt32 SAL_CALL onWMNotify(HWND hwndChild, LPOFNOTIFYW lpOfNotify); + + // we use non-virtual functions to do necessary work before + // calling the virtual funtions (see Gamma: Template method) + void SAL_CALL handleInitDialog(HWND hwndDlg, HWND hwndChild); + +protected: + + // handle to the window of the + // FileOpen/FileSave dialog + // will be set on message + // WM_INITDIALOG, before this + // value is undefined + HWND m_hwndFileOpenDlg; + HWND m_hwndFileOpenDlgChild; + + _OPENFILENAME m_ofn; + + // we connect the instance with the dialog window using + // SetProp, with this function we can reconnect from + // callback functions to this instance + static CFileOpenDialog* SAL_CALL getCurrentInstance(HWND hwnd); + + void SAL_CALL centerPositionToParent() const; + +private: + // FileOpen or FileSaveDialog + bool m_bFileOpenDialog; + rtl::OUString m_dialogTitle; + rtl::OUString m_displayDirectory; + rtl::OUString m_defaultExtension; + + mutable rtl::OUStringBuffer m_filterBuffer; + mutable rtl::OUStringBuffer m_fileTitleBuffer; + mutable rtl::OUStringBuffer m_helperBuffer; + mutable rtl::OUStringBuffer m_fileNameBuffer; + + CGetFileNameWrapper m_GetFileNameWrapper; + + WNDPROC m_pfnBaseDlgProc; + + // callback function + static unsigned int CALLBACK ofnHookProc( + HWND hChildDlg, // handle to child dialog box + unsigned int uiMsg, // message identifier + WPARAM wParam, // message parameter + LPARAM lParam // message parameter + ); + + // we have to subclass the dialog in order + // to clean up the window property we are + // using to connect the window with a class + // instance in WM_NCDESTROY + static LRESULT CALLBACK BaseDlgProc( + HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam ); + +private: + // avoid copy and assignment + CFileOpenDialog(const CFileOpenDialog&); + CFileOpenDialog& operator=(const CFileOpenDialog&); +}; + +#endif diff --git a/fpicker/source/win32/filepicker/FilePicker.cxx b/fpicker/source/win32/filepicker/FilePicker.cxx new file mode 100644 index 000000000000..a3191ce77580 --- /dev/null +++ b/fpicker/source/win32/filepicker/FilePicker.cxx @@ -0,0 +1,799 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <tchar.h> +#include <com/sun/star/lang/DisposedException.hpp> +#include <cppuhelper/interfacecontainer.h> +#include <osl/diagnose.h> + +#ifndef _FILEPICKER_HXX_ +#include "filepicker.hxx" +#endif +#include "WinFileOpenImpl.hxx" + +#include "FPServiceInfo.hxx" +#include "..\misc\WinImplHelper.hxx" +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include "filepickereventnotification.hxx" + +#include <comphelper/sequenceasvector.hxx> + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace com::sun::star; + +using namespace ::com::sun::star::ui::dialogs; +using namespace ::com::sun::star::ui::dialogs::TemplateDescription; + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +#define FILE_PICKER_DLL_NAME TEXT("fps.dll") + +//------------------------------------------------------------------------ +// helper functions +//------------------------------------------------------------------------ + +namespace +{ + // controling event notifications + const bool STARTUP_SUSPENDED = true; + const bool STARTUP_ALIVE = false; + + uno::Sequence<rtl::OUString> SAL_CALL FilePicker_getSupportedServiceNames() + { + uno::Sequence<rtl::OUString> aRet(2); + aRet[0] = rtl::OUString::createFromAscii("com.sun.star.ui.dialogs.FilePicker"); + aRet[1] = rtl::OUString::createFromAscii("com.sun.star.ui.dialogs.SystemFilePicker"); + return aRet; + } +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +CFilePicker::CFilePicker( const uno::Reference<lang::XMultiServiceFactory>& xServiceMgr) : + cppu::WeakComponentImplHelper10< + XFilterManager, + XFilterGroupManager, + XFilePickerControlAccess, + XFilePickerNotifier, + XFilePreview, + XFilePicker2, + lang::XInitialization, + util::XCancellable, + lang::XEventListener, + lang::XServiceInfo>(m_rbHelperMtx), + m_xServiceMgr(xServiceMgr), + m_aAsyncEventNotifier(rBHelper) +{ + HINSTANCE hInstance = GetModuleHandle(FILE_PICKER_DLL_NAME); + OSL_POSTCOND( hInstance, "The name of the service dll must have changed" ); + + // create a default FileOpen dialog without any additional ui elements + m_pImpl = std::auto_ptr< CWinFileOpenImpl >( + new CWinFileOpenImpl( + this, + true, + 0, + 0, + hInstance ) ); +} + +//------------------------------------------------------------------------------------ +// XFPEventListenerManager +//------------------------------------------------------------------------------------ + +void SAL_CALL CFilePicker::addFilePickerListener(const uno::Reference<XFilePickerListener>& xListener) + throw(uno::RuntimeException) +{ + if ( rBHelper.bDisposed ) + throw lang::DisposedException( + rtl::OUString::createFromAscii( "object is already disposed" ), + static_cast< XFilePicker2* >( this ) ); + + if ( !rBHelper.bInDispose && !rBHelper.bDisposed ) + rBHelper.aLC.addInterface( getCppuType( &xListener ), xListener ); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::removeFilePickerListener(const uno::Reference<XFilePickerListener>& xListener ) + throw(uno::RuntimeException) +{ + if ( rBHelper.bDisposed ) + throw lang::DisposedException( + rtl::OUString::createFromAscii( "object is already disposed" ), + static_cast< XFilePicker2* >( this ) ); + + rBHelper.aLC.removeInterface( getCppuType( &xListener ), xListener ); +} + +// ------------------------------------------------- +// XEventListener +// ------------------------------------------------- + +void SAL_CALL CFilePicker::disposing(const lang::EventObject& aEvent) throw(uno::RuntimeException) +{ + uno::Reference<XFilePickerListener> xFilePickerListener(aEvent.Source, ::com::sun::star::uno::UNO_QUERY); + + if (xFilePickerListener.is()) + removeFilePickerListener(xFilePickerListener); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::fileSelectionChanged(FilePickerEvent aEvent) +{ + aEvent.Source = uno::Reference<uno::XInterface>(static_cast<XFilePickerNotifier*>(this)); + m_aAsyncEventNotifier.notifyEvent( + new CFilePickerParamEventNotification(&XFilePickerListener::fileSelectionChanged,aEvent)); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::directoryChanged(FilePickerEvent aEvent) +{ + aEvent.Source = uno::Reference<uno::XInterface>(static_cast<XFilePickerNotifier*>(this)); + m_aAsyncEventNotifier.notifyEvent( + new CFilePickerParamEventNotification(&XFilePickerListener::directoryChanged,aEvent)); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::controlStateChanged(FilePickerEvent aEvent) +{ + aEvent.Source = uno::Reference<uno::XInterface>(static_cast<XFilePickerNotifier*>(this)); + m_aAsyncEventNotifier.notifyEvent( + new CFilePickerParamEventNotification(&XFilePickerListener::controlStateChanged,aEvent)); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::dialogSizeChanged() +{ + m_aAsyncEventNotifier.notifyEvent( + new CFilePickerEventNotification(&XFilePickerListener::dialogSizeChanged)); +} + +//----------------------------------------------------------------------------------------- +// If there are more then one listener the return value of the last one wins +//----------------------------------------------------------------------------------------- + +rtl::OUString SAL_CALL CFilePicker::helpRequested(FilePickerEvent aEvent) const +{ + rtl::OUString aHelpText; + + ::cppu::OInterfaceContainerHelper* pICHelper = + rBHelper.getContainer( getCppuType((uno::Reference<XFilePickerListener>*)0)); + + if (pICHelper) + { + ::cppu::OInterfaceIteratorHelper iter(*pICHelper); + + while(iter.hasMoreElements()) + { + try + { + /* + if there are multiple listeners responding + to this notification the next response + overwrittes the one before if it is not empty + */ + + rtl::OUString temp; + + uno::Reference<XFilePickerListener> xFPListener(iter.next(), uno::UNO_QUERY); + if (xFPListener.is()) + { + temp = xFPListener->helpRequested(aEvent); + if (temp.getLength()) + aHelpText = temp; + } + + } + catch(uno::RuntimeException&) + { + OSL_ENSURE( false, "RuntimeException during event dispatching" ); + } + } + } + + return aHelpText; +} + +//------------------------------------- +// +//------------------------------------- + +bool CFilePicker::startupEventNotification(bool bStartupSuspended) +{ + return m_aAsyncEventNotifier.startup(bStartupSuspended); +} + +//------------------------------------- +// +//------------------------------------- + +void CFilePicker::shutdownEventNotification() +{ + m_aAsyncEventNotifier.shutdown(); +} + +//------------------------------------- +// +//------------------------------------- + +void CFilePicker::suspendEventNotification() +{ + m_aAsyncEventNotifier.suspend(); +} + +//------------------------------------- +// +//------------------------------------- + +void CFilePicker::resumeEventNotification() +{ + m_aAsyncEventNotifier.resume(); +} + +//------------------------------------------------------------------------------------ +// XFilePicker functions +//------------------------------------------------------------------------------------ + +void SAL_CALL CFilePicker::setMultiSelectionMode(sal_Bool bMode) throw(uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + osl::MutexGuard aGuard(m_aMutex); + m_pImpl->setMultiSelectionMode(bMode); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::setTitle(const rtl::OUString& aTitle) throw(uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + osl::MutexGuard aGuard(m_aMutex); + m_pImpl->setTitle(aTitle); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::appendFilter(const rtl::OUString& aTitle, const rtl::OUString& aFilter) + throw(lang::IllegalArgumentException, uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + osl::MutexGuard aGuard(m_aMutex); + m_pImpl->appendFilter(aTitle, aFilter); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::setCurrentFilter(const rtl::OUString& aTitle) + throw(lang::IllegalArgumentException, uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + osl::MutexGuard aGuard(m_aMutex); + m_pImpl->setCurrentFilter(aTitle); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +rtl::OUString SAL_CALL CFilePicker::getCurrentFilter() throw(uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->getCurrentFilter(); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::appendFilterGroup(const rtl::OUString& sGroupTitle, const uno::Sequence<beans::StringPair>& aFilters) + throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + osl::MutexGuard aGuard(m_aMutex); + m_pImpl->appendFilterGroup(sGroupTitle, aFilters); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::setDefaultName(const rtl::OUString& aName) + throw(uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + osl::MutexGuard aGuard(m_aMutex); + m_pImpl->setDefaultName(aName); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::setDisplayDirectory(const rtl::OUString& aDirectory) + throw(lang::IllegalArgumentException, uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + osl::MutexGuard aGuard(m_aMutex); + m_pImpl->setDisplayDirectory(aDirectory); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +rtl::OUString SAL_CALL CFilePicker::getDisplayDirectory() throw(uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->getDisplayDirectory(); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +uno::Sequence<rtl::OUString> SAL_CALL CFilePicker::getFiles() throw(uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->getFiles(); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- +uno::Sequence< ::rtl::OUString > SAL_CALL CFilePicker::getSelectedFiles() throw (uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + osl::MutexGuard aGuard(m_aMutex); + + const uno::Sequence< ::rtl::OUString > lSource = m_pImpl->getFiles(); + const ::sal_Int32 c = lSource.getLength(); + if (c < 2) + return lSource; + + const ::rtl::OUString sPath = lSource[0]; + ::comphelper::SequenceAsVector< ::rtl::OUString > lTarget; + ::sal_Int32 i = 1; + for (i=1; i<c; ++i) + { + const ::rtl::OUString sFile = lSource[i]; + if (sFile.indexOf ('/') > 0) + { + // a) file contains own path ! + lTarget.push_back(sFile); + } + else + { + // b) file is relative to given path + ::rtl::OUStringBuffer sFull(256); + + sFull.append (sPath); + sFull.appendAscii("/" ); + sFull.append (sFile); + + lTarget.push_back(sFull.makeStringAndClear()); + } + } + + return lTarget.getAsConstList(); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +sal_Int16 SAL_CALL CFilePicker::execute() throw(uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + + sal_Int16 ret; + + if (startupEventNotification(STARTUP_SUSPENDED)) + { + // we should not block in this call else + // in the case of an event the client can't + // call another function an we run into a + // deadlock !!!!! + ret = m_pImpl->execute( ); + + shutdownEventNotification(); + } + else + { + OSL_ENSURE(sal_False, "Could not start event notifier thread!"); + + throw uno::RuntimeException( + rtl::OUString::createFromAscii("Error executing dialog"), + static_cast<XFilePicker2*>(this)); + } + + return ret; +} + +//------------------------------------------------------------------------------------ +// XFilePicker functions +//------------------------------------------------------------------------------------ + +void SAL_CALL CFilePicker::setValue(sal_Int16 aControlId, sal_Int16 aControlAction, const uno::Any& aValue) + throw(uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + + osl::MutexGuard aGuard(m_aMutex); + m_pImpl->setValue(aControlId, aControlAction, aValue); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +uno::Any SAL_CALL CFilePicker::getValue(sal_Int16 aControlId, sal_Int16 aControlAction) + throw(uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + + osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->getValue(aControlId, aControlAction); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::enableControl(sal_Int16 aControlId, sal_Bool bEnable) +throw(uno::RuntimeException) +{ + OSL_ASSERT( 0 != m_pImpl.get( ) ); + + osl::MutexGuard aGuard( m_aMutex ); + m_pImpl->enableControl( aControlId, bEnable ); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilePicker::setLabel(sal_Int16 aControlId, const ::rtl::OUString& aLabel) + throw (uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + + osl::MutexGuard aGuard(m_aMutex); + m_pImpl->setLabel(aControlId, aLabel); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +rtl::OUString SAL_CALL CFilePicker::getLabel(sal_Int16 aControlId) + throw (uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + + osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->getLabel(aControlId); +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +uno::Sequence<sal_Int16> SAL_CALL CFilePicker::getSupportedImageFormats() throw (uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + + osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->getSupportedImageFormats(); +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +sal_Int32 SAL_CALL CFilePicker::getTargetColorDepth() throw (uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + + osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->getTargetColorDepth(); +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +sal_Int32 SAL_CALL CFilePicker::getAvailableWidth() throw (uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + + osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->getAvailableWidth(); +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +sal_Int32 SAL_CALL CFilePicker::getAvailableHeight() throw (uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + + osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->getAvailableHeight(); +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +void SAL_CALL CFilePicker::setImage(sal_Int16 aImageFormat, const uno::Any& aImage) + throw (lang::IllegalArgumentException, uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + + osl::MutexGuard aGuard(m_aMutex); + m_pImpl->setImage(aImageFormat, aImage); +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +sal_Bool SAL_CALL CFilePicker::setShowState(sal_Bool bShowState) throw (uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + + osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->setShowState(bShowState); +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +sal_Bool SAL_CALL CFilePicker::getShowState() throw (uno::RuntimeException) +{ + OSL_ASSERT(0 != m_pImpl.get()); + + osl::MutexGuard aGuard(m_aMutex); + return m_pImpl->getShowState(); +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +void SAL_CALL CFilePicker::initialize(const uno::Sequence<uno::Any>& aArguments) + throw( uno::Exception, uno::RuntimeException) +{ + // parameter checking + uno::Any aAny; + if ( 0 == aArguments.getLength( ) ) + throw lang::IllegalArgumentException( + rtl::OUString::createFromAscii( "no arguments" ), + static_cast<XFilePicker2*>(this), 1); + + aAny = aArguments[0]; + + if ( (aAny.getValueType() != ::getCppuType((sal_Int16*)0)) && + (aAny.getValueType() != ::getCppuType((sal_Int8*)0)) ) + throw lang::IllegalArgumentException( + rtl::OUString::createFromAscii("invalid argument type"), + static_cast<XFilePicker2*>(this), 1); + + sal_Int16 templateId = -1; + aAny >>= templateId; + + sal_Bool bFileOpenDialog = sal_True; + sal_uInt32 winResTemplateId = 0; + sal_Bool bIsWin2000 = IsWindows2000Platform(); + + switch ( templateId ) + { + case FILEOPEN_SIMPLE: + bFileOpenDialog = sal_True; + break; + + case FILESAVE_SIMPLE: + bFileOpenDialog = sal_False; + break; + + case FILESAVE_AUTOEXTENSION_PASSWORD: + bFileOpenDialog = sal_False; + if ( bIsWin2000 ) + winResTemplateId = TMPL2000_FILESAVE_AUTOEXT_PASSWORD_BOX_ID; + else + winResTemplateId = TMPL95_FILESAVE_AUTOEXT_PASSWORD_BOX_ID; + break; + + case FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS: + bFileOpenDialog = sal_False; + if ( bIsWin2000 ) + winResTemplateId = TMPL2000_AUTOEXT_PASSWORD_FILTEROPTION_BOX; + else + winResTemplateId = TMPL95_AUTOEXT_PASSWORD_FILTEROPTION_BOX; + break; + + case FILESAVE_AUTOEXTENSION_SELECTION: + bFileOpenDialog = sal_False; + if ( bIsWin2000 ) + winResTemplateId = TMPL2000_AUTOEXT_SELECTION_BOX; + else + winResTemplateId = TMPL95_AUTOEXT_SELECTION_BOX; + break; + + case FILESAVE_AUTOEXTENSION_TEMPLATE: + bFileOpenDialog = sal_False; + if ( bIsWin2000 ) + winResTemplateId = TMPL2000_FILEOPEN_AUTOEXT_TEMPLATE_BOX_ID; + else + winResTemplateId = TMPL95_FILEOPEN_AUTOEXT_TEMPLATE_BOX_ID; + break; + + case FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE: + if ( bIsWin2000 ) + winResTemplateId = TMPL2000_FILEOPEN_LINK_PREVIEW_BOX_ID; + else + winResTemplateId = TMPL95_FILEOPEN_LINK_PREVIEW_BOX_ID; + break; + + case FILEOPEN_PLAY: + if ( bIsWin2000 ) + winResTemplateId = TMPL2000_PLAY_PUSHBUTTON; + else + winResTemplateId = TMPL95_PLAY_PUSHBUTTON; + break; + + case FILEOPEN_READONLY_VERSION: + if ( bIsWin2000 ) + winResTemplateId = TMPL2000_FILEOPEN_READONLY_VERSION_BOX_ID; + else + winResTemplateId = TMPL95_FILEOPEN_READONLY_VERSION_BOX_ID; + break; + + case FILEOPEN_LINK_PREVIEW: + if ( bIsWin2000 ) + winResTemplateId = TMPL2000_FILEOPEN_LINK_PREVIEW_BOX_SIMPLE_ID; + else + winResTemplateId = TMPL95_FILEOPEN_LINK_PREVIEW_BOX_SIMPLE_ID; + break; + + case FILESAVE_AUTOEXTENSION: + bFileOpenDialog = sal_False; + if ( bIsWin2000 ) + winResTemplateId = TMPL2000_FILESAVE_AUTOEXT; + else + winResTemplateId = TMPL95_FILESAVE_AUTOEXT; + break; + + default: + throw lang::IllegalArgumentException( + rtl::OUString::createFromAscii( "Unknown template" ), + static_cast< XFilePicker2* >( this ), + 1 ); + } + + HINSTANCE hInstance = GetModuleHandle( FILE_PICKER_DLL_NAME ); + OSL_POSTCOND( hInstance, "The name of the service dll must have changed" ); + + // create a new impl-class here based on the + // given string, if the given string is empty + // we do nothing + m_pImpl = std::auto_ptr< CWinFileOpenImpl >( + new CWinFileOpenImpl( + this, + bFileOpenDialog, + 0, + winResTemplateId, + hInstance ) ); +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +void SAL_CALL CFilePicker::cancel() + throw(uno::RuntimeException) +{ + OSL_ASSERT(m_pImpl.get()); + + osl::MutexGuard aGuard(m_aMutex); + m_pImpl->cancel(); +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +rtl::OUString SAL_CALL CFilePicker::getImplementationName() + throw(uno::RuntimeException) +{ + return rtl::OUString::createFromAscii(FILE_PICKER_IMPL_NAME); +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +sal_Bool SAL_CALL CFilePicker::supportsService(const rtl::OUString& ServiceName) + throw(uno::RuntimeException ) +{ + uno::Sequence <rtl::OUString> SupportedServicesNames = FilePicker_getSupportedServiceNames(); + + for (sal_Int32 n = SupportedServicesNames.getLength(); n--;) + if (SupportedServicesNames[n].compareTo(ServiceName) == 0) + return sal_True; + + return sal_False; +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +uno::Sequence<rtl::OUString> SAL_CALL CFilePicker::getSupportedServiceNames() + throw(uno::RuntimeException) +{ + return FilePicker_getSupportedServiceNames(); +} diff --git a/fpicker/source/win32/filepicker/FilePicker.hxx b/fpicker/source/win32/filepicker/FilePicker.hxx new file mode 100644 index 000000000000..39dcf5246802 --- /dev/null +++ b/fpicker/source/win32/filepicker/FilePicker.hxx @@ -0,0 +1,255 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _FILEPICKER_HXX_ +#define _FILEPICKER_HXX_ + +//_______________________________________________________________________________________________________________________ +// includes of other projects +//_______________________________________________________________________________________________________________________ + + +#include <cppuhelper/compbase10.hxx> +#include <osl/mutex.hxx> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/ui/dialogs/XFilePicker2.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp> +#include <com/sun/star/ui/dialogs/XFilterManager.hpp> +#include <com/sun/star/ui/dialogs/XFilterGroupManager.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> +#include <com/sun/star/ui/dialogs/XFilePreview.hpp> +#include <com/sun/star/util/XCancellable.hpp> +#include "asynceventnotifier.hxx" +#include "eventnotification.hxx" + +#include <memory> + +//---------------------------------------------------------- +// Implementation class for the XFilePicker Interface +//---------------------------------------------------------- + +//---------------------------------------------------------- +// forward declarations +//---------------------------------------------------------- + +class CWinFileOpenImpl; + +//---------------------------------------------------------- +// class declaration +//---------------------------------------------------------- + +class CFilePickerDummy +{ +protected: + osl::Mutex m_aMutex; + osl::Mutex m_rbHelperMtx; +}; + +class CFilePicker : + public CFilePickerDummy, + public cppu::WeakComponentImplHelper10< + ::com::sun::star::ui::dialogs::XFilterManager, + ::com::sun::star::ui::dialogs::XFilterGroupManager, + ::com::sun::star::ui::dialogs::XFilePickerControlAccess, + ::com::sun::star::ui::dialogs::XFilePickerNotifier, + ::com::sun::star::ui::dialogs::XFilePreview, + ::com::sun::star::ui::dialogs::XFilePicker2, + ::com::sun::star::lang::XInitialization, + ::com::sun::star::util::XCancellable, + ::com::sun::star::lang::XEventListener, + ::com::sun::star::lang::XServiceInfo > +{ +public: + + // ctor + CFilePicker( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceMgr ); + + //------------------------------------------------------------------------------------ + // XFilePickerNotifier + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL addFilePickerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XFilePickerListener >& xListener ) + throw( ::com::sun::star::uno::RuntimeException ); + virtual void SAL_CALL removeFilePickerListener( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::dialogs::XFilePickerListener >& xListener ) + throw( ::com::sun::star::uno::RuntimeException ); + + //------------------------------------------------------------------------------------ + // XExecutableDialog functions + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL setTitle( const ::rtl::OUString& aTitle ) + throw( ::com::sun::star::uno::RuntimeException ); + + virtual sal_Int16 SAL_CALL execute( ) + throw( ::com::sun::star::uno::RuntimeException ); + + //------------------------------------------------------------------------------------ + // XFilePicker functions + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL setMultiSelectionMode( sal_Bool bMode ) + throw( ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL setDefaultName( const ::rtl::OUString& aName ) + throw( ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL setDisplayDirectory( const ::rtl::OUString& aDirectory ) + throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ); + + virtual ::rtl::OUString SAL_CALL getDisplayDirectory( ) + throw( ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getFiles( ) + throw( ::com::sun::star::uno::RuntimeException ); + + //------------------------------------------------------------------------------------ + // XFilePicker2 functions + //------------------------------------------------------------------------------------ + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSelectedFiles( ) + throw (::com::sun::star::uno::RuntimeException); + + //------------------------------------------------------------------------------------ + // XFilterManager functions + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL appendFilter( const ::rtl::OUString& aTitle, const ::rtl::OUString& aFilter ) + throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL setCurrentFilter( const ::rtl::OUString& aTitle ) + throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ); + + virtual ::rtl::OUString SAL_CALL getCurrentFilter( ) + throw( ::com::sun::star::uno::RuntimeException ); + + //------------------------------------------------------------------------------------ + // XFilterGroupManager functions + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL appendFilterGroup( const ::rtl::OUString& sGroupTitle, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aFilters ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + //------------------------------------------------------------------------------------ + // XFilePickerControlAccess functions + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL setValue( sal_Int16 aControlId, sal_Int16 aControlAction, const ::com::sun::star::uno::Any& aValue ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Any SAL_CALL getValue( sal_Int16 aControlId, sal_Int16 aControlAction ) + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL enableControl( sal_Int16 aControlId, sal_Bool bEnable ) + throw(::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL setLabel( sal_Int16 aControlId, const ::rtl::OUString& aLabel ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getLabel( sal_Int16 aControlId ) + throw (::com::sun::star::uno::RuntimeException); + + //------------------------------------------------ + // XFilePreview + //------------------------------------------------ + + virtual ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL getSupportedImageFormats( ) throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getTargetColorDepth( ) throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getAvailableWidth( ) throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getAvailableHeight( ) throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setImage( sal_Int16 aImageFormat, const ::com::sun::star::uno::Any& aImage ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL setShowState( sal_Bool bShowState ) throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL getShowState( ) throw (::com::sun::star::uno::RuntimeException); + + //------------------------------------------------ + // XInitialization + //------------------------------------------------ + + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) + throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + //------------------------------------------------ + // XCancellable + //------------------------------------------------ + + virtual void SAL_CALL cancel( ) + throw(::com::sun::star::uno::RuntimeException); + + //------------------------------------------------ + // XEventListener + //------------------------------------------------ + + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aEvent ) + throw(::com::sun::star::uno::RuntimeException); + + //------------------------------------------------ + // XServiceInfo + //------------------------------------------------ + + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw(::com::sun::star::uno::RuntimeException); + + //------------------------------------------------------------------------------------ + // FilePicker Event functions + //------------------------------------------------------------------------------------ + + void SAL_CALL fileSelectionChanged( ::com::sun::star::ui::dialogs::FilePickerEvent aEvent ); + void SAL_CALL directoryChanged( ::com::sun::star::ui::dialogs::FilePickerEvent aEvent ); + rtl::OUString SAL_CALL helpRequested( ::com::sun::star::ui::dialogs::FilePickerEvent aEvent ) const; + void SAL_CALL controlStateChanged( ::com::sun::star::ui::dialogs::FilePickerEvent aEvent ); + void SAL_CALL dialogSizeChanged( ); + + bool startupEventNotification(bool bStartupSuspended); + void shutdownEventNotification(); + void suspendEventNotification(); + void resumeEventNotification(); + +private: + // prevent copy and assignment + CFilePicker( const CFilePicker& ); + CFilePicker& operator=( const CFilePicker& ); + + using WeakComponentImplHelperBase::disposing; + +private: + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceMgr; // to instanciate own services + CAsyncEventNotifier m_aAsyncEventNotifier; + std::auto_ptr<CWinFileOpenImpl> m_pImpl; +}; + +#endif diff --git a/fpicker/source/win32/filepicker/FilterContainer.cxx b/fpicker/source/win32/filepicker/FilterContainer.cxx new file mode 100644 index 000000000000..a54f796e23ac --- /dev/null +++ b/fpicker/source/win32/filepicker/FilterContainer.cxx @@ -0,0 +1,337 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + + +#include <stdexcept> +#include <osl/diagnose.h> +#include "FilterContainer.hxx" + +#include <utility> + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//------------------------------------------------------------------- +// namespace directives +//------------------------------------------------------------------- + +using ::rtl::OUString; + +//------------------------------------------------------------------------------------- +// ctor +//------------------------------------------------------------------------------------- + +CFilterContainer::CFilterContainer( sal_Int32 initSize ) : + m_vFilters( initSize ), + m_bIterInitialized( sal_False ) +{ +} + +//----------------------------------------------------------------------------------------- +// add a name/filter pair +//----------------------------------------------------------------------------------------- + +sal_Bool SAL_CALL CFilterContainer::addFilter( + const OUString& aName, const OUString& aFilter, sal_Bool bAllowDuplicates ) +{ + // check if the filter is already in the container + sal_Int32 pos = -1; + + if ( !bAllowDuplicates ) + { + pos = getFilterTagPos( aName ); + if ( pos < 0 ) // if not there, append + { + m_vFilters.push_back( std::make_pair( aName, aFilter ) ); + m_bIterInitialized = sal_False; + } + } + else + { + m_vFilters.push_back( std::make_pair( aName, aFilter ) ); + m_bIterInitialized = sal_False; + } + + return ( pos < 0 ) ? sal_True : sal_False; +} + +//----------------------------------------------------------------------------------------- +// delete a filter +// Precondition: the container is not empty +// there is a filter identified by the given name +//----------------------------------------------------------------------------------------- + +sal_Bool SAL_CALL CFilterContainer::delFilter( const OUString& aName ) +{ + OSL_ASSERT( m_vFilters.size() > 0 ); + + sal_Int32 pos = getFilterTagPos( aName ); + if ( pos > -1 ) + { + m_vFilters.erase( ( m_vFilters.begin() + pos ) ); + m_bIterInitialized = sal_False; + } + + return ( pos > -1 ) ? sal_True : sal_False; +} + +//----------------------------------------------------------------------------------------- +// return the number of filters currently in the container +//----------------------------------------------------------------------------------------- + +sal_Int32 SAL_CALL CFilterContainer::numFilter( ) +{ + return m_vFilters.size( ); +} + +//----------------------------------------------------------------------------------------- +// clear all entries +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilterContainer::empty() +{ + m_vFilters.clear( ); +} + +//----------------------------------------------------------------------------------------- +// get a filter by name +// Precondition: the container is not empty +// there is a filter identified by the name +//----------------------------------------------------------------------------------------- + +sal_Bool SAL_CALL CFilterContainer::getFilter( const OUString& aName, OUString& theFilter ) const +{ + OSL_PRECOND( m_vFilters.size() > 0, "Empty filter container" ); + + sal_Int32 pos = getFilterTagPos( aName ); + + try + { + if ( pos > -1 ) + theFilter = m_vFilters.at( pos ).second; + } + catch( std::out_of_range& ) + { + OSL_ENSURE( sal_False, "Filter not in filter container" ); + pos = -1; + } + + return (pos > -1 ) ? sal_True : sal_False; +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +sal_Bool SAL_CALL CFilterContainer::getFilter( sal_Int32 aIndex, OUString& theFilter ) const +{ + sal_Bool bRet = sal_True; + + try + { + theFilter = m_vFilters.at( aIndex ).first; + } + catch( std::out_of_range& ) + { + OSL_ENSURE( sal_False, "Filter index out of range" ); + bRet = sal_False; + } + + return bRet; +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +sal_Int32 SAL_CALL CFilterContainer::getFilterPos( const OUString& aName ) const +{ + return getFilterTagPos( aName ); +} + +//----------------------------------------------------------------------------------------- +// returns the index of the filter identified by name +//----------------------------------------------------------------------------------------- + +sal_Int32 SAL_CALL CFilterContainer::getFilterTagPos( const OUString& aName ) const +{ + if ( m_vFilters.size( ) > 0 ) + { + sal_Int32 i = 0; + FILTER_VECTOR_T::const_iterator iter; + FILTER_VECTOR_T::const_iterator iter_end = m_vFilters.end( ); + + for ( iter = m_vFilters.begin( ); iter != iter_end; ++iter, ++i ) + if ( ( *iter ).first.equalsIgnoreAsciiCase( aName ) ) + return i; + } + + return -1; +} + +//----------------------------------------------------------------------------------------- +// starts enumerating the filter in the container +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFilterContainer::beginEnumFilter( ) +{ + m_iter = m_vFilters.begin( ); + m_bIterInitialized = sal_True; +} + +//----------------------------------------------------------------------------------------- +// returns true if another filter has been retrieved +//----------------------------------------------------------------------------------------- + +sal_Bool SAL_CALL CFilterContainer::getNextFilter( FILTER_ENTRY_T& nextFilterEntry ) +{ + OSL_ASSERT( m_bIterInitialized ); + + sal_Bool bRet = ( m_iter != m_vFilters.end( ) ); + + if ( bRet ) + nextFilterEntry = *m_iter++; + else + m_bIterInitialized = sal_False; + + return bRet; +} + +//----------------------------------------------------------------------------------------- +void SAL_CALL CFilterContainer::setCurrentFilter( const ::rtl::OUString& aName ) +{ + m_sCurrentFilter = aName; +} + +//----------------------------------------------------------------------------------------- +::rtl::OUString SAL_CALL CFilterContainer::getCurrentFilter() const +{ + return m_sCurrentFilter; +} + +//################################################################### + + +//------------------------------------------------------------------- +// calculates the length of a '\0' separated filter, that means +// length of the name + '\0' + length of the filter string + +// a trailing '\0' +//------------------------------------------------------------------- + +static sal_uInt32 _getLengthFilter( CFilterContainer::FILTER_ENTRY_T aFilterEntry ) +{ + return ( + aFilterEntry.first.getLength( ) + 1 + + aFilterEntry.second.getLength( ) + 1 ); +} + +//------------------------------------------------------------------- +// calculates the length of all filters currently in the container +//------------------------------------------------------------------- + +static sal_uInt32 _getTotalFilterLength( CFilterContainer& aFilterContainer ) +{ + CFilterContainer::FILTER_ENTRY_T nextFilter; + + aFilterContainer.beginEnumFilter( ); + + sal_uInt32 totalLength = 0; + while( aFilterContainer.getNextFilter( nextFilter ) ) + totalLength += _getLengthFilter( nextFilter ); + + return ( totalLength > 0 ) ? totalLength + 1 : totalLength; +} + +//------------------------------------------------------------------- +// +//------------------------------------------------------------------- + +inline +void _wcsmemcpy( sal_Unicode* pDest, const sal_Unicode* pSrc, sal_uInt32 nLength ) +{ + memcpy( pDest, pSrc, nLength * sizeof( sal_Unicode ) ); +} + +//------------------------------------------------------------------- +// a helper trivial helper function to create a filter buffer in the +// format the Win32 API requires, +// e.g. "Text\0*.txt\0Doc\0*.doc;*xls\0\0" +//------------------------------------------------------------------- + +rtl::OUString SAL_CALL makeWinFilterBuffer( CFilterContainer& aFilterContainer ) +{ + // calculate the required buffer size + sal_uInt32 reqBuffSize = _getTotalFilterLength( aFilterContainer ); + + // return if there are no filters + if ( !reqBuffSize ) + return OUString( ); + + sal_Unicode* pBuff = new sal_Unicode[reqBuffSize]; + + // initialize the buffer with 0 + ZeroMemory( pBuff, sizeof( sal_Unicode ) * reqBuffSize ); + + OUString winFilterBuff; + CFilterContainer::FILTER_ENTRY_T nextFilter; + sal_uInt32 memPos = 0; + + aFilterContainer.beginEnumFilter( ); + + while( aFilterContainer.getNextFilter( nextFilter ) ) + { + _wcsmemcpy( + pBuff + memPos, + nextFilter.first.getStr( ), + nextFilter.first.getLength( ) ); + + memPos += nextFilter.first.getLength( ) + 1; + + _wcsmemcpy( + pBuff + memPos, + nextFilter.second.getStr( ), + nextFilter.second.getLength( ) ); + + memPos += nextFilter.second.getLength( ) + 1 ; + } + + winFilterBuff = OUString( pBuff, reqBuffSize ); + + // remove the allocated buffer + delete [] pBuff; + + return winFilterBuff; +} + diff --git a/fpicker/source/win32/filepicker/FilterContainer.hxx b/fpicker/source/win32/filepicker/FilterContainer.hxx new file mode 100644 index 000000000000..79b354e6a96d --- /dev/null +++ b/fpicker/source/win32/filepicker/FilterContainer.hxx @@ -0,0 +1,115 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _FILTER_CONTAINER_HXX_ +#define _FILTER_CONTAINER_HXX_ + +#include <sal/types.h> +#include <rtl/ustring.hxx> + +#include <vector> + +//------------------------------------------------------ +// helper class, only useable by OFilterContainer +//------------------------------------------------------ + +class CFilterContainer +{ +public: + // defines a filter entry which is made of a name and a filter value + // e.g. 'Text *.txt' + typedef std::pair< rtl::OUString, rtl::OUString > FILTER_ENTRY_T; + +public: + explicit CFilterContainer( sal_Int32 initSize = 0 ); + + // add a new filter + // returns true if the filter was successfully added + // returns false if duplicates are not allowed and + // the filter is already in the container + sal_Bool SAL_CALL addFilter( + const ::rtl::OUString& aName, + const ::rtl::OUString& aFilter, + sal_Bool bAllowDuplicates = sal_False ); + + // delete the specified filter returns true on + // success and false if the filter was not found + sal_Bool SAL_CALL delFilter( const ::rtl::OUString& aName ); + + // the number of filter already added + sal_Int32 SAL_CALL numFilter( ); + + // clear all entries + void SAL_CALL empty( ); + + // retrieve a filter from the container both methods + // return true on success and false if the specified + // filter was not found + sal_Bool SAL_CALL getFilter( const ::rtl::OUString& aName, ::rtl::OUString& theFilter ) const; + sal_Bool SAL_CALL getFilter( sal_Int32 aIndex, ::rtl::OUString& theFilter ) const; + + // returns the position of the specified filter or -1 + // if the filter was not found + sal_Int32 SAL_CALL getFilterPos( const ::rtl::OUString& aName ) const; + + // starts enumerating the filter in the container + void SAL_CALL beginEnumFilter( ); + + // returns true if another filter has been retrieved + sal_Bool SAL_CALL getNextFilter( FILTER_ENTRY_T& nextFilterEntry ); + + // cache current filter + void SAL_CALL setCurrentFilter( const ::rtl::OUString& aName ); + + // returns cached current filter + ::rtl::OUString SAL_CALL getCurrentFilter() const; + +protected: + typedef std::vector< FILTER_ENTRY_T > FILTER_VECTOR_T; + +private: + // prevent copy and assignment + CFilterContainer( const CFilterContainer& ); + CFilterContainer& SAL_CALL operator=( const CFilterContainer& ); + + sal_Int32 SAL_CALL getFilterTagPos( const ::rtl::OUString& aName ) const; + +private: + FILTER_VECTOR_T m_vFilters; + FILTER_VECTOR_T::const_iterator m_iter; + sal_Bool m_bIterInitialized; + ::rtl::OUString m_sCurrentFilter; +}; + +//---------------------------------------------------------------- +// a helper function to create a filter buffer in the format +// the Win32 API requires, e.g. "Text\0*.txt\0Doc\0*.doc;*xls\0\0" +//---------------------------------------------------------------- + +rtl::OUString SAL_CALL makeWinFilterBuffer( CFilterContainer& aFilterContainer ); + +#endif diff --git a/fpicker/source/win32/filepicker/Fps.rc b/fpicker/source/win32/filepicker/Fps.rc new file mode 100644 index 000000000000..ad08ad06698e --- /dev/null +++ b/fpicker/source/win32/filepicker/Fps.rc @@ -0,0 +1,438 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// German (Germany) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +1000 DIALOG DISCARDABLE 0, 0, 200, 37 +STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "Andale Sans UI" +BEGIN + CONTROL "Mit Schreibschutz öffnen",103,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 52,24,148,10 + COMBOBOX 107,52,8,148,52,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Version:",207,0,10,52,11 + LTEXT "",1119,0,0,200,8 +END + +1001 DIALOG DISCARDABLE 0, 0, 338, 67 +STYLE DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Mit Schreibschutz öffnen",103,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 130,51,161,14 + COMBOBOX 107,130,35,164,52,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Version:",207,68,37,56,11 + LTEXT "",1119,0,0,336,35 +END + +2000 DIALOG DISCARDABLE 0, 0, 210, 53 +STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "Andale Sans UI" +BEGIN + CONTROL "Vorschau",105,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 52,40,157,10 + CONTROL "Als Link einfügen",104,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 52,28,157,10 + COMBOBOX 109,52,12,156,54,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Bildvorlage:",209,4,14,48,10 + LTEXT "",1119,0,0,210,12 +END + +2001 DIALOG DISCARDABLE 0, 0, 280, 72 +STYLE DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Vorschau",105,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 130,58,144,16 + CONTROL "Als Link einfügen",104,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 130,45,144,14 + COMBOBOX 109,130,28,164,62,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP + LTEXT "Bildvorlage:",209,67,30,47,11 + LTEXT "",1119,0,0,281,28 +END + +3000 DIALOG DISCARDABLE 0, 0, 208, 49 +STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "Andale Sans UI" +BEGIN + CONTROL "Automatische Dateinamenserweiterung",100,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,52,36,156,10 + COMBOBOX 108,52,20,156,52,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Vorlagen:",208,4,22,47,11 + LTEXT "",1119,0,0,208,20 +END + +3001 DIALOG DISCARDABLE 0, 0, 296, 72 +STYLE DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Automatische Dateinamenserweiterung",100,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,130,58,157,14 + COMBOBOX 108,130,41,164,100,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP + LTEXT "Vorlagen:",208,67,42,58,8 + LTEXT "",1119,0,0,293,41 +END + +4000 DIALOG DISCARDABLE 0, 0, 196, 41 +STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "Andale Sans UI" +BEGIN + CONTROL "Mit Kennwort speichern",101,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,52,28,141,10 + CONTROL "Automatische Dateinamenserweiterung",100,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,52,16,141,10 + LTEXT "",1119,0,0,195,16 +END + +4001 DIALOG DISCARDABLE 0, 0, 278, 67 +STYLE DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Mit Kennwort speichern",101,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,130,51,144,16 + CONTROL "Automatische Dateinamenserweiterung",100,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,130,38,144,14 + LTEXT "",1119,0,0,277,38 +END + +5000 DIALOG DISCARDABLE 0, 0, 192, 57 +STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "Andale Sans UI" +BEGIN + CONTROL "Filtereinstellungen bearbeiten",102,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,52,44,140,10 + CONTROL "Mit Kennwort speichern",101,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,52,32,140,10 + CONTROL "Automatische Dateinamenserweiterung",100,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,52,20,140,10 + LTEXT "",1119,0,0,192,20 +END + +5001 DIALOG DISCARDABLE 0, 0, 278, 79 +STYLE DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Filtereinstellungen bearbeiten",102,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,130,66,144,13 + CONTROL "Mit Kennwort speichern",101,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,130,52,144,13 + CONTROL "Automatische Dateinamenserweiterung",100,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,130,38,144,14 + LTEXT "",1119,0,0,277,38 +END + +6000 DIALOG DISCARDABLE 0, 0, 212, 25 +STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "Andale Sans UI" +BEGIN + LTEXT "",1119,0,0,212,8,NOT WS_VISIBLE + PUSHBUTTON "Abspielen",106,156,8,50,15 +END + +6001 DIALOG DISCARDABLE 0, 0, 366, 40 +STYLE DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "MS Shell Dlg" +BEGIN + LTEXT "",1119,0,0,364,18,NOT WS_VISIBLE + PUSHBUTTON "Abspielen",106,316,18,50,14 +END + +7000 DIALOG DISCARDABLE 0, 0, 196, 45 +STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "Andale Sans UI" +BEGIN + CONTROL "Selektion",110,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,52, + 32,143,10 + CONTROL "Automatische Dateinamenserweiterung",100,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,52,20,143,10 + LTEXT "",1119,0,0,195,20 +END + +7001 DIALOG DISCARDABLE 0, 0, 278, 65 +STYLE DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Selektion",110,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 130,51,144,16 + CONTROL "Automatische Dateinamenserweiterung",100,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,130,38,144,14 + LTEXT "",1119,0,0,277,38 +END + +8000 DIALOG DISCARDABLE 0, 0, 152, 41 +STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "Andale Sans UI" +BEGIN + CONTROL "Vorschau",105,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,0, + 28,150,10 + CONTROL "Als Link einfügen",104,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,0,16,152,10 + LTEXT "",1119,0,0,149,16 +END + +8001 DIALOG DISCARDABLE 0, 0, 278, 65 +STYLE DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Vorschau",105,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,130, + 51,144,16 + CONTROL "Als Link einfügen",104,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,130,38,144,14 + LTEXT "",1119,0,0,277,38 +END + +9000 DIALOG DISCARDABLE 0, 0, 196, 29 +STYLE DS_3DLOOK | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "Andale Sans UI" +BEGIN + CONTROL "Automatische Dateinamenserweiterung",100,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,0,16,196,10 + LTEXT "",1119,0,0,196,16 +END + +9001 DIALOG DISCARDABLE 0, 0, 278, 54 +STYLE DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "Automatische Dateinamenserweiterung",100,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,130,38,144,14 + LTEXT "",1119,0,0,277,38 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + 1000, DIALOG + BEGIN + VERTGUIDE, 5 + VERTGUIDE, 54 + BOTTOMMARGIN, 34 + END + + 1001, DIALOG + BEGIN + RIGHTMARGIN, 336 + VERTGUIDE, 124 + VERTGUIDE, 130 + HORZGUIDE, 37 + END + + 2000, DIALOG + BEGIN + RIGHTMARGIN, 209 + VERTGUIDE, 61 + HORZGUIDE, 25 + END + + 3000, DIALOG + BEGIN + VERTGUIDE, 51 + BOTTOMMARGIN, 48 + HORZGUIDE, 38 + END + + 3001, DIALOG + BEGIN + RIGHTMARGIN, 294 + VERTGUIDE, 67 + HORZGUIDE, 41 + END + + 4000, DIALOG + BEGIN + RIGHTMARGIN, 194 + VERTGUIDE, 54 + BOTTOMMARGIN, 37 + HORZGUIDE, 34 + END + + 4001, DIALOG + BEGIN + RIGHTMARGIN, 277 + VERTGUIDE, 76 + HORZGUIDE, 52 + END + + 5000, DIALOG + BEGIN + VERTGUIDE, 61 + BOTTOMMARGIN, 56 + HORZGUIDE, 25 + END + + 5001, DIALOG + BEGIN + RIGHTMARGIN, 277 + VERTGUIDE, 76 + HORZGUIDE, 52 + END + + 6000, DIALOG + BEGIN + RIGHTMARGIN, 59 + BOTTOMMARGIN, 20 + END + + 6001, DIALOG + BEGIN + RIGHTMARGIN, 361 + BOTTOMMARGIN, 36 + HORZGUIDE, 20 + END + + 7000, DIALOG + BEGIN + VERTGUIDE, 54 + HORZGUIDE, 34 + END + + 7001, DIALOG + BEGIN + RIGHTMARGIN, 277 + VERTGUIDE, 76 + HORZGUIDE, 52 + END + + 8000, DIALOG + BEGIN + RIGHTMARGIN, 151 + VERTGUIDE, 61 + BOTTOMMARGIN, 37 + END + + 9000, DIALOG + BEGIN + BOTTOMMARGIN, 25 + END + + 9001, DIALOG + BEGIN + RIGHTMARGIN, 277 + VERTGUIDE, 76 + HORZGUIDE, 52 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +1000 DLGINIT +BEGIN + 107, 0x403, 15, 0 +0x7453, 0x7261, 0x7257, 0x7469, 0x7265, 0x3520, 0x322e, "\000" + 107, 0x403, 15, 0 +0x7453, 0x7261, 0x7257, 0x7469, 0x7265, 0x3420, 0x302e, "\000" + 107, 0x403, 15, 0 +0x7453, 0x7261, 0x7257, 0x7469, 0x7265, 0x3320, 0x302e, "\000" + 0 +END + +1001 DLGINIT +BEGIN + 107, 0x403, 15, 0 +0x7453, 0x7261, 0x7257, 0x7469, 0x7265, 0x3520, 0x322e, "\000" + 107, 0x403, 15, 0 +0x7453, 0x7261, 0x7257, 0x7469, 0x7265, 0x3420, 0x302e, "\000" + 107, 0x403, 15, 0 +0x7453, 0x7261, 0x7257, 0x7469, 0x7265, 0x3320, 0x302e, "\000" + 0 +END + +3000 DLGINIT +BEGIN + 108, 0x403, 15, 0 +0x7453, 0x7261, 0x7257, 0x7469, 0x7265, 0x3520, 0x322e, "\000" + 108, 0x403, 15, 0 +0x7453, 0x7261, 0x7257, 0x7469, 0x7265, 0x3420, 0x302e, "\000" + 108, 0x403, 15, 0 +0x7453, 0x7261, 0x7257, 0x7469, 0x7265, 0x3320, 0x302e, "\000" + 0 +END + +3001 DLGINIT +BEGIN + 108, 0x403, 15, 0 +0x7453, 0x7261, 0x7257, 0x7469, 0x7265, 0x3520, 0x322e, "\000" + 108, 0x403, 15, 0 +0x7453, 0x7261, 0x7257, 0x7469, 0x7265, 0x3420, 0x302e, "\000" + 108, 0x403, 15, 0 +0x7453, 0x7261, 0x7257, 0x7469, 0x7265, 0x3320, 0x302e, "\000" + 0 +END + +#endif // German (Germany) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/fpicker/source/win32/filepicker/IVistaFilePickerInternalNotify.hxx b/fpicker/source/win32/filepicker/IVistaFilePickerInternalNotify.hxx new file mode 100644 index 000000000000..8f4e0d040f3e --- /dev/null +++ b/fpicker/source/win32/filepicker/IVistaFilePickerInternalNotify.hxx @@ -0,0 +1,75 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FPICKER_WIN32_VISTA_FILEPICKER_INTERNALNOTIFY_HXX +#define FPICKER_WIN32_VISTA_FILEPICKER_INTERNALNOTIFY_HXX + +//----------------------------------------------------------------------------- +// includes +//----------------------------------------------------------------------------- + +#include "comptr.hxx" +#include "vistatypes.h" + +#include <cppuhelper/basemutex.hxx> +#include <osl/interlck.h> + +#include <shobjidl.h> + +//----------------------------------------------------------------------------- +// namespace +//----------------------------------------------------------------------------- + +#ifdef css + #error "Clash on using CSS as namespace define." +#else + #define css ::com::sun::star +#endif + +namespace fpicker{ +namespace win32{ +namespace vista{ + +//----------------------------------------------------------------------------- +// types, const etcpp. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +/** todo document me + */ +class IVistaFilePickerInternalNotify +{ + public: + + virtual void onAutoExtensionChanged (bool bChecked) = 0; +}; + +}}} + +#undef css + +#endif FPICKER_WIN32_VISTA_FILEPICKER_INTERNALNOTIFY_HXX diff --git a/fpicker/source/win32/filepicker/PreviewCtrl.cxx b/fpicker/source/win32/filepicker/PreviewCtrl.cxx new file mode 100644 index 000000000000..84627a9f3d82 --- /dev/null +++ b/fpicker/source/win32/filepicker/PreviewCtrl.cxx @@ -0,0 +1,615 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <tchar.h> +#include "PreviewCtrl.hxx" +#include <osl/diagnose.h> + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <ocidl.h> +#include <olectl.h> + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +#define PREVIEWWND_CLASS_NAME TEXT("PreviewWnd###") + +#define HIMETRIC_INCH 2540 + +// means 3 pixel left and 3 pixel right +#define HORZ_BODER_SPACE 6 + +// means 3 pixel top and 3 pixel bottom +#define VERT_BORDER_SPACE 6 + +//--------------------------------------------------- +// static member initialization +//--------------------------------------------------- + +CFilePreview* CFilePreview::s_FilePreviewInst = NULL; +CFilePreview::FILEPREVIEW_SINGLETON_DESTROYER_T CFilePreview::s_SingletonDestroyer; + +//--------------------------------------------------- +// some useful helper functions +//--------------------------------------------------- + +namespace // private +{ + class CPreviewException + { + // used when registering or creation + // of the preview window failed + }; + + //------------------------------------------------------------ + // + //------------------------------------------------------------ + + inline + sal_Int32 SubDiv( sal_Int32 nNumber, sal_Int32 nMinuend, sal_Int32 nDenominator ) + { + return ( static_cast<sal_Int32>( ( nNumber - nMinuend ) / nDenominator ) ); + } + + //------------------------------------------------------------ + // convert himetric to pixel + //------------------------------------------------------------ + + inline + sal_Int32 Himetric2Pixel( HDC hDC, sal_Int32 hmSize, sal_Int32 nIndex ) + { + return MulDiv( hmSize, GetDeviceCaps( hDC, nIndex), HIMETRIC_INCH ); + } + + //------------------------------------------------------------ + // + //------------------------------------------------------------ + + inline + sal_uInt32 _getWidthRect( const RECT& aRect ) + { + return ( aRect.right - aRect.left ); + } + + //------------------------------------------------------------ + // + //------------------------------------------------------------ + + inline + sal_uInt32 _getHeightRect( const RECT& aRect ) + { + return ( aRect.bottom - aRect.top ); + } + + //------------------------------------------------------------ + // calc the upper left corner so that a given window will be + // displayed centered within the given window + //------------------------------------------------------------ + + inline + POINT _calcULCorner( HWND hwnd, const CDimension& aPicSize ) + { + RECT rect; + GetClientRect( hwnd, &rect ); + + sal_Int32 nWidthWnd = _getWidthRect( rect ); + sal_Int32 nHeightWnd = _getHeightRect( rect ); + + POINT ulCorner; + ulCorner.x = SubDiv( nWidthWnd, aPicSize.m_cx, 2 ); + ulCorner.y = SubDiv( nHeightWnd, aPicSize.m_cy, 2 ); + + return ulCorner; + } + + //------------------------------------------------------------ + // test if a picture with the given dimensions fits into an + // arbitrary window + // we expect the width and height to be in pixel + //------------------------------------------------------------ + + inline + sal_Bool _pictureSizeFitsWindowSize( HWND hwnd, const CDimension& aPicSize ) + { + RECT rect; + GetClientRect( hwnd, &rect ); + + sal_Int32 nWidthWnd = _getWidthRect( rect ); + sal_Int32 nHeightWnd = _getHeightRect( rect ); + + return ( ( ( nWidthWnd - HORZ_BODER_SPACE ) >= aPicSize.m_cx ) && + ( ( nHeightWnd - VERT_BORDER_SPACE ) >= aPicSize.m_cy ) ); + } + + //------------------------------------------------------------ + // calc the dimemsions so that a given picture fits into a + // given window, if the picture fits into the given window + // the original CDimension will be returned + //------------------------------------------------------------ + + inline + CDimension _scalePictureSize( HWND hwnd, const CDimension& aPicSize ) + { + CDimension scaledPicSize = aPicSize; + + if ( !_pictureSizeFitsWindowSize( hwnd, aPicSize ) ) + { + RECT rect; + GetClientRect( hwnd, &rect ); + + // the dimensions of the preview wnd are not equal + // that's why we equalize it + sal_Int32 nHeightWnd = _getHeightRect( rect ) - VERT_BORDER_SPACE; + sal_Int32 nWidthWnd = nHeightWnd; + + if ( aPicSize.m_cx >= aPicSize.m_cy ) + { + scaledPicSize.m_cx = nWidthWnd; + scaledPicSize.m_cy = + static_cast< sal_Int32 >( + aPicSize.m_cy * nWidthWnd / aPicSize.m_cx ); + } + else + { + scaledPicSize.m_cx = + static_cast< sal_Int32 >( + aPicSize.m_cx * nHeightWnd / aPicSize.m_cy ); + scaledPicSize.m_cy = nHeightWnd; + } + } + + return scaledPicSize; + } + +} // end namespace + + +//--------------------------------------------------- +// to ensure only one instance (singleton) +//--------------------------------------------------- + +CFilePreview* CFilePreview::createInstance( + HWND aParent, + POINT ulCorner, + const CDimension& aSize, + HINSTANCE hInstance, + sal_Bool bShow, + sal_Bool bEnabled ) +{ + if ( !s_FilePreviewInst ) + { + try + { + s_FilePreviewInst = new CFilePreview( + aParent, ulCorner, aSize, hInstance, bShow, bEnabled ); + s_SingletonDestroyer.reset( s_FilePreviewInst ); + } + catch( CPreviewException& ) + { + OSL_ASSERT( !s_FilePreviewInst ); + OSL_ENSURE( sal_False, "Creation of the preview window failed" ); + } + catch( CAutoOleInit::COleInitException& ) + { + OSL_ASSERT( !s_FilePreviewInst ); + OSL_ENSURE( sal_False, "OleInitalize failed" ); + } + } + + return s_FilePreviewInst; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +CFilePreview::CFilePreview( + HWND aParent, + POINT ulCorner, + const CDimension& aSize, + HINSTANCE hInstance, + sal_Bool bShow, + sal_Bool bEnabled ) : + m_hInstance( hInstance ), + m_bEnabled( bEnabled ) +{ + // register the preview window class + WNDCLASSEX wndClsEx; + ZeroMemory(&wndClsEx, sizeof(wndClsEx)); + + wndClsEx.cbSize = sizeof(wndClsEx); + wndClsEx.style = CS_HREDRAW | CS_VREDRAW; + wndClsEx.lpfnWndProc = CFilePreview::WndProc; + wndClsEx.hInstance = m_hInstance; + wndClsEx.hbrBackground = (HBRUSH)( COLOR_INACTIVEBORDER + 1 ); + wndClsEx.lpszClassName = PREVIEWWND_CLASS_NAME; + + // register the preview window class + // !!! Win95 - the window class will be unregistered automaticly + // if the dll is unloaded + // Win2000 - the window class must be unregistered manually + // if the dll is unloaded + m_atomPrevWndClass = RegisterClassEx(&wndClsEx); + if ( !m_atomPrevWndClass ) + throw CPreviewException( ); + + // create the preview window in invisible state + sal_uInt32 dwStyle = bShow ? (WS_CHILD | WS_VISIBLE) : WS_CHILD; + m_hwnd = CreateWindowEx( + WS_EX_CLIENTEDGE, + PREVIEWWND_CLASS_NAME, + TEXT(""), + dwStyle, + ulCorner.x, + ulCorner.y, + aSize.m_cx, + aSize.m_cy, + aParent, + (HMENU)100, // for child windows this will + // be used as child window identifier + m_hInstance, + 0 ); + if (!IsWindow(m_hwnd)) + throw CPreviewException( ); +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +CFilePreview::~CFilePreview( ) +{ + // unregister preview window class + sal_Bool bRet = UnregisterClass( + (LPCTSTR)MAKELONG( m_atomPrevWndClass, 0 ), + m_hInstance ); + OSL_POSTCOND( bRet, "Unregister preview window class failed" ); +} + +//--------------------------------------------------- +// sets the size of the preview window +//--------------------------------------------------- + +sal_Bool SAL_CALL CFilePreview::setSize( const CDimension& aSize ) +{ + OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" ); + + // resize the fileopen file listbox + return SetWindowPos( + m_hwnd, + NULL, + 0, + 0, + aSize.m_cx, + aSize.m_cy, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE ); +} + +//--------------------------------------------------- +// returns the dimension of the preview +//--------------------------------------------------- + +sal_Bool SAL_CALL CFilePreview::getSize( CDimension& theSize ) const +{ + OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" ); + + RECT rect; + sal_Bool bRet = GetWindowRect( m_hwnd, &rect ); + + theSize.m_cx = _getWidthRect( rect ); + theSize.m_cy = _getHeightRect( rect ); + + return bRet; +} + +//--------------------------------------------------- +// sets the position of the upper left corner +// of the preview window relative to the +// upper left corner of the parent window +//--------------------------------------------------- + +sal_Bool SAL_CALL CFilePreview::setPos( POINT ulCorner ) +{ + OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" ); + + // resize the fileopen file listbox + return SetWindowPos( + m_hwnd, + NULL, + ulCorner.x, + ulCorner.y, + 0, + 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE ); +} + +//--------------------------------------------------- +// returns the current position of the preview +// relative to the upper left corner of the +// parent window +//--------------------------------------------------- + +sal_Bool SAL_CALL CFilePreview::getPos( POINT& ulCorner ) const +{ + OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" ); + + POINT pt = { 0, 0 }; + RECT rect; + + sal_Bool bRet = GetWindowRect( m_hwnd, &rect ); + + ulCorner.x = rect.left; + ulCorner.y = rect.top; + + ScreenToClient( m_hwnd, &ulCorner ); + + return bRet; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CFilePreview::enable( sal_Bool bEnable ) +{ + m_bEnabled = bEnable; + + // force a redraw + InvalidateRect( m_hwnd, NULL, TRUE ); + UpdateWindow( m_hwnd ); +} + +//--------------------------------------------------- +// shows the preview window +// possible values see SHOW_STATE +// SS_SHOW - make the window visible +// SS_HIDE - hide the window +// SS_ENABLED - enable the window +// SS_DISABLED - disable the window +//--------------------------------------------------- + +sal_Bool SAL_CALL CFilePreview::show( sal_Bool bShow ) +{ + OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" ); + + sal_Int32 showState = bShow ? SW_SHOW : SW_HIDE; + return ShowWindow( m_hwnd, showState ); +} + +//--------------------------------------------------- +// if the preview is shown and enabled +// preview of the given file will be shown +// returns true on success or false if an error +// occured (the file in not there or not accessible etc.) +//--------------------------------------------------- + +sal_Bool SAL_CALL CFilePreview::update( const rtl::OUString& aFileName ) +{ + OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" ); + + try + { + if ( m_bEnabled ) + { + if ( m_IPicture ) + m_IPicture.Release( ); + + loadFile( aFileName ); + + // force a complete window redraw + InvalidateRect( m_hwnd, NULL, TRUE ); + UpdateWindow( m_hwnd ); + } + } + catch( _com_error& ) + { + } + + return sal_True; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CFilePreview::onPaint( HWND hWnd, HDC hDC ) +{ + OSL_PRECOND( IsWindow( m_hwnd ), "Preview window not initialized" ); + + try + { + if ( m_bEnabled ) + { + // get width and height of picture + long cxPicHIMETRIC; + long cyPicHIMETRIC; + + m_IPicture->get_Width( &cxPicHIMETRIC ); + m_IPicture->get_Height( &cyPicHIMETRIC ); + + // convert himetric to pixels + int cxPicPIXEL = Himetric2Pixel( hDC, cxPicHIMETRIC, LOGPIXELSX ); + int cyPicPIXEL = Himetric2Pixel( hDC, cyPicHIMETRIC, LOGPIXELSY ); + + // scale the picture based on the size of the preview window + RECT rcPrevWnd; + GetClientRect(hWnd, &rcPrevWnd); + + CDimension scaledPicSize = _scalePictureSize( + hWnd, CDimension( cxPicPIXEL, cyPicPIXEL ) ); + + // calc the upper left corner so that the picture + // is centered within the window + POINT ulCorner = _calcULCorner( hWnd, scaledPicSize ); + + // render the picture + HRESULT hr = m_IPicture->Render( + hDC, + ulCorner.x, + ulCorner.y, + scaledPicSize.m_cx, + scaledPicSize.m_cy, + 0, + cyPicHIMETRIC, + cxPicHIMETRIC, + -cyPicHIMETRIC, + &rcPrevWnd ); + } // end if ( m_bEnabled ) + } + catch( _com_error& ) + { + } +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +sal_Bool CFilePreview::loadFile( const rtl::OUString& aFileName ) +{ + HANDLE hFile = 0; + HGLOBAL hGlobal = 0; + LPVOID pData = NULL; + IStreamPtr pIStream; + HRESULT hr = E_FAIL; + sal_Bool bRet; + sal_uInt32 nBytesRead; + sal_uInt32 fszExtra; + sal_uInt32 fsize; + + hFile = CreateFile( + aFileName.getStr( ), + GENERIC_READ, + 0, + NULL, + OPEN_EXISTING, + 0, + NULL ); + if ( INVALID_HANDLE_VALUE == hFile ) + goto CLEANUP_AND_EXIT; + + fszExtra = 0; + fsize = GetFileSize( hFile, &fszExtra ); + + // empty file, error or file to big + if ( -1 == fsize || 0 == fsize || fszExtra ) + goto CLEANUP_AND_EXIT; + + hGlobal = GlobalAlloc( GMEM_MOVEABLE, fsize ); + if ( !hGlobal ) + goto CLEANUP_AND_EXIT; + + pData = GlobalLock( hGlobal ); + if ( !pData ) + goto CLEANUP_AND_EXIT; + + bRet = ReadFile( + hFile, pData, fsize, &nBytesRead, NULL ); + + if ( !bRet ) + goto CLEANUP_AND_EXIT; + + hr = CreateStreamOnHGlobal( + hGlobal, FALSE, &pIStream ); + + if ( SUCCEEDED( hr ) ) + { + hr = OleLoadPicture( + pIStream, fsize, FALSE, + __uuidof( IPicture ), (LPVOID*)&m_IPicture ); + } + +CLEANUP_AND_EXIT: + if ( hFile ) + CloseHandle( hFile ); + + if ( pData ) + GlobalUnlock( hGlobal ); + + if ( hGlobal ) + GlobalFree( hGlobal ); + + return ( SUCCEEDED( hr ) ); +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +LRESULT CALLBACK CFilePreview::WndProc( + HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + LRESULT lResult = 0; + + switch( uMsg ) + { + case WM_PAINT: + { + OSL_PRECOND( s_FilePreviewInst, "Static member not initialized" ); + + HDC hDC; + PAINTSTRUCT ps; + + hDC = BeginPaint( hWnd, &ps ); + s_FilePreviewInst->onPaint( hWnd, hDC ); + EndPaint( hWnd, &ps ); + } + break; + + // under windows 95/98 the creation of the + // hidden target request window fails if + // we don't handle this message ourself + // because the DefWindowProc returns 0 as + // a result of handling WM_NCCREATE what + // leads to a failure of CreateWindow[Ex]!!! + case WM_NCCREATE: + lResult = TRUE; + break; + + default: + return DefWindowProc( hWnd, uMsg, wParam, lParam ); + } + + return lResult; +} + + + diff --git a/fpicker/source/win32/filepicker/PreviewCtrl.hxx b/fpicker/source/win32/filepicker/PreviewCtrl.hxx new file mode 100644 index 000000000000..3e91acab4c56 --- /dev/null +++ b/fpicker/source/win32/filepicker/PreviewCtrl.hxx @@ -0,0 +1,199 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PREVIEWCTRL_HXX_ +#define _PREVIEWCTRL_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> +#include <rtl/ustring.hxx> + +#include <comdef.h> + +#include <memory> + +//--------------------------------------------- +// declaration +//--------------------------------------------- + +class CDimension +{ +public: + CDimension( ) : + m_cx( 0 ), + m_cy( 0 ) + { + } + + CDimension( sal_Int32 cx, sal_Int32 cy ) : + m_cx( cx ), + m_cy( cy ) + { + } + + sal_Int32 m_cx; + sal_Int32 m_cy; +}; + +//-------------------------------------------------- +// we use OleInitialize here because we are calling +// some Ole functions to realize the picture preview +// and we expect to be called from the main thread +// so that there will be no problem calling +// OleInitialize (the main thread should be an STA) +// When OleInitialize should fail at worst the +// preview doesn't work +//-------------------------------------------------- + +class CAutoOleInit +{ +public: + + // used to communicate ole + // initialzation failures + class COleInitException { }; + + CAutoOleInit( ) + { + HRESULT hr = OleInitialize( NULL ); + if ( FAILED( hr ) ) + throw COleInitException( ); + } + + ~CAutoOleInit( ) + { + OleUninitialize( ); + } +}; + +//--------------------------------------------- +// A simple file preview class to preview some +// common picture formats like *.gif, *jpg, etc. +// This class is not thread-safe and is +// implmented as singleton, because the class +// has only one static member to reconnect +// from callback functions +// we use a singleton-destroyer to get rid off +// the singleton instance, but this happens +// only on shutdown (unloading of the dll) - +// it's a question of taste (other solutions +// are possible) +//--------------------------------------------- + +class CFilePreview +{ +public: + // to ensure only one instance (singleton) + static CFilePreview* createInstance( + HWND aParent, + POINT ulCorner, + const CDimension& aSize, + HINSTANCE hInstance, + sal_Bool bShow = sal_True, + sal_Bool bEnabled = sal_True ); + + // sets the size of the preview window + sal_Bool SAL_CALL setSize( const CDimension& aSize ); + + // returns the CDimension of the preview + sal_Bool SAL_CALL getSize( CDimension& theSize ) const; + + // sets the position of the upper left corner + // of the preview window relative to the + // upper left corner of the parent window + sal_Bool SAL_CALL setPos( POINT ulCorner ); + + // returns the current position of the preview + // relative to the upper left corner of the + // parent window + sal_Bool SAL_CALL getPos( POINT& ulCorner ) const; + + // enables or disables the preview window + // bEnable - true the window is enabled and updates its + // view when update is called + // bEnable - false the window shows itself in disabled + // mode and does not update its view when update is + // called + void SAL_CALL enable( sal_Bool bEnable ); + + // shows the preview window + // possible values see SHOW_STATE + sal_Bool SAL_CALL show( sal_Bool bShow ); + + + // if the preview is shown and enabled + // preview of the given file will be shown + // returns true on success or false if an error + // occured (the file in not there or not accessible etc.) + virtual sal_Bool SAL_CALL update( const rtl::OUString& aFileName ); + +protected: + // clients can create instances only through the static create method + CFilePreview( + HWND aParent, + POINT ulCorner, + const CDimension& aSize, + HINSTANCE hInstance, + sal_Bool bShow = sal_True, + sal_Bool bEnabled = sal_True ); + + // only the singleton destroyer class is allowed to delete the + // singleton instance of this class + virtual ~CFilePreview( ); + + // we use the stl auto_ptr class as singleton destroyer + typedef std::auto_ptr< CFilePreview > FILEPREVIEW_SINGLETON_DESTROYER_T; + +protected: + virtual void SAL_CALL onPaint( HWND hWnd, HDC hDC ); + + sal_Bool loadFile( const rtl::OUString& aFileName ); + +private: + CAutoOleInit m_autoOleInit; + POINT m_pt; + CDimension m_dim; + HWND m_hwnd; + sal_Bool m_bEnabled; + IPicturePtr m_IPicture; + ATOM m_atomPrevWndClass; + HINSTANCE m_hInstance; + + static LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + + static CFilePreview* s_FilePreviewInst; + static FILEPREVIEW_SINGLETON_DESTROYER_T s_SingletonDestroyer; + +private: + friend FILEPREVIEW_SINGLETON_DESTROYER_T; +}; + + +#endif diff --git a/fpicker/source/win32/filepicker/SolarMutex.cxx b/fpicker/source/win32/filepicker/SolarMutex.cxx new file mode 100644 index 000000000000..71c1bda7cea7 --- /dev/null +++ b/fpicker/source/win32/filepicker/SolarMutex.cxx @@ -0,0 +1,55 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +#include <vcl/svapp.hxx> +#include <vos/mutex.hxx> +#include <osl/thread.hxx> + +int ReleaseSolarMutexOnMainThreadContext(unsigned nThreadId) +{ + int nAcquireCount = 0; + vos::IMutex& rSolarMutex = Application::GetSolarMutex(); + vos::OThread::TThreadIdentifier nMainThreadId = Application::GetMainThreadIdentifier(); + + if ( nMainThreadId == nThreadId ) + { + ::vos::IMutex& rMutex = Application::GetSolarMutex(); + if ( rMutex.tryToAcquire() ) + nAcquireCount = Application::ReleaseSolarMutex() - 1; + } + + return nAcquireCount; +} + +void AcquireSolarMutex(int nAcquireCount) +{ + if ( nAcquireCount ) + Application::AcquireSolarMutex( nAcquireCount ); +} diff --git a/fpicker/source/win32/filepicker/SolarMutex.hxx b/fpicker/source/win32/filepicker/SolarMutex.hxx new file mode 100644 index 000000000000..b5897d8ea1bb --- /dev/null +++ b/fpicker/source/win32/filepicker/SolarMutex.hxx @@ -0,0 +1,30 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +int ReleaseSolarMutexOnMainThreadContext(unsigned nThreadId); + +void AcquireSolarMutex(int nAcquireCount); diff --git a/fpicker/source/win32/filepicker/VistaFilePicker.cxx b/fpicker/source/win32/filepicker/VistaFilePicker.cxx new file mode 100644 index 000000000000..14b185ee2688 --- /dev/null +++ b/fpicker/source/win32/filepicker/VistaFilePicker.cxx @@ -0,0 +1,725 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#ifdef _MSC_VER +#pragma warning (disable:4917) +#endif + +#include "VistaFilePicker.hxx" +#include "WinFileOpenImpl.hxx" +#include "..\misc\WinImplHelper.hxx" +#include "shared.hxx" + +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerListener.hpp> +#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> + +#include <cppuhelper/interfacecontainer.h> +#include <comphelper/configurationhelper.hxx> +#include <osl/diagnose.h> +#include <osl/mutex.hxx> +#include <osl/file.hxx> +#include <tchar.h> + +#ifdef _MSC_VER +#pragma warning (push, 1) +#endif +#include <shlobj.h> +#ifdef _MSC_VER +#pragma warning (pop) +#endif + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +namespace css = ::com::sun::star; + +namespace fpicker{ +namespace win32{ +namespace vista{ + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +#define FILE_PICKER_DLL_NAME TEXT("fps.dll") + +//------------------------------------------------------------------------ +// helper functions +//------------------------------------------------------------------------ + +namespace +{ + // controling event notifications + const bool STARTUP_SUSPENDED = true; + const bool STARTUP_ALIVE = false; + + css::uno::Sequence< ::rtl::OUString > SAL_CALL VistaFilePicker_getSupportedServiceNames() + { + css::uno::Sequence< ::rtl::OUString > aRet(2); + aRet[0] = ::rtl::OUString::createFromAscii("com.sun.star.ui.dialogs.FilePicker"); + aRet[1] = ::rtl::OUString::createFromAscii("com.sun.star.ui.dialogs.SystemFilePicker"); + return aRet; + } +} + +//----------------------------------------------------------------------------------------- +#define ENABLE_LOGGING + +#define LOGFILE_VISTA "c:\\temp\\vistafiledialog.log" + +#ifdef ENABLE_LOGGING + + #define LOG_FILE(PARAM_MESSAGE) \ + { \ + FILE* pFile = fopen(LOGFILE_VISTA, "a"); \ + fprintf(pFile, PARAM_MESSAGE); \ + fclose(pFile); \ + } + + #define LOG_FILE_1_PARAM(PARAM_MESSAGE, PARAM_1) \ + { \ + FILE* pFile = fopen(LOGFILE_VISTA, "a"); \ + fprintf(pFile, PARAM_MESSAGE, PARAM_1); \ + fclose(pFile); \ + } + + #define LOG_FILE_2_PARAM(PARAM_MESSAGE, PARAM_1, PARAM_2) \ + { \ + FILE* pFile = fopen(LOGFILE_VISTA, "a"); \ + fprintf(pFile, PARAM_MESSAGE, PARAM_1, PARAM_2); \ + fclose(pFile); \ + } + +#else + + #define LOG_FILE(PARAM_MESSAGE) + #define LOG_FILE_1_PARAM(PARAM_MESSAGE, PARAM_1) + #define LOG_FILE_2_PARAM(PARAM_MESSAGE, PARAM_1, PARAM_2) + +#endif + +//----------------------------------------------------------------------------------------- +#define VISTAFILEDIALOG_CHECKED_COMCALL(PARAM_CODE, PARAM_LOGMESSAGE, PARAM_ERRORMESSAGE) \ + { \ + HRESULT aResult; \ + VISTAFILEDIALOG_CHECKED_COMCALL_WITH_RETURN(aResult, PARAM_CODE, PARAM_LOGMESSAGE, PARAM_ERRORMESSAGE) \ + } + +//----------------------------------------------------------------------------------------- +#define VISTAFILEDIALOG_CHECKED_COMCALL_WITH_RETURN(RETURN_HR, PARAM_CODE, PARAM_LOGMESSAGE, PARAM_ERRORMESSAGE) \ + { \ + LOG_FILE(PARAM_LOGMESSAGE) \ + RETURN_HR = PARAM_CODE; \ + if ( FAILED(RETURN_HR) ) \ + { \ + LOG_FILE_1_PARAM("will throw exception for checked COM call:\n%s", PARAM_ERRORMESSAGE) \ + throw css::uno::RuntimeException( \ + ::rtl::OUString::createFromAscii(PARAM_ERRORMESSAGE), \ + css::uno::Reference< css::ui::dialogs::XFilePicker >()); \ + } \ + } + + + +//----------------------------------------------------------------------------------------- +VistaFilePicker::VistaFilePicker(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR) + : TVistaFilePickerBase (m_aMutex ) + , m_xSMGR (xSMGR ) + , m_rDialog (new VistaFilePickerImpl()) + , m_aAsyncExecute (m_rDialog ) + , m_nFilePickerThreadId (0 ) + , m_bInitialized (false ) +{ +} + +//----------------------------------------------------------------------------------------- +VistaFilePicker::~VistaFilePicker() +{ +} + +//------------------------------------------------------------------------------------ +void SAL_CALL VistaFilePicker::addFilePickerListener(const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener) + throw(css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_ADD_PICKER_LISTENER); + rRequest->setArgument(PROP_PICKER_LISTENER, xListener); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); +} + +//----------------------------------------------------------------------------------------- +void SAL_CALL VistaFilePicker::removeFilePickerListener(const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener ) + throw(css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_REMOVE_PICKER_LISTENER); + rRequest->setArgument(PROP_PICKER_LISTENER, xListener); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); +} + +// ------------------------------------------------- +void SAL_CALL VistaFilePicker::disposing(const css::lang::EventObject& /*aEvent*/) + throw(css::uno::RuntimeException) +{ +} + +//------------------------------------------------------------------------------------ +void SAL_CALL VistaFilePicker::setMultiSelectionMode(::sal_Bool bMode) + throw(css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_SET_MULTISELECTION_MODE); + rRequest->setArgument(PROP_MULTISELECTION_MODE, bMode); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); +} + +//----------------------------------------------------------------------------------------- +void SAL_CALL VistaFilePicker::setTitle(const ::rtl::OUString& sTitle) + throw(css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_SET_TITLE); + rRequest->setArgument(PROP_TITLE, sTitle); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); +} + +//----------------------------------------------------------------------------------------- +void SAL_CALL VistaFilePicker::appendFilter(const ::rtl::OUString& sTitle , + const ::rtl::OUString& sFilter) + throw(css::lang::IllegalArgumentException, + css::uno::RuntimeException ) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_APPEND_FILTER); + rRequest->setArgument(PROP_FILTER_TITLE, sTitle ); + rRequest->setArgument(PROP_FILTER_VALUE, sFilter); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); +} + +//----------------------------------------------------------------------------------------- +void SAL_CALL VistaFilePicker::setCurrentFilter(const ::rtl::OUString& sTitle) + throw(css::lang::IllegalArgumentException, + css::uno::RuntimeException ) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_SET_CURRENT_FILTER); + rRequest->setArgument(PROP_FILTER_TITLE, sTitle); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); +} + +//----------------------------------------------------------------------------------------- +::rtl::OUString SAL_CALL VistaFilePicker::getCurrentFilter() + throw(css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_GET_CURRENT_FILTER); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::BLOCKED); + + const ::rtl::OUString sTitle = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, ::rtl::OUString()); + return sTitle; +} + +//----------------------------------------------------------------------------------------- +void SAL_CALL VistaFilePicker::appendFilterGroup(const ::rtl::OUString& /*sGroupTitle*/, + const css::uno::Sequence< css::beans::StringPair >& lFilters ) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ) +{ + ::sal_Int32 c = lFilters.getLength(); + ::sal_Int32 i = 0; + for (i=0; i<c; ++i) + { + const css::beans::StringPair& rFilter = lFilters[i]; + appendFilter(rFilter.First, rFilter.Second); + } +} + +//----------------------------------------------------------------------------------------- +void SAL_CALL VistaFilePicker::setDefaultName(const ::rtl::OUString& sName ) + throw(css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_SET_DEFAULT_NAME); + rRequest->setArgument(PROP_FILENAME, sName); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); +} + +//----------------------------------------------------------------------------------------- +void SAL_CALL VistaFilePicker::setDisplayDirectory(const ::rtl::OUString& sDirectory) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ) +{ + const ::rtl::OUString aPackage( RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common/")); + const ::rtl::OUString aRelPath( RTL_CONSTASCII_USTRINGPARAM("Path/Info")); + const ::rtl::OUString aKey( RTL_CONSTASCII_USTRINGPARAM("WorkPathChanged")); + + css::uno::Any aValue = ::comphelper::ConfigurationHelper::readDirectKey( + m_xSMGR, aPackage, aRelPath, aKey, ::comphelper::ConfigurationHelper::E_READONLY); + + bool bChanged(false); + if (( aValue >>= bChanged ) && bChanged ) + { + ::comphelper::ConfigurationHelper::writeDirectKey( + m_xSMGR, aPackage, aRelPath, aKey, css::uno::makeAny(false), ::comphelper::ConfigurationHelper::E_STANDARD); + } + + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_SET_DIRECTORY); + rRequest->setArgument(PROP_DIRECTORY, sDirectory); + rRequest->setArgument(PROP_FORCE, bChanged); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); +} + +//----------------------------------------------------------------------------------------- +::rtl::OUString SAL_CALL VistaFilePicker::getDisplayDirectory() + throw(css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_GET_DIRECTORY); + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); + const ::rtl::OUString sDirectory = rRequest->getArgumentOrDefault(PROP_FILENAME, ::rtl::OUString()); + + return sDirectory; +} + +//----------------------------------------------------------------------------------------- +// @deprecated cant be supported any longer ... see IDL description for further details +css::uno::Sequence< ::rtl::OUString > SAL_CALL VistaFilePicker::getFiles() + throw(css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_GET_SELECTED_FILES); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::BLOCKED); + + const css::uno::Sequence< ::rtl::OUString > lFiles = rRequest->getArgumentOrDefault(PROP_SELECTED_FILES, css::uno::Sequence< ::rtl::OUString >()); + m_lLastFiles = lFiles; + return lFiles; +} + +//----------------------------------------------------------------------------------------- +css::uno::Sequence< ::rtl::OUString > SAL_CALL VistaFilePicker::getSelectedFiles() + throw(css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_GET_SELECTED_FILES); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::BLOCKED); + + const css::uno::Sequence< ::rtl::OUString > lFiles = rRequest->getArgumentOrDefault(PROP_SELECTED_FILES, css::uno::Sequence< ::rtl::OUString >()); + m_lLastFiles = lFiles; + return lFiles; +} + +//----------------------------------------------------------------------------------------- +::sal_Int16 SAL_CALL VistaFilePicker::execute() + throw(css::uno::RuntimeException) +{ + bool bInitialized(false); + { + osl::MutexGuard aGuard(m_aMutex); + bInitialized = m_bInitialized; + } + + if ( !bInitialized ) + { + sal_Int16 nTemplateDescription = css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE; + css::uno::Sequence < css::uno::Any > aInitArguments(1); + aInitArguments[0] <<= nTemplateDescription; + initialize(aInitArguments); + } + + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_SHOW_DIALOG_MODAL); + + // if we want to show a modal window, the calling thread needs to process messages + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::PROCESS_MESSAGES); + + const ::sal_Bool bOK = rRequest->getArgumentOrDefault(PROP_DIALOG_SHOW_RESULT, (::sal_Bool)sal_False ); + m_lLastFiles = rRequest->getArgumentOrDefault(PROP_SELECTED_FILES , css::uno::Sequence< ::rtl::OUString >()); + + ::sal_Int16 nResult = css::ui::dialogs::ExecutableDialogResults::CANCEL; + if (bOK) + nResult = css::ui::dialogs::ExecutableDialogResults::OK; + return nResult; +} + +//------------------------------------------------------------------------------------ +// XFilePicker functions +//------------------------------------------------------------------------------------ + +void SAL_CALL VistaFilePicker::setValue( ::sal_Int16 nControlId , + ::sal_Int16 nControlAction, + const css::uno::Any& aValue ) + throw(css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_SET_CONTROL_VALUE); + rRequest->setArgument(PROP_CONTROL_ID , nControlId ); + rRequest->setArgument(PROP_CONTROL_ACTION, nControlAction); + rRequest->setArgument(PROP_CONTROL_VALUE , aValue ); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +css::uno::Any SAL_CALL VistaFilePicker::getValue(::sal_Int16 nControlId , + ::sal_Int16 nControlAction) + throw(css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_GET_CONTROL_VALUE); + rRequest->setArgument(PROP_CONTROL_ID , nControlId ); + rRequest->setArgument(PROP_CONTROL_ACTION, nControlAction); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::BLOCKED); + const css::uno::Any aValue = rRequest->getArgumentOrDefault(PROP_CONTROL_VALUE, css::uno::Any()); + return aValue; +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL VistaFilePicker::enableControl(::sal_Int16 nControlId, + ::sal_Bool bEnable ) + throw(css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_ENABLE_CONTROL); + rRequest->setArgument(PROP_CONTROL_ID , nControlId); + rRequest->setArgument(PROP_CONTROL_ENABLE, bEnable ); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL VistaFilePicker::setLabel( ::sal_Int16 nControlId, + const ::rtl::OUString& sLabel ) + throw (css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_SET_CONTROL_LABEL); + rRequest->setArgument(PROP_CONTROL_ID , nControlId); + rRequest->setArgument(PROP_CONTROL_LABEL, sLabel ); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +::rtl::OUString SAL_CALL VistaFilePicker::getLabel(::sal_Int16 nControlId) + throw (css::uno::RuntimeException) +{ + RequestRef rRequest(new Request()); + rRequest->setRequest (VistaFilePickerImpl::E_GET_CONTROL_LABEL); + rRequest->setArgument(PROP_CONTROL_ID, nControlId); + + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::BLOCKED); + const ::rtl::OUString sLabel = rRequest->getArgumentOrDefault(PROP_CONTROL_LABEL, ::rtl::OUString()); + return sLabel; +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +css::uno::Sequence< ::sal_Int16 > SAL_CALL VistaFilePicker::getSupportedImageFormats() + throw (css::uno::RuntimeException) +{ + return css::uno::Sequence< sal_Int16 >(); +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +sal_Int32 SAL_CALL VistaFilePicker::getTargetColorDepth() + throw (css::uno::RuntimeException) +{ + return 0; +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +sal_Int32 SAL_CALL VistaFilePicker::getAvailableWidth() + throw (css::uno::RuntimeException) +{ + return 0; +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +sal_Int32 SAL_CALL VistaFilePicker::getAvailableHeight() + throw (css::uno::RuntimeException) +{ + return 0; +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +void SAL_CALL VistaFilePicker::setImage( sal_Int16 /*nImageFormat*/, + const css::uno::Any& /*aImage */) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ) +{ +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +sal_Bool SAL_CALL VistaFilePicker::setShowState(sal_Bool /*bShowState*/) + throw (css::uno::RuntimeException) +{ + return sal_False; +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +sal_Bool SAL_CALL VistaFilePicker::getShowState() + throw (css::uno::RuntimeException) +{ + return sal_False; +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +void SAL_CALL VistaFilePicker::initialize(const css::uno::Sequence< css::uno::Any >& lArguments) + throw(css::uno::Exception , + css::uno::RuntimeException) +{ + /* + // called twice ? + if (m_pDlg) + throw css::uno::Exception( + ::rtl::OUString::createFromAscii( "XInitialization::initialize() called twice." ), + static_cast< css::ui::dialogs::XFilePicker* >( this )); + */ + + if (lArguments.getLength() < 1) + throw css::lang::IllegalArgumentException( + ::rtl::OUString::createFromAscii( "XInitialization::initialize() called without arguments." ), + static_cast< css::ui::dialogs::XFilePicker2* >( this ), + 1); + + sal_Int32 nTemplate = -1; + lArguments[0] >>= nTemplate; + + ::sal_Bool bFileOpenDialog = sal_True; + ::sal_Int32 nFeatures = 0; + + switch(nTemplate) + { + case css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE : + { + bFileOpenDialog = sal_True; + } + break; + + case css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE : + { + bFileOpenDialog = sal_False; + } + break; + + case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD : + { + bFileOpenDialog = sal_False; + nFeatures |= FEATURE_AUTOEXTENSION; + nFeatures |= FEATURE_PASSWORD; + } + break; + + case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS : + { + bFileOpenDialog = sal_False; + nFeatures |= FEATURE_AUTOEXTENSION; + nFeatures |= FEATURE_PASSWORD; + nFeatures |= FEATURE_FILTEROPTIONS; + } + break; + + case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION : + { + bFileOpenDialog = sal_False; + nFeatures |= FEATURE_AUTOEXTENSION; + nFeatures |= FEATURE_SELECTION; + } + break; + + case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE : + { + bFileOpenDialog = sal_False; + nFeatures |= FEATURE_AUTOEXTENSION; + nFeatures |= FEATURE_TEMPLATE; + } + break; + + case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE : + { + bFileOpenDialog = sal_True; + nFeatures |= FEATURE_LINK; + nFeatures |= FEATURE_PREVIEW; + nFeatures |= FEATURE_IMAGETEMPLATE; + } + break; + + case css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY : + { + bFileOpenDialog = sal_True; + nFeatures |= FEATURE_PLAY; + } + break; + + case css::ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION : + { + bFileOpenDialog = sal_True; + nFeatures |= FEATURE_READONLY; + nFeatures |= FEATURE_VERSION; + } + break; + + case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW : + { + bFileOpenDialog = sal_True; + nFeatures |= FEATURE_LINK; + nFeatures |= FEATURE_PREVIEW; + } + break; + + case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION : + { + bFileOpenDialog = sal_False; + nFeatures |= FEATURE_AUTOEXTENSION; + } + break; + } + + RequestRef rRequest(new Request()); + if (bFileOpenDialog) + rRequest->setRequest (VistaFilePickerImpl::E_CREATE_OPEN_DIALOG); + else + rRequest->setRequest (VistaFilePickerImpl::E_CREATE_SAVE_DIALOG); + rRequest->setArgument(PROP_FEATURES, nFeatures); + rRequest->setArgument(PROP_TEMPLATE_DESCR, nTemplate); + if ( ! m_aAsyncExecute.isRunning()) + m_aAsyncExecute.create(); + m_aAsyncExecute.triggerRequestThreadAware(rRequest, AsyncRequests::NON_BLOCKED); + + { + osl::MutexGuard aGuard(m_aMutex); + m_bInitialized = true; + } +} + +//------------------------------------------------------------------------------------ +// +//------------------------------------------------------------------------------------ + +void SAL_CALL VistaFilePicker::cancel() + throw(css::uno::RuntimeException) +{ +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +::rtl::OUString SAL_CALL VistaFilePicker::getImplementationName() + throw(css::uno::RuntimeException) +{ + return ::rtl::OUString::createFromAscii("com.sun.star.comp.fpicker.VistaFileDialog"); +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +sal_Bool SAL_CALL VistaFilePicker::supportsService(const ::rtl::OUString& sServiceName) + throw(css::uno::RuntimeException ) +{ + css::uno::Sequence< ::rtl::OUString > lSupportedServicesNames = VistaFilePicker_getSupportedServiceNames(); + + for (sal_Int32 n = lSupportedServicesNames.getLength(); n--;) + if (lSupportedServicesNames[n].compareTo(sServiceName) == 0) + return sal_True; + + return sal_False; +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +css::uno::Sequence< ::rtl::OUString > SAL_CALL VistaFilePicker::getSupportedServiceNames() + throw(css::uno::RuntimeException) +{ + return VistaFilePicker_getSupportedServiceNames(); +} + +} // namespace vista +} // namespace win32 +} // namespace fpicker diff --git a/fpicker/source/win32/filepicker/VistaFilePicker.hxx b/fpicker/source/win32/filepicker/VistaFilePicker.hxx new file mode 100644 index 000000000000..2b690c220c18 --- /dev/null +++ b/fpicker/source/win32/filepicker/VistaFilePicker.hxx @@ -0,0 +1,315 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FPICKER_WIN32_VISTA_FILEPICKER_HXX +#define FPICKER_WIN32_VISTA_FILEPICKER_HXX + +//----------------------------------------------------------------------------- +// includes +//----------------------------------------------------------------------------- + +#include "asyncrequests.hxx" +#include "VistaFilePickerImpl.hxx" +#include "VistaFilePickerEventHandler.hxx" + +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/ui/dialogs/XFilePicker.hpp> +#include <com/sun/star/ui/dialogs/XFilePicker2.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp> +#include <com/sun/star/ui/dialogs/XFilterManager.hpp> +#include <com/sun/star/ui/dialogs/XFilterGroupManager.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> +#include <com/sun/star/ui/dialogs/XFilePreview.hpp> +#include <com/sun/star/util/XCancellable.hpp> + +#include <cppuhelper/compbase10.hxx> +#include <cppuhelper/basemutex.hxx> +#include <rtl/ustring.hxx> + +//----------------------------------------------------------------------------- +// namespace +//----------------------------------------------------------------------------- + +#ifdef css + #error "Clash on using CSS as namespace define." +#else + #define css ::com::sun::star +#endif + +namespace fpicker{ +namespace win32{ +namespace vista{ + +//----------------------------------------------------------------------------- +// types +//----------------------------------------------------------------------------- + +typedef ::cppu::WeakComponentImplHelper10< + css::ui::dialogs::XFilePicker2, + css::ui::dialogs::XFilterManager, + css::ui::dialogs::XFilterGroupManager, + css::ui::dialogs::XFilePickerControlAccess, + css::ui::dialogs::XFilePickerNotifier, + css::ui::dialogs::XFilePreview, + css::lang::XInitialization, + css::util::XCancellable, + css::lang::XEventListener, + css::lang::XServiceInfo > TVistaFilePickerBase; + +//----------------------------------------------------------------------------- +/** Implements the XFilePicker & friends interface(s) + for Windos Vista and upcoming versions. + + Note: This will be an UNO wrapper for the real file picker + implementation oly. The real implementation is done in class + VistaFilePickerImpl. + */ +class VistaFilePicker : public ::cppu::BaseMutex + , public TVistaFilePickerBase +{ +public: + + //------------------------------------------------------------------------------------ + // ctor/dtor + //------------------------------------------------------------------------------------ + + VistaFilePicker( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR ); + virtual ~VistaFilePicker(); + + //------------------------------------------------------------------------------------ + // XFilePickerNotifier + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL addFilePickerListener( const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener ) + throw( css::uno::RuntimeException ); + + virtual void SAL_CALL removeFilePickerListener( const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener ) + throw( css::uno::RuntimeException ); + + //------------------------------------------------------------------------------------ + // XExecutableDialog functions + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL setTitle( const ::rtl::OUString& sTitle ) + throw( css::uno::RuntimeException ); + + virtual sal_Int16 SAL_CALL execute( ) + throw( css::uno::RuntimeException ); + + //------------------------------------------------------------------------------------ + // XFilePicker functions + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL setMultiSelectionMode( sal_Bool bMode ) + throw( css::uno::RuntimeException ); + + virtual void SAL_CALL setDefaultName( const ::rtl::OUString& sName ) + throw( css::uno::RuntimeException ); + + virtual void SAL_CALL setDisplayDirectory( const ::rtl::OUString& sDirectory ) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ); + + virtual ::rtl::OUString SAL_CALL getDisplayDirectory( ) + throw( css::uno::RuntimeException ); + + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getFiles( ) + throw( css::uno::RuntimeException ); + + //------------------------------------------------------------------------------------ + // XFilePicker2 functions + //------------------------------------------------------------------------------------ + + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSelectedFiles( ) + throw( css::uno::RuntimeException ); + + //------------------------------------------------------------------------------------ + // XFilterManager functions + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL appendFilter( const ::rtl::OUString& sTitle , + const ::rtl::OUString& sFilter ) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ); + + virtual void SAL_CALL setCurrentFilter( const ::rtl::OUString& sTitle ) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ); + + virtual ::rtl::OUString SAL_CALL getCurrentFilter( ) + throw( css::uno::RuntimeException ); + + //------------------------------------------------------------------------------------ + // XFilterGroupManager functions + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL appendFilterGroup( const ::rtl::OUString& sGroupTitle, + const css::uno::Sequence< css::beans::StringPair >& lFilters ) + throw (css::lang::IllegalArgumentException, + css::uno::RuntimeException ); + + //------------------------------------------------------------------------------------ + // XFilePickerControlAccess functions + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL setValue( sal_Int16 nControlId , + sal_Int16 nControlAction, + const css::uno::Any& aValue ) + throw (css::uno::RuntimeException); + + virtual css::uno::Any SAL_CALL getValue( sal_Int16 nControlId , + sal_Int16 nControlAction ) + throw (css::uno::RuntimeException); + + virtual void SAL_CALL enableControl( sal_Int16 nControlId, + sal_Bool bEnable ) + throw(css::uno::RuntimeException ); + + virtual void SAL_CALL setLabel( sal_Int16 nControlId, + const ::rtl::OUString& sLabel ) + throw (css::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getLabel( sal_Int16 nControlId ) + throw (css::uno::RuntimeException); + + //------------------------------------------------ + // XFilePreview + //------------------------------------------------ + + virtual css::uno::Sequence< sal_Int16 > SAL_CALL getSupportedImageFormats( ) + throw (css::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getTargetColorDepth( ) + throw (css::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getAvailableWidth( ) + throw (css::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getAvailableHeight( ) + throw (css::uno::RuntimeException); + + virtual void SAL_CALL setImage( sal_Int16 nImageFormat, + const css::uno::Any& aImage ) + throw (css::lang::IllegalArgumentException, css::uno::RuntimeException); + + virtual sal_Bool SAL_CALL setShowState( sal_Bool bShowState ) + throw (css::uno::RuntimeException); + + virtual sal_Bool SAL_CALL getShowState( ) + throw (css::uno::RuntimeException); + + //------------------------------------------------ + // XInitialization + //------------------------------------------------ + + virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& lArguments ) + throw(css::uno::Exception , + css::uno::RuntimeException); + + //------------------------------------------------ + // XCancellable + //------------------------------------------------ + + virtual void SAL_CALL cancel( ) + throw(css::uno::RuntimeException); + + //------------------------------------------------ + // XEventListener + //------------------------------------------------ + + virtual void SAL_CALL disposing( const css::lang::EventObject& aEvent ) + throw(css::uno::RuntimeException); + + //------------------------------------------------ + // XServiceInfo + //------------------------------------------------ + + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw(css::uno::RuntimeException); + + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(css::uno::RuntimeException); + + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw(css::uno::RuntimeException); + + /* + //------------------------------------------------------------------------------------ + // FilePicker Event functions + //------------------------------------------------------------------------------------ + + void SAL_CALL fileSelectionChanged(const css::ui::dialogs::FilePickerEvent& aEvent ); + void SAL_CALL directoryChanged(const css::ui::dialogs::FilePickerEvent& aEvent ); + ::rtl::OUString SAL_CALL helpRequested(const css::ui::dialogs::FilePickerEvent& aEvent ) const; + void SAL_CALL controlStateChanged(const css::ui::dialogs::FilePickerEvent& aEvent ); + void SAL_CALL dialogSizeChanged( ); + + bool startupEventNotification(bool bStartupSuspended); + void shutdownEventNotification(); + void suspendEventNotification(); + void resumeEventNotification(); + */ + + private: + + // prevent copy and assignment + VistaFilePicker( const VistaFilePicker& ); + VistaFilePicker& operator=( const VistaFilePicker& ); + + using WeakComponentImplHelperBase::disposing; + + private: + + //--------------------------------------------------------------------- + /// service manager to create own used uno services + css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR; + + //--------------------------------------------------------------------- + css::uno::Sequence< ::rtl::OUString > m_lLastFiles; + + //--------------------------------------------------------------------- + /** execute the COM dialog within a STA thread + * Must be used on the heap ... because it's implemented as OSL thread .-) + */ + RequestHandlerRef m_rDialog; + AsyncRequests m_aAsyncExecute; + + //--------------------------------------------------------------------- + oslThreadIdentifier m_nFilePickerThreadId; + + bool m_bInitialized; +}; + +} // namespace vista +} // namespace win32 +} // namespace fpicker + +#undef css + +#endif // FPICKER_WIN32_VISTA_FILEPICKER_HXX diff --git a/fpicker/source/win32/filepicker/VistaFilePickerEventHandler.cxx b/fpicker/source/win32/filepicker/VistaFilePickerEventHandler.cxx new file mode 100644 index 000000000000..2fadaa6bfdff --- /dev/null +++ b/fpicker/source/win32/filepicker/VistaFilePickerEventHandler.cxx @@ -0,0 +1,507 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include "VistaFilePickerEventHandler.hxx" +#include "asyncrequests.hxx" + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/embed/XStorage.hpp> +#include <com/sun/star/document/XDocumentRevisionListPersistence.hpp> +#include <com/sun/star/util/RevisionTag.hpp> +#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> + +#include <comphelper/processfactory.hxx> +#include <comphelper/storagehelper.hxx> +//#include <tools/urlobj.hxx> +//#include <unotools/ucbhelper.hxx> + +#include <osl/file.hxx> + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +namespace css = ::com::sun::star; + +namespace fpicker{ +namespace win32{ +namespace vista{ + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +//----------------------------------------------------------------------------------------- +VistaFilePickerEventHandler::VistaFilePickerEventHandler(IVistaFilePickerInternalNotify* pInternalNotify) + : m_nRefCount (0 ) + , m_nListenerHandle (0 ) + , m_pDialog ( ) + , m_lListener (m_aMutex) + , m_pInternalNotify (pInternalNotify) +{ +} + +//----------------------------------------------------------------------------------------- +VistaFilePickerEventHandler::~VistaFilePickerEventHandler() +{ +} + +//----------------------------------------------------------------------------------------- +HRESULT STDMETHODCALLTYPE VistaFilePickerEventHandler::QueryInterface(REFIID rIID , + void** ppObject) +{ + *ppObject=NULL; + + if ( rIID == IID_IUnknown ) + *ppObject = (IUnknown*)(IFileDialogEvents*)this; + + if ( rIID == IID_IFileDialogEvents ) + *ppObject = (IFileDialogEvents*)this; + + if ( rIID == IID_IFileDialogControlEvents ) + *ppObject = (IFileDialogControlEvents*)this; + + if ( *ppObject != NULL ) + { + ((IUnknown*)*ppObject)->AddRef(); + return S_OK; + } + + return E_NOINTERFACE; +} + +//----------------------------------------------------------------------------------------- +ULONG STDMETHODCALLTYPE VistaFilePickerEventHandler::AddRef() +{ + return osl_incrementInterlockedCount(&m_nRefCount); +} + +//----------------------------------------------------------------------------------------- +ULONG STDMETHODCALLTYPE VistaFilePickerEventHandler::Release() +{ + ULONG nReturn = --m_nRefCount; + if ( m_nRefCount == 0 ) + delete this; + + return nReturn; +} + +//----------------------------------------------------------------------------------------- +STDMETHODIMP VistaFilePickerEventHandler::OnFileOk(IFileDialog* /*pDialog*/) +{ + return E_NOTIMPL; +} + +//----------------------------------------------------------------------------------------- +STDMETHODIMP VistaFilePickerEventHandler::OnFolderChanging(IFileDialog* /*pDialog*/, + IShellItem* /*pFolder*/) +{ + return E_NOTIMPL; +} + +//----------------------------------------------------------------------------------------- +STDMETHODIMP VistaFilePickerEventHandler::OnFolderChange(IFileDialog* /*pDialog*/) +{ + impl_sendEvent(E_DIRECTORY_CHANGED, 0); + return S_OK; +} + +//----------------------------------------------------------------------------- +::rtl::OUString lcl_getURLFromShellItem2 (IShellItem* pItem) +{ + LPOLESTR pStr = NULL; + ::rtl::OUString sURL; + + SIGDN eConversion = SIGDN_FILESYSPATH; + HRESULT hr = pItem->GetDisplayName ( eConversion, &pStr ); + + if ( FAILED(hr) ) + { + eConversion = SIGDN_URL; + hr = pItem->GetDisplayName ( eConversion, &pStr ); + + if ( FAILED(hr) ) + return ::rtl::OUString(); + + sURL = ::rtl::OUString(reinterpret_cast<sal_Unicode*>(pStr)); + } + else + { + ::osl::FileBase::getFileURLFromSystemPath( reinterpret_cast<sal_Unicode*>(pStr), sURL ); + } + + CoTaskMemFree (pStr); + return sURL; +} + +//----------------------------------------------------------------------------------------- +void lcl_updateVersionListDirectly(IFileDialog* pDialog) +{ + static const ::rtl::OUString SERVICENAME_REVISIONPERSISTENCE = ::rtl::OUString::createFromAscii("com.sun.star.document.DocumentRevisionListPersistence"); + static const ::sal_Int16 CONTROL_VERSIONLIST = css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION; + + TFileDialog iDialog (pDialog); + TFileOpenDialog iOpen ; + TFileDialogCustomize iCustomize; + +#ifdef __MINGW32__ + iDialog->QueryInterface(IID_IFileOpenDialog, (void**)(&iOpen)); + iDialog->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustomize)); +#else + iDialog.query(&iOpen ); + iDialog.query(&iCustomize); +#endif + + // make sure version list match to the current selection always ... + // at least an empty version list will be better then the wrong one .-) + iCustomize->RemoveAllControlItems(CONTROL_VERSIONLIST); + + HRESULT hResult = E_FAIL; + ComPtr< IShellItemArray > iItems; + ComPtr< IShellItem > iItem; + + if (iOpen.is()) + { + hResult = iOpen->GetSelectedItems(&iItems); + if (FAILED(hResult)) + return; + + DWORD nCount; + hResult = iItems->GetCount(&nCount); + if ( FAILED(hResult) ) + return; + + // we can show one version list only within control + if (nCount != 1) + return; + + hResult = iItems->GetItemAt(0, &iItem); + } + else + if (iDialog.is()) + hResult = iDialog->GetCurrentSelection(&iItem); + + if ( FAILED(hResult) ) + return; + + const ::rtl::OUString sURL = lcl_getURLFromShellItem2(iItem); + if (sURL.getLength() < 1) + return; +/* + INetURLObject aURL(sURL); + if (aURL.GetProtocol() != INET_PROT_FILE) + return; + + ::rtl::OUString sMain = aURL.GetMainURL(INetURLObject::NO_DECODE); + if ( ! ::utl::UCBContentHelper::IsDocument(sURL)) + return; +*/ + try + { + css::uno::Reference< css::embed::XStorage > xStorage = ::comphelper::OStorageHelper::GetStorageFromURL(sURL, css::embed::ElementModes::READ); + if ( ! xStorage.is() ) + return; + + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory(); + css::uno::Reference< css::document::XDocumentRevisionListPersistence > xReader (xSMGR->createInstance(SERVICENAME_REVISIONPERSISTENCE), css::uno::UNO_QUERY_THROW); + css::uno::Sequence< css::util::RevisionTag > lVersions = xReader->load(xStorage); + + for (::sal_Int32 i=0; i<lVersions.getLength(); ++i) + { + const css::util::RevisionTag& aTag = lVersions[i]; + iCustomize->AddControlItem(CONTROL_VERSIONLIST, i, reinterpret_cast<LPCTSTR>(aTag.Identifier.getStr())); + } + iCustomize->SetSelectedControlItem(CONTROL_VERSIONLIST, 0); + } + catch(const css::uno::Exception&) + {} +} + +//----------------------------------------------------------------------------------------- +STDMETHODIMP VistaFilePickerEventHandler::OnSelectionChange(IFileDialog* /*pDialog*/) +{ + impl_sendEvent(E_FILE_SELECTION_CHANGED, 0); + //lcl_updateVersionListDirectly(pDialog); + return S_OK; +} + +//----------------------------------------------------------------------------------------- +STDMETHODIMP VistaFilePickerEventHandler::OnShareViolation(IFileDialog* /*pDialog*/ , + + IShellItem* /*pItem*/ , + + FDE_SHAREVIOLATION_RESPONSE* /*pResponse*/) +{ + impl_sendEvent(E_CONTROL_STATE_CHANGED, css::ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER); + return S_OK; +} + +//----------------------------------------------------------------------------------------- +STDMETHODIMP VistaFilePickerEventHandler::OnTypeChange(IFileDialog* /*pDialog*/) +{ + /* + IFileDialogCustomize *iCustomize; + pDialog->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustomize)); + + BOOL bValue = FALSE; + HRESULT hResult = iCustomize->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue); + + if ( bValue ) + { + UINT nIndex; + + pDialog->GetFileTypeIndex( &nIndex ); + + LPCWSTR lpFilterExt = lFilters[nIndex].pszSpec; + + lpFilterExt = wcschr( lpFilterExt, '.' ); + if ( lpFilterExt ) + lpFilterExt++; + pDialog->SetDefaultExtension( lpFilterExt ); + } + return S_OK; + + */ + + impl_sendEvent(E_CONTROL_STATE_CHANGED, css::ui::dialogs::CommonFilePickerElementIds::LISTBOX_FILTER); + + return S_OK; +} + +//----------------------------------------------------------------------------------------- +STDMETHODIMP VistaFilePickerEventHandler::OnOverwrite(IFileDialog* /*pDialog*/ , + IShellItem* /*pItem*/ , + FDE_OVERWRITE_RESPONSE* /*pResponse*/) +{ + return E_NOTIMPL; +} + +//----------------------------------------------------------------------------------------- +STDMETHODIMP VistaFilePickerEventHandler::OnItemSelected(IFileDialogCustomize* /*pCustomize*/, + + DWORD nIDCtl , + + DWORD /*nIDItem*/ ) +{ + + impl_sendEvent(E_CONTROL_STATE_CHANGED, static_cast<sal_Int16>( nIDCtl )); + return S_OK; +} + +//----------------------------------------------------------------------------------------- +STDMETHODIMP VistaFilePickerEventHandler::OnButtonClicked(IFileDialogCustomize* /*pCustomize*/, + DWORD nIDCtl ) +{ + + impl_sendEvent(E_CONTROL_STATE_CHANGED, static_cast<sal_Int16>( nIDCtl)); + return S_OK; +} + +//----------------------------------------------------------------------------------------- +STDMETHODIMP VistaFilePickerEventHandler::OnCheckButtonToggled(IFileDialogCustomize* /*pCustomize*/, + DWORD nIDCtl , + BOOL bChecked ) +{ + /* + if (nIDCtl == css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION) + { + LPCWSTR lpFilterExt = 0; + if ( bChecked ) + { + UINT nIndex; + if (m_pDialog) + { + m_pDialog->GetFileTypeIndex( &nIndex ); + lpFilterExt = lFilters[nIndex].pszSpec; + lpFilterExt = wcschr( lpFilterExt, '.' ); + if ( lpFilterExt ) + lpFilterExt++; + } + } + + if (m_pDialog) + m_pDialog->SetDefaultExtension( lpFilterExt ); + } + */ + + if (nIDCtl == css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION) + m_pInternalNotify->onAutoExtensionChanged(bChecked); + + + impl_sendEvent(E_CONTROL_STATE_CHANGED, static_cast<sal_Int16>( nIDCtl)); + + return S_OK; +} + +//----------------------------------------------------------------------------------------- +STDMETHODIMP VistaFilePickerEventHandler::OnControlActivating(IFileDialogCustomize* /*pCustomize*/, + DWORD nIDCtl ) +{ + impl_sendEvent(E_CONTROL_STATE_CHANGED, static_cast<sal_Int16>( nIDCtl)); + return S_OK; +} + +//----------------------------------------------------------------------------------------- +void SAL_CALL VistaFilePickerEventHandler::addFilePickerListener( const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener ) + throw( css::uno::RuntimeException ) +{ + m_lListener.addInterface(::getCppuType( (const css::uno::Reference< css::ui::dialogs::XFilePickerListener >*)NULL ), xListener); +} + +//----------------------------------------------------------------------------------------- +void SAL_CALL VistaFilePickerEventHandler::removeFilePickerListener( const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener ) + throw( css::uno::RuntimeException ) +{ + m_lListener.removeInterface(::getCppuType( (const css::uno::Reference< css::ui::dialogs::XFilePickerListener >*)NULL ), xListener); +} + +//----------------------------------------------------------------------------------------- +void VistaFilePickerEventHandler::startListening( const TFileDialog& pBroadcaster ) +{ + static const sal_Bool STARTUP_SUSPENDED = sal_True; + static const sal_Bool STARTUP_WORKING = sal_False; + + if (m_pDialog.is()) + return; + + m_pDialog = pBroadcaster; + m_pDialog->Advise(this, &m_nListenerHandle); +} + +//----------------------------------------------------------------------------------------- +void VistaFilePickerEventHandler::stopListening() +{ + if (m_pDialog.is()) + { + m_pDialog->Unadvise(m_nListenerHandle); + m_pDialog.release(); + } +} + +static const ::rtl::OUString PROP_CONTROL_ID = ::rtl::OUString::createFromAscii("control_id"); +static const ::rtl::OUString PROP_PICKER_LISTENER = ::rtl::OUString::createFromAscii("picker_listener"); + +//----------------------------------------------------------------------------------------- +class AsyncPickerEvents : public RequestHandler +{ +public: + + AsyncPickerEvents() + {} + + virtual ~AsyncPickerEvents() + {} + + virtual void before() + {} + + virtual void doRequest(const RequestRef& rRequest) + { + const ::sal_Int32 nEventID = rRequest->getRequest(); + const ::sal_Int16 nControlID = rRequest->getArgumentOrDefault(PROP_CONTROL_ID, (::sal_Int16)0); + const css::uno::Reference< css::ui::dialogs::XFilePickerListener > xListener = rRequest->getArgumentOrDefault(PROP_PICKER_LISTENER, css::uno::Reference< css::ui::dialogs::XFilePickerListener >()); + + if ( ! xListener.is()) + return; + + css::ui::dialogs::FilePickerEvent aEvent; + aEvent.ElementId = nControlID; + + switch (nEventID) + { + case VistaFilePickerEventHandler::E_FILE_SELECTION_CHANGED : + xListener->fileSelectionChanged(aEvent); + break; + + case VistaFilePickerEventHandler::E_DIRECTORY_CHANGED : + xListener->directoryChanged(aEvent); + break; + + case VistaFilePickerEventHandler::E_HELP_REQUESTED : + xListener->helpRequested(aEvent); + break; + + case VistaFilePickerEventHandler::E_CONTROL_STATE_CHANGED : + xListener->controlStateChanged(aEvent); + break; + + case VistaFilePickerEventHandler::E_DIALOG_SIZE_CHANGED : + xListener->dialogSizeChanged(); + break; + + // no default here. Let compiler detect changes on enum set ! + } + } + + virtual void after() + {} +}; + +//----------------------------------------------------------------------------------------- +void VistaFilePickerEventHandler::impl_sendEvent( EEventType eEventType, + ::sal_Int16 nControlID) +{ + static AsyncRequests aNotify(RequestHandlerRef(new AsyncPickerEvents())); + + ::cppu::OInterfaceContainerHelper* pContainer = m_lListener.getContainer( ::getCppuType( ( const css::uno::Reference< css::ui::dialogs::XFilePickerListener >*) NULL ) ); + if ( ! pContainer) + return; + + ::cppu::OInterfaceIteratorHelper pIterator(*pContainer); + while (pIterator.hasMoreElements()) + { + try + { + css::uno::Reference< css::ui::dialogs::XFilePickerListener > xListener (pIterator.next(), css::uno::UNO_QUERY); + + RequestRef rRequest(new Request()); + rRequest->setRequest (eEventType); + rRequest->setArgument(PROP_PICKER_LISTENER, xListener); + if ( nControlID ) + rRequest->setArgument(PROP_CONTROL_ID, nControlID); + + aNotify.triggerRequestDirectly(rRequest); + //aNotify.triggerRequestNonBlocked(rRequest); + } + catch(const css::uno::RuntimeException&) + { + pIterator.remove(); + } + } +} + +} // namespace vista +} // namespace win32 +} // namespace fpicker diff --git a/fpicker/source/win32/filepicker/VistaFilePickerEventHandler.hxx b/fpicker/source/win32/filepicker/VistaFilePickerEventHandler.hxx new file mode 100644 index 000000000000..4b9434d8c6c2 --- /dev/null +++ b/fpicker/source/win32/filepicker/VistaFilePickerEventHandler.hxx @@ -0,0 +1,225 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FPICKER_WIN32_VISTA_FILEPICKER_EVENTHANDLER_HXX +#define FPICKER_WIN32_VISTA_FILEPICKER_EVENTHANDLER_HXX + +//----------------------------------------------------------------------------- +// includes +//----------------------------------------------------------------------------- + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma warning( disable : 4917 ) +#endif + +#include "comptr.hxx" +#include "vistatypes.h" +#include "IVistaFilePickerInternalNotify.hxx" + +#include <com/sun/star/ui/dialogs/XFilePickerListener.hpp> +#include <com/sun/star/uno/Reference.hxx> + +#include <cppuhelper/basemutex.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <osl/interlck.h> + +#include <shobjidl.h> + +//----------------------------------------------------------------------------- +// namespace +//----------------------------------------------------------------------------- + +#ifdef css + #error "Clash on using CSS as namespace define." +#else + #define css ::com::sun::star +#endif + +namespace fpicker{ +namespace win32{ +namespace vista{ + +//----------------------------------------------------------------------------- +// types, const etcpp. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +/** todo document me + */ +class VistaFilePickerEventHandler : public ::cppu::BaseMutex + , public IFileDialogEvents + , public IFileDialogControlEvents +{ + public: + + //------------------------------------------------------------------------------------ + // ctor/dtor + //------------------------------------------------------------------------------------ + + VistaFilePickerEventHandler(IVistaFilePickerInternalNotify* pInternalNotify); + virtual ~VistaFilePickerEventHandler(); + + //------------------------------------------------------------------------------------ + // IUnknown + //------------------------------------------------------------------------------------ + virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID rIID , + void** ppObject); + virtual ULONG STDMETHODCALLTYPE AddRef(); + virtual ULONG STDMETHODCALLTYPE Release(); + + //------------------------------------------------------------------------------------ + // IFileDialogEvents + //------------------------------------------------------------------------------------ + + STDMETHODIMP OnFileOk(IFileDialog* pDialog); + + STDMETHODIMP OnFolderChanging(IFileDialog* pDialog, + IShellItem* pFolder); + + STDMETHODIMP OnFolderChange(IFileDialog* pDialog); + + STDMETHODIMP OnSelectionChange(IFileDialog* pDialog); + + STDMETHODIMP OnShareViolation(IFileDialog* pDialog , + IShellItem* pItem , + FDE_SHAREVIOLATION_RESPONSE* pResponse); + + STDMETHODIMP OnTypeChange(IFileDialog* pDialog); + + STDMETHODIMP OnOverwrite(IFileDialog* pDialog , + IShellItem* pItem , + FDE_OVERWRITE_RESPONSE* pResponse); + + //------------------------------------------------------------------------------------ + // IFileDialogControlEvents + //------------------------------------------------------------------------------------ + + STDMETHODIMP OnItemSelected(IFileDialogCustomize* pCustomize, + DWORD nIDCtl , + DWORD nIDItem ); + + STDMETHODIMP OnButtonClicked(IFileDialogCustomize* pCustomize, + DWORD nIDCtl ); + + STDMETHODIMP OnCheckButtonToggled(IFileDialogCustomize* pCustomize, + DWORD nIDCtl , + BOOL bChecked ); + + STDMETHODIMP OnControlActivating(IFileDialogCustomize* pCustomize, + DWORD nIDCtl ); + + //------------------------------------------------------------------------------------ + // XFilePickerNotifier + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL addFilePickerListener( const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener ) + throw( css::uno::RuntimeException ); + + virtual void SAL_CALL removeFilePickerListener( const css::uno::Reference< css::ui::dialogs::XFilePickerListener >& xListener ) + throw( css::uno::RuntimeException ); + + //------------------------------------------------------------------------------------ + // native interface + //------------------------------------------------------------------------------------ + + //------------------------------------------------------------------------------------ + /** start listening for file picker events on the given file open dialog COM object. + * + * The broadcaster will be cached internaly so deregistration will be easy. + * Further all needed informations are capsulated within this class (e.g. the listener handler). + * Nobody outside must know such informations. + * + * Nothing will happen if an inconsistent state will be detected + * (means: double registration will be ignored). + * + * @param pBroadcaster + * reference to the dialog, where we should start listening. + */ + void startListening( const TFileDialog& pBroadcaster ); + + //------------------------------------------------------------------------------------ + /** stop listening for file picker events on the internaly cached dialog COM object. + * + * The COM dialog provided on the startListeneing() call was cached internaly. + * And now its used to deregister this listener. Doing so the also internaly cached + * listener handle is used. If listener was not already registered - nothing will happen. + */ + void stopListening(); + + public: + + enum EEventType + { + E_FILE_SELECTION_CHANGED, + E_DIRECTORY_CHANGED, + E_HELP_REQUESTED, + E_CONTROL_STATE_CHANGED, + E_DIALOG_SIZE_CHANGED + }; + + private: + + //------------------------------------------------------------------------------------ + /// @todo document me + void impl_sendEvent( EEventType eEventType, + ::sal_Int16 nControlID); + + private: + + //------------------------------------------------------------------------------------ + /// ref count for AddRef/Release() + oslInterlockedCount m_nRefCount; + + //------------------------------------------------------------------------------------ + /// unique handle for this listener provided by the broadcaster on registration time + DWORD m_nListenerHandle; + + //------------------------------------------------------------------------------------ + /// cached file dialog instance (there we listen for events) + TFileDialog m_pDialog; + + //--------------------------------------------------------------------- + IVistaFilePickerInternalNotify* m_pInternalNotify; + + //--------------------------------------------------------------------- + /** used to inform file picker listener asynchronously. + * Those listener must be called asynchronously .. because + * every request will block the caller thread. Mostly that will be + * the main thread of the office. Further the global SolarMutex will + * be locked during this time. If we call our listener back now synchronously .. + * we will block on SolarMutex.acquire() forever .-)) + */ + ::cppu::OMultiTypeInterfaceContainerHelper m_lListener; +}; + +} // namespace vista +} // namespace win32 +} // namespace fpicker + +#undef css + +#endif // FPICKER_WIN32_VISTA_FILEPICKER_EVENTHANDLER_HXX diff --git a/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx b/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx new file mode 100644 index 000000000000..ac59a4f65b99 --- /dev/null +++ b/fpicker/source/win32/filepicker/VistaFilePickerImpl.cxx @@ -0,0 +1,1212 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +//----------------------------------------------------------------------------- +// includes +//----------------------------------------------------------------------------- + +#include "VistaFilePickerImpl.hxx" + +#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/ControlActions.hpp> +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <comphelper/sequenceasvector.hxx> +#include <osl/file.hxx> +#include <osl/mutex.hxx> +#ifdef __MINGW32__ +#include <limits.h> +#endif +#include "..\misc\WinImplHelper.hxx" + + inline bool is_current_process_window(HWND hwnd) +{ + DWORD pid; + GetWindowThreadProcessId(hwnd, &pid); + return (pid == GetCurrentProcessId()); +} + +HWND choose_parent_window() +{ + HWND hwnd_parent = GetForegroundWindow(); + if (!is_current_process_window(hwnd_parent)) + hwnd_parent = GetDesktopWindow(); + return hwnd_parent; +} + +//----------------------------------------------------------------------------- +// namespace +//----------------------------------------------------------------------------- + +namespace fpicker{ +namespace win32{ +namespace vista{ + +namespace css = ::com::sun::star; + +//----------------------------------------------------------------------------- +// types, const etcpp. +//----------------------------------------------------------------------------- + + +static const ::sal_Int16 INVALID_CONTROL_ID = -1; +static const ::sal_Int16 INVALID_CONTROL_ACTION = -1; + +typedef ::comphelper::SequenceAsVector< ::rtl::OUString > TStringList; + +// Guids used for IFileDialog::SetClientGuid +static const GUID CLIENTID_FILEDIALOG_SIMPLE = {0xB8628FD3, 0xA3F5, 0x4845, 0x9B, 0x62, 0xD5, 0x1E, 0xDF, 0x97, 0xC4, 0x83}; +static const GUID CLIENTID_FILEDIALOG_OPTIONS = {0x93ED486F, 0x0D04, 0x4807, 0x8C, 0x44, 0xAC, 0x26, 0xCB, 0x6C, 0x5D, 0x36}; +static const GUID CLIENTID_FILESAVE = {0x3B2E2261, 0x402D, 0x4049, 0xB0, 0xC0, 0x91, 0x13, 0xF8, 0x6E, 0x84, 0x7C}; +static const GUID CLIENTID_FILESAVE_PASSWORD = {0xC12D4F4C, 0x4D41, 0x4D4F, 0x97, 0xEF, 0x87, 0xF9, 0x8D, 0xB6, 0x1E, 0xA6}; +static const GUID CLIENTID_FILESAVE_SELECTION = {0x5B2482B3, 0x0358, 0x4E09, 0xAA, 0x64, 0x2B, 0x76, 0xB2, 0xA0, 0xDD, 0xFE}; +static const GUID CLIENTID_FILESAVE_TEMPLATE = {0x9996D877, 0x20D5, 0x424B, 0x9C, 0x2E, 0xD3, 0xB6, 0x31, 0xEC, 0xF7, 0xCE}; +static const GUID CLIENTID_FILEOPEN_LINK_TEMPLATE = {0x32237796, 0x1509, 0x49D1, 0xBB, 0x7E, 0x63, 0xAD, 0x36, 0xAE, 0x86, 0x8C}; +static const GUID CLIENTID_FILEOPEN_PLAY = {0x32CFB147, 0xF5AE, 0x4F90, 0xA1, 0xF1, 0x81, 0x20, 0x72, 0xBB, 0x2F, 0xC5}; +static const GUID CLIENTID_FILEOPEN_LINK = {0x39AC4BAE, 0x7D2D, 0x46BC, 0xBE, 0x2E, 0xF8, 0x8C, 0xB5, 0x65, 0x5E, 0x6A}; + +//----------------------------------------------------------------------------- +::rtl::OUString lcl_getURLFromShellItem (IShellItem* pItem) +{ + LPOLESTR pStr = NULL; + ::rtl::OUString sURL; + + SIGDN eConversion = SIGDN_FILESYSPATH; + HRESULT hr = pItem->GetDisplayName ( eConversion, &pStr ); + + if ( FAILED(hr) ) + { + eConversion = SIGDN_URL; + hr = pItem->GetDisplayName ( eConversion, &pStr ); + + if ( FAILED(hr) ) + return ::rtl::OUString(); + + sURL = ::rtl::OUString(reinterpret_cast<sal_Unicode*>(pStr)); + } + else + { + ::osl::FileBase::getFileURLFromSystemPath( reinterpret_cast<sal_Unicode*>(pStr), sURL ); + } + + CoTaskMemFree (pStr); + return sURL; +} + +//----------------------------------------------------------------------------------------- +::std::vector< COMDLG_FILTERSPEC > lcl_buildFilterList(CFilterContainer& rContainer) +{ + const sal_Int32 c = rContainer.numFilter(); + sal_Int32 i = 0; + ::std::vector< COMDLG_FILTERSPEC > lList ; + CFilterContainer::FILTER_ENTRY_T aFilter; + + rContainer.beginEnumFilter( ); + while( rContainer.getNextFilter(aFilter) ) + { + COMDLG_FILTERSPEC aSpec; + + aSpec.pszName = reinterpret_cast<LPCTSTR>(aFilter.first.getStr()) ; + aSpec.pszSpec = reinterpret_cast<LPCTSTR>(aFilter.second.getStr()); + + lList.push_back(aSpec); + } + + return lList; +} + +//----------------------------------------------------------------------------------------- +VistaFilePickerImpl::VistaFilePickerImpl() + : m_iDialogOpen () + , m_iDialogSave () + , m_hLastResult () + , m_lFilters () + , m_lLastFiles () + , m_iEventHandler(new VistaFilePickerEventHandler(this)) + , m_bInExecute (sal_False) + , m_bWasExecuted (sal_False) + , m_sDirectory () + , m_sFilename () +{ + m_hParentWindow = choose_parent_window(); +} + +//------------------------------------------------------------------------------- +VistaFilePickerImpl::~VistaFilePickerImpl() +{ +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::before() +{ + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + // TRICKY .-) + // osl::Thread class initializes COm already in MTA mode because it's needed + // by VCL and UNO so. There is no way to change that from outside ... + // but we need a STA environment ... + // So we make it by try-and-error ... + // If first CoInitialize will fail .. we unitialize COM initialize it new .-) + + m_hLastResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + if ( FAILED(m_hLastResult) ) + { + CoUninitialize(); + m_hLastResult = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + } +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::doRequest(const RequestRef& rRequest) +{ + try + { + switch(rRequest->getRequest()) + { + case E_ADD_PICKER_LISTENER : + impl_sta_addFilePickerListener(rRequest); + break; + + case E_REMOVE_PICKER_LISTENER : + impl_sta_removeFilePickerListener(rRequest); + break; + + case E_APPEND_FILTER : + impl_sta_appendFilter(rRequest); + break; + + case E_SET_CURRENT_FILTER : + impl_sta_setCurrentFilter(rRequest); + break; + + case E_GET_CURRENT_FILTER : + impl_sta_getCurrentFilter(rRequest); + break; + + case E_CREATE_OPEN_DIALOG : + impl_sta_CreateOpenDialog(rRequest); + break; + + case E_CREATE_SAVE_DIALOG : + impl_sta_CreateSaveDialog(rRequest); + break; + + case E_SET_MULTISELECTION_MODE : + impl_sta_SetMultiSelectionMode(rRequest); + break; + + case E_SET_TITLE : + impl_sta_SetTitle(rRequest); + break; + + case E_SET_FILENAME: + impl_sta_SetFileName(rRequest); + break; + + case E_SET_DIRECTORY : + impl_sta_SetDirectory(rRequest); + break; + + case E_GET_DIRECTORY : + impl_sta_GetDirectory(rRequest); + break; + + case E_SET_DEFAULT_NAME : + impl_sta_SetDefaultName(rRequest); + break; + + case E_GET_SELECTED_FILES : + impl_sta_getSelectedFiles(rRequest); + break; + + case E_SHOW_DIALOG_MODAL : + impl_sta_ShowDialogModal(rRequest); + break; + + case E_SET_CONTROL_VALUE : + impl_sta_SetControlValue(rRequest); + break; + + case E_GET_CONTROL_VALUE : + impl_sta_GetControlValue(rRequest); + break; + + case E_SET_CONTROL_LABEL : + impl_sta_SetControlLabel(rRequest); + break; + + case E_GET_CONTROL_LABEL : + impl_sta_GetControlLabel(rRequest); + break; + + case E_ENABLE_CONTROL : + impl_sta_EnableControl(rRequest); + break; + + // no default: let the compiler detect changes on enum ERequest ! + } + } + catch(...) + {} +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::after() +{ + CoUninitialize(); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_addFilePickerListener(const RequestRef& rRequest) +{ + // SYNCHRONIZED outside ! + const css::uno::Reference< css::ui::dialogs::XFilePickerListener > xListener = rRequest->getArgumentOrDefault(PROP_PICKER_LISTENER, css::uno::Reference< css::ui::dialogs::XFilePickerListener >()); + if ( ! xListener.is()) + return; + + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + TFileDialogEvents iHandler = m_iEventHandler; + aLock.clear(); + // <- SYNCHRONIZED + + VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get(); + if (pHandlerImpl) + pHandlerImpl->addFilePickerListener(xListener); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_removeFilePickerListener(const RequestRef& rRequest) +{ + // SYNCHRONIZED outside ! + const css::uno::Reference< css::ui::dialogs::XFilePickerListener > xListener = rRequest->getArgumentOrDefault(PROP_PICKER_LISTENER, css::uno::Reference< css::ui::dialogs::XFilePickerListener >()); + if ( ! xListener.is()) + return; + + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + TFileDialogEvents iHandler = m_iEventHandler; + aLock.clear(); + // <- SYNCHRONIZED + + VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get(); + if (pHandlerImpl) + pHandlerImpl->removeFilePickerListener(xListener); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_appendFilter(const RequestRef& rRequest) +{ + const ::rtl::OUString sTitle = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, ::rtl::OUString()); + const ::rtl::OUString sFilter = rRequest->getArgumentOrDefault(PROP_FILTER_VALUE, ::rtl::OUString()); + + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + m_lFilters.addFilter(sTitle, sFilter); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_setCurrentFilter(const RequestRef& rRequest) +{ + const ::rtl::OUString sTitle = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, ::rtl::OUString()); + + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + m_lFilters.setCurrentFilter(sTitle); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_getCurrentFilter(const RequestRef& rRequest) +{ + TFileDialog iDialog = impl_getBaseDialogInterface(); + UINT nIndex = UINT_MAX; + HRESULT hResult = iDialog->GetFileTypeIndex(&nIndex); + if ( + ( FAILED(hResult) ) || + ( nIndex == UINT_MAX ) // COM dialog sometimes return S_OK for empty filter lists .-( + ) + return; + + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + ::rtl::OUString sTitle; + ::sal_Int32 nRealIndex = (nIndex-1); // COM dialog base on 1 ... filter container on 0 .-) + if ( + (nRealIndex >= 0 ) && + (m_lFilters.getFilter(nRealIndex, sTitle)) + ) + rRequest->setArgument(PROP_FILTER_TITLE, sTitle); + else if ( nRealIndex == -1 ) // Dialog not visible yet + { + sTitle = m_lFilters.getCurrentFilter(); + rRequest->setArgument(PROP_FILTER_TITLE, sTitle); + } + + aLock.clear(); + // <- SYNCHRONIZED +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_CreateOpenDialog(const RequestRef& rRequest) +{ + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + m_hLastResult = m_iDialogOpen.create(); + if (FAILED(m_hLastResult)) + return; + + TFileDialog iDialog; +#ifdef __MINGW32__ + m_iDialogOpen->QueryInterface(IID_IFileDialog, (void **)(&iDialog)); +#else + m_iDialogOpen.query(&iDialog); +#endif + + TFileDialogEvents iHandler = m_iEventHandler; + + aLock.clear(); + // <- SYNCHRONIZED + + DWORD nFlags = 0; + iDialog->GetOptions ( &nFlags ); + + nFlags &= ~FOS_FORCESHOWHIDDEN; + nFlags |= FOS_PATHMUSTEXIST; + nFlags |= FOS_FILEMUSTEXIST; + nFlags |= FOS_OVERWRITEPROMPT; + nFlags |= FOS_DONTADDTORECENT; + + iDialog->SetOptions ( nFlags ); + + ::sal_Int32 nFeatures = rRequest->getArgumentOrDefault(PROP_FEATURES, (::sal_Int32)0); + ::sal_Int32 nTemplate = rRequest->getArgumentOrDefault(PROP_TEMPLATE_DESCR, (::sal_Int32)0); + impl_sta_enableFeatures(nFeatures, nTemplate); + + VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get(); + if (pHandlerImpl) + pHandlerImpl->startListening(iDialog); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_CreateSaveDialog(const RequestRef& rRequest) +{ + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + m_hLastResult = m_iDialogSave.create(); + if (FAILED(m_hLastResult)) + return; + + TFileDialogEvents iHandler = m_iEventHandler; + TFileDialog iDialog; +#ifdef __MINGW32__ + m_iDialogSave->QueryInterface(IID_IFileDialog, (void **)(&iDialog)); +#else + m_iDialogSave.query(&iDialog); +#endif + + aLock.clear(); + // <- SYNCHRONIZED + + DWORD nFlags = 0; + iDialog->GetOptions ( &nFlags ); + + nFlags &= ~FOS_FORCESHOWHIDDEN; + nFlags |= FOS_PATHMUSTEXIST; + nFlags |= FOS_FILEMUSTEXIST; + nFlags |= FOS_OVERWRITEPROMPT; + nFlags |= FOS_DONTADDTORECENT; + + iDialog->SetOptions ( nFlags ); + + ::sal_Int32 nFeatures = rRequest->getArgumentOrDefault(PROP_FEATURES, (::sal_Int32)0); + ::sal_Int32 nTemplate = rRequest->getArgumentOrDefault(PROP_TEMPLATE_DESCR, (::sal_Int32)0); + impl_sta_enableFeatures(nFeatures, nTemplate); + + VistaFilePickerEventHandler* pHandlerImpl = (VistaFilePickerEventHandler*)iHandler.get(); + if (pHandlerImpl) + pHandlerImpl->startListening(iDialog); +} + +//------------------------------------------------------------------------------- +static const ::sal_Int32 GROUP_VERSION = 1; +static const ::sal_Int32 GROUP_TEMPLATE = 2; +static const ::sal_Int32 GROUP_IMAGETEMPLATE = 3; +static const ::sal_Int32 GROUP_CHECKBOXES = 4; + +//------------------------------------------------------------------------------- +static void setLabelToControl(CResourceProvider& rResourceProvider, TFileDialogCustomize iCustom, sal_uInt16 nControlId) +{ + ::rtl::OUString aLabel = rResourceProvider.getResString(nControlId); + aLabel = SOfficeToWindowsLabel(aLabel); + iCustom->SetControlLabel(nControlId, reinterpret_cast<LPCWSTR>(aLabel.getStr()) ); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_enableFeatures(::sal_Int32 nFeatures, ::sal_Int32 nTemplate) +{ + GUID aGUID = {}; + switch (nTemplate) + { + case css::ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE : + case css::ui::dialogs::TemplateDescription::FILESAVE_SIMPLE : + aGUID = CLIENTID_FILEDIALOG_SIMPLE; + break; + + case css::ui::dialogs::TemplateDescription::FILEOPEN_READONLY_VERSION : + case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS : + aGUID = CLIENTID_FILEDIALOG_OPTIONS; + break; + + case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION : + aGUID = CLIENTID_FILESAVE; + break; + + case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD : + aGUID = CLIENTID_FILESAVE_PASSWORD; + break; + + case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_SELECTION : + aGUID = CLIENTID_FILESAVE_SELECTION; + break; + + case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_TEMPLATE : + aGUID = CLIENTID_FILESAVE_TEMPLATE; + break; + + case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE : + aGUID = CLIENTID_FILEOPEN_LINK_TEMPLATE; + break; + + case css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY : + aGUID = CLIENTID_FILEOPEN_PLAY; + break; + + case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW : + aGUID = CLIENTID_FILEOPEN_LINK; + break; + } + TFileDialog iDialog = impl_getBaseDialogInterface(); + iDialog->SetClientGuid ( aGUID ); + + TFileDialogCustomize iCustom = impl_getCustomizeInterface(); + + if ((nFeatures & FEATURE_VERSION) == FEATURE_VERSION) + { + iCustom->StartVisualGroup (GROUP_VERSION, L"Version"); + iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION); + iCustom->EndVisualGroup (); + iCustom->MakeProminent (GROUP_VERSION); + } + + if ((nFeatures & FEATURE_TEMPLATE) == FEATURE_TEMPLATE) + { + iCustom->StartVisualGroup (GROUP_TEMPLATE, L"Template"); + iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE); + iCustom->EndVisualGroup (); + iCustom->MakeProminent (GROUP_TEMPLATE); + } + + if ((nFeatures & FEATURE_IMAGETEMPLATE) == FEATURE_IMAGETEMPLATE) + { + iCustom->StartVisualGroup (GROUP_IMAGETEMPLATE, L"Style"); + iCustom->AddComboBox (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE); + iCustom->EndVisualGroup (); + iCustom->MakeProminent (GROUP_IMAGETEMPLATE); + } + + iCustom->StartVisualGroup (GROUP_CHECKBOXES, L""); + + sal_uInt16 nControlId(0); + if ((nFeatures & FEATURE_AUTOEXTENSION) == FEATURE_AUTOEXTENSION) + { + nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION; + iCustom->AddCheckButton (nControlId, L"Auto Extension", true); + setLabelToControl(m_ResProvider, iCustom, nControlId); + } + + if ((nFeatures & FEATURE_PASSWORD) == FEATURE_PASSWORD) + { + nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD; + iCustom->AddCheckButton (nControlId, L"Password", false); + setLabelToControl(m_ResProvider, iCustom, nControlId); + } + + if ((nFeatures & FEATURE_READONLY) == FEATURE_READONLY) + { + nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY; + iCustom->AddCheckButton (nControlId, L"Readonly", false); + setLabelToControl(m_ResProvider, iCustom, nControlId); + } + + if ((nFeatures & FEATURE_FILTEROPTIONS) == FEATURE_FILTEROPTIONS) + { + nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS; + iCustom->AddCheckButton (nControlId, L"Filter Options", false); + setLabelToControl(m_ResProvider, iCustom, nControlId); + } + + if ((nFeatures & FEATURE_LINK) == FEATURE_LINK) + { + nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK; + iCustom->AddCheckButton (nControlId, L"Link", false); + setLabelToControl(m_ResProvider, iCustom, nControlId); + } + + if ((nFeatures & FEATURE_SELECTION) == FEATURE_SELECTION) + { + nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION; + iCustom->AddCheckButton (nControlId, L"Selection", false); + setLabelToControl(m_ResProvider, iCustom, nControlId); + } + + /* can be ignored ... new COM dialog supports preview native now ! + if ((nFeatures & FEATURE_PREVIEW) == FEATURE_PREVIEW) + iCustom->AddCheckButton (css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW, L"Preview", false); + */ + + iCustom->EndVisualGroup(); + + if ((nFeatures & FEATURE_PLAY) == FEATURE_PLAY) + iCustom->AddPushButton (css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY, L"Play"); + +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_SetMultiSelectionMode(const RequestRef& rRequest) +{ + const ::sal_Bool bMultiSelection = rRequest->getArgumentOrDefault(PROP_MULTISELECTION_MODE, (::sal_Bool)sal_True); + + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + TFileDialog iDialog = impl_getBaseDialogInterface(); + aLock.clear(); + // <- SYNCHRONIZED + + DWORD nFlags = 0; + m_hLastResult = iDialog->GetOptions ( &nFlags ); + + if (bMultiSelection) + nFlags |= FOS_ALLOWMULTISELECT; + else + nFlags &= ~FOS_ALLOWMULTISELECT; + + iDialog->SetOptions ( nFlags ); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_SetTitle(const RequestRef& rRequest) +{ + ::rtl::OUString sTitle = rRequest->getArgumentOrDefault(PROP_TITLE, ::rtl::OUString()); + + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + TFileDialog iDialog = impl_getBaseDialogInterface(); + aLock.clear(); + // <- SYNCHRONIZED + + iDialog->SetTitle(reinterpret_cast<LPCTSTR>(sTitle.getStr())); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_SetFileName(const RequestRef& rRequest) +{ + ::rtl::OUString sFileName = rRequest->getArgumentOrDefault(PROP_FILENAME, ::rtl::OUString()); + + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + TFileDialog iDialog = impl_getBaseDialogInterface(); + aLock.clear(); + // <- SYNCHRONIZED + + iDialog->SetFileName(reinterpret_cast<LPCTSTR>(sFileName.getStr())); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_SetDirectory(const RequestRef& rRequest) +{ + ::rtl::OUString sDirectory = rRequest->getArgumentOrDefault(PROP_DIRECTORY, ::rtl::OUString()); + bool bForce = rRequest->getArgumentOrDefault(PROP_FORCE, false); + + if( !m_bInExecute) + { + // Vista stores last used folders for file dialogs + // so we don't want the application to change the folder + // in most cases. + // Store the requested folder in the mean time and decide later + // what to do + m_sDirectory = sDirectory; + } + + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + TFileDialog iDialog = impl_getBaseDialogInterface(); + aLock.clear(); + // <- SYNCHRONIZED + + ComPtr< IShellItem > pFolder; +#ifdef __MINGW32__ + HRESULT hResult = SHCreateItemFromParsingName ( reinterpret_cast<LPCTSTR>(sDirectory.getStr()), NULL, IID_IShellItem, (void**)(&pFolder) ); +#else + HRESULT hResult = SHCreateItemFromParsingName ( sDirectory, NULL, IID_PPV_ARGS(&pFolder) ); +#endif + if ( FAILED(hResult) ) + return; + + if ( m_bInExecute || bForce ) + iDialog->SetFolder(pFolder); + else + { + // Use set default folder as Microsoft recommends in the IFileDialog documentation. + iDialog->SetDefaultFolder(pFolder); + } +} + +void VistaFilePickerImpl::impl_sta_GetDirectory(const RequestRef& rRequest) +{ + TFileDialog iDialog = impl_getBaseDialogInterface(); + ComPtr< IShellItem > pFolder; + HRESULT hResult = iDialog->GetFolder( &pFolder ); + if ( FAILED(hResult) ) + return; + ::rtl::OUString sFolder = lcl_getURLFromShellItem ( pFolder ); + if( sFolder.getLength()) + rRequest->setArgument( PROP_DIRECTORY, sFolder ); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_SetDefaultName(const RequestRef& rRequest) +{ + ::rtl::OUString sFilename = rRequest->getArgumentOrDefault(PROP_FILENAME, ::rtl::OUString()); + TFileDialog iDialog = impl_getBaseDialogInterface(); + + TFileDialogCustomize iCustom = impl_getCustomizeInterface(); + if ( ! iCustom.is()) + return; + + // if we have the autoextension check box set, remove (or change ???) the extension of the filename + // so that the autoextension mechanism can do its job + BOOL bValue = FALSE; + HRESULT hResult = iCustom->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue); + if ( bValue ) + { + sal_Int32 nSepPos = sFilename.lastIndexOf( '.' ); + if ( -1 != nSepPos ) + sFilename = sFilename.copy(0, nSepPos); + } + + iDialog->SetFileName ( reinterpret_cast<LPCTSTR>(sFilename.getStr())); + m_sFilename = sFilename; +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_setFiltersOnDialog() +{ + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + ::std::vector< COMDLG_FILTERSPEC > lFilters = lcl_buildFilterList(m_lFilters); + ::rtl::OUString sCurrentFilter = m_lFilters.getCurrentFilter(); + sal_Int32 nCurrentFilter = m_lFilters.getFilterPos(sCurrentFilter); + TFileDialog iDialog = impl_getBaseDialogInterface(); + TFileDialogCustomize iCustomize = impl_getCustomizeInterface(); + + aLock.clear(); + // <- SYNCHRONIZED + + COMDLG_FILTERSPEC *pFilt = &lFilters[0]; + iDialog->SetFileTypes(lFilters.size(), pFilt/*&lFilters[0]*/); + iDialog->SetFileTypeIndex(nCurrentFilter + 1); + + BOOL bValue = FALSE; + HRESULT hResult = iCustomize->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue); + + if ( bValue ) + { + LPCWSTR lpFilterExt = lFilters[0].pszSpec; + + lpFilterExt = wcsrchr( lpFilterExt, '.' ); + if ( lpFilterExt ) + lpFilterExt++; + iDialog->SetDefaultExtension( lpFilterExt ); + } + +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_getSelectedFiles(const RequestRef& rRequest) +{ + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + TFileOpenDialog iOpen = m_iDialogOpen; + TFileSaveDialog iSave = m_iDialogSave; + ::sal_Bool bInExecute = m_bInExecute; + + aLock.clear(); + // <- SYNCHRONIZED + + // ask dialog for results + // Note : we must differ between single/multi selection ! + // Note further: we must react different if dialog is in execute or not .-( + ComPtr< IShellItem > iItem; + ComPtr< IShellItemArray > iItems; + HRESULT hResult = E_FAIL; + + if (iOpen.is()) + { + if (bInExecute) + hResult = iOpen->GetSelectedItems(&iItems); + else + { + hResult = iOpen->GetResults(&iItems); + if (FAILED(hResult)) + hResult = iOpen->GetResult(&iItem); + } + } + else + if (iSave.is()) + { + if (bInExecute) + hResult = iSave->GetCurrentSelection(&iItem); + else + hResult = iSave->GetResult(&iItem); + } + + if (FAILED(hResult)) + return; + + // convert and pack results + TStringList lFiles; + if (iItem.is()) + { + const ::rtl::OUString sURL = lcl_getURLFromShellItem(iItem); + if (sURL.getLength() > 0) + lFiles.push_back(sURL); + } + + if (iItems.is()) + { + DWORD nCount; + hResult = iItems->GetCount(&nCount); + if ( SUCCEEDED(hResult) ) + { + for (DWORD i=0; i<nCount; ++i) + { + hResult = iItems->GetItemAt(i, &iItem); + if ( SUCCEEDED(hResult) ) + { + const ::rtl::OUString sURL = lcl_getURLFromShellItem(iItem); + if (sURL.getLength() > 0) + lFiles.push_back(sURL); + } + } + } + } + + rRequest->setArgument(PROP_SELECTED_FILES, lFiles.getAsConstList()); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_ShowDialogModal(const RequestRef& rRequest) +{ + impl_sta_setFiltersOnDialog(); + + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + TFileDialog iDialog = impl_getBaseDialogInterface(); + TFileOpenDialog iOpen = m_iDialogOpen; + TFileSaveDialog iSave = m_iDialogSave; + + // it's important to know if we are showing the dialog. + // Some dialog interface methods cant be called then or some + // tasks must be done differently .-) (e.g. see impl_sta_getSelectedFiles()) + m_bInExecute = sal_True; + + m_bWasExecuted = sal_True; + + aLock.clear(); + // <- SYNCHRONIZED + + // we set the directory only if we have a save dialog and a filename + // for the other cases, the file dialog remembers its last location + // according to its client guid. + if( m_sDirectory.getLength()) + { + ComPtr< IShellItem > pFolder; + #ifdef __MINGW32__ + HRESULT hResult = SHCreateItemFromParsingName ( reinterpret_cast<LPCTSTR>(m_sDirectory.getStr()), NULL, IID_IShellItem, (void**)(&pFolder) ); + #else + HRESULT hResult = SHCreateItemFromParsingName ( m_sDirectory, NULL, IID_PPV_ARGS(&pFolder) ); + #endif + if ( SUCCEEDED(hResult) ) + { + if (m_sFilename.getLength()) + { + ::rtl::OUString aFileURL(m_sDirectory); + sal_Int32 nIndex = aFileURL.lastIndexOf('/'); + if (nIndex != aFileURL.getLength()-1) + aFileURL += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/")); + aFileURL += m_sFilename; + + TFileDialogCustomize iCustom = impl_getCustomizeInterface(); + + BOOL bValue = FALSE; + HRESULT hResult = iCustom->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue); + if ( bValue ) + { + ::rtl::OUString aExt; + UINT nFileType; + hResult = iDialog->GetFileTypeIndex(&nFileType); + if ( SUCCEEDED(hResult) ) + { + ::sal_Int32 nRealIndex = (nFileType-1); // COM dialog base on 1 ... filter container on 0 .-) + ::std::vector< COMDLG_FILTERSPEC > lFilters = lcl_buildFilterList(m_lFilters); + LPCWSTR lpFilterExt = lFilters[nRealIndex].pszSpec; + + lpFilterExt = wcsrchr( lpFilterExt, '.' ); + if ( lpFilterExt ) + aFileURL += reinterpret_cast<const sal_Unicode*>(lpFilterExt); + } + } + + // Check existence of file. Set folder only for this special case + ::rtl::OUString aSystemPath; + osl_getSystemPathFromFileURL( aFileURL.pData, &aSystemPath.pData ); + + WIN32_FIND_DATA aFindFileData; + HANDLE hFind = FindFirstFile( reinterpret_cast<LPCWSTR>(aSystemPath.getStr()), &aFindFileData ); + if (hFind != INVALID_HANDLE_VALUE) + iDialog->SetFolder(pFolder); + else + hResult = iDialog->AddPlace(pFolder, FDAP_TOP); + + FindClose( hFind ); + } + else + hResult = iDialog->AddPlace(pFolder, FDAP_TOP); + } + } + + + HRESULT hResult = E_FAIL; + try + { + // show dialog and wait for user decision + if (iOpen.is()) + hResult = iOpen->Show( m_hParentWindow ); // parent window needed + else + if (iSave.is()) + hResult = iSave->Show( m_hParentWindow ); // parent window needed + } + catch(...) + {} + + // SYNCHRONIZED-> + aLock.reset(); + m_bInExecute = sal_False; + aLock.clear(); + // <- SYNCHRONIZED + + if ( FAILED(hResult) ) + return; + + impl_sta_getSelectedFiles(rRequest); + rRequest->setArgument(PROP_DIALOG_SHOW_RESULT, (::sal_Bool)sal_True); +} + +//------------------------------------------------------------------------------- +TFileDialog VistaFilePickerImpl::impl_getBaseDialogInterface() +{ + TFileDialog iDialog; + + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + if (m_iDialogOpen.is()) +#ifdef __MINGW32__ + m_iDialogOpen->QueryInterface(IID_IFileDialog, (void**)(&iDialog)); +#else + m_iDialogOpen.query(&iDialog); +#endif + if (m_iDialogSave.is()) +#ifdef __MINGW32__ + m_iDialogSave->QueryInterface(IID_IFileDialog, (void**)(&iDialog)); +#else + m_iDialogSave.query(&iDialog); +#endif + + return iDialog; +} + +//------------------------------------------------------------------------------- +TFileDialogCustomize VistaFilePickerImpl::impl_getCustomizeInterface() +{ + TFileDialogCustomize iCustom; + + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + if (m_iDialogOpen.is()) +#ifdef __MINGW32__ + m_iDialogOpen->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustom)); +#else + m_iDialogOpen.query(&iCustom); +#endif + else + if (m_iDialogSave.is()) +#ifdef __MINGW32__ + m_iDialogSave->QueryInterface(IID_IFileDialogCustomize, (void**)(&iCustom)); +#else + m_iDialogSave.query(&iCustom); +#endif + + return iCustom; +} + +//------------------------------------------------------------------------------- +void lcl_removeControlItemsWorkaround(const TFileDialogCustomize& iCustom , + ::sal_Int16 nControlId) +{ + ::sal_Int32 i = 0; + HRESULT hResult; + + hResult = iCustom->SetSelectedControlItem(nControlId, 1000); + hResult = S_OK; + while ( SUCCEEDED(hResult) ) + hResult = iCustom->RemoveControlItem(nControlId, i++); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_SetControlValue(const RequestRef& rRequest) +{ + ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID ); + ::sal_Int16 nAction = rRequest->getArgumentOrDefault(PROP_CONTROL_ACTION, INVALID_CONTROL_ACTION); + css::uno::Any aValue = rRequest->getArgumentOrDefault(PROP_CONTROL_VALUE , css::uno::Any() ); + + // dont check for right values here ... + // most parameters are optional ! + + TFileDialogCustomize iCustom = impl_getCustomizeInterface(); + if ( ! iCustom.is()) + return; + + switch (nId) + { + case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION : + case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD : + case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY : + case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS : + case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK : + //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now ! + case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION : + { + ::sal_Bool bValue = sal_False; + aValue >>= bValue; + iCustom->SetCheckButtonState(nId, bValue); + } + break; + + case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION : + case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE : + case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE : + { + HRESULT hResult; + switch (nAction) + { + case css::ui::dialogs::ControlActions::DELETE_ITEMS : + { + hResult = iCustom->RemoveAllControlItems(nId); + if ( FAILED(hResult) ) + lcl_removeControlItemsWorkaround(iCustom, nId); + } + break; + + case css::ui::dialogs::ControlActions::ADD_ITEMS : + { + css::uno::Sequence< ::rtl::OUString > lItems; + aValue >>= lItems; + for (::sal_Int32 i=0; i<lItems.getLength(); ++i) + { + const ::rtl::OUString& sItem = lItems[i]; + hResult = iCustom->AddControlItem(nId, i, reinterpret_cast<LPCTSTR>(sItem.getStr())); + } + } + break; + + case css::ui::dialogs::ControlActions::SET_SELECT_ITEM : + { + ::sal_Int32 nItem = 0; + aValue >>= nItem; + hResult = iCustom->SetSelectedControlItem(nId, nItem); + } + break; + } + } + break; + + case css::ui::dialogs::ExtendedFilePickerElementIds::PUSHBUTTON_PLAY : + { + } + break; + } +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_GetControlValue(const RequestRef& rRequest) +{ + ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID ); + ::sal_Int16 nAction = rRequest->getArgumentOrDefault(PROP_CONTROL_ACTION, INVALID_CONTROL_ACTION); + + // dont check for right values here ... + // most parameters are optional ! + + TFileDialogCustomize iCustom = impl_getCustomizeInterface(); + if ( ! iCustom.is()) + return; + + css::uno::Any aValue; + if( m_bWasExecuted ) + switch (nId) + { + case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD : + case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY : + case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS : + case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK : + //case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PREVIEW : // can be ignored ... preview is supported native now ! + case css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION : + { + BOOL bValue = sal_False; + HRESULT hResult = iCustom->GetCheckButtonState(nId, &bValue); + if ( SUCCEEDED(hResult) ) + aValue = css::uno::makeAny((sal_Bool)bValue); + } + break; + } + + if (aValue.hasValue()) + rRequest->setArgument(PROP_CONTROL_VALUE, aValue); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_SetControlLabel(const RequestRef& rRequest) +{ + ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID ); + ::rtl::OUString sLabel = rRequest->getArgumentOrDefault(PROP_CONTROL_LABEL, ::rtl::OUString() ); + + // dont check for right values here ... + // most parameters are optional ! + + TFileDialogCustomize iCustom = impl_getCustomizeInterface(); + if ( ! iCustom.is()) + return; + iCustom->SetControlLabel ( nId, reinterpret_cast<LPCTSTR>(sLabel.getStr())); +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_GetControlLabel(const RequestRef& /*rRequest*/) +{ +} + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_sta_EnableControl(const RequestRef& rRequest) +{ + ::sal_Int16 nId = rRequest->getArgumentOrDefault(PROP_CONTROL_ID , INVALID_CONTROL_ID ); + ::sal_Bool bEnabled = rRequest->getArgumentOrDefault(PROP_CONTROL_ENABLE, (::sal_Bool)sal_True); + + // dont check for right values here ... + // most parameters are optional ! + + TFileDialogCustomize iCustom = impl_getCustomizeInterface(); + if ( ! iCustom.is()) + return; + + CDCONTROLSTATEF eState = CDCS_VISIBLE; + if (bEnabled) + eState |= CDCS_ENABLED; + else + eState |= CDCS_INACTIVE; + + iCustom->SetControlState(nId, eState); +} +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::impl_SetDefaultExtension( const rtl::OUString& currentFilter ) +{ + TFileDialog iDialog = impl_getBaseDialogInterface(); + if (currentFilter.getLength()) + { + rtl::OUString FilterExt; + m_lFilters.getFilter(currentFilter, FilterExt); + + sal_Int32 posOfPoint = FilterExt.indexOf(L'.'); + const sal_Unicode* pFirstExtStart = FilterExt.getStr() + posOfPoint + 1; + + sal_Int32 posOfSemiColon = FilterExt.indexOf(L';') - 1; + if (posOfSemiColon < 0) + posOfSemiColon = FilterExt.getLength() - 1; + + FilterExt = rtl::OUString(pFirstExtStart, posOfSemiColon - posOfPoint); + iDialog->SetDefaultExtension ( reinterpret_cast<LPCTSTR>(FilterExt.getStr()) ); + } +} + + +//------------------------------------------------------------------------------- +void VistaFilePickerImpl::onAutoExtensionChanged (bool bChecked) +{ + // SYNCHRONIZED-> + ::osl::ResettableMutexGuard aLock(m_aMutex); + + const ::rtl::OUString sFilter = m_lFilters.getCurrentFilter (); + ::rtl::OUString sExt ; + if ( !m_lFilters.getFilter (sFilter, sExt)) + return; + + TFileDialog iDialog = impl_getBaseDialogInterface(); + + aLock.clear(); + // <- SYNCHRONIZED + + LPCWSTR pExt = 0; + if ( bChecked ) + { + pExt = reinterpret_cast<LPCTSTR>(sExt.getStr()); + pExt = wcsrchr( pExt, '.' ); + if ( pExt ) + pExt++; + } + iDialog->SetDefaultExtension( pExt ); +} + +} // namespace vista +} // namespace win32 +} // namespace fpicker diff --git a/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx b/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx new file mode 100644 index 000000000000..6be17935609b --- /dev/null +++ b/fpicker/source/win32/filepicker/VistaFilePickerImpl.hxx @@ -0,0 +1,353 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FPICKER_WIN32_VISTA_FILEPICKERIMPL_HXX +#define FPICKER_WIN32_VISTA_FILEPICKERIMPL_HXX + +//----------------------------------------------------------------------------- +// includes +//----------------------------------------------------------------------------- + +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +#pragma warning( disable : 4917 ) +#endif + +#include "platform_vista.h" +#include "asyncrequests.hxx" +#include "comptr.hxx" +#include "vistatypes.h" +#include "FilterContainer.hxx" +#include "VistaFilePickerEventHandler.hxx" +#include "IVistaFilePickerInternalNotify.hxx" +#include "..\misc\resourceprovider.hxx" + +#include <com/sun/star/uno/Sequence.hxx> + +#include <comphelper/sequenceashashmap.hxx> +#include <cppuhelper/interfacecontainer.h> +#include <cppuhelper/basemutex.hxx> +#include <osl/thread.hxx> +#include <osl/conditn.hxx> +#include <rtl/ustring.hxx> + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <shobjidl.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//----------------------------------------------------------------------------- +// namespace +//----------------------------------------------------------------------------- + +#ifdef css + #error "Clash on using CSS as namespace define." +#else + #define css ::com::sun::star +#endif + +namespace fpicker{ +namespace win32{ +namespace vista{ + +//----------------------------------------------------------------------------- +// types, const etcpp +//----------------------------------------------------------------------------- + +static const ::sal_Int32 FEATURE_AUTOEXTENSION = 1; +static const ::sal_Int32 FEATURE_PASSWORD = 2; +static const ::sal_Int32 FEATURE_FILTEROPTIONS = 4; +static const ::sal_Int32 FEATURE_SELECTION = 8; +static const ::sal_Int32 FEATURE_TEMPLATE = 16; +static const ::sal_Int32 FEATURE_LINK = 32; +static const ::sal_Int32 FEATURE_PREVIEW = 64; +static const ::sal_Int32 FEATURE_IMAGETEMPLATE = 128; +static const ::sal_Int32 FEATURE_PLAY = 256; +static const ::sal_Int32 FEATURE_READONLY = 512; +static const ::sal_Int32 FEATURE_VERSION = 1024; + +static const ::rtl::OUString PROP_PICKER_LISTENER = ::rtl::OUString::createFromAscii("picker_listener" ); // [XFilePickerListenert] +static const ::rtl::OUString PROP_DIALOG_SHOW_RESULT = ::rtl::OUString::createFromAscii("dialog_show_result" ); // [sal_Bool] true=OK, false=CANCEL +static const ::rtl::OUString PROP_SELECTED_FILES = ::rtl::OUString::createFromAscii("selected_files" ); // [seq< OUString >] contains all user selected files (can be empty!) +static const ::rtl::OUString PROP_MULTISELECTION_MODE = ::rtl::OUString::createFromAscii("multiselection_mode"); // [sal_Bool] true=ON, false=OFF +static const ::rtl::OUString PROP_TITLE = ::rtl::OUString::createFromAscii("title" ); // [OUString] +static const ::rtl::OUString PROP_FILENAME = ::rtl::OUString::createFromAscii("filename" ); // [OUString] +static const ::rtl::OUString PROP_DIRECTORY = ::rtl::OUString::createFromAscii("directory" ); // [OUString] +static const ::rtl::OUString PROP_FEATURES = ::rtl::OUString::createFromAscii("features" ); // [sal_Int32] +static const ::rtl::OUString PROP_TEMPLATE_DESCR = ::rtl::OUString::createFromAscii("templatedescription"); // [sal_Int32] +static const ::rtl::OUString PROP_FILTER_TITLE = ::rtl::OUString::createFromAscii("filter_title" ); // [OUString] +static const ::rtl::OUString PROP_FILTER_VALUE = ::rtl::OUString::createFromAscii("filter_value" ); // [OUString] +static const ::rtl::OUString PROP_FORCE = ::rtl::OUString::createFromAscii("force" ); // [sal_Bool] + +static const ::rtl::OUString PROP_CONTROL_ID = ::rtl::OUString::createFromAscii("control_id" ); // [sal_Int16] +static const ::rtl::OUString PROP_CONTROL_ACTION = ::rtl::OUString::createFromAscii("control_action" ); // [sal_Int16] +static const ::rtl::OUString PROP_CONTROL_VALUE = ::rtl::OUString::createFromAscii("control_value" ); // [Any] +static const ::rtl::OUString PROP_CONTROL_LABEL = ::rtl::OUString::createFromAscii("control_label" ); // [OUString] +static const ::rtl::OUString PROP_CONTROL_ENABLE = ::rtl::OUString::createFromAscii("control_enable" ); // [sal_Bool] true=ON, false=OFF + +//----------------------------------------------------------------------------- +/** native implementation of the file picker on Vista and upcoming windows versions. + * This dialog uses COM internaly. Further it marshall every request so it will + * be executed within it's own STA thread ! + */ +//----------------------------------------------------------------------------- +class VistaFilePickerImpl : private ::cppu::BaseMutex + , public RequestHandler + , public IVistaFilePickerInternalNotify +{ + public: + + //--------------------------------------------------------------------- + /** used for marshalling requests. + * Will be used to map requests to the right implementations. + */ + enum ERequest + { + E_NO_REQUEST, + E_ADD_PICKER_LISTENER, + E_REMOVE_PICKER_LISTENER, + E_APPEND_FILTER, + E_SET_CURRENT_FILTER, + E_GET_CURRENT_FILTER, + E_CREATE_OPEN_DIALOG, + E_CREATE_SAVE_DIALOG, + E_SET_MULTISELECTION_MODE, + E_SET_TITLE, + E_SET_FILENAME, + E_GET_DIRECTORY, + E_SET_DIRECTORY, + E_SET_DEFAULT_NAME, + E_GET_SELECTED_FILES, + E_SHOW_DIALOG_MODAL, + E_SET_CONTROL_VALUE, + E_GET_CONTROL_VALUE, + E_SET_CONTROL_LABEL, + E_GET_CONTROL_LABEL, + E_ENABLE_CONTROL + }; + + public: + + //--------------------------------------------------------------------- + // ctor/dtor - nothing special + //--------------------------------------------------------------------- + VistaFilePickerImpl(); + virtual ~VistaFilePickerImpl(); + + //--------------------------------------------------------------------- + // RequestHandler + //--------------------------------------------------------------------- + + virtual void before(); + virtual void doRequest(const RequestRef& rRequest); + virtual void after(); + + //--------------------------------------------------------------------- + virtual void onAutoExtensionChanged (bool bChecked); + + private: + + //--------------------------------------------------------------------- + /// implementation of request E_ADD_FILEPICKER_LISTENER + void impl_sta_addFilePickerListener(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_REMOVE_FILEPICKER_LISTENER + void impl_sta_removeFilePickerListener(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_APPEND_FILTER + void impl_sta_appendFilter(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_SET_CURRENT_FILTER + void impl_sta_setCurrentFilter(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_GET_CURRENT_FILTER + void impl_sta_getCurrentFilter(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_CREATE_OPEN_DIALOG + void impl_sta_CreateOpenDialog(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_CREATE_SAVE_DIALOG + void impl_sta_CreateSaveDialog(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_SET_MULTISELECTION_MODE + void impl_sta_SetMultiSelectionMode(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_SET_TITLE + void impl_sta_SetTitle(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_SET_FILENAME + void impl_sta_SetFileName(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_SET_DIRECTORY + void impl_sta_SetDirectory(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_GET_DIRECTORY + void impl_sta_GetDirectory(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_SET_DEFAULT_NAME + void impl_sta_SetDefaultName(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_GET_SELECTED_FILES + void impl_sta_getSelectedFiles(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_SHOW_DIALOG_MODAL + void impl_sta_ShowDialogModal(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_SET_CONTROL_VALUE + void impl_sta_SetControlValue(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_GET_CONTROL_VALUE + void impl_sta_GetControlValue(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_SET_CONTROL_LABEL + void impl_sta_SetControlLabel(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_GET_CONTROL_LABEL + void impl_sta_GetControlLabel(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /// implementation of request E_ENABLE_CONTROL + void impl_sta_EnableControl(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /** create all needed (optional!) UI controls adressed by the field nFeatures. + * The given number nFeatures is used as a flag field. Use const values FEATURE_XXX + * to adress it. + * + * Internal new controls will be added to the dialog. Every control can be accessed + * by it's own control id. Those control ID must be one of the const set + * css::ui::dialogs::ExtendedFilePickerElementIds. + * + * @see setControlValue() + * @see getControlValue() + * @see setControlLabel() + * @see getControlLabel() + * @see enableControl() + * + * @param nFeatures + * flag field(!) knows all features wich must be enabled. + */ + void impl_sta_enableFeatures(::sal_Int32 nFeatures, ::sal_Int32 nTemplate); + + //--------------------------------------------------------------------- + /** returns an interface, which can be used to customize the internaly used + * COM dialog. + * + * Because we use two member (open/save dialog) internaly, this method + * ask the current active one for it's customization interface. + * + * @return the customization interface for the current used dialog. + * Must not be null. + */ + TFileDialogCustomize impl_getCustomizeInterface(); + TFileDialog impl_getBaseDialogInterface(); + + //--------------------------------------------------------------------- + /// fill filter list of internal used dialog. + void impl_sta_setFiltersOnDialog(); + + void impl_SetDefaultExtension( const rtl::OUString& currentFilter ); + + private: + + //--------------------------------------------------------------------- + /// COM object representing a file open dialog + TFileOpenDialog m_iDialogOpen; + + //--------------------------------------------------------------------- + /// COM object representing a file save dialog + TFileSaveDialog m_iDialogSave; + + //--------------------------------------------------------------------- + /// knows the return state of the last COM call + HRESULT m_hLastResult; + + //--------------------------------------------------------------------- + /// @todo document me + CFilterContainer m_lFilters; + + //--------------------------------------------------------------------- + /** cache last selected list of files + * Because those list must be retrieved directly after closing the dialog + * (and only in case it was finished successfully) we cache it internaly. + * Because the outside provided UNO API decouple showing the dialog + * and asking for results .-) + */ + css::uno::Sequence< ::rtl::OUString > m_lLastFiles; + + //--------------------------------------------------------------------- + /** help us to handle dialog events and provide them to interested office + * listener. + */ + TFileDialogEvents m_iEventHandler; + + //--------------------------------------------------------------------- + /// @todo document me + ::sal_Bool m_bInExecute; + + ::sal_Bool m_bWasExecuted; + + // handle to parent window + HWND m_hParentWindow; + + // + ::rtl::OUString m_sDirectory; + + // + ::rtl::OUString m_sFilename; + + // Resource provider + CResourceProvider m_ResProvider; +}; + +} // namespace vista +} // namespace win32 +} // namespace fpicker + +#undef css + +#endif // FPICKER_WIN32_VISTA_FILEPICKERIMPL_HXX diff --git a/fpicker/source/win32/filepicker/WinFileOpenImpl.cxx b/fpicker/source/win32/filepicker/WinFileOpenImpl.cxx new file mode 100644 index 000000000000..d5bcce4707f4 --- /dev/null +++ b/fpicker/source/win32/filepicker/WinFileOpenImpl.cxx @@ -0,0 +1,996 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#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" + +#ifndef _FILEPICKER_HXX_ +#include "filepicker.hxx" +#endif +#include "controlaccess.hxx" +#include <rtl/ustrbuf.hxx> +#include <rtl/string.hxx> +#include <osl/thread.hxx> +#include "filepickerstate.hxx" + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using namespace com::sun::star; + +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 +{ + INIT_CUSTOM_CONTROLS, + CACHE_CONTROL_VALUES +}; + +struct EnumParam +{ + ECW_ACTION_T m_action; + CWinFileOpenImpl* m_instance; + + EnumParam( ECW_ACTION_T action, CWinFileOpenImpl* instance ): + m_action( action ), + m_instance( instance ) + {} +}; + +//------------------------------------------------------------------------- +// ctor +//------------------------------------------------------------------------- + +CWinFileOpenImpl::CWinFileOpenImpl( + CFilePicker* aFilePicker, + sal_Bool bFileOpenDialog, + sal_uInt32 dwFlags, + sal_uInt32 dwTemplateId, + HINSTANCE hInstance) : + CFileOpenDialog(bFileOpenDialog, dwFlags, dwTemplateId, hInstance), + m_filterContainer(new CFilterContainer()), + m_Preview(new CPreviewAdapter(hInstance)), + m_CustomControlFactory(new CCustomControlFactory()), + m_CustomControls(m_CustomControlFactory->CreateCustomControlContainer()), + m_FilePicker(aFilePicker), + m_bInitialSelChanged(sal_True), + m_HelpPopupWindow(hInstance, m_hwndFileOpenDlg), + m_ExecuteFilePickerState(new CExecuteFilePickerState()), + m_NonExecuteFilePickerState(new CNonExecuteFilePickerState()) +{ + m_FilePickerState = m_NonExecuteFilePickerState; +} + +//------------------------------------------------------------------------ +// dtor +//------------------------------------------------------------------------ + +CWinFileOpenImpl::~CWinFileOpenImpl() +{ + delete m_ExecuteFilePickerState; + delete m_NonExecuteFilePickerState; +} + +//------------------------------------------------------------------------ +// we expect the directory in URL format +//------------------------------------------------------------------------ + +void CWinFileOpenImpl::setDisplayDirectory(const rtl::OUString& aDirectory) + throw( IllegalArgumentException, uno::RuntimeException ) +{ + rtl::OUString aSysDirectory; + if( aDirectory.getLength() > 0) + { + if ( ::osl::FileBase::E_None != + ::osl::FileBase::getSystemPathFromFileURL(aDirectory,aSysDirectory)) + throw IllegalArgumentException( + rtl::OUString::createFromAscii("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 + // hierarchie which is the desktop folder + if ( aSysDirectory.lastIndexOf(BACKSLASH) != (aSysDirectory.getLength() - 1)) + aSysDirectory += BACKSLASH; + } + + // call base class method + CFileOpenDialog::setDisplayDirectory(aSysDirectory); +} + +//------------------------------------------------------------------------ +// we return the directory in URL format +//------------------------------------------------------------------------ + +rtl::OUString CWinFileOpenImpl::getDisplayDirectory() throw(uno::RuntimeException) +{ + return m_FilePickerState->getDisplayDirectory(this); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::setDefaultName(const rtl::OUString& aName) + 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<rtl::OUString> SAL_CALL CWinFileOpenImpl::getFiles() + throw(uno::RuntimeException) +{ + return m_FilePickerState->getFiles(this); +} + +//----------------------------------------------------------------------------------------- +// shows the FileOpen/FileSave dialog +//----------------------------------------------------------------------------------------- + +sal_Int16 SAL_CALL CWinFileOpenImpl::execute( ) throw(uno::RuntimeException) +{ + sal_Int16 rc = CFileOpenDialog::doModal(); + + if (1 == rc) + rc = ::com::sun::star::ui::dialogs::ExecutableDialogResults::OK; + else if (0 == rc) + rc = ::com::sun::star::ui::dialogs::ExecutableDialogResults::CANCEL; + else + throw uno::RuntimeException( + rtl::OUString::createFromAscii("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 rtl::OUString& aTitle, const rtl::OUString& aFilter) + throw(IllegalArgumentException, uno::RuntimeException) +{ + sal_Bool bRet = m_filterContainer->addFilter(aTitle, aFilter); + + if (!bRet) + throw IllegalArgumentException( + rtl::OUString::createFromAscii("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 + if (0 == getSelectedFilterIndex()) + CFileOpenDialog::setFilterIndex(1); +} + +//----------------------------------------------------------------------------------------- +// sets a current filter +//----------------------------------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::setCurrentFilter(const rtl::OUString& aTitle) + throw( IllegalArgumentException, uno::RuntimeException) +{ + sal_Int32 filterPos = m_filterContainer->getFilterPos(aTitle); + + if (filterPos < 0) + throw IllegalArgumentException( + rtl::OUString::createFromAscii("filter doesn't exist"), + static_cast<XFilePicker2*>(m_FilePicker), 1); + + // filter index of the base class starts with 1 + CFileOpenDialog::setFilterIndex(filterPos + 1); +} + +//----------------------------------------------------------------------------------------- +// returns the currently selected filter +//----------------------------------------------------------------------------------------- + +rtl::OUString SAL_CALL CWinFileOpenImpl::getCurrentFilter() throw(uno::RuntimeException) +{ + sal_uInt32 nIndex = getSelectedFilterIndex(); + + rtl::OUString currentFilter; + if (nIndex > 0) + { + // filter index of the base class starts with 1 + if (!m_filterContainer->getFilter(nIndex - 1, currentFilter)) { + OSL_ASSERT(false); + } + } + + return currentFilter; +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +inline void SAL_CALL CWinFileOpenImpl::appendFilterGroupSeparator() +{ + m_filterContainer->addFilter(FILTER_SEPARATOR, ALL_FILES_WILDCARD, ALLOW_DUPLICATES); +} + +//----------------------------------------------------------------------------------------- +// XFilterGroupManager +//----------------------------------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::appendFilterGroup(const rtl::OUString& sGroupTitle, const uno::Sequence<beans::StringPair>& aFilters) + throw (IllegalArgumentException, uno::RuntimeException) +{ + (void) sGroupTitle; // avoid warning + OSL_ENSURE(0 == sGroupTitle.getLength(), "appendFilterGroup: Parameter 'GroupTitle' currently ignored"); + + sal_Int32 nFilters = aFilters.getLength(); + + OSL_PRECOND(nFilters > 0, "Empty filter list"); + + if (nFilters > 0) + { + // append a separator before the next group if + // there is already a group of filters + if (m_filterContainer->numFilter() > 0) + appendFilterGroupSeparator(); + + for (int i = 0; i < nFilters; i++) + appendFilter(aFilters[i].First, aFilters[i].Second); + } +} + +//================================================================================================================= +// XExtendedFilePicker +//================================================================================================================= + +void SAL_CALL CWinFileOpenImpl::setValue(sal_Int16 aControlId, sal_Int16 aControlAction, const uno::Any& aValue) + throw(uno::RuntimeException) +{ + OSL_ASSERT(m_FilePickerState); + m_FilePickerState->setValue(aControlId, aControlAction, aValue); +} + +//----------------------------------------------------------------------------------------- +// returns the value of an custom template element +// we assume that there are only checkboxes or comboboxes +//----------------------------------------------------------------------------------------- + +uno::Any SAL_CALL CWinFileOpenImpl::getValue(sal_Int16 aControlId, sal_Int16 aControlAction) + throw(uno::RuntimeException) +{ + OSL_ASSERT(m_FilePickerState); + return m_FilePickerState->getValue(aControlId, aControlAction); +} + +//----------------------------------------------------------------------------------------- +// enables a custom template element +//----------------------------------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::enableControl(sal_Int16 ControlID, sal_Bool bEnable) + throw(uno::RuntimeException) +{ + OSL_ASSERT(m_FilePickerState); + m_FilePickerState->enableControl(ControlID, bEnable); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::setLabel( sal_Int16 aControlId, const rtl::OUString& aLabel ) + throw (uno::RuntimeException) +{ + m_FilePickerState->setLabel(aControlId, aLabel); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +rtl::OUString SAL_CALL CWinFileOpenImpl::getLabel( sal_Int16 aControlId ) + throw (uno::RuntimeException) +{ + return m_FilePickerState->getLabel(aControlId); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +uno::Sequence<sal_Int16> SAL_CALL CWinFileOpenImpl::getSupportedImageFormats() + throw (uno::RuntimeException) +{ + return m_Preview->getSupportedImageFormats(); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +sal_Int32 SAL_CALL CWinFileOpenImpl::getTargetColorDepth() + throw (uno::RuntimeException) +{ + return m_Preview->getTargetColorDepth(); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +sal_Int32 SAL_CALL CWinFileOpenImpl::getAvailableWidth() + throw (uno::RuntimeException) +{ + return m_Preview->getAvailableWidth(); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +sal_Int32 SAL_CALL CWinFileOpenImpl::getAvailableHeight() + throw (uno::RuntimeException) +{ + return m_Preview->getAvailableHeight(); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::setImage(sal_Int16 aImageFormat, const uno::Any& aImage) + throw (IllegalArgumentException, uno::RuntimeException) +{ + m_Preview->setImage(aImageFormat,aImage); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +sal_Bool SAL_CALL CWinFileOpenImpl::setShowState(sal_Bool bShowState) + throw (uno::RuntimeException) +{ + return m_Preview->setShowState(bShowState); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +sal_Bool SAL_CALL CWinFileOpenImpl::getShowState() + throw (uno::RuntimeException) +{ + return m_Preview->getShowState(); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::cancel() +{ + if (IsWindow(m_hwndFileOpenDlg)) + { + // simulate a mouse click to the + // cancel button + PostMessage( + m_hwndFileOpenDlg, + WM_COMMAND, + MAKEWPARAM(IDCANCEL,BN_CLICKED), + (LPARAM)GetDlgItem(m_hwndFileOpenDlg, IDCANCEL)); + } +} + +//----------------------------------------------------------------------------------------- +// returns the id of a custom template element +//----------------------------------------------------------------------------------------- + +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) + if (nID >= ctlFirst) + nID = 0; + + return sal::static_int_cast< sal_Int16 >(nID); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +inline sal_Bool SAL_CALL CWinFileOpenImpl::IsCustomControlHelpRequested(LPHELPINFO lphi) const +{ + 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) +{ + unsigned int lResult = 0; + + CWinFileOpenImpl* pImpl = dynamic_cast<CWinFileOpenImpl*>(getCurrentInstance(hWnd)); + + switch(wMessage) + { + case WM_HELP: + { + LPHELPINFO lphi = reinterpret_cast<LPHELPINFO>(lParam); + + if (pImpl->IsCustomControlHelpRequested(lphi)) + pImpl->onCustomControlHelpRequest(lphi); + else + lResult = CallWindowProc( + reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc), + hWnd,wMessage,wParam,lParam); + } + break; + + case WM_SIZE: + lResult = CallWindowProc( + reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc), + hWnd,wMessage,wParam,lParam); + + pImpl->onWMSize(); + break; + + case WM_WINDOWPOSCHANGED: + lResult = CallWindowProc( + reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc), + hWnd,wMessage,wParam,lParam); + + pImpl->onWMWindowPosChanged(); + break; + + case WM_SHOWWINDOW: + lResult = CallWindowProc( + reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc), + hWnd,wMessage,wParam,lParam); + + pImpl->onWMShow((BOOL)wParam); + break; + + case WM_NCDESTROY: + // restore the old window proc + SetWindowLong(hWnd, GWL_WNDPROC, + reinterpret_cast<LONG>(pImpl->m_pfnOldDlgProc)); + + lResult = CallWindowProc( + reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc), + hWnd,wMessage,wParam,lParam); + break; + + default: + lResult = CallWindowProc( + reinterpret_cast<WNDPROC>(pImpl->m_pfnOldDlgProc), + hWnd,wMessage,wParam,lParam); + break; + + } // switch + + return lResult; +} + +//----------------------------------------------------------------- +// +//----------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::InitControlLabel(HWND hWnd) +{ + //----------------------------------------- + // set the labels for all extendet controls + //----------------------------------------- + + sal_Int16 aCtrlId = sal::static_int_cast< sal_Int16 >(GetDlgCtrlID(hWnd)); + rtl::OUString aLabel = m_ResProvider.getResString(aCtrlId); + if (aLabel.getLength()) + setLabel(aCtrlId, aLabel); +} + +//----------------------------------------------------------------- +// 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 (defined in MS platform sdk dlgs.h) +// and all push buttons will be left aligned with the standard +// "OK" button +//----------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::InitCustomControlContainer(HWND hCustomControl) +{ + m_CustomControls->AddControl( + m_CustomControlFactory->CreateCustomControl(hCustomControl,m_hwndFileOpenDlg)); +} + +//----------------------------------------------------------------- +// +//----------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::CacheControlState(HWND hWnd) +{ + OSL_ASSERT(m_FilePickerState && m_NonExecuteFilePickerState); + m_ExecuteFilePickerState->cacheControlState(hWnd, m_NonExecuteFilePickerState); +} + +//----------------------------------------------------------------- +// +//----------------------------------------------------------------- + +BOOL CALLBACK CWinFileOpenImpl::EnumChildWndProc(HWND hWnd, LPARAM lParam) +{ + EnumParam* enumParam = (EnumParam*)lParam; + CWinFileOpenImpl* pImpl = enumParam->m_instance; + + OSL_ASSERT(pImpl); + + BOOL bRet = TRUE; + + switch(enumParam->m_action) + { + case INIT_CUSTOM_CONTROLS: + pImpl->InitControlLabel(hWnd); + pImpl->InitCustomControlContainer(hWnd); + break; + + case CACHE_CONTROL_VALUES: + pImpl->CacheControlState(hWnd); + break; + + default: + // should not end here + OSL_ASSERT(sal_False); + } + + return bRet; +} + +//----------------------------------------------------------------- +// +//----------------------------------------------------------------- + +sal_uInt32 SAL_CALL CWinFileOpenImpl::onFileOk() +{ + m_NonExecuteFilePickerState->reset(); + + EnumParam enumParam(CACHE_CONTROL_VALUES,this); + + EnumChildWindows( + m_hwndFileOpenDlgChild, + CWinFileOpenImpl::EnumChildWndProc, + (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 + // remeber that this is the first SelChanged message + // and set the default name here to overwrite the + // windows setting + InitialSetDefaultName(); + + FilePickerEvent evt; + 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); // under Win98 it is edt1 instead of cmb13 + + 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); + + const int MAX_GAP = IsWindows98() ? 5 : 10; + const int OFFSET = IsWindows98() ? 10 : 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, (LPPOINT)&rcFileNameBox); + MoveWindow(hFileNameBox, rcFileNameBox.left + gap + OFFSET, rcFileNameBox.top, w - OFFSET, h, true); + + RECT rcFilterBox; + GetWindowRect(hFilterBox, &rcFilterBox); + w = rcFilterBox.right - rcFilterBox.left; + h = rcFilterBox.bottom - rcFilterBox.top; + ScreenToClient(m_hwndFileOpenDlg, (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, (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, (LPPOINT)&rcFileNameBoxLabel); + MoveWindow(hFileNameBoxLabel, rcFileNameBoxLabel.left, rcFileNameBoxLabel.top, w, h, true); +} + +void SAL_CALL CWinFileOpenImpl::onInitDone() +{ + m_Preview->setParent(m_hwndFileOpenDlg); + + // 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 + + EnumParam enumParam(INIT_CUSTOM_CONTROLS,this); + + EnumChildWindows( + m_hwndFileOpenDlgChild, + CWinFileOpenImpl::EnumChildWndProc, + (LPARAM)&enumParam); + + m_ExecuteFilePickerState->initFilePickerControls( + m_NonExecuteFilePickerState->getControlCommand()); + + SetDefaultExtension(); + + m_CustomControls->Align(); + + m_CustomControls->SetFont( + reinterpret_cast<HFONT>(SendMessage(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 + PostMessage( + HWND_BROADCAST, + RegisterWindowMessage(TEXT("SYSTEM_WINDOW_ACTIVATED")), + 0, + 0); + + // call the parent function to center the + // dialog to it's parent + CFileOpenDialog::onInitDone(); +} + +//----------------------------------------------------------------- +// +//----------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::onFolderChanged() +{ + FilePickerEvent evt; + m_FilePicker->directoryChanged(evt); +} + +//----------------------------------------------------------------- +// +//----------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::onTypeChanged(sal_uInt32) +{ + SetDefaultExtension(); + + FilePickerEvent evt; + evt.ElementId = LISTBOX_FILTER; + m_FilePicker->controlStateChanged(evt); +} + +//----------------------------------------------------------------------------------------- +// onMessageCommand handler +//----------------------------------------------------------------------------------------- + +sal_uInt32 SAL_CALL CWinFileOpenImpl::onCtrlCommand( + HWND, sal_uInt16 ctrlId, sal_uInt16) +{ + SetDefaultExtension(); + + if (ctrlId < ctlFirst) + { + FilePickerEvent evt; + evt.ElementId = ctrlId; + m_FilePicker->controlStateChanged(evt); + } + + return 0; +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void CWinFileOpenImpl::onWMSize() +{ + m_Preview->notifyParentSizeChanged(); + m_CustomControls->Align(); + m_FilePicker->dialogSizeChanged(); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void CWinFileOpenImpl::onWMShow(BOOL bShow) +{ + m_Preview->notifyParentShow(bShow); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void CWinFileOpenImpl::onWMWindowPosChanged() +{ + m_Preview->notifyParentWindowPosChanged(); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void CWinFileOpenImpl::onCustomControlHelpRequest(LPHELPINFO lphi) +{ + FilePickerEvent evt; + evt.ElementId = sal::static_int_cast< sal_Int16 >(lphi->iCtrlId); + + rtl::OUString aPopupHelpText = m_FilePicker->helpRequested(evt); + + 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>( + SetWindowLong( hwndDlg, GWL_WNDPROC, + reinterpret_cast<LONG>(SubClassFunc))); +} + +//----------------------------------------------------------------------------------------- +// processing before showing the dialog +//----------------------------------------------------------------------------------------- + +bool SAL_CALL CWinFileOpenImpl::preModal() +{ + CFileOpenDialog::setFilter( + makeWinFilterBuffer(*m_filterContainer.get())); + + return true; +} + +//----------------------------------------------------------------------------------------- +// processing after showing the dialog +//----------------------------------------------------------------------------------------- + +void CWinFileOpenImpl::postModal(sal_Int16 nDialogResult) +{ + CFileOpenDialog::postModal(nDialogResult); + + // 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; +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CWinFileOpenImpl::SetDefaultExtension() +{ + HWND hwndChkSaveWithExt = GetDlgItem(m_hwndFileOpenDlgChild, 100); + + if (hwndChkSaveWithExt) + { + uno::Any aAny = CheckboxGetState(hwndChkSaveWithExt); + sal_Bool bChecked = *reinterpret_cast<const sal_Bool*>(aAny.getValue()); + + if (bChecked) + { + sal_uInt32 nIndex = getSelectedFilterIndex(); + + rtl::OUString currentFilter; + if (nIndex > 0) + { + // filter index of the base class starts with 1 + m_filterContainer->getFilter(nIndex - 1, currentFilter); + + if (currentFilter.getLength()) + { + rtl::OUString FilterExt; + m_filterContainer->getFilter(currentFilter, FilterExt); + + sal_Int32 posOfPoint = FilterExt.indexOf(L'.'); + const sal_Unicode* pFirstExtStart = FilterExt.getStr() + posOfPoint + 1; + + sal_Int32 posOfSemiColon = FilterExt.indexOf(L';') - 1; + if (posOfSemiColon < 0) + posOfSemiColon = FilterExt.getLength() - 1; + + FilterExt = rtl::OUString(pFirstExtStart, posOfSemiColon - posOfPoint); + + SendMessage(m_hwndFileOpenDlg, CDM_SETDEFEXT, 0, reinterpret_cast<LPARAM>(FilterExt.getStr())); + } + } + } + else + { + SendMessage(m_hwndFileOpenDlg, CDM_SETDEFEXT, 0, reinterpret_cast<LPARAM>(TEXT(""))); + } + } + + // !!! HACK !!! +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +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) + if (m_bInitialSelChanged && m_defaultName.getLength()) + { + sal_Int32 edt1Id = edt1; + + // under W2k the 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 so we must use this id + if (IsWindows2000Platform()) + edt1Id = cmb13; + + HWND hwndEdt1 = GetDlgItem(m_hwndFileOpenDlg, edt1Id); + SetWindowText(hwndEdt1, reinterpret_cast<LPCTSTR>(m_defaultName.getStr())); + } + + m_bInitialSelChanged = sal_False; +} diff --git a/fpicker/source/win32/filepicker/WinFileOpenImpl.hxx b/fpicker/source/win32/filepicker/WinFileOpenImpl.hxx new file mode 100644 index 000000000000..61d63952f8c7 --- /dev/null +++ b/fpicker/source/win32/filepicker/WinFileOpenImpl.hxx @@ -0,0 +1,234 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _WINFILEOPENIMPL_HXX_ +#define _WINFILEOPENIMPL_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#ifndef _COM_SUN_STAR_UI_DIALOGS_XEXTENDEDFILEPICKER_HPP_ +#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> +#endif +#include <com/sun/star/ui/dialogs/FilePickerEvent.hpp> +#include <com/sun/star/ui/dialogs/XFilterGroupManager.hpp> +#include "FilterContainer.hxx" +#include "FileOpenDlg.hxx" +#include "previewadapter.hxx" +#include "helppopupwindow.hxx" +#include "customcontrol.hxx" +#include "customcontrolfactory.hxx" +#include "..\misc\resourceprovider.hxx" + +#include <utility> +#include <memory> +#include <vector> +#include <osl/conditn.hxx> + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +// forward declaration +class CFilePicker; +class CFilePickerState; +class CExecuteFilePickerState; +class CNonExecuteFilePickerState; + +class CWinFileOpenImpl : public CFileOpenDialog +{ +public: + CWinFileOpenImpl( + CFilePicker* aFilePicker, + sal_Bool bFileOpenDialog = sal_True, + sal_uInt32 dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, + sal_uInt32 dwTemplateId = 0, + HINSTANCE hInstance = 0 ); + + virtual ~CWinFileOpenImpl( ); + + //----------------------------------------------------------------------------------------- + // XExecutableDialog + //----------------------------------------------------------------------------------------- + + virtual sal_Int16 SAL_CALL execute( ) throw( ::com::sun::star::uno::RuntimeException ); + + //----------------------------------------------------------------------------------------- + // XFilePicker + //----------------------------------------------------------------------------------------- + + virtual void SAL_CALL setDefaultName( const ::rtl::OUString& aName ) + throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getFiles( ) + throw(::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL setDisplayDirectory( const ::rtl::OUString& aDirectory ) + throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ); + + virtual ::rtl::OUString SAL_CALL getDisplayDirectory( ) throw ( ::com::sun::star::uno::RuntimeException ); + + //----------------------------------------------------------------------------------------- + // XFilterManager + //----------------------------------------------------------------------------------------- + + virtual void SAL_CALL appendFilter( const ::rtl::OUString& aTitle, const ::rtl::OUString& aFilter ) + throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL setCurrentFilter( const ::rtl::OUString& aTitle ) + throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ); + + virtual ::rtl::OUString SAL_CALL getCurrentFilter( ) + throw( ::com::sun::star::uno::RuntimeException ); + + //----------------------------------------------------------------------------------------- + // XFilterGroupManager + //----------------------------------------------------------------------------------------- + + virtual void SAL_CALL appendFilterGroup( const ::rtl::OUString& sGroupTitle, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aFilters ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + //----------------------------------------------------------------------------------------- + // XFilePickerControlAccess + //----------------------------------------------------------------------------------------- + + virtual void SAL_CALL setValue( sal_Int16 aControlId, sal_Int16 aControlAction, const ::com::sun::star::uno::Any& aValue ) + throw( ::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Any SAL_CALL getValue( sal_Int16 aControlId, sal_Int16 aControlAction ) + throw( ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL enableControl( sal_Int16 aControlId, sal_Bool bEnable ) + throw( ::com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL setLabel( sal_Int16 aControlId, const ::rtl::OUString& aLabel ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::rtl::OUString SAL_CALL getLabel( sal_Int16 aControlId ) + throw ( ::com::sun::star::uno::RuntimeException); + + //------------------------------------------------ + // XFilePreview + //------------------------------------------------ + + virtual ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL getSupportedImageFormats( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getTargetColorDepth( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getAvailableWidth( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getAvailableHeight( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setImage( sal_Int16 aImageFormat, const ::com::sun::star::uno::Any& aImage ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL setShowState( sal_Bool bShowState ) + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL getShowState( ) + throw (::com::sun::star::uno::RuntimeException); + + //------------------------------------------------ + // XCancelable + //------------------------------------------------ + + virtual void SAL_CALL cancel( ); + + //------------------------------------------------ + // Implementation details + //------------------------------------------------ + +protected: + sal_Int16 SAL_CALL getFocused( ); + + virtual bool SAL_CALL preModal( ); + virtual void SAL_CALL postModal( sal_Int16 nDialogResult ); + + virtual sal_uInt32 SAL_CALL onFileOk(); + virtual void SAL_CALL onSelChanged( HWND hwndListBox ); + + // only called back if OFN_EXPLORER is set + virtual void SAL_CALL onInitDone(); + virtual void SAL_CALL onFolderChanged(); + virtual void SAL_CALL onTypeChanged( sal_uInt32 nFilterIndex ); + + // call base class method first when overloading + virtual void SAL_CALL onInitDialog( HWND hwndDlg ); + + virtual sal_uInt32 SAL_CALL onCtrlCommand( HWND hwndDlg, sal_uInt16 ctrlId, sal_uInt16 notifyCode ); + + + void onWMSize(); + void onWMShow(BOOL bShow); + void onWMWindowPosChanged(); + void onCustomControlHelpRequest(LPHELPINFO lphi); + +private: + inline void SAL_CALL appendFilterGroupSeparator( ); + + inline sal_Bool SAL_CALL IsCustomControlHelpRequested(LPHELPINFO lphi) const; + + void EnlargeStdControlLabels() const; + + // initialize all controls from cache + void SAL_CALL InitControlLabel( HWND hWnd ); + void SAL_CALL InitCustomControlContainer(HWND hCustomControl); + + // save the control state + void SAL_CALL CacheControlState(HWND hWnd); + + void SAL_CALL SetDefaultExtension(); + void SAL_CALL InitialSetDefaultName(); + + static LRESULT CALLBACK SubClassFunc(HWND hWnd, UINT wMessage, WPARAM wParam, LPARAM lParam); + + static BOOL CALLBACK EnumChildWndProc( HWND hWnd, LPARAM lParam ); + +private: + std::auto_ptr<CFilterContainer> m_filterContainer; + std::auto_ptr<CPreviewAdapter> m_Preview; + std::auto_ptr<CCustomControlFactory> m_CustomControlFactory; + std::auto_ptr<CCustomControl> m_CustomControls; + CFilePicker* m_FilePicker; + WNDPROC m_pfnOldDlgProc; + rtl::OUString m_defaultName; + sal_Bool m_bInitialSelChanged; + CHelpPopupWindow m_HelpPopupWindow; + CFilePickerState* m_FilePickerState; + CExecuteFilePickerState* m_ExecuteFilePickerState; + CNonExecuteFilePickerState* m_NonExecuteFilePickerState; + CResourceProvider m_ResProvider; +}; + + +#endif diff --git a/fpicker/source/win32/filepicker/afxres.h b/fpicker/source/win32/filepicker/afxres.h new file mode 100644 index 000000000000..0961c334dd41 --- /dev/null +++ b/fpicker/source/win32/filepicker/afxres.h @@ -0,0 +1,2 @@ +#include <windows.h> +#include <dlgs.h> diff --git a/fpicker/source/win32/filepicker/asynceventnotifier.cxx b/fpicker/source/win32/filepicker/asynceventnotifier.cxx new file mode 100644 index 000000000000..592c9e0c0e47 --- /dev/null +++ b/fpicker/source/win32/filepicker/asynceventnotifier.cxx @@ -0,0 +1,327 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> +#include "asynceventnotifier.hxx" +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerListener.hpp> + +#include <process.h> +#include <memory> +#include "SolarMutex.hxx" + +//------------------------------------------------ +// +//------------------------------------------------ + +using namespace com::sun::star; +using ::com::sun::star::ui::dialogs::XFilePickerListener; + +//------------------------------------------------ +// +//------------------------------------------------ + +CAsyncEventNotifier::CAsyncEventNotifier(cppu::OBroadcastHelper& rBroadcastHelper) : + m_hThread(0), + m_bRun(false), + m_ThreadId(0), + m_rBroadcastHelper(rBroadcastHelper), + m_NotifyEvent(m_hEvents[0]), + m_ResumeNotifying(m_hEvents[1]) +{ + // m_NotifyEvent + m_hEvents[0] = CreateEvent(0, /* no security */ + true, /* manual reset */ + false, /* initial state not signaled */ + 0); /* automatic name */ + + // m_ResumeNotifying + m_hEvents[1] = CreateEvent(0, /* no security */ + true, /* manual reset */ + false, /* initial state not signaled */ + 0); /* automatic name */ +} + +//------------------------------------------------ +// +//------------------------------------------------ + +CAsyncEventNotifier::~CAsyncEventNotifier() +{ + OSL_ENSURE(0 == m_hThread,"Thread not stopped, destroying this instance leads to desaster"); + + CloseHandle(m_hEvents[0]); + CloseHandle(m_hEvents[1]); +} + +//------------------------------------------------ +// +//------------------------------------------------ + +void SAL_CALL CAsyncEventNotifier::addListener(const uno::Type& aType , + const uno::Reference< uno::XInterface >& xListener) +{ + if ( m_rBroadcastHelper.bDisposed ) + throw lang::DisposedException( + ::rtl::OUString::createFromAscii( "FilePicker is already disposed" ), + uno::Reference< uno::XInterface >() ); + + if ( m_rBroadcastHelper.bInDispose ) + throw lang::DisposedException( + ::rtl::OUString::createFromAscii( "FilePicker will be disposed now." ), + uno::Reference< uno::XInterface >() ); + + m_rBroadcastHelper.aLC.addInterface( aType, xListener ); +} + +//------------------------------------------------ +// +//------------------------------------------------ + +void SAL_CALL CAsyncEventNotifier::removeListener(const uno::Type& aType , + const uno::Reference< uno::XInterface >& xListener) +{ + if ( m_rBroadcastHelper.bDisposed ) + throw lang::DisposedException( + ::rtl::OUString::createFromAscii( "FilePicker is already disposed." ), + uno::Reference< uno::XInterface >() ); + + m_rBroadcastHelper.aLC.removeInterface( aType, xListener ); +} + +//------------------------------------------------ +// +//------------------------------------------------ + +bool SAL_CALL CAsyncEventNotifier::startup(bool bCreateSuspended) +{ + osl::MutexGuard aGuard(m_Mutex); + + // m_bRun may already be false because of a + // call to stop but the thread did not yet + // terminate so m_hEventNotifierThread is + // yet a valid thread handle that should + // not be overwritten + if (!m_bRun) + { + if (!bCreateSuspended) + SetEvent(m_ResumeNotifying); + + m_hThread = (HANDLE)_beginthreadex( + NULL, 0, CAsyncEventNotifier::ThreadProc, this, 0, &m_ThreadId); + + OSL_ASSERT(0 != m_hThread); + + if (m_hThread) + m_bRun = true; + } + + OSL_POSTCOND(m_bRun,"Could not start event notifier!"); + + return m_bRun; +} + +//------------------------------------------------ +// +//------------------------------------------------ + +void SAL_CALL CAsyncEventNotifier::shutdown() +{ + unsigned nThreadId = GetCurrentThreadId(); + + OSL_PRECOND(nThreadId != m_ThreadId, "Method called in wrong thread context!"); + + osl::ResettableMutexGuard aGuard(m_Mutex); + + OSL_PRECOND(m_bRun,"Event notifier does not run!"); + + m_bRun = false; + m_EventList.clear(); + + // awake the the notifier thread + SetEvent(m_ResumeNotifying); + SetEvent(m_NotifyEvent); + + // releas the mutex here because the event + // notifier thread may need it to finish + aGuard.clear(); + + // we are waiting infinite, so error will + // be better detected in form of deadlocks + if (WaitForSingleObject(m_hThread, INFINITE) == WAIT_FAILED) { + OSL_ENSURE(false, "Waiting for thread termination failed!"); + } + + // lock mutex again to reset m_hThread + // and prevent a race with start() + aGuard.reset(); + + CloseHandle(m_hThread); + m_hThread = 0; +} + +//------------------------------------------------ +// +//------------------------------------------------ + +void CAsyncEventNotifier::suspend() +{ + ResetEvent(m_ResumeNotifying); +} + +//------------------------------------------------ +// +//------------------------------------------------ + +void CAsyncEventNotifier::resume() +{ + SetEvent(m_ResumeNotifying); +} + +//------------------------------------------------ +// +//------------------------------------------------ + +void SAL_CALL CAsyncEventNotifier::notifyEvent(CEventNotification* EventNotification) +{ + osl::MutexGuard aGuard(m_Mutex); + + OSL_ENSURE(m_bRun,"Event notifier is not running!"); + + if (m_bRun) + { + m_EventList.push_back(EventNotification); + SetEvent(m_NotifyEvent); + } +} + +//------------------------------------------------ +// +//------------------------------------------------ + +size_t SAL_CALL CAsyncEventNotifier::getEventListSize() +{ + osl::MutexGuard aGuard(m_Mutex); + return m_EventList.size(); +} + +//------------------------------------------------ +// +//------------------------------------------------ + +void SAL_CALL CAsyncEventNotifier::resetNotifyEvent() +{ + osl::MutexGuard aGuard(m_Mutex); + if (0 == m_EventList.size()) + ResetEvent(m_NotifyEvent); +} + +//------------------------------------------------ +// +//------------------------------------------------ + +CEventNotification* SAL_CALL CAsyncEventNotifier::getNextEventRecord() +{ + osl::MutexGuard aGuard(m_Mutex); + return m_EventList.front(); +} + +//------------------------------------------------ +// +//------------------------------------------------ + +void SAL_CALL CAsyncEventNotifier::removeNextEventRecord() +{ + osl::MutexGuard aGuard(m_Mutex); + m_EventList.pop_front(); +} + +//------------------------------------------------ +// +//------------------------------------------------ + +void SAL_CALL CAsyncEventNotifier::run() +{ + while (m_bRun) + { + WaitForMultipleObjects(2, m_hEvents, true, INFINITE); + + if (m_bRun) + { + while (getEventListSize() > 0) + { + std::auto_ptr<CEventNotification> EventNotification(getNextEventRecord()); + removeNextEventRecord(); + + ::cppu::OInterfaceContainerHelper* pICHelper = + m_rBroadcastHelper.getContainer(getCppuType((uno::Reference<XFilePickerListener>*)0)); + + if (pICHelper) + { + ::cppu::OInterfaceIteratorHelper iter(*pICHelper); + + while(iter.hasMoreElements()) + { + try + { + EventNotification->notifyEventListener(iter.next()); + } + catch(uno::RuntimeException&) + { + OSL_ENSURE(sal_False,"RuntimeException during event dispatching"); + } + } + } + + } // while(getEventListSize() > 0) + + resetNotifyEvent(); + + } // if (m_bRun) + + } // while(m_bRun) +} + +//------------------------------------------------ +// +//------------------------------------------------ + +unsigned int WINAPI CAsyncEventNotifier::ThreadProc(LPVOID pParam) +{ + CAsyncEventNotifier* pInst = reinterpret_cast< CAsyncEventNotifier* >(pParam); + OSL_ASSERT(pInst); + + pInst->run(); + + return 0; +} diff --git a/fpicker/source/win32/filepicker/asynceventnotifier.hxx b/fpicker/source/win32/filepicker/asynceventnotifier.hxx new file mode 100644 index 000000000000..5b8854aae38c --- /dev/null +++ b/fpicker/source/win32/filepicker/asynceventnotifier.hxx @@ -0,0 +1,109 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _ASYNCEVENTNOTIFIER_HXX_ +#define _ASYNCEVENTNOTIFIER_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <osl/mutex.hxx> +#include <osl/conditn.hxx> +#include <cppuhelper/interfacecontainer.h> + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +#include <list> +#include <utility> +#include "eventnotification.hxx" + +//--------------------------------------------- +// +//--------------------------------------------- + +class CAsyncEventNotifier +{ +public: + CAsyncEventNotifier(cppu::OBroadcastHelper& rBroadcastHelper); + ~CAsyncEventNotifier(); + + bool SAL_CALL startup(bool bCreateSuspended = true); + void SAL_CALL shutdown(); + + // notifications may be added the + // the event queue but will only + // be notified to the clients after + // resume was called + void suspend(); + + // resume notifying events + void resume(); + + // this class is responsible for the memory management of + // the CEventNotification instance + void SAL_CALL notifyEvent(CEventNotification* EventNotification); + + void SAL_CALL addListener (const ::com::sun::star::uno::Type& aType , + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xListener); + void SAL_CALL removeListener(const ::com::sun::star::uno::Type& aType , + const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xListener); + +private: + size_t SAL_CALL getEventListSize(); + void SAL_CALL resetNotifyEvent(); + CEventNotification* SAL_CALL getNextEventRecord(); + void SAL_CALL removeNextEventRecord(); + + void SAL_CALL run( ); + + static unsigned int WINAPI ThreadProc(LPVOID pParam); + +private: + std::list<CEventNotification*> m_EventList; + HANDLE m_hThread; + bool m_bRun; + unsigned m_ThreadId; + ::cppu::OBroadcastHelper& m_rBroadcastHelper; + HANDLE m_hEvents[2]; + HANDLE& m_NotifyEvent; + HANDLE& m_ResumeNotifying; + osl::Mutex m_Mutex; + +// prevent copy and assignment +private: + CAsyncEventNotifier( const CAsyncEventNotifier& ); + CAsyncEventNotifier& operator=( const CAsyncEventNotifier& ); +}; + +#endif diff --git a/fpicker/source/win32/filepicker/asyncrequests.cxx b/fpicker/source/win32/filepicker/asyncrequests.cxx new file mode 100644 index 000000000000..902160f40005 --- /dev/null +++ b/fpicker/source/win32/filepicker/asyncrequests.cxx @@ -0,0 +1,228 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "asyncrequests.hxx" +#include <vcl/svapp.hxx> +#include <vos/mutex.hxx> + +//----------------------------------------------------------------------------- +// namespace +//----------------------------------------------------------------------------- + +namespace fpicker{ +namespace win32{ +namespace vista{ + +namespace css = ::com::sun::star; + +//----------------------------------------------------------------------------- +void lcl_sleep(::osl::Condition& aCondition , + ::sal_Int32 nMilliSeconds) +{ + ULONG nAcquireCount = Application::ReleaseSolarMutex(); + + if (nMilliSeconds < 1) + aCondition.wait(0); + else + { + TimeValue aTime; + aTime.Seconds = (nMilliSeconds / 1000); + aTime.Nanosec = (nMilliSeconds % 1000) * 1000000; + aCondition.wait(&aTime); + } + + Application::AcquireSolarMutex( nAcquireCount ); +} + +//----------------------------------------------------------------------------- +void Request::wait(::sal_Int32 nMilliSeconds) +{ + lcl_sleep(m_aJoiner, nMilliSeconds); +} + +void Request::waitProcessMessages() +{ + ::vos::OGuard aGuard( Application::GetSolarMutex() ); + while (!m_aJoiner.check()) + Application::Yield(); +} + +//----------------------------------------------------------------------------- +void Request::notify() +{ + m_aJoiner.set(); +} + +//----------------------------------------------------------------------------- +AsyncRequests::AsyncRequests(const RequestHandlerRef& rHandler) + : ::cppu::BaseMutex( ) + , ::osl::Thread ( ) + , m_bFinish (sal_False) + , m_rHandler (rHandler ) + , m_lRequests ( ) +{ +} + +//----------------------------------------------------------------------------- +AsyncRequests::~AsyncRequests() +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + m_bFinish = sal_True; + aLock.clear(); + // <- SYNCHRONIZED + + join(); +} + +void AsyncRequests::triggerRequestProcessMessages (const RequestRef& rRequest) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + m_lRequests.push(rRequest); + aLock.clear(); + // <- SYNCHRONIZED + + if ( ! isRunning()) + create(); + + rRequest->waitProcessMessages(); +} + +//----------------------------------------------------------------------------- +void AsyncRequests::triggerRequestBlocked(const RequestRef& rRequest) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + m_lRequests.push(rRequest); + aLock.clear(); + // <- SYNCHRONIZED + + if ( ! isRunning()) + create(); + + rRequest->wait(Request::WAIT_INFINITE); +} + +//----------------------------------------------------------------------------- +void AsyncRequests::triggerRequestNonBlocked(const RequestRef& rRequest) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + m_lRequests.push(rRequest); + aLock.clear(); + // <- SYNCHRONIZED + + if ( ! isRunning()) + create(); +} + +//----------------------------------------------------------------------------- +void AsyncRequests::triggerRequestDirectly(const RequestRef& rRequest) +{ + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + RequestHandlerRef rHandler = m_rHandler; + aLock.clear(); + // <- SYNCHRONIZED + + if (rHandler != NULL) + rHandler->doRequest(rRequest); +} + +//----------------------------------------------------------------------------- +void AsyncRequests::triggerRequestThreadAware(const RequestRef& rRequest, + ::sal_Int16 nWait ) +{ + oslThreadIdentifier nOurThreadId = getIdentifier(); + oslThreadIdentifier nCallerThreadId = ::osl::Thread::getCurrentIdentifier(); + if (nOurThreadId == nCallerThreadId) + triggerRequestDirectly(rRequest); + else if (nWait == BLOCKED) + triggerRequestBlocked(rRequest); + else if (nWait == PROCESS_MESSAGES) + triggerRequestProcessMessages(rRequest); + else + triggerRequestNonBlocked(rRequest); +} + +//----------------------------------------------------------------------------- + + +//----------------------------------------------------------------------------- +void SAL_CALL AsyncRequests::run() +{ + static const ::sal_Int32 TIME_TO_WAIT_FOR_NEW_REQUESTS = 250; + + // SYNCHRONIZED -> + ::osl::ResettableMutexGuard aLock(m_aMutex); + RequestHandlerRef rHandler = m_rHandler; + ::sal_Bool bFinished = m_bFinish; + aLock.clear(); + // <- SYNCHRONIZED + + if (rHandler != NULL) + rHandler->before(); + + ::osl::Condition aWait; + + while ( ! bFinished) + { + // SYNCHRONIZED -> + aLock.reset(); + + RequestRef rRequest; + if ( ! m_lRequests.empty()) + { + rRequest = m_lRequests.front(); + m_lRequests.pop(); + } + bFinished = m_bFinish; + + aLock.clear(); + // <- SYNCHRONIZED + + if (rRequest == NULL) + { + lcl_sleep(aWait, TIME_TO_WAIT_FOR_NEW_REQUESTS); + continue; + } + + if (rHandler != NULL) + { + rHandler->doRequest(rRequest); + rRequest->notify(); + } + } + + if (rHandler != NULL) + rHandler->after(); +} + +} // namespace vista +} // namespace win32 +} // namespace fpicker diff --git a/fpicker/source/win32/filepicker/asyncrequests.hxx b/fpicker/source/win32/filepicker/asyncrequests.hxx new file mode 100644 index 000000000000..752d919c2199 --- /dev/null +++ b/fpicker/source/win32/filepicker/asyncrequests.hxx @@ -0,0 +1,227 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FPICKER_WIN32_VISTA_ASYNCREQUESTS_HXX +#define FPICKER_WIN32_VISTA_ASYNCREQUESTS_HXX + +//----------------------------------------------------------------------------- +// includes +//----------------------------------------------------------------------------- + +#include <cppuhelper/basemutex.hxx> +#include <comphelper/sequenceashashmap.hxx> +#include <osl/conditn.hxx> +#include <osl/thread.hxx> +#include <osl/time.h> +#include <queue> +#include <boost/shared_ptr.hpp> + +//----------------------------------------------------------------------------- +// namespace +//----------------------------------------------------------------------------- + +#ifdef css + #error "Clash on using CSS as namespace define." +#else + #define css ::com::sun::star +#endif + +namespace fpicker{ +namespace win32{ +namespace vista{ + +//----------------------------------------------------------------------------- +/** @todo document me + */ +class Request +{ + //------------------------------------------------------------------------- + public: + + static const ::sal_Int32 WAIT_INFINITE = 0; + + //------------------------------------------------------------------------- + // interface + //------------------------------------------------------------------------- + + public: + + //--------------------------------------------------------------------- + explicit Request() + : m_aJoiner ( ) + , m_nRequest (-1) + , m_lArguments( ) + { + m_aJoiner.reset(); + } + + //--------------------------------------------------------------------- + virtual ~Request() {}; + + //--------------------------------------------------------------------- + void setRequest(::sal_Int32 nRequest) + { + m_nRequest = nRequest; + } + + //--------------------------------------------------------------------- + ::sal_Int32 getRequest() + { + return m_nRequest; + } + + //--------------------------------------------------------------------- + void clearArguments() + { + m_lArguments.clear(); + } + + //--------------------------------------------------------------------- + template< class TArgumentType > + void setArgument(const ::rtl::OUString& sName , + const TArgumentType& aValue) + { + m_lArguments[sName] <<= aValue; + } + + //--------------------------------------------------------------------- + template< class TArgumentType > + TArgumentType getArgumentOrDefault(const ::rtl::OUString& sName , + const TArgumentType& aDefault) + { + return m_lArguments.getUnpackedValueOrDefault(sName, aDefault); + } + + //--------------------------------------------------------------------- + void wait(::sal_Int32 nMilliSeconds = WAIT_INFINITE); + + void waitProcessMessages(); + + //--------------------------------------------------------------------- + void notify(); + + //------------------------------------------------------------------------- + // member + //------------------------------------------------------------------------- + + private: + + ::osl::Condition m_aJoiner; + ::sal_Int32 m_nRequest; + ::comphelper::SequenceAsHashMap m_lArguments; +}; + +typedef ::boost::shared_ptr< Request > RequestRef; +typedef ::std::queue< RequestRef > RequestQueue; + +//----------------------------------------------------------------------------- +class RequestHandler +{ + public: + virtual void before() = 0; + virtual void doRequest(const RequestRef& rRequest) = 0; + virtual void after() = 0; +}; + +typedef ::boost::shared_ptr< RequestHandler > RequestHandlerRef; + +//----------------------------------------------------------------------------- +/** @todo docuemnt me + */ +class AsyncRequests : private ::cppu::BaseMutex + , public ::osl::Thread +{ + public: + static const ::sal_Int16 PROCESS_MESSAGES = 2; + static const ::sal_Int16 BLOCKED = 1; + static const ::sal_Int16 NON_BLOCKED = 0; + + //--------------------------------------------------------------------- + /** creates the new asynchronous request executor. + */ + explicit AsyncRequests(const RequestHandlerRef& rHandler); + + void setHandler(const RequestHandlerRef& rHandler) + { + m_rHandler = rHandler; + } + + //--------------------------------------------------------------------- + /** does nothing special / excepting to make sure our class wont be inline .-) + */ + virtual ~AsyncRequests(); + + //--------------------------------------------------------------------- + /** @todo document me + */ + void triggerRequestProcessMessages (const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /** @todo document me + */ + void triggerRequestBlocked(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /** @todo document me + */ + void triggerRequestNonBlocked(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /** @todo document me + */ + void triggerRequestDirectly(const RequestRef& rRequest); + + //--------------------------------------------------------------------- + /** @todo document me + */ + void triggerRequestThreadAware(const RequestRef& rRequest, + ::sal_Int16 nWait ); + + private: + + //--------------------------------------------------------------------- + /** our STA .-) + * Will run between start() & finish(). Internaly it runs a loop ... + * waiting for requests. Every request will be executed synchronously + * in blocked mode. + */ + virtual void SAL_CALL run(); + + private: + + ::sal_Bool m_bFinish; + RequestHandlerRef m_rHandler; + RequestQueue m_lRequests; +}; + +} // namespace vista +} // namespace win32 +} // namespace fpicker + +#undef css + +#endif // FPICKER_WIN32_VISTA_ASYNCREQUESTS_HXX diff --git a/fpicker/source/win32/filepicker/comptr.hxx b/fpicker/source/win32/filepicker/comptr.hxx new file mode 100644 index 000000000000..dad2ab5518e6 --- /dev/null +++ b/fpicker/source/win32/filepicker/comptr.hxx @@ -0,0 +1,222 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef COMPTR_HXX +#define COMPTR_HXX + +#include <sal/types.h> +#include <osl/diagnose.h> +#include <shobjidl.h> + +template< class T_INTERFACE , + REFIID P_IID = IID_NULL , + REFCLSID P_CLSID = CLSID_NULL > +class ComPtr +{ + public: + + //--------------------------------------------------------------------- + /** initialize com ptr with null. + */ + ComPtr() + { + m_pInterface = NULL; + } + + //--------------------------------------------------------------------- + /** initialize com ptr with given interface. + */ + ComPtr(T_INTERFACE* pInterface) + { + m_pInterface = pInterface; + if (m_pInterface) + m_pInterface->AddRef(); + } + + //--------------------------------------------------------------------- + /** copy ctor. + */ + ComPtr(const ComPtr< T_INTERFACE, P_IID, P_CLSID >& aCopy) + { + m_pInterface = aCopy.m_pInterface; + if (m_pInterface) + m_pInterface->AddRef(); + } + + //--------------------------------------------------------------------- + /** initialize object by quering external object for the right interface. + */ + ComPtr(IUnknown* pIUnknown) + { + if (pIUnknown) + pIUnknown->QueryInterface(P_IID, (void**)&m_pInterface); + } + + //--------------------------------------------------------------------- + /** deinitialize com object right. + */ + ~ComPtr() + { + release(); + } + + public: + + //--------------------------------------------------------------------- + HRESULT create() + { + return CoCreateInstance(P_CLSID, NULL, CLSCTX_ALL, P_IID, (void**)&m_pInterface); + } + + //--------------------------------------------------------------------- + operator T_INTERFACE*() const + { + return m_pInterface; + } + + //--------------------------------------------------------------------- + T_INTERFACE& operator*() const + { + return *m_pInterface; + } + + //--------------------------------------------------------------------- + T_INTERFACE** operator&() + { + return &m_pInterface; + } + + //--------------------------------------------------------------------- + T_INTERFACE* operator->() const + { + return m_pInterface; + } + + //--------------------------------------------------------------------- + T_INTERFACE* operator=(T_INTERFACE* pInterface) + { + if ( equals(pInterface) ) + return m_pInterface; + + m_pInterface->Release(); + m_pInterface = pInterface; + if (m_pInterface) + m_pInterface->AddRef(); + + return m_pInterface; + } + + //--------------------------------------------------------------------- + T_INTERFACE* operator=(IUnknown* pIUnknown) + { + if (pIUnknown) + pIUnknown->QueryInterface(P_IID, (void**)&m_pInterface); + return m_pInterface; + } + + //--------------------------------------------------------------------- + T_INTERFACE* operator=(const ComPtr< T_INTERFACE, P_IID, P_CLSID >& aCopy) + { + m_pInterface = aCopy.m_pInterface; + if (m_pInterface) + m_pInterface->AddRef(); + + return m_pInterface; + } + + //--------------------------------------------------------------------- + T_INTERFACE* get() const + { + return m_pInterface; + } + + //--------------------------------------------------------------------- + void attach(T_INTERFACE* pInterface) + { + if (pInterface) + { + m_pInterface->Release(); + m_pInterface = pInterface; + } + } + + //--------------------------------------------------------------------- + T_INTERFACE* detach() + { + T_INTERFACE* pInterface = m_pInterface; + m_pInterface = NULL; + return pInterface; + } + + //--------------------------------------------------------------------- + void release() + { + if (m_pInterface) + { + m_pInterface->Release(); + m_pInterface = NULL; + } + } + +#ifndef __MINGW32__ + //--------------------------------------------------------------------- + template< class T_QUERYINTERFACE > + HRESULT query(T_QUERYINTERFACE** pQuery) + { + return m_pInterface->QueryInterface(__uuidof(T_QUERYINTERFACE), (void**)pQuery); + } +#endif + + //--------------------------------------------------------------------- + ::sal_Bool equals(IUnknown* pCheck) + { + if ( + ( ! m_pInterface ) && + ( ! pCheck ) + ) + return sal_True; + + IUnknown* pCurrent = NULL; + m_pInterface->QueryInterface(IID_IUnknown, (void**)&pCurrent); + + ::sal_Bool bEquals = (pCheck == pCurrent); + pCurrent->Release(); + + return bEquals; + } + + //--------------------------------------------------------------------- + ::sal_Bool is() + { + return (m_pInterface != 0); + } + + private: + T_INTERFACE* m_pInterface; +}; + +#endif diff --git a/fpicker/source/win32/filepicker/controlaccess.cxx b/fpicker/source/win32/filepicker/controlaccess.cxx new file mode 100644 index 000000000000..c6cf3b3ae6c6 --- /dev/null +++ b/fpicker/source/win32/filepicker/controlaccess.cxx @@ -0,0 +1,261 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <tchar.h> +#include <osl/diagnose.h> +#include "controlaccess.hxx" +#include "..\misc\WinImplHelper.hxx" + +//------------------------------------------------------------ +// we are using a table based algorithm to dispatch control +// actions there is one table containing one action table for +// each control class and one action table per control class +// which contains function pointer to control action functions +//------------------------------------------------------------ + +//------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------ + +using rtl::OUString; + +namespace // private +{ + + //------------------------------------------------------------ + // table setup + //------------------------------------------------------------ + + CTRL_SETVALUE_FUNCTION_T CheckboxSetValueFunctionTable[] = + { + CheckboxSetState + }; + const size_t SIZE_CHECKBOX_SETVALUE_FUNCTION_TABLE = + sizeof( CheckboxSetValueFunctionTable ) / sizeof( CTRL_SETVALUE_FUNCTION_T ); + + CTRL_GETVALUE_FUNCTION_T CheckboxGetValueFunctionTable[] = + { + CheckboxGetState + }; + const size_t SIZE_CHECKBOX_GETVALUE_FUNCTION_TABLE = + sizeof( CheckboxGetValueFunctionTable ) / sizeof( CTRL_GETVALUE_FUNCTION_T ); + + CTRL_SETVALUE_FUNCTION_T ListboxSetValueFunctionTable[] = + { + NULL, + ListboxAddItem, + ListboxAddItems, + ListboxDeleteItem, + ListboxDeleteItems, + ListboxSetSelectedItem + }; + const size_t SIZE_LISTBOX_SETVALUE_FUNCTION_TABLE = + sizeof( ListboxSetValueFunctionTable ) / sizeof( CTRL_SETVALUE_FUNCTION_T ); + + CTRL_GETVALUE_FUNCTION_T ListboxGetValueFunctionTable[] = + { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + ListboxGetItems, + ListboxGetSelectedItem, + ListboxGetSelectedItemIndex + }; + const size_t SIZE_LISTBOX_GETVALUE_ACTION_TABLE = + sizeof( ListboxGetValueFunctionTable ) / sizeof( CTRL_GETVALUE_FUNCTION_T ); + + struct _ENTRY + { + LPVOID lpFunctionTable; + size_t TableSize; + }; + + // an array of function tables, one for each control class + _ENTRY CtrlClassSetValueFunctionTable[] = + { + { NULL, 0 }, + { CheckboxSetValueFunctionTable, SIZE_CHECKBOX_SETVALUE_FUNCTION_TABLE }, + { ListboxSetValueFunctionTable, SIZE_LISTBOX_SETVALUE_FUNCTION_TABLE }, + { NULL, 0 } + }; + + // an array of function tables, one for each control class + _ENTRY CtrlClassGetValueFunctionTable[] = + { + { NULL, 0 }, + { CheckboxGetValueFunctionTable, SIZE_CHECKBOX_GETVALUE_FUNCTION_TABLE }, + { ListboxGetValueFunctionTable, SIZE_LISTBOX_GETVALUE_ACTION_TABLE }, + { NULL, 0 } + }; + + //------------------------------------------------------------ + // + //------------------------------------------------------------ + + CTRL_SETVALUE_FUNCTION_T SAL_CALL GetCtrlSetValueFunction( + CTRL_SETVALUE_FUNCTION_T* aCtrlSetValueFunctionTable, size_t aTableSize, sal_Int16 aCtrlAction ) + { + if ( !aCtrlSetValueFunctionTable || + aCtrlAction < 0 + || sal::static_int_cast< sal_uInt16 >(aCtrlAction) >= aTableSize ) + return NULL; + + return aCtrlSetValueFunctionTable[aCtrlAction]; + } + + //------------------------------------------------------------ + // + //------------------------------------------------------------ + + CTRL_GETVALUE_FUNCTION_T SAL_CALL GetCtrlGetValueFunction( + CTRL_GETVALUE_FUNCTION_T* aCtrlGetValueFunctionTable, size_t aTableSize, sal_Int16 aCtrlAction ) + { + if ( !aCtrlGetValueFunctionTable || + aCtrlAction < 0 || + sal::static_int_cast< sal_uInt16 >(aCtrlAction) >= aTableSize ) + return NULL; + + return aCtrlGetValueFunctionTable[aCtrlAction]; + } + + //------------------------------------------------------------ + // + //------------------------------------------------------------ + + inline + _ENTRY SAL_CALL GetCtrlClassSetValueFunctionTable( CTRL_CLASS aCtrlClass ) + { + return CtrlClassSetValueFunctionTable[aCtrlClass]; + } + + //------------------------------------------------------------ + // + //------------------------------------------------------------ + + inline + _ENTRY SAL_CALL GetCtrlClassGetValueFunctionTable( CTRL_CLASS aCtrlClass ) + { + return CtrlClassGetValueFunctionTable[aCtrlClass]; + } + + int WindowsFileOpenCtrlIds[] = + { + 0, + IDOK, // PUSHBUTTON_OK + IDCANCEL, // PUSHBUTTON_CANCEL + cmb1, // LISTBOX_FILTER + 0, // CONTROL_FILEVIEW + 0, // not available in system file picker + stc2, // LISTBOX_FILTER_LABEL + stc3 // LISTBOX_FILE_NAME_LABEL + }; + const int SIZE_WINDOWS_FILEOPEN_CTRL_IDS = + sizeof(WindowsFileOpenCtrlIds)/sizeof(WindowsFileOpenCtrlIds[0]); + +}; // end namespace + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +CTRL_SETVALUE_FUNCTION_T SAL_CALL GetCtrlSetValueFunction( CTRL_CLASS aCtrlClass, sal_Int16 aCtrlAction ) +{ + _ENTRY aEntry = + GetCtrlClassSetValueFunctionTable( aCtrlClass ); + + return GetCtrlSetValueFunction( + reinterpret_cast< CTRL_SETVALUE_FUNCTION_T* >( aEntry.lpFunctionTable ), + aEntry.TableSize, + aCtrlAction ); +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +CTRL_GETVALUE_FUNCTION_T SAL_CALL GetCtrlGetValueFunction( CTRL_CLASS aCtrlClass, sal_Int16 aCtrlAction ) +{ + _ENTRY aEntry = + GetCtrlClassGetValueFunctionTable( aCtrlClass ); + + return GetCtrlGetValueFunction( + reinterpret_cast< CTRL_GETVALUE_FUNCTION_T* >( aEntry.lpFunctionTable ), + aEntry.TableSize, + aCtrlAction ); +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +CTRL_CLASS SAL_CALL GetCtrlClass( HWND hwndCtrl ) +{ + CTRL_CLASS aCtrlClass = UNKNOWN; + TCHAR aClassName[256]; + + int nRet = GetClassName(hwndCtrl,aClassName,(sizeof(aClassName)/sizeof(TCHAR))); + if (nRet) + { + if (0 == _tcsicmp(aClassName,TEXT("button"))) + { + // button means many things so we have + // to find out what button it is + LONG lBtnStyle = GetWindowLong(hwndCtrl,GWL_STYLE); + if (lBtnStyle & BS_CHECKBOX) + aCtrlClass = CHECKBOX; + else if (((lBtnStyle & BS_PUSHBUTTON) == 0) || (lBtnStyle & BS_DEFPUSHBUTTON)) + aCtrlClass = PUSHBUTTON; + } + else if (0 == _tcsicmp(aClassName,TEXT("listbox")) || + 0 == _tcsicmp(aClassName,TEXT("combobox"))) + aCtrlClass = LISTBOX; + } + + return aCtrlClass; +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +int SAL_CALL CommonFilePickerCtrlIdToWinFileOpenCtrlId( sal_Int16 aControlId ) +{ + if ( aControlId < 0 || aControlId > SIZE_WINDOWS_FILEOPEN_CTRL_IDS ) + return aControlId; + + return WindowsFileOpenCtrlIds[aControlId]; +} diff --git a/fpicker/source/win32/filepicker/controlaccess.hxx b/fpicker/source/win32/filepicker/controlaccess.hxx new file mode 100644 index 000000000000..3a6b925c46d2 --- /dev/null +++ b/fpicker/source/win32/filepicker/controlaccess.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _CONTROLACCESS_HXX_ +#define _CONTROLACCESS_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> +#include <rtl/ustring.hxx> + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <com/sun/star/uno/Any.hxx> + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +typedef void ( SAL_CALL *CTRL_SETVALUE_FUNCTION_T)( HWND, const ::com::sun::star::uno::Any&, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >&, sal_Int16 ); +typedef ::com::sun::star::uno::Any ( SAL_CALL *CTRL_GETVALUE_FUNCTION_T )( HWND ); + +// the currently supported control classes +enum CTRL_CLASS +{ + UNKNOWN = 0, + CHECKBOX, + LISTBOX, + PUSHBUTTON +}; + +// returns the class of a control +CTRL_CLASS SAL_CALL GetCtrlClass( HWND hwndCtrl ); + +// returns a pointer to a setValue function based on the control class +// and the control action, if no function was found NULL will be returned +CTRL_SETVALUE_FUNCTION_T SAL_CALL GetCtrlSetValueFunction( CTRL_CLASS aCtrlClass, sal_Int16 aCtrlAction ); + +// returns a pointer to a getValue function based on the control class +// and the control action, if no function was found NULL will be returned +CTRL_GETVALUE_FUNCTION_T SAL_CALL GetCtrlGetValueFunction( CTRL_CLASS aCtrlClass, sal_Int16 aCtrlAction ); + +// translates a CommonFilePickerElementId as defined in CommonFilePickerElementIds.idl +// to a control id that is valid for the FileOpen dialog under windows as defined +// in dlgs.h in the Windows Platform SDK +int SAL_CALL CommonFilePickerCtrlIdToWinFileOpenCtrlId( sal_Int16 aControlId ); + +#endif diff --git a/fpicker/source/win32/filepicker/controlcommand.cxx b/fpicker/source/win32/filepicker/controlcommand.cxx new file mode 100644 index 000000000000..c66c76549f9d --- /dev/null +++ b/fpicker/source/win32/filepicker/controlcommand.cxx @@ -0,0 +1,282 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include "controlcommand.hxx" +#include "controlcommandrequest.hxx" +#include "controlcommandresult.hxx" +#include "filepickerstate.hxx" + +//--------------------------------------------- +// +//--------------------------------------------- + +CControlCommand::CControlCommand( sal_Int16 aControlId ) : + m_NextCommand( NULL ), + m_aControlId( aControlId ) +{ +} + +//--------------------------------------------- +// +//--------------------------------------------- + +CControlCommand::~CControlCommand( ) +{ +} + +//--------------------------------------------- +// +//--------------------------------------------- + +CControlCommandResult* SAL_CALL CControlCommand::handleRequest( CControlCommandRequest* pRequest ) +{ + // if the command does not support handleRequest, it should at least + // redirect the request to the next element + // so the base class implementation has to do it + + OSL_ENSURE( pRequest, "inavlid parameter" ); + + CControlCommandResult* result; + CControlCommand* nextCommand; + + nextCommand = getNextCommand( ); + if ( nextCommand ) + { + result = nextCommand->handleRequest( pRequest ); + } + else + { + result = new CControlCommandResult(); + } + + return result; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +CControlCommand* SAL_CALL CControlCommand::getNextCommand( ) const +{ + return m_NextCommand; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CControlCommand::setNextCommand( CControlCommand* nextCommand ) +{ + m_NextCommand = nextCommand; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +sal_Int16 SAL_CALL CControlCommand::getControlId( ) const +{ + return m_aControlId; +} + + +//--------------------------------------------- +// +//--------------------------------------------- + +CValueControlCommand::CValueControlCommand( + sal_Int16 aControlId, + sal_Int16 aControlAction, + const ::com::sun::star::uno::Any& aValue ) : + CControlCommand( aControlId ), + m_aControlAction( aControlAction ), + m_aValue( aValue ) +{ +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CValueControlCommand::exec( CFilePickerState* aFilePickerState ) +{ + OSL_ENSURE( aFilePickerState, "empty reference" ); + + aFilePickerState->setValue( + getControlId( ), + m_aControlAction, + m_aValue ); +} + +//--------------------------------------------- +// +//--------------------------------------------- + +CControlCommandResult* SAL_CALL CValueControlCommand::handleRequest( CControlCommandRequest* aRequest ) +{ + CValueControlCommandRequest* value_request = + dynamic_cast< CValueControlCommandRequest* >( aRequest ); + + CControlCommandResult* result; + CControlCommand* nextCommand; + + if ( value_request && + (value_request->getControlId( ) == getControlId( )) && + (value_request->getControlAction( ) == m_aControlAction) ) + { + result = new CValueCommandResult( sal_True, m_aValue ); + } + else + { + nextCommand = getNextCommand( ); + if ( nextCommand ) + { + result = nextCommand->handleRequest( aRequest ); + } + else + { + result = new CControlCommandResult( ); + } + } + + return result; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +sal_Int16 SAL_CALL CValueControlCommand::getControlAction( ) const +{ + return m_aControlAction; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +::com::sun::star::uno::Any SAL_CALL CValueControlCommand::getValue( ) const +{ + return m_aValue; +} + + +//--------------------------------------------- +// +//--------------------------------------------- + +CLabelControlCommand::CLabelControlCommand( + sal_Int16 aControlId, + const rtl::OUString& aLabel ) : + CControlCommand( aControlId ), + m_aLabel( aLabel ) +{ +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CLabelControlCommand::exec( CFilePickerState* aFilePickerState ) +{ + OSL_ENSURE( aFilePickerState, "empty reference" ); + + aFilePickerState->setLabel( getControlId( ), m_aLabel ); +} + +//--------------------------------------------- +// +//--------------------------------------------- + +CControlCommandResult* SAL_CALL CLabelControlCommand::handleRequest( CControlCommandRequest* aRequest ) +{ + OSL_ENSURE( aRequest, "inavlid parameter" ); + + CControlCommandResult* result; + CControlCommand* nextCommand; + + CValueControlCommandRequest* value_request = + dynamic_cast< CValueControlCommandRequest* >( aRequest ); + + if ( !value_request && + (aRequest->getControlId( ) == getControlId( )) ) + { + result = new CLabelCommandResult( sal_True, m_aLabel ); + } + else + { + nextCommand = getNextCommand( ); + if ( nextCommand ) + { + result = nextCommand->handleRequest( aRequest ); + } + else + { + result = new CControlCommandResult( ); + } + } + + return result; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +rtl::OUString SAL_CALL CLabelControlCommand::getLabel( ) const +{ + return m_aLabel; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +CEnableControlCommand::CEnableControlCommand( + sal_Int16 aControlId, + sal_Bool bEnable ) : + CControlCommand( aControlId ), + m_bEnable( bEnable ) +{ +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CEnableControlCommand::exec( CFilePickerState* aFilePickerState ) +{ + OSL_ENSURE( aFilePickerState, "empty reference" ); + + aFilePickerState->enableControl( getControlId( ), m_bEnable ); +} diff --git a/fpicker/source/win32/filepicker/controlcommand.hxx b/fpicker/source/win32/filepicker/controlcommand.hxx new file mode 100644 index 000000000000..c63888ceeeb1 --- /dev/null +++ b/fpicker/source/win32/filepicker/controlcommand.hxx @@ -0,0 +1,143 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _CONTROLCOMMAND_HXX_ +#define _CONTROLCOMMAND_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> +#include <com/sun/star/uno/Any.hxx> +#include <rtl/ustring.hxx> + +//--------------------------------------------- +// +//--------------------------------------------- + +class CFilePickerState; +class CControlCommandRequest; +class CControlCommandResult; + +//--------------------------------------------- +// +//--------------------------------------------- + +class CControlCommand +{ +public: + CControlCommand( sal_Int16 aControlId ); + virtual ~CControlCommand( ); + + virtual void SAL_CALL exec( CFilePickerState* aFilePickerState ) = 0; + + // the client inherits the ownership of the returned + // CControlCommandResult and has to delete it or he may + // use the auto_ptr template for automatic deletion + virtual CControlCommandResult* SAL_CALL handleRequest( CControlCommandRequest* aRequest ); + + // clients of this method should use the returned + // pointer only temporary because it's not ref-counted + // and the ownerhsip belongs to this instance + CControlCommand* SAL_CALL getNextCommand( ) const; + + // transfers the ownership to this class + void SAL_CALL setNextCommand( CControlCommand* nextCommand ); + +protected: + sal_Int16 SAL_CALL getControlId( ) const; + +private: + CControlCommand* m_NextCommand; + sal_Int16 m_aControlId; +}; + +//--------------------------------------------- +// +//--------------------------------------------- + +class CValueControlCommand : public CControlCommand +{ +public: + CValueControlCommand( + sal_Int16 aControlId, + sal_Int16 aControlAction, + const ::com::sun::star::uno::Any& aValue ); + + virtual void SAL_CALL exec( CFilePickerState* aFilePickerState ); + + virtual CControlCommandResult* SAL_CALL handleRequest( CControlCommandRequest* aRequest ); + + sal_Int16 SAL_CALL getControlAction( ) const; + + ::com::sun::star::uno::Any SAL_CALL getValue( ) const; + +private: + sal_Int16 m_aControlAction; + ::com::sun::star::uno::Any m_aValue; +}; + +//--------------------------------------------- +// +//--------------------------------------------- + +class CLabelControlCommand : public CControlCommand +{ +public: + CLabelControlCommand( + sal_Int16 aControlId, + const rtl::OUString& aLabel ); + + virtual void SAL_CALL exec( CFilePickerState* aFilePickerState ); + + virtual CControlCommandResult* SAL_CALL handleRequest( CControlCommandRequest* aRequest ); + + rtl::OUString SAL_CALL getLabel( ) const; + +private: + rtl::OUString m_aLabel; +}; + +//--------------------------------------------- +// +//--------------------------------------------- + +class CEnableControlCommand : public CControlCommand +{ +public: + CEnableControlCommand( + sal_Int16 controlId, + sal_Bool bEnable ); + + virtual void SAL_CALL exec( CFilePickerState* aFilePickerState ); + +private: + sal_Bool m_bEnable; +}; + +#endif diff --git a/fpicker/source/win32/filepicker/controlcommandrequest.hxx b/fpicker/source/win32/filepicker/controlcommandrequest.hxx new file mode 100644 index 000000000000..c9c6de78fb08 --- /dev/null +++ b/fpicker/source/win32/filepicker/controlcommandrequest.hxx @@ -0,0 +1,86 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _CONTROLCOMMANDREQUEST_HXX_ +#define _CONTROLCOMMANDREQUEST_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> + +//--------------------------------------------- +// declaration +//--------------------------------------------- + +class CControlCommandRequest +{ +public: + CControlCommandRequest( sal_Int16 aControlId ) : + m_aControlId( aControlId ) + { + } + + virtual ~CControlCommandRequest( ) + { + } + + sal_Int16 SAL_CALL getControlId( ) const + { + return m_aControlId; + } + +private: + sal_Int16 m_aControlId; +}; + +//--------------------------------------------- +// +//--------------------------------------------- + +class CValueControlCommandRequest : public CControlCommandRequest +{ +public: + CValueControlCommandRequest( + sal_Int16 aControlId, + sal_Int16 aControlAction ) : + CControlCommandRequest( aControlId ), + m_aControlAction( aControlAction ) + { + } + + sal_Int16 SAL_CALL getControlAction( ) const + { + return m_aControlAction; + } + +private: + sal_Int16 m_aControlAction; +}; + +#endif diff --git a/fpicker/source/win32/filepicker/controlcommandresult.hxx b/fpicker/source/win32/filepicker/controlcommandresult.hxx new file mode 100644 index 000000000000..b1eeb9d27521 --- /dev/null +++ b/fpicker/source/win32/filepicker/controlcommandresult.hxx @@ -0,0 +1,108 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _CONTROLCOMMANDRESULT_HXX_ +#define _CONTROLCOMMANDRESULT_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> +#include <com/sun/star/uno/Any.hxx> +#include <rtl/ustring.hxx> + +//--------------------------------------------- +// declaration +//--------------------------------------------- + +class CControlCommandResult +{ +public: + CControlCommandResult( sal_Bool bResult = sal_False ) : + m_bResult( bResult ) + { + } + + virtual ~CControlCommandResult( ) + { + } + + sal_Bool SAL_CALL hasResult( ) const + { + return m_bResult; + } + +private: + sal_Bool m_bResult; +}; + +//--------------------------------------------- +// +//--------------------------------------------- + +class CValueCommandResult : public CControlCommandResult +{ +public: + CValueCommandResult( sal_Bool bResult, const ::com::sun::star::uno::Any& aValue ) : + CControlCommandResult( bResult ), + m_aValue( aValue ) + { + } + + ::com::sun::star::uno::Any SAL_CALL getValue( ) const + { + return m_aValue; + } + +private: + ::com::sun::star::uno::Any m_aValue; +}; + +//--------------------------------------------- +// +//--------------------------------------------- + +class CLabelCommandResult : public CControlCommandResult +{ +public: + CLabelCommandResult( sal_Bool bResult, const rtl::OUString& aLabel ) : + CControlCommandResult( bResult ), + m_aLabel( aLabel ) + { + } + + rtl::OUString SAL_CALL getLabel( ) const + { + return m_aLabel; + } + +private: + rtl::OUString m_aLabel; +}; + +#endif diff --git a/fpicker/source/win32/filepicker/customcontrol.cxx b/fpicker/source/win32/filepicker/customcontrol.cxx new file mode 100644 index 000000000000..257a96a0f3e1 --- /dev/null +++ b/fpicker/source/win32/filepicker/customcontrol.cxx @@ -0,0 +1,67 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" +#include "customcontrol.hxx" + +//----------------------------------- +// +//----------------------------------- + +CCustomControl::~CCustomControl() +{ +} + +//----------------------------------- +// +//----------------------------------- + +void SAL_CALL CCustomControl::AddControl(CCustomControl*) +{ + // will be implemented by custom control containers +} + +//----------------------------------- +// +//----------------------------------- + +void SAL_CALL CCustomControl::RemoveControl(CCustomControl*) +{ + // will be implemented by custom control containers +} + +//----------------------------------- +// +//----------------------------------- + +void SAL_CALL CCustomControl::RemoveAllControls() +{ + // will be implemented by custom control containers +} + + diff --git a/fpicker/source/win32/filepicker/customcontrol.hxx b/fpicker/source/win32/filepicker/customcontrol.hxx new file mode 100644 index 000000000000..3cfd7e35ce83 --- /dev/null +++ b/fpicker/source/win32/filepicker/customcontrol.hxx @@ -0,0 +1,60 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _CUSTOMCONTROL_HXX_ +#define _CUSTOMCONTROL_HXX_ + +#include <sal/types.h> + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//----------------------------------- +// +//----------------------------------- + +class CCustomControl +{ +public: + virtual ~CCustomControl(); + + // align the control to a reference object/control + virtual void SAL_CALL Align() = 0; + + virtual void SAL_CALL SetFont(HFONT hFont) = 0; + + virtual void SAL_CALL AddControl(CCustomControl* aCustomControl); + virtual void SAL_CALL RemoveControl(CCustomControl* aCustomControl); + virtual void SAL_CALL RemoveAllControls(); +}; + +#endif diff --git a/fpicker/source/win32/filepicker/customcontrolcontainer.cxx b/fpicker/source/win32/filepicker/customcontrolcontainer.cxx new file mode 100644 index 000000000000..e1afa16868f2 --- /dev/null +++ b/fpicker/source/win32/filepicker/customcontrolcontainer.cxx @@ -0,0 +1,143 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" +#include "customcontrolcontainer.hxx" + +#include <algorithm> +#include <functional> + +//----------------------------------- +// +//----------------------------------- + +namespace /* private */ +{ + void DeleteCustomControl(CCustomControl* aCustomControl) + { + delete aCustomControl; + }; + + void AlignCustomControl(CCustomControl* aCustomControl) + { + aCustomControl->Align(); + }; + + class CSetFontHelper + { + public: + CSetFontHelper(HFONT hFont) : + m_hFont(hFont) + { + } + + void SAL_CALL operator()(CCustomControl* aCustomControl) + { + aCustomControl->SetFont(m_hFont); + } + + private: + HFONT m_hFont; + }; +} + +//----------------------------------- +// +//----------------------------------- + +CCustomControlContainer::~CCustomControlContainer() +{ + RemoveAllControls(); +} + +//----------------------------------- +// +//----------------------------------- + +void SAL_CALL CCustomControlContainer::Align() +{ + std::for_each( + m_ControlContainer.begin(), + m_ControlContainer.end(), + AlignCustomControl); +} + +//----------------------------------- +// +//----------------------------------- + +void SAL_CALL CCustomControlContainer::SetFont(HFONT hFont) +{ + CSetFontHelper aSetFontHelper(hFont); + + std::for_each( + m_ControlContainer.begin(), + m_ControlContainer.end(), + aSetFontHelper); +} + +//----------------------------------- +// +//----------------------------------- + +void SAL_CALL CCustomControlContainer::AddControl(CCustomControl* aCustomControl) +{ + m_ControlContainer.push_back(aCustomControl); +} + +//----------------------------------- +// +//----------------------------------- + +void SAL_CALL CCustomControlContainer::RemoveControl(CCustomControl* aCustomControl) +{ + ControlContainer_t::iterator iter_end = m_ControlContainer.end(); + + ControlContainer_t::iterator iter = + std::find(m_ControlContainer.begin(),iter_end,aCustomControl); + + if (iter != iter_end) + { + delete *iter; + m_ControlContainer.remove(aCustomControl); + } +} + +//----------------------------------- +// +//----------------------------------- + +void SAL_CALL CCustomControlContainer::RemoveAllControls() +{ + std::for_each( + m_ControlContainer.begin(), + m_ControlContainer.end(), + DeleteCustomControl); + + m_ControlContainer.clear(); +} diff --git a/fpicker/source/win32/filepicker/customcontrolcontainer.hxx b/fpicker/source/win32/filepicker/customcontrolcontainer.hxx new file mode 100644 index 000000000000..b3d09622b72a --- /dev/null +++ b/fpicker/source/win32/filepicker/customcontrolcontainer.hxx @@ -0,0 +1,60 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _CUSTOMCONTROLCONTAINER_HXX_ +#define _CUSTOMCONTROLCONTAINER_HXX_ + +#include "customcontrol.hxx" + +#include <list> + +//----------------------------------- +// A container for custom controls +// the container is resposible for +// the destruction of the custom +// controls +//----------------------------------- + +class CCustomControlContainer : public CCustomControl +{ +public: + virtual ~CCustomControlContainer(); + + virtual void SAL_CALL Align(); + virtual void SAL_CALL SetFont(HFONT hFont); + + virtual void SAL_CALL AddControl(CCustomControl* aCustomControl); + virtual void SAL_CALL RemoveControl(CCustomControl* aCustomControl); + virtual void SAL_CALL RemoveAllControls(); + +private: + typedef std::list<CCustomControl*> ControlContainer_t; + + ControlContainer_t m_ControlContainer; +}; + +#endif diff --git a/fpicker/source/win32/filepicker/customcontrolfactory.cxx b/fpicker/source/win32/filepicker/customcontrolfactory.cxx new file mode 100644 index 000000000000..1cef962dfa7a --- /dev/null +++ b/fpicker/source/win32/filepicker/customcontrolfactory.cxx @@ -0,0 +1,86 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +#include <tchar.h> +#include "customcontrolfactory.hxx" +#include "customcontrolcontainer.hxx" +#include "dialogcustomcontrols.hxx" +#include <osl/diagnose.h> + +//----------------------------------- +// +//----------------------------------- + +CCustomControl* CCustomControlFactory::CreateCustomControl(HWND aControlHandle, HWND aParentHandle) +{ + OSL_PRECOND(IsWindow(aControlHandle),"Invalid control handle"); + OSL_PRECOND(IsWindow(aControlHandle),"Invalid parent handle"); + + // get window class + // if static text create static text control etc. + + TCHAR aClsName[256]; + ZeroMemory(aClsName,sizeof(aClsName)); + if (GetClassName(aControlHandle,aClsName,sizeof(aClsName)) == 0) { + OSL_ENSURE(false,"Invalid window handle"); + } + + if (0 == _tcsicmp(aClsName,TEXT("button"))) + { + // button means many things so we have + // to find out what button it is + LONG lBtnStyle = GetWindowLong(aControlHandle,GWL_STYLE); + + if (lBtnStyle & BS_CHECKBOX) + return new CCheckboxCustomControl(aControlHandle,aParentHandle); + + if ( ((lBtnStyle & BS_PUSHBUTTON) == 0) || (lBtnStyle & BS_DEFPUSHBUTTON)) + return new CPushButtonCustomControl(aControlHandle,aParentHandle); + + return new CDummyCustomControl(aControlHandle,aParentHandle); + } + + if (0 == _tcsicmp(aClsName,TEXT("listbox")) || 0 == _tcsicmp(aClsName,TEXT("combobox"))) + return new CComboboxCustomControl(aControlHandle,aParentHandle); + + if (0 == _tcsicmp(aClsName,TEXT("static"))) + return new CStaticCustomControl(aControlHandle,aParentHandle); + + return new CDummyCustomControl(aControlHandle,aParentHandle); +} + +//----------------------------------- +// +//----------------------------------- + +CCustomControl* CCustomControlFactory::CreateCustomControlContainer() +{ + return new CCustomControlContainer(); +} diff --git a/fpicker/source/win32/filepicker/customcontrolfactory.hxx b/fpicker/source/win32/filepicker/customcontrolfactory.hxx new file mode 100644 index 000000000000..ed363245c245 --- /dev/null +++ b/fpicker/source/win32/filepicker/customcontrolfactory.hxx @@ -0,0 +1,61 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _CUSTOMCONTROLFACTORY_HXX_ +#define _CUSTOMCONTROLFACTORY_HXX_ + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//----------------------------------- +// forward declaration +//----------------------------------- + +class CCustomControl; + +//----------------------------------- +// +//----------------------------------- + +class CCustomControlFactory +{ +public: + + // The CCustomControl instances will be created on the heap + // and the client is responsible for deleting this instances + // (he adopts ownership) + virtual CCustomControl* CreateCustomControl(HWND aControlHandle, HWND aParentHandle); + + virtual CCustomControl* CreateCustomControlContainer(); +}; + +#endif diff --git a/fpicker/source/win32/filepicker/dialogcustomcontrols.cxx b/fpicker/source/win32/filepicker/dialogcustomcontrols.cxx new file mode 100644 index 000000000000..11c7a414d63b --- /dev/null +++ b/fpicker/source/win32/filepicker/dialogcustomcontrols.cxx @@ -0,0 +1,195 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +#ifndef _DIALOGCUSTOMCONTROLS_CXX_ +#include "dialogcustomcontrols.hxx" +#endif +#include <osl/diagnose.h> + +//----------------------------------- +// +//----------------------------------- + +CDialogCustomControlBase::CDialogCustomControlBase(HWND aControlHandle, HWND aParentHandle) : + m_CustomControlHandle(aControlHandle), + m_ParentHandle(aParentHandle) +{ +} + +//----------------------------------- +// +//----------------------------------- + +void SAL_CALL CDialogCustomControlBase::SetFont(HFONT hFont) +{ + SendMessage( + m_CustomControlHandle, + WM_SETFONT, + (WPARAM)hFont, + (LPARAM)TRUE); +} + +//----------------------------------- +// +//----------------------------------- + +void SAL_CALL CDialogCustomControlBase::AlignToBuddy(HWND aBuddyHandle) +{ + OSL_PRECOND(IsWindow(aBuddyHandle),"Invalid buddy window handle"); + + RECT rcBuddy; + GetWindowRect(aBuddyHandle,&rcBuddy); + + POINT pt = {rcBuddy.left,rcBuddy.top}; + ScreenToClient(m_ParentHandle,&pt); + + int cx_new = rcBuddy.right - rcBuddy.left; + int cy_new = rcBuddy.bottom - rcBuddy.top; + + // keep the vertical position because + // the Windows dialog controler does + // this job + RECT rcMe; + GetWindowRect(m_CustomControlHandle,&rcMe); + + POINT ptMe = {rcMe.left,rcMe.top}; + ScreenToClient(m_ParentHandle,&ptMe); + + SetWindowPos( + m_CustomControlHandle, + HWND_TOP, + pt.x, + ptMe.y, + cx_new, + cy_new, + SWP_NOACTIVATE); +} + +//----------------------------------- +// +//----------------------------------- + +CDummyCustomControl::CDummyCustomControl(HWND, HWND) +{ +} + +//----------------------------------- +// +//----------------------------------- + +void SAL_CALL CDummyCustomControl::Align() +{ + // do nothing +} + +//----------------------------------- +// +//----------------------------------- + +void SAL_CALL CDummyCustomControl::SetFont(HFONT) +{ + // do nothing +} + +//----------------------------------- +// +//----------------------------------- + +CStaticCustomControl::CStaticCustomControl(HWND aControlHandle, HWND aParentHandle) : + CDialogCustomControlBase(aControlHandle,aParentHandle) +{ +} + +//----------------------------------- +// Align to the "File name" static +// text of the standard FileOpen dlg +//----------------------------------- + +void SAL_CALL CStaticCustomControl::Align() +{ + AlignToBuddy(GetDlgItem(m_ParentHandle,stc3)); +} + +//----------------------------------- +// +//----------------------------------- + +CPushButtonCustomControl::CPushButtonCustomControl(HWND aControlHandle, HWND aParentHandle) : + CDialogCustomControlBase(aControlHandle,aParentHandle) +{ +} + +//----------------------------------- +// Align to the "OK" button of the +// standard FileOpen dlg +//----------------------------------- + +void SAL_CALL CPushButtonCustomControl::Align() +{ + AlignToBuddy(GetDlgItem(m_ParentHandle,IDCANCEL)); +} + +//----------------------------------- +// +//----------------------------------- + +CComboboxCustomControl::CComboboxCustomControl(HWND aControlHandle, HWND aParentHandle) : + CDialogCustomControlBase(aControlHandle,aParentHandle) +{ +} + +//----------------------------------- +// Align to the "File name" combobox +// of the standard FileOpen dlg +//----------------------------------- + +void SAL_CALL CComboboxCustomControl::Align() +{ + AlignToBuddy(GetDlgItem(m_ParentHandle,cmb1)); +} + +//----------------------------------- +// +//----------------------------------- + +CCheckboxCustomControl::CCheckboxCustomControl(HWND aControlHandle, HWND aParentHandle) : + CDialogCustomControlBase(aControlHandle,aParentHandle) +{ +} + +//----------------------------------- +// Align to the "File name" combobox +// of the standard FileOpen dlg +//----------------------------------- + +void SAL_CALL CCheckboxCustomControl::Align() +{ + AlignToBuddy(GetDlgItem(m_ParentHandle,cmb1)); +} diff --git a/fpicker/source/win32/filepicker/dialogcustomcontrols.hxx b/fpicker/source/win32/filepicker/dialogcustomcontrols.hxx new file mode 100644 index 000000000000..11c3d04a7043 --- /dev/null +++ b/fpicker/source/win32/filepicker/dialogcustomcontrols.hxx @@ -0,0 +1,123 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _DIALOGCUSTOMCONTROLS_HXX_ +#define _DIALOGCUSTOMCONTROLS_HXX_ + +#include "customcontrol.hxx" + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//----------------------------------- +// +//----------------------------------- + +class CDummyCustomControl : public CCustomControl +{ +public: + CDummyCustomControl(HWND aControlHandle, HWND aParentHandle); + + virtual void SAL_CALL Align(); + virtual void SAL_CALL SetFont(HFONT hFont); +}; + +//----------------------------------- +// +//----------------------------------- + +class CDialogCustomControlBase : public CCustomControl +{ +protected: + CDialogCustomControlBase(HWND aControlHandle, HWND aParentHandle); + + virtual void SAL_CALL SetFont(HFONT hFont); + + // aligns the specific control class to a reference + // buddy + // + void SAL_CALL AlignToBuddy(HWND aBuddyHandle); + +protected: + HWND m_CustomControlHandle; + HWND m_ParentHandle; +}; + +//----------------------------------- +// +//----------------------------------- + +class CStaticCustomControl : public CDialogCustomControlBase +{ +public: + CStaticCustomControl(HWND aControlHandle, HWND aParentHandle); + + virtual void SAL_CALL Align(); +}; + +//----------------------------------- +// +//----------------------------------- + +class CPushButtonCustomControl : public CDialogCustomControlBase +{ +public: + CPushButtonCustomControl(HWND aControlHandle, HWND aParentHandle); + + virtual void SAL_CALL Align(); +}; + +//----------------------------------- +// +//----------------------------------- + +class CComboboxCustomControl : public CDialogCustomControlBase +{ +public: + CComboboxCustomControl(HWND aControlHandle, HWND aParentHandle); + + virtual void SAL_CALL Align(); +}; + +//----------------------------------- +// +//----------------------------------- + +class CCheckboxCustomControl : public CDialogCustomControlBase +{ +public: + CCheckboxCustomControl(HWND aControlHandle, HWND aParentHandle); + + virtual void SAL_CALL Align(); +}; + +#endif diff --git a/fpicker/source/win32/filepicker/dibpreview.cxx b/fpicker/source/win32/filepicker/dibpreview.cxx new file mode 100644 index 000000000000..fcc369972ff8 --- /dev/null +++ b/fpicker/source/win32/filepicker/dibpreview.cxx @@ -0,0 +1,472 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <tchar.h> +#include "dibpreview.hxx" +#include <osl/diagnose.h> + +#ifndef _COM_SUN_STAR_UI_DIALOG_FILEPREVIEWIMAGEFORMATS_HPP_ +#include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp> +#endif + +#ifndef _USTRING_HXX_ +#include <rtl/ustring.hxx> +#endif + +#include <stdexcept> +#include <string> + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::uno::RuntimeException; +using ::com::sun::star::uno::Any; +using ::com::sun::star::lang::IllegalArgumentException; +using rtl::OUString; + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +namespace /* private */ +{ + const LPTSTR CURRENT_INSTANCE = TEXT("CurrInst"); +}; + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +#define PREVIEWWND_CLASS_NAME TEXT("DIBPreviewWnd###") + +// means 3 pixel left and 3 pixel right +#define HORZ_BODER_SPACE 6 + +// means 3 pixel top and 3 pixel bottom +#define VERT_BORDER_SPACE 6 + +//--------------------------------------------------- +// static member initialization +//--------------------------------------------------- + +osl::Mutex CDIBPreview::s_Mutex; +ATOM CDIBPreview::s_ClassAtom = 0; +sal_Int32 CDIBPreview::s_RegisterDibPreviewWndCount = 0; + +//--------------------------------------------------- +// +//--------------------------------------------------- + +CDIBPreview::CDIBPreview(HINSTANCE instance,HWND parent,sal_Bool bShowWindow) : + m_Instance(instance) +{ + RegisterDibPreviewWindowClass(); + + DWORD dwStyle = WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; + + if (bShowWindow) + dwStyle |= WS_VISIBLE; + + m_Hwnd = CreateWindowEx( + WS_EX_CLIENTEDGE, + PREVIEWWND_CLASS_NAME, + TEXT(""), + dwStyle, + 0, 0, 0, 0, + parent, + (HMENU)0x0, // for child windows this will + // be used as child window identifier + m_Instance, + (LPVOID)this // pass a pointer to the current + // instance of this class + ); + + bool bSuccess = IsWindow(m_Hwnd); + + OSL_POSTCOND(bSuccess,"Coud not create preview window"); + + if (!bSuccess) + { + UnregisterDibPreviewWindowClass(); + throw std::runtime_error("Could not create preview window"); + } +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +CDIBPreview::~CDIBPreview( ) +{ + // remember: we don't have to destroy the + // preview window because it will be destroyed + // by it's parent window (the FileOpen dialog) + // but we have to unregister the window class + //if ( m_bWndClassRegistered ) + UnregisterDibPreviewWindowClass(); +} + +//------------------------------- +// +//------------------------------- + +sal_Int32 SAL_CALL CDIBPreview::getTargetColorDepth() throw (RuntimeException) +{ + HDC hdc = GetDC(m_Hwnd); + int clrRes = 0; + + if (hdc) + clrRes = GetDeviceCaps(hdc, COLORRES); + + return clrRes; +} + +//------------------------------- +// +//------------------------------- + +sal_Int32 SAL_CALL CDIBPreview::getAvailableWidth() throw (RuntimeException) +{ + RECT rect; + bool bRet = GetClientRect(m_Hwnd,&rect); + + sal_Int32 cx = 0; + + if ( bRet ) + cx = rect.right; + + return cx; +} + +//------------------------------- +// +//------------------------------- + +sal_Int32 SAL_CALL CDIBPreview::getAvailableHeight() throw (RuntimeException) +{ + RECT rect; + bool bRet = GetClientRect(m_Hwnd,&rect); + + sal_Int32 cy = 0; + + if ( bRet ) + cy = rect.bottom; + + return cy; +} + +//------------------------------- +// +//------------------------------- + +void SAL_CALL CDIBPreview::setImage(sal_Int16 aImageFormat, const Any& aImage) + throw (IllegalArgumentException, RuntimeException) +{ + PreviewBase::setImage(aImageFormat,aImage); + + // if the any has no value we have an + // empty Sequence which clears the + // preview window + osl::ClearableMutexGuard aGuard(m_PaintLock); + + m_Image.realloc(0); + m_ImageData >>= m_Image; + + aGuard.clear(); + + InvalidateRect(m_Hwnd,NULL,FALSE); + UpdateWindow(m_Hwnd); +} + +//------------------------------- +// +//------------------------------- + +sal_Bool SAL_CALL CDIBPreview::setShowState(sal_Bool bShowState) throw (RuntimeException) +{ + PreviewBase::setShowState(bShowState); + ShowWindow(m_Hwnd, m_bShowState ? SW_SHOW : SW_HIDE); + return sal_True; +} + +//------------------------------- +// +//------------------------------- + +sal_Bool SAL_CALL CDIBPreview::getShowState() throw (RuntimeException) +{ + return (sal_Bool)IsWindowVisible(m_Hwnd); +} + +//------------------------------- +// +//------------------------------- + +HWND SAL_CALL CDIBPreview::getWindowHandle() const +{ + return m_Hwnd; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CDIBPreview::onPaint(HWND hWnd, HDC hDC) +{ + BITMAPFILEHEADER* pbmfh; + BITMAPINFO * pbmi; + BYTE * pBits; + int cxDib; + int cyDib; + + osl::MutexGuard aGuard(m_PaintLock); + + try + { + pbmfh = reinterpret_cast<BITMAPFILEHEADER*>(m_Image.getArray()); + + if ( !IsBadReadPtr( pbmfh, sizeof(BITMAPFILEHEADER)) && + (pbmfh->bfType == ('B' | ('M' << 8))) ) + { + pbmi = reinterpret_cast<BITMAPINFO*>((pbmfh + 1)); + pBits = reinterpret_cast<BYTE*>(((DWORD)pbmfh) + pbmfh->bfOffBits); + + cxDib = pbmi->bmiHeader.biWidth; + cyDib = abs (pbmi->bmiHeader.biHeight); + + SetStretchBltMode(hDC, COLORONCOLOR); + + int nWidth = getAvailableWidth(); + int nHeight = getAvailableHeight(); + + int nX = abs(nWidth - cxDib) / 2; + int nY = abs(nHeight - cyDib) / 2; + + int GDIError = GDI_ERROR; + GDIError = StretchDIBits( + hDC, nX, nY, cxDib, cyDib, + 0, 0, cxDib, cyDib, pBits, pbmi, + DIB_RGB_COLORS, SRCCOPY); + + OSL_ASSERT(GDI_ERROR != GDIError); + + // paint the border + RECT rc; + + if (nY > 0) + { + // top + rc.left = 0; + rc.top = 0; + rc.right = nWidth; + rc.bottom = nY; + FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1)); + + // bottom + rc.left = 0; + rc.top = nHeight - nY - 1; + rc.right = nWidth; + rc.bottom = nHeight; + FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1)); + } + + if (nX > 0) + { + // left + rc.left = 0; + rc.top = nY; + rc.right = nX; + rc.bottom = nHeight - nY; + FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1)); + + // right + rc.left = nWidth - nX - 1; + rc.top = nY; + rc.right = nWidth; + rc.bottom = nHeight - nY; + FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1)); + } + } + else // clear background + { + RECT rc; + GetClientRect(hWnd,&rc); + FillRect(hDC,&rc,(HBRUSH)(COLOR_INACTIVEBORDER + 1)); + } + } + catch(...) + { + OSL_ASSERT(sal_False); + } +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +LRESULT CALLBACK CDIBPreview::WndProc( + HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LRESULT lResult = 0; + + switch(uMsg) + { + + // we connect a pointer to the current instance + // with a window instance via SetProp + case WM_CREATE: + { + LPCREATESTRUCT lpcs = + reinterpret_cast< LPCREATESTRUCT >(lParam); + + OSL_ASSERT(lpcs->lpCreateParams); + + // connect the instance handle to the window + SetProp(hWnd, CURRENT_INSTANCE, lpcs->lpCreateParams); + } + break; + + // we remove the window property which connects + // a class instance with a window class + case WM_NCDESTROY: + { + // RemoveProp returns the saved value on success + if (reinterpret_cast<CDIBPreview*>( + RemoveProp(hWnd, CURRENT_INSTANCE)) == NULL) + { + OSL_ASSERT(false); + } + } + break; + + case WM_PAINT: + { + CDIBPreview* pImpl = reinterpret_cast<CDIBPreview*>( + GetProp(hWnd, CURRENT_INSTANCE)); + + OSL_ASSERT(pImpl); + + HDC hDC; + PAINTSTRUCT ps; + + hDC = BeginPaint(hWnd,&ps); + pImpl->onPaint(hWnd,hDC); + EndPaint(hWnd,&ps); + } + break; + + // ignore this message in order to + // avoid flickering during paint + case WM_ERASEBKGND: + lResult = 1; + break; + + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + + return lResult; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +ATOM SAL_CALL CDIBPreview::RegisterDibPreviewWindowClass() +{ + osl::MutexGuard aGuard( s_Mutex ); + + if (0 == s_ClassAtom) + { + // register the preview window class + WNDCLASSEX wndClsEx; + ZeroMemory(&wndClsEx, sizeof(wndClsEx)); + + wndClsEx.cbSize = sizeof(wndClsEx); + wndClsEx.style = CS_HREDRAW | CS_VREDRAW; + wndClsEx.lpfnWndProc = CDIBPreview::WndProc; + wndClsEx.hInstance = m_Instance; + wndClsEx.hbrBackground = (HBRUSH)(COLOR_INACTIVEBORDER + 1); + wndClsEx.lpszClassName = PREVIEWWND_CLASS_NAME; + + // register the preview window class + // !!! Win95 - the window class will be unregistered automaticly + // if the dll is unloaded + // Win2000 - the window class must be unregistered manually + // if the dll is unloaded + s_ClassAtom = RegisterClassEx(&wndClsEx); + + OSL_POSTCOND(s_ClassAtom,"Could not register preview window class"); + + if (0 == s_ClassAtom) + throw std::runtime_error("Preview window class could not be registered"); + } + + // increment the register class counter + // so that we keep track of the number + // of class registrations + //if ( 0 != s_ClassAtom ) + s_RegisterDibPreviewWndCount++; + + return s_ClassAtom; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CDIBPreview::UnregisterDibPreviewWindowClass() +{ + osl::MutexGuard aGuard( s_Mutex ); + + OSL_ASSERT( ( (0 != s_ClassAtom) && (s_RegisterDibPreviewWndCount > 0)) || + ( (0 == s_ClassAtom) && (0 == s_RegisterDibPreviewWndCount) ) ); + + // update the register class counter + // and unregister the window class if + // counter drops to zero + if (0 != s_ClassAtom) + { + s_RegisterDibPreviewWndCount--; + OSL_ASSERT(s_RegisterDibPreviewWndCount >= 0); + } + + if (0 == s_RegisterDibPreviewWndCount) + { + UnregisterClass((LPCTSTR)MAKELONG(s_ClassAtom,0),m_Instance); + s_ClassAtom = 0; + } +} diff --git a/fpicker/source/win32/filepicker/dibpreview.hxx b/fpicker/source/win32/filepicker/dibpreview.hxx new file mode 100644 index 000000000000..ab8a0793a490 --- /dev/null +++ b/fpicker/source/win32/filepicker/dibpreview.hxx @@ -0,0 +1,116 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _DIBPREVIEW_HXX_ +#define _DIBPREVIEW_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include "previewbase.hxx" +#include <osl/mutex.hxx> + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//--------------------------------------------- +// A very simple wrapper for a window that does +// display DIBs. +// Maybe it would be better and more extensible +// to create another class that is responsible +// for rendering a specific image format into +// the area of the window, but for our purpose +// it's enough to go the simple way - KISS. +//--------------------------------------------- + +class CDIBPreview : public PreviewBase +{ +public: + + // ctor + CDIBPreview(HINSTANCE instance,HWND parent,sal_Bool bShowWindow = sal_False); + + // dtor + virtual ~CDIBPreview( ); + + // preview interface implementation + + virtual sal_Int32 SAL_CALL getTargetColorDepth() + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getAvailableWidth() + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getAvailableHeight() + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setImage(sal_Int16 aImageFormat, const ::com::sun::star::uno::Any& aImage) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL setShowState(sal_Bool bShowState) + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL getShowState() + throw (::com::sun::star::uno::RuntimeException); + + virtual HWND SAL_CALL getWindowHandle() const; + +private: + virtual void SAL_CALL onPaint( HWND hWnd, HDC hDC ); + + ATOM SAL_CALL RegisterDibPreviewWindowClass( ); + void SAL_CALL UnregisterDibPreviewWindowClass( ); + + static LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + +private: + HINSTANCE m_Instance; + HWND m_Hwnd; + com::sun::star::uno::Sequence<sal_Int8> m_Image; + osl::Mutex m_PaintLock; + + // the preview window class has to be registered only + // once per process, so multiple instance of this class + // share the registered window class + static ATOM s_ClassAtom; + static osl::Mutex s_Mutex; + static sal_Int32 s_RegisterDibPreviewWndCount; + +// prevent copy and assignment +private: + CDIBPreview(const CDIBPreview&); + CDIBPreview& operator=(const CDIBPreview&); +}; + + +#endif diff --git a/fpicker/source/win32/filepicker/eventnotification.hxx b/fpicker/source/win32/filepicker/eventnotification.hxx new file mode 100644 index 000000000000..6bd63f091441 --- /dev/null +++ b/fpicker/source/win32/filepicker/eventnotification.hxx @@ -0,0 +1,53 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _EVENTNOTIFICATION_HXX_ +#define _EVENTNOTIFICATION_HXX_ + +#ifndef _COM_SUN_STAR_UNO_XINTEFACE_HPP_ +#include <com/sun/star/uno/XInterface.hpp> +#endif +#include <com/sun/star/uno/Reference.hxx> + +//----------------------------------- +// encapsulate a filepicker event +// notification, because there are +// two types of filepicker notifications +// with and without parameter +// this is an application of the +// "command" pattern see GoF +//----------------------------------- + +class CEventNotification +{ +public: + virtual ~CEventNotification() { }; + + virtual void SAL_CALL notifyEventListener( com::sun::star::uno::Reference< com::sun::star::uno::XInterface > xListener ) = 0; +}; + +#endif diff --git a/fpicker/source/win32/filepicker/filepickereventnotification.cxx b/fpicker/source/win32/filepicker/filepickereventnotification.cxx new file mode 100644 index 000000000000..06f1b690c02b --- /dev/null +++ b/fpicker/source/win32/filepicker/filepickereventnotification.cxx @@ -0,0 +1,84 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" +#include "filepickereventnotification.hxx" +#include <sal/types.h> + +//----------------------------------- +// namespace directives +//----------------------------------- + +using namespace com::sun::star::uno; +using namespace com::sun::star::ui::dialogs; + +//----------------------------------- +// A FilePicker event without +// parameter +//----------------------------------- + +CFilePickerEventNotification::CFilePickerEventNotification(EventListenerMethod_t EventListenerMethod) : + m_EventListenerMethod(EventListenerMethod) +{ +} + +//---------------------------------- +// +//---------------------------------- + +void SAL_CALL CFilePickerEventNotification::notifyEventListener( Reference< XInterface > xListener ) +{ + Reference<XFilePickerListener> xFilePickerListener(xListener,UNO_QUERY); + if (xFilePickerListener.is()) + (xFilePickerListener.get()->*m_EventListenerMethod)(); +} + + +//################################################## + + +//---------------------------------- +// A FilePicker event with parameter +//---------------------------------- + +CFilePickerParamEventNotification::CFilePickerParamEventNotification(EventListenerMethod_t EventListenerMethod, const FilePickerEvent& FilePickerEvent) : + m_EventListenerMethod(EventListenerMethod), + m_FilePickerEvent(FilePickerEvent) +{ +} + +//---------------------------------- +// A FilePicker event with parameter +//---------------------------------- + +void SAL_CALL CFilePickerParamEventNotification::notifyEventListener( Reference< XInterface > xListener ) +{ + Reference<XFilePickerListener> xFilePickerListener(xListener,UNO_QUERY); + if (xFilePickerListener.is()) + (xFilePickerListener.get()->*m_EventListenerMethod)(m_FilePickerEvent); +} diff --git a/fpicker/source/win32/filepicker/filepickereventnotification.hxx b/fpicker/source/win32/filepicker/filepickereventnotification.hxx new file mode 100644 index 000000000000..a783427acae1 --- /dev/null +++ b/fpicker/source/win32/filepicker/filepickereventnotification.hxx @@ -0,0 +1,73 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _FILEPICKEREVENTNOTIFICATION_HXX_ +#define _FILEPICKEREVENTNOTIFICATION_HXX_ + +#include "eventnotification.hxx" +#include <com/sun/star/ui/dialogs/XFilePickerListener.hpp> +#include <com/sun/star/ui/dialogs/FilePickerEvent.hpp> + +//----------------------------------- +// A FilePicker event without +// parameter +//----------------------------------- + +class CFilePickerEventNotification : public CEventNotification +{ +public: + typedef void (SAL_CALL ::com::sun::star::ui::dialogs::XFilePickerListener::*EventListenerMethod_t)(); + +public: + CFilePickerEventNotification(EventListenerMethod_t EventListenerMethod); + + virtual void SAL_CALL notifyEventListener( com::sun::star::uno::Reference< com::sun::star::uno::XInterface > xListener ); + +private: + EventListenerMethod_t m_EventListenerMethod; +}; + +//---------------------------------- +// A FilePicker event with parameter +//---------------------------------- + +class CFilePickerParamEventNotification : public CEventNotification +{ +public: + typedef void (SAL_CALL ::com::sun::star::ui::dialogs::XFilePickerListener::*EventListenerMethod_t)(const ::com::sun::star::ui::dialogs::FilePickerEvent&); + + CFilePickerParamEventNotification(EventListenerMethod_t EventListenerMethod, const ::com::sun::star::ui::dialogs::FilePickerEvent& FilePickerEvent); + + virtual void SAL_CALL notifyEventListener( com::sun::star::uno::Reference< com::sun::star::uno::XInterface > xListener ); + +private: + EventListenerMethod_t m_EventListenerMethod; + com::sun::star::ui::dialogs::FilePickerEvent m_FilePickerEvent; +}; + + +#endif diff --git a/fpicker/source/win32/filepicker/filepickerstate.cxx b/fpicker/source/win32/filepicker/filepickerstate.cxx new file mode 100644 index 000000000000..fdacebd0b9db --- /dev/null +++ b/fpicker/source/win32/filepicker/filepickerstate.cxx @@ -0,0 +1,717 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include "filepickerstate.hxx" +#include <osl/diagnose.h> +#include "controlaccess.hxx" +#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/ListBoxControlActions.hpp> +#include <com/sun/star/ui/dialogs/ControlActions.hpp> +#include "controlcommandrequest.hxx" +#include "controlcommandresult.hxx" +#include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/uno/XInterface.hpp> +#include <osl/file.hxx> +#include "FileOpenDlg.hxx" + +#include <memory> +#include "..\misc\WinImplHelper.hxx" +//--------------------------------------------- +// +//--------------------------------------------- + +using rtl::OUString; +using com::sun::star::uno::Any; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::Reference; +using com::sun::star::uno::XInterface; + +using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds; +using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds; +using namespace ::com::sun::star::ui::dialogs::ListboxControlActions; + +//--------------------------------------------- +// +//--------------------------------------------- + +const sal_Int32 MAX_LABEL = 256; +const sal_Int16 LISTBOX_LABEL_OFFSET = 100; + +//--------------------------------------------- +// declaration +//--------------------------------------------- + +CFilePickerState::~CFilePickerState( ) +{ +} + +//--------------------------------------------- +// +//--------------------------------------------- + +CNonExecuteFilePickerState::CNonExecuteFilePickerState( ) : + m_FirstControlCommand( NULL ) +{ +} + +//--------------------------------------------- +// +//--------------------------------------------- + +CNonExecuteFilePickerState::~CNonExecuteFilePickerState( ) +{ + reset( ); +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CNonExecuteFilePickerState::setValue( sal_Int16 aControlId, sal_Int16 aControlAction, const Any& aValue ) +{ + CValueControlCommand* value_command = new CValueControlCommand( + aControlId, aControlAction, aValue ); + + addControlCommand( value_command ); +} + +//--------------------------------------------- +// +//--------------------------------------------- + +Any SAL_CALL CNonExecuteFilePickerState::getValue( sal_Int16 aControlId, sal_Int16 aControlAction ) +{ + CValueControlCommandRequest value_request( aControlId, aControlAction ); + Any aAny; + + if (m_FirstControlCommand) + { + // pass the request along the command-chain + std::auto_ptr< CControlCommandResult > result( m_FirstControlCommand->handleRequest( &value_request ) ); + + OSL_ENSURE( result.get(), "invalid getValue request" ); + + if ( result.get() ) + { + // #101753 must remove assertion else running into deadlock + // because getValue may be called asynchronously from main thread + // with locked SOLAR_MUTEX but we also need SOLAR_MUTEX in + // WinFileOpenDialog::onInitDone ... but we cannot dismiss the + // assertion dialog because at this point the FileOpen Dialog + // has aleady the focus but is not yet visible :-( + // The real cure is to remove the VCL/SOLAR_MUTEX dependency + // cause by the use of our resource manager and not being able to + // generate native windows resources + //OSL_ENSURE( result->hasResult( ), "invalid getValue request" ); + + if ( result->hasResult( ) ) + { + CValueCommandResult* value_result = dynamic_cast< CValueCommandResult* >( result.get( ) ); + OSL_ENSURE( value_result, "should have be a CValueCommandResult" ); + + aAny = value_result->getValue( ); + OSL_ENSURE( aAny.hasValue( ), "empty any" ); + } + } + } + + return aAny; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CNonExecuteFilePickerState::enableControl( sal_Int16 aControlId, sal_Bool bEnable ) +{ + CEnableControlCommand* enable_command = new CEnableControlCommand( + aControlId, bEnable ); + + addControlCommand( enable_command ); +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CNonExecuteFilePickerState::setLabel( sal_Int16 aControlId, const ::rtl::OUString& aLabel ) +{ + CLabelControlCommand* label_command = new CLabelControlCommand( + aControlId, aLabel ); + + addControlCommand( label_command ); +} + +//--------------------------------------------- +// +//--------------------------------------------- + +OUString SAL_CALL CNonExecuteFilePickerState::getLabel( sal_Int16 aControlId ) +{ + CControlCommandRequest label_request( aControlId ); + + // pass the request along the command-chain + std::auto_ptr< CControlCommandResult > result( m_FirstControlCommand->handleRequest( &label_request ) ); + + OSL_ENSURE( result->hasResult( ), "invalid getValue request" ); + + OUString aLabel; + + if ( result->hasResult( ) ) + { + CLabelCommandResult* label_result = dynamic_cast< CLabelCommandResult* >( result.get( ) ); + OSL_ENSURE( label_result, "should have be a CLabelCommandResult" ); + + aLabel = label_result->getLabel( ); + } + + return aLabel; +} + +/* #i26224# + When typing file names with drive letter but without '\' + in the "File name" box of the FileOpen dialog the FileOpen + dialog makes strange paths out of them e.g. "d:.\test.sxw". + Such file names will not be accepted by sal so we fix these + somehow broken paths here. */ +OUString MatchFixBrokenPath(const OUString& path) +{ + OSL_ASSERT(path.getLength() >= 4); + + if (path[1] == ':' && path[2] == '.' && path[3] == '\\') + { + // skip the '.' + return OUString(path, 2) + path.copy(3, path.getLength() - 3); + } + return path; +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- +static ::rtl::OUString trimTrailingSpaces(const ::rtl::OUString& rString) +{ + rtl::OUString aResult(rString); + + sal_Int32 nIndex = rString.lastIndexOf(' '); + if (nIndex == rString.getLength()-1) + { + while (nIndex >= 0 && rString[nIndex] == ' ') + nIndex--; + if (nIndex >= 0) + aResult = rString.copy(0,nIndex+1); + else + aResult = ::rtl::OUString(); + } + return aResult; +} + +Sequence< OUString > SAL_CALL CNonExecuteFilePickerState::getFiles( CFileOpenDialog* aFileOpenDialog ) +{ + OSL_PRECOND( aFileOpenDialog, "invalid parameter" ); + + Sequence< OUString > aFilePathList; + OUString aFilePathURL; + OUString aFilePath; + ::osl::FileBase::RC rc; + + aFilePath = aFileOpenDialog->getFullFileName( ); + + if ( aFilePath.getLength( ) ) + { + // tokenize the returned string and copy the + // sub-strings separately into a sequence + const sal_Unicode* pTemp = aFilePath.getStr(); + const sal_Unicode* pStrEnd = pTemp + aFilePath.getLength(); + sal_uInt32 lSubStr; + + while (pTemp < pStrEnd) + { + // detect the length of the next sub string + lSubStr = rtl_ustr_getLength(pTemp); + + aFilePathList.realloc(aFilePathList.getLength() + 1); + + aFilePathList[aFilePathList.getLength() - 1] = + MatchFixBrokenPath(OUString(pTemp, lSubStr)); + + pTemp += (lSubStr + 1); + } + + // change all entries to file URLs + sal_Int32 lenFileList = aFilePathList.getLength( ); + OSL_ASSERT( lenFileList >= 1 ); + + for ( sal_Int32 i = 0; i < lenFileList; i++ ) + { + aFilePath = trimTrailingSpaces(aFilePathList[i]); + rc = ::osl::FileBase::getFileURLFromSystemPath( + aFilePath, aFilePathURL ); + + // we do return all or nothing, that means + // in case of failures we destroy the sequence + // and return an empty sequence + if ( rc != ::osl::FileBase::E_None ) + { + aFilePathList.realloc( 0 ); + break; + } + + aFilePathList[i] = aFilePathURL; + } + } + + return aFilePathList; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +OUString SAL_CALL CNonExecuteFilePickerState::getDisplayDirectory( CFileOpenDialog* aFileOpenDialog ) +{ + OSL_PRECOND( aFileOpenDialog, "invalid parameter" ); + + OUString pathURL; + OUString displayDir; + + displayDir = aFileOpenDialog->getLastDisplayDirectory( ); + + if ( displayDir.getLength( ) ) + ::osl::FileBase::getFileURLFromSystemPath( displayDir, pathURL ); + + return pathURL; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CNonExecuteFilePickerState::reset( ) +{ + CControlCommand* nextCommand; + CControlCommand* currentCommand = m_FirstControlCommand; + + while( currentCommand ) + { + nextCommand = currentCommand->getNextCommand( ); + delete currentCommand; + currentCommand = nextCommand; + } + + m_FirstControlCommand = NULL; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +CControlCommand* SAL_CALL CNonExecuteFilePickerState::getControlCommand( ) const +{ + return m_FirstControlCommand; +} + +//--------------------------------------------- +// we append new control commands to the end +// of the list so that we are sure the commands +// will be executed as the client issued it +//--------------------------------------------- + +void SAL_CALL CNonExecuteFilePickerState::addControlCommand( CControlCommand* aControlCommand ) +{ + OSL_ASSERT( aControlCommand ); + + if ( NULL == m_FirstControlCommand ) + { + m_FirstControlCommand = aControlCommand; + } + else + { + CControlCommand* pNextControlCommand = m_FirstControlCommand; + + while ( pNextControlCommand->getNextCommand( ) != NULL ) + pNextControlCommand = pNextControlCommand->getNextCommand( ); + + pNextControlCommand->setNextCommand( aControlCommand ); + } +} + +//####################################################################### + +//--------------------------------------------- +// +//--------------------------------------------- + +CExecuteFilePickerState::CExecuteFilePickerState( HWND hwndDlg ) : + m_hwndDlg( hwndDlg ) +{ +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CExecuteFilePickerState::setValue( sal_Int16 aControlId, sal_Int16 aControlAction, const Any& aValue ) +{ + // we do not support SET_HELP_URL/GET_HELP_URL + if ( com::sun::star::ui::dialogs::ControlActions::SET_HELP_URL == aControlAction ) + return; + + HWND hwndCtrl = GetHwndDlgItem( aControlId ); + + // the filter listbox can be manipulated via this + // method the caller should use XFilterManager + if ( !hwndCtrl || (aControlId == LISTBOX_FILTER) ) + { + OSL_ENSURE( sal_False, "invalid control id" ); + return; + } + + CTRL_CLASS aCtrlClass = GetCtrlClass( hwndCtrl ); + if ( UNKNOWN == aCtrlClass ) + { + OSL_ENSURE( sal_False, "unsupported control class" ); + return; + } + + CTRL_SETVALUE_FUNCTION_T lpfnSetValue = + GetCtrlSetValueFunction( aCtrlClass, aControlAction ); + + if ( !lpfnSetValue ) + { + OSL_ENSURE( sal_False, "unsupported control action" ); + return; + } + + // the function that we call should throw an IllegalArgumentException if + // the given value is invalid or empty, that's why we provide a Reference + // to an XInterface and a argument position + lpfnSetValue( hwndCtrl, aValue, Reference< XInterface >( ), 3 ); +} + +//--------------------------------------------- +// +//--------------------------------------------- + +Any SAL_CALL CExecuteFilePickerState::getValue( sal_Int16 aControlId, sal_Int16 aControlAction ) +{ + // we do not support SET_HELP_URL/GET_HELP_URL + if ( com::sun::star::ui::dialogs::ControlActions::GET_HELP_URL == aControlAction ) + return Any( ); + + HWND hwndCtrl = GetHwndDlgItem( aControlId ); + + // the filter listbox can be manipulated via this + // method the caller should use XFilterManager + if ( !hwndCtrl || (aControlId == LISTBOX_FILTER) ) + { + OSL_ENSURE( sal_False, "invalid control id" ); + return Any( ); + } + + CTRL_CLASS aCtrlClass = GetCtrlClass( hwndCtrl ); + if ( UNKNOWN == aCtrlClass ) + { + OSL_ENSURE( sal_False, "unsupported control class" ); + return Any( ); + } + + CTRL_GETVALUE_FUNCTION_T lpfnGetValue = + GetCtrlGetValueFunction( aCtrlClass, aControlAction ); + + if ( !lpfnGetValue ) + { + OSL_ENSURE( sal_False, "unsupported control action" ); + return Any( ); + } + + return lpfnGetValue( hwndCtrl ); +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CExecuteFilePickerState::enableControl( sal_Int16 aControlId, sal_Bool bEnable ) +{ + HWND hwndCtrl = GetHwndDlgItem( aControlId ); + + OSL_ENSURE( IsWindow( hwndCtrl ), "invalid element id"); + + EnableWindow( hwndCtrl, bEnable ); +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CExecuteFilePickerState::setLabel( sal_Int16 aControlId, const OUString& aLabel ) +{ + HWND hwndCtrl = GetHwndDlgItem( aControlId ); + + OSL_ENSURE( IsWindow( hwndCtrl ), "invalid element id"); + + if ( IsListboxControl( hwndCtrl ) ) + hwndCtrl = GetListboxLabelItem( aControlId ); + + OUString aWinLabel = SOfficeToWindowsLabel( aLabel ); + + // somewhat risky because we don't know if OUString + // has a terminating '\0' + SetWindowText( hwndCtrl, reinterpret_cast<LPCTSTR>(aWinLabel.getStr( )) ); +} + +//--------------------------------------------- +// +//--------------------------------------------- + +OUString SAL_CALL CExecuteFilePickerState::getLabel( sal_Int16 aControlId ) +{ + HWND hwndCtrl = GetHwndDlgItem( aControlId ); + + OSL_ENSURE( IsWindow( hwndCtrl ), "invalid element id"); + + if ( IsListboxControl( hwndCtrl ) ) + hwndCtrl = GetListboxLabelItem( aControlId ); + + sal_Unicode aLabel[MAX_LABEL]; + int nRet = GetWindowText( hwndCtrl, reinterpret_cast<LPTSTR>(aLabel), MAX_LABEL ); + + OUString ctrlLabel; + if ( nRet ) + { + ctrlLabel = OUString( aLabel, rtl_ustr_getLength( aLabel ) ); + ctrlLabel = WindowsToSOfficeLabel( aLabel ); + } + + return ctrlLabel; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +Sequence< OUString > SAL_CALL CExecuteFilePickerState::getFiles( CFileOpenDialog* aFileOpenDialog ) +{ + OSL_POSTCOND( aFileOpenDialog, "invalid parameter" ); + + Sequence< OUString > aFilePathList; + OUString aFilePathURL; + OUString aFilePath; + ::osl::FileBase::RC rc; + + // in execution mode getFullFileName doesn't + // return anything, so we must use another way + + // returns the currently selected file(s) + // including path information + aFilePath = aFileOpenDialog->getCurrentFilePath( ); + + // if multiple files are selected or the user + // typed anything that doesn't seem to be a valid + // file name getFileURLFromSystemPath fails + // and we return an empty file list + rc = ::osl::FileBase::getFileURLFromSystemPath( + aFilePath, aFilePathURL ); + + if ( ::osl::FileBase::E_None == rc ) + { + aFilePathList.realloc( 1 ); + aFilePathList[0] = aFilePathURL; + } + + return aFilePathList; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +OUString SAL_CALL CExecuteFilePickerState::getDisplayDirectory( CFileOpenDialog* aFileOpenDialog ) +{ + OSL_POSTCOND( aFileOpenDialog, "invalid parameter" ); + + OUString pathURL; + OUString displayDir; + + displayDir = aFileOpenDialog->getCurrentFolderPath( ); + + if ( displayDir.getLength( ) ) + ::osl::FileBase::getFileURLFromSystemPath( displayDir, pathURL ); + + return pathURL; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CExecuteFilePickerState::initFilePickerControls( CControlCommand* firstControlCommand ) +{ + CControlCommand* aControlCommand = firstControlCommand; + + while ( aControlCommand ) + { + aControlCommand->exec( this ); + aControlCommand = aControlCommand->getNextCommand( ); + } +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CExecuteFilePickerState::cacheControlState( HWND hwndControl, CFilePickerState* aNonExecFilePickerState ) +{ + OSL_ENSURE( hwndControl && aNonExecFilePickerState, "invalid parameters" ); + + CTRL_CLASS aCtrlClass = GetCtrlClass( hwndControl ); + + sal_Int16 aControlAction; + CTRL_GETVALUE_FUNCTION_T lpfnGetValue; + + if ( CHECKBOX == aCtrlClass ) + { + aControlAction = 0; + + lpfnGetValue = GetCtrlGetValueFunction( aCtrlClass, aControlAction ); + + OSL_ASSERT( lpfnGetValue ); + + aNonExecFilePickerState->setValue( + sal::static_int_cast< sal_Int16 >( GetDlgCtrlID( hwndControl ) ), + aControlAction, + lpfnGetValue( hwndControl ) ); + + aNonExecFilePickerState->setLabel( + sal::static_int_cast< sal_Int16 >( GetDlgCtrlID( hwndControl ) ), + getLabel( + sal::static_int_cast< sal_Int16 >( + GetDlgCtrlID( hwndControl ) ) ) ); + } + else if ( LISTBOX == aCtrlClass ) + { + // for listboxes we save only the + // last selected item and the last + // selected item index + + aControlAction = GET_SELECTED_ITEM; + + lpfnGetValue = GetCtrlGetValueFunction( aCtrlClass, aControlAction ); + + aNonExecFilePickerState->setValue( + sal::static_int_cast< sal_Int16 >( GetDlgCtrlID( hwndControl ) ), + aControlAction, + lpfnGetValue( hwndControl ) ); + + aControlAction = ::com::sun::star::ui::dialogs::ControlActions::GET_SELECTED_ITEM_INDEX; + + lpfnGetValue = GetCtrlGetValueFunction( aCtrlClass, aControlAction ); + + aNonExecFilePickerState->setValue( + sal::static_int_cast< sal_Int16 >( GetDlgCtrlID( hwndControl ) ), + aControlAction, + lpfnGetValue( hwndControl ) ); + } +} + +//--------------------------------------------- +// +//--------------------------------------------- + +void SAL_CALL CExecuteFilePickerState::setHwnd( HWND hwndDlg ) +{ + m_hwndDlg = hwndDlg; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +inline sal_Bool SAL_CALL CExecuteFilePickerState::IsListboxControl( HWND hwndControl ) const +{ + OSL_PRECOND( IsWindow( hwndControl ), "invalid parameter" ); + + CTRL_CLASS aCtrlClass = GetCtrlClass( hwndControl ); + return ( LISTBOX == aCtrlClass ); +} + +//--------------------------------------------- +// because listboxes (comboboxes) and their labels +// are seperated we have to translate the listbox +// id to their corresponding label id +// the convention is that the label id of a listbox +// is the id of the listbox + 100 +//--------------------------------------------- + +inline sal_Int16 SAL_CALL CExecuteFilePickerState::ListboxIdToListboxLabelId( sal_Int16 aListboxId ) const +{ + return ( aListboxId + LISTBOX_LABEL_OFFSET ); +} + +//--------------------------------------------- +// +//--------------------------------------------- + +inline HWND SAL_CALL CExecuteFilePickerState::GetListboxLabelItem( sal_Int16 aControlId ) const +{ + sal_Int16 aLabelId = ListboxIdToListboxLabelId( aControlId ); + HWND hwndCtrl = GetHwndDlgItem( aLabelId ); + + OSL_ASSERT( IsWindow( hwndCtrl ) ); + + return hwndCtrl; +} + +//--------------------------------------------- +// +//--------------------------------------------- + +HWND SAL_CALL CExecuteFilePickerState::GetHwndDlgItem( sal_Int16 aControlId, sal_Bool bIncludeStdCtrls ) const +{ + OSL_ENSURE( IsWindow( m_hwndDlg ), "no valid parent window set before" ); + + HWND hwndCtrl = GetDlgItem( m_hwndDlg, aControlId ); + + // maybe it's a control of the dialog itself for instance + // the ok and cancel button + if ( !hwndCtrl && bIncludeStdCtrls ) + { + hwndCtrl = GetDlgItem( + GetParent( m_hwndDlg ), + CommonFilePickerCtrlIdToWinFileOpenCtrlId( aControlId ) ); + } + + return hwndCtrl; +} diff --git a/fpicker/source/win32/filepicker/filepickerstate.hxx b/fpicker/source/win32/filepicker/filepickerstate.hxx new file mode 100644 index 000000000000..7ea1322a6542 --- /dev/null +++ b/fpicker/source/win32/filepicker/filepickerstate.hxx @@ -0,0 +1,162 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _FILEPICKERSTATE_HXX_ +#define _FILEPICKERSTATE_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> +#include "controlcommand.hxx" +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include <rtl/ustring.hxx> + +#define WIN32_LEAN_AND_MEAN +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +//--------------------------------------------- +// +//--------------------------------------------- + +class CControlCommand; +class CFileOpenDialog; + +//--------------------------------------------- +// declaration +//--------------------------------------------- + +class CFilePickerState +{ +public: + virtual ~CFilePickerState( ); + + virtual void SAL_CALL setValue( sal_Int16 aControlId, sal_Int16 aControlAction, const ::com::sun::star::uno::Any& aValue ) = 0; + + virtual ::com::sun::star::uno::Any SAL_CALL getValue( sal_Int16 aControlId, sal_Int16 aControlAction ) = 0; + + virtual void SAL_CALL enableControl( sal_Int16 aControlId, sal_Bool bEnable ) = 0; + + virtual void SAL_CALL setLabel( sal_Int16 aControlId, const ::rtl::OUString& aLabel ) = 0; + + virtual ::rtl::OUString SAL_CALL getLabel( sal_Int16 aControlId ) = 0; + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getFiles( CFileOpenDialog* aFileOpenDialog ) = 0; + + virtual rtl::OUString SAL_CALL getDisplayDirectory( CFileOpenDialog* aFileOpenDialog ) = 0; +}; + +//--------------------------------------------- +// this class is not thread-safe +//--------------------------------------------- + +class CNonExecuteFilePickerState : public CFilePickerState +{ +public: + CNonExecuteFilePickerState( ); + + virtual ~CNonExecuteFilePickerState( ); + + virtual void SAL_CALL setValue( sal_Int16 aControlId, sal_Int16 aControlAction, const ::com::sun::star::uno::Any& aValue ); + + virtual ::com::sun::star::uno::Any SAL_CALL getValue( sal_Int16 aControlId, sal_Int16 aControlAction ); + + virtual void SAL_CALL enableControl( sal_Int16 aControlId, sal_Bool bEnable ); + + virtual void SAL_CALL setLabel( sal_Int16 aControlId, const ::rtl::OUString& aLabel ); + + virtual ::rtl::OUString SAL_CALL getLabel( sal_Int16 aControlId ); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getFiles( CFileOpenDialog* aFileOpenDialog ); + + virtual rtl::OUString SAL_CALL getDisplayDirectory( CFileOpenDialog* aFileOpenDialog ); + + void SAL_CALL reset( ); + + CControlCommand* SAL_CALL getControlCommand( ) const; + +protected: + void SAL_CALL addControlCommand( CControlCommand* aControlCommand ); + +private: + CControlCommand* m_FirstControlCommand; +}; + +//--------------------------------------------- +// this class is not thread-safe +//--------------------------------------------- + +class CExecuteFilePickerState : public CFilePickerState +{ +public: + CExecuteFilePickerState( HWND hwndDlg = NULL ); + + virtual void SAL_CALL setValue( sal_Int16 aControlId, sal_Int16 aControlAction, const ::com::sun::star::uno::Any& aValue ); + + virtual ::com::sun::star::uno::Any SAL_CALL getValue( sal_Int16 aControlId, sal_Int16 aControlAction ); + + virtual void SAL_CALL enableControl( sal_Int16 aControlId, sal_Bool bEnable ); + + virtual void SAL_CALL setLabel( sal_Int16 aControlId, const ::rtl::OUString& aLabel ); + + virtual ::rtl::OUString SAL_CALL getLabel( sal_Int16 aControlId ); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getFiles( CFileOpenDialog* aFileOpenDialog ); + + virtual rtl::OUString SAL_CALL getDisplayDirectory( CFileOpenDialog* aFileOpenDialog ); + + void SAL_CALL initFilePickerControls( CControlCommand* firstControlCommand ); + + void SAL_CALL cacheControlState( HWND hwndControl, CFilePickerState* aFilePickerState ); + + void SAL_CALL setHwnd( HWND hwndDlg ); + +private: + + inline sal_Bool SAL_CALL IsListboxControl( HWND hwndControl ) const; + + inline sal_Int16 SAL_CALL ListboxIdToListboxLabelId( sal_Int16 aListboxId ) const; + + inline HWND SAL_CALL GetListboxLabelItem( sal_Int16 aControlId ) const; + + // returns a hwnd for a control if successful + // if bIncludeStdCtrls is false, the standard file dialog + // controls like OK button, etc. will not be considered + // the function return 0 on failure + HWND SAL_CALL GetHwndDlgItem( sal_Int16 aControlId, sal_Bool bIncludeStdCtrls = sal_True ) const; + + HWND m_hwndDlg; +}; + +#endif diff --git a/fpicker/source/win32/filepicker/fps.xml b/fpicker/source/win32/filepicker/fps.xml new file mode 100644 index 000000000000..93530780956b --- /dev/null +++ b/fpicker/source/win32/filepicker/fps.xml @@ -0,0 +1,51 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name>fps</module-name> + <component-description> + <author> Tino Rachui </author> + <name> com.sun.star.comp.ui.dialogs.FilePicker </name> + <description> + The win32 implementation of the FilePicker service. +</description> + <loader-name>com.sun.star.loader.SharedLibrary</loader-name> + <language> c++ </language> + <status value="beta"/> + <supported-service> com.sun.star.ui.dialogs.FilePicker </supported-service> + <service-dependency>...</service-dependency> + <type> com.sun.star.ui.dialogs.XExecutableDialog </type> + <type> com.sun.star.ui.dialogs.XFilePicker </type> + <type> com.sun.star.ui.dialogs.XFilterManager </type> + <type> com.sun.star.ui.dialogs.XFilterGroupManager </type> + <type> com.sun.star.ui.dialogs.XFilePickerListener </type> + <type> com.sun.star.ui.dialogs.ExecutableDialogException </type> + <type> com.sun.star.ui.dialogs.XFilePickerNotifier </type> + <type> com.sun.star.ui.dialogs.XFilePickerControlAccess </type> + <type> com.sun.star.ui.dialogs.XFilePreview </type> + <type> com.sun.star.ui.dialogs.ExtendedFilePickerElementIds </type> + <type> com.sun.star.ui.dialogs.ExecutableDialogResults </type> + <type> com.sun.star.ui.dialogs.FilePickerEvent </type> + <type> com.sun.star.ui.dialogs.CommonFilePickerElementIds </type> + <type> com.sun.star.ui.dialogs.ListboxControlActions </type> + <type> com.sun.star.ui.dialogs.TemplateDescription </type> + <type> com.sun.star.ui.dialogs.FilePreviewImageFormats </type> + <type> com.sun.star.util.XCancellable </type> + <type> com.sun.star.lang.XComponent </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.lang.IllegalArgumentException </type> + <type> com.sun.star.uno.TypeClass </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.XAggregation </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.container.XSet </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper </runtime-module-dependency> + <runtime-module-dependency> cppu2 </runtime-module-dependency> + <runtime-module-dependency> sal2 </runtime-module-dependency> +</module-description> diff --git a/fpicker/source/win32/filepicker/getfilenamewrapper.cxx b/fpicker/source/win32/filepicker/getfilenamewrapper.cxx new file mode 100644 index 000000000000..43994393e139 --- /dev/null +++ b/fpicker/source/win32/filepicker/getfilenamewrapper.cxx @@ -0,0 +1,296 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <stdio.h> +#include <osl/diagnose.h> +#include "getfilenamewrapper.hxx" + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <objbase.h> +#include <process.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +namespace /* private */ +{ + + //----------------------------------------------- + // This class prevents changing of the working + // directory. + //----------------------------------------------- + class CurDirGuard + { + BOOL m_bValid; + wchar_t* m_pBuffer; + DWORD m_nBufLen; + + public: + CurDirGuard() + : m_bValid( FALSE ) + , m_pBuffer( NULL ) + , m_nBufLen( 0 ) + { + m_nBufLen = GetCurrentDirectoryW( 0, NULL ); + if ( m_nBufLen ) + { + m_pBuffer = new wchar_t[m_nBufLen]; + m_bValid = ( GetCurrentDirectoryW( m_nBufLen, m_pBuffer ) == ( m_nBufLen - 1 ) ); + } + } + + ~CurDirGuard() + { + BOOL bDirSet = FALSE; + + if ( m_pBuffer ) + { + if ( m_bValid ) + { + if ( m_nBufLen - 1 > MAX_PATH ) + { + if ( (LONG32)GetVersion() < 0 ) + { + // this is Win 98/ME branch, such a long path can not be set + // use the system path as fallback later + } + else + { + DWORD nNewLen = m_nBufLen + 8; + wchar_t* pNewBuffer = new wchar_t[nNewLen]; + if ( m_nBufLen > 3 && m_pBuffer[0] == (wchar_t)'\\' && m_pBuffer[1] == (wchar_t)'\\' ) + { + if ( m_pBuffer[2] == (wchar_t)'?' ) + _snwprintf( pNewBuffer, nNewLen, L"%s", m_pBuffer ); + else + _snwprintf( pNewBuffer, nNewLen, L"\\\\?\\UNC\\%s", m_pBuffer+2 ); + } + else + _snwprintf( pNewBuffer, nNewLen, L"\\\\?\\%s", m_pBuffer ); + bDirSet = SetCurrentDirectoryW( pNewBuffer ); + + delete [] pNewBuffer; + } + } + else + bDirSet = SetCurrentDirectoryW( m_pBuffer ); + } + + delete [] m_pBuffer; + m_pBuffer = NULL; + } + + if ( !bDirSet ) + { + // the fallback solution + wchar_t pPath[MAX_PATH+1]; + if ( GetWindowsDirectoryW( pPath, MAX_PATH+1 ) <= MAX_PATH ) + { + SetCurrentDirectoryW( pPath ); + } + else + { + // the system path is also too long?!! + } + } + } + }; + + //----------------------------------------------- + // + //----------------------------------------------- + + struct GetFileNameParam + { + GetFileNameParam(bool bOpen, LPOPENFILENAME lpofn) : + m_bOpen(bOpen), + m_lpofn(lpofn), + m_bRet(false), + m_ExtErr(0) + {} + + bool m_bOpen; + LPOPENFILENAME m_lpofn; + bool m_bRet; + int m_ExtErr; + }; + + //----------------------------------------------- + // + //----------------------------------------------- + + unsigned __stdcall ThreadProc(void* pParam) + { + CurDirGuard aGuard; + + GetFileNameParam* lpgfnp = + reinterpret_cast<GetFileNameParam*>(pParam); + + HRESULT hr = OleInitialize( NULL ); + + if (lpgfnp->m_bOpen) + lpgfnp->m_bRet = GetOpenFileName(lpgfnp->m_lpofn); + else + lpgfnp->m_bRet = GetSaveFileName(lpgfnp->m_lpofn); + + lpgfnp->m_ExtErr = CommDlgExtendedError(); + + if ( SUCCEEDED( hr ) ) + OleUninitialize(); + + return 0; + } + + //----------------------------------------------- + // exceutes GetOpenFileName/GetSaveFileName in + // a separat thread + //----------------------------------------------- + + bool ThreadExecGetFileName(LPOPENFILENAME lpofn, bool bOpen, /*out*/ int& ExtErr) + { + GetFileNameParam gfnp(bOpen,lpofn); + unsigned id; + + HANDLE hThread = reinterpret_cast<HANDLE>( + _beginthreadex(0, 0, ThreadProc, &gfnp, 0, &id)); + + OSL_POSTCOND(hThread, "could not create STA thread"); + + WaitForSingleObject(hThread, INFINITE); + CloseHandle(hThread); + + ExtErr = gfnp.m_ExtErr; + + return gfnp.m_bRet; + } + + //----------------------------------------------- + // This function returns true if the calling + // thread belongs to a Multithreaded Appartment + // (MTA) + //----------------------------------------------- + + bool IsMTA() + { + HRESULT hr = CoInitialize(NULL); + + if (RPC_E_CHANGED_MODE == hr) + return true; + + if(SUCCEEDED(hr)) + CoUninitialize(); + + return false; + } + +} // namespace private + + +//----------------------------------------------- +// +//----------------------------------------------- + +CGetFileNameWrapper::CGetFileNameWrapper() : + m_ExtendedDialogError(0) +{ +} + +//----------------------------------------------- +// +//----------------------------------------------- + +bool CGetFileNameWrapper::getOpenFileName(LPOPENFILENAME lpofn) +{ + OSL_PRECOND(lpofn,"invalid parameter"); + + bool bRet = false; + + if (IsMTA()) + { + bRet = ThreadExecGetFileName( + lpofn, true, m_ExtendedDialogError); + } + else + { + CurDirGuard aGuard; + + HRESULT hr = OleInitialize( NULL ); + + bRet = GetOpenFileName(lpofn); + m_ExtendedDialogError = CommDlgExtendedError(); + + if ( SUCCEEDED( hr ) ) + OleUninitialize(); + } + + return bRet; +} + +//----------------------------------------------- +// +//----------------------------------------------- + +bool CGetFileNameWrapper::getSaveFileName(LPOPENFILENAME lpofn) +{ + OSL_PRECOND(lpofn,"invalid parameter"); + + bool bRet = false; + + if (IsMTA()) + { + bRet = ThreadExecGetFileName( + lpofn, false, m_ExtendedDialogError); + } + else + { + CurDirGuard aGuard; + + bRet = GetSaveFileName(lpofn); + m_ExtendedDialogError = CommDlgExtendedError(); + } + + return bRet; +} + +//----------------------------------------------- +// +//----------------------------------------------- + +int CGetFileNameWrapper::commDlgExtendedError( ) +{ + return m_ExtendedDialogError; +} + diff --git a/fpicker/source/win32/filepicker/getfilenamewrapper.hxx b/fpicker/source/win32/filepicker/getfilenamewrapper.hxx new file mode 100644 index 000000000000..89914c7c7112 --- /dev/null +++ b/fpicker/source/win32/filepicker/getfilenamewrapper.hxx @@ -0,0 +1,66 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _GETFILENAMEWRAPPER_HXX_ +#define _GETFILENAMEWRAPPER_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> + +#define WIN32_LEAN_AND_MEAN +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#include <commdlg.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +/* + A simple wrapper around the GetOpenFileName/GetSaveFileName API. + Because currently the Win32 API functions GetOpenFileName/GetSaveFileName + work only properly in an Single Threaded Appartment. +*/ + +class CGetFileNameWrapper +{ +public: + CGetFileNameWrapper(); + + bool getOpenFileName(LPOPENFILENAME lpofn); + bool getSaveFileName(LPOPENFILENAME lpofn); + int commDlgExtendedError(); + +private: + int m_ExtendedDialogError; +}; + +#endif diff --git a/fpicker/source/win32/filepicker/helppopupwindow.cxx b/fpicker/source/win32/filepicker/helppopupwindow.cxx new file mode 100644 index 000000000000..5019af71e23e --- /dev/null +++ b/fpicker/source/win32/filepicker/helppopupwindow.cxx @@ -0,0 +1,615 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <tchar.h> +#include "helppopupwindow.hxx" +#include <osl/diagnose.h> + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +using rtl::OUString; +using osl::Mutex; + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +namespace /* private */ +{ + + const LPTSTR CURRENT_INSTANCE = TEXT("CurrInst"); + +}; + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +#define HELPPOPUPWND_CLASS_NAME TEXT("hlppopupwnd###") + +const sal_Int32 MAX_CHARS_PER_LINE = 55; + +const sal_Int32 SHADOW_WIDTH = 6; +const sal_Int32 SHADOW_HEIGHT = 6; +const sal_Int32 SHADOW_OFFSET = 6; +const sal_Int32 YOFFSET = 20; + +const DWORD OUTER_FRAME_COLOR = 0; // black +const sal_Int32 OUTER_FRAME_WIDTH = 1; // pixel + +// it's the standard windows color of an inactive window border +const DWORD INNER_FRAME_COLOR = 0xC8D0D4; +const sal_Int32 INNER_FRAME_WIDTH = 1; // pixel + +//--------------------------------------------------- +// static member initialization +//--------------------------------------------------- + +osl::Mutex CHelpPopupWindow::s_Mutex; +ATOM CHelpPopupWindow::s_ClassAtom = 0; +sal_Int32 CHelpPopupWindow::s_RegisterWndClassCount = 0; + +//--------------------------------------------------- +// +//--------------------------------------------------- + +CHelpPopupWindow::CHelpPopupWindow( + HINSTANCE hInstance, + HWND hwndParent ) : + m_hMargins( 0 ), + m_vMargins( 0 ), + m_avCharWidth( 0 ), + m_avCharHeight( 0 ), + m_hwnd( NULL ), + m_hwndParent( hwndParent ), + m_hInstance( hInstance ), + m_hBitmapShadow( NULL ), + m_hBrushShadow( NULL ) +{ + m_bWndClassRegistered = RegisterWindowClass( ) ? sal_True : sal_False; + + // create a pattern brush for the window shadow + WORD aPattern[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 }; + + m_hBitmapShadow = CreateBitmap( 8, 8, 1, 1, aPattern ); + m_hBrushShadow = CreatePatternBrush( m_hBitmapShadow ); +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +CHelpPopupWindow::~CHelpPopupWindow( ) +{ + // remember: we don't have to destroy the + // preview window because it will be destroyed + // by it's parent window (the FileOpen dialog) + // but we have to unregister the window class + if ( m_bWndClassRegistered ) + UnregisterWindowClass( ); + + DeleteObject( m_hBitmapShadow ); + DeleteObject( m_hBrushShadow ); +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CHelpPopupWindow::setText( const rtl::OUString& aHelpText ) +{ + m_HelpText = aHelpText; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CHelpPopupWindow::show( sal_Int32 x, sal_Int32 y ) +{ + OSL_ENSURE( NULL == m_hwnd, "method should not be called twice in sequence" ); + + // we create a window with length and heigth of 0 + // first in order to get a device context of this + // window, then we calculate the upper left corner + // and the dimensions and resize the window + + m_hwnd = CreateWindowEx( + NULL, + HELPPOPUPWND_CLASS_NAME, + NULL, + WS_POPUP, + 0, + 0, + 0, + 0, + m_hwndParent, + NULL, + m_hInstance, + (LPVOID)this ); + + OSL_ENSURE( m_hwnd, "creating help popup window failed" ); + + sal_Int32 cx_new; + sal_Int32 cy_new; + + adjustWindowSize( &cx_new, &cy_new ); + adjustWindowPos( x, y, cx_new, cy_new ); + + UpdateWindow( m_hwnd ); + ShowWindow( m_hwnd, SW_SHOW ); +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +HWND SAL_CALL CHelpPopupWindow::setParent( HWND hwndNewParent ) +{ + HWND oldParent = m_hwndParent; + + m_hwndParent = hwndNewParent; + + return oldParent; +} + +//--------------------------------------------------- +// calculates the necessary dimensions of the popup +// window including the margins etc. +//--------------------------------------------------- + +void SAL_CALL CHelpPopupWindow::calcWindowRect( LPRECT lprect ) +{ + OSL_ASSERT( m_hwnd && lprect ); + + SetRect( lprect, 0, 0, MAX_CHARS_PER_LINE * m_avCharWidth, 0 ); + + HDC hdc = GetDC( m_hwnd ); + + // set the font we are using later + HGDIOBJ oldFont = SelectObject( + hdc, GetStockObject( DEFAULT_GUI_FONT ) ); + + UINT nFormat = DT_WORDBREAK | DT_CALCRECT | DT_EXTERNALLEADING | DT_LEFT; + + if ( m_HelpText.getLength( ) <= MAX_CHARS_PER_LINE ) + nFormat |= DT_SINGLELINE; + + DrawText( + hdc, + reinterpret_cast<LPCTSTR>(m_HelpText.getStr( )), + m_HelpText.getLength( ), + lprect, + nFormat ); + + // add the necessary space for the frames + // and margins + + lprect->bottom += + m_vMargins + + SHADOW_HEIGHT + + OUTER_FRAME_WIDTH * 2 + + INNER_FRAME_WIDTH * 2; + + lprect->right += + SHADOW_WIDTH + + 2 * m_avCharWidth + + OUTER_FRAME_WIDTH * 2 + + INNER_FRAME_WIDTH * 2; + + SelectObject( hdc, oldFont ); + + ReleaseDC( m_hwnd, hdc ); +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CHelpPopupWindow::adjustWindowSize( sal_Int32* cx_new, sal_Int32* cy_new ) +{ + OSL_ASSERT( cx_new && cy_new ); + + RECT rect; + calcWindowRect( &rect ); + + // adjust the window size + SetWindowPos( + m_hwnd, + NULL, + 0, + 0, + rect.right, + rect.bottom, + SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER ); + + *cx_new = rect.right; + *cy_new = rect.bottom; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CHelpPopupWindow::adjustWindowPos( + sal_Int32 x, sal_Int32 y, sal_Int32 cx, sal_Int32 cy ) +{ + int popX; + int popY; + int popWidth; + int popHeight; + + OSL_ASSERT( m_hwnd ); + + HDC hdc = GetDC( m_hwnd ); + + // assuming these are screen coordinates + popWidth = cx; + popHeight = cy; + popX = x - ( popWidth / 2 ); + popY = y - YOFFSET; + + int xScreen = GetDeviceCaps( hdc, HORZRES ); + int yScreen = GetDeviceCaps( hdc, VERTRES ); + + if (popX < 0) + popX = 0; + + if (popY < 0) + popY = 0; + + if ((popX + popWidth) > xScreen) + popX = xScreen - popWidth; + + if ((popY + popHeight) > yScreen) + popY = yScreen - popHeight; + + SetWindowPos( + m_hwnd, + NULL, + popX, + popY, + 0, + 0, + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE ); + + ReleaseDC( m_hwnd, hdc ); +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CHelpPopupWindow::onPaint( HWND hWnd, HDC hdc ) +{ + RECT rc; + RECT rect; + HGDIOBJ hpen, hpenOld; + HGDIOBJ hbrOld; + COLORREF oldBkColor; + COLORREF oldTextColor; + HGDIOBJ oldFont; + HGDIOBJ oldBrush; + HGDIOBJ hBrush; + + GetClientRect( hWnd, &rc ); + + // draw the black border + + hBrush = CreateSolidBrush( GetSysColor( COLOR_INFOBK ) ); + oldBrush = SelectObject( hdc, hBrush ); + + hpen = CreatePen( PS_SOLID, 0, OUTER_FRAME_COLOR ); + hpenOld = SelectObject( hdc, hpen ); + + Rectangle( hdc, + rc.left + OUTER_FRAME_WIDTH, + rc.top + OUTER_FRAME_WIDTH, + rc.right - SHADOW_WIDTH, + rc.bottom - SHADOW_HEIGHT); + + SelectObject( hdc, oldBrush ); + SelectObject( hdc, hpenOld ); + + DeleteObject( hBrush ); + DeleteObject( hpen ); + + // draw a light gray border + + hBrush = CreateSolidBrush( GetSysColor( COLOR_INFOBK ) ); + oldBrush = SelectObject( hdc, hBrush ); + + hpen = CreatePen( PS_SOLID, 0, INNER_FRAME_COLOR ); + hpenOld = SelectObject( hdc, hpen ); + + Rectangle( hdc, + rc.left + OUTER_FRAME_WIDTH + 1, + rc.top + OUTER_FRAME_WIDTH + 1, + rc.right - SHADOW_WIDTH - OUTER_FRAME_WIDTH, + rc.bottom - SHADOW_HEIGHT - OUTER_FRAME_WIDTH ); + + SelectObject( hdc, oldBrush ); + SelectObject( hdc, hpenOld ); + + DeleteObject( hBrush ); + DeleteObject( hpen ); + + // Write some text to this window + + rect.left = rc.left + OUTER_FRAME_WIDTH + INNER_FRAME_WIDTH + 1 + m_hMargins; + rect.top = rc.top + OUTER_FRAME_WIDTH + INNER_FRAME_WIDTH + 1 + m_vMargins / 2; + rect.right = rc.right - SHADOW_WIDTH - OUTER_FRAME_WIDTH - INNER_FRAME_WIDTH - m_hMargins; + rect.bottom = rc.bottom - SHADOW_HEIGHT - OUTER_FRAME_WIDTH - INNER_FRAME_WIDTH - m_vMargins / 2; + + oldBkColor = SetBkColor( hdc, GetSysColor( COLOR_INFOBK ) ); + oldTextColor = SetTextColor( hdc, COLOR_INFOTEXT ); + + oldFont = SelectObject( hdc, GetStockObject( DEFAULT_GUI_FONT ) ); + + UINT nFormat = DT_WORDBREAK | DT_EXTERNALLEADING | DT_LEFT; + + if ( m_HelpText.getLength( ) <= MAX_CHARS_PER_LINE ) + nFormat |= DT_SINGLELINE; + + DrawText( + hdc, + (LPWSTR)m_HelpText.getStr( ), + m_HelpText.getLength( ), + &rect, + nFormat ); + + SelectObject( hdc, oldFont ); + SetTextColor( hdc, oldTextColor ); + SetBkColor( hdc, oldBkColor ); + + // set text color and text background color + // see MSDN PatBlt + + oldBkColor = SetBkColor( hdc, RGB( 0, 0, 0 ) ); + oldTextColor = SetTextColor( hdc, RGB( 255, 255, 255 ) ); + + // Get our brush for the shadow + + UnrealizeObject( m_hBrushShadow ); + hbrOld = SelectObject( hdc, m_hBrushShadow ); + + // bottom shadow + + PatBlt(hdc, + rc.left + SHADOW_OFFSET, + rc.bottom - SHADOW_HEIGHT, + rc.right - SHADOW_OFFSET - SHADOW_WIDTH, + SHADOW_HEIGHT, + 0xA000C9); + + // right-side shadow + + PatBlt(hdc, + rc.right - SHADOW_WIDTH, + rc.top + SHADOW_OFFSET, + SHADOW_WIDTH, + rc.bottom - SHADOW_OFFSET, + 0xA000C9); + + SelectObject(hdc, hbrOld); + SetTextColor( hdc, oldTextColor ); + SetBkColor( hdc, oldBkColor ); +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CHelpPopupWindow::onNcDestroy() +{ + m_hwnd = NULL; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CHelpPopupWindow::onCreate( HWND hwnd ) +{ + m_hwnd = hwnd; + + HDC hdc = GetDC( m_hwnd ); + + HGDIOBJ oldFont = SelectObject( + hdc, GetStockObject( DEFAULT_GUI_FONT ) ); + + TEXTMETRIC tm; + GetTextMetrics( hdc, &tm ); + + m_avCharWidth = tm.tmAveCharWidth; + m_avCharHeight = tm.tmHeight; + + if ( 0 == m_hMargins ) + m_hMargins = m_avCharWidth; + + if ( 0 == m_vMargins ) + m_vMargins = m_avCharHeight; + + SelectObject( hdc, oldFont ); + + ReleaseDC( m_hwnd, hdc ); +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +LRESULT CALLBACK CHelpPopupWindow::WndProc( + HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + LRESULT lResult = 0; + + switch ( uMsg ) + { + case WM_CREATE: + { + LPCREATESTRUCT lpcs = + reinterpret_cast< LPCREATESTRUCT >( lParam ); + + OSL_ASSERT( lpcs->lpCreateParams ); + + CHelpPopupWindow* pImpl = reinterpret_cast< CHelpPopupWindow* >( + lpcs->lpCreateParams ); + + // connect the instance handle to the window + SetProp( hWnd, CURRENT_INSTANCE, pImpl ); + + pImpl->onCreate( hWnd ); + + // capture mouse and keybord events + SetCapture( hWnd ); + } + break; + + case WM_PAINT: + { + CHelpPopupWindow* pImpl = reinterpret_cast< CHelpPopupWindow* >( + GetProp( hWnd, CURRENT_INSTANCE ) ); + + OSL_ASSERT( pImpl ); + + PAINTSTRUCT ps; + + BeginPaint(hWnd, &ps); + pImpl->onPaint( hWnd, ps.hdc ); + EndPaint(hWnd, &ps); + } + break; + + case WM_NCDESTROY: + { + // RemoveProp returns the saved value on success + CHelpPopupWindow* pImpl = reinterpret_cast< CHelpPopupWindow* >( + RemoveProp( hWnd, CURRENT_INSTANCE ) ); + + OSL_ASSERT( pImpl ); + + pImpl->onNcDestroy(); + } + break; + + case WM_LBUTTONDOWN: + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + ReleaseCapture(); + DestroyWindow(hWnd); + break; + + default: + return DefWindowProc(hWnd, uMsg, wParam, lParam); + } + + return lResult; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +ATOM SAL_CALL CHelpPopupWindow::RegisterWindowClass( ) +{ + osl::MutexGuard aGuard( s_Mutex ); + + if ( 0 == s_ClassAtom ) + { + // register the window class + WNDCLASSEX wndClsEx; + + ZeroMemory(&wndClsEx, sizeof(wndClsEx)); + + wndClsEx.cbSize = sizeof(wndClsEx); + wndClsEx.lpfnWndProc = CHelpPopupWindow::WndProc; + wndClsEx.hInstance = m_hInstance; + wndClsEx.hCursor = LoadCursor(NULL, IDC_ARROW); + wndClsEx.hbrBackground = (HBRUSH)GetStockObject( NULL_BRUSH ); + wndClsEx.lpszClassName = HELPPOPUPWND_CLASS_NAME; + + // register the preview window class + // !!! Win95 - the window class will be unregistered automaticly + // if the dll is unloaded + // Win2000 - the window class must be unregistered manually + // if the dll is unloaded + s_ClassAtom = RegisterClassEx( &wndClsEx ); + OSL_ASSERT(s_ClassAtom); + } + + // increment the register class counter + // so that we keep track of the number + // of class registrations + if (0 != s_ClassAtom) + s_RegisterWndClassCount++; + + return s_ClassAtom; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CHelpPopupWindow::UnregisterWindowClass( ) +{ + osl::MutexGuard aGuard( s_Mutex ); + + OSL_ASSERT( ( (0 != s_ClassAtom) && (s_RegisterWndClassCount > 0)) || + ( (0 == s_ClassAtom) && (0 == s_RegisterWndClassCount) ) ); + + // update the register class counter + // and unregister the window class if + // counter drops to zero + if ( 0 != s_ClassAtom ) + { + s_RegisterWndClassCount--; + OSL_ASSERT( s_RegisterWndClassCount >= 0 ); + } + + if ( 0 == s_RegisterWndClassCount ) + { + if ( !UnregisterClass( + (LPCTSTR)MAKELONG( s_ClassAtom, 0 ), m_hInstance ) ) + { + OSL_ENSURE( false, "unregister window class failed" ); + } + + s_ClassAtom = 0; + } +} diff --git a/fpicker/source/win32/filepicker/helppopupwindow.hxx b/fpicker/source/win32/filepicker/helppopupwindow.hxx new file mode 100644 index 000000000000..c58f3d03407b --- /dev/null +++ b/fpicker/source/win32/filepicker/helppopupwindow.hxx @@ -0,0 +1,143 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _HELPPOPUPWINDOW_HXX_ +#define _HELPPOPUPWINDOW_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> +#include <rtl/ustring.hxx> +#include <osl/mutex.hxx> + +#define WIN32_LEAN_AND_MEAN +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//--------------------------------------------- +// declaration +//--------------------------------------------- + +/* + A simple popup window similary to the one the + windows help (using WinHelp) creates when called + with the option HELP_CONTEXTPOPUP. + + The interface is very simple but necessary for our + needs. + The window automaticaly calculates the necessary + dimensions of the window and a appropriate show + position based on the position the client provides. + When the user click any mouse button or hits any key + the window closes itself and disappears. +*/ + +class CHelpPopupWindow +{ +public: + + /* + The client may set some parameter of the window. + When the client omits to set one or more values + a default value will be taken. + The values are in pixel. + */ + CHelpPopupWindow( + HINSTANCE hInstance, + HWND hwndParent ); + + /* + dtor + */ + ~CHelpPopupWindow( ); + + /* + The client may set the text the window is showing + on next activation. + */ + void SAL_CALL setText( const rtl::OUString& aHelpText ); + + /* + Shows the window with the text that was last set. + The posistion is the prefered position. The window + may itself show at a slightly different position + if it fits not at the prefered position. + */ + void SAL_CALL show( sal_Int32 x, sal_Int32 y ); + + HWND SAL_CALL setParent( HWND hwndNewParent ); + +private: + void SAL_CALL onPaint( HWND, HDC ); + void SAL_CALL onNcDestroy(); + void SAL_CALL onCreate( HWND ); + + POINT SAL_CALL calcUpperLeftCorner( ); + void SAL_CALL calcWindowRect( LPRECT lprect ); + + void SAL_CALL adjustWindowSize( sal_Int32*, sal_Int32* ); + void SAL_CALL adjustWindowPos( sal_Int32 x, sal_Int32 y, sal_Int32 cx, sal_Int32 cy ); + + ATOM SAL_CALL RegisterWindowClass( ); + void SAL_CALL UnregisterWindowClass( ); + + static LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + +private: + sal_Int32 m_hMargins; + sal_Int32 m_vMargins; + sal_Int32 m_avCharWidth; + sal_Int32 m_avCharHeight; + HWND m_hwnd; + HWND m_hwndParent; + HINSTANCE m_hInstance; + sal_Bool m_bWndClassRegistered; + ::rtl::OUString m_HelpText; + HBITMAP m_hBitmapShadow; + HBRUSH m_hBrushShadow; + + // the window class has to be registered only + // once per process, so multiple instance of this class + // share the registered window class + static ATOM s_ClassAtom; + static osl::Mutex s_Mutex; + static sal_Int32 s_RegisterWndClassCount; + +// prevent copy and assignment +private: + CHelpPopupWindow( const CHelpPopupWindow& ); + CHelpPopupWindow& operator=( const CHelpPopupWindow& ); +}; + +#endif diff --git a/fpicker/source/win32/filepicker/makefile.mk b/fpicker/source/win32/filepicker/makefile.mk new file mode 100644 index 000000000000..17e4f2609069 --- /dev/null +++ b/fpicker/source/win32/filepicker/makefile.mk @@ -0,0 +1,84 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=fpicker +TARGET=fps +#LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +CDEFS+=-D_UNICODE +CDEFS+=-DUNICODE +#CDEFS+=-DWIN32_LEAN_AND_MEAN +#CDEFS+=-DWIN32 +CDEFS+=-U_WIN32_WINNT -D_WIN32_WINNT=0x0600 + + +# --- Resources ---------------------------------------------------- + +.IF "$(GUI)" == "WNT" +RCFILES=fps.rc +.ENDIF + +# --- Files -------------------------------------------------------- + +SLOFILES=$(SLO)$/FileOpenDlg.obj\ + $(SLO)$/FPentry.obj\ + $(SLO)$/FilePicker.obj\ + $(SLO)$/WinFileOpenImpl.obj\ + $(SLO)$/FilterContainer.obj\ + $(SLO)$/controlaccess.obj\ + $(SLO)$/dibpreview.obj\ + $(SLO)$/helppopupwindow.obj\ + $(SLO)$/controlcommand.obj\ + $(SLO)$/filepickerstate.obj\ + $(SLO)$/getfilenamewrapper.obj\ + $(SLO)$/asynceventnotifier.obj\ + $(SLO)$/previewadapter.obj\ + $(SLO)$/previewbase.obj\ + $(SLO)$/filepickereventnotification.obj\ + $(SLO)$/customcontrol.obj\ + $(SLO)$/customcontrolcontainer.obj\ + $(SLO)$/customcontrolfactory.obj\ + $(SLO)$/dialogcustomcontrols.obj\ + $(SLO)$/asyncrequests.obj\ + $(SLO)$/VistaFilePickerEventHandler.obj\ + $(SLO)$/VistaFilePickerImpl.obj\ + $(SLO)$/VistaFilePicker.obj\ + $(SLO)$/SolarMutex.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/fpicker/source/win32/filepicker/platform_vista.h b/fpicker/source/win32/filepicker/platform_vista.h new file mode 100644 index 000000000000..e8812909f757 --- /dev/null +++ b/fpicker/source/win32/filepicker/platform_vista.h @@ -0,0 +1,87 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PLATFORM_VISTA_H_ +#define _PLATFORM_VISTA_H_ + +#pragma once + +// Change these values to use different versions +#undef WINVER +#undef _WIN32_WINNT +#undef _WIN32_IE +#undef _WTL_NO_CSTRING + +#define WINVER 0x0600 +#define _WIN32_WINNT 0x0600 +#define _WIN32_IE 0x0700 +#define _WTL_NO_CSTRING + +#if defined _MSC_VER +#pragma warning(push, 1) +#include <comip.h> +#pragma warning(pop) +#endif + +// ATL/WTL +//#include <atlbase.h> +//#include <atlstr.h> +//#include <atlapp.h> +//extern CAppModule _Module; +//#include <atlcom.h> +//#include <atlwin.h> +//#include <atlframe.h> +//#include <atlcrack.h> +//#include <atlctrls.h> +//#include <atlctrlx.h> +//#include <atldlgs.h> +//#include <atlmisc.h> + +/* +// STL +#include <vector> + +// Global functions +LPCTSTR PrepFilterString ( CString& sFilters ); +bool PathFromShellItem ( IShellItem* pItem, CString& sPath ); +bool BuildFilterSpecList ( _U_STRINGorID szFilterList, + std::vector<CString>& vecsFilterParts, + std::vector<COMDLG_FILTERSPEC>& vecFilters ); +*/ + +#if defined _M_IX86 + #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_IA64 + #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='ia64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#elif defined _M_X64 + #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") +#else + #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") +#endif + +#endif + diff --git a/fpicker/source/win32/filepicker/platform_xp.h b/fpicker/source/win32/filepicker/platform_xp.h new file mode 100644 index 000000000000..d9603ade0820 --- /dev/null +++ b/fpicker/source/win32/filepicker/platform_xp.h @@ -0,0 +1,55 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PLATFORM_XP_H_ +#define _PLATFORM_XP_H_ + +#pragma once + +// Change these values to use different versions +#undef WINVER +#undef _WIN32_WINNT +#undef _WIN32_IE +#undef _WTL_NO_CSTRING + +#define WINVER 0x0500 +#define _WIN32_WINNT 0x0500 +#define _WIN32_IE 0x0600 +#define _WTL_NO_CSTRING + +#if defined _MSC_VER + #pragma warning(push, 1) +#endif + +#include <windows.h> + +#if defined _MSC_VER + #pragma warning(pop) +#endif + +#endif + diff --git a/fpicker/source/win32/filepicker/previewadapter.cxx b/fpicker/source/win32/filepicker/previewadapter.cxx new file mode 100644 index 000000000000..d8fee2044115 --- /dev/null +++ b/fpicker/source/win32/filepicker/previewadapter.cxx @@ -0,0 +1,713 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +#include <tchar.h> +#include "previewadapter.hxx" + +#ifndef _COM_SUN_STAR_UI_DIALOG_FILEPREVIEWIMAGEFORMATS_HPP_ +#include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp> +#endif +#include "dibpreview.hxx" +#include "../misc/WinImplHelper.hxx" + +#include <memory> +#include <stdexcept> + +//--------------------------------------------- +// +//--------------------------------------------- + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; + +//--------------------------------------------- +// An impl class to hide implementation details +// from clients +//--------------------------------------------- + +class CPreviewAdapterImpl +{ +public: + CPreviewAdapterImpl(HINSTANCE instance); + + virtual ~CPreviewAdapterImpl(); + + virtual sal_Int32 SAL_CALL getTargetColorDepth(); + + virtual sal_Int32 SAL_CALL getAvailableWidth(); + + virtual sal_Int32 SAL_CALL getAvailableHeight(); + + virtual void SAL_CALL setImage( sal_Int16 aImageFormat, const Any& aImage ) + throw (IllegalArgumentException,RuntimeException); + + virtual sal_Bool SAL_CALL setShowState(sal_Bool bShowState); + + virtual sal_Bool SAL_CALL getShowState(); + + virtual void SAL_CALL setParent(HWND parent); + + virtual HWND SAL_CALL getParent(); + + //------------------------------------- + // parent notification handler + //------------------------------------- + + virtual void SAL_CALL notifyParentShow(sal_Bool bShow); + + virtual void SAL_CALL notifyParentSizeChanged(); + + virtual void SAL_CALL notifyParentWindowPosChanged(); + +protected: + virtual void SAL_CALL calcRightMargin(); + + virtual void SAL_CALL rearrangeLayout(); + + void SAL_CALL initializeActivePreview() throw(std::runtime_error); + + HWND SAL_CALL findFileListbox() const; + +// member +protected: + HINSTANCE m_Instance; + std::auto_ptr<PreviewBase> m_Preview; + HWND m_FileDialog; + int m_RightMargin; + +//prevent copy/assignment +private: + CPreviewAdapterImpl(const CPreviewAdapterImpl&); + CPreviewAdapterImpl& operator=(const CPreviewAdapterImpl&); +}; + +//----------------------------------------- +// +//----------------------------------------- + +CPreviewAdapterImpl::CPreviewAdapterImpl(HINSTANCE instance) : + m_Instance(instance), + m_Preview(new PreviewBase()), // create dummy preview (NULL-Object pattern) + m_FileDialog(0), + m_RightMargin(0) +{ +} + +//----------------------------------------- +// +//----------------------------------------- + +CPreviewAdapterImpl::~CPreviewAdapterImpl() +{ +} + +//----------------------------------------- +// +//----------------------------------------- + +sal_Int32 SAL_CALL CPreviewAdapterImpl::getTargetColorDepth() +{ + return m_Preview->getTargetColorDepth(); +} + +//----------------------------------------- +// +//----------------------------------------- + +sal_Int32 SAL_CALL CPreviewAdapterImpl::getAvailableWidth() +{ + return m_Preview->getAvailableWidth(); +} + +//----------------------------------------- +// +//----------------------------------------- + +sal_Int32 SAL_CALL CPreviewAdapterImpl::getAvailableHeight() +{ + return m_Preview->getAvailableHeight(); +} + +//----------------------------------------- +// +//----------------------------------------- + +void SAL_CALL CPreviewAdapterImpl::setImage( sal_Int16 aImageFormat, const Any& aImage ) + throw (IllegalArgumentException,RuntimeException) +{ + m_Preview->setImage(aImageFormat,aImage); +} + +//----------------------------------------- +// +//----------------------------------------- + +sal_Bool SAL_CALL CPreviewAdapterImpl::setShowState( sal_Bool bShowState ) +{ + sal_Bool bRet = m_Preview->setShowState(bShowState); + rearrangeLayout(); + return bRet; +} + +//----------------------------------------- +// +//----------------------------------------- + +sal_Bool SAL_CALL CPreviewAdapterImpl::getShowState() +{ + return m_Preview->getShowState(); +} + +//----------------------------------------- +// +//----------------------------------------- + +void SAL_CALL CPreviewAdapterImpl::setParent(HWND parent) +{ + OSL_PRECOND(IsWindow(parent),"Invalid FileDialog handle"); + + m_FileDialog = parent; + calcRightMargin(); +} + +//----------------------------------------- +// +//----------------------------------------- + +HWND SAL_CALL CPreviewAdapterImpl::getParent() +{ + return m_FileDialog; +} + +//----------------------------------------- +// +//----------------------------------------- + +void SAL_CALL CPreviewAdapterImpl::calcRightMargin() +{ + // Calculate the right reference margin + // + // Assumtions: + // 1. This method will be called before the dialog becomes + // visible + // 2. There exist a FileListbox with the id lst1 even + // if it is not visible like under Win2000/XP + // 3. Initially this FileListbox has the appropriate size + // to fit within the FileListbox + // 4. The margin between the right edge of the FileListbox + // and the right edge of the FileDialog will be constant + // even if the size of the dialog changes + + HWND flb = GetDlgItem(m_FileDialog,lst1); + + OSL_ENSURE(IsWindow(flb),"Filelistbox not found"); + + RECT rcFlb; + GetWindowRect(flb,&rcFlb); + + RECT rcFileDlg; + GetWindowRect(m_FileDialog,&rcFileDlg); + + m_RightMargin = rcFileDlg.right - rcFlb.right; +} + +//----------------------------------------- +// +//----------------------------------------- + +void SAL_CALL CPreviewAdapterImpl::notifyParentShow(sal_Bool) +{ +} + +//----------------------------------------- +// +//----------------------------------------- + +void SAL_CALL CPreviewAdapterImpl::notifyParentSizeChanged() +{ + rearrangeLayout(); +} + +//----------------------------------------- +// +//----------------------------------------- + +void SAL_CALL CPreviewAdapterImpl::notifyParentWindowPosChanged() +{ +} + +//----------------------------------------- +// +//----------------------------------------- + +void SAL_CALL CPreviewAdapterImpl::rearrangeLayout() +{ + // try to get a handle to the filelistbox + // if there is no new-style filelistbox like + // in Win2000/XP there should be at least the + // old listbox, so we take this one + // lst1 - identifies the old-style filelistbox + // lst2 - identifies the new-style filelistbox + // see dlgs.h + HWND flb_new = findFileListbox(); + + // under Windows NT 4.0 the size of the old + // filelistbox will be used as reference for + // sizing the new filelistbox, so we have + // to change the size of it too + HWND flb_old = GetDlgItem(m_FileDialog,lst1); + + RECT rcFlbNew; + GetWindowRect(flb_new,&rcFlbNew); + + RECT rcFileDlg; + GetWindowRect(m_FileDialog,&rcFileDlg); + rcFileDlg.right -= m_RightMargin; + + // the available area for the filelistbox should be + // the left edge of the filelistbox and the right + // edge of the OK button, we take this as reference + int height = rcFlbNew.bottom - rcFlbNew.top; + int width = rcFileDlg.right - rcFlbNew.left; + + HWND prvwnd = m_Preview->getWindowHandle(); + + // we use GetWindowLong to ask for the visibility + // of the preview window because IsWindowVisible + // only returns true the specified window including + // its parent windows are visible + // this is not the case when we are called in response + // to the WM_SHOWWINDOW message, somehow the WS_VISIBLE + // style bit of the FileOpen dialog must be set after that + // message + LONG lStyle = GetWindowLong(prvwnd,GWL_STYLE); + BOOL bIsVisible = (BOOL)(lStyle & WS_VISIBLE); + + int cx = 0; + + if (IsWindow(prvwnd) && bIsVisible) + { + cx = width/2; + + // resize the filelistbox to the half of the + // available space + BOOL bRet = SetWindowPos(flb_new, + NULL, 0, 0, cx, height, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + + bRet = SetWindowPos(flb_old, + NULL, 0, 0, cx, height, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + + // get the new dimensions of the filelistbox after + // resizing and take the right,top corner as starting + // point for the preview window + GetWindowRect(flb_new,&rcFlbNew); + POINT pt = { rcFlbNew.right, rcFlbNew.top }; + ScreenToClient(m_FileDialog,&pt); + + // resize the preview window to fit within + // the available space and set the window + // to the top of the z-order else it will + // be invisible + SetWindowPos(prvwnd, + HWND_TOP, pt.x, pt.y, cx, height, SWP_NOACTIVATE); + } + else + { + // resize the filelistbox to the maximum available + // space + cx = rcFileDlg.right - rcFlbNew.left; + + // resize the old filelistbox + SetWindowPos(flb_old, + NULL, 0, 0, cx, height, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); + + // resize the new filelistbox + SetWindowPos(flb_new, + NULL, 0, 0, cx, height, + SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE ); + } +} + +//----------------------------------------- +// +//----------------------------------------- + +void SAL_CALL CPreviewAdapterImpl::initializeActivePreview() throw(std::runtime_error) +{ + sal_Bool bShowState = m_Preview->getImaginaryShowState(); + + sal_Int16 aImgFrmt; + Any aImg; + m_Preview->getImage(aImgFrmt,aImg); + + HWND flb = findFileListbox(); + + PreviewBase* prv = new CDIBPreview( + m_Instance, GetParent(flb), bShowState); + + m_Preview.reset(prv); + + m_Preview->setImage(aImgFrmt,aImg); +} + +//----------------------------------------- +// +//----------------------------------------- + +HWND SAL_CALL CPreviewAdapterImpl::findFileListbox() const +{ + // try to get a handle to the filelistbox + // if there is no new-style filelistbox like + // in Win2000/XP there should be at least the + // old listbox, so we take this one + // lst1 - identifies the old-style filelistbox + // lst2 - identifies the new-style filelistbox + // see dlgs.h + HWND flb = GetDlgItem(m_FileDialog,lst2); + if (!IsWindow(flb)) + flb = GetDlgItem(m_FileDialog,lst1); + + return flb; +} + + +//############################################################## + + +//----------------------------------------- +// Special implementation for Win98 +// because: +// +//----------------------------------------- + +class CWin98PreviewAdapterImpl : public CPreviewAdapterImpl +{ +public: + CWin98PreviewAdapterImpl(HINSTANCE instance); + + virtual void SAL_CALL notifyParentWindowPosChanged(); + +protected: + virtual void SAL_CALL rearrangeLayout(); + + bool isValidToolbarDimension() const; + +private: + sal_Bool m_PreviewActive; + int m_ToolbarPosX; + int m_ToolbarPosY; + int m_ToolbarWidth; + int m_ToolbarHeight; +}; + +//-------------------------------------------- +// +//-------------------------------------------- + +CWin98PreviewAdapterImpl::CWin98PreviewAdapterImpl(HINSTANCE instance) : + CPreviewAdapterImpl(instance), + m_PreviewActive(sal_False), + m_ToolbarPosX(0), + m_ToolbarPosY(0), + m_ToolbarWidth(0), + m_ToolbarHeight(0) +{ +} + +//-------------------------------------------- +// +//-------------------------------------------- + +void SAL_CALL CWin98PreviewAdapterImpl::notifyParentWindowPosChanged() +{ + try + { + // the reason for this condition is + // Windows 98 + // Under Windows 98 the message WM_SHOWWINDOW + // will be sent only the first time the + // GetOpenFileName function is called within + // the same process + // so we must use another message to initialize + // the preview window + if (IsWindow(m_FileDialog) && !m_PreviewActive) + { + initializeActivePreview(); + m_PreviewActive = sal_True; + rearrangeLayout(); + } + + if (IsWindow(m_FileDialog) && !isValidToolbarDimension()) + { + RECT rcStc1; + GetWindowRect(GetDlgItem(m_FileDialog,stc1),&rcStc1); + + RECT rcCmb2; + GetWindowRect(GetDlgItem(m_FileDialog,cmb2),&rcCmb2); + + // Assumption: + // the toolbar position is only valid + // if the left edge is greater or equal + // than the right edge of the drives listbox + // the stc1 static text is invisible at runtime + // but will be used as reference for the position + // and dimension of the toolbar + if (rcStc1.left >= rcCmb2.right) + { + // important: save the upper left corner in + // client coordinates + POINT pt = {rcStc1.left,rcStc1.top}; + ScreenToClient(m_FileDialog,&pt); + + m_ToolbarPosX = pt.x; + m_ToolbarPosY = pt.y; + m_ToolbarWidth = rcStc1.right - rcStc1.left; + m_ToolbarHeight = rcStc1.bottom - rcStc1.top; + } + } + } + catch(std::runtime_error&) + { + } +} + +//-------------------------------------------- +// +//-------------------------------------------- + +void SAL_CALL CWin98PreviewAdapterImpl::rearrangeLayout() +{ + CPreviewAdapterImpl::rearrangeLayout(); + + // fix the position of the upper toolbar + // because the FileDialog moves all windows + // that are to the right of the FileListbox + // so if we have changed the size of the + // FileListbox we would run into trouble else + if (isValidToolbarDimension()) + { + HWND hwndTlb = FindWindowEx( + m_FileDialog,NULL,TEXT("ToolbarWindow32"),NULL); + + SetWindowPos(hwndTlb, + HWND_TOP, + m_ToolbarPosX, + m_ToolbarPosY, + m_ToolbarWidth, + m_ToolbarHeight, + SWP_NOACTIVATE); + } +} + +//-------------------------------------------- +// +//-------------------------------------------- + +bool CWin98PreviewAdapterImpl::isValidToolbarDimension() const +{ + return (m_ToolbarPosX > 0 && + m_ToolbarPosY > 0 && + m_ToolbarWidth > 0 && + m_ToolbarHeight > 0); +} + +//############################################################## + + +//-------------------------------------------- +// Implementation for Windows 95/NT/ME/2000/XP +// because: +// +//-------------------------------------------- + +class CWin95NTPreviewAdapterImpl : public CPreviewAdapterImpl +{ +public: + CWin95NTPreviewAdapterImpl(HINSTANCE instance); + + virtual void SAL_CALL notifyParentShow(sal_Bool bShow); +}; + +//-------------------------------------------- +// +//-------------------------------------------- + +CWin95NTPreviewAdapterImpl::CWin95NTPreviewAdapterImpl(HINSTANCE instance) : + CPreviewAdapterImpl(instance) +{ +} + +//-------------------------------------------- +// +//-------------------------------------------- + +void SAL_CALL CWin95NTPreviewAdapterImpl::notifyParentShow(sal_Bool bShow) +{ + try + { + if (bShow) + { + initializeActivePreview(); + rearrangeLayout(); + } + } + catch(std::runtime_error&) + { + } +} + + +//############################################################## + + +//------------------------------- +// ctor +//------------------------------- + +CPreviewAdapter::CPreviewAdapter(HINSTANCE instance) +{ + if (!IsWindows98()) + m_pImpl.reset(new CWin95NTPreviewAdapterImpl(instance)); + else + m_pImpl.reset(new CWin98PreviewAdapterImpl(instance)); +} + +//------------------------------- +// +//------------------------------- + +CPreviewAdapter::~CPreviewAdapter() +{ +} + +//------------------------------- +// +//------------------------------- + +Sequence<sal_Int16> SAL_CALL CPreviewAdapter::getSupportedImageFormats() +{ + com::sun::star::uno::Sequence<sal_Int16> imgFormats(1); + imgFormats[0] = ::com::sun::star::ui::dialogs::FilePreviewImageFormats::BITMAP; + return imgFormats; +} + +//------------------------------- +// +//------------------------------- + +sal_Int32 SAL_CALL CPreviewAdapter::getTargetColorDepth() +{ + return m_pImpl->getTargetColorDepth(); +} + +//------------------------------- +// +//------------------------------- + +sal_Int32 SAL_CALL CPreviewAdapter::getAvailableWidth() +{ + return m_pImpl->getAvailableWidth(); +} + +//------------------------------- +// +//------------------------------- + +sal_Int32 SAL_CALL CPreviewAdapter::getAvailableHeight() +{ + return m_pImpl->getAvailableHeight(); +} + +//------------------------------- +// +//------------------------------- + +void SAL_CALL CPreviewAdapter::setImage( sal_Int16 aImageFormat, const Any& aImage ) + throw (IllegalArgumentException, RuntimeException) +{ + m_pImpl->setImage(aImageFormat,aImage); +} + +//------------------------------- +// +//------------------------------- + +sal_Bool SAL_CALL CPreviewAdapter::setShowState( sal_Bool bShowState ) +{ + return m_pImpl->setShowState(bShowState); +} + +//------------------------------- +// +//------------------------------- + +sal_Bool SAL_CALL CPreviewAdapter::getShowState() +{ + return m_pImpl->getShowState(); +} + +//------------------------------- +// +//------------------------------- + +void SAL_CALL CPreviewAdapter::setParent(HWND parent) +{ + m_pImpl->setParent(parent); +} + +//------------------------------- +// +//------------------------------- + +void SAL_CALL CPreviewAdapter::notifyParentShow(bool bShow) +{ + m_pImpl->notifyParentShow(bShow); +} + +//------------------------------- +// +//------------------------------- + +void SAL_CALL CPreviewAdapter::notifyParentSizeChanged() +{ + m_pImpl->notifyParentSizeChanged(); +} + +//------------------------------- +// +//------------------------------- + +void SAL_CALL CPreviewAdapter::notifyParentWindowPosChanged() +{ + m_pImpl->notifyParentWindowPosChanged(); +} diff --git a/fpicker/source/win32/filepicker/previewadapter.hxx b/fpicker/source/win32/filepicker/previewadapter.hxx new file mode 100644 index 000000000000..82f3ac409f13 --- /dev/null +++ b/fpicker/source/win32/filepicker/previewadapter.hxx @@ -0,0 +1,107 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PREVIEWADAPTER_HXX_ +#define _PREVIEWADAPTER_HXX_ + +#include <sal/types.h> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/uno/Any.hxx> + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <memory> + +// forward declaration +class CPreviewAdapterImpl; + +//--------------------------------------------- +// A kind of a facade for the preview class. +// We want to hide the fact that the preview +// window may only become visible if there is +// a valid parent window (means, the FilePicker) +// is in execution mode. So unless someone sets +// the preview active with a valid parent +// window the preview may not be visible +//--------------------------------------------- + +class CPreviewAdapter +{ +public: + + // ctor + CPreviewAdapter(HINSTANCE instance); + + ~CPreviewAdapter(); + + ::com::sun::star::uno::Sequence<sal_Int16> SAL_CALL getSupportedImageFormats(); + + sal_Int32 SAL_CALL getTargetColorDepth(); + + sal_Int32 SAL_CALL getAvailableWidth(); + + sal_Int32 SAL_CALL getAvailableHeight(); + + void SAL_CALL setImage(sal_Int16 aImageFormat, const ::com::sun::star::uno::Any& aImage) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + sal_Bool SAL_CALL setShowState(sal_Bool bShowState); + + sal_Bool SAL_CALL getShowState(); + + void SAL_CALL setParent(HWND parent); + + //-------------------------------------- + // notification from parent + //-------------------------------------- + + void SAL_CALL notifyParentShow(bool bShow); + + void SAL_CALL notifyParentSizeChanged(); + + void SAL_CALL notifyParentWindowPosChanged(); + +private: + // hide implementation details using the + // bridge pattern + std::auto_ptr<CPreviewAdapterImpl> m_pImpl; + +// prevent copy and assignment +private: + CPreviewAdapter(const CPreviewAdapter&); + CPreviewAdapter& operator=(const CPreviewAdapter&); +}; + + +#endif diff --git a/fpicker/source/win32/filepicker/previewbase.cxx b/fpicker/source/win32/filepicker/previewbase.cxx new file mode 100644 index 000000000000..4e778e4fc011 --- /dev/null +++ b/fpicker/source/win32/filepicker/previewbase.cxx @@ -0,0 +1,150 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" +#include "previewbase.hxx" + +#ifndef _COM_SUN_STAR_UI_DIALOG_FILEPREVIEWIMAGEFORMATS_HPP_ +#include <com/sun/star/ui/dialogs/FilePreviewImageFormats.hpp> +#endif + +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace rtl; + +//------------------------------- +// +//------------------------------- + +PreviewBase::PreviewBase() : + m_ImageFormat(::com::sun::star::ui::dialogs::FilePreviewImageFormats::BITMAP), + m_bShowState(sal_False) +{ +} + +//------------------------------- +// +//------------------------------- + +PreviewBase::~PreviewBase() +{ +} + +//------------------------------- +// +//------------------------------- + +sal_Int32 SAL_CALL PreviewBase::getTargetColorDepth() throw (RuntimeException) +{ + return 0; +} + +//------------------------------- +// +//------------------------------- + +sal_Int32 SAL_CALL PreviewBase::getAvailableWidth() throw (RuntimeException) +{ + return 0; +} + +//------------------------------- +// +//------------------------------- + +sal_Int32 SAL_CALL PreviewBase::getAvailableHeight() throw (RuntimeException) +{ + return 0; +} + +//------------------------------- +// +//------------------------------- + +void SAL_CALL PreviewBase::setImage( sal_Int16 aImageFormat, const ::com::sun::star::uno::Any& aImage ) + throw (IllegalArgumentException, RuntimeException) +{ + if (aImageFormat != ::com::sun::star::ui::dialogs::FilePreviewImageFormats::BITMAP) + throw IllegalArgumentException( + OUString::createFromAscii("unsupported image format"), 0, 1); + + if (aImage.hasValue() && (aImage.getValueType() != getCppuType((Sequence<sal_Int8>*)0))) + throw IllegalArgumentException( + OUString::createFromAscii("invalid image data"), 0, 2); + + // save the new image data and force a redraw + m_ImageData = aImage; + m_ImageFormat = aImageFormat; +} + +//------------------------------- +// +//------------------------------- + +void SAL_CALL PreviewBase::getImage(sal_Int16& aImageFormat,com::sun::star::uno::Any& aImage) +{ + aImageFormat = m_ImageFormat; + aImage = m_ImageData; +} + +//------------------------------- +// +//------------------------------- + +sal_Bool SAL_CALL PreviewBase::setShowState( sal_Bool bShowState ) throw (RuntimeException) +{ + m_bShowState = bShowState; + return sal_True; +} + +//------------------------------- +// +//------------------------------- + +sal_Bool SAL_CALL PreviewBase::getShowState() throw (RuntimeException) +{ + return sal_False; +} + +//------------------------------- +// +//------------------------------- + +sal_Bool SAL_CALL PreviewBase::getImaginaryShowState() const +{ + return m_bShowState; +} + +//------------------------------- +// +//------------------------------- + +HWND SAL_CALL PreviewBase::getWindowHandle() const +{ + return 0; +} diff --git a/fpicker/source/win32/filepicker/previewbase.hxx b/fpicker/source/win32/filepicker/previewbase.hxx new file mode 100644 index 000000000000..b9296b439db2 --- /dev/null +++ b/fpicker/source/win32/filepicker/previewbase.hxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PREVIEWBASE_HXX_ +#define _PREVIEWBASE_HXX_ + +#include <sal/types.h> +#include <com/sun/star/uno/Sequence.hxx> +#include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/uno/Any.hxx> + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//--------------------------------------------- +// Common interface for previews +//--------------------------------------------- + +class PreviewBase +{ +public: + PreviewBase(); + + // dtor + virtual ~PreviewBase(); + + virtual sal_Int32 SAL_CALL getTargetColorDepth() + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getAvailableWidth() + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Int32 SAL_CALL getAvailableHeight() + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL setImage( sal_Int16 aImageFormat, const ::com::sun::star::uno::Any& aImage ) + throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL setShowState( sal_Bool bShowState ) + throw (::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL getShowState() + throw (::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL getImage(sal_Int16& aImageFormat,com::sun::star::uno::Any& aImage); + + sal_Bool SAL_CALL getImaginaryShowState() const; + + virtual HWND SAL_CALL getWindowHandle() const; + +protected: + ::com::sun::star::uno::Any m_ImageData; + sal_Int16 m_ImageFormat; + sal_Bool m_bShowState; +}; + + +#endif diff --git a/fpicker/source/win32/filepicker/propmap.hxx b/fpicker/source/win32/filepicker/propmap.hxx new file mode 100644 index 000000000000..1b4130b24716 --- /dev/null +++ b/fpicker/source/win32/filepicker/propmap.hxx @@ -0,0 +1,101 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _PROPMAP_HXX_ +#define _PROPMAP_HXX_ + +#include <hash_map> +#include <rtl/ustring.hxx> +#include <sal/types.h> + +typedef ::std::hash_map< ::rtl::OUString , + void* , + ::rtl::OUStringHash , + ::std::equal_to< ::rtl::OUString > > TPropMapBase; + +class TPropMap +{ + private: + + TPropMapBase m_aMap; + + public: + + template< class TValueType > + void put(const ::rtl::OUString& sKey , + const TValueType& rValue) + { + void* pValue = (void*)&rValue; + m_aMap[sKey] = pValue; + } + + template< class TValueType > + void put_copy(const ::rtl::OUString& sKey , + const TValueType& rValue) + { + TValueType* pCopy = new TValueType(rValue); + m_aMap[sKey] = (void*)pCopy; + } + + template< class TValueType > + sal_Bool get(const ::rtl::OUString& sKey , + TValueType** pValue) + { + TPropMapBase::iterator pIt = m_aMap.find(sKey); + if (pIt == m_aMap.end()) + return sal_False; + + void* pItem = pIt->second; + *pValue = (TValueType*)pItem; + return (pItem != 0); + } + + template< class TValueType > + sal_Bool get_copy(const ::rtl::OUString& sKey , + TValueType& rValue) + { + TPropMapBase::iterator pIt = m_aMap.find(sKey); + if (pIt == m_aMap.end()) + return sal_False; + + void* pValue = pIt->second; + if ( ! pValue) + return sal_False; + + rValue = *((TValueType*)pValue); + //delete pValue; + m_aMap.erase(pIt); + return sal_True; + } + + void clear() + { + m_aMap.clear(); + } +}; + +#endif diff --git a/fpicker/source/win32/filepicker/resource.h b/fpicker/source/win32/filepicker/resource.h new file mode 100644 index 000000000000..200b095e60f7 --- /dev/null +++ b/fpicker/source/win32/filepicker/resource.h @@ -0,0 +1,21 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by Fps.rc +// +#define IDD_DIALOG1 101 +#define IDB_BITMAP1 117 +#define IDB_BITMAP2 118 +#define IDC_BUTTON1 1008 +#define stc32 -1 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 119 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1014 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/fpicker/source/win32/filepicker/shared.hxx b/fpicker/source/win32/filepicker/shared.hxx new file mode 100644 index 000000000000..8be38aaeb7fc --- /dev/null +++ b/fpicker/source/win32/filepicker/shared.hxx @@ -0,0 +1,38 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FPICKER_WIN32_FILEPICKER_SHARED_HXX +#define FPICKER_WIN32_FILEPICKER_SHARED_HXX + +#include <rtl/ustring.hxx> + +const ::rtl::OUString BACKSLASH = ::rtl::OUString::createFromAscii( "\\" ); +const ::rtl::OUString FILTER_SEPARATOR = ::rtl::OUString::createFromAscii( "------------------------------------------" ); +const ::rtl::OUString ALL_FILES_WILDCARD = ::rtl::OUString::createFromAscii( "*.*" ); +const ::sal_Bool ALLOW_DUPLICATES = sal_True; + +#endif
\ No newline at end of file diff --git a/fpicker/source/win32/filepicker/vistatypes.h b/fpicker/source/win32/filepicker/vistatypes.h new file mode 100644 index 000000000000..d4c9975ccb78 --- /dev/null +++ b/fpicker/source/win32/filepicker/vistatypes.h @@ -0,0 +1,68 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef FPICKER_WIN32_VISTA_TYPES_HXX +#define FPICKER_WIN32_VISTA_TYPES_HXX + +//----------------------------------------------------------------------------- +// includes +//----------------------------------------------------------------------------- + +#include "comptr.hxx" +#include <shobjidl.h> + +//----------------------------------------------------------------------------- +// namespace +//----------------------------------------------------------------------------- + +#ifdef css + #error "Clash on using CSS as namespace define." +#else + #define css ::com::sun::star +#endif + +namespace fpicker{ +namespace win32{ +namespace vista{ + +//----------------------------------------------------------------------------- +// types, const etcpp. +//----------------------------------------------------------------------------- + +typedef ComPtr< IFileDialog , IID_IFileDialog > TFileDialog; +typedef ComPtr< IFileOpenDialog , IID_IFileOpenDialog , CLSID_FileOpenDialog > TFileOpenDialog; +typedef ComPtr< IFileSaveDialog , IID_IFileSaveDialog , CLSID_FileSaveDialog > TFileSaveDialog; +typedef ComPtr< IFileDialogEvents , IID_IFileDialogEvents > TFileDialogEvents; +typedef ComPtr< IFileDialogCustomize, IID_IFileDialogCustomize > TFileDialogCustomize; + +} // namespace vista +} // namespace win32 +} // namespace fpicker + +#undef css + +#endif // FPICKER_WIN32_VISTA_TYPES_HXX diff --git a/fpicker/source/win32/filepicker/workbench/Test_fps.cxx b/fpicker/source/win32/filepicker/workbench/Test_fps.cxx new file mode 100644 index 000000000000..8db37cefd34c --- /dev/null +++ b/fpicker/source/win32/filepicker/workbench/Test_fps.cxx @@ -0,0 +1,387 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + + +//_________________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________________ +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <osl/file.hxx> + +//_________________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________________ +#include <cppuhelper/servicefactory.hxx> + +#ifndef _RTL_USTRING_ +#include <rtl/ustring> +#endif +#include <sal/types.h> +#include <osl/diagnose.h> +#include <com/sun/star/ui/dialogs/XFilePicker.hpp> +#include <com/sun/star/ui/dialogs/XFilterManager.hpp> + +#ifndef _COM_SUN_STAR_UI_DIALOGS_FILEDIALOGRESULTS_HPP_ +#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> +#endif +#include <cppuhelper/implbase1.hxx> +#include <com/sun/star/ui/dialogs/XFilePickerListener.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerControlAccess.hpp> +#include <com/sun/star/ui/dialogs/XFilePickerNotifier.hpp> +#include <com/sun/star/ui/dialogs/TemplateDescription.hpp> +#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/ListboxControlActions.hpp> +#include <com/sun/star/ui/dialogs/XFilePreview.hpp> + +#include <osl/thread.h> + +#include <stdio.h> +#include <windows.h> + +#include "..\FPServiceInfo.hxx" + +// +// namesapces +// + +using namespace ::rtl ; +using namespace ::cppu ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::lang ; +using namespace ::com::sun::star::ui::dialogs ; +using namespace ::com::sun::star::ui::dialogs::TemplateDescription; + +using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds; +using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds; +using namespace ::com::sun::star::ui::dialogs::ListboxControlActions; + +using namespace std ; + +// forward + +void TestFilterManager( Reference< XFilePicker > xFilePicker ); + + +#define RDB_SYSPATH "D:\\Projects\\gsl\\sysui\\wntmsci7\\bin\\applicat.rdb" + +//_________________________________________________________________________________________________________________________ +// global variables +//_________________________________________________________________________________________________________________________ + +Reference< XMultiServiceFactory > g_xFactory; + +const OUString BMP_EXTENSION = OUString::createFromAscii( "bmp" ); + +//------------------------------------------------------------------------------------------------------------------------- +// a test client +//------------------------------------------------------------------------------------------------------------------------- + +class FilePickerListener : public WeakImplHelper1< XFilePickerListener > +{ +public: + + // XEventListener + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) + throw(::com::sun::star::uno::RuntimeException); + + // XFilePickerListener + virtual void SAL_CALL fileSelectionChanged( const ::com::sun::star::ui::dialogs::FilePickerEvent& aEvent ) + throw(::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL directoryChanged( const ::com::sun::star::ui::dialogs::FilePickerEvent& aEvent ) + throw(::com::sun::star::uno::RuntimeException); + + virtual OUString SAL_CALL helpRequested( const ::com::sun::star::ui::dialogs::FilePickerEvent& aEvent ) + throw(::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL controlStateChanged( const ::com::sun::star::ui::dialogs::FilePickerEvent& aEvent ) + throw(::com::sun::star::uno::RuntimeException); + + virtual void SAL_CALL dialogSizeChanged( ) + throw (::com::sun::star::uno::RuntimeException); +}; + +void SAL_CALL FilePickerListener::disposing( const ::com::sun::star::lang::EventObject& Source ) + throw(::com::sun::star::uno::RuntimeException) +{ +} + +void SAL_CALL FilePickerListener::fileSelectionChanged( const ::com::sun::star::ui::dialogs::FilePickerEvent& aEvent ) + throw(::com::sun::star::uno::RuntimeException) +{ + try + { + Reference< XFilePicker > rXFilePicker( aEvent.Source, UNO_QUERY ); + Reference< XFilePreview > rXFilePreview( rXFilePicker, UNO_QUERY ); + + if ( !rXFilePreview.is( ) ) + return; + + Sequence< OUString > aFileList = rXFilePicker->getFiles( ); + if ( 1 == aFileList.getLength( ) ) + { + OUString FilePath = aFileList[0]; + + // detect file extension + sal_Int32 nIndex = FilePath.lastIndexOf( BMP_EXTENSION ); + if ( (FilePath.getLength( ) - 3) == nIndex ) + { + OUString FileSysPath; + ::osl::FileBase::getSystemPathFromFileURL( + FilePath, FileSysPath ); + + HANDLE hFile = CreateFileW( + FileSysPath.getStr( ), + GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) ; + + if (hFile == INVALID_HANDLE_VALUE) + return; + + DWORD dwHighSize; + DWORD dwFileSize = GetFileSize (hFile, &dwHighSize) ; + + if (dwHighSize) + { + CloseHandle (hFile) ; + return; + } + + Sequence< sal_Int8 > aDIB( dwFileSize ); + + DWORD dwBytesRead; + BOOL bSuccess = ReadFile (hFile, aDIB.getArray( ), dwFileSize, &dwBytesRead, NULL) ; + CloseHandle (hFile); + + BITMAPFILEHEADER* pbmfh = (BITMAPFILEHEADER*)aDIB.getConstArray( ); + if (!bSuccess || (dwBytesRead != dwFileSize) + || (pbmfh->bfType != * (WORD *) "BM") + || (pbmfh->bfSize != dwFileSize)) + { + return; + } + + Any aAny; + + aAny <<= aDIB; + rXFilePreview->setImage( 1, aAny ); + } + } + } + catch( IllegalArgumentException& ex ) + { + ex = ex; + } +} + +void SAL_CALL FilePickerListener::directoryChanged( const ::com::sun::star::ui::dialogs::FilePickerEvent& aEvent ) + throw(::com::sun::star::uno::RuntimeException) +{ + Reference< XFilePickerControlAccess > rFilePickerCtrlAccess( aEvent.Source, UNO_QUERY ); +} + +OUString SAL_CALL FilePickerListener::helpRequested( const ::com::sun::star::ui::dialogs::FilePickerEvent& aEvent ) + throw(::com::sun::star::uno::RuntimeException) +{ + return OUString( ); +} + +void SAL_CALL FilePickerListener::controlStateChanged( const ::com::sun::star::ui::dialogs::FilePickerEvent& aEvent ) + throw(::com::sun::star::uno::RuntimeException) +{ + try + { + Reference< XFilePickerControlAccess > rFPCtrlAccess( aEvent.Source, UNO_QUERY ); + + Any aValue; + + OUString lbString( L"Ein Eintrag 1" ); + aValue <<= lbString; + rFPCtrlAccess->setValue( LISTBOX_VERSION, ADD_ITEM, aValue ); + + lbString = OUString( L"Ein Eintrag 2" ); + aValue <<= lbString; + rFPCtrlAccess->setValue( LISTBOX_VERSION, ADD_ITEM, aValue ); + + lbString = OUString( L"Ein Eintrag 3" ); + aValue <<= lbString; + rFPCtrlAccess->setValue( LISTBOX_VERSION, ADD_ITEM, aValue ); + + sal_Int16 nSel = 1; + aValue <<= nSel; + rFPCtrlAccess->setValue( LISTBOX_VERSION, SET_SELECT_ITEM, aValue ); + + sal_Int32 nDel = 0; + aValue <<= nDel; + rFPCtrlAccess->setValue( LISTBOX_VERSION, DELETE_ITEM, aValue ); + } + catch( ... ) + { + } +} + +void SAL_CALL FilePickerListener::dialogSizeChanged( ) + throw(::com::sun::star::uno::RuntimeException) +{ +} + +//-------------------------------------------------------- +// main +//-------------------------------------------------------- + + +int SAL_CALL main(int nArgc, char* Argv[], char* Env[] ) +{ + printf("Starting test of FPS-Service\n"); + + //------------------------------------------------- + // get the global service-manager + //------------------------------------------------- + + // Get global factory for uno services. + OUString rdbName = OUString( RTL_CONSTASCII_USTRINGPARAM( RDB_SYSPATH ) ); + Reference< XMultiServiceFactory > g_xFactory( createRegistryServiceFactory( rdbName ) ); + + // Print a message if an error occured. + if ( g_xFactory.is() == sal_False ) + { + OSL_ENSURE(sal_False, "Can't create RegistryServiceFactory"); + return(-1); + } + + //------------------------------------------------- + // try to get an Interface to a XFilePicker Service + //------------------------------------------------- + + Sequence< Any > arguments(1); + //arguments[0] = makeAny( FILEOPEN_SIMPLE ); + //arguments[0] = makeAny( FILESAVE_SIMPLE ); + //arguments[0] = makeAny( FILESAVE_AUTOEXTENSION_PASSWORD ); + //arguments[0] = makeAny( FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS ); + //arguments[0] = makeAny( FILESAVE_AUTOEXTENSION_SELECTION ); + //arguments[0] = makeAny( FILESAVE_AUTOEXTENSION_TEMPLATE ); + //arguments[0] = makeAny( FILEOPEN_LINK_PREVIEW_IMAGE_TEMPLATE ); + //arguments[0] = makeAny( FILEOPEN_PLAY ); + arguments[0] = makeAny( FILEOPEN_READONLY_VERSION ); + + Reference< XFilePicker > xFilePicker = Reference< XFilePicker >( + g_xFactory->createInstanceWithArguments( + OUString::createFromAscii( FILE_PICKER_SERVICE_NAME ), arguments ), UNO_QUERY ); + + // install a FilePicker notifier + Reference< XFilePickerListener > xFPListener( + static_cast< XFilePickerListener* >( new FilePickerListener()), UNO_QUERY ); + + Reference< XFilePickerNotifier > xFPNotifier( xFilePicker, UNO_QUERY ); + if ( xFPNotifier.is( ) ) + xFPNotifier->addFilePickerListener( xFPListener ); + + xFilePicker->setTitle( OUString::createFromAscii("FileOpen Simple...")); + xFilePicker->setMultiSelectionMode( sal_True ); + xFilePicker->setDefaultName( OUString::createFromAscii("d:\\test2.sxw")); + + OUString aDirURL; + OUString aSysPath = OStringToOUString( "d:\\ueaeoe", osl_getThreadTextEncoding( ) ); + ::osl::FileBase::getFileURLFromSystemPath( aSysPath, aDirURL ); + xFilePicker->setDisplayDirectory( aDirURL ); + + Reference< XFilterManager > xFilterMgr( xFilePicker, UNO_QUERY ); + if ( xFilterMgr.is( ) ) + { + xFilterMgr->appendFilter( L"Alle", L"*.*" ); + xFilterMgr->appendFilter( L"BMP", L"*.bmp" ); + xFilterMgr->appendFilter( L"SDW", L"*.sdw;*.sdc;*.sdi" ); + xFilterMgr->appendFilter( L"SXW", L"*.sxw;*.sxi" ); + } + + Reference< XFilePickerControlAccess > xFPControlAccess( xFilePicker, UNO_QUERY ); + + Any aAny; + sal_Bool bChkState = sal_False; + + aAny.setValue( &bChkState, getCppuType( (sal_Bool*)0 ) ); + xFPControlAccess->setValue( CHECKBOX_AUTOEXTENSION, 0, aAny ); + + OUString aVersion( L"Version 1" ); + aAny <<= aVersion; + xFPControlAccess->setValue( LISTBOX_VERSION, ADD_ITEM, aAny ); + xFPControlAccess->setValue( LISTBOX_VERSION, ADD_ITEM, aAny ); + xFPControlAccess->setValue( LISTBOX_VERSION, ADD_ITEM, aAny ); + + xFilePicker->execute( ); + + sal_Bool bCheckState; + aAny = xFPControlAccess->getValue( CHECKBOX_AUTOEXTENSION, 0 ); + if ( aAny.hasValue( ) ) + bCheckState = *reinterpret_cast< const sal_Bool* >( aAny.getValue( ) ); + + aAny = xFPControlAccess->getValue( CHECKBOX_READONLY, 0 ); + if ( aAny.hasValue( ) ) + bCheckState = *reinterpret_cast< const sal_Bool* >( aAny.getValue( ) ); + + aAny = xFPControlAccess->getValue( LISTBOX_VERSION, GET_SELECTED_ITEM ); + sal_Int32 nSel; + if ( aAny.hasValue( ) ) + aAny >>= nSel; + + aDirURL = xFilePicker->getDisplayDirectory( ); + Sequence< OUString > aFileList = xFilePicker->getFiles( ); + for ( int i = 0; i < aFileList.getLength( ); i++ ) + { + OUString nextPath = aFileList[i]; + } + + if ( xFPNotifier.is( ) ) + xFPNotifier->removeFilePickerListener( xFPListener ); + + //-------------------------------------------------- + // shutdown + //-------------------------------------------------- + + // Cast factory to XComponent + Reference< XComponent > xComponent( g_xFactory, UNO_QUERY ); + + // Print a message if an error occured. + if ( xComponent.is() == sal_False ) + { + OSL_ENSURE(sal_False, "Error shuting down"); + } + + // Dispose and clear factory + xComponent->dispose(); + g_xFactory.clear(); + g_xFactory = Reference< XMultiServiceFactory >(); + + printf("Test successful\n"); + + return 0; +} diff --git a/fpicker/source/win32/filepicker/workbench/makefile.mk b/fpicker/source/win32/filepicker/workbench/makefile.mk new file mode 100644 index 000000000000..926e2c22a0ed --- /dev/null +++ b/fpicker/source/win32/filepicker/workbench/makefile.mk @@ -0,0 +1,62 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. + +PRJNAME=sysui +TARGET=testfps +LIBTARGET=NO +TARGETTYPE=CUI + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +CFLAGS+=-GR -GX + +# --- Files -------------------------------------------------------- + + +OBJFILES=$(OBJ)$/test_fps.obj + +APP1TARGET=$(TARGET) +APP1OBJS=$(OBJFILES) + +APP1STDLIBS+=\ + $(CPPULIB)\ + $(CPPUHELPERLIB)\ + $(SALLIB)\ + $(USER32LIB)\ + $(OLE32LIB) + +APP1DEF=$(MISC)$/$(APP1TARGET).def + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk + + diff --git a/fpicker/source/win32/folderpicker/FOPServiceInfo.hxx b/fpicker/source/win32/folderpicker/FOPServiceInfo.hxx new file mode 100644 index 000000000000..4dc86192a051 --- /dev/null +++ b/fpicker/source/win32/folderpicker/FOPServiceInfo.hxx @@ -0,0 +1,54 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _FOPSERVICEINFO_HXX_ +#define _FOPSERVICEINFO_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +// the service name is a description of a set of +// interfaces (is the same as component categories in COM) + +// the service names +#define FOLDER_PICKER_SERVICE_NAME "com.sun.star.ui.dialogs.SystemFolderPicker" + +// the implementation names +#define FOLDER_PICKER_IMPL_NAME "com.sun.star.ui.dialogs.Win32FolderPicker" + +// the registry key names +// a key under which this service will be registered, Format: -> "/ImplName/UNO/SERVICES/ServiceName" +// < Implementation-Name ></UNO/SERVICES/>< Service-Name > +#define FOLDER_PICKER_REGKEY_NAME "/com.sun.star.ui.dialogs.Win32FolderPicker/UNO/SERVICES/com.sun.star.ui.dialogs.SystemFolderPicker" + +#endif diff --git a/fpicker/source/win32/folderpicker/FolderPicker.cxx b/fpicker/source/win32/folderpicker/FolderPicker.cxx new file mode 100644 index 000000000000..acfe310e1cc6 --- /dev/null +++ b/fpicker/source/win32/folderpicker/FolderPicker.cxx @@ -0,0 +1,219 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> + +#ifndef _FOLDERPICKER_HXX_ +#include "folderpicker.hxx" +#endif +#include <com/sun/star/lang/DisposedException.hpp> +#include "WinFOPImpl.hxx" + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using com::sun::star::uno::Reference; +using com::sun::star::uno::RuntimeException; +using com::sun::star::uno::Sequence; +using com::sun::star::uno::XInterface; +using com::sun::star::lang::XMultiServiceFactory; +using com::sun::star::lang::XServiceInfo; +using com::sun::star::lang::DisposedException; +using com::sun::star::lang::IllegalArgumentException; +using rtl::OUString; +using osl::MutexGuard; + +using namespace cppu; +using namespace com::sun::star::ui::dialogs; + +//------------------------------------------------------------------------ +// defines +//------------------------------------------------------------------------ + +#define FOLDERPICKER_IMPL_NAME "com.sun.star.ui.dialogs.Win32FolderPicker" + +//------------------------------------------------------------------------ +// helper functions +//------------------------------------------------------------------------ + +namespace +{ + Sequence< OUString > SAL_CALL FolderPicker_getSupportedServiceNames() + { + Sequence< OUString > aRet(1); + aRet[0] = OUString::createFromAscii("com.sun.star.ui.dialogs.SystemFolderPicker"); + return aRet; + } +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +CFolderPicker::CFolderPicker( const Reference< XMultiServiceFactory >& xServiceMgr ) : + m_xServiceMgr( xServiceMgr ) +{ + m_pFolderPickerImpl = std::auto_ptr< CWinFolderPickerImpl > ( new CWinFolderPickerImpl( this ) ); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFolderPicker::setTitle( const OUString& aTitle ) throw( RuntimeException ) +{ + OSL_ASSERT( m_pFolderPickerImpl.get( ) ); + MutexGuard aGuard( m_aMutex ); + m_pFolderPickerImpl->setTitle( aTitle ); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFolderPicker::setDisplayDirectory( const OUString& aDirectory ) + throw( IllegalArgumentException, RuntimeException ) +{ + OSL_ASSERT( m_pFolderPickerImpl.get( ) ); + MutexGuard aGuard( m_aMutex ); + m_pFolderPickerImpl->setDisplayDirectory( aDirectory ); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +OUString SAL_CALL CFolderPicker::getDisplayDirectory( ) + throw( RuntimeException ) +{ + OSL_ASSERT( m_pFolderPickerImpl.get( ) ); + MutexGuard aGuard( m_aMutex ); + return m_pFolderPickerImpl->getDisplayDirectory( ); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +OUString SAL_CALL CFolderPicker::getDirectory( ) throw( RuntimeException ) +{ + OSL_ASSERT( m_pFolderPickerImpl.get( ) ); + MutexGuard aGuard( m_aMutex ); + return m_pFolderPickerImpl->getDirectory( ); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +void SAL_CALL CFolderPicker::setDescription( const OUString& aDescription ) throw( RuntimeException ) +{ + OSL_ASSERT( m_pFolderPickerImpl.get( ) ); + MutexGuard aGuard( m_aMutex ); + m_pFolderPickerImpl->setDescription( aDescription ); +} + +//----------------------------------------------------------------------------------------- +// +//----------------------------------------------------------------------------------------- + +sal_Int16 SAL_CALL CFolderPicker::execute( ) + throw( RuntimeException ) +{ + OSL_ASSERT( m_pFolderPickerImpl.get( ) ); + + // we should not block in this call else + // in the case of an event the client can'tgetPImplFromHandle( hWnd ) + // call another function an we run into a + // deadlock !!!!! + return m_pFolderPickerImpl->execute( ); +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +OUString SAL_CALL CFolderPicker::getImplementationName( ) + throw( RuntimeException ) +{ + return OUString::createFromAscii( FOLDERPICKER_IMPL_NAME ); +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +sal_Bool SAL_CALL CFolderPicker::supportsService( const OUString& ServiceName ) + throw( RuntimeException ) +{ + Sequence < OUString > SupportedServicesNames = FolderPicker_getSupportedServiceNames(); + + for ( sal_Int32 n = SupportedServicesNames.getLength(); n--; ) + if (SupportedServicesNames[n].compareTo(ServiceName) == 0) + return sal_True; + + return sal_False; +} + +// ------------------------------------------------- +// XServiceInfo +// ------------------------------------------------- + +Sequence< OUString > SAL_CALL CFolderPicker::getSupportedServiceNames( ) + throw( RuntimeException ) +{ + return FolderPicker_getSupportedServiceNames(); +} + +// ------------------------------------------------- +// XCancellable +// ------------------------------------------------- + +void SAL_CALL CFolderPicker::cancel( ) + throw(RuntimeException) +{ + OSL_ASSERT( m_pFolderPickerImpl.get( ) ); + MutexGuard aGuard( m_aMutex ); + m_pFolderPickerImpl->cancel( ); +} + +//------------------------------------------------ +// overwrite base class method, which is called +// by base class dispose function +//------------------------------------------------ + +void SAL_CALL CFolderPicker::disposing() +{ +} + diff --git a/fpicker/source/win32/folderpicker/FolderPicker.hxx b/fpicker/source/win32/folderpicker/FolderPicker.hxx new file mode 100644 index 000000000000..0bb02c3b7682 --- /dev/null +++ b/fpicker/source/win32/folderpicker/FolderPicker.hxx @@ -0,0 +1,129 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _FOLDERPICKER_HXX_ +#define _FOLDERPICKER_HXX_ + +//--------------------------------------------------------- +// includes of other projects +//--------------------------------------------------------- + +#include <cppuhelper/implbase3.hxx> +#include <osl/mutex.hxx> +#include <com/sun/star/lang/XServiceInfo.hpp> + +#ifndef _COM_SUN_STAR_UI_XFOLDERPICKER_HPP_ +#include <com/sun/star/ui/dialogs/XFolderPicker.hpp> +#endif +#include <com/sun/star/util/XCancellable.hpp> + +#include <memory> + +#ifndef _FPIMPLBASE_HXX_ +#include "WinFOPImpl.hxx" +#endif + +//---------------------------------------------------------- +// class declaration +//---------------------------------------------------------- + +class CFolderPicker : + public cppu::WeakImplHelper3< + com::sun::star::ui::dialogs::XFolderPicker, + com::sun::star::lang::XServiceInfo, + com::sun::star::util::XCancellable > +{ +public: + + // ctor/dtor + CFolderPicker( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceMgr ); + + //------------------------------------------------------------------------------------ + // XExecutableDialog + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL setTitle( const rtl::OUString& aTitle ) + throw( com::sun::star::uno::RuntimeException ); + + virtual sal_Int16 SAL_CALL execute( ) + throw( com::sun::star::uno::RuntimeException ); + + //------------------------------------------------------------------------------------ + // XFolderPicker functions + //------------------------------------------------------------------------------------ + + virtual void SAL_CALL setDisplayDirectory( const rtl::OUString& aDirectory ) + throw( com::sun::star::lang::IllegalArgumentException, com::sun::star::uno::RuntimeException ); + + virtual rtl::OUString SAL_CALL getDisplayDirectory( ) + throw( com::sun::star::uno::RuntimeException ); + + virtual rtl::OUString SAL_CALL getDirectory( ) + throw( com::sun::star::uno::RuntimeException ); + + virtual void SAL_CALL setDescription( const rtl::OUString& aDescription ) + throw( com::sun::star::uno::RuntimeException ); + + //------------------------------------------------ + // XServiceInfo + //------------------------------------------------ + + virtual ::rtl::OUString SAL_CALL getImplementationName( ) + throw(::com::sun::star::uno::RuntimeException); + + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) + throw(::com::sun::star::uno::RuntimeException); + + //------------------------------------------------ + // XCancellable + //------------------------------------------------ + + virtual void SAL_CALL cancel( ) + throw(::com::sun::star::uno::RuntimeException); + + //------------------------------------------------ + // overwrite base class method, which is called + // by base class dispose function + //------------------------------------------------ + + virtual void SAL_CALL disposing(); + +private: + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xServiceMgr; + std::auto_ptr< CWinFolderPickerImpl > m_pFolderPickerImpl; + osl::Mutex m_aMutex; + +// prevent copy and assignment +private: + CFolderPicker( const CFolderPicker& ); + CFolderPicker& operator=( const CFolderPicker& ); +}; + +#endif diff --git a/fpicker/source/win32/folderpicker/FopEvtDisp.hxx b/fpicker/source/win32/folderpicker/FopEvtDisp.hxx new file mode 100644 index 000000000000..dfaa5a9abf9b --- /dev/null +++ b/fpicker/source/win32/folderpicker/FopEvtDisp.hxx @@ -0,0 +1,45 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _FOPEVENTDISPATCHER_HXX_ +#define _FOPEVENTDISPATCHER_HXX_ + +#include <com/sun/star/lang/EventObject.hpp> + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ +class CFOPEventDispatcher +{ +public: + + // dispatches a FilePickerEvent to wherever + virtual void SAL_CALL helpRequested( ::com::sun::star::lang::EventObject aEvent ) const = 0; +}; + +#endif diff --git a/fpicker/source/win32/folderpicker/Fopentry.cxx b/fpicker/source/win32/folderpicker/Fopentry.cxx new file mode 100644 index 000000000000..3c861cc67ce3 --- /dev/null +++ b/fpicker/source/win32/folderpicker/Fopentry.cxx @@ -0,0 +1,119 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//----------------------------------------------------------------------- +// includes of other projects +//----------------------------------------------------------------------- +#include <cppuhelper/factory.hxx> +#include <com/sun/star/container/XSet.hpp> +#include <osl/diagnose.h> + +#ifndef _FILEPICKER_HXX_ +#include "folderpicker.hxx" +#endif + +#ifndef _FPSERVICEINFO_HXX_ +#include "FOPServiceInfo.hxx" +#endif +#include "WinFOPImpl.hxx" + +//----------------------------------------------------------------------- +// namespace directives +//----------------------------------------------------------------------- + +using namespace ::rtl ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::container ; +using namespace ::com::sun::star::lang ; +using namespace ::com::sun::star::registry ; +using namespace ::cppu ; +using com::sun::star::ui::dialogs::XFolderPicker; + + +namespace +{ + + //----------------------------------------------------------------------- + // + //----------------------------------------------------------------------- + + Reference< XInterface > SAL_CALL createInstance( const Reference< XMultiServiceFactory >& rServiceManager ) + { + return Reference< XInterface >( static_cast< XFolderPicker* >( new CFolderPicker( rServiceManager ) ) ); + } +} + +//----------------------------------------------------------------------- +// the 3 important functions which will be exported +//----------------------------------------------------------------------- + +extern "C" +{ + +//---------------------------------------------------------------------- +// component_getImplementationEnvironment +//---------------------------------------------------------------------- + +void SAL_CALL component_getImplementationEnvironment( + const sal_Char ** ppEnvTypeName, uno_Environment ** ) +{ + *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; +} + +//---------------------------------------------------------------------- +// component_getFactory +// returns a factory to create XFilePicker-Services +//---------------------------------------------------------------------- + +void* SAL_CALL component_getFactory( const sal_Char* pImplName, uno_Interface* pSrvManager, uno_Interface* ) +{ + void* pRet = 0; + + if ( pSrvManager && ( 0 == rtl_str_compare( pImplName, FOLDER_PICKER_IMPL_NAME ) ) ) + { + Sequence< OUString > aSNS( 1 ); + aSNS.getArray( )[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( FOLDER_PICKER_SERVICE_NAME ) ); + + Reference< XSingleServiceFactory > xFactory ( createSingleFactory( + reinterpret_cast< XMultiServiceFactory* > ( pSrvManager ), + OUString::createFromAscii( pImplName ), + createInstance, + aSNS ) ); + if ( xFactory.is() ) + { + xFactory->acquire(); + pRet = xFactory.get(); + } + } + + return pRet; +} + +} // extern "C" diff --git a/fpicker/source/win32/folderpicker/MtaFop.cxx b/fpicker/source/win32/folderpicker/MtaFop.cxx new file mode 100644 index 000000000000..254887a2a0f1 --- /dev/null +++ b/fpicker/source/win32/folderpicker/MtaFop.cxx @@ -0,0 +1,839 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" +#include <osl/diagnose.h> +#include <osl/conditn.hxx> + +#include "MtaFop.hxx" +#include <wchar.h> +#include <process.h> +#include "..\misc\resourceprovider.hxx" + +#include <systools/win32/comtools.hxx> + +using rtl::OUString; +using osl::Condition; + +const sal_uInt32 MSG_BROWSEFORFOLDER = WM_USER + 1; +const sal_uInt32 MSG_SHUTDOWN = WM_USER + 2; + +const sal_uInt32 MAX_WAITTIME = 2000; // msec + +const sal_Bool MANUAL_RESET = sal_True; +const sal_Bool AUTO_RESET = sal_False; +const sal_Bool INIT_NONSIGNALED = sal_False; + +typedef sal::systools::COMReference<IMalloc> IMallocPtr; +typedef sal::systools::COMReference<IShellFolder> IShellFolderPtr; + +namespace +{ + const char* FOLDERPICKER_SRV_DLL_NAME = "fop.dll"; + const char g_szWndClsName[] = "FopStaReqWnd###"; + const char* CURRENT_INSTANCE = "CurrInst"; + + typedef struct _RequestContext + { + HANDLE hEvent; + sal_Bool bRet; + } RequestContext; + + inline sal_Bool InitializeRequestContext( RequestContext* aRequestContext ) + { + OSL_ASSERT( aRequestContext ); + + aRequestContext->hEvent = CreateEventA( + 0, AUTO_RESET, INIT_NONSIGNALED, NULL ); + + aRequestContext->bRet = sal_False; + + return ( 0 != aRequestContext->hEvent ); + } + + inline void DeinitializeRequestContext( RequestContext* aRequestContext ) + { + OSL_ASSERT( aRequestContext && aRequestContext->hEvent ); + CloseHandle( aRequestContext->hEvent ); + } + + //------------------------------- + // Determine if current thread is + // an MTA or STA thread + //------------------------------- + bool IsMTA() + { + HRESULT hr = CoInitialize(NULL); + + if (RPC_E_CHANGED_MODE == hr) + return true; + + if(SUCCEEDED(hr)) + CoUninitialize(); + + return false; + } +} + +//---------------------------------------------------------------- +// static member initialization +//---------------------------------------------------------------- + +ATOM CMtaFolderPicker::s_ClassAtom = 0; +osl::Mutex CMtaFolderPicker::s_Mutex; +sal_Int32 CMtaFolderPicker::s_StaRequestWndRegisterCount = 0; + +//-------------------------------------------------------------------- +// ctor +//-------------------------------------------------------------------- + +CMtaFolderPicker::CMtaFolderPicker( sal_uInt32 Flags ) : + m_hStaThread( NULL ), + m_uStaThreadId( 0 ), + m_hEvtThrdReady( NULL ), + m_hwndStaRequestWnd( NULL ) +{ + m_hInstance = GetModuleHandleA( FOLDERPICKER_SRV_DLL_NAME ); + OSL_ENSURE( m_hInstance, "The name of the FolderPicker service dll must have changed" ); + + ZeroMemory( &m_bi, sizeof( m_bi ) ); + + // !!!!!!!!!!!!!!!!! IMPORTANT !!!!!!!!!!!!!!!!!!! + // + // Remember: This HACK prevents you from stepping + // through your code in the debugger because if you + // set a break point in the ctor here the debugger + // may become the owner of the FolderBrowse dialog + // and so it seems that the Visual Studio and the + // office are hanging + m_bi.hwndOwner = GetForegroundWindow( ); + + /* + Flag Available + -------------------------------- + BIF_EDITBOX Version 4.71 + BIF_NEWDIALOGSTYLE Version 5.0 + BIF_SHAREABLE Version 5.0 + BIF_VALIDATE Version 4.71 + + Version 4.71 - Internet Explorer 4.0 + Version 5.0 - Internet Explorer 5.0 + Windows 2000 + */ + m_bi.ulFlags = Flags; + + m_bi.lpfn = CMtaFolderPicker::FolderPickerCallback; + m_bi.lParam = reinterpret_cast< LPARAM >( this ); + + //--------------------------------------- + // read the default strings for title and + // description from a resource file + + CResourceProvider ResProvider; + + m_dialogTitle = ResProvider.getResString( 500 ); + m_Description = ResProvider.getResString( 501 ); + + // signals that the thread was successfully set up + m_hEvtThrdReady = CreateEventA( + 0, + MANUAL_RESET, + INIT_NONSIGNALED, + NULL ); + + if ( m_hEvtThrdReady ) + { + // setup the sta thread + m_hStaThread = (HANDLE)_beginthreadex( + NULL, + 0, + CMtaFolderPicker::StaThreadProc, + this, + 0, + &m_uStaThreadId ); + + OSL_ASSERT( m_hStaThread ); + } + + OSL_ASSERT( m_hEvtThrdReady ); +} + +//-------------------------------------------------------------------- +// dtor +//-------------------------------------------------------------------- + +CMtaFolderPicker::~CMtaFolderPicker( ) +{ + // only if the is a valid event handle + // there may also be a thread a hidden + // target request window and so on + // see ctor + if ( m_hEvtThrdReady ) + { + // block calling threads because we + // are about to shutdown + ResetEvent( m_hEvtThrdReady ); + + // force the destruction of the sta thread request window + // and the end of the thread + // remeber: DestroyWindow may only be called from within + // the thread that created the window + if ( IsWindow( m_hwndStaRequestWnd ) ) + { + SendMessageA( m_hwndStaRequestWnd, MSG_SHUTDOWN, 0, 0 ); + + // we place unregister class here because + // if we have a valid window we must have + // sucessfully registered a window class + // if the creation of the window itself + // failed after registering the window + // class we have unregistered it immediately + // in createStaRequestWindow below + UnregisterStaRequestWindowClass( ); + } + + if ( m_hStaThread ) + { + // wait for thread shutdown + sal_uInt32 dwResult = WaitForSingleObject( m_hStaThread, MAX_WAITTIME ); + OSL_ENSURE( dwResult == WAIT_OBJECT_0, "sta thread could not terminate" ); + + // terminate the thread if it + // doesn't shutdown itself + if ( WAIT_OBJECT_0 != dwResult ) + TerminateThread( + m_hStaThread, sal::static_int_cast< DWORD >(-1) ); + + CloseHandle( m_hStaThread ); + } + + CloseHandle( m_hEvtThrdReady ); + } +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +sal_Bool CMtaFolderPicker::browseForFolder( ) +{ + sal_Bool bRet = sal_False; + + if (IsMTA()) + { + + OSL_ASSERT( m_hEvtThrdReady ); + + if ( WaitForSingleObject( m_hEvtThrdReady, MAX_WAITTIME ) != WAIT_OBJECT_0 ) + { + OSL_ENSURE( sal_False, "sta thread not ready" ); + return sal_False; + } + + RequestContext aReqCtx; + + if ( !InitializeRequestContext( &aReqCtx ) ) + { + OSL_ASSERT( sal_False ); + return sal_False; + } + + // marshall request into the sta thread + PostMessageA( + m_hwndStaRequestWnd, + MSG_BROWSEFORFOLDER, + 0, + reinterpret_cast< LPARAM >( &aReqCtx ) ); + + // waiting for the event to be signaled or + // window messages so that we don't block + // our parent window + + sal_Bool bContinue = sal_True; + + while ( bContinue ) + { + DWORD dwResult = MsgWaitForMultipleObjects( + 1, &aReqCtx.hEvent, FALSE, INFINITE, QS_ALLEVENTS ); + + switch ( dwResult ) + { + // the request context event is signaled + case WAIT_OBJECT_0: + bContinue = sal_False; + break; + + // a window message has arrived + case WAIT_OBJECT_0 + 1: + { + // dispatching all messages but we expect to + // receive only paint or timer messages that's + // why we don't need to call TranslateMessage or + // TranslateAccelerator, because keybord or + // mouse messages are for the FolderPicker which + // is in the foreground and should not arrive here + MSG msg; + while ( PeekMessageA( &msg, NULL, 0, 0, PM_REMOVE ) ) + DispatchMessageA(&msg); + } + break; + + // should not happen + default: + OSL_ASSERT( sal_False ); + } + } + + /*sal_Bool*/ bRet = aReqCtx.bRet; + DeinitializeRequestContext( &aReqCtx ); + } + else + { + bRet = onBrowseForFolder(); + } + + return bRet; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +void SAL_CALL CMtaFolderPicker::setDisplayDirectory( const OUString& aDirectory ) +{ + m_displayDir = aDirectory; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +OUString SAL_CALL CMtaFolderPicker::getDisplayDirectory( ) +{ + return m_displayDir; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +OUString SAL_CALL CMtaFolderPicker::getDirectory( ) +{ + return m_SelectedDir; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +void SAL_CALL CMtaFolderPicker::setDescription( const rtl::OUString& aDescription ) +{ + m_Description = aDescription; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +void SAL_CALL CMtaFolderPicker::setTitle( const OUString& aTitle ) +{ + m_dialogTitle = aTitle; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +OUString SAL_CALL CMtaFolderPicker::getTitle( ) +{ + return m_dialogTitle; +} + +//----------------------------------------------------- +// XCancellable +//----------------------------------------------------- + +void SAL_CALL CMtaFolderPicker::cancel( ) +{ + if ( IsWindow( m_hwnd ) ) + { + // simulate a mouse click to the + // cancel button + PostMessageA( + m_hwnd, + WM_COMMAND, + MAKEWPARAM( IDCANCEL, BN_CLICKED ), + (LPARAM)GetDlgItem( m_hwnd, IDCANCEL ) ); + } +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +sal_Bool SAL_CALL CMtaFolderPicker::onBrowseForFolder( ) +{ + sal_Bool bRet; + LPITEMIDLIST lpiid; + + // pre SHBrowseFroFolder + + m_bi.pidlRoot = 0; + m_bi.pszDisplayName = reinterpret_cast<LPWSTR>(m_pathBuff.get()); + + if ( m_Description.getLength( ) ) + m_bi.lpszTitle = reinterpret_cast<LPCWSTR>(m_Description.getStr( )); + + lpiid = SHBrowseForFolderW( &m_bi ); + bRet = ( NULL != lpiid ); + + // post SHBrowseForFolder + + m_SelectedDir = getPathFromItemIdList( lpiid ); + releaseItemIdList( lpiid ); + + return bRet; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +void SAL_CALL CMtaFolderPicker::releaseItemIdList( LPITEMIDLIST lpItemIdList ) +{ + IMallocPtr pIMalloc; + SHGetMalloc(&pIMalloc); + if (pIMalloc.is()) + { + pIMalloc->Free(lpItemIdList); + lpItemIdList = NULL; + } +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +LPITEMIDLIST SAL_CALL CMtaFolderPicker::getItemIdListFromPath( const rtl::OUString& aDirectory ) +{ + // parameter checking + if ( !aDirectory.getLength( ) ) + return NULL; + + LPITEMIDLIST lpItemIdList(NULL); + + IShellFolderPtr pIShellFolder; + SHGetDesktopFolder(&pIShellFolder); + + if (pIShellFolder.is()) + { + pIShellFolder->ParseDisplayName( + NULL, + NULL, + reinterpret_cast<LPWSTR>(const_cast< sal_Unicode* >( aDirectory.getStr( ) )), + NULL, + &lpItemIdList, + NULL ); + } + + return lpItemIdList; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +OUString SAL_CALL CMtaFolderPicker::getPathFromItemIdList( LPCITEMIDLIST lpItemIdList ) +{ + OUString path; + + if ( lpItemIdList ) + { + bool bRet = SHGetPathFromIDListW( lpItemIdList, reinterpret_cast<LPWSTR>(m_pathBuff.get()) ); + if ( bRet ) + path = m_pathBuff.get( ); + } + + return path; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +void SAL_CALL CMtaFolderPicker::enableOk( sal_Bool bEnable ) +{ + OSL_ASSERT( IsWindow( m_hwnd ) ); + + SendMessageW( + m_hwnd, + BFFM_ENABLEOK, + static_cast< WPARAM >( 0 ), + static_cast< LPARAM >( bEnable ) ); +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +void SAL_CALL CMtaFolderPicker::setSelection( const rtl::OUString& aDirectory ) +{ + OSL_ASSERT( IsWindow( m_hwnd ) ); + +#ifdef _MSC_VER +#pragma message( "#######################################" ) +#pragma message( "SendMessageW wrapper has to be extended" ) +#pragma message( "#######################################" ) +#endif + + SendMessageW( + m_hwnd, + BFFM_SETSELECTIONW, + static_cast< WPARAM >( sal_True ), + reinterpret_cast< LPARAM >( aDirectory.getStr( ) ) ); +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +void SAL_CALL CMtaFolderPicker::setStatusText( const rtl::OUString& aStatusText ) +{ + OSL_ASSERT( IsWindow( m_hwnd ) ); + + SendMessageW( + m_hwnd, + BFFM_SETSTATUSTEXTW, + static_cast< WPARAM >( 0 ), + reinterpret_cast< LPARAM >( aStatusText.getStr( ) ) ); +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +void SAL_CALL CMtaFolderPicker::onInitialized( ) +{ + LPITEMIDLIST lpiidDisplayDir = getItemIdListFromPath( m_displayDir ); + + if ( lpiidDisplayDir ) + { + SendMessageA( + m_hwnd, + BFFM_SETSELECTION, + (WPARAM)FALSE, + (LPARAM) lpiidDisplayDir ); + + releaseItemIdList( lpiidDisplayDir ); + } +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +sal_uInt32 CMtaFolderPicker::onValidateFailed() +{ + // to be overwritten by subclasses + return 1; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +int CALLBACK CMtaFolderPicker::FolderPickerCallback( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData ) +{ + CMtaFolderPicker* pImpl = reinterpret_cast< CMtaFolderPicker* >( lpData ); + OSL_ASSERT( pImpl ); + + int nRC = 0; + + switch( uMsg ) + { + case BFFM_INITIALIZED: + pImpl->m_hwnd = hwnd; + pImpl->onInitialized( ); + SetWindowTextW( hwnd, reinterpret_cast<LPCWSTR>(pImpl->m_dialogTitle.getStr()) ); + break; + + case BFFM_SELCHANGED: + pImpl->m_hwnd = hwnd; + pImpl->onSelChanged( + pImpl->getPathFromItemIdList( + reinterpret_cast< LPITEMIDLIST >( lParam ) ) ); + break; + + case BFFM_VALIDATEFAILEDW: + nRC = pImpl->onValidateFailed(); + break; + + default: + OSL_ASSERT( sal_False ); + } + + return nRC; +} + +//-------------------------------------------------------------------- +// the window proc +//-------------------------------------------------------------------- + +LRESULT CALLBACK CMtaFolderPicker::StaWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + LRESULT lResult = 0; + CMtaFolderPicker* pImpl = NULL; + + /* + we connect to the belonging class instance of this + window using SetProp, GetProp etc. + this may fail if somehow the class instance destroyed + before the window + */ + + switch( uMsg ) + { + case WM_CREATE: + { + LPCREATESTRUCT lpcs = + reinterpret_cast< LPCREATESTRUCT >( lParam ); + + OSL_ASSERT( lpcs->lpCreateParams ); + + // connect the instance handle to the window + SetPropA( hWnd, CURRENT_INSTANCE, lpcs->lpCreateParams ); + } + break; + + case WM_NCDESTROY: + // RemoveProp returns the saved value on success + pImpl = reinterpret_cast< CMtaFolderPicker* >( + RemovePropA( hWnd, CURRENT_INSTANCE ) ); + + OSL_ASSERT( pImpl && !IsBadReadPtr( pImpl, sizeof( CMtaFolderPicker ) ) ); + break; + + case MSG_BROWSEFORFOLDER: + { + RequestContext* aReqCtx = reinterpret_cast< RequestContext* >( lParam ); + OSL_ASSERT( aReqCtx ); + + pImpl = reinterpret_cast< CMtaFolderPicker* >( + GetPropA( hWnd, CURRENT_INSTANCE ) ); + + OSL_ASSERT( pImpl && !IsBadReadPtr( pImpl, sizeof( CMtaFolderPicker ) ) ); + + aReqCtx->bRet = pImpl->onBrowseForFolder( ); + SetEvent( aReqCtx->hEvent ); + } + break; + + case MSG_SHUTDOWN: + pImpl = reinterpret_cast< CMtaFolderPicker* >( + GetPropA( hWnd, CURRENT_INSTANCE ) ); + + OSL_ASSERT( pImpl && !IsBadReadPtr( pImpl, sizeof( CMtaFolderPicker ) ) ); + + DestroyWindow( pImpl->m_hwndStaRequestWnd ); + break; + + case WM_DESTROY: + PostQuitMessage( 0 ); + break; + + default: + lResult = DefWindowProcA( hWnd, uMsg, wParam, lParam ); + break; + } + + return lResult; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +sal_Bool SAL_CALL CMtaFolderPicker::createStaRequestWindow( ) +{ + bool bIsWnd = false; + + if ( RegisterStaRequestWindowClass( ) ) + { + m_hwndStaRequestWnd = CreateWindowA( + g_szWndClsName, NULL, + 0, 0, 0, 0, 0, + NULL, NULL, m_hInstance, + (LPVOID)this // provide the instance of the class + ); + + bIsWnd = IsWindow( m_hwndStaRequestWnd ); + + // we do immediately unregister the window class + // if the creation of the window fails because we + // don't want to spoil the register class counter + if ( !bIsWnd ) + UnregisterStaRequestWindowClass( ); + + OSL_ENSURE( bIsWnd, "sta request window creation failed" ); + } + + return bIsWnd; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +unsigned int CMtaFolderPicker::run( ) +{ + OSL_ASSERT( m_hEvtThrdReady ); + + // setup an sta environment + HRESULT hr = CoInitialize( NULL ); + + // if we can't setup an sta environment + // we stop here and return + if ( FAILED( hr ) ) + { + OSL_ENSURE( sal_False, "CoInitialize failed" ); + return sal::static_int_cast< unsigned int >(-1); + } + + unsigned int nRet; + + if ( createStaRequestWindow( ) ) + { + SetEvent( m_hEvtThrdReady ); + + // pumping messages + MSG msg; + while( GetMessageA( &msg, NULL, 0, 0 ) ) + DispatchMessageA( &msg ); + + nRet = 0; + } + else + { + OSL_ENSURE( sal_False, "failed to create sta thread" ); + nRet = sal::static_int_cast< unsigned int >(-1); + } + + // shutdown sta environment + CoUninitialize( ); + + return nRet; +} + +//-------------------------------------------------------------------- +// +//-------------------------------------------------------------------- + +unsigned int WINAPI CMtaFolderPicker::StaThreadProc( LPVOID pParam ) +{ + CMtaFolderPicker* pInst = + reinterpret_cast<CMtaFolderPicker*>( pParam ); + + OSL_ASSERT( pInst ); + + HRESULT hr = OleInitialize( NULL ); + + unsigned int result = pInst->run( ); + + if ( SUCCEEDED( hr ) ) + OleUninitialize(); + + return result; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +ATOM SAL_CALL CMtaFolderPicker::RegisterStaRequestWindowClass( ) +{ + osl::MutexGuard aGuard( s_Mutex ); + + if ( 0 == s_ClassAtom ) + { + WNDCLASSEXA wcex; + + ZeroMemory( &wcex, sizeof( WNDCLASSEXA ) ); + + wcex.cbSize = sizeof(WNDCLASSEXA); + wcex.style = 0; + wcex.lpfnWndProc = static_cast< WNDPROC >( CMtaFolderPicker::StaWndProc ); + wcex.cbClsExtra = 0; + wcex.cbWndExtra = 0; + wcex.hInstance = m_hInstance; + wcex.hIcon = NULL; + wcex.hCursor = NULL; + wcex.hbrBackground = NULL; + wcex.lpszMenuName = NULL; + wcex.lpszClassName = g_szWndClsName; + wcex.hIconSm = NULL; + + s_ClassAtom = RegisterClassExA( &wcex ); + OSL_ASSERT( s_ClassAtom ); + } + + // increment the register class counter + // so that we keep track of the number + // of class registrations + if ( 0 != s_ClassAtom ) + s_StaRequestWndRegisterCount++; + + return s_ClassAtom; +} + +//--------------------------------------------------- +// +//--------------------------------------------------- + +void SAL_CALL CMtaFolderPicker::UnregisterStaRequestWindowClass( ) +{ + osl::MutexGuard aGuard( s_Mutex ); + + OSL_ASSERT( 0 != s_ClassAtom ); + + // update the register class counter + // and unregister the window class if + // counter drops to zero + if ( 0 != s_ClassAtom ) + { + s_StaRequestWndRegisterCount--; + OSL_ASSERT( s_StaRequestWndRegisterCount >= 0 ); + } + + if ( 0 == s_StaRequestWndRegisterCount ) + { + UnregisterClass( + (LPCTSTR)MAKELONG( s_ClassAtom, 0 ), m_hInstance ); + + s_ClassAtom = 0; + } +} diff --git a/fpicker/source/win32/folderpicker/MtaFop.hxx b/fpicker/source/win32/folderpicker/MtaFop.hxx new file mode 100644 index 000000000000..4735300c0ee0 --- /dev/null +++ b/fpicker/source/win32/folderpicker/MtaFop.hxx @@ -0,0 +1,191 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _MTAFOP_HXX_ +#define _MTAFOP_HXX_ + +#include <sal/types.h> +#include <rtl/ustring.hxx> +#include <osl/mutex.hxx> + +#include <utility> +#ifdef __MINGW32__ +#include <windows.h> +#endif +#if defined _MSC_VER +#pragma warning(push, 1) +#pragma warning(disable: 4917) +#endif +#include <objidl.h> +#include <shlobj.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include "..\misc\WinImplHelper.hxx" + +//---------------------------------------------------------------- +// a simple helper class used to provide a buffer for different +// Win32 file and directory functions +//---------------------------------------------------------------- + +class CAutoPathBuff +{ +public: + CAutoPathBuff( size_t size = 0 ) + { + if (0 == size) + size = 32000; // max path length under Win2000 + + pBuff = new sal_Unicode[size]; + + OSL_POSTCOND(pBuff,"Could not allocate path buffer"); + } + + ~CAutoPathBuff( ) + { + delete [] pBuff; + } + + operator sal_Unicode*( ) + { + OSL_PRECOND( pBuff, \ + "No path buffer allocated" ); + return pBuff; + } + + sal_Unicode* get( ) + { + OSL_PRECOND( pBuff, \ + "No path buffer allocated" ); + return pBuff; + } + +private: + sal_Unicode* pBuff; +}; + +//-------------------------------------------------------- +// the Mta-Ole clipboard class is for internal use only! +// only one instance of this class should be created, the +// user has to ensure this! +// the class is not thread-safe because it will be used +// only from within the clipboard service and the methods +// of the clipboard service are already synchronized +//-------------------------------------------------------- + +class CMtaFolderPicker +{ +public: + CMtaFolderPicker( sal_uInt32 Flags ); + virtual ~CMtaFolderPicker( ); + + // shell functions + sal_Bool SAL_CALL browseForFolder( ); + + virtual void SAL_CALL setDisplayDirectory( const rtl::OUString& aDirectory ); + virtual rtl::OUString SAL_CALL getDisplayDirectory( ); + virtual rtl::OUString SAL_CALL getDirectory( ); + + virtual void SAL_CALL setDescription( const rtl::OUString& aDescription ); + + virtual void SAL_CALL setTitle( const rtl::OUString& aTitle ); + rtl::OUString SAL_CALL getTitle( ); + + //----------------------------------------------------- + // XCancellable + //----------------------------------------------------- + + virtual void SAL_CALL cancel( ); + +protected: + void SAL_CALL enableOk( sal_Bool bEnable ); + void SAL_CALL setSelection( const rtl::OUString& aDirectory ); + void SAL_CALL setStatusText( const rtl::OUString& aStatusText ); + + virtual void SAL_CALL onInitialized( ); + virtual void SAL_CALL onSelChanged( const rtl::OUString& aNewPath ) = 0; + +private: + sal_uInt32 onValidateFailed(); + + // helper functions + LPITEMIDLIST SAL_CALL getItemIdListFromPath( const rtl::OUString& aDirectory ); + rtl::OUString SAL_CALL getPathFromItemIdList( LPCITEMIDLIST lpItemIdList ); + void SAL_CALL releaseItemIdList( LPITEMIDLIST lpItemIdList ); + + unsigned int run( ); + + // create a hidden windows which serves as an request + // target; so we guarantee synchronization + sal_Bool SAL_CALL createStaRequestWindow( ); + + //--------------------------------------------------------------- + // message handler functions; remeber these functions are called + // from a different thread context! + //--------------------------------------------------------------- + + sal_Bool SAL_CALL onBrowseForFolder( ); + + static LRESULT CALLBACK StaWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); + static unsigned int WINAPI StaThreadProc( LPVOID pParam ); + + static int CALLBACK FolderPickerCallback( HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData ); + +protected: + HWND m_hwnd; + +private: + ATOM SAL_CALL RegisterStaRequestWindowClass( ); + void SAL_CALL UnregisterStaRequestWindowClass( ); + +private: + HANDLE m_hStaThread; + unsigned m_uStaThreadId; + HANDLE m_hEvtThrdReady; + HWND m_hwndStaRequestWnd; + rtl::OUString m_dialogTitle; + rtl::OUString m_Description; + rtl::OUString m_displayDir; + rtl::OUString m_SelectedDir; + BROWSEINFOW m_bi; + CAutoPathBuff m_pathBuff; + HINSTANCE m_hInstance; + + // the request window class has to be registered only + // once per process, so multiple instance of this class + // share the registered window class + static ATOM s_ClassAtom; + static osl::Mutex s_Mutex; + static sal_Int32 s_StaRequestWndRegisterCount; + +// prevent copy and assignment +private: + CMtaFolderPicker( const CMtaFolderPicker& ); + CMtaFolderPicker& operator=( const CMtaFolderPicker& ); +}; + +#endif diff --git a/fpicker/source/win32/folderpicker/WinFOPImpl.cxx b/fpicker/source/win32/folderpicker/WinFOPImpl.cxx new file mode 100644 index 000000000000..1aac4f5f8c53 --- /dev/null +++ b/fpicker/source/win32/folderpicker/WinFOPImpl.cxx @@ -0,0 +1,168 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#ifndef _WINDIRBROWSEIMPL_HXX_ +#include "WinFOPImpl.hxx" +#endif +#include <osl/diagnose.h> +#include <com/sun/star/lang/EventObject.hpp> + +#ifndef _COM_SUN_STAR_UI_FILEDIALOGRESULTS_HPP_ +#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> +#endif +#include "FopEvtDisp.hxx" +#include <osl/file.hxx> +#include "FolderPicker.hxx" + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using com::sun::star::uno::RuntimeException; +using com::sun::star::lang::IllegalArgumentException; +using com::sun::star::lang::EventObject; +using rtl::OUString; + +using namespace com::sun::star::ui::dialogs; +using osl::FileBase; + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +const OUString BACKSLASH = OUString::createFromAscii( "\\" ); + +//------------------------------------------------------------------------ +// ctor +//------------------------------------------------------------------------ + +CWinFolderPickerImpl::CWinFolderPickerImpl( CFolderPicker* aFolderPicker ) : + CMtaFolderPicker( BIF_RETURNONLYFSDIRS | BIF_RETURNFSANCESTORS | BIF_EDITBOX | BIF_VALIDATE ), + m_pFolderPicker( aFolderPicker ), + m_nLastDlgResult( ::com::sun::star::ui::dialogs::ExecutableDialogResults::CANCEL ) +{ +} + +//------------------------------------------------------------------------ +// get directory in URL format, convert it to system format and set the +// member variable +// If the given URL for the directory is invalid the function throws an +// IllegalArgumentException +// If the specified path is well formed but invalid for the underlying +// OS the FolderPicker starts in the root of the file system hierarchie +//------------------------------------------------------------------------ + +void SAL_CALL CWinFolderPickerImpl::setDisplayDirectory( const OUString& aDirectory ) + throw( IllegalArgumentException, RuntimeException ) +{ + OUString sysDir; + + if( aDirectory.getLength( ) ) + { + // assuming that this function succeeds after successful execution + // of getAbsolutePath + ::osl::FileBase::RC rc = + ::osl::FileBase::getSystemPathFromFileURL( aDirectory, sysDir ); + + if ( ::osl::FileBase::E_None != rc ) + throw IllegalArgumentException( + OUString::createFromAscii( "directory is not a valid file url" ), + static_cast< XFolderPicker* >( m_pFolderPicker ), + 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 + // hierarchie which is the desktop folder + if ( sysDir.lastIndexOf( BACKSLASH ) != (sysDir.getLength( ) - 1) ) + sysDir += BACKSLASH; + } + + // call base class method + CMtaFolderPicker::setDisplayDirectory( sysDir ); +} + +//------------------------------------------------------------------------ +// we return the directory in URL format +//------------------------------------------------------------------------ + +OUString CWinFolderPickerImpl::getDisplayDirectory( ) + throw( RuntimeException ) +{ + // call base class method to get the directory in system format + OUString displayDirectory = CMtaFolderPicker::getDisplayDirectory( ); + + OUString displayDirectoryURL; + if ( displayDirectory.getLength( ) ) + ::osl::FileBase::getFileURLFromSystemPath( displayDirectory, displayDirectoryURL ); + + return displayDirectoryURL; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +OUString SAL_CALL CWinFolderPickerImpl::getDirectory( ) throw( RuntimeException ) +{ + OUString sysDir = CMtaFolderPicker::getDirectory( ); + OUString dirURL; + + if ( sysDir.getLength( ) ) + ::osl::FileBase::getFileURLFromSystemPath( sysDir, dirURL ); + + return dirURL; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Int16 SAL_CALL CWinFolderPickerImpl::execute( ) throw( RuntimeException ) +{ + return m_nLastDlgResult = CMtaFolderPicker::browseForFolder( ) ? + ::com::sun::star::ui::dialogs::ExecutableDialogResults::OK : + ::com::sun::star::ui::dialogs::ExecutableDialogResults::CANCEL; +} + +//--------------------------------------------------------------------- +// +//--------------------------------------------------------------------- + +void CWinFolderPickerImpl::onSelChanged( const OUString& aNewPath ) +{ + setStatusText( aNewPath ); +} diff --git a/fpicker/source/win32/folderpicker/WinFOPImpl.hxx b/fpicker/source/win32/folderpicker/WinFOPImpl.hxx new file mode 100644 index 000000000000..eb7889f86167 --- /dev/null +++ b/fpicker/source/win32/folderpicker/WinFOPImpl.hxx @@ -0,0 +1,83 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _WINFOPIMPL_HXX_ +#define _WINFOPIMPL_HXX_ + + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include "MtaFop.hxx" + +//------------------------------------------------------------------------ +// forward +//------------------------------------------------------------------------ + +class CFolderPicker; + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +class CWinFolderPickerImpl : public CMtaFolderPicker +{ +public: + CWinFolderPickerImpl( CFolderPicker* aFolderPicker ); + + //----------------------------------------------------------------------------------------- + // XExecutableDialog + //----------------------------------------------------------------------------------------- + + virtual sal_Int16 SAL_CALL execute( ) + throw( com::sun::star::uno::RuntimeException ); + + //----------------------------------------------------- + // XFolderPicker + //----------------------------------------------------- + + virtual void SAL_CALL setDisplayDirectory( const rtl::OUString& aDirectory ) + throw( com::sun::star::lang::IllegalArgumentException, com::sun::star::uno::RuntimeException ); + + virtual rtl::OUString SAL_CALL getDisplayDirectory( ) + throw( com::sun::star::uno::RuntimeException ); + + virtual rtl::OUString SAL_CALL getDirectory( ) + throw( com::sun::star::uno::RuntimeException ); + +protected: + virtual void SAL_CALL onSelChanged( const rtl::OUString& aNewPath ); + +private: + CFolderPicker* m_pFolderPicker; + sal_Int16 m_nLastDlgResult; +}; + +#endif diff --git a/fpicker/source/win32/folderpicker/fop.xml b/fpicker/source/win32/folderpicker/fop.xml new file mode 100644 index 000000000000..7c6835a88cb9 --- /dev/null +++ b/fpicker/source/win32/folderpicker/fop.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd"> +<module-description xmlns:xlink="http://www.w3.org/1999/xlink"> + <module-name>fop</module-name> + <component-description> + <author> Tino Rachui </author> + <name>com.sun.star.comp.ui.dialogs.FolderPicker</name> + <description> + The win32 implementation of the FolderPicker service. +</description> + <loader-name>com.sun.star.loader.SharedLibrary</loader-name> + <language> c++ </language> + <status value="beta"/> + <supported-service> com.sun.star.ui.dialogs.FolderPicker </supported-service> + <service-dependency>...</service-dependency> + <type> com.sun.star.ui.dialogs.XExecutableDialog </type> + <type> com.sun.star.ui.dialogs.XFolderPicker </type> + <type> com.sun.star.ui.dialogs.ExecutableDialogException </type> + <type> com.sun.star.ui.dialogs.ExecutableDialogResults </type> + <type> com.sun.star.ui.dialogs.ExtendedFilePickerElementIds </type> + <type> com.sun.star.ui.dialogs.CommonFilePickerElementIds </type> + <type> com.sun.star.util.XCancellable </type> + <type> com.sun.star.lang.XMultiServiceFactory </type> + <type> com.sun.star.lang.XSingleServiceFactory </type> + <type> com.sun.star.lang.XServiceInfo </type> + <type> com.sun.star.lang.XTypeProvider </type> + <type> com.sun.star.lang.IllegalArgumentException </type> + <type> com.sun.star.uno.TypeClass </type> + <type> com.sun.star.uno.XWeak </type> + <type> com.sun.star.uno.XAggregation </type> + <type> com.sun.star.registry.XRegistryKey </type> + <type> com.sun.star.container.XSet </type> + </component-description> + <project-build-dependency> cppuhelper </project-build-dependency> + <project-build-dependency> cppu </project-build-dependency> + <project-build-dependency> sal </project-build-dependency> + <runtime-module-dependency> cppuhelper </runtime-module-dependency> + <runtime-module-dependency> cppu2 </runtime-module-dependency> + <runtime-module-dependency> sal2 </runtime-module-dependency> +</module-description> diff --git a/fpicker/source/win32/folderpicker/makefile.mk b/fpicker/source/win32/folderpicker/makefile.mk new file mode 100644 index 000000000000..7f0556d7cecb --- /dev/null +++ b/fpicker/source/win32/folderpicker/makefile.mk @@ -0,0 +1,51 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=fpicker +TARGET=fop +#LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE +COMP1TYPELIST=$(TARGET) + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk + +# --- Files -------------------------------------------------------- + +# enable rtti +CFLAGS+=-GR + +SLOFILES=$(SLO)$/fopentry.obj\ + $(SLO)$/folderpicker.obj\ + $(SLO)$/WinFopImpl.obj\ + $(SLO)$/MtaFop.obj + +# --- Targets ------------------------------------------------------ + +.INCLUDE : target.mk diff --git a/fpicker/source/win32/folderpicker/workbench/Test_fops.cxx b/fpicker/source/win32/folderpicker/workbench/Test_fops.cxx new file mode 100644 index 000000000000..472562194566 --- /dev/null +++ b/fpicker/source/win32/folderpicker/workbench/Test_fops.cxx @@ -0,0 +1,203 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + + +//----------------------------------------------------------- +// interface includes +//----------------------------------------------------------- +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/registry/XSimpleRegistry.hpp> +#include <osl/file.hxx> + +//-------------------------------------------------------------- +// other includes +//-------------------------------------------------------------- +#include <cppuhelper/servicefactory.hxx> + +#ifndef _RTL_USTRING_ +#include <rtl/ustring.hxx> +#endif +#include <sal/types.h> +#include <osl/diagnose.h> + +#ifndef _COM_SUN_STAR_UI_XFOLDERPICKER_HPP_ +#include <com/sun/star/ui/dialogs/XFolderPicker.hpp> +#endif + +#ifndef _COM_SUN_STAR_UI_FILEDIALOGRESULTS_HPP_ +#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp> +#endif +#include <cppuhelper/implbase1.hxx> + +#include <stdio.h> + +#ifndef _FPSERVICEINFO_HXX_ +#include "..\FOPServiceInfo.hxx" +#endif + +#include <osl/file.hxx> + +#define _WIN32_DCOM + +#include <windows.h> + +//-------------------------------------------------------------- +// namesapces +//-------------------------------------------------------------- + +using namespace ::rtl ; +using namespace ::cppu ; +using namespace ::com::sun::star::uno ; +using namespace ::com::sun::star::lang ; +using namespace ::com::sun::star::ui::dialogs; +using namespace std ; + +//-------------------------------------------------------------- +// defines +//-------------------------------------------------------------- + +#define RDB_SYSPATH "D:\\Projects\\gsl\\sysui\\wntmsci7\\bin\\applicat.rdb" + +//-------------------------------------------------------------- +// global variables +//-------------------------------------------------------------- + +Reference< XMultiServiceFactory > g_xFactory; + +/* +void CreateDeepDirectory( ) +{ + // create a deep directory + + OUString aPathURL( L"file:///d|/Deep" ); + OUString normalizedPath; + + OSL_ASSERT( ::osl::FileBase::E_None == \ + ::osl::FileBase::getNormalizedPathFromFileURL( aPathURL, normalizedPath ) ); + + while( ::osl::FileBase::E_None == osl::Directory::create( normalizedPath ) ) + { + aPathURL += L"/Deep"; + OSL_ASSERT( ::osl::FileBase::E_None == \ + ::osl::FileBase::getNormalizedPathFromFileURL( aPathURL, normalizedPath ) ); + } + +} +*/ + +//-------------------------------------------------------------- +// main +//-------------------------------------------------------------- + + +int SAL_CALL main(int /*nArgc*/, char* /*Argv[]*/, char* /*Env[]*/ ) +{ + CoInitializeEx( NULL, COINIT_MULTITHREADED ); + + printf("Starting test of FolderPicker Service\n"); + + //CreateDeepDirectory( ); + + //------------------------------------------------- + // get the global service-manager + //------------------------------------------------- + + // Get global factory for uno services. + OUString rdbName = OUString( RTL_CONSTASCII_USTRINGPARAM( RDB_SYSPATH ) ); + Reference< XMultiServiceFactory > g_xFactory( createRegistryServiceFactory( rdbName ) ); + + // Print a message if an error occured. + if ( g_xFactory.is() == sal_False ) + { + OSL_ENSURE(sal_False, "Can't create RegistryServiceFactory"); + return(-1); + } + + printf("Creating RegistryServiceFactory successful\n"); + + //------------------------------------------------- + // try to get an Interface to a XFilePicker Service + //------------------------------------------------- + + Reference< XFolderPicker > xFolderPicker; + + xFolderPicker = Reference< XFolderPicker >( + g_xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM ( FOLDER_PICKER_SERVICE_NAME ) ) ), UNO_QUERY ); + + if ( xFolderPicker.is() == sal_False ) + { + OSL_ENSURE( sal_False, "Error creating FolderPicker Service" ); + return(-1); + } + + try + { + xFolderPicker->setDisplayDirectory( L"file:///C|" ); + xFolderPicker->setTitle( L"FolderBrowse Dialog" ); + xFolderPicker->execute( ); + + OUString rootDir = xFolderPicker->getDisplayDirectory( ); + OUString selectedDir = xFolderPicker->getDirectory( ); + + xFolderPicker->setDisplayDirectory( selectedDir ); + xFolderPicker->execute( ); + + rootDir = xFolderPicker->getDisplayDirectory( ); + selectedDir = xFolderPicker->getDirectory( ); + } + catch( ::com::sun::star::uno::Exception& ) + { + MessageBox( NULL, "Exception caught!", "Error", MB_OK ); + } + + //-------------------------------------------------- + // shutdown + //-------------------------------------------------- + + // Cast factory to XComponent + Reference< XComponent > xComponent( g_xFactory, UNO_QUERY ); + + // Print a message if an error occured. + if ( xComponent.is() == sal_False ) + { + OSL_ENSURE(sal_False, "Error shuting down"); + } + + // Dispose and clear factory + xComponent->dispose(); + g_xFactory.clear(); + g_xFactory = Reference< XMultiServiceFactory >(); + + printf("Test successful\n"); + + CoUninitialize( ); + + return 0; +} diff --git a/fpicker/source/win32/folderpicker/workbench/makefile.mk b/fpicker/source/win32/folderpicker/workbench/makefile.mk new file mode 100644 index 000000000000..bfdf840989f8 --- /dev/null +++ b/fpicker/source/win32/folderpicker/workbench/makefile.mk @@ -0,0 +1,62 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/..$/.. + +PRJNAME= sysui +TARGET= testfops +LIBTARGET= NO +TARGETTYPE= CUI + + +# --- Settings ----------------------------------------------------- +#.INCLUDE : $(PRJ)$/util$/makefile.pmk + +.INCLUDE : settings.mk + +CFLAGS+=-GR -EHa + +# --- Files -------------------------------------------------------- + + +OBJFILES= $(OBJ)$/test_fops.obj + +APP1TARGET= test_fops + +APP1OBJS= $(OBJ)$/test_fops.obj + +APP1STDLIBS+= $(CPPULIB) \ + $(CPPUHELPERLIB) \ + $(SALLIB) \ + $(USER32LIB)\ + $(OLE32LIB) + +APP1DEF= $(MISC)$/$(APP1TARGET).def + +# --- Targets ------------------------------------------------------ +.INCLUDE : target.mk + diff --git a/fpicker/source/win32/misc/AutoBuffer.cxx b/fpicker/source/win32/misc/AutoBuffer.cxx new file mode 100644 index 000000000000..08d7e34d3851 --- /dev/null +++ b/fpicker/source/win32/misc/AutoBuffer.cxx @@ -0,0 +1,169 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include "AutoBuffer.hxx" +#include <osl/diagnose.h> + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//------------------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------------------ + +using rtl::OUString; + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CAutoUnicodeBuffer::CAutoUnicodeBuffer( size_t size, sal_Bool bLazyCreation ) : + m_buffSize( size ), + m_pBuff( NULL ) +{ + if ( !bLazyCreation ) + init( ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CAutoUnicodeBuffer::~CAutoUnicodeBuffer( ) +{ + delete [] m_pBuff; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CAutoUnicodeBuffer::resize( size_t new_size ) +{ + if ( new_size != m_buffSize ) + { + if ( new_size > m_buffSize ) + { + delete [] m_pBuff; + m_pBuff = NULL; + } + + m_buffSize = new_size; + } + + return sal_True; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CAutoUnicodeBuffer::empty( ) +{ + if ( m_pBuff ) + ZeroMemory( m_pBuff, m_buffSize * sizeof( sal_Unicode ) ); +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Bool SAL_CALL CAutoUnicodeBuffer::fill( const sal_Unicode* pContent, size_t nLen ) +{ + OSL_ASSERT( pContent && m_buffSize && (m_buffSize >= nLen) ); + + init( ); + + sal_Bool bRet = sal_False; + + if ( m_pBuff && pContent && nLen ) + { + CopyMemory( m_pBuff, pContent, nLen * sizeof( sal_Unicode ) ); + bRet = sal_True; + } + + return bRet; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +size_t SAL_CALL CAutoUnicodeBuffer::size( ) const +{ + return m_buffSize; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +CAutoUnicodeBuffer::operator sal_Unicode*( ) +{ + return m_pBuff; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +sal_Unicode* CAutoUnicodeBuffer::operator&( ) +{ + return m_pBuff; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +const sal_Unicode* CAutoUnicodeBuffer::operator&( ) const +{ + return m_pBuff; +} + +//------------------------------------------------------------------------ +// +//------------------------------------------------------------------------ + +void SAL_CALL CAutoUnicodeBuffer::init( ) +{ + if ( !m_pBuff && (m_buffSize > 0) ) + m_pBuff = new sal_Unicode[ m_buffSize ]; + + empty( ); +} diff --git a/fpicker/source/win32/misc/AutoBuffer.hxx b/fpicker/source/win32/misc/AutoBuffer.hxx new file mode 100644 index 000000000000..ccf6c0759e11 --- /dev/null +++ b/fpicker/source/win32/misc/AutoBuffer.hxx @@ -0,0 +1,82 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _AUTO_BUFFER_HXX_ +#define _AUTO_BUFFER_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> +#include <rtl/ustring.hxx> + +//------------------------------------------------------------- +// A simple unicode buffer management class, the class itself +// is responsible for the allocated unicode buffer, any +// modification of the buffer size outside the class may lead +// to undefined behaviour +//------------------------------------------------------------- + +class CAutoUnicodeBuffer +{ +public: + + // if bLazyCreation is true the buffer will be created + // when someone wants to fill the buffer + CAutoUnicodeBuffer( size_t size, sal_Bool bLazyCreation = sal_False ); + ~CAutoUnicodeBuffer( ); + + // resizes the buffer + sal_Bool SAL_CALL resize( size_t new_size ); + + // zeros the buffer + void SAL_CALL empty( ); + + // fills the buffer with a given content + sal_Bool SAL_CALL fill( const sal_Unicode* pContent, size_t nLen ); + + // returns the size of the buffer + size_t SAL_CALL size( ) const; + + // conversion operator + operator sal_Unicode*( ); + + // address operator + sal_Unicode* operator&( ); + + const sal_Unicode* operator&( ) const; + +private: + void SAL_CALL init( ); + +private: + size_t m_buffSize; // the number of unicode chars + sal_Unicode* m_pBuff; +}; + +#endif diff --git a/fpicker/source/win32/misc/WinImplHelper.cxx b/fpicker/source/win32/misc/WinImplHelper.cxx new file mode 100644 index 000000000000..6e8e93c6587d --- /dev/null +++ b/fpicker/source/win32/misc/WinImplHelper.cxx @@ -0,0 +1,610 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> +#include "AutoBuffer.hxx" +#include "WinImplHelper.hxx" +#include <com/sun/star/uno/Sequence.hxx> + +//------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------ + +using rtl::OUString; +using rtl::OUStringBuffer; +using ::com::sun::star::lang::IllegalArgumentException; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::XInterface; +using ::com::sun::star::uno::Any; +using ::com::sun::star::uno::Sequence; + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +const rtl::OUString TILDE = OUString::createFromAscii( "~" ); +const sal_Unicode TILDE_SIGN = L'~'; +const rtl::OUString AMPERSAND = OUString::createFromAscii( "&" ); +const sal_Unicode AMPERSAND_SIGN = L'&'; + +//------------------------------------------------------------ +// OS NAME Platform Major Minor +// +// Windows NT 3.51 VER_PLATFORM_WIN32_NT 3 51 +// Windows NT 4.0 VER_PLATFORM_WIN32_NT 4 0 +// Windows 2000 VER_PLATFORM_WIN32_NT 5 0 +// Windows XP VER_PLATFORM_WIN32_NT 5 1 +// Windows Vista VER_PLATFORM_WIN32_NT 6 0 +// Windows 7 VER_PLATFORM_WIN32_NT 6 1 +// Windows 95 VER_PLATFORM_WIN32_WINDOWS 4 0 +// Windows 98 VER_PLATFORM_WIN32_WINDOWS 4 10 +// Windows ME VER_PLATFORM_WIN32_WINDOWS 4 90 +//------------------------------------------------------------ + +bool SAL_CALL IsWindowsVersion(unsigned int PlatformId, unsigned int MajorVersion, int MinorVersion = -1) +{ + OSVERSIONINFO osvi; + osvi.dwOSVersionInfoSize = sizeof(osvi); + + if(!GetVersionEx(&osvi)) + return false; + + bool bRet = (PlatformId == osvi.dwPlatformId) && + (MajorVersion == osvi.dwMajorVersion); + + if (MinorVersion > -1) + bRet = bRet && + (sal::static_int_cast< unsigned int >(MinorVersion) == + osvi.dwMinorVersion); + + return bRet; +} + +//------------------------------------------------------------ +// determine if we are running under Vista or newer OS +//------------------------------------------------------------ + +bool SAL_CALL IsWindowsVistaOrNewer() +{ + OSVERSIONINFO osvi; + osvi.dwOSVersionInfoSize = sizeof(osvi); + + if(!GetVersionEx(&osvi)) + return false; + + bool bRet = (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId) && + (osvi.dwMajorVersion >= 6); + + bRet = bRet && + (osvi.dwMinorVersion >= + sal::static_int_cast< unsigned int >(0)); + + return bRet; +} + +//------------------------------------------------------------ +// determine if we are running under Windows 7 +//------------------------------------------------------------ + +bool SAL_CALL IsWindows7() +{ + return IsWindowsVersion(VER_PLATFORM_WIN32_NT, 6, 1); +} + +//------------------------------------------------------------ +// determine if we are running under Windows Vista +//------------------------------------------------------------ + +bool SAL_CALL IsWindowsVista() +{ + return IsWindowsVersion(VER_PLATFORM_WIN32_NT, 6, 0); +} + +//------------------------------------------------------------ +// determine if we are running under Windows XP +//------------------------------------------------------------ + +bool SAL_CALL IsWindowsXP() +{ + return IsWindowsVersion(VER_PLATFORM_WIN32_NT, 5, 1); +} + +//------------------------------------------------------------ +// determine if we are running under Windows 2000 +//------------------------------------------------------------ + +bool SAL_CALL IsWindows2000() +{ + return IsWindowsVersion(VER_PLATFORM_WIN32_NT, 5, 0); +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +bool SAL_CALL IsWindows98() +{ + return IsWindowsVersion(VER_PLATFORM_WIN32_WINDOWS, 4, 10); +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +bool SAL_CALL IsWindowsME() +{ + return IsWindowsVersion(VER_PLATFORM_WIN32_WINDOWS, 4, 90); +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +bool SAL_CALL IsWindows2000Platform() +{ + // POST: return true if we are at least on Windows 2000 + + // WRONG!: return IsWindowsVersion(VER_PLATFORM_WIN32_NT, 5); + + OSVERSIONINFO osvi; + ZeroMemory(&osvi, sizeof(osvi)); + osvi.dwOSVersionInfoSize = sizeof(osvi); + GetVersionEx(&osvi); + if ( osvi.dwMajorVersion >= 5 ) + { + return true; + } + return false; +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +void SAL_CALL ListboxAddString( HWND hwnd, const OUString& aString ) +{ + LRESULT rc = SendMessageW( + hwnd, CB_ADDSTRING, 0, reinterpret_cast< LPARAM >(aString.getStr( )) ); + (void) rc; // avoid warning + OSL_ASSERT( (CB_ERR != rc) && (CB_ERRSPACE != rc) ); +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +OUString SAL_CALL ListboxGetString( HWND hwnd, sal_Int32 aPosition ) +{ + OSL_ASSERT( IsWindow( hwnd ) ); + + OUString aString; + + LRESULT lItem = + SendMessageW( hwnd, CB_GETLBTEXTLEN, aPosition, 0 ); + + if ( (CB_ERR != lItem) && (lItem > 0) ) + { + // message returns the len of a combobox item + // without trailing '\0' that's why += 1 + lItem++; + + CAutoUnicodeBuffer aBuff( lItem ); + + LRESULT lRet = + SendMessageW( + hwnd, CB_GETLBTEXT, aPosition, + reinterpret_cast<LPARAM>(&aBuff) ); + + OSL_ASSERT( lRet != CB_ERR ); + + if ( CB_ERR != lRet ) + aString = OUString( aBuff, lRet ); + } + + return aString; +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +void SAL_CALL ListboxAddItem( HWND hwnd, const Any& aItem, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos ) + throw( IllegalArgumentException ) +{ + OSL_ASSERT( IsWindow( hwnd ) ); + + if ( !aItem.hasValue( ) || + aItem.getValueType( ) != getCppuType((OUString*)0) ) + throw IllegalArgumentException( + OUString::createFromAscii( "invalid value type or any has no value" ), + rXInterface, + aArgPos ); + + OUString cbItem; + aItem >>= cbItem; + + ListboxAddString( hwnd, cbItem ); +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +void SAL_CALL ListboxAddItems( HWND hwnd, const Any& aItemList, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos ) + throw( IllegalArgumentException ) +{ + OSL_ASSERT( IsWindow( hwnd ) ); + + if ( !aItemList.hasValue( ) || + aItemList.getValueType( ) != getCppuType((Sequence<OUString>*)0) ) + throw IllegalArgumentException( + OUString::createFromAscii( "invalid value type or any has no value" ), + rXInterface, + aArgPos ); + + Sequence< OUString > aStringList; + aItemList >>= aStringList; + + sal_Int32 nItemCount = aStringList.getLength( ); + for( sal_Int32 i = 0; i < nItemCount; i++ ) + { + ListboxAddString( hwnd, aStringList[i] ); + } +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +void SAL_CALL ListboxDeleteItem( HWND hwnd, const Any& aPosition, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos ) + throw( IllegalArgumentException ) +{ + OSL_ASSERT( IsWindow( hwnd ) ); + + if ( !aPosition.hasValue( ) || + ( (aPosition.getValueType( ) != getCppuType((sal_Int32*)0)) && + (aPosition.getValueType( ) != getCppuType((sal_Int16*)0)) && + (aPosition.getValueType( ) != getCppuType((sal_Int8*)0)) ) ) + throw IllegalArgumentException( + OUString::createFromAscii( "invalid value type or any has no value" ), + rXInterface, + aArgPos ); + + sal_Int32 nPos; + aPosition >>= nPos; + + LRESULT lRet = SendMessage( hwnd, CB_DELETESTRING, nPos, 0 ); + + // if the return value is CB_ERR the given + // index was not correct + if ( CB_ERR == lRet ) + throw IllegalArgumentException( + OUString::createFromAscii( "inavlid item position" ), + rXInterface, + aArgPos ); +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +void SAL_CALL ListboxDeleteItems( HWND hwnd, const Any&, const Reference< XInterface >&, sal_Int16 ) + throw( IllegalArgumentException ) +{ + OSL_ASSERT( IsWindow( hwnd ) ); + + LRESULT lRet = 0; + + do + { + // the return value on success is the number + // of remaining elements in the listbox + lRet = SendMessageW( hwnd, CB_DELETESTRING, 0, 0 ); + } + while ( (lRet != CB_ERR) && (lRet > 0) ); +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +void SAL_CALL ListboxSetSelectedItem( HWND hwnd, const Any& aPosition, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos ) + throw( IllegalArgumentException ) +{ + OSL_ASSERT( IsWindow( hwnd ) ); + + if ( !aPosition.hasValue( ) || + ( (aPosition.getValueType( ) != getCppuType((sal_Int32*)0)) && + (aPosition.getValueType( ) != getCppuType((sal_Int16*)0)) && + (aPosition.getValueType( ) != getCppuType((sal_Int8*)0)) ) ) + throw IllegalArgumentException( + OUString::createFromAscii( "invalid value type or any has no value" ), + rXInterface, + aArgPos ); + + sal_Int32 nPos; + aPosition >>= nPos; + + if ( nPos < -1 ) + throw IllegalArgumentException( + OUString::createFromAscii("invalid index"), + rXInterface, + aArgPos ); + + LRESULT lRet = SendMessageW( hwnd, CB_SETCURSEL, nPos, 0 ); + + if ( (CB_ERR == lRet) && (-1 != nPos) ) + throw IllegalArgumentException( + OUString::createFromAscii("invalid index"), + rXInterface, + aArgPos ); +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +Any SAL_CALL ListboxGetItems( HWND hwnd ) +{ + OSL_ASSERT( IsWindow( hwnd ) ); + + LRESULT nItemCount = SendMessageW( hwnd, CB_GETCOUNT, 0, 0 ); + + Sequence< OUString > aItemList; + + if ( CB_ERR != nItemCount ) + { + aItemList.realloc( nItemCount ); + + for ( sal_Int32 i = 0; i < nItemCount; i++ ) + { + aItemList[i] = ListboxGetString( hwnd, i ); + } + } + + Any aAny; + aAny <<= aItemList; + + return aAny; +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +Any SAL_CALL ListboxGetSelectedItem( HWND hwnd ) +{ + OSL_ASSERT( IsWindow( hwnd ) ); + + LRESULT idxItem = SendMessageW( hwnd, CB_GETCURSEL, 0, 0 ); + + Any aAny; + aAny <<= ListboxGetString( hwnd, idxItem ); + + return aAny; +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +Any SAL_CALL ListboxGetSelectedItemIndex( HWND hwnd ) +{ + OSL_ASSERT( IsWindow( hwnd ) ); + + LRESULT idxItem = SendMessageW( hwnd, CB_GETCURSEL, 0, 0 ); + + Any aAny; + aAny <<= static_cast< sal_Int32 >( idxItem ); + + return aAny; +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +Any SAL_CALL CheckboxGetState( HWND hwnd ) +{ + OSL_ASSERT( IsWindow( hwnd ) ); + + LRESULT lChkState = SendMessageW( hwnd, BM_GETCHECK, 0, 0 ); + sal_Bool bChkState = (lChkState == BST_CHECKED) ? sal_True : sal_False; + Any aAny; + aAny.setValue( &bChkState, getCppuType((sal_Bool*)0) ); + return aAny; +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +void SAL_CALL CheckboxSetState( + HWND hwnd, const ::com::sun::star::uno::Any& aState, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos ) + throw( IllegalArgumentException ) +{ + OSL_ASSERT( IsWindow( hwnd ) ); + + if ( !aState.hasValue( ) || + aState.getValueType( ) != getCppuType((sal_Bool*)0) ) + throw IllegalArgumentException( + OUString::createFromAscii( "invalid value type or any has no value" ), + rXInterface, + aArgPos ); + + sal_Bool bCheckState = *reinterpret_cast< const sal_Bool* >( aState.getValue( ) ); + WPARAM wParam = bCheckState ? BST_CHECKED : BST_UNCHECKED; + SendMessageW( hwnd, BM_SETCHECK, wParam, 0 ); +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +sal_uInt32 SAL_CALL _wcslenex( const sal_Unicode* pStr ) +{ + if ( !pStr ) + return 0; + + const sal_Unicode* pTemp = pStr; + sal_uInt32 strLen = 0; + while( *pTemp || *(pTemp + 1) ) + { + pTemp++; + strLen++; + } + + return strLen; +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +void Replace( const OUString& aLabel, sal_Unicode OldChar, sal_Unicode NewChar, OUStringBuffer& aBuffer ) +{ + OSL_ASSERT( aLabel.getLength( ) ); + OSL_ASSERT( aBuffer.getCapacity( ) >= (aLabel.getLength( )) ); + + sal_Int32 i = 0; + const sal_Unicode* pCurrent = aLabel.getStr( ); + const sal_Unicode* pNext = aLabel.getStr( ) + 1; + const sal_Unicode* pEnd = aLabel.getStr( ) + aLabel.getLength( ); + + while( pCurrent < pEnd ) + { + OSL_ASSERT( pNext <= pEnd ); + OSL_ASSERT( (i >= 0) && (i < aBuffer.getCapacity( )) ); + + if ( OldChar == *pCurrent ) + { + if ( OldChar == *pNext ) + { + // two OldChars in line will + // be replaced by one + // e.g. ~~ -> ~ + aBuffer.insert( i, *pCurrent ); + + // skip the next one + pCurrent++; + pNext++; + } + else + { + // one OldChar will be replace + // by NexChar + aBuffer.insert( i, NewChar ); + } + } + else if ( *pCurrent == NewChar ) + { + // a NewChar will be replaced by + // two NewChars + // e.g. & -> && + aBuffer.insert( i++, *pCurrent ); + aBuffer.insert( i, *pCurrent ); + } + else + { + aBuffer.insert( i, *pCurrent ); + } + + pCurrent++; + pNext++; + i++; + } +} + +//------------------------------------------------------------ +// converts a soffice label to a windows label +// the following rules for character replacements +// will be done: +// '~' -> '&' +// '~~' -> '~' +// '&' -> '&&' +//------------------------------------------------------------ + +OUString SOfficeToWindowsLabel( const rtl::OUString& aSOLabel ) +{ + OUString aWinLabel = aSOLabel; + + if ( (aWinLabel.indexOf( TILDE ) > -1) || (aWinLabel.indexOf( AMPERSAND ) > -1) ) + { + sal_Int32 nStrLen = aWinLabel.getLength( ); + + // in the worst case the new string is + // doubled in length, maybe some waste + // of memory but how long is a label + // normaly(?) + rtl::OUStringBuffer aBuffer( nStrLen * 2 ); + + Replace( aWinLabel, TILDE_SIGN, AMPERSAND_SIGN, aBuffer ); + + aWinLabel = aBuffer.makeStringAndClear( ); + } + + return aWinLabel; +} + +//------------------------------------------------------------ +// converts a windows label to a soffice label +// the following rules for character replacements +// will be done: +// '&' -> '~' +// '&&' -> '&' +// '~' -> '~~' +//------------------------------------------------------------ + +OUString WindowsToSOfficeLabel( const rtl::OUString& aWinLabel ) +{ + OUString aSOLabel = aWinLabel; + + if ( (aSOLabel.indexOf( TILDE ) > -1) || (aSOLabel.indexOf( AMPERSAND ) > -1) ) + { + sal_Int32 nStrLen = aSOLabel.getLength( ); + + // in the worst case the new string is + // doubled in length, maybe some waste + // of memory but how long is a label + // normaly(?) + rtl::OUStringBuffer aBuffer( nStrLen * 2 ); + + Replace( aSOLabel, AMPERSAND_SIGN, TILDE_SIGN, aBuffer ); + + aSOLabel = aBuffer.makeStringAndClear( ); + } + + return aSOLabel; +} + diff --git a/fpicker/source/win32/misc/WinImplHelper.hxx b/fpicker/source/win32/misc/WinImplHelper.hxx new file mode 100644 index 000000000000..412536cb37d6 --- /dev/null +++ b/fpicker/source/win32/misc/WinImplHelper.hxx @@ -0,0 +1,123 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _WINIMPLHELPER_HXX_ +#define _WINIMPLHELPER_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> +#include <rtl/ustring.hxx> + +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/lang/IllegalArgumentException.hpp> + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +bool SAL_CALL IsWindowsVistaOrNewer(); +bool SAL_CALL IsWindows7(); +bool SAL_CALL IsWindowsVista(); +bool SAL_CALL IsWindows2000(); +bool SAL_CALL IsWindowsXP(); +bool SAL_CALL IsWindows98(); +bool SAL_CALL IsWindowsME(); + +// returns true if the platform is +// Windows 2000 or above +bool SAL_CALL IsWindows2000Platform(); + +#define IsWin2000 IsWindows2000 + +// set actions +void SAL_CALL ListboxAddItem( + HWND hwnd, const ::com::sun::star::uno::Any& aItem, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rXInterface, sal_Int16 aArgPos ) + throw( ::com::sun::star::lang::IllegalArgumentException ); + +void SAL_CALL ListboxAddItems( + HWND hwnd, const ::com::sun::star::uno::Any& aItemList, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rXInterface, sal_Int16 aArgPos ) + throw( ::com::sun::star::lang:: IllegalArgumentException ); + +void SAL_CALL ListboxDeleteItem( + HWND hwnd, const ::com::sun::star::uno::Any& aPosition, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rXInterface, sal_Int16 aArgPos ) + throw( ::com::sun::star::lang::IllegalArgumentException ); + +void SAL_CALL ListboxDeleteItems( + HWND hwnd, const ::com::sun::star::uno::Any& aUnused, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rXInterface, sal_Int16 aArgPos ) + throw( ::com::sun::star::lang::IllegalArgumentException ); + +void SAL_CALL ListboxSetSelectedItem( + HWND hwnd, const ::com::sun::star::uno::Any& aPosition, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rXInterface, sal_Int16 aArgPos ) + throw( ::com::sun::star::lang::IllegalArgumentException ); + +// get actions +::com::sun::star::uno::Any SAL_CALL ListboxGetItems( HWND hwnd ); +::com::sun::star::uno::Any SAL_CALL ListboxGetSelectedItem( HWND hwnd ); +::com::sun::star::uno::Any SAL_CALL ListboxGetSelectedItemIndex( HWND hwnd ); + +// checkbox helper functions +::com::sun::star::uno::Any SAL_CALL CheckboxGetState( HWND hwnd ); + +void SAL_CALL CheckboxSetState( + HWND hwnd, const ::com::sun::star::uno::Any& aState, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rXInterface, sal_Int16 aArgPos ) + throw( ::com::sun::star::lang::IllegalArgumentException ); + +// calculates the length of '\0' separated and '\0\0' +// ending strings used in some Win32 functions +// e.g. Filter\0*.txt\0\0 +// the returned length excludes the last '\0' +sal_uInt32 SAL_CALL _wcslenex( const sal_Unicode* pStr ); + + +// converts a soffice label to a windows label +// the following rules for character replacements +// will be done: +// '~' -> '&' +// '~~' -> '~' +// '&' -> '&&' +rtl::OUString SOfficeToWindowsLabel( const rtl::OUString& aSOLabel ); + +// converts a windows label to a soffice label +// the following rules for character replacements +// will be done: +// '&' -> '~' +// '&&' -> '&' +// '~' -> '~~' +rtl::OUString WindowsToSOfficeLabel( const rtl::OUString& aWinLabel ); + +#endif diff --git a/fpicker/source/win32/misc/makefile.mk b/fpicker/source/win32/misc/makefile.mk new file mode 100644 index 000000000000..70faefdeaef4 --- /dev/null +++ b/fpicker/source/win32/misc/makefile.mk @@ -0,0 +1,57 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJNAME=fpicker +TARGET=utils +LIBTARGET=NO +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ---------------------------------- + +.INCLUDE : settings.mk + +.IF "$(COM)"=="GCC" +CFLAGSAPPEND+=-fexceptions -fno-enforce-eh-specs -DUNICODE -D_UNICODE +.ELSE +CFLAGS+=-EHa -DUNICODE -D_UNICODE +.ENDIF + +# --- Files ------------------------------------- + +SLOFILES=$(SLO)$/WinImplHelper.obj\ + $(SLO)$/AutoBuffer.obj\ + $(SLO)$/resourceprovider.obj + +LIB1TARGET=$(SLB)$/$(TARGET).lib +LIB1OBJFILES=$(SLOFILES) + +# --- Targets ---------------------------------- + +.INCLUDE : target.mk + + diff --git a/fpicker/source/win32/misc/resourceprovider.cxx b/fpicker/source/win32/misc/resourceprovider.cxx new file mode 100644 index 000000000000..b5448a93008c --- /dev/null +++ b/fpicker/source/win32/misc/resourceprovider.cxx @@ -0,0 +1,194 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_fpicker.hxx" + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ +#include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> +#include "resourceprovider.hxx" +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> + +#ifndef _TOOLS_SIMPLERESMGR_HXX +#include <tools/simplerm.hxx> +#endif +#include <com/sun/star/ui/dialogs/CommonFilePickerElementIds.hpp> +#include <com/sun/star/ui/dialogs/ExtendedFilePickerElementIds.hpp> + +#include <svtools/svtools.hrc> + +//------------------------------------------------------------ +// namespace directives +//------------------------------------------------------------ + +using rtl::OUString; +using namespace ::com::sun::star::ui::dialogs::ExtendedFilePickerElementIds; +using namespace ::com::sun::star::ui::dialogs::CommonFilePickerElementIds; + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +#define FOLDERPICKER_TITLE 500 +#define FOLDER_PICKER_DEF_DESCRIPTION 501 + +//------------------------------------------------------------ +// we have to translate control ids to resource ids +//------------------------------------------------------------ + +struct _Entry +{ + sal_Int32 ctrlId; + sal_Int16 resId; +}; + +_Entry CtrlIdToResIdTable[] = { + { CHECKBOX_AUTOEXTENSION, STR_SVT_FILEPICKER_AUTO_EXTENSION }, + { CHECKBOX_PASSWORD, STR_SVT_FILEPICKER_PASSWORD }, + { CHECKBOX_FILTEROPTIONS, STR_SVT_FILEPICKER_FILTER_OPTIONS }, + { CHECKBOX_READONLY, STR_SVT_FILEPICKER_READONLY }, + { CHECKBOX_LINK, STR_SVT_FILEPICKER_INSERT_AS_LINK }, + { CHECKBOX_PREVIEW, STR_SVT_FILEPICKER_SHOW_PREVIEW }, + { PUSHBUTTON_PLAY, STR_SVT_FILEPICKER_PLAY }, + { LISTBOX_VERSION_LABEL, STR_SVT_FILEPICKER_VERSION }, + { LISTBOX_TEMPLATE_LABEL, STR_SVT_FILEPICKER_TEMPLATES }, + { LISTBOX_IMAGE_TEMPLATE_LABEL, STR_SVT_FILEPICKER_IMAGE_TEMPLATE }, + { CHECKBOX_SELECTION, STR_SVT_FILEPICKER_SELECTION }, + { FOLDERPICKER_TITLE, STR_SVT_FOLDERPICKER_DEFAULT_TITLE }, + { FOLDER_PICKER_DEF_DESCRIPTION, STR_SVT_FOLDERPICKER_DEFAULT_DESCRIPTION } +}; + +const sal_Int32 SIZE_TABLE = sizeof( CtrlIdToResIdTable ) / sizeof( _Entry ); + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +sal_Int16 CtrlIdToResId( sal_Int32 aControlId ) +{ + sal_Int16 aResId = -1; + + for ( sal_Int32 i = 0; i < SIZE_TABLE; i++ ) + { + if ( CtrlIdToResIdTable[i].ctrlId == aControlId ) + { + aResId = CtrlIdToResIdTable[i].resId; + break; + } + } + + return aResId; +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +class CResourceProvider_Impl +{ +public: + + //------------------------------------- + // + //------------------------------------- + + CResourceProvider_Impl( ) + { + const ::vos::OGuard aGuard( Application::GetSolarMutex() ); + + com::sun::star::lang::Locale aLoc( Application::GetSettings().GetUILocale() ); + m_ResMgr = new SimpleResMgr( CREATEVERSIONRESMGR_NAME( fps_office ), aLoc ); + } + + //------------------------------------- + // + //------------------------------------- + + ~CResourceProvider_Impl( ) + { + delete m_ResMgr; + } + + //------------------------------------- + // + //------------------------------------- + + OUString getResString( sal_Int16 aId ) + { + OUString aResOUString; + + try + { + OSL_ASSERT( m_ResMgr ); + + // translate the control id to a resource id + sal_Int16 aResId = CtrlIdToResId( aId ); + + if ( aResId > -1 ) + aResOUString = m_ResMgr->ReadString( aResId ); + } + catch(...) + { + } + + return aResOUString; + } + +public: + SimpleResMgr* m_ResMgr; +}; + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +CResourceProvider::CResourceProvider( ) : + m_pImpl( new CResourceProvider_Impl() ) +{ +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +CResourceProvider::~CResourceProvider( ) +{ + delete m_pImpl; +} + +//------------------------------------------------------------ +// +//------------------------------------------------------------ + +OUString CResourceProvider::getResString( sal_Int16 aId ) +{ + return m_pImpl->getResString( aId ); +} diff --git a/fpicker/source/win32/misc/resourceprovider.hxx b/fpicker/source/win32/misc/resourceprovider.hxx new file mode 100644 index 000000000000..97cd753053bf --- /dev/null +++ b/fpicker/source/win32/misc/resourceprovider.hxx @@ -0,0 +1,60 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + + +#ifndef _RESOURCEPROVIDER_HXX_ +#define _RESOURCEPROVIDER_HXX_ + +//------------------------------------------------------------------------ +// includes +//------------------------------------------------------------------------ + +#include <sal/types.h> + +#ifndef _RTL_USTRING_HXX_ +#include <rtl/ustring> +#endif + +//------------------------------------------------------------------------ +// deklarations +//------------------------------------------------------------------------ + +class CResourceProvider_Impl; + +class CResourceProvider +{ +public: + CResourceProvider( ); + ~CResourceProvider( ); + + rtl::OUString getResString( sal_Int16 aId ); + +private: + CResourceProvider_Impl* m_pImpl; +}; + +#endif |