/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
if (bGetResult)
iItems = TDialogImplBase::getResult(bInExecute);
return iItems;
}
};
}
using TSaveDialogImpl = TDialogImpl<TFileSaveDialog, CLSID_FileSaveDialog>; using TFolderPickerDialogImpl = TDialogImpl<TFileOpenDialog, CLSID_FileOpenDialog>;
static OUString lcl_getURLFromShellItem (IShellItem* pItem)
{
sal::systools::CoTaskMemAllocated<wchar_t> pStr;
HRESULT hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pStr); if (FAILED(hr))
{ // tdf#155176: One could think that querying SIGDN_URL would go first. But Windows uses // current 8-bit codepage for the filenames, and URL-encodes those octets. So check it // only after SIGDN_FILESYSPATH query failed (can it ever happen?) if (SUCCEEDED(pItem->GetDisplayName(SIGDN_URL, &pStr))) return OUString(o3tl::toU(pStr));
OUString sURL; if (SUCCEEDED(hr))
::osl::FileBase::getFileURLFromSystemPath(OUString(o3tl::toU(pStr)), sURL); return sURL;
}
// Vista file picker shows the filter mask next to filter name in the list; so we need to remove the // mask from the filter name to avoid duplicating masks static OUString lcl_AdjustFilterName(const OUString& sName)
{ const sal_Int32 idx = sName.indexOf("(."); return (idx > 0) ? OUString(o3tl::trim(sName.subView(0, idx))) : sName;
}
// rvStrings holds the OUStrings, pointers to which data are stored in returned COMDLG_FILTERSPEC static ::std::vector<COMDLG_FILTERSPEC> lcl_buildFilterList(CFilterContainer& rContainer,
std::vector<OUString>& rvStrings)
{
::std::vector< COMDLG_FILTERSPEC > lList ;
CFilterContainer::FILTER_ENTRY_T aFilter;
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::FILEOPEN_PREVIEW : 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::FILEOPEN_READONLY_VERSION_FILTEROPTIONS : case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD_FILTEROPTIONS :
aGUID = CLIENTID_FILEDIALOG_OPTIONS; break;
case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION_PASSWORD :
aGUID = CLIENTID_FILESAVE_PASSWORD; break;
case css::ui::dialogs::TemplateDescription::FILESAVE_AUTOEXTENSION : 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_LINK_PREVIEW_IMAGE_ANCHOR :
aGUID = CLIENTID_FILEOPEN_LINK_ANCHOR; break;
case css::ui::dialogs::TemplateDescription::FILEOPEN_PLAY : case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PLAY :
aGUID = CLIENTID_FILEOPEN_PLAY; break;
case css::ui::dialogs::TemplateDescription::FILEOPEN_LINK_PREVIEW :
aGUID = CLIENTID_FILEOPEN_LINK; break;
}
TFileDialog iDialog = impl_getBaseDialogInterface(); if (iDialog.is())
iDialog->SetClientGuid ( aGUID );
TFileDialogCustomize iCustom = impl_getCustomizeInterface(); if (!iCustom.is()) return;
/* 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, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_PLAY).replaceFirst("~","").getStr()));
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 meantime and decide later // what to do
m_sDirectory = sDirectory;
}
TFileDialog iDialog = impl_getBaseDialogInterface(); if (!iDialog.is()) return;
sal::systools::COMReference<IShellItem> pFolder; if ( !createFolderItem(sDirectory, pFolder) ) return;
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 ( FAILED(hResult) ) return; if ( bValue )
{
sal_Int32 nSepPos = sFilename.lastIndexOf( '.' ); if ( -1 != nSepPos )
sFilename = sFilename.copy(0, nSepPos);
}
void VistaFilePickerImpl::impl_sta_setFiltersOnDialog()
{
std::vector<OUString> vStrings; // to hold the adjusted filter names, pointers to which will be // stored in lFilters
::std::vector< COMDLG_FILTERSPEC > lFilters = lcl_buildFilterList(m_lFilters, vStrings);
OUString sCurrentFilter = m_lFilters.getCurrentFilter();
sal_Int32 nCurrentFilter = m_lFilters.getFilterPos(sCurrentFilter);
TFileDialog iDialog = impl_getBaseDialogInterface(); if (!iDialog.is()) return;
TFileDialogCustomize iCustomize = impl_getCustomizeInterface(); if (!iCustomize.is()) return;
void VistaFilePickerImpl::impl_sta_getSelectedFiles(Request& rRequest)
{ if (m_pDialog == nullptr) return;
// ask dialog for results // we must react different if dialog is in execute or not .-(
sal::systools::COMReference<IShellItemArray> iItems = m_pDialog->getResult(m_bInExecute); if (!iItems.is()) return;
// convert and pack results
std::vector< OUString > lFiles; if (DWORD nCount; SUCCEEDED(iItems->GetCount(&nCount)))
{ for (DWORD i = 0; i < nCount; ++i)
{ if (sal::systools::COMReference<IShellItem> iItem;
SUCCEEDED(iItems->GetItemAt(i, &iItem)))
{ if (const OUString sURL = lcl_getURLFromShellItem(iItem.get()); !sURL.isEmpty())
lFiles.push_back(sURL);
}
}
}
TFileDialog iDialog = impl_getBaseDialogInterface(); if (!iDialog.is()) return;
// it's important to know if we are showing the dialog. // Some dialog interface methods can't be called then or some // tasks must be done differently .-) (e.g. see impl_sta_getSelectedFiles())
m_bInExecute = true;
m_bWasExecuted = true;
// 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())
{
sal::systools::COMReference<IShellItem> pFolder; if ( createFolderItem(m_sDirectory, pFolder) )
{ if (m_sFilename.getLength())
{
OUString aFileURL(m_sDirectory);
sal_Int32 nIndex = aFileURL.lastIndexOf('/'); if (nIndex != aFileURL.getLength()-1)
aFileURL += "/";
aFileURL += m_sFilename;
TFileDialogCustomize iCustom = impl_getCustomizeInterface(); if (!iCustom.is()) return;
BOOL bValue = FALSE;
HRESULT hResult = iCustom->GetCheckButtonState( css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_AUTOEXTENSION, &bValue); if ( bValue )
{
UINT nFileType;
hResult = iDialog->GetFileTypeIndex(&nFileType); if ( SUCCEEDED(hResult) && nFileType > 0 )
{ // COM dialog base on 1 ... filter container on 0 .-)
::size_t nRealIndex = nFileType-1;
OUString sFilter; if (m_lFilters.getFilterByIndex(nRealIndex, sFilter))
{ const sal_Int32 idx = sFilter.indexOf('.'); if (idx >= 0)
aFileURL += sFilter.subView(idx);
}
}
}
// Check existence of file. Set folder only for this special case
OUString aSystemPath;
osl_getSystemPathFromFileURL( aFileURL.pData, &aSystemPath.pData );
HRESULT hResult = E_FAIL; try
{ // tdf#146007: Make sure we don't hold solar mutex: COM may need to forward // the execution to the main thread, and holding solar mutex could deadlock
SolarMutexReleaser r; // show dialog and wait for user decision
hResult = iDialog->Show(m_hParentWindow ? m_hParentWindow
: choose_parent_window()); // parent window needed
} catch(...)
{}
m_bInExecute = false;
if (m_iEventHandler.is())
{ auto* pHandlerImpl = static_cast<VistaFilePickerEventHandler*>(m_iEventHandler.get());
pHandlerImpl->stopListening();
}
// don't 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 :
{ bool bValue = 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 : case css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_ANCHOR :
{
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 :
{
aValue >>= m_lItems; for (::sal_Int32 i=0; i<m_lItems.getLength(); ++i)
{ const OUString& sItem = m_lItems[i];
hResult = iCustom->AddControlItem(nId, i, o3tl::toW(sItem.getStr()));
}
} break;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.