chart2/source/tools/ReferenceSizeProvider.cxx | 3 sc/source/filter/excel/xepage.cxx | 5 - sc/source/filter/xml/xmlcelli.cxx | 30 ++++-- sc/source/ui/app/scmod.cxx | 2 sd/qa/unit/uiimpress.cxx | 70 ++++++++-------- sd/source/ui/unoidl/unomodel.cxx | 8 - sfx2/source/doc/guisaveas.cxx | 13 ++ sw/qa/uibase/shells/shells.cxx | 113 ++++++++++++-------------- sw/source/uibase/shells/textsh1.cxx | 21 ++++ sw/source/uibase/uno/loktxdoc.cxx | 3 10 files changed, 149 insertions(+), 119 deletions(-)
New commits: commit 6a7591039e0de8490fc5934ef1ed7238c3166646 Author: Szymon Kłos <[email protected]> AuthorDate: Wed Feb 19 08:20:28 2025 +0100 Commit: Caolán McNamara <[email protected]> CommitDate: Thu Feb 27 09:07:22 2025 +0000 lok: don't invalidate on theme switch In LOK invalidation means: content was changed. Apart of tiles we send the background color so client already knows - has to redraw and new rendering state options also trigger notifications. LOK with this knowledge will request tiles in new theme variant if not having them already in the cache. Invalidation was causing the cache in WSD beeing cleared. What caused expensive redrawing of all tiles needed later. Especially visible when joining with new view or dark mode switching. Old logs: [ kitbroker_001 ] TRC KitQueue(2) - pop child-04c uno .uno:ChangeTheme {"NewTheme":{"type":"string","value":"Dark"}}| kit/KitQueue.cpp:410 ... [ kitbroker_001 ] TRC Should we trim our caches ?| kit/Kit.cpp:1057 [ kitbroker_001 ] TRC Document::ViewCallback [5] [LOK_CALLBACK_VIEW_RENDER_STATE] [SD;Dark].| kit/Kit.cpp:1158 [ kitbroker_001 ] TRC postMessage called with: client-04c canonicalidchange: viewid=5 canonicalid=1001 viewrenderedstate=SD;Dark| kit/Kit.cpp:832 [ kitbroker_001 ] TRC Document::ViewCallback [5] [LOK_CALLBACK_APPLICATION_BACKGROUND_COLOR] [1c1c1c].| kit/Kit.cpp:1158 [ kitbroker_001 ] TRC Document::ViewCallback end.| kit/Kit.cpp:1214 [ kitbroker_001 ] TRC Document::ViewCallback [5] [LOK_CALLBACK_INVALIDATE_TILES] [EMPTY, 1, 0].| kit/Kit.cpp:1158 [ kitbroker_001 ] TRC Document::ViewCallback end.| kit/Kit.cpp:1214 [ kitbroker_001 ] TRC Document::ViewCallback [5] [LOK_CALLBACK_CALC_FUNCTION_LIST] [hidetip].| kit/Kit.cpp:1158 [ kitbroker_001 ] TRC Document::ViewCallback end.| kit/Kit.cpp:1214 [ kitbroker_001 ] TRC Document::ViewCallback [5] [LOK_CALLBACK_VIEW_RENDER_STATE] [SD;Dark].| kit/Kit.cpp:1158 [ kitbroker_001 ] TRC Document::ViewCallback [5] [LOK_CALLBACK_APPLICATION_BACKGROUND_COLOR] [1c1c1c].| kit/Kit.cpp:1158 [ kitbroker_001 ] TRC Document::ViewCallback end.| kit/Kit.cpp:1214 [ kitbroker_001 ] TRC Document::ViewCallback [5] [LOK_CALLBACK_VIEW_RENDER_STATE] [SD;Dark].| kit/Kit.cpp:1158 [ kitbroker_001 ] TRC Document::ViewCallback [5] [LOK_CALLBACK_APPLICATION_BACKGROUND_COLOR] [1c1c1c].| kit/Kit.cpp:1158 [ kitbroker_001 ] TRC Document::ViewCallback end.| kit/Kit.cpp:1214 [ kitbroker_001 ] TRC Document::ViewCallback [4] [LOK_CALLBACK_INVALIDATE_TILES] [EMPTY, 1, 0].| kit/Kit.cpp:1158 [ kitbroker_001 ] TRC Removing smaller invalidation: EMPTY, 1, 0 -> 0 0 2147483647 2147483647 1 0| kit/KitQueue.cpp:231 [ kitbroker_001 ] TRC Document::ViewCallback end.| kit/Kit.cpp:1214 ... [ docbroker_001 ] TRC Removing invalidated tiles: part: 1, mode: 0, x: 0, y: 0, width: 2147483647, height: 2147483647, viewid: 1000| wsd/TileCache.cpp:282 ... [ docbroker_001 ] TRC TileCombined request for nviewid=1000 part=1 width=256 height=256 tileposx=0,3840,7680,11520,15360,19200,0,3840,7680,11520,15360,19200,0,3840,7680,11520,15360,19200,0,3840,7680,11520,15360,19200 tileposy=314880,314880,314880,314880,314880,314880,318720,318720,318720,318720,318720,318720,322560,322560,322560,322560,322560,322560,326400,326400,326400,326400,326400,326400 tilewidth=3840 tileheight=3840 ver=-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 oldwid=1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 from wsd| wsd/DocumentBroker.cpp:4371 It makes big performance impact. Recently this code was reworked in 77ae7611fb2a670bb567718ce2cd3c4cc2fd9660 Signed-off-by: Szymon Kłos <[email protected]> Change-Id: I4d295c526638ab199d50f284d962da411f18b7b4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181860 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Michael Meeks <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> (cherry picked from commit f4817fdfe0861bef2f71e7ae5dfd309573714761) diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx index 99019917cd5b..4817f793f037 100644 --- a/sc/source/ui/app/scmod.cxx +++ b/sc/source/ui/app/scmod.cxx @@ -238,7 +238,7 @@ void ScModule::ConfigurationChanged(utl::ConfigurationBroadcaster* p, Configurat } // if nothing changed, and the hint was OnlyCurrentDocumentColorScheme we can skip invalidate - const bool bSkipInvalidate = bUnchanged && eHints == ConfigurationHints::OnlyCurrentDocumentColorScheme; + const bool bSkipInvalidate = bKit ||(bUnchanged && eHints == ConfigurationHints::OnlyCurrentDocumentColorScheme); if (!bSkipInvalidate) { pViewSh->PaintGrid(); commit 7bf674d926c22aa81a4d4404dd513a6d71c5b2ee Author: Ashod Nakashian <[email protected]> AuthorDate: Sat Feb 22 08:42:58 2025 -0500 Commit: Caolán McNamara <[email protected]> CommitDate: Thu Feb 27 09:07:09 2025 +0000 lok: handle saveas as export SaveAs saves the document to a new path. In the jail, this is unhelpful, since we upload the document after saving from a specific path. Instead, we do SaveACopy, or export, which saves the given document as a copy, retaining the original path for subsequent saves. This fixes a serious issue where after hitting Ctrl+Shift+S, the document would no longer store any further changes (in fact, it was saving the changes to a different path, which was not used for uploading). Signed-off-by: Ashod Nakashian <[email protected]> Change-Id: I6ba72df6a0a908d181786c02cb7c060177cd0302 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182071 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Caolán McNamara <[email protected]> (cherry picked from commit fcf4dd4f09018874ad25a035815f46705db0740a) diff --git a/sfx2/source/doc/guisaveas.cxx b/sfx2/source/doc/guisaveas.cxx index adfc6c8345fa..78074c4bedab 100644 --- a/sfx2/source/doc/guisaveas.cxx +++ b/sfx2/source/doc/guisaveas.cxx @@ -1789,8 +1789,12 @@ bool SfxStoringHelper::FinishGUIStoreModel(::comphelper::SequenceAsHashMap::cons aArgsSequence = aModelData.GetMediaDescr().getAsConstPropertyValueList(); // store the document and handle it's docinfo - - DocumentSettingsGuard aSettingsGuard( aModelData.GetModel(), aModelData.IsRecommendReadOnly(), nStoreMode & EXPORT_REQUESTED ); + // Restore when exporting (which is also done when LoKit is enable, see below). + const bool bRestore + = (nStoreMode & EXPORT_REQUESTED) + || ((nStoreMode & SAVEAS_REQUESTED) && comphelper::LibreOfficeKit::isActive()); + DocumentSettingsGuard aSettingsGuard(aModelData.GetModel(), aModelData.IsRecommendReadOnly(), + bRestore); // Treat attempted PDF export like a print: update document print statistics if ((nStoreMode & PDFEXPORT_REQUESTED) && SfxViewShell::Current()) @@ -1886,7 +1890,10 @@ bool SfxStoringHelper::FinishGUIStoreModel(::comphelper::SequenceAsHashMap::cons try { #endif - if ( nStoreMode & EXPORT_REQUESTED ) + // SaveAs in LoKit is unhelpful. It saves the document to a new path, which + // breaks the link with the storage, so new modifications can't be uploaded. + if ((nStoreMode & EXPORT_REQUESTED) + || ((nStoreMode & SAVEAS_REQUESTED) && comphelper::LibreOfficeKit::isActive())) aModelData.GetStorable()->storeToURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aArgsSequence ); else aModelData.GetStorable()->storeAsURL( aURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aArgsSequence ); commit 0d6eefe77ed1b1ac9798f3ad9a215892cce33409 Author: Ashod Nakashian <[email protected]> AuthorDate: Sun Feb 23 09:06:31 2025 -0500 Commit: Caolán McNamara <[email protected]> CommitDate: Thu Feb 27 09:07:04 2025 +0000 sc: filter: check for null Brush The likely cause of the this crash: /opt/collaboraoffice/program/libmergedlo.so(SvxBrushItem::GetGraphicObject(rtl::OUString const&) const+0x25)[0x7faf881f90e5] /opt/collaboraoffice/program/libmergedlo.so(SvxBrushItem::GetGraphic(rtl::OUString const&) const+0xd)[0x7faf881f964d] /opt/collaboraoffice/program/libscfiltlo.so(+0x1b1dbe)[0x7faf7a32fdbe] /opt/collaboraoffice/program/libscfiltlo.so(+0x107371)[0x7faf7a285371] This was fixed by identifying all the GetGraphic() calls on a pointer. This turned out to be the only unprotected one in sc/source/filter, where the stack shows. Signed-off-by: Ashod Nakashian <[email protected]> Change-Id: I64175e838423dfeaa4f93762c4894a99236a2ece Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182073 Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> (cherry picked from commit 3e146b4c8dcc15bb12ef036162090a0301d6aadf) diff --git a/sc/source/filter/excel/xepage.cxx b/sc/source/filter/excel/xepage.cxx index 28779bd209a1..06af615d0e56 100644 --- a/sc/source/filter/excel/xepage.cxx +++ b/sc/source/filter/excel/xepage.cxx @@ -489,8 +489,9 @@ void XclExpPageSettings::SaveXml( XclExpXmlStream& rStrm ) XclExpImgData* XclExpPageSettings::getGraphicExport() { - if( const Graphic* pGraphic = maData.mxBrushItem->GetGraphic() ) - return new XclExpImgData( *pGraphic, EXC_ID8_IMGDATA ); + if( maData.mxBrushItem ) + if( const Graphic* pGraphic = maData.mxBrushItem->GetGraphic() ) + return new XclExpImgData( *pGraphic, EXC_ID8_IMGDATA ); return nullptr; } commit ca4e0b62bd814ff1d4f2e707ff658dd4a63cb728 Author: Ashod Nakashian <[email protected]> AuthorDate: Sun Feb 23 08:24:25 2025 -0500 Commit: Caolán McNamara <[email protected]> CommitDate: Thu Feb 27 09:06:58 2025 +0000 chart2: protect against null chart objects in ReferenceSizeProvider The likely cause of this crash: /opt/collaboraoffice/program/../program/libchartcorelo.so(chart::ReferenceSizeProvider::getAutoResizeState(rtl::Reference<chart::ChartModel> const&)+0x87)[0x7f98773> /opt/collaboraoffice/program/../program/libchartcorelo.so(chart::ReferenceSizeProvider::ReferenceSizeProvider(com::sun::star::awt::Size, rtl::Reference<chart::ChartModel> const&)+0x2c)[0x7> /opt/collaboraoffice/program/../program/libchartcontrollerlo.so(+0x1fc3ae)[0x7f98769e43ae] /opt/collaboraoffice/program/../program/libchartcontrollerlo.so(+0x1fd3b8)[0x7f98769e53b8] Although it's not entirely clear that, if the given chart is null, a subsequent access wouldn't seg-fault. Signed-off-by: Ashod Nakashian <[email protected]> Change-Id: I16a39436c10adfca7f26e9304fd249efb0a53f8b Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182072 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> (cherry picked from commit 9aa52c452596db522cd9db616d98b03fe87c74d0) diff --git a/chart2/source/tools/ReferenceSizeProvider.cxx b/chart2/source/tools/ReferenceSizeProvider.cxx index 57c2015ad23b..6135724dca5d 100644 --- a/chart2/source/tools/ReferenceSizeProvider.cxx +++ b/chart2/source/tools/ReferenceSizeProvider.cxx @@ -224,7 +224,8 @@ ReferenceSizeProvider::AutoResizeState ReferenceSizeProvider::getAutoResizeState // Main Title if( xChartDoc.is()) impl_getAutoResizeFromTitled( xChartDoc, eResult ); - if( eResult == AUTO_RESIZE_AMBIGUOUS ) + if (eResult == AUTO_RESIZE_AMBIGUOUS + || eResult == AUTO_RESIZE_UNKNOWN) // Unknown when xChartDoc is null. return eResult; // diagram is needed by the rest of the objects commit 4cfdab5a57d8c512fa6c3f744cfdfcd98b10b018 Author: Pranam Lashkari <[email protected]> AuthorDate: Wed Feb 26 21:55:40 2025 +0530 Commit: Caolán McNamara <[email protected]> CommitDate: Thu Feb 27 09:06:42 2025 +0000 sc comment kit: use iso format dates Change-Id: I84d83005287869cea44f27c1d5a337bd67975bab Reviewed-on: https://gerrit.libreoffice.org/c/core/+/182243 Tested-by: Caolán McNamara <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Jenkins CollaboraOffice <[email protected]> diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx index 84c0409d1f45..6efbd607a7b1 100644 --- a/sc/source/filter/xml/xmlcelli.cxx +++ b/sc/source/filter/xml/xmlcelli.cxx @@ -930,18 +930,26 @@ void ScXMLTableRowCellContext::SetAnnotation(const ScAddress& rPos) double fDate; if (rXMLImport.GetMM100UnitConverter().convertDateTime(fDate, mxAnnotationData->maCreateDate)) { - SvNumberFormatter* pNumForm = pDoc->GetFormatTable(); - - // Date string is in format ISO 8601 inside <dc:date> - // i.e: 2024-08-14 or 2024-08-14T23:55:06 or 20240814T235506 - // Time always has prefix 'T' - sal_uInt32 nfIndex = pNumForm->GetFormatIndex( - mxAnnotationData->maCreateDate.indexOf('T') > -1 ? NF_DATETIME_SYS_DDMMYYYY_HHMMSS - : NF_DATE_SYS_DDMMYYYY, - LANGUAGE_SYSTEM); OUString aDate; - const Color* pColor = nullptr; - pNumForm->GetOutputString( fDate, nfIndex, aDate, &pColor ); + if (comphelper::LibreOfficeKit::isActive()) + { + //online handles the date format itself in browser + aDate = mxAnnotationData->maCreateDate; + } + else + { + SvNumberFormatter* pNumForm = pDoc->GetFormatTable(); + + // Date string is in format ISO 8601 inside <dc:date> + // i.e: 2024-08-14 or 2024-08-14T23:55:06 or 20240814T235506 + // Time always has prefix 'T' + sal_uInt32 nfIndex = pNumForm->GetFormatIndex( + mxAnnotationData->maCreateDate.indexOf('T') > -1 ? NF_DATETIME_SYS_DDMMYYYY_HHMMSS + : NF_DATE_SYS_DDMMYYYY, + LANGUAGE_SYSTEM); + const Color* pColor = nullptr; + pNumForm->GetOutputString( fDate, nfIndex, aDate, &pColor ); + } pNote->SetDate( aDate ); } pNote->SetAuthor( mxAnnotationData->maAuthor ); commit 913bf1b633d111c5b00077e92267cb4eddfdcda0 Author: Attila Szűcs <[email protected]> AuthorDate: Thu Feb 13 18:01:49 2025 +0100 Commit: Caolán McNamara <[email protected]> CommitDate: Thu Feb 27 09:05:36 2025 +0000 FillApi: fixed JSON validity issues Changed extract to always extract a valid JSON file. Extract changed in 2 place: At charts: old format: "DataValues": [ "Row.0": [ "22", "24"], "Row.1": [ "18", "16"], "Row.2": [ "32", "32"], "Row.3": [ "25", "23"] ] New: "DataValues": [ [ "22", "24"], [ "18", "16"], [ "32", "32"], [ "25", "23"] ] At Slides the following arrays changed to objects: "MasterSlides" [ -> "MasterSlides" { "Slides" [ -> "Slides" { "Objects" [ -> "Texts" { "Texts" [ -> "Texts" { Change-Id: I18180db714c0d0701380376a72e608cb080b67cd --- Transform will still accept the old not valid JSON files also, But for now, they will also accept a bit different JSON format file that is valid JSON. "Transforms" now can be an array and all of its element an object old: "Transforms": { "Charts.ByEmbedIndex.0": { new: "Transforms": [ { "Charts.ByEmbedIndex.0": { The same chanes was at : "Charts.????" "UserDefinedProperties" //at Document Properties --- These changes was needed only becsuse of 2 JSON rule: 1: Arrays can not conatin propertyes. (only values, and objects are allower) 2: Objects cannot have 2 property with the same name. Also updated unit tests. Change-Id: I70311b1c6da57305dc1d9e8ec1f29ab5aa93ee56 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181934 Tested-by: Jenkins Reviewed-by: Miklos Vajna <[email protected]> diff --git a/sd/qa/unit/uiimpress.cxx b/sd/qa/unit/uiimpress.cxx index f0613c45a223..1b15ae494c24 100644 --- a/sd/qa/unit/uiimpress.cxx +++ b/sd/qa/unit/uiimpress.cxx @@ -216,61 +216,61 @@ CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testDocumentStructureTransformExtractSlide pXPresDocument->getCommandValues(aJsonWriter, aCommand); OString aExpectedStr - = "{ \"DocStructure\": { \"SlideCount\": 7, \"MasterSlideCount\": 8, \"MasterSlides\": [ " + = "{ \"DocStructure\": { \"SlideCount\": 7, \"MasterSlideCount\": 8, \"MasterSlides\": { " "\"MasterSlide 0\": { \"Name\": \"Topic_Separator_Purple\"}, \"MasterSlide 1\": { " "\"Name\": \"Content_sidebar_White\"}, \"MasterSlide 2\": { \"Name\": \"Topic Separator " "white\"}, \"MasterSlide 3\": { \"Name\": \"Content_sidebar_White_\"}, \"MasterSlide " "4\": { \"Name\": \"Topic_Separator_Purple_\"}, \"MasterSlide 5\": { \"Name\": " "\"Content_White_Purple_Sidebar\"}, \"MasterSlide 6\": { \"Name\": \"Default 1\"}, " - "\"MasterSlide 7\": { \"Name\": \"Default 1_\"}], \"Slides\": [ \"Slide 0\": { " + "\"MasterSlide 7\": { \"Name\": \"Default 1_\"}}, \"Slides\": { \"Slide 0\": { " "\"SlideName\": \"Slide3-Renamed\", \"MasterSlideName\": " "\"Content_White_Purple_Sidebar\", \"LayoutId\": 3, \"LayoutName\": " - "\"AUTOLAYOUT_TITLE_2CONTENT\", \"ObjectCount\": 4, \"Objects\": [ \"Objects 0\": { " - "\"TextCount\": 1, \"Texts\": [ \"Text 0\": { \"ParaCount\": 1, \"Paragraphs\": [ " - "\"Friendly Open Source Project\"]}]}, \"Objects 1\": { }, \"Objects 2\": { " - "\"TextCount\": 1, \"Texts\": [ \"Text 0\": { \"ParaCount\": 9, \"Paragraphs\": [ \"Real " + "\"AUTOLAYOUT_TITLE_2CONTENT\", \"ObjectCount\": 4, \"Objects\": { \"Objects 0\": { " + "\"TextCount\": 1, \"Texts\": { \"Text 0\": { \"ParaCount\": 1, \"Paragraphs\": [ " + "\"Friendly Open Source Project\"]}}}, \"Objects 1\": { }, \"Objects 2\": { " + "\"TextCount\": 1, \"Texts\": { \"Text 0\": { \"ParaCount\": 9, \"Paragraphs\": [ \"Real " "Open Source\", \"100% open-source code\", \"Built with LibreOffice technology\", " "\"Built with Free Software technology stacks: primarily C++\", \"Runs best on Linux\", " "\"Open Development\", \"Anyone can contribute & participate\", \"Follow commits and " - "tickets\", \"Public community calls - forum has details\"]}]}, \"Objects 3\": { " - "\"TextCount\": 1, \"Texts\": [ \"Text 0\": { \"ParaCount\": 5, \"Paragraphs\": [ " + "tickets\", \"Public community calls - forum has details\"]}}}, \"Objects 3\": { " + "\"TextCount\": 1, \"Texts\": { \"Text 0\": { \"ParaCount\": 5, \"Paragraphs\": [ " "\"Focus:\", \"a non-renewable resource.\", \"Office Productivity & Documents\", " "\"Excited about migrating your\u0001documents\", \"Grateful to our partners for " - "solving\u0001other problems.\"]}]}]}, \"Slide 1\": { \"SlideName\": \"Slide 2\", " + "solving\u0001other problems.\"]}}}}}, \"Slide 1\": { \"SlideName\": \"Slide 2\", " "\"MasterSlideName\": \"Topic_Separator_Purple\", \"LayoutId\": 3, \"LayoutName\": " - "\"AUTOLAYOUT_TITLE_2CONTENT\", \"ObjectCount\": 1, \"Objects\": [ \"Objects 0\": { " - "\"TextCount\": 1, \"Texts\": [ \"Text 0\": { \"ParaCount\": 3, \"Paragraphs\": [ " - "\"Collabora Online\", \"\", \"Powerful Online Collaboration\"]}]}]}, \"Slide 2\": { " + "\"AUTOLAYOUT_TITLE_2CONTENT\", \"ObjectCount\": 1, \"Objects\": { \"Objects 0\": { " + "\"TextCount\": 1, \"Texts\": { \"Text 0\": { \"ParaCount\": 3, \"Paragraphs\": [ " + "\"Collabora Online\", \"\", \"Powerful Online Collaboration\"]}}}}}, \"Slide 2\": { " "\"SlideName\": \"Slide1-Duplicated\", \"MasterSlideName\": \"Topic_Separator_Purple\", " "\"LayoutId\": 3, \"LayoutName\": \"AUTOLAYOUT_TITLE_2CONTENT\", \"ObjectCount\": 1, " - "\"Objects\": [ \"Objects 0\": { \"TextCount\": 1, \"Texts\": [ \"Text 0\": { " + "\"Objects\": { \"Objects 0\": { \"TextCount\": 1, \"Texts\": { \"Text 0\": { " "\"ParaCount\": 3, \"Paragraphs\": [ \"Collabora Online\", \"\", \"Powerful Online " - "Collaboration\"]}]}]}, \"Slide 3\": { \"SlideName\": \"SlideInserted-1\", " + "Collaboration\"]}}}}}, \"Slide 3\": { \"SlideName\": \"SlideInserted-1\", " "\"MasterSlideName\": \"Content_sidebar_White\", \"LayoutId\": 18, \"LayoutName\": " - "\"AUTOLAYOUT_TITLE_4CONTENT\", \"ObjectCount\": 5, \"Objects\": [ \"Objects 0\": { " - "\"TextCount\": 1, \"Texts\": [ \"Text 0\": { \"ParaCount\": 1, \"Paragraphs\": [ " - "\"Click to add Title\"]}]}, \"Objects 1\": { \"TextCount\": 1, \"Texts\": [ \"Text 0\": " - "{ \"ParaCount\": 1, \"Paragraphs\": [ \"Click to add Text\"]}]}, \"Objects 2\": { " - "\"TextCount\": 1, \"Texts\": [ \"Text 0\": { \"ParaCount\": 1, \"Paragraphs\": [ " - "\"Click to add Text\"]}]}, \"Objects 3\": { \"TextCount\": 1, \"Texts\": [ \"Text 0\": " - "{ \"ParaCount\": 1, \"Paragraphs\": [ \"Click to add Text\"]}]}, \"Objects 4\": { " - "\"TextCount\": 1, \"Texts\": [ \"Text 0\": { \"ParaCount\": 1, \"Paragraphs\": [ " - "\"Click to add Text\"]}]}]}, \"Slide 4\": { \"SlideName\": \"Slide 6\", " + "\"AUTOLAYOUT_TITLE_4CONTENT\", \"ObjectCount\": 5, \"Objects\": { \"Objects 0\": { " + "\"TextCount\": 1, \"Texts\": { \"Text 0\": { \"ParaCount\": 1, \"Paragraphs\": [ " + "\"Click to add Title\"]}}}, \"Objects 1\": { \"TextCount\": 1, \"Texts\": { \"Text 0\": " + "{ \"ParaCount\": 1, \"Paragraphs\": [ \"Click to add Text\"]}}}, \"Objects 2\": { " + "\"TextCount\": 1, \"Texts\": { \"Text 0\": { \"ParaCount\": 1, \"Paragraphs\": [ " + "\"Click to add Text\"]}}}, \"Objects 3\": { \"TextCount\": 1, \"Texts\": { \"Text 0\": " + "{ \"ParaCount\": 1, \"Paragraphs\": [ \"Click to add Text\"]}}}, \"Objects 4\": { " + "\"TextCount\": 1, \"Texts\": { \"Text 0\": { \"ParaCount\": 1, \"Paragraphs\": [ " + "\"Click to add Text\"]}}}}}, \"Slide 4\": { \"SlideName\": \"Slide 6\", " "\"MasterSlideName\": \"Topic_Separator_Purple\", \"LayoutId\": 3, \"LayoutName\": " - "\"AUTOLAYOUT_TITLE_2CONTENT\", \"ObjectCount\": 1, \"Objects\": [ \"Objects 0\": { " - "\"TextCount\": 1, \"Texts\": [ \"Text 0\": { \"ParaCount\": 1, \"Paragraphs\": [ \"With " - "thanks to our Partners, Customers & Community !\"]}]}]}, \"Slide 5\": { \"SlideName\": " + "\"AUTOLAYOUT_TITLE_2CONTENT\", \"ObjectCount\": 1, \"Objects\": { \"Objects 0\": { " + "\"TextCount\": 1, \"Texts\": { \"Text 0\": { \"ParaCount\": 1, \"Paragraphs\": [ \"With " + "thanks to our Partners, Customers & Community !\"]}}}}}, \"Slide 5\": { \"SlideName\": " "\"SlideInserted-Name\", \"MasterSlideName\": \"Topic Separator white\", \"LayoutId\": " - "3, \"LayoutName\": \"AUTOLAYOUT_TITLE_2CONTENT\", \"ObjectCount\": 3, \"Objects\": [ " - "\"Objects 0\": { \"TextCount\": 1, \"Texts\": [ \"Text 0\": { \"ParaCount\": 1, " - "\"Paragraphs\": [ \"first\"]}]}, \"Objects 1\": { \"TextCount\": 1, \"Texts\": [ \"Text " - "0\": { \"ParaCount\": 1, \"Paragraphs\": [ \"second\"]}]}, \"Objects 2\": { " - "\"TextCount\": 1, \"Texts\": [ \"Text 0\": { \"ParaCount\": 1, \"Paragraphs\": [ " - "\"third\"]}]}]}, \"Slide 6\": { \"SlideName\": \"Slide 7\", \"MasterSlideName\": " + "3, \"LayoutName\": \"AUTOLAYOUT_TITLE_2CONTENT\", \"ObjectCount\": 3, \"Objects\": { " + "\"Objects 0\": { \"TextCount\": 1, \"Texts\": { \"Text 0\": { \"ParaCount\": 1, " + "\"Paragraphs\": [ \"first\"]}}}, \"Objects 1\": { \"TextCount\": 1, \"Texts\": { \"Text " + "0\": { \"ParaCount\": 1, \"Paragraphs\": [ \"second\"]}}}, \"Objects 2\": { " + "\"TextCount\": 1, \"Texts\": { \"Text 0\": { \"ParaCount\": 1, \"Paragraphs\": [ " + "\"third\"]}}}}}, \"Slide 6\": { \"SlideName\": \"Slide 7\", \"MasterSlideName\": " "\"Topic_Separator_Purple\", \"LayoutId\": 3, \"LayoutName\": " - "\"AUTOLAYOUT_TITLE_2CONTENT\", \"ObjectCount\": 1, \"Objects\": [ \"Objects 0\": { " - "\"TextCount\": 1, \"Texts\": [ \"Text 0\": { \"ParaCount\": 3, \"Paragraphs\": [ " - "\"Collabora Online\", \"\", \"Powerful Online Collaboration\"]}]}]}]}}"_ostr; + "\"AUTOLAYOUT_TITLE_2CONTENT\", \"ObjectCount\": 1, \"Objects\": { \"Objects 0\": { " + "\"TextCount\": 1, \"Texts\": { \"Text 0\": { \"ParaCount\": 3, \"Paragraphs\": [ " + "\"Collabora Online\", \"\", \"Powerful Online Collaboration\"]}}}}}}}}"_ostr; CPPUNIT_ASSERT_EQUAL(aExpectedStr, aJsonWriter.finishAndGetAsOString()); } diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx index b4de36be2f33..91d113f75b33 100644 --- a/sd/source/ui/unoidl/unomodel.cxx +++ b/sd/source/ui/unoidl/unomodel.cxx @@ -1475,7 +1475,7 @@ void GetDocStructureSlides(::tools::JsonWriter& rJsonWriter, SdXImpressDocument* // write data of every master slide if (nMasterPageCount > 0) { - auto aMasterPagesNode = rJsonWriter.startArray("MasterSlides"); + auto aMasterPagesNode = rJsonWriter.startNode("MasterSlides"); for (int nMPId = 0; nMPId < nMasterPageCount; nMPId++) { auto aMasterPageNode = rJsonWriter.startNode("MasterSlide " + std::to_string(nMPId)); @@ -1488,7 +1488,7 @@ void GetDocStructureSlides(::tools::JsonWriter& rJsonWriter, SdXImpressDocument* // write data of every slide if (nPageCount > 0) { - auto aPagesNode = rJsonWriter.startArray("Slides"); + auto aPagesNode = rJsonWriter.startNode("Slides"); for (int nPId = 0; nPId < nPageCount; nPId++) { auto aPageNode = rJsonWriter.startNode("Slide " + std::to_string(nPId)); @@ -1517,7 +1517,7 @@ void GetDocStructureSlides(::tools::JsonWriter& rJsonWriter, SdXImpressDocument* if (nObjCount > 0) { - auto aObjectsNode = rJsonWriter.startArray("Objects"); + auto aObjectsNode = rJsonWriter.startNode("Objects"); for (int nOId = 0; nOId < nObjCount; nOId++) { auto aObjectNode = rJsonWriter.startNode("Objects " + std::to_string(nOId)); @@ -1529,7 +1529,7 @@ void GetDocStructureSlides(::tools::JsonWriter& rJsonWriter, SdXImpressDocument* rJsonWriter.put("TextCount", nTextCount); if (nTextCount > 0) { - auto aTextsNode = rJsonWriter.startArray("Texts"); + auto aTextsNode = rJsonWriter.startNode("Texts"); for (int nTId = 0; nTId < nTextCount; nTId++) { auto aTextNode diff --git a/sw/qa/uibase/shells/shells.cxx b/sw/qa/uibase/shells/shells.cxx index 218cf47ff11b..999a1aa54109 100644 --- a/sw/qa/uibase/shells/shells.cxx +++ b/sw/qa/uibase/shells/shells.cxx @@ -587,34 +587,33 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureTransformChart) createSwDoc("docStructureChartExampleOriginal.odt"); OString aJson = R"json( { - "Transforms": { - "Charts.ByEmbedIndex.0": { - "modifyrow.1": [ 19, 15 ], - "datayx.3.1": 37, - "deleterow.0": "", - "deleterow.1": "", - "insertrow.0": [ 15, 17 ], - "setrowdesc.0": "Paul", - "insertrow.2": [ 19, 22 ], - "setrowdesc.2": "Barbara", - "insertrow.4": [ 29, 27 ], - "setrowdesc.4": "Elizabeth", - "insertrow.5": [ 14, 26 ], - "setrowdesc.5": "William", - "insertcolumn.1": [ 1,2,3,4,5,6 ], - "insertcolumn.0": [ 2,1,2,1,2,1 ], - "insertcolumn.4": [ 7,7,7,7,7,7 ], - "setcolumndesc.4": "c4", - "setcolumndesc.0": "c0", - "setcolumndesc.2": "c2" - }, - "Charts.BySubTitle.Subtitle2": { + "Transforms": [ + {"Charts.ByEmbedIndex.0": [ + {"modifyrow.1": [ 19, 15 ]}, + {"datayx.3.1": 37}, + {"deleterow.0": ""}, + {"deleterow.1": ""}, + {"insertrow.0": [ 15, 17 ]}, + {"setrowdesc.0": "Paul"}, + {"insertrow.2": [ 19, 22 ]}, + {"setrowdesc.2": "Barbara"}, + {"insertrow.4": [ 29, 27 ]}, + {"setrowdesc.4": "Elizabeth"}, + {"insertrow.5": [ 14, 26 ]}, + {"setrowdesc.5": "William"}, + {"insertcolumn.1": [ 1,2,3,4,5,6 ]}, + {"insertcolumn.0": [ 2,1,2,1,2,1 ]}, + {"insertcolumn.4": [ 7,7,7,7,7,7 ]}, + {"setcolumndesc.4": "c4"}, + {"setcolumndesc.0": "c0"}, + {"setcolumndesc.2": "c2"} + ]}, + {"Charts.BySubTitle.Subtitle2": { "deletecolumn.3": "" - }, - "Charts.ByEmbedName.Object3": { - "resize": [ 12, 3 ], - "setrowdesc": - [ + }}, + {"Charts.ByEmbedName.Object3": [ + {"resize": [ 12, 3 ]}, + {"setrowdesc": [ "United Kingdom", "United States of America", "Canada", @@ -627,11 +626,11 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureTransformChart) "Italy", "France", "Egypt" - ], - "modifycolumn.0": [ 12, 9, 8, 5, 5, 4, 3, 3, 2, 2, 1, 1], - "resize": [ 12, 2 ] - }, - "Charts.ByTitle.Fixed issues": { + ]}, + {"modifycolumn.0": [ 12, 9, 8, 5, 5, 4, 3, 3, 2, 2, 1, 1]}, + {"resize": [ 12, 2 ]} + ]}, + {"Charts.ByTitle.Fixed issues": { "data": [ [ 3,1,2 ], [ 2,0,1 ], [ 3,2,0 ], @@ -652,8 +651,8 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureTransformChart) [ 2,2,2,1,2,3 ] ], "setrowdesc": ["2023.01",".02",".03",".04",".05",".06",".07",".08",".09",".10",".11",".12","2023.01",".02",".03",".04",".05",".06"], "setcolumndesc": ["Jennifer", "Charles", "Thomas", "Maria", "Lisa", "Daniel"] - } - } + }} + ] } )json"_ostr; @@ -760,14 +759,14 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureExtractChart) = "{ \"DocStructure\": { \"Charts.ByEmbedIndex.0\": { \"name\": \"Object1\", \"title\": " "\"Paid leave days\", \"subtitle\": \"Subtitle2\", \"RowDescriptions\": [ \"James\", " "\"Mary\", \"Patricia\", \"David\"], \"ColumnDescriptions\": [ \"2022\", \"2023\"], " - "\"DataValues\": [ \"Row.0\": [ \"22\", \"24\"], \"Row.1\": [ \"18\", \"16\"], " - "\"Row.2\": [ \"32\", \"32\"], \"Row.3\": [ \"25\", \"23\"]]}, " + "\"DataValues\": [ [ \"22\", \"24\"], [ \"18\", \"16\"], [ \"32\", \"32\"], " + "[ \"25\", \"23\"]]}, " "\"Charts.ByEmbedIndex.1\": { \"name\": \"Object2\", \"title\": \"Fixed issues\", " "\"subtitle\": \"Subtitle1\", \"RowDescriptions\": [ \"\"], \"ColumnDescriptions\": [ \" " - "\"], \"DataValues\": [ \"Row.0\": [ \"NaN\"]]}, \"Charts.ByEmbedIndex.2\": { \"name\": " + "\"], \"DataValues\": [ [ \"NaN\"]]}, \"Charts.ByEmbedIndex.2\": { \"name\": " "\"Object3\", \"title\": \"Employees from countries\", \"subtitle\": \"Subtitle3\", " "\"RowDescriptions\": [ \"\"], \"ColumnDescriptions\": [ \"Column 1\"], \"DataValues\": " - "[ \"Row.0\": [ \"NaN\"]]}}}"_ostr; + "[ [ \"NaN\"]]}}}"_ostr; CPPUNIT_ASSERT_EQUAL(aExpectedStr, aJsonWriter.finishAndGetAsOString()); } @@ -777,8 +776,8 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureDocProperties) createSwDoc("docStructureChartExampleOriginal.odt"); OString aJson = R"json( { - "Transforms": { - "DocumentProperties": { + "Transforms": [ + { "DocumentProperties": { "Author":"Author TxT", "Generator":"Generator TxT", "CreationDate":"2024-01-21T14:45:00", @@ -817,35 +816,35 @@ CPPUNIT_TEST_FIXTURE(SwUibaseShellsTest, testDocumentStructureDocProperties) "Rights":"Rights TxT", "Source":"Source TxT", "Type":"Type TxT", - "UserDefinedProperties":{ - "Add.NewPropName Str": { + "UserDefinedProperties": [ + {"Add.NewPropName Str": { "type": "string", "value": "this is a string" - }, - "Add.NewPropName Str": { + }}, + {"Add.NewPropName Str": { "type": "boolean", "value": false - }, - "Add.NewPropName Bool": { + }}, + {"Add.NewPropName Bool": { "type": "boolean", "value": true - }, - "Add.NewPropName Numb": { + }}, + {"Add.NewPropName Numb": { "type": "long", "value": 1245 - }, - "Add.NewPropName float": { + }}, + {"Add.NewPropName float": { "type": "float", "value": 12.45 - }, - "Add.NewPropName Double": { + }}, + {"Add.NewPropName Double": { "type": "double", "value": 124.578 - }, - "Delete": "NewPropName Double" - } - } - } + }}, + {"Delete": "NewPropName Double"} + ] + } } + ] } )json"_ostr; diff --git a/sw/source/uibase/shells/textsh1.cxx b/sw/source/uibase/shells/textsh1.cxx index 01eb735e2aa3..1042ff8bff42 100644 --- a/sw/source/uibase/shells/textsh1.cxx +++ b/sw/source/uibase/shells/textsh1.cxx @@ -2502,8 +2502,13 @@ void SwTextShell::Execute(SfxRequest &rReq) if (aItem.first == "Transforms") { // Handle all transformations - for (const auto& aItem2 : aItem.second) + for (const auto& aItem2Obj : aItem.second) { + // handle `"Transforms": { ` and `"Transforms": [` cases as well + // if an element is an object `{...}`, then get the first element of the object + const auto& aItem2 + = aItem2Obj.first == "" ? *aItem2Obj.second.ordered_begin() : aItem2Obj; + if (aItem2.first == "DocumentProperties") { uno::Reference<document::XDocumentPropertiesSupplier> @@ -2754,8 +2759,13 @@ void SwTextShell::Execute(SfxRequest &rReq) if (!xUserPropsAccess.is()) continue; - for (const auto& aItem4 : aItem3.second) + for (const auto& aItem4Obj : aItem3.second) { + // handle [{},{}...] case as well as {}...} + const auto& aItem4 = aItem4Obj.first == "" + ? *aItem4Obj.second.ordered_begin() + : aItem4Obj; + if (aItem4.first == "Delete") { std::string aPropName @@ -2971,8 +2981,13 @@ void SwTextShell::Execute(SfxRequest &rReq) } } - for (const auto& aItem3 : aItem2.second) + for (const auto& aItem3Obj : aItem2.second) { + //handle [] and {} cases + const auto& aItem3 = aItem3Obj.first == "" + ? *aItem3Obj.second.ordered_begin() + : aItem3Obj; + if (aItem3.first.starts_with("deletecolumn.") || aItem3.first.starts_with("deleterow.") || aItem3.first.starts_with("insertcolumn.") diff --git a/sw/source/uibase/uno/loktxdoc.cxx b/sw/source/uibase/uno/loktxdoc.cxx index 92108c9f6c22..2e2e6288b3a4 100644 --- a/sw/source/uibase/uno/loktxdoc.cxx +++ b/sw/source/uibase/uno/loktxdoc.cxx @@ -638,8 +638,7 @@ void GetDocStructureCharts(tools::JsonWriter& rJsonWriter, SwDocShell* /*pDocShe auto aDataValuesNode = rJsonWriter.startArray("DataValues"); for (int j = 0; j < aData.getLength(); j++) { - OString aRowNodeName("Row."_ostr + OString::number(j)); - auto aRowNode = rJsonWriter.startArray(aRowNodeName); + auto aRowNode = rJsonWriter.startAnonArray(); for (int k = 0; k < aData[j].getLength(); k++) { rJsonWriter.putSimpleValue(OUString::number(aData[j][k]));
