fpicker/source/win32/VistaFilePickerImpl.cxx |  215 +++++++++++----------------
 fpicker/source/win32/VistaFilePickerImpl.hxx |   27 ---
 2 files changed, 93 insertions(+), 149 deletions(-)

New commits:
commit 43e306ebe61ef5a849dcfd1e74b697be3b3fe716
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Feb 25 22:35:29 2021 +0300
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Fri Feb 26 08:58:59 2021 +0100

    Simplify VistaFilePickerImpl
    
    Change-Id: I13ac92f8f28a1d912681239fee1780093f8be444
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111561
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/fpicker/source/win32/VistaFilePickerImpl.cxx 
b/fpicker/source/win32/VistaFilePickerImpl.cxx
index 0355e940c6f9..b0e733be88bc 100644
--- a/fpicker/source/win32/VistaFilePickerImpl.cxx
+++ b/fpicker/source/win32/VistaFilePickerImpl.cxx
@@ -27,6 +27,7 @@
 #include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
 #include <com/sun/star/lang/SystemDependent.hpp>
 #include <comphelper/sequence.hxx>
+#include <comphelper/windowserrorstring.hxx>
 #include <fpicker/strings.hrc>
 #include <fpsofficeResMgr.hxx>
 #include <osl/file.hxx>
@@ -93,6 +94,59 @@ const GUID CLIENTID_FILEOPEN_PLAY            = {0x32CFB147, 
0xF5AE, 0x4F90, 0xA1
 const GUID CLIENTID_FILEOPEN_LINK            = {0x39AC4BAE, 0x7D2D, 0x46BC, 
0xBE, 0x2E, 0xF8, 0x8C, 0xB5, 0x65, 0x5E, 0x6A};
 
 
+class TDialogImplBase
+{
+public:
+    template <class ComPtrDialog> TDialogImplBase(ComPtrDialog&& iDialog)
+    {
+        HRESULT hResult = iDialog.create();
+        if (FAILED(hResult))
+            throw 
css::uno::RuntimeException(WindowsErrorStringFromHRESULT(hResult));
+        hResult = iDialog.query(&m_iDialog);
+        if (FAILED(hResult))
+            throw 
css::uno::RuntimeException(WindowsErrorStringFromHRESULT(hResult));
+    }
+
+    TFileDialog getComPtr() { return m_iDialog; };
+    virtual ComPtr<IShellItemArray> getResult(bool bInExecute)
+    {
+        ComPtr<IShellItem> iItem;
+        if (bInExecute)
+            m_iDialog->GetCurrentSelection(&iItem);
+        else
+            m_iDialog->GetResult(&iItem);
+        void* iItems = nullptr;
+        SHCreateShellItemArrayFromShellItem(iItem, IID_IShellItemArray, 
&iItems);
+        return 
ComPtr<IShellItemArray>(reinterpret_cast<IShellItemArray*>(iItems));
+    }
+
+private:
+    TFileDialog m_iDialog;
+};
+
+template <class ComPtrDialog> class TDialogImpl : public TDialogImplBase
+{
+public:
+    TDialogImpl() : TDialogImplBase(ComPtrDialog()) {}
+};
+
+class TOpenDialogImpl : public TDialogImpl<TFileOpenDialog>
+{
+public:
+    ComPtr<IShellItemArray> getResult(bool bInExecute) override
+    {
+        ComPtr<IShellItemArray> iItems;
+        TFileOpenDialog iDialog{ getComPtr() };
+        if (FAILED(bInExecute ? iDialog->GetSelectedItems(&iItems) : 
iDialog->GetResults(&iItems)))
+            iItems = TDialogImplBase::getResult(bInExecute);
+        return iItems;
+    }
+};
+
+using TSaveDialogImpl = TDialogImpl<TFileSaveDialog>;
+using TFolderPickerDialogImpl = TDialogImpl<TFolderPickerDialog>;
+
+
 static OUString lcl_getURLFromShellItem (IShellItem* pItem)
 {
     LPWSTR pStr = nullptr;
@@ -179,11 +233,7 @@ static ::std::vector<COMDLG_FILTERSPEC> 
lcl_buildFilterList(CFilterContainer& rC
 
 
 VistaFilePickerImpl::VistaFilePickerImpl()
-    : m_iDialogOpen  ()
-    , m_iDialogSave  ()
-    , m_iFolderPicker()
-    , m_hLastResult  ()
-    , m_lFilters     ()
+    : m_lFilters     ()
     , m_iEventHandler(new VistaFilePickerEventHandler(this))
     , m_bInExecute   (false)
     , m_bWasExecuted (false)
@@ -209,7 +259,7 @@ void VistaFilePickerImpl::before()
     // 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...
-    m_hLastResult = o3tl::safeCoInitializeEx(COINIT_APARTMENTTHREADED, 
mnNbCallCoInitializeExForReinit);
+    o3tl::safeCoInitializeEx(COINIT_APARTMENTTHREADED, 
mnNbCallCoInitializeExForReinit);
 }
 
 
@@ -433,37 +483,20 @@ void VistaFilePickerImpl::impl_sta_getCurrentFilter(const 
RequestRef& rRequest)
 }
 
 
-void VistaFilePickerImpl::impl_sta_CreateDialog(const RequestRef& rRequest, 
PickerDialog eType, DWORD nOrFlags)
+template <class TDialogImplClass> void 
VistaFilePickerImpl::impl_sta_CreateDialog()
 {
     // SYNCHRONIZED->
     osl::ClearableMutexGuard aLock(m_aMutex);
+    m_pDialog.reset(new TDialogImplClass);
+}
 
-    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;
-    }
+void VistaFilePickerImpl::impl_sta_InitDialog(const RequestRef& rRequest, 
DWORD nOrFlags)
+{
+    // SYNCHRONIZED->
+    osl::ClearableMutexGuard aLock(m_aMutex);
 
+    TFileDialog iDialog = impl_getBaseDialogInterface();
     TFileDialogEvents iHandler = m_iEventHandler;
 
     aLock.clear();
@@ -509,30 +542,22 @@ void VistaFilePickerImpl::impl_sta_CreateDialog(const 
RequestRef& rRequest, Pick
 
 void VistaFilePickerImpl::impl_sta_CreateOpenDialog(const RequestRef& rRequest)
 {
-    DWORD nFlags = 0;
-    nFlags |=  FOS_FILEMUSTEXIST;
-    nFlags |=  FOS_OVERWRITEPROMPT;
-
-    impl_sta_CreateDialog(rRequest, PickerDialog::FileOpen, nFlags);
+    impl_sta_CreateDialog<TOpenDialogImpl>();
+    impl_sta_InitDialog(rRequest, FOS_FILEMUSTEXIST | FOS_OVERWRITEPROMPT);
 }
 
 
 void VistaFilePickerImpl::impl_sta_CreateSaveDialog(const RequestRef& rRequest)
 {
-    DWORD nFlags = 0;
-    nFlags |=  FOS_FILEMUSTEXIST;
-    nFlags |=  FOS_OVERWRITEPROMPT;
-
-    impl_sta_CreateDialog(rRequest, PickerDialog::FileSave, nFlags);
+    impl_sta_CreateDialog<TSaveDialogImpl>();
+    impl_sta_InitDialog(rRequest, FOS_FILEMUSTEXIST | FOS_OVERWRITEPROMPT);
 }
 
 
 void VistaFilePickerImpl::impl_sta_CreateFolderPicker(const RequestRef& 
rRequest)
 {
-    DWORD nFlags = 0;
-    nFlags |=  FOS_PICKFOLDERS;
-
-    impl_sta_CreateDialog(rRequest, PickerDialog::Folder, nFlags);
+    impl_sta_CreateDialog<TFolderPickerDialogImpl>();
+    impl_sta_InitDialog(rRequest, FOS_PICKFOLDERS);
 }
 
 
@@ -710,7 +735,7 @@ void 
VistaFilePickerImpl::impl_sta_SetMultiSelectionMode(const RequestRef& rRequ
     // <- SYNCHRONIZED
 
     DWORD nFlags = 0;
-    m_hLastResult = iDialog->GetOptions ( &nFlags );
+    iDialog->GetOptions(&nFlags);
 
     if (bMultiSelection)
         nFlags |=  FOS_ALLOWMULTISELECT;
@@ -866,76 +891,31 @@ void VistaFilePickerImpl::impl_sta_getSelectedFiles(const 
RequestRef& rRequest)
     // SYNCHRONIZED->
     osl::ClearableMutexGuard aLock(m_aMutex);
 
-    TFileOpenDialog iOpen      = m_iDialogOpen;
-    TFileSaveDialog iSave      = m_iDialogSave;
-    TFolderPickerDialog iPick  = m_iFolderPicker;
+    std::shared_ptr<TDialogImplBase> pDialog(m_pDialog);
     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 (!pDialog)
+        return;
 
-    if (FAILED(hResult))
+    // ask dialog for results
+    // we must react different if dialog is in execute or not .-(
+    ComPtr<IShellItemArray> iItems = pDialog->getResult(bInExecute);
+    if (!iItems)
         return;
 
     // convert and pack results
     std::vector< OUString > lFiles;
-    if (iItem.is())
+    if (DWORD nCount; SUCCEEDED(iItems->GetCount(&nCount)))
     {
-        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)
         {
-            for (DWORD i=0; i<nCount; ++i)
+            if (ComPtr<IShellItem> iItem; SUCCEEDED(iItems->GetItemAt(i, 
&iItem)))
             {
-                hResult = iItems->GetItemAt(i, &iItem);
-                if ( SUCCEEDED(hResult) )
-                {
-                    const OUString sURL = lcl_getURLFromShellItem(iItem);
-                    if (sURL.getLength() > 0)
-                        lFiles.push_back(sURL);
-                }
+                if (const OUString sURL = lcl_getURLFromShellItem(iItem); 
!sURL.isEmpty())
+                    lFiles.push_back(sURL);
             }
         }
     }
@@ -952,9 +932,6 @@ void VistaFilePickerImpl::impl_sta_ShowDialogModal(const 
RequestRef& rRequest)
     ::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
@@ -1033,14 +1010,7 @@ void VistaFilePickerImpl::impl_sta_ShowDialogModal(const 
RequestRef& rRequest)
     try
     {
         // show dialog and wait for user decision
-        if (iOpen.is())
-            hResult = iOpen->Show( hParentWindow ); // parent window needed
-        else
-        if (iSave.is())
-            hResult = iSave->Show( hParentWindow ); // parent window needed
-        else
-        if (iPick.is())
-            hResult = iPick->Show( hParentWindow ); // parent window needed
+        hResult = iDialog->Show(hParentWindow); // parent window needed
     }
     catch(...)
     {}
@@ -1065,13 +1035,8 @@ TFileDialog 
VistaFilePickerImpl::impl_getBaseDialogInterface()
 
     // SYNCHRONIZED->
     osl::MutexGuard 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);
+    if (m_pDialog)
+        iDialog = m_pDialog->getComPtr();
 
     return iDialog;
 }
@@ -1084,12 +1049,8 @@ TFileDialogCustomize 
VistaFilePickerImpl::impl_getCustomizeInterface()
     // SYNCHRONIZED->
     osl::MutexGuard 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);
+    if (m_pDialog)
+        m_pDialog->getComPtr().query(&iCustom);
 
     return iCustom;
 }
diff --git a/fpicker/source/win32/VistaFilePickerImpl.hxx 
b/fpicker/source/win32/VistaFilePickerImpl.hxx
index d60e3acbe020..1353c55e869a 100644
--- a/fpicker/source/win32/VistaFilePickerImpl.hxx
+++ b/fpicker/source/win32/VistaFilePickerImpl.hxx
@@ -82,6 +82,7 @@ const OUString PROP_CONTROL_ENABLE("control_enable"     ); // 
[sal_Bool] true=ON
 const OUString PROP_PARENT_WINDOW("ParentWindow"); //[css::awt::XWindow] 
preferred parent window
 const OUString STRING_SEPARATOR("------------------------------------------" );
 
+class TDialogImplBase;
 
 /** native implementation of the file picker on Vista and upcoming windows 
versions.
  *  This dialog uses COM internally. Further it marshall every request so it 
will
@@ -278,30 +279,12 @@ class VistaFilePickerImpl : private ::cppu::BaseMutex
         void impl_SetDefaultExtension( const OUString& currentFilter );
 
    private:
-        enum class PickerDialog
-        {
-            FileOpen,
-            FileSave,
-            Folder,
-        };
-
-        void impl_sta_CreateDialog(const RequestRef& rRequest, PickerDialog 
eType, DWORD nOrFlags);
-
-
-        /// COM object representing a file open dialog
-        TFileOpenDialog m_iDialogOpen;
-
-
-        /// COM object representing a file save dialog
-        TFileSaveDialog m_iDialogSave;
-
-
-        /// COM object representing a folder picker dialog
-        TFolderPickerDialog m_iFolderPicker;
+        template <class TDialogImplClass> void impl_sta_CreateDialog();
+        void impl_sta_InitDialog(const RequestRef& rRequest, DWORD nOrFlags);
 
 
-        /// knows the return state of the last COM call
-        HRESULT m_hLastResult;
+        /// object representing a file dialog
+        std::shared_ptr<TDialogImplBase> m_pDialog;
 
 
         /// @todo document me
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to