From 3a874f1c80c37e8b35666e1d73161ff762eb7e4c Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 5 Jun 2019 16:28:53 +0200 Subject: [PATCH] tdf#111522 svx: fix crash with view1 doing text edit and view2 doing sdr undo If one view has an active text edit, then current code doesn't handle manipulating the undo text outside the text edit, so avoid problems by simply not adding an undo action to the undo stack for shape creation or move. Other actions might want to do the same in the future: check for CanDoSdrUndo() before calling SdrUndoFactory member functions. [ Found no existing test suite similar to CppunitTest_sw_uiwriter, so added one. ] Change-Id: I3a364bf4fe6f9b0c13aa07283681b1045368cf7a Reviewed-on: https://gerrit.libreoffice.org/73558 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- include/svx/svdedtv.hxx | 6 ++ sd/CppunitTest_sd_uiimpress.mk | 84 +++++++++++++++++++++++++++ sd/Module_sd.mk | 1 + sd/qa/unit/data/tdf111522.odp | Bin 0 -> 10869 bytes sd/qa/unit/uiimpress.cxx | 100 +++++++++++++++++++++++++++++++++ svx/source/svdraw/svdedtv.cxx | 18 +++++- svx/source/svdraw/svdedtv1.cxx | 2 +- 7 files changed, 209 insertions(+), 2 deletions(-) create mode 100644 sd/CppunitTest_sd_uiimpress.mk create mode 100644 sd/qa/unit/data/tdf111522.odp create mode 100644 sd/qa/unit/uiimpress.cxx diff --git a/include/svx/svdedtv.hxx b/include/svx/svdedtv.hxx index af60deaac0f6..0305b7fb144c 100644 --- a/include/svx/svdedtv.hxx +++ b/include/svx/svdedtv.hxx @@ -185,6 +185,12 @@ public: void SetUndoComment(const OUString& rComment, const OUString& rObjDescr) { mpModel->SetUndoComment(rComment,rObjDescr); } bool IsUndoEnabled() const; + /** + * Checks if this or other views have an active text edit, in which case object undos are not + * created. + */ + bool CanDoSdrUndo() const; + std::vector< std::unique_ptr > CreateConnectorUndo( SdrObject& rO ); void AddUndoActions( std::vector< std::unique_ptr > ); diff --git a/sd/CppunitTest_sd_uiimpress.mk b/sd/CppunitTest_sd_uiimpress.mk new file mode 100644 index 000000000000..7881d15d2ef8 --- /dev/null +++ b/sd/CppunitTest_sd_uiimpress.mk @@ -0,0 +1,84 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# +# This file is part of the LibreOffice project. +# +# 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/. +# +#************************************************************************* + +$(eval $(call gb_CppunitTest_CppunitTest,sd_uiimpress)) + +$(eval $(call gb_CppunitTest_use_externals,sd_uiimpress,\ + boost_headers \ + libxml2 \ +)) + +$(eval $(call gb_CppunitTest_add_exception_objects,sd_uiimpress, \ + sd/qa/unit/uiimpress \ +)) + +$(eval $(call gb_CppunitTest_use_libraries,sd_uiimpress, \ + $(call gb_Helper_optional,AVMEDIA,avmedia) \ + basegfx \ + canvastools \ + comphelper \ + cppcanvas \ + cppu \ + cppuhelper \ + drawinglayer \ + editeng \ + for \ + forui \ + i18nlangtag \ + i18nutil \ + msfilter \ + oox \ + sal \ + salhelper \ + sax \ + sb \ + sd \ + sfx \ + sot \ + svl \ + svt \ + svx \ + svxcore \ + test \ + tl \ + tk \ + ucbhelper \ + unotest \ + utl \ + vcl \ + xo \ +)) + +$(eval $(call gb_CppunitTest_set_include,sd_uiimpress,\ + -I$(SRCDIR)/sd/inc \ + -I$(SRCDIR)/sd/source/ui/inc \ + -I$(SRCDIR)/sd/source/ui/slidesorter/inc \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_CppunitTest_use_sdk_api,sd_uiimpress)) + +$(eval $(call gb_CppunitTest_use_externals,sd_uiimpress,\ + boost_headers \ +)) + +$(eval $(call gb_CppunitTest_use_ure,sd_uiimpress)) +$(eval $(call gb_CppunitTest_use_vcl,sd_uiimpress)) + +$(eval $(call gb_CppunitTest_use_rdb,sd_uiimpress,services)) + +$(eval $(call gb_CppunitTest_use_custom_headers,sd_uiimpress,\ + officecfg/registry \ +)) + +$(eval $(call gb_CppunitTest_use_configuration,sd_uiimpress)) + +# vim: set noet sw=4 ts=4: diff --git a/sd/Module_sd.mk b/sd/Module_sd.mk index bd2796ae818e..a7edda76cbe4 100644 --- a/sd/Module_sd.mk +++ b/sd/Module_sd.mk @@ -36,6 +36,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sd,\ CppunitTest_sd_export_tests \ CppunitTest_sd_filters_test \ CppunitTest_sd_misc_tests \ + CppunitTest_sd_uiimpress \ CppunitTest_sd_html_export_tests \ CppunitTest_sd_activex_controls_tests \ )) diff --git a/sd/qa/unit/data/tdf111522.odp b/sd/qa/unit/data/tdf111522.odp new file mode 100644 index 0000000000000000000000000000000000000000..fd6ebeb6ed220fc2b3c59b12196f170282766ae5 GIT binary patch literal 10869 zcmbuF1ymeK+wXBFXwaa+gF6Iwf(Li^VbH-LxCD21cXwxS_W*%FaF+xpz$N>hz1e-g z?4J9b`^@xIb)SCz)m_z7_0+FRQ3e_Y8v+6W0>VVJU!IMsyqF0B0^;ZPdB)pHl{!)Mmq;n$LI8qa}@s&MLUk`vcgW#wUz|HY}SBL*-!Kq&h{OU1WKuK)=B%~Bvv0d_5#?;yh zYLh*8u>1z~_o*cxlgw5}Jl|;Cl-+vyj|6FPjTT0==l+E+4Yc|L(-7us5qvb{u>D~$ zVh_^Ps1q>`9pd_APlFEGBX;tpflbOTg-Dz8dtWyZc4=u{-$|yszx2>kl(4Z#<bqhKN8$N%>HKXCfYGY{IE>aA5U&o9)ew zv}))NmOz2Bb<_MK6i;nW(GA=F-Nq3)%PFzbI6cZRMkHK2Fpda0wbIyvvcf2NEs9zI zV#YMq7fHqGF$w-t z{X6eb9fCPbcWDvhDa-Nr^j-+pM?jOe??wti*r5(fsb4C+U>_*rSP8b(kD^Y0fH7rBd#<-QUmz~^ewvm}3HHdq`d zUX`VIr2&g;AQ3&RV3Vc-V}YQb)X#pT1bl1;xiPSji!VJz#MvAW=)>YUY5qVd#`ZX4 z@4ErXCH18%54LU#@*yIvjnMlH1J?u{O@N0iH4&XR9b0a7(gj?Vfk3r(G(Fw-Rj8C; z_RSk~^4C7)$|zj&G)iLL2f2v5)1h9uQ+Ye(Idn-8uHb-OgA?`SUiUuMk97tOAg@WD zsX!h%=)~Av3fMGd*E<+Bbd<-Nf><(nI~*W!ItNrsKob4t+=8U)W>mqf_|3h`qGB#( z@#d|CC)yCx$VQYmI)trM++w|-naFydCIKtYkTWbgeq>eR7TTx?&g)UTVUiLQy^n#R zS>$dYx%)Q7V!lB{^=6RrtVS=?05PX}h>??GfFSDe0i~7ze{>@**zIWf7iFwY*wPwr}-p;MzhcP5V>BJb;#Q}X&u8VB}jCDhW? zKB>ErNmOFx&kc{Q;gudBK;)ADf!~+wxz^8eLI$`v_kQ#Up_qnS?w*1xl$f24{jMiz z>6^RR*O22iyo-rOpJCJeie}}pE)@DJeubCIkmZssrHF?fdXa#X)Ppnuc#^b9V>5L7 zY(kG*oDQ#rGW}Fh6)C*foFV|}F@xSb{jpt9nV%ANN2yIdAVh$aabTN=lKB+OHXl3$Q3i zMPZJ$(H)rIogHb6dq_m4Foo31`S@|-5UIUjNh|G6M)cHN(+4aNpF2|=_siqI#4w+AJrKjD3L$nmWioeD^zBRU8^ro+liGqhN zg@^0p!X6x)xUS}U=g0;22M0wu2Bu=@DRS6N8+9UA6Mif!6!Wo>1KAsOzC+p+PLo#T z50`$SW(gnh+7#9J3Ary5gB|nX<-uiFqx1n&R_KX%WUy{C62Y6~m#fvxY$5|tg|t_1 z61QOuQZON}*o;0j;5b;omlH(+M!Y6RKT%L92_MeEAS>6cd!}gt{ z--H5quAQVPkh@JH0}Vnw;mL|-bU&si+9+zU+9Q`k zGALwl(yZ$CAQitihqWmZ-5{a6T(%RGx|ALhhJr()F6XWOddnm7()$%sLb7xa$!LNp zc3%})bO-M@H(lZM@XCi_UA;!kfbd*`pzwUC5c)2Hk4TugG6q-`M5Xb8N?88g@S~Wp z0a2!R>Jr^>UO)&K$xo2*xH>;zSDbc>tWC(O^@~Pk`}s@c(_t5BJsu;JKx|zxW@jwW zK%^%kkslvc$R7#kqp6KjTs^)C!&I309O4Do`N*ItD*dpnnZju20&PvpqyI3X$YEJQ zD_(28rcBI~cxCq)@>`L+2;Cxx3@Upi*M%5j3T5VW;J7Wr2~5_${aBIJ7>HQZ!gyl| zQQf(VIkYT~05>=kJW~IDFX&supv~4jKKCMnHZ|Gn7ApJ*HC7|>(qobM4~+X?#_Xo8 zg2S9SN=+0Zi5OpEnt`|7P0|S@QIkp;DZtx&GaQ>Y)Ghmsj#s|Y$>NCYSpii5$9X&n zVwdSg{SQ_xoOJY)uIM2l0t(6$Us4GwYMM*7+PYy;+IK9@x|S? z@>WNJslHhh57K$2az@-v}VvmBr}iaTb}tC z94>IRsR~JiC~&5X$I_$5`UpUE9g}z^)uSovfYswTbLFS5RWEy#2Uv~~sk_;t64}i^ z4yc8b9Jgo4&Elm0-W zfqmR-FIZ*dDd?Ofcn)>HFMsvzTtZnU>Wh4IKxQ~Lobemq)BtcMlk6ouL=ZEBR&~;p zpV{s`dus8w0DazUb%Fu@3-b$25OrG&%JI92J*5=Sqg~yAzCzARj`R&>=6+dLwDu0= zA4sIYE9@*neKX+;-1@E~;4){R#bgvcL6lppZ8)hm!V-eQLJf)cK$jA$x$HX=(dtJW zap69;)xyOtaYe!|YkkedmC$SY$IC2ZqpgZVAq)44Yx?lJy}2dp`J8VaID>mr^J3gC z<)W*rb*`pg+i;uBSz4w&U{+V_lfPKRd%AEj9HsRYwRzyQIx_^_xie|)-5s*duddY_ zB(*a%eS;D|wdctj>}Pk6k})U7MKU|JFM-;qaMcOdijukfDjTYv7a>QKWuTn$)L^$J zenFjRwxidmM&{#@o4QJBRxdWjM^s}^WK@vy?K8(9xf;TXzzdc-N~3}OkeBT>4FZR` z)Ylq)e`#iH8uVeave`F!Gm!~1sm9Nkn<<(|(^dti#5`;eG$I6ugAMVId zr3Y6lo-Y^h6_<9Kz|kH5ac0%Gr;dyXC0ffDcqV~(^`$2nDRmNjdsHGKTUtRK3Y=v0W$y>(}py;Ubf*d_Mz)j5G6YZBYFNji2?16w8txS-39X zYFgw6xR59+IlTK<32lZj#`W&s`>V%TQOjY3x?Vt-na;fa&edR5fEL{&t3wTSxq&-L zbJ9_KMvg3S*S%KW|I(y5Bs8!N+mKT3lgx$xIyK*X@D1IHwpD);yVPwO$a+2cG=7#r zh;|sW_W}aZl5Pcv)B7nz29cjyoRFPlboQjD_Fh$IFQLwhx$utR2Kw~S09EoJ!?MC^ zS$Q~;D6w^FSN%0;TZxqDmMKzBWiBK!=Bj@ex=LK3ekq?4r|64iyB_`WVSh=}%gKoT z0?C=ve&4=~K(J_~(D_^Bm+~p!#(um8R#a+!dD5G6@?C;38np1Q`ts`BD{3@UM`cgs ziQWFxulmvJ9$8wwo$g+Q=&b{Zf6WrB>6fo>Bd872J?QEaAJ>@_ohTtoezzy2>*v`&- zomo-P$2a(Qj?S10ei?YP`LeBFfH*mu@c!vwR{A~z5p9kmda=Z;NbOQXSvPWl#c01! zIpPD?okWl>2g4z&+~)%gw#iTI%kYZ}+d^x$k1IpC%WJ_O@bfSfS;?g!bZ{8S`zxZ8 zLpZ}zvD(m$%Tlkz3{F%)s_MkEbDo4Sne26~OXeCD-VF(oD*ThZDjD%^PXP=h} zLzSD?BK>i&ODkQB4l;e;R>Qb9<0QDc$Hwl0eI?LZ7+Hk1v@@139#~4)VEwT}Zd!N% zk-P#gt8_qxi5Zw}ZyjP)c#z0ol`K4gc#M=utwSI1ccx)1jK)s$Dbet ze*%WW3K9b1=Z5#pJX9<|Hby{0OMoMj)1O&JJD_=}qP!$362VU_f+{T~_8tP_*#QC~ z8UgzGcdA1??>P}vlvNSu=jWG@kdT#?RaI5Bv9SSxK<@7D0RaIK5fSn6@#*R5`T6-Z zH8sP-!*g?UD=RC9hldvz7mtsR&jL?RPu)FEM$fq&X)$3H*X856B@8erx|pyhq%|T1 z=aWH3;DWS03fNok|KM3Zl>VSYAg@momH*pq#C=+C#XCX}(2tw;(=8vmo;QmCn_z zr9FH$c?*^%&%rv0<`4_nk4``@*Sn=mE!)%1mI7%Ja=tLj`Vo7wqYxaZPDumZvy_v9 z_=$=F^zAW_WhnCMfns8-@9t{z-BKw)QTSU+gHeAtx%^GJ5YG-9#(2IZ|73YTIV6ht z$7~?I+AUOFj%c40DPto(XRtv5ckj)JX>-2p+@3{fG9GUhRGQ=Yu2V6CknnmtOcJhc zFAMT!4>5G3b=U&fW}1LC+t!=Cw{!QMYy_?=n+AO-$1Wzq4}k=Eq`BfZqHi_Uyorl* z;NrwPvR_g2o@_r*z3wl9>(Z;r02Nn1j*mx_xm#OEXrpQ_W9y5ki}`OH=T<9_N@FbnV;12FV-Bj}TJOLpnww~mGY~hcPsd*% zii*)7mTD`xhsZeC{Ms2oOxP|U12C@$!=r^)?~-t-4d1yh_LJ&FMj#X%HL<39CqIdX z2UB^%>4#2)>L-h%>_1+OE~UjTf2XvESoif@c+lIU`9pXjw!O0Me z%SXpxWq-0b;T4KAj-ie`KVtQA;r5SeWg&fgVhGw}5br!kVJEtRW?#$G5_{cjljabd z(E&22Vn;45gJovV8|vDE52~yr-v~d)i?#FIa)zaoFFrM2qz%(0&Q~rlDt)Y2o&nU$ zXtc6m!F*RTC)3K_Qy$s!hF0U2p93mYzoc&sHgGz}kn|%791KXpU+!H9Mskbgfl@j; zz*6vI^+rG_V{U{UKEy953=$i>K$<90A2$nC^6ahq5cr+;vvgv7j)Qb=Ym1m{rpLU0 zMZ}f|mjpd9zvOwm%hzHi$;;}_&W2s+&(mHfN>H-fk0^SikC2y2oL?-=@ufPbI*6G! z5bdoHwuogEuP~}|lrw6%E{m6;IfCVi2*llPjli}^b3BHhdW3p#jxAa^4dG6xMZqNX z)8x7RksBTOWH7Wvg*X<|kst0^=n!X~7oJ~jf786-N1 zp?%RUMPeDn!mG&#PB}8U98LDT?R(o|Bflc1(3Gs~f5ZCvkRrUAFY;)jj8TWRw`|>| zNx0J#ij^B+sv1eJrWw>Pr|uO+0Au$##? z9hxhbK&`vW+ZHKV+&*a2nXOr|@X;6#c>>y6o9xZQWvNEmD98*LQPrv1`s(`yEH8|H z4m8uYgt_n6`VeajMunU+08-ENG5Je^ETx=%aXKduXCRchXAF|uM4_T<%$-h_LKd=a zQIWZ_g=fy;#W?=U)-llX^#s-Q{0HkC&epPyMvt?D(gTet*Ux;(yY+3_pxEe7BzLk( z87J#YO$TLxS4V}wb`|SLZoqw+2iA9;Pi zu8&r2DEj^2kN@oM=<-=fG{fzBm_S2<0#Ku~9R?Kx$inN9PI{od;X8SI>@jiUZsdCW zcC%z3w0`63{<=x*fRLpNcb-Nx{g6Ed(ORqunk_U*GMBr%z?!=G%0&lhtlK6YS)D6L z##6O8YLW&Pu7&I`6Jqp99wo#gAuBizpzb}wFH?hNiZ zPNM!ZhW*_@`NzvZQzyfpqhy52Xk;2Q_UiSU=+6v`=$SZ%oT}<h=M(SZS5jRv6OGI%hN3#doO#hc&GpKEU^u5pgew zbY`6ggL~eVOO$7s;uD)s_rt9b+MdjjYYa~c*sRUx$qcj1F;B5y@sng#i|U_(2&!eW zbk!3tD=3$?tEw+ef?7NvgC~bllo?;>`FxzEB@77jjK_VC*8{lcHIM-H$GKJ|ID6M{ z4Lf*Zv0@CyBsf>R!G=6%OX_0`&6JjSofYJZTP1}PMH0RlLVP{@mcAO2YGGQ7gfJN*Tk7RO>vhCpN z*Z=vjoVd@2T|duIDxTx{e}2h}@*Gt;nmRdI0?q$;&AX~)W4pnP{^;G6E8;PeDIcFS zv+Ad%_BA8%8zvNNXG$L|NhHydJoLk*IsEeROt&*uJFl)Fw%yTg3ckVsTb#}Z?Y5gE zMAk@}7U}JYx)L@izyWD(vvfqc#2wvb#g9P_FHbQ}dY-u}T`93tQL-&;Z>l6Ly=A?^ z_%Hd1BCZ9pLGIB2$w^vmlW$7^mb!%HkVE(^o7$&lsu4F0S2-FPDesnQ<^%)!!UgyFGXgjrA> z#*Oka<6-!zCbq$1suLsdU_io6oK7wD>#LNN(B#!yC`W7d{G)}F?heY z%OLa$rNtMzdU~&Y#C|)806HwEeY!ewyu^5m917-0xgBwQAqKiv(J4l0pEWI_Y}|v9 zNW1=X)QiO-V_OmuyPE>V7?EnZ(iJ2iaKrw>bRA2GOD1^v&EAi6^6!qtj2r>s3ywr^ zr!#c@7abwP8M7BGCW8FL8=GZA?$iq74~{m{DNdKk-U0y{5~O=HXK_$XZhJ`AbJJJ= ztGOh#N+Xjh`eqyuJP{vTT;G0lb}Nhtq+F|<*l;j-MjyxM6+X%}8s=Msv-t>-PYLUf(m?;~4STfA+N0Cp_auYNl4~mU& z{+_Rf=-QbWQ%Xe!r--$Zvi>i0AUv?Z0vP_b$fu%7E)AX+FfaNC+c-Z%W(86oSJm61 zOoG!eg3IAxxH}TwNJ)t^Y`eU!bIfiy+y95sZ`JE992JxKAkc zN`@frO?8_!2PWyDui;KvfjWtUQweu?rcPicQ#C!yB?ir*Qxu=M)Pw;U$|Y}XVEs@P z@wd6qJdT~gml05d0o^&@raoo6?O}J0(P{Xz;)-2y8mS$6X)@E}oh6E{fj}85IqE2$ zJ~4}23b9wl2*{e+IOzusP$?*&?j0`}k8>1FiZ?1;L#(%3}etu+Ddo1!s!lf z(-+xD1?obsN!*WlX7-!)z$63K=CqwKNLM_;>x$O9iCs)s^jJ}z0u zLacFl?i4$IIes_9dSEsItYj(Q%`_XIP9i40C;f1{wS~-*h5Digt3Hu66~l*p4i?F~ z-OHv}vNYL&NOJm6G<7fC@{@k((h7-Nq^!#Ps;#i59f`CSn)bfIDZ}>@qSCRPrlXN3 zsGmcUSEjp^=5zc~^sn*D%jY3UPFzKpL0Vpd$;J?9X=dv9$CST9S;h*?jJ~>yE#V)9UW)**tB8 z#kjZi&+yvrp_`i266=b5=lCs#4w0*>goxvtf&(8WbcsT6Wh#SILC(bCBPVjS^x<-- zD-cn8o+B8d0~6HFV-ad6Uk1ePV_ckNfo`pr&j?oBN+9ZOv_L#BB%1=52lAT*mxpup zWKInK$X4X7=1!RVS}l?rj^~qbOO>b)_8xUOsuP^ak8dEQfijzK(ImDgk*Q!j{5U_2 zAF{EX4QVt+aMt9o_=oOQQ3m$8Z-#(CfBw9Ao;0vi{oMOMt96aR literal 0 HcmV?d00001 diff --git a/sd/qa/unit/uiimpress.cxx b/sd/qa/unit/uiimpress.cxx new file mode 100644 index 000000000000..910f4a9dd0c3 --- /dev/null +++ b/sd/qa/unit/uiimpress.cxx @@ -0,0 +1,100 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * 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/. + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +using namespace ::com::sun::star; + +/// Impress UI tests. +class SdUiImpressTest : public test::BootstrapFixture, public unotest::MacrosTest +{ +protected: + uno::Reference mxComponentContext; + uno::Reference mxComponent; + +public: + virtual void setUp() override; + virtual void tearDown() override; +}; + +void SdUiImpressTest::setUp() +{ + test::BootstrapFixture::setUp(); + + mxComponentContext.set(comphelper::getComponentContext(getMultiServiceFactory())); + mxDesktop.set(frame::Desktop::create(mxComponentContext)); +} + +void SdUiImpressTest::tearDown() +{ + if (mxComponent.is()) + mxComponent->dispose(); + + test::BootstrapFixture::tearDown(); +} + +CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf111522) +{ + // Load the document and create two new windows. + mxComponent = loadFromDesktop(m_directories.getURLFromSrc("sd/qa/unit/data/tdf111522.odp")); + auto pImpressDocument = dynamic_cast(mxComponent.get()); + sd::ViewShell* pViewShell = pImpressDocument->GetDocShell()->GetViewShell(); + pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_NEWWINDOW, SfxCallMode::SYNCHRON); + sd::ViewShell* pViewShell1 = pImpressDocument->GetDocShell()->GetViewShell(); + pViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_NEWWINDOW, SfxCallMode::SYNCHRON); + sd::ViewShell* pViewShell2 = pImpressDocument->GetDocShell()->GetViewShell(); + CPPUNIT_ASSERT(pViewShell1 != pViewShell2); + + // Have slide 1 in window 1, slide 2 in window 2. + SfxRequest aRequest(pViewShell2->GetViewFrame(), SID_SWITCHPAGE); + aRequest.AppendItem(SfxUInt32Item(ID_VAL_WHATPAGE, 1)); + aRequest.AppendItem( + SfxUInt32Item(ID_VAL_WHATKIND, static_cast(PageKind::Standard))); + pViewShell2->ExecuteSlot(aRequest, /*bAsync=*/false); + + // Start text edit in window 1. + SdPage* pPage1 = pViewShell1->GetActualPage(); + SdrObject* pShape1 = pPage1->GetObj(0); + SdrView* pView1 = pViewShell1->GetView(); + pView1->MarkObj(pShape1, pView1->GetSdrPageView()); + pView1->SdrBeginTextEdit(pShape1); + CPPUNIT_ASSERT(pView1->IsTextEdit()); + + // Move the shape in window 2 & undo. + SdPage* pPage2 = pViewShell2->GetActualPage(); + CPPUNIT_ASSERT(pPage1 != pPage2); + SdrObject* pShape2 = pPage2->GetObj(0); + SdrView* pView2 = pViewShell2->GetView(); + pView2->MarkObj(pShape2, pView2->GetSdrPageView()); + pView2->MoveMarkedObj(Size(1, 1), /*bCopy=*/false); + // Without the accompanying fix in place, this test would have failed with an assertion failure + // in SdrObjEditView::SdrEndTextEdit() as mpOldTextEditUndoManager was not nullptr. + pViewShell2->GetViewFrame()->GetDispatcher()->Execute(SID_UNDO, SfxCallMode::SYNCHRON); +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/svdraw/svdedtv.cxx b/svx/source/svdraw/svdedtv.cxx index 51678b78b0d0..5883eab62640 100644 --- a/svx/source/svdraw/svdedtv.cxx +++ b/svx/source/svdraw/svdedtv.cxx @@ -972,7 +972,7 @@ bool SdrEditView::InsertObjectAtView(SdrObject* pObj, SdrPageView& rPV, SdrInser if (!pObj->IsInserted()) { rPV.GetObjList()->InsertObject(pObj, SAL_MAX_SIZE); } - if( IsUndoEnabled() ) + if( IsUndoEnabled() && CanDoSdrUndo()) AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pObj)); if (!(nOptions & SdrInsertFlags::DONTMARK)) { @@ -1028,4 +1028,20 @@ bool SdrEditView::IsUndoEnabled() const return mpModel->IsUndoEnabled(); } +bool SdrEditView::CanDoSdrUndo() const +{ + size_t nViews = mpModel->GetListenerCount(); + for (size_t nView = 0; nView < nViews; ++nView) + { + SdrEditView* pView = dynamic_cast(mpModel->GetListener(nView)); + if (!pView) + continue; + + if (pView->IsTextEdit()) + return false; + } + + return true; +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/svdraw/svdedtv1.cxx b/svx/source/svdraw/svdedtv1.cxx index f781b64b36f7..66bc4c15ae69 100644 --- a/svx/source/svdraw/svdedtv1.cxx +++ b/svx/source/svdraw/svdedtv1.cxx @@ -175,7 +175,7 @@ void SdrEditView::AddUndoActions( std::vector< std::unique_ptr > void SdrEditView::MoveMarkedObj(const Size& rSiz, bool bCopy) { - const bool bUndo = IsUndoEnabled(); + const bool bUndo = IsUndoEnabled() && CanDoSdrUndo(); if( bUndo ) {