From 233286df08aeedb4e228fd523365b94543b16fca Mon Sep 17 00:00:00 2001 From: Balazs Varga Date: Tue, 13 Jul 2021 18:03:28 +0200 Subject: [PATCH] tdf#64086 tdf#143623 tdf#66250 XLSX: fix named ranges in charts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit tdf#64086: fix broken XLSX import of named ranges in charts Do not create inner data table in Calc for charts, if the data source contains named ranges. Use the named ranges (local sheet names and global names) to find the data source of charts, so it will be updated correctly if we modify the values in cells. Second part: tdf#143623: chart OOXML, offapi: export the named ranges in charts with the proper special (non-ooxml-standard) Excel syntax. We need to add "[0]" characters before a global named range for proper refreshing of chart data. Also we have to add the sheet name to the local named ranges even if it's on the same sheet, but only in case of charts. Because of this, add property RefConventionChartOOXML to com::sun::star::sheet::FormulaParser, which specifies that use special OOXML chart syntax in case of OOXML reference convention, when parsing a formula string. Third part: tdf#66250 ODF chart: export the reference of named ranges in case of charts, if the named range contains a valid reference. Note: maybe export the name of named ranges would be a nicer solution in the future. Follow-up of commit 3c766512984feff739377d0f0af46558ee7139fd "Related: tdf#64086 Add FormulaGrammar::isRefConventionOOXML()". Thanks to Eike Rathke for his help. Change-Id: I10d8563fb436092e833682f331c25b0c0829ef86 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118862 Tested-by: László Németh Reviewed-by: László Németh --- chart2/qa/extras/chart2export2.cxx | 17 ++++ .../data/xlsx/chart_with_name_range.xlsx | Bin 0 -> 14575 bytes offapi/com/sun/star/sheet/FormulaParser.idl | 10 +++ oox/source/export/chartexport.cxx | 2 + oox/source/token/properties.txt | 1 + sc/inc/compiler.hxx | 3 + sc/inc/tokenuno.hxx | 1 + sc/inc/unonames.hxx | 1 + sc/qa/uitest/chart/tdf64086.py | 31 +++++++ sc/qa/uitest/data/tdf64086.xlsx | Bin 0 -> 15670 bytes sc/source/core/tool/compiler.cxx | 27 +++++- sc/source/core/tool/reftokenhelper.cxx | 20 +++++ sc/source/ui/unoobj/chart2uno.cxx | 79 +++++++++++++++--- sc/source/ui/unoobj/tokenuno.cxx | 15 +++- 14 files changed, 192 insertions(+), 15 deletions(-) create mode 100644 chart2/qa/extras/data/xlsx/chart_with_name_range.xlsx create mode 100644 sc/qa/uitest/chart/tdf64086.py create mode 100644 sc/qa/uitest/data/tdf64086.xlsx diff --git a/chart2/qa/extras/chart2export2.cxx b/chart2/qa/extras/chart2export2.cxx index e05d984f75cf..adde208d620c 100644 --- a/chart2/qa/extras/chart2export2.cxx +++ b/chart2/qa/extras/chart2export2.cxx @@ -97,6 +97,7 @@ public: void testTdf138181(); void testCustomShapeText(); void testuserShapesXLSX(); + void testNameRangeXLSX(); CPPUNIT_TEST_SUITE(Chart2ExportTest2); CPPUNIT_TEST(testSetSeriesToSecondaryAxisXLSX); @@ -157,6 +158,7 @@ public: CPPUNIT_TEST(testTdf138181); CPPUNIT_TEST(testCustomShapeText); CPPUNIT_TEST(testuserShapesXLSX); + CPPUNIT_TEST(testNameRangeXLSX); CPPUNIT_TEST_SUITE_END(); }; @@ -1420,6 +1422,21 @@ void Chart2ExportTest2::testuserShapesXLSX() CPPUNIT_ASSERT(!xRange->getString().isEmpty()); } +void Chart2ExportTest2::testNameRangeXLSX() +{ + load(u"/chart2/qa/extras/data/xlsx/", "chart_with_name_range.xlsx"); + xmlDocUniquePtr pXmlDoc = parseExport("xl/charts/chart", "Calc Office Open XML"); + CPPUNIT_ASSERT(pXmlDoc); + // test the syntax of local range name on the the local sheet. + assertXPathContent(pXmlDoc, + "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser/c:cat/c:strRef/c:f", + "Sheet1!local_name_range"); + // test the syntax of a global range name. + assertXPathContent(pXmlDoc, + "/c:chartSpace/c:chart/c:plotArea/c:barChart/c:ser/c:val/c:numRef/c:f", + "[0]!series1"); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Chart2ExportTest2); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/chart2/qa/extras/data/xlsx/chart_with_name_range.xlsx b/chart2/qa/extras/data/xlsx/chart_with_name_range.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..2f2b814011fff6862b70c205b525e82251ede385 GIT binary patch literal 14575 zcmeHu1y@|zwlxHIcXxM};2}tG2@>3;DBLAD!QI`11oz+s2<{Tx3GOamb-M3OU;4iB z{ebt*7}PE}wI*ZjT5~Twin0)pm|)OguwY zodct**yS2Xe^wcDD^fFU5pFy^y$Dlnm}JG;&h!MbMwk($L`8(5G6->wz{@(=i`|_? zxF%GG)dv4gqNEu}Rx+drXo9HBY*bmI*d3(SWxmtw7^;-t)4TxFZ5I)OYst^234X@(o~~G2^Q#2IvokD0?33<2Nv2kgSpi~GEVo(Zx zFYkeQNS@T??~am5pXUOxQYYX^%Q6!IwY>Zx^IE;wpW(Za2yyUovg3B%s@uWM>8QbM z^3k4k5%I>zV&?SBhA=KWG&jso%#c0rz4AOxEfgQ&Z}-@<5=D^#9l`L(az`39yr`c& zbU$#9U6?`b!KU>+citd?fjvJ%fGPe5o$J(CDK0=Z`VPca1Q4C|>`km4SeXBK{XZK2 zFXrywR4{N|qTZ!EDCy4535K59K2g%HY^?{)dHQntD&?(=8?AF| z6n$x9agOZw6$;78Q;90nQResfa2N%ILD;WTe6@PzG?xu;zJO1QsT`IERW|Ts@5PO# z`OGF3{zMWE;d^&5k%HClU}!e~#k1dCpQAOskUmXP11OYLl}pGDAv(ErqodOr zBLa=g>cztfAFp+2kZK(#a3#vyy*!UvcYgHIq{Rwct6EUM@jHo$BBWaO0$yho>23_~qV((m7jHF2b_Y0mGeB@MMV{Mg2FfswIb9FZI>CwyWZM>rxLQ@ z6$xwoF!sl<|r{broQ z5<-`*bqZNTQOrnaw9KZ-HP3D2Ad9`oN2NXF zF3js-SALSHQy{D48#`)gKq#Pt$B<4{ShltR7f zdjZfb?m(9tBkt6cwMEXd3VZFhjNH8~4^=347($Km<=}PL+F8BRhQns@TxQP5x#XE{ z0}|vY^TXUvc3a{QxCQa+pUm?WicdNRF|HZpp76n7!9mRX(?k88 zfB*7U;Gm!r#NYqjSDCV$Y!54HE5cJSt4o?Q7TUZc3;BWCJ__vjTDk>lG7j&H6$1KZ z9gP`T76@RF+wpLp^EDUpIt0dLCqr>4I;1;>^|1gHaQJ)}0@m=boY?Oz6bAai-hSyJ z0&=PYMw3u%KVv2)@AeHX6<%;&A-Tjw(?k%bXS(&=B))J3o#p37GJcK+CoPEN1~$GsMaFQ``Q{4t?CXQ6oZE<1XWkv+7GbF@ zaS7LJ&mc$A;QqHHK6J4TTe&GMYR7AiV)p}d?F(m&gBQo9o8SAUS3uwNKTSp@FnAFb zWK6N3!x|U#iN6kO2Xhk>M+cT)3)>&3cKYvATmRNTfkF>JHyoQSriNr89#VZc@08w4 z9?7u)@U;*&Z8!0;o<)}Pbyg;`6x#Ff8fiK`m9uxJp|3TRanLN{y?7O_A!jnO|0cA3 z>0OjO>qO8L-)G}tWzSJgq2c9r*%{@fy;wGXu$&n><_HVJmDyTjKXV1{vLGq41XAdy zlE4arZ&F9pp9Z4*R_Aa6W*gsxOq1bO)AE{NNGJJC7eXnOkwahX$MU%QQ}2@5`V}vj zI7k$jgBgx6*c=hjO8WKUglW;US7aZxR4ULmtDJ#+m`-qagbm(=@1i!WW^=-f&<+MUB z3{qbam`RTq1On8gs>r`>unH0A3(Kbav^mtzC}hTvo#U0_av}1Hg%jsva>&p-TOet4 zYJknu7iP%1SrzGt7=j7@kgE|4z;83$Df7EvAv2#5CaUv-Hf%TYzWb`g<|Ns!Olt=ln|}$lWvgrMORUrO$Pi-=_cdZH_&f28Qbwr=|1h8Lym(OWYB^6Ukoq73^r#=Z#waY!8Bp6-X@Kt50k*!aJ&fn%O_mB5gAI*wHys~FEiygi?3E@+l!ltc%MfDQ)@o$PIq$E6K?&%j6|aQ=p&tjML6a? zIhCUY^!9w1x|GEePJo=@deV$e4-gNgb^?qv4u(l&6)AKcA5Mh2E@C8WRj&f~>maQ#>s#>Sz zH1~_oYBg6_T!A8)f3ip9dyTCch&jEaf28-n*yCt!0x)6u_4rT?7C22Bswge(E80>#Jn7{KINw;o%K}9ySv`0!hJtu#eDhsdk~@`G zaDY1s_k28${JQl0!hDn2O4rR}LZS?Zi=RW|w_z@Zdqf7zu(Dd-w;#S=+p-%P#lF*i zidf4YJ9$l}#4Z_6)wsn{dBUQ5bCY*&E-T5~OWaRmh*0++H88JUMJve~-owY;4fnup zASj7Wd|S)Ay^DL%TdP5rVEGLorC9rp zi#C^%?}KpyucMZFvP%}MY_otij8erSad0#N{As`a@-A#0lhO5WTT+4`| zMs~NiXUEDrLtHXL>10o7|0WAJP2kY-yV>y{I0m_$2pmSLcF{n1-b=1)f33`*AE zE_iuFy&1@jx!df5g6T9W*PEU;>t84wH&a`}&>1=&ZxMGB8daSstW(?~awT%<OE^bCihwQw46{# z=B4JaL-@l<3@w{Z(NkqHTU3#i-pK_Ylj1dnFY2AdeA-8Vi^((``1*v4uol}iV9+W# zRsq)C*xe?JQx&lpOW5pqMB4k#IEu)b0&_H-JC2gQDl0@>N@-KaXaZ`*Op#1%02r+Cl9#jfTF$EZ06}lXyTv^}Xu=_gqa2uc#nG zd`}2);wy|&gEEdhA5DU8L7q59pK$j7*7HwQ7s?&0{!~RZ**ibX3FR?n51z8Jg!X{yS`&ftbWo-ncAuyu-KV(B(PRHu~~!3f<|y;$e)jO>{RWgevUL zcon&Q9qhFzs`;RbvJx%rCt;vQ#RL<(V$W>U&PYjwLN+vJmkHX}AXOObL{n zaFz6s#V~bE19ay$`mHB2nH%ljrl2*xlCW>&!nh4ejRzI9IMuFkPdyC%Y zl;A0Lg(kx$0(*|Vh-);fH{>*pzSPtzV?6>kw{@1V4fGV8R<{_txZSg^&`lIm+Bmr? zjm~(|nKm~K28nn$)xi?+{2$`v2cX$vl0D*knDm%@5|B8@33CAq??0jnX>6p5Fp#9$ zp*jlmyRvsuSOhKMDrL%(_^zpZv3)A}wnAJ+IZxQtN)i#(3cd7#frHJ8GYJK=Ii>D zR|G^SD^u1GyPW1%`R>q~8l{C=6-HP@g(>bEfRiNe>(hD~;r@&vEhiDieVL4#yMe{8 z)21*DzJl(yKDITyGUG3V5RF03Fy(6gBv0ZEgh&k1T1KjFoW<)QQ#nAjb65EmAUfw#pEzm?^)8Znc>+M?Sh; zj)8_bwB#wiBnZ@MT3~{#i)C*gXPokvDIl6!i0~e3OG;p?Jc}1%*Zb&Er-SqKUkeTa zO9D?#pcwWD5ey9JPcQ7?=w@x=@T=VLekn4K8?&uq%0*<60~Z#Pyx+1LaYAOHWa3@H zGQU2$Rm7)o4yy7y)_X>;s!WL6G$N0N45|tJtf=!0y+N}x7bBW8K(Oq5oj3E7Xx~O}(^xj5+YsI$n(r(>8 zL>Q&-eaQitlVORVp7S?}d#6QQ>zg)NfCU&fh^v zh3r?@OABxxuQ13%g=+n9;a-2wRnAjsLiQ8 zxIInRiuQsY$h&kE3y)|*-NZ}7W4;-M0%;h#QirF9lS|M1ez+D z^_DFuiO7ub4JG{-*;#A-Q3 z50?4cb5uv3n4N)f4e{d%ZcEiLhQ@xLDjY~C_%5&c<1CTVwn$^nx-BPY7+LGir>Xuu zfmi)?S}Te*SDj16Yh@3bALMmA_-GExtP_kJTTFx2&WhdYP};}YUNuAqbPkev#Q}ZW zX@`(W1xVl73H(~ktK&M1zRSmUjxGYjc)7@x;!U|Vry8>Oiajc8N6F-t zXLBq`MRix}{Lt(nr>gHlLz|g_*m58EX-Np=GI`GDBx%x1$I6d&I)%xd^Qq}VpYAC&ZTy)b z>f7cpEr^wOqIFkvc46fu`h9EAgTlaGb+H0roN3o8vLceiNwEx>@cAgHJgL!_)%4oS zSjuTfsG1Kp6di1U&3E(|^iSi~ss9 zd@u+~`2E@@_x1tDDX%P1a^xIj*n_V8>2>w(VYOYR@%+kwX~TYyH1=|t;H&_w;{nVf ztOQ&(EP}4sTNDAW7I-24pp)*ON*{BW3=qL5HL1#A@(pM;_9RrJ!|s?9YC7U@Wo{-o z$GPWus%Fgx!~6jUfa}u%t6Y<|sA^LjrpfnlM1@c@mJF}WuMf-Ylb>=ph#ZSzT`Yb1 zF5PC4l7}4fim1cAN^1_!sUpq=W&MB1I?EN7n)x=!a7Q%AxcsCJzb>WJX%lPLy05># z1pwKQJ~q`%?yNyDP!A)12h=lXjGYI-FOfCIE3%B#xb0DD!>@k-WL6QF8kf$!t!*|V zmGf!hd6|5XB8T%^V`bt7wvVAdH6_f60>bN`Dh>}4a4M7P2<%!ZCc=bNkh!cBR7VSA zaCS~c4E+RniMjh#PF>;tz1)z)p`IGRG&66>Y2bgQP8MSH^8~2>Y>e}7>KK8j11j(Q zTK>#ZHFSU!T$o;O*M$)&md7|bQam}w3yU*qKkgo>FF;YEij9QFCA%MJE=(4N-5eA8 zP|8gt0&s}I#)GHY>W>#aJdZD{^gNqN+#KZ+OqJiQACN{+(93ADRVDYVw7!-_-jE_7 zr|&Arj=M?RyBW+=5O!0F9Hdg(t|p_3$d=f( zZdWyQQN(RnV2P8+F+G--mXstXoBCbZY-v$h(m5Z)Pt`<#T;QoX?Z7ASSMJ~OTW8cw zA*Nf4s!R)FwMK?T>GmVv*E_=xRC}9kOrwdEgyhWA9=@3kP*~?Y(jcQTT!R|qzP%G* zQLVixvvVD@F1$5Q$pMD2 z;hD|hsTR8yTN1>Ufxs95t|@OF(x>e0O=lRFr4Pk)srsy1R5*|y2-I%R9Bt**3-hfkMOH`1Ub_D%Cyth~5HzCnp86E0 zPO9;Ak9M9Qy9XuS9hg1E+}}S3u_1(!ots-tV7ykX8RDg3M*0rCaL%f|uf8ghY6Aau z#z2nrxeH(o%7lRyhhnR>llI3(_d!yl+LX*W~27Z ze^z1%J9aQb>?3P_M;T#_WgW(>vKnVGieyT{DAi@q2*AqQu_=GbILpiX%*`~zQCUJl zw6efi(g+@t6k}padpsF7>nuhwvLZ@fNjt3A3hRSF8UBsgq)}eK%i?>Y_>u6Bk6D4} zbh1-iIJ?(|>uz)d0dkeV?TX!3osLBC3LOQMHsbonLaZMW1D?sHK@w$WsJYCB4ZtD~O7SNSM-OHccsA(U8mEvNZRjF_hDR$nia z=&$wGLRon0CurU!ELm^X^png+BvCKrB*jkS=agkRd1$60cRw7)I7SzBTd&Tnsw^bn zocbKdtZk%no)MeO*+J*~vqr+Xi(69b#;SFASs8AP_!8}W-xGtL;Xd!BI2y6USfZMs zL{15qRIl$iPXEN96?ooCIJ^1&^K$js9u;od`y+W9m&}g%J{TlygJT|S*q&bPpTn-v z7ZUoEdEN~qZwshM9nxFOXOP0j4Z+VkarB`RgFO*p`iZx}f)zHvB4M?ET%vto#0!wP zqp_JF1R090{~V|7+Q4?|k~6w!=eKe4&j#*u#z{)a553 z?hVqC)GzZyS^qcB79p4bH2`P=%lD=;n8qX=e)cm#Lft+y{H3%A^kU`H*wKYI`!(p6|= z-n_o9g9a~4W=)z}eKcQ-?4qJ_#o~)YAEiHv2lo5RMgwmi*BnJe;pC_c0022}Y7U{?`<7nhBRJ9TZ%3QN8qmzcR%? zeV`TqxXz3E#1P{n0&!tZXG!m*UG9k9T7IS8JW6fX(GrH{Z z(Kj(Y4g)ma6_bazgPMv$NMDA@mAec+Y4k%{IgxGVCsP=(%I*v(ux|C|DSgyec632l z=w?y%%1cEPFnnP6v=*2I<`fNl!)8)OO=&pE8}8(BiL^+B|&93Y&aWyJKXEUrdA9EnL~BVCk{=Xc)xx@J_k1ZXILOfE!#w zEJIs@72gYb(8eOurp67LX&c-~4JX>Lm%<2!m3ee120(bA%(f&~vt?OdZMLS1en3U; z*ByX|ao!%Fv@@tcP89)LY-K_*AWb&-@Mun)d9O1qhhW9GT1FUons24!3?=4_3~eKj zRv=o_9nM9(#ssD_yF5jje-6v5sn z-;j^4cycj3SZ7XZrpx|{$O_RsNkJ{s?Hr77XLDJEbBAXoK3;)>0GK6FAgf4bnGoLl zEPdiGRlISJ`Bl+w-kK_zV>A2^<(3ZlpQ)!Qn8VGfSY@9NM#-7fJlJJv7)MqzvzM9&dA>Ro|?b5S?Uc+sL{2XuyCo2VY4YLT{fwH&49TIwJMmu}IFWTP=qE?%j6`|XK zuAVll=Fu>FQT_1xeEC%a%g2~ZR|f_f0&`_b8QqlQLhRJYlwb(>9!$o40{ksRSK{o z?=>J|Tzf?p*-uHJ=(M|-exy8>tjx$G?Awg!&v*sr^DMHLZZ5?xuMATgpFFT{S4wm2 zik!C3$pd7R0Qbg%`7pir;7EWRtfG0p-k1Zypp%NJ<1Zwx$>>k^-W53xn|rCau)YFwOE{&e062d ztP!JC04i1d*}`&t6Qi<_@9F26U-=AVFY6#Jc@(bIHW}}pf-8_+fc##Hi&v#9sz$Oo z*JmNqocE?8OjCJdZdmh&Jlea29WpmUB7Jti6_MJ2erO%DpPyAfYY_yQNT0r!kptd- z$vJInfy5MYN{Kl~asQI)u&e8n9JUi#5NdrKM4m{Zz4QobF8woIB*ZK#egwt(HlU&x z)}P7nzan~|HPGJS*Kw8~Cu#%AhTl}6--6kpla`Zr74C;Z(csEi8-BkcT_~{iNLMr$ zCqwTPxZiKT^`T@Le=n7~NKIHLg)F&nvuZUHR9VVqyfgv zk?!Zzpb+iR`)`wZGs>Atc3zW83gPXN#F1GFxb4ZSZY?X`SMYnEu4enYucA^NH&>49 z`2Xwak5y43*b3Sw2GCuKKlkg8iHN_N+<%Tp{BCvs8juKx8vdh}5OC~wjCy4=;f@+p zs4HCRR&f|RjI`|*G+JBkEOcbA>O+;6_0Ql4k#?5_`WIRof#{_be5_5X(5&<6g`+U(+8)LSfv6!j3uDF zpF3B4^Znyp7@fSjxZpgx1V`|}L)PJfGppmtHg}AyFk^hgP5&@Ey3t!{|M+8~_F(1h z{_H&&FSRl~kZ%997G#Nwm9L;XRKKDrqZ0|cjVRJ+o$-FT73}sq1#>FbP!3(n+veBPvm6mQA}8nvnzlz z;$JtoU_}2`9YiMSqZ~Rc!cpy*X>HGsV;XLO*m`DuG#B^7Y+f`_0Xkmqol*n7*wQv> z>bIiJXX{y~yqp@2s1)l5w49-jWYnZVnYqw(vq%-OgBOg&)rxvs13dp#`HuvPz7wE3 zQ6S|>Kr3jz;V-KEsrv5}_?O~k(Va4&d61w#zV>aK$pcXd?j?WH1GQNg*q^mXX~tde zQ17n_ajL@JMsajMdkH%TdKDB4#ZW2M>o*f)nkpFe*91ll?ssF*erAqhR+dCyfKLy) zZ`mM_e6KB)s3^fDgN-0tzNKk(iaB=c8O{mj2*vS*RO~f&<`PM)%zwUXUlL~A-V_&Ej+&NBO;MVo`ttZoN~&TR%ciV z6>Ybuhr0A`zyKm3JO-{e)h3&qzY@`))2W=^(E2kxBiti7)G9CH+s0SoxNMLOer*R> z<4UpPy2{)oj<3QEX>(o~a7OyUW;H>p7Cb+!MkAPh8y5YM66wrRhj-YK**g1`=E%84 zpU0NF>>0LwG)r%(SO^E8j;WZ*o{DQD)34&`{UganJxfGx_6Pw%5vpgZ1mdpi6(XnF z2mF>C_;%IACLpX8z*A|Kd#?d%APLsz*; zMmd1XLW6??g93`)A$u*z;8@ zL}ONJ!LDzb&EzFTViK)g@arK9kpcxMSg1t?be@{{5wp5LdPmA-)A_&-rW}S!-qL$t z3m&^4W6#J;Uu|x`-Fv?0FracMvqT7x2{lUgc$Jn0KfOsbd;iY6*vg6%)hgE}0$J!T zHa1E-LOs+#<%|hoDox+Kh@CFz^9S=v*KeGvaNN0=eSTj>&8af|;gr4y6(U)lk$u`0 z2osc!1EN+@3Cj||LKB{%F_p<8SCvyhIknhXRVv=sVIuB^2HS=Z^_u4P!hpfBylTkrf>9h4B|MGNG zyG_Q8ap+|3hcZ(APN6-yNt{ijd$Kv_{^^n})rYQ!d2=SumB(pIPqu*(4(FY0>Tjpd zYQiAP|MM^hf5imqfBg5yi~eN;|62dc!$yj-{|WG)4>bHs@Q-yA6kGo3B7Zr?mx3>c zynl;cfE>?@k?)tn|2e1nTND)0!v7Nf^B@0XYV{?~%i+b}NI9TZ@c%T*_!8yi5Z7;% z70}QZ2<7ES*Gqtx{pa5RCZLi#2;g@&`laa0w$^V^X@WmRUpBd3BD`!J{YIc6{DtuE zSnuyq-b<91J%ZmT0mQ#h{*_<+(Kz^(Uc5wjSz-B&5CW>XfHvVTgx~d+mk2Mjn%@ZO z^nXV%`kmvvgm@X~|Aq)+_yzI*3;SOJzKorJ0|qeu0{r*x{tuD#OTd@$=x;z@roSus zU!&8PVE-A-{e}Vqi)IG(dtSzNFU9}Ur~X}Bn(c4me|cC%Stt;*{|Fn=z&t@-ScmhE G-~J!%pNCxl literal 0 HcmV?d00001 diff --git a/offapi/com/sun/star/sheet/FormulaParser.idl b/offapi/com/sun/star/sheet/FormulaParser.idl index 2c1145ec1369..fb9085130341 100644 --- a/offapi/com/sun/star/sheet/FormulaParser.idl +++ b/offapi/com/sun/star/sheet/FormulaParser.idl @@ -81,6 +81,16 @@ service FormulaParser */ [property] sequence< ExternalLinkInfo > ExternalLinks; + + /** specifies that use special ooxml chart syntax in case of OOXML reference + convention, when parsing a formula string. + +

Special syntax like: [0]!GlobalNamedRange, LocalSheet!LocalNamedRange

+ + @since LibreOffice 7.3 + */ + [property] boolean RefConventionChartOOXML; + }; diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx index 2a0d335ca86b..dfebc8bf061a 100644 --- a/oox/source/export/chartexport.cxx +++ b/oox/source/export/chartexport.cxx @@ -710,6 +710,8 @@ OUString ChartExport::parseFormula( const OUString& rRange ) if( xParserProps.is() ) { xParserProps->setPropertyValue("FormulaConvention", uno::makeAny(css::sheet::AddressConvention::XL_OOX) ); + // For referencing named ranges correctly with special excel chart syntax. + xParserProps->setPropertyValue("RefConventionChartOOXML", uno::makeAny(true) ); } aResult = xParser->printFormula( aTokens, CellAddress( 0, 0, 0 ) ); } diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index b35a5bc3cd4a..808df85533ff 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -411,6 +411,7 @@ RangeYMaximum RangeYMinimum ReadOnly RefAngle +RefConventionChartOOXML RefR RefX RefY diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx index 17e258dc3805..8ae65a4eb8b3 100644 --- a/sc/inc/compiler.hxx +++ b/sc/inc/compiler.hxx @@ -297,6 +297,8 @@ private: ExtendedErrorDetection meExtendedErrorDetection; bool mbCloseBrackets; // whether to close open brackets automatically, default TRUE bool mbRewind; // whether symbol is to be rewound to some step during lexical analysis + bool mbRefConventionChartOOXML; // whether to use special ooxml chart syntax in case of OOXML reference convention, + // when parsing a formula string. [0]!GlobalNamedRange, LocalSheet!LocalNamedRange std::vector maExternalFiles; std::vector maTabNames; /// sheet names mangled for the current grammar for output @@ -426,6 +428,7 @@ public: */ void SetAutoCorrection( bool bVal ); void SetCloseBrackets( bool bVal ) { mbCloseBrackets = bVal; } + void SetRefConventionChartOOXML( bool bVal ) { mbRefConventionChartOOXML = bVal; } void SetRefConvention( const Convention *pConvP ); void SetRefConvention( const formula::FormulaGrammar::AddressConvention eConv ); diff --git a/sc/inc/tokenuno.hxx b/sc/inc/tokenuno.hxx index cded5065f6b2..d025ba0cf44d 100644 --- a/sc/inc/tokenuno.hxx +++ b/sc/inc/tokenuno.hxx @@ -62,6 +62,7 @@ private: bool mbEnglish; bool mbIgnoreSpaces; bool mbCompileFAP; + bool mbRefConventionChartOOXML; void SetCompilerFlags( ScCompiler& rCompiler ) const; diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx index c4e7a234f1a3..56936063f74c 100644 --- a/sc/inc/unonames.hxx +++ b/sc/inc/unonames.hxx @@ -674,6 +674,7 @@ #define SC_UNO_OPCODEMAP "OpCodeMap" #define SC_UNO_EXTERNALLINKS "ExternalLinks" #define SC_UNO_COMPILEFAP "CompileFAP" +#define SC_UNO_REF_CONV_CHARTOOXML "RefConventionChartOOXML" // Chart2 #define SC_UNONAME_ROLE "Role" diff --git a/sc/qa/uitest/chart/tdf64086.py b/sc/qa/uitest/chart/tdf64086.py new file mode 100644 index 000000000000..238a936a9caa --- /dev/null +++ b/sc/qa/uitest/chart/tdf64086.py @@ -0,0 +1,31 @@ +# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*- +# +# 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/. +# + +from uitest.framework import UITestCase +from uitest.uihelper.common import get_url_for_data_file + +class NamedRangesChart(UITestCase): + + def test_chart_series_ranges_with_named_ranges_as_datasource(self): + with self.ui_test.load_file(get_url_for_data_file("tdf64086.xlsx")) as calc_doc: + + xChart = calc_doc.Sheets[0].Charts[0] + xDataSeries = xChart.getEmbeddedObject().getFirstDiagram().CoordinateSystems[0].ChartTypes[0].DataSeries + + self.assertEqual(3, len(xDataSeries)) + + test_range1 = calc_doc.Sheets[0].NamedRanges.getByName("Local_sheet_name") + self.assertEqual(xDataSeries[0].DataSequences[0].Values.SourceRangeRepresentation, test_range1.Name) + + test_range2 = calc_doc.NamedRanges.getByName("global_name") + self.assertEqual(xDataSeries[1].DataSequences[0].Values.SourceRangeRepresentation, test_range2.Name) + + test_range3 = calc_doc.Sheets[1].NamedRanges.getByName("other_sheet_name") + test_range3_Name = calc_doc.Sheets[1].Name + '.' + test_range3.Name + self.assertEqual(xDataSeries[2].DataSequences[0].Values.SourceRangeRepresentation, test_range3_Name) + +# vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/sc/qa/uitest/data/tdf64086.xlsx b/sc/qa/uitest/data/tdf64086.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..4cbd5ce8dbd1d24510cca138d6d0a76882052494 GIT binary patch literal 15670 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 - if (nTab >= 0 && nTab != aPos.Tab()) + if (nTab >= 0 && (nTab != aPos.Tab() || mbRefConventionChartOOXML)) { // Sheet-local on other sheet. OUString aName; @@ -5326,6 +5342,11 @@ void ScCompiler::CreateStringFromIndex( OUStringBuffer& rBuffer, const FormulaTo aBuffer.append(ScCompiler::GetNativeSymbol(ocErrName)); aBuffer.append( pConv->getSpecialSymbol( ScCompiler::Convention::SHEET_SEPARATOR)); } + else if (mbRefConventionChartOOXML) + { + aBuffer.append("[0]"); + aBuffer.append(pConv->getSpecialSymbol(ScCompiler::Convention::SHEET_SEPARATOR)); + } aBuffer.append(pData->GetName()); } } diff --git a/sc/source/core/tool/reftokenhelper.cxx b/sc/source/core/tool/reftokenhelper.cxx index 58d9353222dc..7d49a60f3e97 100644 --- a/sc/source/core/tool/reftokenhelper.cxx +++ b/sc/source/core/tool/reftokenhelper.cxx @@ -108,6 +108,16 @@ void ScRefTokenHelper::compileRangeRepresentation( if (p->GetString().isEmpty()) bFailure = true; break; + case svIndex: + { + if (p->GetOpCode() == ocName) + { + ScRangeData* pNameRange = rDoc.FindRangeNameBySheetAndIndex(p->GetSheet(), p->GetIndex()); + if (!pNameRange->HasReferences()) + bFailure = true; + } + } + break; default: bFailure = true; break; @@ -150,6 +160,16 @@ bool ScRefTokenHelper::getRangeFromToken( rRange = rRefData.toAbs(*pDoc, rPos); return true; } + case svIndex: + { + if (pToken->GetOpCode() == ocName) + { + ScRangeData* pNameRange = pDoc->FindRangeNameBySheetAndIndex(pToken->GetSheet(), pToken->GetIndex()); + if (pNameRange->IsReference(rRange, rPos)) + return true; + } + return false; + } default: ; // do nothing } diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx index 2f0461b39a5d..3d1b05256578 100644 --- a/sc/source/ui/unoobj/chart2uno.cxx +++ b/sc/source/ui/unoobj/chart2uno.cxx @@ -874,9 +874,21 @@ public: ScTokenRef aStart, aEnd; bool bValidToken = splitRangeToken(*mpDoc, rToken, aStart, aEnd); + // Check there is a valid reference in named range + if (!bValidToken && rToken->GetType() == svIndex && rToken->GetOpCode() == ocName) + { + ScRangeData* pNameRange = mpDoc->FindRangeNameBySheetAndIndex(rToken->GetSheet(), rToken->GetIndex()); + if (pNameRange->HasReferences()) + { + const ScTokenRef aTempToken = pNameRange->GetCode()->FirstToken(); + bValidToken = splitRangeToken(*mpDoc, aTempToken, aStart, aEnd); + } + } + OSL_ENSURE(bValidToken, "invalid token"); if (!bValidToken) return; + ScCompiler aCompiler(*mpDoc, ScAddress(0,0,0), FormulaGrammar::GRAM_ENGLISH); { OUString aStr; @@ -1593,7 +1605,7 @@ class RangeAnalyzer { public: RangeAnalyzer(); - void initRangeAnalyzer( const vector& rTokens ); + void initRangeAnalyzer( const ScDocument* pDoc, const vector& rTokens ); void analyzeRange( sal_Int32& rnDataInRows, sal_Int32& rnDataInCols, bool& rbRowSourceAmbiguous ) const; bool inSameSingleRow( const RangeAnalyzer& rOther ); @@ -1621,7 +1633,7 @@ RangeAnalyzer::RangeAnalyzer() { } -void RangeAnalyzer::initRangeAnalyzer( const vector& rTokens ) +void RangeAnalyzer::initRangeAnalyzer( const ScDocument* pDoc, const vector& rTokens ) { mnRowCount=0; mnColumnCount=0; @@ -1675,6 +1687,28 @@ void RangeAnalyzer::initRangeAnalyzer( const vector& rTokens ) mbAmbiguous=true; } } + else if (eVar == svIndex && aRefToken->GetOpCode() == ocName) + { + ScRangeData* pNameRange = pDoc->FindRangeNameBySheetAndIndex(aRefToken->GetSheet(), aRefToken->GetIndex()); + ScRange aRange; + if (pNameRange->IsReference(aRange)) + { + mnColumnCount = std::max(mnColumnCount, static_cast(abs(aRange.aEnd.Col() - aRange.aStart.Col()) + 1)); + mnRowCount = std::max(mnRowCount, static_cast(abs(aRange.aEnd.Row() - aRange.aStart.Row()) + 1)); + if (mnStartColumn == -1) + { + mnStartColumn = aRange.aStart.Col(); + mnStartRow = aRange.aStart.Row(); + } + else + { + if (mnStartColumn != aRange.aStart.Col() && mnStartRow != aRange.aStart.Row()) + mbAmbiguous = true; + } + } + else + mbAmbiguous = true; + } else mbAmbiguous=true; } @@ -1777,10 +1811,22 @@ uno::Sequence< beans::PropertyValue > SAL_CALL ScChart2DataProvider::detectArgum const sal_Unicode cSep = ScCompiler::GetNativeSymbolChar(ocSep); ScRefTokenHelper::compileRangeRepresentation( aTokens, xLabel->getSourceRangeRepresentation(), *m_pDocument, cSep, m_pDocument->GetGrammar(), true); - aLabel.initRangeAnalyzer(aTokens); + aLabel.initRangeAnalyzer(m_pDocument, aTokens); for (const auto& rxToken : aTokens) { - ScRefTokenHelper::join(m_pDocument, aAllTokens, rxToken, ScAddress()); + if (rxToken->GetType() == svIndex && rxToken->GetOpCode() == ocName) + { + ScRangeData* pNameRange = m_pDocument->FindRangeNameBySheetAndIndex(rxToken->GetSheet(), rxToken->GetIndex()); + if (pNameRange->HasReferences()) + { + const ScTokenRef aTempToken = pNameRange->GetCode()->FirstToken(); + ScRefTokenHelper::join(m_pDocument, aAllTokens, aTempToken, ScAddress()); + } + else + ScRefTokenHelper::join(m_pDocument, aAllTokens, rxToken, ScAddress()); + } + else + ScRefTokenHelper::join(m_pDocument, aAllTokens, rxToken, ScAddress()); if(!bThisIsCategories) ScRefTokenHelper::join(m_pDocument, aAllSeriesLabelTokens, rxToken, ScAddress()); } @@ -1795,10 +1841,22 @@ uno::Sequence< beans::PropertyValue > SAL_CALL ScChart2DataProvider::detectArgum const sal_Unicode cSep = ScCompiler::GetNativeSymbolChar(ocSep); ScRefTokenHelper::compileRangeRepresentation( aTokens, xValues->getSourceRangeRepresentation(), *m_pDocument, cSep, m_pDocument->GetGrammar(), true); - aValues.initRangeAnalyzer(aTokens); + aValues.initRangeAnalyzer(m_pDocument, aTokens); for (const auto& rxToken : aTokens) { - ScRefTokenHelper::join(m_pDocument, aAllTokens, rxToken, ScAddress()); + if (rxToken->GetType() == svIndex && rxToken->GetOpCode() == ocName) + { + ScRangeData* pNameRange = m_pDocument->FindRangeNameBySheetAndIndex(rxToken->GetSheet(), rxToken->GetIndex()); + if (pNameRange->HasReferences()) + { + const ScTokenRef aTempToken = pNameRange->GetCode()->FirstToken(); + ScRefTokenHelper::join(m_pDocument, aAllTokens, aTempToken, ScAddress()); + } + else + ScRefTokenHelper::join(m_pDocument, aAllTokens, rxToken, ScAddress()); + } + else + ScRefTokenHelper::join(m_pDocument, aAllTokens, rxToken, ScAddress()); if(bThisIsCategories) ScRefTokenHelper::join(m_pDocument, aAllCategoriesValuesTokens, rxToken, ScAddress()); } @@ -1885,13 +1943,13 @@ uno::Sequence< beans::PropertyValue > SAL_CALL ScChart2DataProvider::detectArgum RangeAnalyzer aTop,aLeft; if( eRowSource==chart::ChartDataRowSource_COLUMNS ) { - aTop.initRangeAnalyzer(aAllSeriesLabelTokens); - aLeft.initRangeAnalyzer(aAllCategoriesValuesTokens); + aTop.initRangeAnalyzer(m_pDocument, aAllSeriesLabelTokens); + aLeft.initRangeAnalyzer(m_pDocument, aAllCategoriesValuesTokens); } else { - aTop.initRangeAnalyzer(aAllCategoriesValuesTokens); - aLeft.initRangeAnalyzer(aAllSeriesLabelTokens); + aTop.initRangeAnalyzer(m_pDocument, aAllCategoriesValuesTokens); + aLeft.initRangeAnalyzer(m_pDocument, aAllSeriesLabelTokens); } lcl_addUpperLeftCornerIfMissing(m_pDocument, aAllTokens, aTop.getRowCount(), aLeft.getColumnCount());//e.g. #i91212# } @@ -2127,6 +2185,7 @@ ScChart2DataProvider::createDataSequenceByFormulaTokens( } } break; + case svIndex: case svString: case svSingleRef: case svDoubleRef: diff --git a/sc/source/ui/unoobj/tokenuno.cxx b/sc/source/ui/unoobj/tokenuno.cxx index b07a04e12b04..96f882d282ea 100644 --- a/sc/source/ui/unoobj/tokenuno.cxx +++ b/sc/source/ui/unoobj/tokenuno.cxx @@ -78,7 +78,8 @@ ScFormulaParserObj::ScFormulaParserObj(ScDocShell* pDocSh) : mnConv( sheet::AddressConvention::UNSPECIFIED ), mbEnglish( false ), mbIgnoreSpaces( true ), - mbCompileFAP( false ) + mbCompileFAP( false ), + mbRefConventionChartOOXML( false ) { mpDocShell->GetDocument().AddUnoObject(*this); } @@ -122,7 +123,8 @@ void ScFormulaParserObj::SetCompilerFlags( ScCompiler& rCompiler ) const rCompiler.EnableJumpCommandReorder(!mbCompileFAP); rCompiler.EnableStopOnError(!mbCompileFAP); - rCompiler.SetExternalLinks( maExternalLinks); + rCompiler.SetExternalLinks(maExternalLinks); + rCompiler.SetRefConventionChartOOXML(mbRefConventionChartOOXML); } uno::Sequence SAL_CALL ScFormulaParserObj::parseFormula( @@ -243,6 +245,11 @@ void SAL_CALL ScFormulaParserObj::setPropertyValue( if (!(aValue >>= maExternalLinks)) throw lang::IllegalArgumentException(); } + else if ( aPropertyName == SC_UNO_REF_CONV_CHARTOOXML ) + { + if (!(aValue >>= mbRefConventionChartOOXML)) + throw lang::IllegalArgumentException(); + } else throw beans::UnknownPropertyException(aPropertyName); } @@ -275,6 +282,10 @@ uno::Any SAL_CALL ScFormulaParserObj::getPropertyValue( const OUString& aPropert { aRet <<= maExternalLinks; } + else if ( aPropertyName == SC_UNO_REF_CONV_CHARTOOXML ) + { + aRet <<= mbRefConventionChartOOXML; + } else throw beans::UnknownPropertyException(aPropertyName); return aRet;