    /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
    /*
     * This file is part of the LibreOffice project.
     *
     * This Source Code Form is subject to the terms of the Mozilla Public
     * License, v. 2.0. If a copy of the MPL was not distributed with this
     * file, You can obtain one at http://mozilla.org/MPL/2.0/.
     *
     * This file incorporates work covered by the following license notice:
     *
     *   Licensed to the Apache Software Foundation (ASF) under one or more
     *   contributor license agreements. See the NOTICE file distributed
     *   with this work for additional information regarding copyright
     *   ownership. The ASF licenses this file to you under the Apache
     *   License, Version 2.0 (the "License"); you may not use this file
     *   except in compliance with the License. You may obtain a copy of
     *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
     */

    #include "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 <com/sun/star/beans/StringPair.hpp>
    #include <com/sun/star/awt/XWindow.hpp>
    #include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
    #include <com/sun/star/lang/SystemDependent.hpp>
    #include <comphelper/sequence.hxx>
    #include <fpicker/strings.hrc>
    #include <fpsofficeResMgr.hxx>
    #include <osl/file.hxx>
    #include <osl/mutex.hxx>
    #include <rtl/process.h>
    #include <o3tl/char16_t2wchar_t.hxx>
    #include "WinImplHelper.hxx"

    #include <shlguid.h>
    #include <shlobj.h>

     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 {

    bool createFolderItem(OUString const & url, ComPtr<IShellItem> & folder) {
        OUString path;
        if (osl::FileBase::getSystemPathFromFileURL(url, path)
            != osl::FileBase::E_None)
        {
            return false;
        }
        HRESULT res = SHCreateItemFromParsingName(
            o3tl::toW(path.getStr()), nullptr,
            IID_PPV_ARGS(&folder));
        return SUCCEEDED(res);
    }

    }

    namespace fpicker{
    namespace win32{
    namespace vista{

    // types, const etcpp.

    static const ::sal_Int16 INVALID_CONTROL_ID     = -1;
    static const ::sal_Int16 INVALID_CONTROL_ACTION = -1;

    // 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_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_LINK_ANCHOR     = {0xBE3188CB, 0x399A, 0x45AE, 0x8F, 0x78, 0x75, 0x17, 0xAF, 0x26, 0x81, 0xEA};
    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};

    OUString lcl_getURLFromShellItem (IShellItem* pItem)
    {
        LPWSTR pStr = nullptr;
        OUString sURL;
        HRESULT hr;

        hr = pItem->GetDisplayName ( SIGDN_FILESYSPATH, &pStr );
        if (SUCCEEDED(hr))
        {
            ::osl::FileBase::getFileURLFromSystemPath( o3tl::toU(pStr), sURL );
            goto cleanup;
        }

        hr = pItem->GetDisplayName ( SIGDN_URL, &pStr );
        if (SUCCEEDED(hr))
        {
            sURL = o3tl::toU(pStr);
            goto cleanup;
        }

        hr = pItem->GetDisplayName ( SIGDN_PARENTRELATIVEPARSING, &pStr );
        if (SUCCEEDED(hr))
        {
            GUID known_folder_id;
            std::wstring aStr = pStr;
            CoTaskMemFree (pStr);

            if (0 == aStr.compare(0, 3, L"::{"))
                aStr = aStr.substr(2);
            hr = IIDFromString(aStr.c_str(), &known_folder_id);
            if (SUCCEEDED(hr))
            {
                hr = SHGetKnownFolderPath(known_folder_id, 0, nullptr, &pStr);
                if (SUCCEEDED(hr))
                {
                    ::osl::FileBase::getFileURLFromSystemPath(o3tl::toU(pStr), sURL);
                    goto cleanup;
                }
            }
        }

        // Default fallback
        hr = SHGetKnownFolderPath(FOLDERID_Documents, 0, nullptr, &pStr);
        if (SUCCEEDED(hr))
            ::osl::FileBase::getFileURLFromSystemPath(o3tl::toU(pStr), sURL);
        else // shouldn't happen...
            goto bailout;

    cleanup:
        CoTaskMemFree (pStr);
    bailout:
        return sURL;
    }

    ::std::vector< COMDLG_FILTERSPEC > lcl_buildFilterList(CFilterContainer& rContainer)
    {
              ::std::vector< COMDLG_FILTERSPEC > lList  ;
              CFilterContainer::FILTER_ENTRY_T   aFilter;

        rContainer.beginEnumFilter( );
        while( rContainer.getNextFilter(aFilter) )
        {
            COMDLG_FILTERSPEC aSpec;

            aSpec.pszName = o3tl::toW(aFilter.first.getStr()) ;
            aSpec.pszSpec = o3tl::toW(aFilter.second.getStr());

            lList.push_back(aSpec);
        }

        return lList;
    }

    VistaFilePickerImpl::VistaFilePickerImpl()
        : m_iDialogOpen  ()
        , m_iDialogSave  ()
        , m_iFolderPicker()
        , m_hLastResult  ()
        , m_lFilters     ()
        , m_iEventHandler(new VistaFilePickerEventHandler(this))
        , m_bInExecute   (false)
        , m_bWasExecuted (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 uninitialize COM initialize it new .-)

        m_hLastResult = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
        if ( FAILED(m_hLastResult) )
        {
            CoUninitialize();
            m_hLastResult = CoInitializeEx(nullptr, 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_APPEND_FILTERGROUP :
                        impl_sta_appendFilterGroup(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_CREATE_FOLDER_PICKER:
                        impl_sta_CreateFolderPicker(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 = static_cast<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 = static_cast<VistaFilePickerEventHandler*>(iHandler.get());
        if (pHandlerImpl)
            pHandlerImpl->removeFilePickerListener(xListener);
    }

    void VistaFilePickerImpl::impl_sta_appendFilter(const RequestRef& rRequest)
    {
        const OUString sTitle  = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, OUString());
        const OUString sFilter = rRequest->getArgumentOrDefault(PROP_FILTER_VALUE, OUString());

        // SYNCHRONIZED->
        ::osl::ResettableMutexGuard aLock(m_aMutex);

        m_lFilters.addFilter(sTitle, sFilter);
    }

    void VistaFilePickerImpl::impl_sta_appendFilterGroup(const RequestRef& rRequest)
    {
        const css::uno::Sequence< css::beans::StringPair > aFilterGroup  =
            rRequest->getArgumentOrDefault(PROP_FILTER_GROUP, css::uno::Sequence< css::beans::StringPair >());

        // SYNCHRONIZED->
        ::osl::ResettableMutexGuard aLock(m_aMutex);

        if ( m_lFilters.numFilter() > 0 && aFilterGroup.getLength() > 0 )
            m_lFilters.addFilter( STRING_SEPARATOR, "", true );

        ::sal_Int32 c = aFilterGroup.getLength();
        ::sal_Int32 i = 0;
        for (i=0; i<c; ++i)
        {
            const css::beans::StringPair& rFilter = aFilterGroup[i];
            m_lFilters.addFilter(rFilter.First, rFilter.Second);
        }
    }

    void VistaFilePickerImpl::impl_sta_setCurrentFilter(const RequestRef& rRequest)
    {
        const OUString sTitle  = rRequest->getArgumentOrDefault(PROP_FILTER_TITLE, 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);

        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_CreateDialog(const RequestRef& rRequest, PickerDialog eType, DWORD nOrFlags)
    {
        // SYNCHRONIZED->
        ::osl::ResettableMutexGuard aLock(m_aMutex);

        TFileDialog iDialog;

        switch (eType)
        {
        case PickerDialog::FileOpen:
            m_hLastResult = m_iDialogOpen.create();
            if (FAILED(m_hLastResult))
                return;
            m_iDialogOpen.query(&iDialog);
            break;

        case PickerDialog::FileSave:
            m_hLastResult = m_iDialogSave.create();
            if (FAILED(m_hLastResult))
                return;
            m_iDialogSave.query(&iDialog);
            break;

        case PickerDialog::Folder:
            m_hLastResult = m_iFolderPicker.create();
            if (FAILED(m_hLastResult))
                return;
            m_iFolderPicker.query(&iDialog);
            break;
        }

        TFileDialogEvents iHandler = m_iEventHandler;

        aLock.clear();
        // <- SYNCHRONIZED

        DWORD nFlags = 0;
        iDialog->GetOptions ( &nFlags );

        nFlags &= ~FOS_FORCESHOWHIDDEN;
        nFlags |=  FOS_PATHMUSTEXIST;
        nFlags |=  FOS_DONTADDTORECENT;
        nFlags |= nOrFlags;

        iDialog->SetOptions ( nFlags );

        css::uno::Reference<css::awt::XWindow> xWindow = rRequest->getArgumentOrDefault(PROP_PARENT_WINDOW, css::uno::Reference<css::awt::XWindow>());
        if(xWindow.is())
        {
            css::uno::Reference<css::awt::XSystemDependentWindowPeer> xSysDepWin(xWindow,css::uno::UNO_QUERY);
            if(xSysDepWin.is()) {
                css::uno::Sequence<sal_Int8> aProcessIdent(16);
                rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8*>(aProcessIdent.getArray()));
                css::uno::Any aAny = xSysDepWin->getWindowHandle(aProcessIdent,css::lang::SystemDependent::SYSTEM_WIN32);
                sal_Int64 tmp = 0;
                aAny >>= tmp;
                if(tmp != 0)
                    m_hParentWindow = reinterpret_cast<HWND>(tmp);
            }
        }

        ::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 = static_cast<VistaFilePickerEventHandler*>(iHandler.get());
        if (pHandlerImpl)
            pHandlerImpl->startListening(iDialog);
    }

    void VistaFilePickerImpl::impl_sta_CreateOpenDialog(const RequestRef& rRequest)
    {
        DWORD nFlags = 0;
        nFlags |=  FOS_FILEMUSTEXIST;
        nFlags |=  FOS_OVERWRITEPROMPT;

        impl_sta_CreateDialog(rRequest, PickerDialog::FileOpen, nFlags);
    }

    void VistaFilePickerImpl::impl_sta_CreateSaveDialog(const RequestRef& rRequest)
    {
        DWORD nFlags = 0;
        nFlags |=  FOS_FILEMUSTEXIST;
        nFlags |=  FOS_OVERWRITEPROMPT;

        impl_sta_CreateDialog(rRequest, PickerDialog::FileSave, nFlags);
    }

    void VistaFilePickerImpl::impl_sta_CreateFolderPicker(const RequestRef& rRequest)
    {
        DWORD nFlags = 0;
        nFlags |=  FOS_PICKFOLDERS;

        impl_sta_CreateDialog(rRequest, PickerDialog::Folder, nFlags);
    }

    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 const ::sal_Int32 GROUP_IMAGEANCHOR     =   5;

    static void setLabelToControl(TFileDialogCustomize iCustom, sal_uInt16 nControlId)
    {
        OUString aLabel = CResourceProvider::getResString(nControlId);
        aLabel = SOfficeToWindowsLabel(aLabel);
        iCustom->SetControlLabel(nControlId, o3tl::toW(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::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::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();
        iDialog->SetClientGuid ( aGUID );

        TFileDialogCustomize iCustom = impl_getCustomizeInterface();

        if ((nFeatures & FEATURE_VERSION) == FEATURE_VERSION)
        {
            iCustom->StartVisualGroup (GROUP_VERSION, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_VERSION).replaceFirst("~","").getStr()));
            iCustom->AddComboBox      (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_VERSION);
            iCustom->EndVisualGroup   ();
            iCustom->MakeProminent    (GROUP_VERSION);
        }

        if ((nFeatures & FEATURE_TEMPLATE) == FEATURE_TEMPLATE)
        {
            iCustom->StartVisualGroup (GROUP_TEMPLATE, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_TEMPLATES).replaceFirst("~","").getStr()));
            iCustom->AddComboBox      (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_TEMPLATE);
            iCustom->EndVisualGroup   ();
            iCustom->MakeProminent    (GROUP_TEMPLATE);
        }

        if ((nFeatures & FEATURE_IMAGETEMPLATE) == FEATURE_IMAGETEMPLATE)
        {
            iCustom->StartVisualGroup (GROUP_IMAGETEMPLATE, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_IMAGE_TEMPLATE).replaceFirst("~","").getStr()));
            iCustom->AddComboBox      (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_TEMPLATE);
            iCustom->EndVisualGroup   ();
            iCustom->MakeProminent    (GROUP_IMAGETEMPLATE);
        }

        if ((nFeatures & FEATURE_IMAGEANCHOR) == FEATURE_IMAGEANCHOR)
        {
            iCustom->StartVisualGroup (GROUP_IMAGEANCHOR, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_IMAGE_ANCHOR).replaceFirst("~","").getStr()));
            iCustom->AddComboBox      (css::ui::dialogs::ExtendedFilePickerElementIds::LISTBOX_IMAGE_ANCHOR);
            iCustom->EndVisualGroup   ();
            iCustom->MakeProminent    (GROUP_IMAGEANCHOR);
        }

        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, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_AUTO_EXTENSION).replaceFirst("~","").getStr()), true);
            setLabelToControl(iCustom, nControlId);
        }

        if ((nFeatures & FEATURE_PASSWORD) == FEATURE_PASSWORD)
        {
            nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_PASSWORD;
            iCustom->AddCheckButton (nControlId, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_PASSWORD).replaceFirst("~","").getStr()), false);
            setLabelToControl(iCustom, nControlId);
        }

        if ((nFeatures & FEATURE_GPGPASSWORD) == FEATURE_GPGPASSWORD)
        {
            nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_GPGENCRYPTION;
            iCustom->AddCheckButton (nControlId, L"GpgPassword", false);
            setLabelToControl(iCustom, nControlId);
        }

        if ((nFeatures & FEATURE_READONLY) == FEATURE_READONLY)
        {
            nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_READONLY;
            iCustom->AddCheckButton (nControlId, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_READONLY).replaceFirst("~","").getStr()), false);
            setLabelToControl(iCustom, nControlId);
        }

        if ((nFeatures & FEATURE_FILTEROPTIONS) == FEATURE_FILTEROPTIONS)
        {
            nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_FILTEROPTIONS;
            iCustom->AddCheckButton (nControlId, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_FILTER_OPTIONS).replaceFirst("~","").getStr()), false);
            setLabelToControl(iCustom, nControlId);
        }

        if ((nFeatures & FEATURE_LINK) == FEATURE_LINK)
        {
            nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_LINK;
            iCustom->AddCheckButton (nControlId, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_INSERT_AS_LINK).replaceFirst("~","").getStr()), false);
            setLabelToControl(iCustom, nControlId);
        }

        if ((nFeatures & FEATURE_SELECTION) == FEATURE_SELECTION)
        {
            nControlId = css::ui::dialogs::ExtendedFilePickerElementIds::CHECKBOX_SELECTION;
            iCustom->AddCheckButton (nControlId, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_SELECTION).replaceFirst("~","").getStr()), false);
            setLabelToControl(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, o3tl::toW(FpsResId(STR_SVT_FILEPICKER_PLAY).replaceFirst("~","").getStr()));

    }

    void VistaFilePickerImpl::impl_sta_SetMultiSelectionMode(const RequestRef& rRequest)
    {
        const bool bMultiSelection = rRequest->getArgumentOrDefault(PROP_MULTISELECTION_MODE, 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)
    {
        OUString sTitle = rRequest->getArgumentOrDefault(PROP_TITLE, OUString());

        // SYNCHRONIZED->
        ::osl::ResettableMutexGuard aLock(m_aMutex);
        TFileDialog iDialog = impl_getBaseDialogInterface();
        aLock.clear();
        // <- SYNCHRONIZED

        iDialog->SetTitle(o3tl::toW(sTitle.getStr()));
    }

    void VistaFilePickerImpl::impl_sta_SetFileName(const RequestRef& rRequest)
    {
        OUString sFileName = rRequest->getArgumentOrDefault(PROP_FILENAME, OUString());

        // SYNCHRONIZED->
        ::osl::ResettableMutexGuard aLock(m_aMutex);
        TFileDialog iDialog = impl_getBaseDialogInterface();
        aLock.clear();
        // <- SYNCHRONIZED

        iDialog->SetFileName(o3tl::toW(sFileName.getStr()));
    }

    void VistaFilePickerImpl::impl_sta_SetDirectory(const RequestRef& rRequest)
    {
        OUString sDirectory = rRequest->getArgumentOrDefault(PROP_DIRECTORY, 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;
        if ( !createFolderItem(sDirectory, pFolder) )
            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;
        OUString sFolder = lcl_getURLFromShellItem ( pFolder );
        if( sFolder.getLength())
            rRequest->setArgument( PROP_DIRECTORY, sFolder );
    }

    void VistaFilePickerImpl::impl_sta_SetDefaultName(const RequestRef& rRequest)
    {
        OUString sFilename = rRequest->getArgumentOrDefault(PROP_FILENAME, 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 ( FAILED(hResult) )
            return;
        if ( bValue )
        {
            sal_Int32 nSepPos = sFilename.lastIndexOf( '.' );
            if ( -1 != nSepPos )
                sFilename = sFilename.copy(0, nSepPos);
        }

        iDialog->SetFileName (o3tl::toW(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);
        OUString                    sCurrentFilter = m_lFilters.getCurrentFilter();
        sal_Int32                          nCurrentFilter = m_lFilters.getFilterPos(sCurrentFilter);
        TFileDialog                        iDialog        = impl_getBaseDialogInterface();
        TFileDialogCustomize               iCustomize     = impl_getCustomizeInterface();

        aLock.clear();
        // <- SYNCHRONIZED

        if (lFilters.empty())
            return;

        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 ( FAILED(hResult) )
            return;

        if ( bValue )
        {
            PCWSTR 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;
        TFolderPickerDialog iPick  = m_iFolderPicker;
        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);
        }
        else if (iPick.is())
        {
            if (bInExecute)
                hResult = iPick->GetCurrentSelection(&iItem);
            else
            {
                hResult = iPick->GetResult(&iItem);
            }
        }

        if (FAILED(hResult))
            return;

        // convert and pack results
        std::vector< OUString > lFiles;
        if (iItem.is())
        {
            const 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 OUString sURL = lcl_getURLFromShellItem(iItem);
                        if (sURL.getLength() > 0)
                            lFiles.push_back(sURL);
                    }
                }
            }
        }

        rRequest->setArgument(PROP_SELECTED_FILES, comphelper::containerToSequence(lFiles));
    }

    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;
        TFolderPickerDialog iPick = m_iFolderPicker;

        // 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;

        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;
            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();

                    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);
                            ::std::vector< COMDLG_FILTERSPEC > lFilters = lcl_buildFilterList(m_lFilters);
                            if ( nRealIndex < lFilters.size() )
                            {
                                PCWSTR lpFilterExt = lFilters[nRealIndex].pszSpec;

                                lpFilterExt = wcsrchr( lpFilterExt, '.' );
                                if ( lpFilterExt )
                                    aFileURL += o3tl::toU(lpFilterExt);
                            }
                        }
                    }

                    // Check existence of file. Set folder only for this special case
                    OUString aSystemPath;
                    osl_getSystemPathFromFileURL( aFileURL.pData, &aSystemPath.pData );

                    WIN32_FIND_DATAW aFindFileData;
                    HANDLE  hFind = FindFirstFileW( o3tl::toW(aSystemPath.getStr()), &aFindFileData );
                    if (hFind != INVALID_HANDLE_VALUE)
                        iDialog->SetFolder(pFolder);
                    else
                        hResult = iDialog->AddPlace(pFolder, FDAP_TOP);

                    FindClose( hFind );
                }
                else
                    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
            else
            if (iPick.is())
                hResult = iPick->Show( m_hParentWindow ); // parent window needed
        }
        catch(...)
        {}

        // SYNCHRONIZED->
        aLock.reset();
        m_bInExecute = false;
        aLock.clear();
        // <- SYNCHRONIZED

        if ( FAILED(hResult) )
            return;

        impl_sta_getSelectedFiles(rRequest);
        rRequest->setArgument(PROP_DIALOG_SHOW_RESULT, true);
    }

    TFileDialog VistaFilePickerImpl::impl_getBaseDialogInterface()
    {
        TFileDialog iDialog;

        // SYNCHRONIZED->
        ::osl::ResettableMutexGuard aLock(m_aMutex);

        if (m_iDialogOpen.is())
            m_iDialogOpen.query(&iDialog);
        if (m_iDialogSave.is())
            m_iDialogSave.query(&iDialog);
        if (m_iFolderPicker.is())
            m_iFolderPicker.query(&iDialog);

        return iDialog;
    }

    TFileDialogCustomize VistaFilePickerImpl::impl_getCustomizeInterface()
    {
        TFileDialogCustomize iCustom;

        // SYNCHRONIZED->
        ::osl::ResettableMutexGuard aLock(m_aMutex);

        if (m_iDialogOpen.is())
            m_iDialogOpen.query(&iCustom);
        else if (m_iDialogSave.is())
            m_iDialogSave.query(&iCustom);
        else if (m_iFolderPicker.is())
            m_iFolderPicker.query(&iCustom);

        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->getValue(PROP_CONTROL_VALUE);

        // 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;

                        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    );

        // don't 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_GPGENCRYPTION :
            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;
                    HRESULT hResult = iCustom->GetCheckButtonState(nId, &bValue);
                    if ( SUCCEEDED(hResult) )
                        aValue <<= bool(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:
                {
                    DWORD    bValue = 0;
                    HRESULT hResult = iCustom->GetSelectedControlItem(nId, &bValue);
                    if ( SUCCEEDED(hResult) )
                    {
                        const OUString& sItem = m_lItems[bValue];
                        aValue <<= OUString(sItem.getStr());
                    }
                }
                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  );
        OUString sLabel = rRequest->getArgumentOrDefault(PROP_CONTROL_LABEL, OUString() );

        // don't check for right values here ...
        // most parameters are optional !

        TFileDialogCustomize iCustom = impl_getCustomizeInterface();
        if ( ! iCustom.is())
            return;
        iCustom->SetControlLabel (nId, o3tl::toW(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  );
        bool bEnabled = rRequest->getArgumentOrDefault(PROP_CONTROL_ENABLE, true);

        // don't 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 OUString& currentFilter )
    {
       TFileDialog iDialog = impl_getBaseDialogInterface();
       if (currentFilter.getLength())
       {
            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 = OUString(pFirstExtStart, posOfSemiColon - posOfPoint);
            iDialog->SetDefaultExtension ( o3tl::toW(FilterExt.getStr()) );
       }
    }

    void VistaFilePickerImpl::onAutoExtensionChanged (bool bChecked)
    {
        // SYNCHRONIZED->
        ::osl::ResettableMutexGuard aLock(m_aMutex);

        const OUString sFilter = m_lFilters.getCurrentFilter ();
              OUString sExt    ;
        if ( !m_lFilters.getFilter (sFilter, sExt))
            return;

        TFileDialog iDialog = impl_getBaseDialogInterface();

        aLock.clear();
        // <- SYNCHRONIZED

        PCWSTR pExt = nullptr;
        if ( bChecked )
        {
            pExt = o3tl::toW(sExt.getStr());
            pExt = wcsrchr( pExt, '.' );
            if ( pExt )
                pExt++;
        }
        iDialog->SetDefaultExtension( pExt );
    }

    bool VistaFilePickerImpl::onFileTypeChanged( UINT /*nTypeIndex*/ )
    {
        return true;
    }

    } // namespace vista
    } // namespace win32
    } // namespace fpicker

    /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

↑ V547 Expression 'tmp != 0' is always false.

↑ V519 The 'hResult' variable is assigned values twice successively. Perhaps this is a mistake. Check lines: 1097, 1098.