[Libreoffice-commits] core.git: framework/source include/sfx2 include/unotools offapi/com sfx2/source sw/qa unotools/source

Jan-Marek Glogowski (via logerrit) logerrit at kemper.freedesktop.org
Tue Feb 11 23:28:25 UTC 2020


 framework/source/loadenv/loadenv.cxx             |   10 ++++------
 include/sfx2/sfxsids.hrc                         |    2 +-
 include/unotools/mediadescriptor.hxx             |    1 +
 offapi/com/sun/star/document/MediaDescriptor.idl |   13 +++++++++++++
 sfx2/source/appl/appuno.cxx                      |   18 ++++++++++++++++++
 sfx2/source/doc/sfxbasemodel.cxx                 |    8 ++++++++
 sfx2/source/view/frmload.cxx                     |    4 +++-
 sw/qa/python/check_xmodel.py                     |    4 +++-
 unotools/source/misc/mediadescriptor.cxx         |    6 ++++++
 9 files changed, 57 insertions(+), 9 deletions(-)

New commits:
commit 61e1e0413296928d929f99c0f006c6cbbcf4ac40
Author:     Jan-Marek Glogowski <jan-marek.glogowski at extern.cib.de>
AuthorDate: Fri Feb 7 23:16:50 2020 +0000
Commit:     Thorsten Behrens <Thorsten.Behrens at CIB.de>
CommitDate: Wed Feb 12 00:27:51 2020 +0100

    tdf#126700 allow replacing the default documents
    
    Per default, a document opened by a user action will always open
    in a new frame. For tdf#83722, this behaviour was extended to
    documents created from templates.
    
    But this currently also affects the default factory templates, if
    these are replaced by a config setting with a real template, which
    was not intentional.
    
    So this patch introduces a new MediaDescriptor property, which
    allows to mark a document as replaceable and automatically sets
    it for factory default documents. If this property is set to true,
    a document just acts as a placeholder while it's unmodified. I.e.
    the next opened document from its frame will close and replace it.
    
    Change-Id: I45ffa8709f7cdda949fac78f3b363f120f0c4a03
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88257
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>

diff --git a/framework/source/loadenv/loadenv.cxx b/framework/source/loadenv/loadenv.cxx
index 2de5ebbfa7f2..78897aa813cc 100644
--- a/framework/source/loadenv/loadenv.cxx
+++ b/framework/source/loadenv/loadenv.cxx
@@ -1093,10 +1093,11 @@ bool LoadEnv::impl_loadContent()
     bool bHidden    = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_HIDDEN(), false);
     bool bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_MINIMIZED(), false);
     bool bPreview   = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_PREVIEW(), false);
-    css::uno::Reference< css::task::XStatusIndicator > xProgress  = m_lMediaDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_STATUSINDICATOR(), css::uno::Reference< css::task::XStatusIndicator >());
 
     if (!bHidden && !bMinimized && !bPreview)
     {
+        css::uno::Reference<css::task::XStatusIndicator> xProgress = m_lMediaDescriptor.getUnpackedValueOrDefault(
+            utl::MediaDescriptor::PROP_STATUSINDICATOR(), css::uno::Reference<css::task::XStatusIndicator>());
         if (!xProgress.is())
         {
             // Note: it's an optional interface!
@@ -1519,12 +1520,9 @@ css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget()
     if (xOldDoc.is())
     {
         utl::MediaDescriptor lOldDocDescriptor(xModel->getArgs());
-        bool bFromTemplate = lOldDocDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_ASTEMPLATE() , false);
-        OUString sReferrer = lOldDocDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_REFERRER(), OUString());
 
-        // tdf#83722: valid but unmodified document, either from template
-        // or opened by the user (via File > New, referrer is set to private:user)
-        if (bFromTemplate || (sReferrer == "private:user"))
+        // replaceable document
+        if (!lOldDocDescriptor.getUnpackedValueOrDefault(utl::MediaDescriptor::PROP_REPLACEABLE(), false))
             return css::uno::Reference< css::frame::XFrame >();
 
         bReactivateOldControllerOnError = xOldDoc->suspend(true);
diff --git a/include/sfx2/sfxsids.hrc b/include/sfx2/sfxsids.hrc
index 63d5ce036c63..d7367587db1d 100644
--- a/include/sfx2/sfxsids.hrc
+++ b/include/sfx2/sfxsids.hrc
@@ -269,8 +269,8 @@ class SvxSearchItem;
 #define SID_LOCK_PRINT                      (SID_SFX_START + 1736)
 #define SID_LOCK_SAVE                       (SID_SFX_START + 1737)
 #define SID_LOCK_EDITDOC                    (SID_SFX_START + 1738)
+#define SID_REPLACEABLE                     (SID_SFX_START + 1739)
 
-//      SID_SFX_free_START                  (SID_SFX_START + 1739)
 //      SID_SFX_free_END                    (SID_SFX_START + 3999)
 
 #define SID_OPEN_NEW_VIEW                   (SID_SFX_START + 520)
diff --git a/include/unotools/mediadescriptor.hxx b/include/unotools/mediadescriptor.hxx
index 6a826ce309ac..da94f4188b3c 100644
--- a/include/unotools/mediadescriptor.hxx
+++ b/include/unotools/mediadescriptor.hxx
@@ -84,6 +84,7 @@ class UNOTOOLS_DLLPUBLIC MediaDescriptor : public comphelper::SequenceAsHashMap
         static const OUString& PROP_PREVIEW();
         static const OUString& PROP_READONLY();
         static const OUString& PROP_REFERRER();
+        static const OUString& PROP_REPLACEABLE();
         static const OUString& PROP_SALVAGEDFILE();
         static const OUString& PROP_STATUSINDICATOR();
         static const OUString& PROP_STREAM();
diff --git a/offapi/com/sun/star/document/MediaDescriptor.idl b/offapi/com/sun/star/document/MediaDescriptor.idl
index 728ef4ab4a29..119ed0e4c3fb 100644
--- a/offapi/com/sun/star/document/MediaDescriptor.idl
+++ b/offapi/com/sun/star/document/MediaDescriptor.idl
@@ -596,6 +596,19 @@ service MediaDescriptor
         @since LibreOffice 6.4
      */
     [optional,property] boolean LockEditDoc;
+
+    /** Mark the document as replaceable / a placeholder
+
+        <p>Normally a document is always opened in a new frame. If this property is
+        set to true, this document just acts as a placeholder while it's unmodified.
+        I.e. the next opened document from its frame will close and replace it.</p>
+
+        <p>This defaults to false, except for the default template of a LibreOffice
+        module, referenced as "private:factory/<module>".</p>
+
+        @since LibreOffice 7.0
+     */
+    [optional,property] boolean Replaceable;
 };
 
 
diff --git a/sfx2/source/appl/appuno.cxx b/sfx2/source/appl/appuno.cxx
index 2989ee0ad2ac..ede87667adce 100644
--- a/sfx2/source/appl/appuno.cxx
+++ b/sfx2/source/appl/appuno.cxx
@@ -153,6 +153,7 @@ static char const sLockExport[] = "LockExport";
 static char const sLockPrint[] = "LockPrint";
 static char const sLockSave[] = "LockSave";
 static char const sLockEditDoc[] = "LockEditDoc";
+static char const sReplaceable[] = "Replaceable";
 
 static bool isMediaDescriptor( sal_uInt16 nSlotId )
 {
@@ -865,6 +866,14 @@ void TransformParameters( sal_uInt16 nSlotId, const uno::Sequence<beans::Propert
                 if (bOK)
                     rSet.Put( SfxBoolItem( SID_LOCK_EDITDOC, bVal ) );
             }
+            else if (aName == sReplaceable)
+            {
+                bool bVal = false;
+                bool bOK = (rProp.Value >>= bVal);
+                DBG_ASSERT(bOK, "invalid type for Replaceable");
+                if (bOK)
+                    rSet.Put(SfxBoolItem(SID_REPLACEABLE, bVal));
+            }
 #ifdef DBG_UTIL
             else
                 --nFoundArgs;
@@ -1092,6 +1101,8 @@ void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, uno::Sequence<b
                 nAdditional++;
             if ( rSet.GetItemState( SID_LOCK_EDITDOC ) == SfxItemState::SET )
                 nAdditional++;
+            if (rSet.GetItemState(SID_REPLACEABLE) == SfxItemState::SET)
+                nAdditional++;
 
             // consider additional arguments
             nProps += nAdditional;
@@ -1259,6 +1270,8 @@ void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, uno::Sequence<b
                         continue;
                     if ( nId == SID_LOCK_EDITDOC )
                         continue;
+                    if (nId == SID_REPLACEABLE)
+                        continue;
                }
 
                 OString aDbg = "Unknown item detected: " + OString::number(static_cast<sal_Int32>(nId));
@@ -1676,6 +1689,11 @@ void TransformItems( sal_uInt16 nSlotId, const SfxItemSet& rSet, uno::Sequence<b
             pValue[nActProp].Name = sLockEditDoc;
             pValue[nActProp++].Value <<= static_cast<const SfxBoolItem*>(pItem)->GetValue();
         }
+        if (rSet.GetItemState(SID_REPLACEABLE, false, &pItem) == SfxItemState::SET)
+        {
+            pValue[nActProp].Name = sReplaceable;
+            pValue[nActProp++].Value <<= static_cast<const SfxBoolItem*>(pItem)->GetValue();
+        }
     }
 
     rArgs = aSequ;
diff --git a/sfx2/source/doc/sfxbasemodel.cxx b/sfx2/source/doc/sfxbasemodel.cxx
index 5e363821be93..7d6c8317f804 100644
--- a/sfx2/source/doc/sfxbasemodel.cxx
+++ b/sfx2/source/doc/sfxbasemodel.cxx
@@ -1122,6 +1122,14 @@ void SAL_CALL SfxBaseModel::setArgs(const Sequence<beans::PropertyValue>& aArgs)
                 ok = true;
             }
         }
+        else if (rArg.Name == "Replaceable")
+        {
+            if (rArg.Value >>= bValue)
+            {
+                pMedium->GetItemSet()->Put(SfxBoolItem(SID_REPLACEABLE, bValue));
+                ok = true;
+            }
+        }
         if (!ok)
         {
             throw lang::IllegalArgumentException("Setting property not supported: " + rArg.Name,
diff --git a/sfx2/source/view/frmload.cxx b/sfx2/source/view/frmload.cxx
index 82b438d8e7fa..f69706de1b04 100644
--- a/sfx2/source/view/frmload.cxx
+++ b/sfx2/source/view/frmload.cxx
@@ -611,7 +611,9 @@ sal_Bool SAL_CALL SfxFrameLoader_Impl::load( const Sequence< PropertyValue >& rA
     const OUString sURL = aDescriptor.getOrDefault( "URL", OUString() );
     const bool bIsFactoryURL = sURL.startsWith( "private:factory/" );
     bool bInitNewModel = bIsFactoryURL;
-    if ( bIsFactoryURL && !bExternalModel )
+    const bool bIsDefault = bIsFactoryURL && !bExternalModel;
+    aDescriptor.put("Replaceable", bIsDefault);
+    if (bIsDefault)
     {
         const OUString sFactory = sURL.copy( sizeof( "private:factory/" ) -1 );
         // special handling for some weird factory URLs a la private:factory/swriter?slot=21053
diff --git a/sw/qa/python/check_xmodel.py b/sw/qa/python/check_xmodel.py
index f6894dd21a3f..27740958ddb1 100644
--- a/sw/qa/python/check_xmodel.py
+++ b/sw/qa/python/check_xmodel.py
@@ -37,7 +37,8 @@ class TestXModel(unittest.TestCase):
         p5 = PropertyValue(Name="LockPrint", Value=True)
         p6 = PropertyValue(Name="LockSave", Value=True)
         p7 = PropertyValue(Name="LockEditDoc", Value=True)
-        xDoc.setArgs([p1, p2, p3, p4, p5, p6, p7])
+        p8 = PropertyValue(Name="Replaceable", Value=True)
+        xDoc.setArgs([p1, p2, p3, p4, p5, p6, p7, p8])
 
         # Make sure that all properties are returned with getArgs()
         args = xDoc.getArgs()
@@ -48,6 +49,7 @@ class TestXModel(unittest.TestCase):
         self.assertTrue(p5 in args)
         self.assertTrue(p6 in args)
         self.assertTrue(p7 in args)
+        self.assertTrue(p8 in args)
 
         xDoc.close(True)
 
diff --git a/unotools/source/misc/mediadescriptor.cxx b/unotools/source/misc/mediadescriptor.cxx
index 0d0839f62b18..1b830fb4e7d9 100644
--- a/unotools/source/misc/mediadescriptor.cxx
+++ b/unotools/source/misc/mediadescriptor.cxx
@@ -222,6 +222,12 @@ const OUString& MediaDescriptor::PROP_REFERRER()
     return sProp;
 }
 
+const OUString& MediaDescriptor::PROP_REPLACEABLE()
+{
+    static const OUString sProp("Replaceable");
+    return sProp;
+}
+
 const OUString& MediaDescriptor::PROP_STATUSINDICATOR()
 {
     static const OUString sProp("StatusIndicator");


More information about the Libreoffice-commits mailing list