[Libreoffice-commits] core.git: 3 commits - svx/source

Lionel Elie Mamane lionel at mamane.lu
Tue Jul 21 09:06:43 PDT 2015


 svx/source/form/fmvwimp.cxx         |   98 +++++++++++++++++++++++++++++-------
 svx/source/form/formcontrolling.cxx |   12 ++--
 2 files changed, 87 insertions(+), 23 deletions(-)

New commits:
commit ba30fabf3ca88fedc05d521c9ec06a0b77007661
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date:   Tue Jul 21 17:31:56 2015 +0200

    Listen to error only while operating on controller.
    
    Else, on any action done directly (not through the
    FormControllerHelper) on the controller and raising an SQL error, this
    would silently swallow the error message, and the operation would fail
    without any message to the user.
    
    E.g. when validating an insertion or modification in a grid control by
    moving the cursor to a different line (as opposed to clicking the
    "Save Record" button).
    
    Change-Id: Ie569d9c826609f803f7b312c0469907155558ef2

diff --git a/svx/source/form/formcontrolling.cxx b/svx/source/form/formcontrolling.cxx
index db5d2be..6fcf0a7 100644
--- a/svx/source/form/formcontrolling.cxx
+++ b/svx/source/form/formcontrolling.cxx
@@ -240,11 +240,6 @@ namespace svx
             m_xFormOperations = FormOperations::createWithFormController( comphelper::getProcessComponentContext(), _rxController );
             if ( m_xFormOperations.is() )
                 m_xFormOperations->setFeatureInvalidation( this );
-
-            // to prevent the controller from displaying any error messages which happen while we operate on it,
-            // we add ourself as XSQLErrorListener. By contract, a FormController displays errors if and only if
-            // no SQLErrorListeners are registered.
-            _rxController->addSQLErrorListener( this );
         }
         catch( const Exception& )
         {
@@ -333,6 +328,11 @@ namespace svx
         const_cast< FormControllerHelper* >( this )->m_aOperationError.clear();
         try
         {
+            // to prevent the controller from displaying any error messages which happen while we operate on it,
+            // we add ourself as XSQLErrorListener. By contract, a FormController displays errors if and only if
+            // no SQLErrorListeners are registered.
+            m_xFormOperations->getController()->addSQLErrorListener( const_cast< FormControllerHelper* >(this) );
+
             switch ( _eWhat )
             {
             case COMMIT_CONTROL:
@@ -359,10 +359,12 @@ namespace svx
         }
         catch ( const SQLException& )
         {
+            m_xFormOperations->getController()->removeSQLErrorListener( const_cast< FormControllerHelper* >(this) );
             aError = ::cppu::getCaughtException();
         }
         catch( const Exception& )
         {
+            m_xFormOperations->getController()->removeSQLErrorListener( const_cast< FormControllerHelper* >(this) );
             SQLException aFallbackError;
             aFallbackError.Message = ::comphelper::anyToString( ::cppu::getCaughtException() );
             aError <<= aFallbackError;
commit b28ec7f462fcbb612b1c8a89af84c7c2601a5c65
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date:   Tue Jul 21 17:01:37 2015 +0200

    janitorial
    
    Change-Id: I727c5af7659e9591563c0784fee5d0d9317ebc24

diff --git a/svx/source/form/fmvwimp.cxx b/svx/source/form/fmvwimp.cxx
index 6d6c9a6..b153f3fb6 100644
--- a/svx/source/form/fmvwimp.cxx
+++ b/svx/source/form/fmvwimp.cxx
@@ -746,7 +746,7 @@ IMPL_LINK_NOARG(FmXFormView, OnActivate)
                 pAdapter =*i;
         }
 
-        if ( pAdapter.get() )
+        if ( pAdapter.is() )
         {
             Reference< XFormController > xControllerToActivate;
             for (   ::std::vector< Reference< XFormController > >::const_iterator i = pAdapter->GetList().begin();
commit 42f0a84764add89c6b22943d55c821acbcf3f37d
Author: Lionel Elie Mamane <lionel at mamane.lu>
Date:   Tue Jul 21 16:58:38 2015 +0200

    form document view activation: prioritise activation of already active form
    
    This avoids arbitrarily switching to the first form in the document,
    which would do a (premature!) save to the database of the
    modifications pending in the active form. This may lead to a database
    error, when the data is not in a shape to be written to the database,
    e.g. when on an insertion row and not all mandatory fields have been
    filled in. This then pops up an error message to the user.
    
    Change-Id: I30bb533598ca707b892bb7155e54ce05d4ddf275

diff --git a/svx/source/form/fmvwimp.cxx b/svx/source/form/fmvwimp.cxx
index 51db499..6d6c9a6 100644
--- a/svx/source/form/fmvwimp.cxx
+++ b/svx/source/form/fmvwimp.cxx
@@ -654,6 +654,66 @@ void FmXFormView::resumeTabOrderUpdate()
     m_aNeedTabOrderUpdate.clear();
 }
 
+namespace
+{
+    bool isActivableDatabaseForm(const Reference< XFormController > &xController)
+    {
+        // only database forms are to be activated
+        Reference< XRowSet >  xForm(xController->getModel(), UNO_QUERY);
+        if ( !xForm.is() || !getConnection( xForm ).is() )
+            return false;
+
+        Reference< XPropertySet > xFormSet( xForm, UNO_QUERY );
+        if ( !xFormSet.is() )
+        {
+            SAL_WARN( "svx.form", "FmXFormView::OnActivate: a form which does not have properties?" );
+            return false;
+        }
+
+        const OUString aSource = ::comphelper::getString( xFormSet->getPropertyValue( FM_PROP_COMMAND ) );
+
+        return !aSource.isEmpty();
+    }
+
+    class find_active_databaseform
+    {
+        const Reference< XFormController > xActiveController;
+
+    public:
+
+        find_active_databaseform( const Reference< XFormController > _xActiveController )
+            : xActiveController(_xActiveController )
+        {}
+
+        Reference < XFormController > operator() (const Reference< XFormController > &xController)
+        {
+            if(xController == xActiveController && isActivableDatabaseForm(xController))
+                return xController;
+
+            Reference< XIndexAccess > xSubControllers( xController, UNO_QUERY );
+            if ( !xSubControllers.is() )
+            {
+                SAL_WARN( "svx.form", "FmXFormView::OnActivate: a form controller which does not have children?" );
+                return nullptr;
+            }
+
+            for(sal_Int32 i = 0; i < xSubControllers->getCount(); ++i)
+            {
+                const Any a(xSubControllers->getByIndex(i));
+                Reference < XFormController > xI;
+                if ((a >>= xI) && xI.is())
+                {
+                    Reference < XFormController > xRes(operator()(xI));
+                    if (xRes.is())
+                        return xRes;
+                }
+            }
+
+            return nullptr;
+        }
+    };
+}
+
 
 IMPL_LINK_NOARG(FmXFormView, OnActivate)
 {
@@ -668,6 +728,13 @@ IMPL_LINK_NOARG(FmXFormView, OnActivate)
     // setting the controller to activate
     if (m_pView->GetFormShell() && m_pView->GetActualOutDev() && m_pView->GetActualOutDev()->GetOutDevType() == OUTDEV_WINDOW)
     {
+        FmXFormShell* const pShImpl =  m_pView->GetFormShell()->GetImpl();
+
+        if(!pShImpl)
+            return 0;
+
+        find_active_databaseform fad(pShImpl->getActiveController());
+
         vcl::Window* pWindow = const_cast<vcl::Window*>(static_cast<const vcl::Window*>(m_pView->GetActualOutDev()));
         PFormViewPageWindowAdapter pAdapter = m_aPageWindowAdapters.empty() ? NULL : m_aPageWindowAdapters[0];
         for (   PageWindowAdapterList::const_iterator i = m_aPageWindowAdapters.begin();
@@ -681,6 +748,7 @@ IMPL_LINK_NOARG(FmXFormView, OnActivate)
 
         if ( pAdapter.get() )
         {
+            Reference< XFormController > xControllerToActivate;
             for (   ::std::vector< Reference< XFormController > >::const_iterator i = pAdapter->GetList().begin();
                     i != pAdapter->GetList().end();
                     ++i
@@ -690,27 +758,21 @@ IMPL_LINK_NOARG(FmXFormView, OnActivate)
                 if ( !xController.is() )
                     continue;
 
-                // only database forms are to be activated
-                Reference< XRowSet >  xForm(xController->getModel(), UNO_QUERY);
-                if ( !xForm.is() || !getConnection( xForm ).is() )
-                    continue;
-
-                Reference< XPropertySet > xFormSet( xForm, UNO_QUERY );
-                if ( !xFormSet.is() )
                 {
-                    SAL_WARN( "svx.form", "FmXFormView::OnActivate: a form which does not have properties?" );
-                    continue;
+                    Reference< XFormController > xActiveController(fad(xController));
+                    if (xActiveController.is())
+                    {
+                        xControllerToActivate = xActiveController;
+                        break;
+                    }
                 }
 
-                const OUString aSource = ::comphelper::getString( xFormSet->getPropertyValue( FM_PROP_COMMAND ) );
-                if ( !aSource.isEmpty() )
-                {
-                    FmXFormShell* pShImpl =  m_pView->GetFormShell()->GetImpl();
-                    if ( pShImpl )
-                        pShImpl->setActiveController( xController );
-                    break;
-                }
+                if(xControllerToActivate.is() || !isActivableDatabaseForm(xController))
+                    continue;
+
+                xControllerToActivate = xController;
             }
+            pShImpl->setActiveController( xControllerToActivate );
         }
     }
     return 0;


More information about the Libreoffice-commits mailing list